/**
 * nonce-store — Replay attack prevention via nonce deduplication.
 *
 * NonceStore tracks seen idempotencyKeys within a TTL window to prevent
 * replay attacks. The Redis implementation uses SET NX PX for atomic ops.
 * The InMemory implementation is for testing only.
 *
 * ADR-ECO-017: nonce dedup via Redis SETNX TTL 10 min (auth side).
 *
 * @module auth/nonce-store
 * @public
 */
/**
 * In-memory NonceStore for unit tests.
 * NOT for production — no persistence, no distributed dedup.
 */
export class InMemoryNonceStore {
    store = new Map();
    async setNX(key, ttlMs) {
        const now = Date.now();
        // Evict expired entries on each call (bounded cleanup)
        for (const [k, expiry] of this.store.entries()) {
            if (expiry <= now)
                this.store.delete(k);
        }
        if (this.store.has(key)) {
            return false; // duplicate
        }
        this.store.set(key, now + ttlMs);
        return true;
    }
    /** Test helper: clear all state. */
    reset() {
        this.store.clear();
    }
}
/**
 * Redis-backed NonceStore for production.
 * Uses SET key value NX PX ttlMs — atomic, no race condition.
 */
export class RedisNonceStore {
    redis;
    constructor(redis) {
        this.redis = redis;
    }
    async setNX(key, ttlMs) {
        const result = await this.redis.set(`vauban:nonce:${key}`, "1", {
            nx: true,
            px: ttlMs,
        });
        // SET NX returns "OK" on success, null if key already exists
        return result !== null;
    }
}
//# sourceMappingURL=nonce-store.js.map