refactor(server): extract createApp and add auth/admin test seams
createApp() builds the Application without listening, so tests can call app.handle() directly. The listen call is gated behind import.meta.main so importing server.ts no longer boots a port. ADMIN_DIDS is read inside requireAdmin on each call (was frozen at module load), and a mutable authenticator indirection lets tests stub authenticateRequest via _setAuthenticatorForTest.
This commit is contained in:
80
server.ts
80
server.ts
@@ -19,13 +19,25 @@ type AuthCtx = {
|
||||
response: { status: number; body: unknown };
|
||||
};
|
||||
|
||||
let authenticator: typeof authenticateRequest = authenticateRequest;
|
||||
|
||||
export const _setAuthenticatorForTest = (
|
||||
fn: typeof authenticateRequest,
|
||||
): void => {
|
||||
authenticator = fn;
|
||||
};
|
||||
|
||||
export const _resetAuthenticatorForTest = (): void => {
|
||||
authenticator = authenticateRequest;
|
||||
};
|
||||
|
||||
const requireDidOwnership = async (
|
||||
ctx: AuthCtx,
|
||||
did: string,
|
||||
): Promise<boolean> => {
|
||||
let verifiedDid: string;
|
||||
try {
|
||||
verifiedDid = await authenticateRequest(
|
||||
verifiedDid = await authenticator(
|
||||
ctx.request.headers.get("Authorization"),
|
||||
);
|
||||
} catch {
|
||||
@@ -41,17 +53,18 @@ const requireDidOwnership = async (
|
||||
return true;
|
||||
};
|
||||
|
||||
const ADMIN_DIDS = new Set(
|
||||
(Deno.env.get("ADMIN_DIDS") ?? "")
|
||||
.split(",")
|
||||
.map((d) => d.trim())
|
||||
.filter(Boolean),
|
||||
);
|
||||
const adminDids = (): Set<string> =>
|
||||
new Set(
|
||||
(Deno.env.get("ADMIN_DIDS") ?? "")
|
||||
.split(",")
|
||||
.map((d) => d.trim())
|
||||
.filter(Boolean),
|
||||
);
|
||||
|
||||
const requireAdmin = async (ctx: AuthCtx): Promise<boolean> => {
|
||||
let verifiedDid: string;
|
||||
try {
|
||||
verifiedDid = await authenticateRequest(
|
||||
verifiedDid = await authenticator(
|
||||
ctx.request.headers.get("Authorization"),
|
||||
);
|
||||
} catch {
|
||||
@@ -59,7 +72,7 @@ const requireAdmin = async (ctx: AuthCtx): Promise<boolean> => {
|
||||
ctx.response.body = { error: "Unauthorized" };
|
||||
return false;
|
||||
}
|
||||
if (!ADMIN_DIDS.has(verifiedDid)) {
|
||||
if (!adminDids().has(verifiedDid)) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Admin only" };
|
||||
return false;
|
||||
@@ -260,27 +273,34 @@ router.delete("/:did/webhooks/:id", async (ctx) => {
|
||||
// ctx.response.status = 204;
|
||||
// })
|
||||
|
||||
const app = new Application();
|
||||
export const createApp = (): Application => {
|
||||
const app = new Application();
|
||||
|
||||
app.use(async (ctx, next) => {
|
||||
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
ctx.response.headers.set(
|
||||
"Access-Control-Allow-Methods",
|
||||
"GET, POST, PUT, DELETE, OPTIONS",
|
||||
);
|
||||
ctx.response.headers.set(
|
||||
"Access-Control-Allow-Headers",
|
||||
"Content-Type, Authorization",
|
||||
);
|
||||
if (ctx.request.method === "OPTIONS") {
|
||||
ctx.response.status = 204;
|
||||
return;
|
||||
}
|
||||
await next();
|
||||
});
|
||||
app.use(async (ctx, next) => {
|
||||
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
ctx.response.headers.set(
|
||||
"Access-Control-Allow-Methods",
|
||||
"GET, POST, PUT, DELETE, OPTIONS",
|
||||
);
|
||||
ctx.response.headers.set(
|
||||
"Access-Control-Allow-Headers",
|
||||
"Content-Type, Authorization",
|
||||
);
|
||||
if (ctx.request.method === "OPTIONS") {
|
||||
ctx.response.status = 204;
|
||||
return;
|
||||
}
|
||||
await next();
|
||||
});
|
||||
|
||||
app.use(router.routes());
|
||||
app.use(router.allowedMethods());
|
||||
app.use(router.routes());
|
||||
app.use(router.allowedMethods());
|
||||
|
||||
log("[server] listening on port 8080");
|
||||
app.listen({ port: 8080 });
|
||||
return app;
|
||||
};
|
||||
|
||||
if (import.meta.main) {
|
||||
const app = createApp();
|
||||
log("[server] listening on port 8080");
|
||||
app.listen({ port: 8080 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user