auth.provider API
    Preparing search index...

    Atomic primitives for server-issued challenge tracking. Identifies a single- winner across N concurrent calls; ceremony classification (replayed vs unknown) is layered above by ChallengeCeremony, NOT by this primitive.

    Per A1 §5.1 (lines 89-138). Concurrency contract:

    • issue(scope, value): N parallel → exactly 1 success, N-1 throws "duplicate"
    • consume(scope, value): N parallel on live entry → exactly 1 returns true, N-1 return false
    • find: read-only, no atomicity required

    Adapters MUST throw ChallengeStorageError per the throw matrix in ./errors.mts. find / consume MUST NOT throw on nonexistent / expired entries (return null / false respectively). This contract is enforced by the shared adapter contract test suite (__tests__/adapters.contract.mts, established in Tasks 3 + 4 and re-imported by the Redis adapter tests in Tasks 11 + 12).

    interface ChallengeStore {
        kind: string;
        consume(scope: string, value: string): Promise<boolean>;
        find(scope: string, value: string): Promise<Challenge | null>;
        issue(scope: string, value: string, expiresAtMs: number): Promise<void>;
    }
    Index

    Properties

    Methods

    Properties

    kind: string

    Methods

    • Atomically delete the entry if it exists. Returns true iff THIS call deleted a non-expired entry.

      Parameters

      • scope: string
      • value: string

      Returns Promise<boolean>

    • Non-mutating lookup. Returns null for absent / expired entries. Reading does not mutate state; safe to call repeatedly.

      Note: Redis-backed adapters reconstruct expiresAtMs from PTTL and may drift by <10ms vs the originally-issued epoch ms. The drift is benign — the wrapper layer (ChallengeCeremony, Task 5) only uses expiresAtMs to set the subsequent markSeen TTL; the security window remains TTL-bounded. Per A1 §5.1 (lines 117-122).

      Parameters

      • scope: string
      • value: string

      Returns Promise<Challenge | null>

    • Atomically register a server-issued challenge.

      Parameters

      • scope: string
      • value: string
      • expiresAtMs: number

      Returns Promise<void>

      ChallengeStorageError({ reason: "duplicate" }) when (scope, value) has a non-expired entry.

      ChallengeStorageError({ reason: "expired-at-issue" }) when expiresAtMs <= now() at call time.