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>
130 lines
3.8 KiB
TypeScript
130 lines
3.8 KiB
TypeScript
import { Hono } from "jsr:@hono/hono@4";
|
|
import { sqlWrapper } from "../../db.ts";
|
|
import { auditWrapper } from "../../audit.ts";
|
|
import { getAuthenticatedUser } from "../../auth-session.ts";
|
|
import { getClientIp } from "../../middleware.ts";
|
|
|
|
export const appsAdminRoutes = new Hono();
|
|
|
|
appsAdminRoutes.get("/", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const apps = await sqlWrapper.sql`
|
|
SELECT a.id, a.name, a.spiffe_id, a.description, a.created_at,
|
|
COUNT(g.id) AS active_grants_count
|
|
FROM apps a
|
|
LEFT JOIN grants g ON a.id = g.app_id
|
|
GROUP BY a.id, a.name, a.spiffe_id, a.description, a.created_at
|
|
ORDER BY a.created_at ASC
|
|
`;
|
|
return c.json({ apps });
|
|
});
|
|
|
|
appsAdminRoutes.post("/", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const {
|
|
name,
|
|
spiffeId,
|
|
description,
|
|
domain,
|
|
is_public,
|
|
bypass_paths,
|
|
allowed_cidrs,
|
|
} = await c.req.json();
|
|
if (!name || !spiffeId) {
|
|
return c.json({ error: "Name and SPIFFE ID are required" }, 400);
|
|
}
|
|
|
|
try {
|
|
const newApp = await sqlWrapper.sql`
|
|
INSERT INTO apps (name, spiffe_id, description, domain, is_public, bypass_paths, allowed_cidrs)
|
|
VALUES (${name.trim()}, ${spiffeId.trim()}, ${
|
|
description?.trim() || null
|
|
}, ${domain?.trim() || null}, ${is_public || false}, ${
|
|
bypass_paths || []
|
|
}, ${allowed_cidrs || []})
|
|
RETURNING id, name, spiffe_id, description, created_at
|
|
`.then((res: any) => res[0]);
|
|
|
|
auditWrapper.auditLog(auth.userId, "app_registered", newApp.id, {
|
|
name: newApp.name,
|
|
spiffe_id: newApp.spiffe_id,
|
|
}, getClientIp(c));
|
|
return c.json({ success: true, app: newApp });
|
|
} catch (err: any) {
|
|
if (err.code === "23505") {
|
|
return c.json({
|
|
error: "An application with this SPIFFE ID already exists",
|
|
}, 409);
|
|
}
|
|
return c.json({ error: "Failed to register application" }, 500);
|
|
}
|
|
});
|
|
|
|
appsAdminRoutes.put("/:id", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const appId = c.req.param("id");
|
|
const {
|
|
name,
|
|
description,
|
|
domain,
|
|
is_public,
|
|
bypass_paths,
|
|
allowed_cidrs,
|
|
} = await c.req.json();
|
|
|
|
if (!name) {
|
|
return c.json({ error: "Application name is required" }, 400);
|
|
}
|
|
|
|
try {
|
|
const updatedApp = await sqlWrapper.sql`
|
|
UPDATE apps
|
|
SET name = ${name.trim()},
|
|
description = ${description?.trim() || null},
|
|
domain = ${domain?.trim() || null},
|
|
is_public = ${is_public || false},
|
|
bypass_paths = ${bypass_paths || []},
|
|
allowed_cidrs = ${allowed_cidrs || []}
|
|
WHERE id = ${appId}
|
|
RETURNING id, name, spiffe_id, description, domain, is_public, bypass_paths, allowed_cidrs
|
|
`.then((res: any) => res[0]);
|
|
|
|
if (!updatedApp) return c.json({ error: "Application not found" }, 404);
|
|
|
|
auditWrapper.auditLog(auth.userId, "app_updated", updatedApp.id, {
|
|
name: updatedApp.name,
|
|
}, getClientIp(c));
|
|
|
|
return c.json({ success: true, app: updatedApp });
|
|
} catch (_err: any) {
|
|
return c.json({ error: "Failed to update application" }, 500);
|
|
}
|
|
});
|
|
|
|
appsAdminRoutes.delete("/:id", async (c) => {
|
|
const auth = await getAuthenticatedUser(c);
|
|
if (!auth) return c.json({ error: "Unauthorized" }, 401);
|
|
|
|
const appId = c.req.param("id");
|
|
const app = await sqlWrapper
|
|
.sql`DELETE FROM apps WHERE id = ${appId} RETURNING id, name`
|
|
.then((res: any) => res[0]);
|
|
if (app) {
|
|
auditWrapper.auditLog(
|
|
auth.userId,
|
|
"app_deleted",
|
|
appId,
|
|
{ name: app.name },
|
|
getClientIp(c),
|
|
);
|
|
return c.json({ success: true });
|
|
}
|
|
return c.json({ error: "Application not found" }, 404);
|
|
});
|