mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 13:02:49 +08:00
Adds an admin/member role to WebUI auth. /api/users and /api/audit are now gated by a requireAdmin middleware; all other authenticated endpoints accept both roles. Schema migration defaults all existing users to admin to preserve access. POST /api/users defaults new users to member; first-run setup always creates an admin. Adds PATCH /api/users/:id/role with last-admin demotion and deletion guards. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import type { Request, Response, NextFunction, RequestHandler } from "express";
|
|
import type { SessionStore } from "../../data/sessions.js";
|
|
import { SESSION_TTL_MS } from "../../data/sessions.js";
|
|
import {
|
|
validateSessionFromHeaders,
|
|
extractSessionToken,
|
|
SESSION_COOKIE_NAME,
|
|
} from "../auth/validateSession.js";
|
|
|
|
declare module "express-serve-static-core" {
|
|
interface Request {
|
|
user?: { id: string; username: string; role: "admin" | "member" };
|
|
}
|
|
}
|
|
|
|
export function createRequireAuth(sessions: SessionStore): RequestHandler {
|
|
return function requireAuth(req: Request, res: Response, next: NextFunction) {
|
|
const result = validateSessionFromHeaders(req.headers.cookie, sessions);
|
|
if (!result) {
|
|
res.clearCookie(SESSION_COOKIE_NAME, { path: "/" });
|
|
res.status(401).json({ error: "unauthenticated" });
|
|
return;
|
|
}
|
|
req.user = { id: result.userId, username: result.username, role: result.role };
|
|
const token = extractSessionToken(req.headers.cookie);
|
|
if (token) {
|
|
res.cookie(SESSION_COOKIE_NAME, token, {
|
|
httpOnly: true,
|
|
sameSite: "lax",
|
|
secure: req.secure,
|
|
path: "/",
|
|
maxAge: SESSION_TTL_MS,
|
|
});
|
|
}
|
|
next();
|
|
};
|
|
}
|