Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
/**
* DTP-06 — replay protection via per-client nonce LRU.
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
type DriveTemplateError,
DTP_CODES,
TEMPLATE_NONCE_LRU_DEFAULT_CAPACITY,
TemplateNonceLru,
validateTemplate,
} from "../src/index.js";
import { makeKeys, makeNonce, signed } from "./_helpers.js";
describe("DTP-06 — replay protection", () => {
it("hydrate with same (driveId, nonce) twice rejects on second call", {
timeout: 5000,
}, () => {
const keys = makeKeys();
const lru = new TemplateNonceLru();
const tpl = signed(
{
issuer: keys.publicHex,
nonce: makeNonce(0x42),
},
keys
);
const ctx = { clock: () => Date.now(), nonceLru: lru };
validateTemplate(tpl, ctx);
try {
validateTemplate(tpl, ctx);
throw new Error("expected REPLAY rejection");
} catch (err) {
expect((err as DriveTemplateError).code).toBe(
DTP_CODES.TEMPLATE_REPLAY
);
}
});
it("LRU capacity is the documented default", { timeout: 5000 }, () => {
expect(TEMPLATE_NONCE_LRU_DEFAULT_CAPACITY).toBe(1024);
});
it("LRU evicts oldest entry past capacity", { timeout: 5000 }, () => {
const lru = new TemplateNonceLru(2);
const a = makeNonce(1);
const b = makeNonce(2);
const c = makeNonce(3);
lru.remember("d", a);
lru.remember("d", b);
lru.remember("d", c);
expect(lru.has("d", a)).toBe(false);
expect(lru.has("d", b)).toBe(true);
expect(lru.has("d", c)).toBe(true);
expect(lru.size).toBe(2);
});
it("LRU reinserts on duplicate to refresh recency", {
timeout: 5000,
}, () => {
const lru = new TemplateNonceLru(2);
const a = makeNonce(1);
const b = makeNonce(2);
lru.remember("d", a);
lru.remember("d", b);
lru.remember("d", a); // refresh
const c = makeNonce(3);
lru.remember("d", c); // evicts b, not a
expect(lru.has("d", a)).toBe(true);
expect(lru.has("d", b)).toBe(false);
expect(lru.has("d", c)).toBe(true);
});
it("LRU rejects non-positive capacity", { timeout: 5000 }, () => {
expect(() => new TemplateNonceLru(0)).toThrow();
expect(() => new TemplateNonceLru(-1)).toThrow();
expect(() => new TemplateNonceLru(1.5)).toThrow();
});
it("clear() empties the LRU", { timeout: 5000 }, () => {
const lru = new TemplateNonceLru(8);
lru.remember("d", makeNonce(1));
expect(lru.size).toBe(1);
lru.clear();
expect(lru.size).toBe(0);
});
it("capacity getter exposes the configured cap", {
timeout: 5000,
}, () => {
const lru = new TemplateNonceLru(99);
expect(lru.capacity).toBe(99);
});
});