1import { describe, expect, it } from "vite-plus/test";
2import * as PlatformError from "effect/PlatformError";
3
4import { SecretStorePersistError } from "./ServerSecretStore.ts";
5import { mapDpopFailureReason, mapDpopReplayStoreError } from "./dpop.ts";
6
7const storeFailure = (tag: "AlreadyExists" | "PermissionDenied") =>
8 new SecretStorePersistError({
9 resource: "DPoP proof",
10 cause: PlatformError.systemError({
11 _tag: tag,
12 module: "FileSystem",
13 method: "open",
14 pathOrDescriptor: "dpop-proof.bin",
15 }),
16 });
17
18describe("mapDpopReplayStoreError", () => {
19 it("reports replay conflicts as invalid credentials", () => {
20 const cause = storeFailure("AlreadyExists");
21 const error = mapDpopReplayStoreError(cause);
22
23 expect(error._tag).toBe("ServerAuthInvalidCredentialError");
24 if (error._tag === "ServerAuthInvalidCredentialError") {
25 expect(error.cause).toBe(cause);
26 expect(error.dpopFailureReason).toBe("replay");
27 }
28 });
29
30 it("reports replay-store availability failures as internal errors", () => {
31 const error = mapDpopReplayStoreError(storeFailure("PermissionDenied"));
32
33 expect(error._tag).toBe("ServerAuthDpopReplayStateRecordError");
34 if (error._tag === "ServerAuthDpopReplayStateRecordError") {
35 expect(error.message).toBe("Failed to record DPoP proof replay state.");
36 }
37 });
38});
39
40describe("mapDpopFailureReason", () => {
41 it("maps verifier failures to safe client-facing categories", () => {
42 const mappings = [
43 ["time_window", "time_window"],
44 ["key_mismatch", "key_mismatch"],
45 ["method_mismatch", "request_mismatch"],
46 ["url_mismatch", "request_mismatch"],
47 ["access_token_hash_mismatch", "token_mismatch"],
48 ["missing_proof", "invalid_proof"],
49 ["malformed_proof", "invalid_proof"],
50 ["invalid_signature", "invalid_proof"],
51 ["invalid_proof", "invalid_proof"],
52 ] as const;
53
54 for (const [code, expected] of mappings) {
55 expect(mapDpopFailureReason(code)).toBe(expected);
56 }
57 });
58});