Files
remanso-jetstream/tests/auth_verify_test.ts

119 lines
3.4 KiB
TypeScript

import { assertEquals, assertRejects, assertThrows } from "@std/assert";
import { authenticateRequest, decodeJwtPayload } from "../src/auth/verify.ts";
import { installFetchStub, jsonResponse } from "./_helpers/fetch_stub.ts";
const makeJwt = (payload: Record<string, unknown>): string => {
const header = btoa(JSON.stringify({ alg: "HS256", typ: "JWT" }));
const body = btoa(JSON.stringify(payload));
return `${header}.${body}.sig`;
};
Deno.test("decodeJwtPayload parses sub from a 3-segment JWT", () => {
const token = makeJwt({ sub: "did:plc:abc", iat: 1 });
const payload = decodeJwtPayload(token);
assertEquals(payload.sub, "did:plc:abc");
});
Deno.test("decodeJwtPayload throws on malformed token", () => {
assertThrows(() => decodeJwtPayload("not.a.valid.jwt"));
assertThrows(() => decodeJwtPayload("onlytwo.parts"));
});
Deno.test("authenticateRequest rejects missing or non-Bearer Authorization", async () => {
await assertRejects(() => authenticateRequest(null));
await assertRejects(() => authenticateRequest(""));
await assertRejects(() => authenticateRequest("Basic abc"));
});
Deno.test(
"authenticateRequest resolves PDS then verifies session and returns did",
async () => {
const did = "did:plc:user";
const stub = installFetchStub((req) => {
if (req.url === `https://plc.directory/${did}`) {
return jsonResponse({
service: [{
id: "#atproto_pds",
serviceEndpoint: "https://pds.example.com",
}],
});
}
if (
req.url ===
"https://pds.example.com/xrpc/com.atproto.server.getSession"
) {
return jsonResponse({ did });
}
return jsonResponse({ error: "unexpected" }, { status: 500 });
});
try {
const result = await authenticateRequest(
`Bearer ${makeJwt({ sub: did })}`,
);
assertEquals(result, did);
const sessionCall = stub.calls.find((c) => c.url.includes("/getSession"));
assertEquals(
sessionCall?.headers.get("Authorization")?.startsWith("Bearer "),
true,
);
} finally {
stub.restore();
}
},
);
Deno.test(
"authenticateRequest throws when plc.directory or getSession is non-2xx",
async () => {
const did = "did:plc:user";
const plcFailStub = installFetchStub(() =>
new Response("not found", { status: 404 })
);
try {
await assertRejects(() =>
authenticateRequest(`Bearer ${makeJwt({ sub: did })}`)
);
} finally {
plcFailStub.restore();
}
const sessionFailStub = installFetchStub((req) => {
if (req.url.startsWith("https://plc.directory/")) {
return jsonResponse({
service: [{
id: "#atproto_pds",
serviceEndpoint: "https://pds.example.com",
}],
});
}
return new Response("nope", { status: 401 });
});
try {
await assertRejects(() =>
authenticateRequest(`Bearer ${makeJwt({ sub: did })}`)
);
} finally {
sessionFailStub.restore();
}
},
);
Deno.test(
"authenticateRequest throws when DID document has no atproto_pds service",
async () => {
const did = "did:plc:user";
const stub = installFetchStub(() =>
jsonResponse({ service: [{ id: "#other", serviceEndpoint: "x" }] })
);
try {
await assertRejects(() =>
authenticateRequest(`Bearer ${makeJwt({ sub: did })}`)
);
} finally {
stub.restore();
}
},
);