auth-core-roles.ts160 lines · main
1/**
2 * briven-engine roles API for yellow Auth dashboard (Phase 6).
3 * Platform operator session required.
4 */
5
6import { Hono } from 'hono';
7
8import { requireAuthCoreDashboard } from '../middleware/auth-core-guard.js';
9import { requireDashboardProjectAdmin } from '../services/auth-core/dashboard-project-auth.js';
10import { BRIVEN_ENGINE_ID, isAuthCoreInitialized } from '../services/auth-core/engine.js';
11import {
12 assignBrivenEngineRole,
13 createBrivenEngineRole,
14 deleteBrivenEngineRole,
15 getBrivenEngineUserRoles,
16 listBrivenEngineRoles,
17 unassignBrivenEngineRole,
18} from '../services/auth-core/roles.js';
19import type { AppEnv } from '../types/app-env.js';
20
21export const authCoreRolesRouter = new Hono<AppEnv>();
22
23authCoreRolesRouter.use('/v1/auth-core/roles', requireAuthCoreDashboard());
24authCoreRolesRouter.use('/v1/auth-core/roles/*', requireAuthCoreDashboard());
25authCoreRolesRouter.use('/v1/auth-core/users/*/roles', requireAuthCoreDashboard());
26
27authCoreRolesRouter.get('/v1/auth-core/roles', async (c) => {
28 if (!isAuthCoreInitialized()) {
29 return c.json(
30 { engine: BRIVEN_ENGINE_ID, roles: [], code: 'auth_core_sdk_not_ready' },
31 503,
32 );
33 }
34 const projectGate = await requireDashboardProjectAdmin(
35 c,
36 c.req.query('projectId'),
37 );
38 if (projectGate instanceof Response) return projectGate;
39 const projectId = projectGate.projectId;
40 const tenantId = c.req.query('tenantId') ?? undefined;
41 return c.json(await listBrivenEngineRoles({ projectId, tenantId }));
42});
43
44authCoreRolesRouter.post('/v1/auth-core/roles', async (c) => {
45 let body: {
46 role?: string;
47 permissions?: string[];
48 projectId?: string;
49 tenantId?: string;
50 } = {};
51 try {
52 body = await c.req.json();
53 } catch {
54 body = {};
55 }
56 if (!body.role) {
57 return c.json({ engine: BRIVEN_ENGINE_ID, code: 'role_required' }, 400);
58 }
59 const projectGate = await requireDashboardProjectAdmin(c, body.projectId);
60 if (projectGate instanceof Response) return projectGate;
61 return c.json(
62 await createBrivenEngineRole(body.role, body.permissions ?? [], {
63 projectId: projectGate.projectId,
64 tenantId: body.tenantId,
65 }),
66 );
67});
68
69authCoreRolesRouter.post('/v1/auth-core/roles/assign', async (c) => {
70 let body: {
71 userId?: string;
72 role?: string;
73 projectId?: string;
74 tenantId?: string;
75 } = {};
76 try {
77 body = await c.req.json();
78 } catch {
79 body = {};
80 }
81 if (!body.userId || !body.role) {
82 return c.json(
83 { engine: BRIVEN_ENGINE_ID, code: 'userId_and_role_required' },
84 400,
85 );
86 }
87 const projectGate = await requireDashboardProjectAdmin(c, body.projectId);
88 if (projectGate instanceof Response) return projectGate;
89 return c.json(
90 await assignBrivenEngineRole(body.userId, body.role, {
91 projectId: projectGate.projectId,
92 tenantId: body.tenantId,
93 }),
94 );
95});
96
97authCoreRolesRouter.post('/v1/auth-core/roles/unassign', async (c) => {
98 let body: {
99 userId?: string;
100 role?: string;
101 projectId?: string;
102 tenantId?: string;
103 } = {};
104 try {
105 body = await c.req.json();
106 } catch {
107 body = {};
108 }
109 if (!body.userId || !body.role) {
110 return c.json(
111 { engine: BRIVEN_ENGINE_ID, code: 'userId_and_role_required' },
112 400,
113 );
114 }
115 const projectGate = await requireDashboardProjectAdmin(c, body.projectId);
116 if (projectGate instanceof Response) return projectGate;
117 return c.json(
118 await unassignBrivenEngineRole(body.userId, body.role, {
119 projectId: projectGate.projectId,
120 tenantId: body.tenantId,
121 }),
122 );
123});
124
125authCoreRolesRouter.delete('/v1/auth-core/roles', async (c) => {
126 let body: { role?: string; projectId?: string; tenantId?: string } = {};
127 try {
128 body = await c.req.json();
129 } catch {
130 body = {};
131 }
132 // Also allow ?role=&projectId=
133 const role = body.role ?? c.req.query('role') ?? undefined;
134 const projectId = body.projectId ?? c.req.query('projectId') ?? undefined;
135 if (!role) {
136 return c.json({ engine: BRIVEN_ENGINE_ID, code: 'role_required' }, 400);
137 }
138 const projectGate = await requireDashboardProjectAdmin(c, projectId);
139 if (projectGate instanceof Response) return projectGate;
140 return c.json(
141 await deleteBrivenEngineRole(role, {
142 projectId: projectGate.projectId,
143 tenantId: body.tenantId ?? c.req.query('tenantId') ?? undefined,
144 }),
145 );
146});
147
148authCoreRolesRouter.get('/v1/auth-core/users/:userId/roles', async (c) => {
149 const projectGate = await requireDashboardProjectAdmin(
150 c,
151 c.req.query('projectId'),
152 );
153 if (projectGate instanceof Response) return projectGate;
154 return c.json(
155 await getBrivenEngineUserRoles(c.req.param('userId'), {
156 projectId: projectGate.projectId,
157 tenantId: c.req.query('tenantId') ?? undefined,
158 }),
159 );
160});