Repository navigation
Revoke the server session at logout and show synced home paths as ~ - #46
Merged
Merged
Conversation
statsai auth logout now posts the stored refresh token to /api/devices/logout before clearing local credentials. The call is best effort: a network error or non-2xx response prints a warning and local credentials are still cleared. --local-only skips the server call.
Sync payloads now rewrite a project path_label under the home directory to ~/... (the home directory itself to ~) for summaries, sessions, and task work items and spans. Only the outgoing label changes: the local store keeps the full path, path_hash and other identities are untouched, and pending-sync selection hashes the same payload that is sent.
The --include-projects, --include-tasks, --include-sessions, and --include-activity help now names the fields each one adds to hosted sync. The README lists the same, and the sync contract no longer says session rows carry no paths.
Task buckets are re-sent only when they change, so buckets a target already held kept their full home paths after the sanitizer started showing them as ~. Each acknowledged bucket now records the sanitizer version it was sent under (schema 31), and incremental sync treats a bucket acknowledged under an older version as pending. Bumping TASK_BUCKET_SYNC_SANITIZER_VERSION re-sends them again for any future sanitizer change. Summaries and sessions already re-send because their payload hash changes; a test now covers that.
A sync refreshing at the same time could rotate the refresh token after logout read it. The server answers 204 for an already-revoked token, so logout reported success while the rotated session stayed active. Logout now takes the same lock token refresh uses before reading credentials and holds it through the server revocation and local cleanup, including with --local-only.
After the schema 31 migration, an acknowledged deletion tombstone read as sanitizer version 0. Sync status counted it as pending while sync selection, which only re-sends deleted buckets when dirty, never chose it, so task_bucket_backlog stayed above zero. A tombstone is an empty snapshot and no sanitizer change affects it, so only local buckets are re-sent for an older sanitizer version. Selection and status now share task_bucket_needs_sync and the same tracked-bucket query.
If a refresh reached the server but its response was lost, the stored refresh token is already rotated away and its successor is live. The logout endpoint answers 204 for the old token without touching the successor, so logout reported success while a session stayed active. Under the refresh lock, logout now replays the pending rotation with its rotationId, as the next refresh would, and revokes the successor. If that exchange fails, logout warns that the session may still be active and how to revoke it, then clears local credentials.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
statsai auth logoutnow revokes the device session on the server beforeclearing local credentials, by posting the stored refresh token to
/api/devices/logout. It holds the auth refresh lock from reading thecredentials through revocation and cleanup, so a concurrent sync cannot
rotate the token in between. If an earlier refresh was interrupted after
the server rotated the token, logout replays that rotation with its saved
rotationIdand revokes the successor. When revocation fails, logout warnsthat the session may still be active and how to revoke it, then clears
local credentials anyway.
--local-onlyskips the server call.Synced project path labels under the home directory are sent as
~/....Only the sync payload changes: local storage, local display, path hashes
and every identity key stay the same. Summaries, sessions, task work items
and task spans are covered. Each acknowledged task bucket now records the
sanitizer version it was sent under (store migration 031), so the first
incremental sync after upgrading re-sends affected buckets once; deleted
buckets carry no labels and are not re-sent. Sync status and selection share
one predicate for pending buckets. Summaries and sessions re-send once on
their own because their payload hash changes.
The
--include-projects,--include-sessions,--include-tasksand--include-activityhelp text, the README anddocs/sync-contract.mdnowsay what each flag sends.