mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
feat(auth): add requireAuth middleware
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
df5d125279
commit
17c11f0512
2 files changed
+78
No files matched your search
@@ -0,0 +1,56 @@
|
|||||||
|
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||||
|
import express from "express";
|
||||||
|
import cookieParser from "cookie-parser";
|
||||||
|
import request from "supertest";
|
||||||
|
import { createDatabase, type BotDatabase } from "../../data/database.js";
|
||||||
|
import { createUserStore } from "../../data/users.js";
|
||||||
|
import { createSessionStore } from "../../data/sessions.js";
|
||||||
|
import { createRequireAuth } from "./requireAuth.js";
|
||||||
|
import { SESSION_COOKIE_NAME } from "../auth/validateSession.js";
|
||||||
|
|
||||||
|
describe("requireAuth middleware", () => {
|
||||||
|
let botDb: BotDatabase;
|
||||||
|
let app: express.Express;
|
||||||
|
let validToken: string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
botDb = createDatabase(":memory:");
|
||||||
|
const users = createUserStore(botDb.db);
|
||||||
|
const sessions = createSessionStore(botDb.db);
|
||||||
|
const u = await users.createUser("alice", "pw");
|
||||||
|
validToken = sessions.createSession(u.id).token;
|
||||||
|
|
||||||
|
app = express();
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(createRequireAuth(sessions));
|
||||||
|
app.get("/protected", (req, res) => {
|
||||||
|
res.json({ ok: true, user: (req as any).user });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
botDb.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects requests without a session cookie", async () => {
|
||||||
|
const res = await request(app).get("/protected");
|
||||||
|
expect(res.status).toBe(401);
|
||||||
|
expect(res.body).toEqual({ error: "unauthenticated" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects requests with an unknown session cookie", async () => {
|
||||||
|
const res = await request(app)
|
||||||
|
.get("/protected")
|
||||||
|
.set("Cookie", `${SESSION_COOKIE_NAME}=garbage`);
|
||||||
|
expect(res.status).toBe(401);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows requests with a valid session cookie and attaches req.user", async () => {
|
||||||
|
const res = await request(app)
|
||||||
|
.get("/protected")
|
||||||
|
.set("Cookie", `${SESSION_COOKIE_NAME}=${validToken}`);
|
||||||
|
expect(res.status).toBe(200);
|
||||||
|
expect(res.body.ok).toBe(true);
|
||||||
|
expect(res.body.user.username).toBe("alice");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import type { Request, Response, NextFunction, RequestHandler } from "express";
|
||||||
|
import type { SessionStore } from "../../data/sessions.js";
|
||||||
|
import { validateSessionFromHeaders, SESSION_COOKIE_NAME } from "../auth/validateSession.js";
|
||||||
|
|
||||||
|
declare module "express-serve-static-core" {
|
||||||
|
interface Request {
|
||||||
|
user?: { id: string; username: string };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 };
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in new issue
Block a user