Binds the store to one path on one filesystem.
Injected filesystem access.
Absolute path of the app-tokens JSON file.
Refresh-token lifetime in days.
Issues the first refresh token of a new family.
Device, factors and fingerprint captured at authorization.
Current epoch milliseconds, injectable for tests.
The new record together with its one-time plaintext token.
Looks up a record by the plaintext token the client presented.
The plaintext refresh token.
Current epoch milliseconds, injectable for tests.
The matching record, or undefined when unknown, pruned, or unreadable.
Rotates a refresh token: the presented record is revoked and a replacement joins the same family. Presenting an already-revoked token means the client or an attacker replayed it, so the whole family is revoked instead, unless it falls within ROTATION_OVERLAP_MS of its rotation.
An expired token reads as unknown, because the load that feeds this drops expired records before anything looks at them. A spent token is kept until its overlap has passed, even when that is after its own expiry.
The plaintext refresh token presented by the client.
Current epoch milliseconds, injectable for tests.
Procedure with the replacement token, or a failure naming the reason.
Revokes the family a live record belongs to, so signing a device out kills its replacements too. It reads the file as a write does, so an unreadable file throws rather than reading as "no such session".
Public record id, as shown in the sessions list.
Current epoch milliseconds, injectable for tests.
True when a live record with that id existed.
Revokes the family of the record a refresh token belongs to, whether or not that record was already rotated. It reads the file as a write does, so an unreadable file throws rather than reading as "no such token".
The plaintext refresh token.
Current epoch milliseconds, injectable for tests.
True when an unexpired record held that token.
Lists the records that can still be refreshed.
Current epoch milliseconds, injectable for tests.
Live records, newest last; none when the file cannot be read.
Deletes staged files a killed write left beside the file.
How many were removed, or why the directory could not be read.
Persists app refresh tokens as hashes in a JSON file on the data volume.