user management
This commit is contained in:
@@ -1,12 +1,119 @@
|
||||
import { permissions } from "@mrp/shared";
|
||||
import { Router } from "express";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ok } from "../../lib/http.js";
|
||||
import { fail, ok } from "../../lib/http.js";
|
||||
import { requirePermissions } from "../../lib/rbac.js";
|
||||
import { getAdminDiagnostics } from "./service.js";
|
||||
import {
|
||||
createAdminRole,
|
||||
createAdminUser,
|
||||
getAdminDiagnostics,
|
||||
listAdminPermissions,
|
||||
listAdminRoles,
|
||||
listAdminUsers,
|
||||
updateAdminRole,
|
||||
updateAdminUser,
|
||||
} from "./service.js";
|
||||
|
||||
export const adminRouter = Router();
|
||||
|
||||
const roleSchema = z.object({
|
||||
name: z.string().trim().min(1).max(120),
|
||||
description: z.string(),
|
||||
permissionKeys: z.array(z.string().trim().min(1)),
|
||||
});
|
||||
|
||||
const userSchema = z.object({
|
||||
email: z.string().email(),
|
||||
firstName: z.string().trim().min(1).max(120),
|
||||
lastName: z.string().trim().min(1).max(120),
|
||||
isActive: z.boolean(),
|
||||
roleIds: z.array(z.string().trim().min(1)),
|
||||
password: z.string().min(8).nullable(),
|
||||
});
|
||||
|
||||
function getRouteParam(value: unknown) {
|
||||
return typeof value === "string" ? value : null;
|
||||
}
|
||||
|
||||
adminRouter.get("/diagnostics", requirePermissions([permissions.adminManage]), async (_request, response) => {
|
||||
return ok(response, await getAdminDiagnostics());
|
||||
});
|
||||
|
||||
adminRouter.get("/permissions", requirePermissions([permissions.adminManage]), async (_request, response) => {
|
||||
return ok(response, await listAdminPermissions());
|
||||
});
|
||||
|
||||
adminRouter.get("/roles", requirePermissions([permissions.adminManage]), async (_request, response) => {
|
||||
return ok(response, await listAdminRoles());
|
||||
});
|
||||
|
||||
adminRouter.post("/roles", requirePermissions([permissions.adminManage]), async (request, response) => {
|
||||
const parsed = roleSchema.safeParse(request.body);
|
||||
if (!parsed.success) {
|
||||
return fail(response, 400, "INVALID_INPUT", "Role payload is invalid.");
|
||||
}
|
||||
|
||||
const result = await createAdminRole(parsed.data, request.authUser?.id);
|
||||
if (!result.ok) {
|
||||
return fail(response, 400, "INVALID_INPUT", result.reason);
|
||||
}
|
||||
|
||||
return ok(response, result.role, 201);
|
||||
});
|
||||
|
||||
adminRouter.put("/roles/:roleId", requirePermissions([permissions.adminManage]), async (request, response) => {
|
||||
const roleId = getRouteParam(request.params.roleId);
|
||||
if (!roleId) {
|
||||
return fail(response, 400, "INVALID_INPUT", "Role id is invalid.");
|
||||
}
|
||||
|
||||
const parsed = roleSchema.safeParse(request.body);
|
||||
if (!parsed.success) {
|
||||
return fail(response, 400, "INVALID_INPUT", "Role payload is invalid.");
|
||||
}
|
||||
|
||||
const result = await updateAdminRole(roleId, parsed.data, request.authUser?.id);
|
||||
if (!result.ok) {
|
||||
return fail(response, 400, "INVALID_INPUT", result.reason);
|
||||
}
|
||||
|
||||
return ok(response, result.role);
|
||||
});
|
||||
|
||||
adminRouter.get("/users", requirePermissions([permissions.adminManage]), async (_request, response) => {
|
||||
return ok(response, await listAdminUsers());
|
||||
});
|
||||
|
||||
adminRouter.post("/users", requirePermissions([permissions.adminManage]), async (request, response) => {
|
||||
const parsed = userSchema.safeParse(request.body);
|
||||
if (!parsed.success) {
|
||||
return fail(response, 400, "INVALID_INPUT", "User payload is invalid.");
|
||||
}
|
||||
|
||||
const result = await createAdminUser(parsed.data, request.authUser?.id);
|
||||
if (!result.ok) {
|
||||
return fail(response, 400, "INVALID_INPUT", result.reason);
|
||||
}
|
||||
|
||||
return ok(response, result.user, 201);
|
||||
});
|
||||
|
||||
adminRouter.put("/users/:userId", requirePermissions([permissions.adminManage]), async (request, response) => {
|
||||
const userId = getRouteParam(request.params.userId);
|
||||
if (!userId) {
|
||||
return fail(response, 400, "INVALID_INPUT", "User id is invalid.");
|
||||
}
|
||||
|
||||
const parsed = userSchema.safeParse(request.body);
|
||||
if (!parsed.success) {
|
||||
return fail(response, 400, "INVALID_INPUT", "User payload is invalid.");
|
||||
}
|
||||
|
||||
const result = await updateAdminUser(userId, parsed.data, request.authUser?.id);
|
||||
if (!result.ok) {
|
||||
return fail(response, 400, "INVALID_INPUT", result.reason);
|
||||
}
|
||||
|
||||
return ok(response, result.user);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user