refactor(backend): remove auth for public API
Deploy to VPS / deploy (push) Failing after 35s
Deploy to VPS / deploy (push) Failing after 35s
- Remove auth module (auth.routes.ts, /api/auth/login) - Remove adminAuth middleware from voice and media routes - Remove adminAuth() function from shared middlewares - Remove auth-related e2e test - Clean up .env.example
This commit is contained in:
@@ -62,16 +62,6 @@ describe("API Config", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("API Auth", () => {
|
||||
it("POST /auth/login with wrong password returns 401", async () => {
|
||||
const { status } = await api("/auth/login", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ password: "wrong" }),
|
||||
});
|
||||
expect(status).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
describe("API Voice", () => {
|
||||
it("GET /guilds returns 200", async () => {
|
||||
const { status } = await api("/guilds");
|
||||
|
||||
@@ -7,7 +7,6 @@ import express, {
|
||||
} from "express";
|
||||
import helmet from "helmet";
|
||||
import { createAnalysisRouter } from "../modules/analysis/analysis.routes.js";
|
||||
import { createAuthRouter } from "../modules/auth/auth.routes.js";
|
||||
import { createConfigRouter } from "../modules/config/config.routes.js";
|
||||
import { createDashboardRouter } from "../modules/dashboard/dashboard.routes.js";
|
||||
import { createHealthRouter } from "../modules/health/health.routes.js";
|
||||
@@ -18,10 +17,9 @@ import { createRecordingsRouter } from "../modules/recordings/recordings.routes.
|
||||
import { createUiStateRouter } from "../modules/ui-state/ui-state.routes.js";
|
||||
import { createGuildsRouter } from "../modules/voice/guilds.routes.js";
|
||||
import { createVoiceRouter } from "../modules/voice/voice.routes.js";
|
||||
import { config } from "../shared/config/index.js";
|
||||
import { adminAuth, errorHandler } from "../shared/middlewares/index.js";
|
||||
import { errorHandler } from "../shared/middlewares/index.js";
|
||||
|
||||
const ADMIN_PASSWORD = config.ADMIN_PASSWORD || "admin";
|
||||
// Auth removed — dashboard is public
|
||||
|
||||
const logger = createChildLogger("http.app");
|
||||
|
||||
@@ -61,13 +59,8 @@ export function createHttpApp(): Express {
|
||||
next();
|
||||
});
|
||||
|
||||
// Health check (no auth required)
|
||||
// All routes are public
|
||||
app.use("/api", createHealthRouter());
|
||||
|
||||
// Auth (no auth required)
|
||||
app.use("/api", createAuthRouter());
|
||||
|
||||
// Public read-only endpoints
|
||||
app.use("/api", createConfigRouter());
|
||||
app.use("/api", createDashboardRouter());
|
||||
app.use("/api", createMessagesRouter());
|
||||
@@ -77,11 +70,8 @@ export function createHttpApp(): Express {
|
||||
app.use("/api", createUiStateRouter());
|
||||
app.use("/api/guilds", createGuildsRouter());
|
||||
|
||||
// Protected routes — require admin authentication (X-Admin-Password header)
|
||||
// Only voice and media control endpoints need auth
|
||||
const adminAuthMiddleware = adminAuth(ADMIN_PASSWORD);
|
||||
app.use("/api", adminAuthMiddleware, createMediaRouter());
|
||||
app.use("/api", adminAuthMiddleware, createVoiceRouter());
|
||||
app.use("/api", createMediaRouter());
|
||||
app.use("/api", createVoiceRouter());
|
||||
|
||||
// 404 handler
|
||||
app.use((_req: Request, res: Response) => {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { UnauthorizedError } from "@bete/shared/errors";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import type { Request, Response, Router } from "express";
|
||||
import express from "express";
|
||||
import { config } from "../../shared/config/index.js";
|
||||
import { asyncHandler, rateLimit } from "../../shared/middlewares/index.js";
|
||||
|
||||
const logger = createChildLogger("auth.routes");
|
||||
|
||||
const adminPassword = config.ADMIN_PASSWORD || "admin";
|
||||
|
||||
// Rate limit: max 10 login attempts per IP per 15 minutes
|
||||
const loginRateLimit = rateLimit({ windowMs: 15 * 60 * 1000, max: 10 });
|
||||
|
||||
export function createAuthRouter(): Router {
|
||||
const router = express.Router();
|
||||
|
||||
// POST /api/auth/login
|
||||
router.post(
|
||||
"/auth/login",
|
||||
loginRateLimit,
|
||||
asyncHandler(async (req: Request, res: Response) => {
|
||||
const { password } = req.body as { password?: string };
|
||||
|
||||
logger.debug("Auth login attempt");
|
||||
|
||||
if (!password || password !== adminPassword) {
|
||||
throw new UnauthorizedError("Invalid password");
|
||||
}
|
||||
|
||||
res.json({ ok: true });
|
||||
}),
|
||||
);
|
||||
|
||||
return router;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
AppError,
|
||||
UnauthorizedError,
|
||||
ValidationError,
|
||||
} from "@bete/shared/errors";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
@@ -30,18 +29,6 @@ export function errorHandler(
|
||||
});
|
||||
}
|
||||
|
||||
export function adminAuth(adminPassword: string) {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
const password = req.headers["x-admin-password"] as string;
|
||||
|
||||
if (!password || password !== adminPassword) {
|
||||
throw new UnauthorizedError("Invalid admin password");
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
export function asyncHandler(
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user