fix: clean up an interrupted ring pubky pick - #1386
Conversation
Roll back the session and Ring reference when the pick is cancelled after sign in, and clear both when activation fails after the session is saved. Refs #1363
This comment has been minimized.
This comment has been minimized.
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
jvsena42
left a comment
There was a problem hiding this comment.
One MEDIUM inline. Ring adoption is unreleased; Paykit is on by default on master.
#1386 and #1393 both fix #1363 with opposite designs: #1386 rolls a pick back on Back, #1393 finishes it. Only one should merge. They conflict in PubkyRepo.kt and PubkyRepoTest.kt, but PaykitSdkService.kt auto-merges, so resolving PubkyRepo toward #1393 still brings in #1386's activateOrClearLocked. In #1393's flow, that cleanup deletes PAYKIT_SESSION before signInRingIdentity checks hasSessionChangedSince. A first pick then falls through to the sign-up fallback #1393 removed, and with the Ring reference already deleted, persistSessionAccess saves the Ring secret as a local key (the mechanism in greptile r4139882837). Close whichever one is not chosen.
Checked and clean:
- No adoption happens without a user tap.
- The rollback's reference-match guard runs under
initializeMutexwithNonCancellable. - Back during sign-in or profile load discards the new session and clears only the reference.
- There is no manifest or registrar change, and shipped local identities are unaffected.
|
I've closed #1393 in favour of this one. Rolling back on Back is simpler on Android than finishing the pick off-screen, which needed extra serialization there and led to the problem jvsena42 found on it. Two things from that work that might help here:
One question: should iOS roll back too, so both platforms match? It finishes the pick today only because adoption runs in an unstructured Once this lands I'll open a follow-up with the #1363 items it leaves out, the |
|
Two independent reviews, nothing blocking a merge. worth doing, does not block
nits
|
|
Pushed dab5dbc, which answers the review feedback so far:
I updated the description to match. Local verification: |
@Jasonvdb thanks, I took that approach in dab5dbc:
A follow-up works for those. The teardown order in |
@coreyphillips thanks. All four are addressed in dab5dbc:
|
pwltr
left a comment
There was a problem hiding this comment.
Requesting changes for the MEDIUM-priority rollback finding inline.
|
Pushed e48e277, which answers @pwltr's review: a pick now counts as newer only once it has verified its Ring credential and is about to save its reference, so a pick that fails before that no longer stops an earlier pick's rollback. I added a test for that case and listed it in the description. Local verification: |
pwltr
left a comment
There was a problem hiding this comment.
Follow-up on the rollback ownership issue: the credential-lookup case is fixed, but a later sign-in failure still leaves the earlier Ring session behind after Back.
|
Pushed effae80, which answers @pwltr's follow-up review. Instead of tracking which pick is newer, Ring picks now run one at a time: This changes one behaviour: a second pick started while another is still loading waits for it instead of running alongside it. I updated the description and the overlapping-pick tests, and added a test for a later pick that fails at sign-in. Local verification: |
jvsena42
left a comment
There was a problem hiding this comment.
Re-checked dab5dbc, e48e277 and effae80. No findings; the activation-cleanup MEDIUM is resolved. With #1393 closed, the competing-design note no longer applies.
Checked and clean:
adoptionMutexserializes picks, and an abandoned pick rolls back underNonCancellablebefore the next one starts, so picking B after Back cannot end up signed in as A.- A pick rolls back only itself, only while
!completed, and re-checks the reference underinitializeMutex. - Lock order is always
adoptionMutex→initializeMutex, so there is no deadlock path. - The sign-up fallback no longer runs after sign-in saved a session, so the Ring secret cannot be stored locally.
- Every cancel point discards the new session and clears the reference.
Fixes #1363
Refs: #1329
This PR fixes an interrupted or failed Pubky Ring pick leaving a hidden signed-in session behind.
Description
Out of Scope
PubkyAuthHandlerRegistrar: thepubkyauth://alias disabled while Ring was unavailable at launch is only recomputed when the identity changes, raised in bug: an interrupted ring pubky pick leaves a half-saved session #1363.PubkyRepo: the source-loss warning redacts the whole Ring reference, raised in bug: an interrupted ring pubky pick leaves a half-saved session #1363.PaykitSdkSessionProvider:clearSessionAccessdeletes the Ring reference before the session credentials, so a failed session delete leaves a session without its reference, raised in fix: clean up an interrupted ring pubky pick #1386 (comment).Design
N/A — no UI changes.
Preview
N/A — no user-visible changes.
QA Notes
Journeys
N/A — not drivable; see Manual Tests.
Manual Tests
regression:No profile → Pubky Choice → tap a Ring pubky and let it finish → signed in as that pubky, Create Profile shown when it has no profile — Pubky Ring app not in CapabilitiesAutomated Checks
PubkyRepoTest.kt— a pick cancelled after sign-in ends signed out with no session and no Ring reference, also when revoking the session failsPubkyRepoTest.kt— a sign-in that saves a session and then fails ends with no session and no Ring reference, without signing upPubkyRepoTest.kt— a newer pick of the same pubky starts only after a cancelled older pick rolled back, and keeps its session and Ring referencePubkyRepoTest.kt— cancelling a pick leaves no session or Ring reference when a pick of another pubky fails at the credential lookup or at sign-inPubkyRepoTest.kt— replaces the test that kept the identity when profile loading was cancelledjust compile,just test,just lint