Extracted domain-specific sub-routers from monolithic `server/routes/admin.ts` and `server/routes/auth.ts` into isolated modules within `server/routes/admin/` and `server/routes/auth/` respectively. The original entry routers were updated to import and assemble these sub-routers without breaking their current HTTP interface or rate limiting/authorization middleware. Testing and linting were run ensuring perfect functionality and 100% test passing score. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
137 lines
4.2 KiB
TypeScript
137 lines
4.2 KiB
TypeScript
import { Hono } from "jsr:@hono/hono@4";
|
|
import { sqlWrapper } from "../../db.ts";
|
|
import { valkey } from "../../valkey.ts";
|
|
import { auditWrapper } from "../../audit.ts";
|
|
import { getAuthenticatedUser } from "../../auth-session.ts";
|
|
import { getClientIp } from "../../middleware.ts";
|
|
import { computeJwkThumbprint } from "../../http_signatures.ts";
|
|
|
|
export const hardwareKeysAdminRoutes = new Hono();
|
|
|
|
hardwareKeysAdminRoutes.get("/aaguid", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
const allowlist = await sqlWrapper
|
|
.sql`SELECT id, aaguid, description, created_at FROM aaguid_allowlist ORDER BY created_at DESC`;
|
|
return c.json({ allowlist });
|
|
});
|
|
|
|
hardwareKeysAdminRoutes.post("/aaguid", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
const { aaguid, description } = await c.req.json();
|
|
const uuidRegex =
|
|
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/i;
|
|
if (!aaguid || !uuidRegex.test(aaguid)) {
|
|
return c.json({ error: "Valid AAGUID (UUID) is required" }, 400);
|
|
}
|
|
try {
|
|
await sqlWrapper
|
|
.sql`INSERT INTO aaguid_allowlist (aaguid, description) VALUES (${aaguid.toLowerCase()}, ${
|
|
description || null
|
|
})`;
|
|
auditWrapper.auditLog(
|
|
auth.userId,
|
|
"aaguid_added",
|
|
null,
|
|
{ aaguid },
|
|
getClientIp(c),
|
|
);
|
|
return c.json({ success: true });
|
|
} catch (err: any) {
|
|
if (err.code === "23505") {
|
|
return c.json({ error: "AAGUID already exists" }, 409);
|
|
}
|
|
return c.json({ error: "Internal server error" }, 500);
|
|
}
|
|
});
|
|
|
|
hardwareKeysAdminRoutes.delete("/aaguid/:id", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
const id = c.req.param("id");
|
|
const record = await sqlWrapper
|
|
.sql`DELETE FROM aaguid_allowlist WHERE id = ${id} RETURNING aaguid`
|
|
.then((res: any) => res[0]);
|
|
if (record) {
|
|
auditWrapper.auditLog(
|
|
auth.userId,
|
|
"aaguid_removed",
|
|
null,
|
|
{ aaguid: record.aaguid },
|
|
getClientIp(c),
|
|
);
|
|
}
|
|
return c.json({ success: true });
|
|
});
|
|
|
|
hardwareKeysAdminRoutes.post("/hwk", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const { jwk, name } = await c.req.json();
|
|
if (!jwk || !name || typeof name !== "string") {
|
|
return c.json({ error: "Missing required fields: jwk, name" }, 400);
|
|
}
|
|
|
|
if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) {
|
|
return c.json({ error: "Invalid JWK: Must be an Ed25519 OKP key" }, 400);
|
|
}
|
|
|
|
try {
|
|
const fingerprint = await computeJwkThumbprint(jwk);
|
|
|
|
// 1. Dual Storage: PostgreSQL (Durability)
|
|
await sqlWrapper.sql`
|
|
INSERT INTO hwk_keys (fingerprint, public_key, name)
|
|
VALUES (${fingerprint}, ${JSON.stringify(jwk)}, ${name})
|
|
`;
|
|
|
|
// 2. Dual Storage: Valkey (O(1) Verification)
|
|
await valkey.sadd("auth:hwk:fingerprints", fingerprint);
|
|
|
|
auditWrapper.auditLog(
|
|
auth.userId,
|
|
"hwk_added",
|
|
null,
|
|
{ fingerprint, name },
|
|
getClientIp(c),
|
|
);
|
|
|
|
return c.json({ success: true, fingerprint }, 201);
|
|
} catch (err: any) {
|
|
if (err.code === "23505") {
|
|
return c.json({ error: "This key has already been registered" }, 409);
|
|
}
|
|
console.error("Failed to add HWK:", err);
|
|
return c.json({ error: "Internal server error" }, 500);
|
|
}
|
|
});
|
|
|
|
hardwareKeysAdminRoutes.delete("/hwk/:fingerprint", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const fingerprint = c.req.param("fingerprint");
|
|
|
|
// 1. Remove from PostgreSQL
|
|
const record = await sqlWrapper.sql`
|
|
DELETE FROM hwk_keys WHERE fingerprint = ${fingerprint} RETURNING id, name
|
|
`.then((res: any) => res[0]);
|
|
|
|
if (record) {
|
|
// 2. Remove from Valkey
|
|
try {
|
|
await valkey.srem("auth:hwk:fingerprints", fingerprint);
|
|
} catch (_err) {}
|
|
|
|
auditWrapper.auditLog(auth.userId, "hwk_removed", null, {
|
|
fingerprint,
|
|
name: record.name,
|
|
}, getClientIp(c));
|
|
return c.json({ success: true });
|
|
}
|
|
|
|
return c.json({ error: "Key not found" }, 404);
|
|
});
|