Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"dev": "node src/server.js",
"start": "node src/server.js",
"test": "node --test src/tests"
"test": "node --test src/tests/*.test.js"
},
"dependencies": {
"cors": "^2.8.5",
Expand Down
59 changes: 58 additions & 1 deletion apps/api/src/controllers/adminController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,63 @@
import { ok } from "../utils/response.js";
import { getAdminMetrics } from "../services/adminService.js";
import {
decideListing,
getAdminMetrics,
getAuditLog,
getControls,
getDisputeDetail,
getDisputes,
getModerationQueue,
getUserDetail,
getUsers,
ruleDispute,
updateControl,
updateUserStatus
} from "../services/adminService.js";

export async function metrics(req, res) {
return ok(res, await getAdminMetrics());
}

export async function users(req, res) {
return ok(res, await getUsers(req.query));
}

export async function userDetail(req, res) {
return ok(res, await getUserDetail(req.params.id));
}

export async function userStatus(req, res) {
return ok(res, await updateUserStatus(req.params.id, req.body, req.user));
}

export async function moderation(req, res) {
return ok(res, await getModerationQueue(req.query));
}

export async function moderationDecision(req, res) {
return ok(res, await decideListing(req.params.id, req.body, req.user));
}

export async function disputes(req, res) {
return ok(res, await getDisputes(req.query));
}

export async function disputeDetail(req, res) {
return ok(res, await getDisputeDetail(req.params.id));
}

export async function disputeRuling(req, res) {
return ok(res, await ruleDispute(req.params.id, req.body, req.user));
}

export async function controls(req, res) {
return ok(res, await getControls());
}

export async function platformControl(req, res) {
return ok(res, await updateControl(req.params.key, req.body, req.user));
}

export async function auditLog(req, res) {
return ok(res, await getAuditLog(req.query));
}
8 changes: 8 additions & 0 deletions apps/api/src/middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ export function authMiddleware(req, res, next) {
return fail(res, "Invalid token", 401);
}
}

export function requireAdmin(req, res, next) {
if (req.user?.role !== "admin") {
return fail(res, "Forbidden: admin role required", 403);
}

return next();
}
29 changes: 27 additions & 2 deletions apps/api/src/routes/adminRoutes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
import { Router } from "express";
import { metrics } from "../controllers/adminController.js";
import { authMiddleware } from "../middleware/auth.js";
import {
auditLog,
controls,
disputeDetail,
disputeRuling,
disputes,
metrics,
moderation,
moderationDecision,
platformControl,
userDetail,
userStatus,
users
} from "../controllers/adminController.js";
import { authMiddleware, requireAdmin } from "../middleware/auth.js";

export const adminRoutes = Router();

adminRoutes.use(authMiddleware);
adminRoutes.use(requireAdmin);
adminRoutes.get("/metrics", metrics);
adminRoutes.get("/users", users);
adminRoutes.get("/users/:id", userDetail);
adminRoutes.post("/users/:id/status", userStatus);
adminRoutes.get("/moderation", moderation);
adminRoutes.post("/moderation/:id/decision", moderationDecision);
adminRoutes.get("/disputes", disputes);
adminRoutes.get("/disputes/:id", disputeDetail);
adminRoutes.post("/disputes/:id/ruling", disputeRuling);
adminRoutes.get("/controls", controls);
adminRoutes.post("/controls/:key", platformControl);
adminRoutes.get("/audit", auditLog);
Loading
Loading