@seifer-webapp-factory/authorization 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +17 -0
  2. package/backend/templates/cache/ttl-cache.ts +41 -0
  3. package/backend/templates/config/config-fragment.ts +41 -0
  4. package/backend/templates/nestjs/authz.controller.ts +253 -0
  5. package/backend/templates/nestjs/authz.module.ts +158 -0
  6. package/backend/templates/nestjs/tokens.ts +41 -0
  7. package/backend/templates/persistence/migrations/0001_authz.sql +45 -0
  8. package/backend/templates/persistence/migrations/index.ts +84 -0
  9. package/backend/templates/persistence/pg-policy-store.ts +193 -0
  10. package/backend/templates/persistence/seed.ts +60 -0
  11. package/dist/backend/src/index.d.ts +10 -0
  12. package/dist/backend/src/index.d.ts.map +1 -0
  13. package/dist/backend/src/index.js +9 -0
  14. package/dist/backend/src/index.js.map +1 -0
  15. package/dist/backend/src/policy.d.ts +13 -0
  16. package/dist/backend/src/policy.d.ts.map +1 -0
  17. package/dist/backend/src/policy.js +49 -0
  18. package/dist/backend/src/policy.js.map +1 -0
  19. package/dist/backend/src/ports.d.ts +90 -0
  20. package/dist/backend/src/ports.d.ts.map +1 -0
  21. package/dist/backend/src/ports.js +2 -0
  22. package/dist/backend/src/ports.js.map +1 -0
  23. package/dist/backend/src/services.d.ts +81 -0
  24. package/dist/backend/src/services.d.ts.map +1 -0
  25. package/dist/backend/src/services.js +234 -0
  26. package/dist/backend/src/services.js.map +1 -0
  27. package/dist/contract/endpoints.d.ts +433 -0
  28. package/dist/contract/endpoints.d.ts.map +1 -0
  29. package/dist/contract/endpoints.js +57 -0
  30. package/dist/contract/endpoints.js.map +1 -0
  31. package/dist/contract/errors.d.ts +33 -0
  32. package/dist/contract/errors.d.ts.map +1 -0
  33. package/dist/contract/errors.js +51 -0
  34. package/dist/contract/errors.js.map +1 -0
  35. package/dist/contract/events.d.ts +50 -0
  36. package/dist/contract/events.d.ts.map +1 -0
  37. package/dist/contract/events.js +13 -0
  38. package/dist/contract/events.js.map +1 -0
  39. package/dist/contract/index.d.ts +10 -0
  40. package/dist/contract/index.d.ts.map +1 -0
  41. package/dist/contract/index.js +10 -0
  42. package/dist/contract/index.js.map +1 -0
  43. package/dist/contract/permissions.d.ts +35 -0
  44. package/dist/contract/permissions.d.ts.map +1 -0
  45. package/dist/contract/permissions.js +37 -0
  46. package/dist/contract/permissions.js.map +1 -0
  47. package/dist/contract/schemas.d.ts +288 -0
  48. package/dist/contract/schemas.d.ts.map +1 -0
  49. package/dist/contract/schemas.js +91 -0
  50. package/dist/contract/schemas.js.map +1 -0
  51. package/dist/frontend/src/client.d.ts +31 -0
  52. package/dist/frontend/src/client.d.ts.map +1 -0
  53. package/dist/frontend/src/client.js +83 -0
  54. package/dist/frontend/src/client.js.map +1 -0
  55. package/dist/frontend/src/composables.d.ts +62 -0
  56. package/dist/frontend/src/composables.d.ts.map +1 -0
  57. package/dist/frontend/src/composables.js +170 -0
  58. package/dist/frontend/src/composables.js.map +1 -0
  59. package/dist/frontend/src/guards.d.ts +12 -0
  60. package/dist/frontend/src/guards.d.ts.map +1 -0
  61. package/dist/frontend/src/guards.js +10 -0
  62. package/dist/frontend/src/guards.js.map +1 -0
  63. package/dist/frontend/src/index.d.ts +12 -0
  64. package/dist/frontend/src/index.d.ts.map +1 -0
  65. package/dist/frontend/src/index.js +9 -0
  66. package/dist/frontend/src/index.js.map +1 -0
  67. package/dist/manifest.d.ts +56 -0
  68. package/dist/manifest.d.ts.map +1 -0
  69. package/dist/manifest.js +100 -0
  70. package/dist/manifest.js.map +1 -0
  71. package/dist/scaffolder/core/config.d.ts +86 -0
  72. package/dist/scaffolder/core/config.d.ts.map +1 -0
  73. package/dist/scaffolder/core/config.js +92 -0
  74. package/dist/scaffolder/core/config.js.map +1 -0
  75. package/dist/scaffolder/core/errors.d.ts +46 -0
  76. package/dist/scaffolder/core/errors.d.ts.map +1 -0
  77. package/dist/scaffolder/core/errors.js +60 -0
  78. package/dist/scaffolder/core/errors.js.map +1 -0
  79. package/dist/scaffolder/core/extend.d.ts +86 -0
  80. package/dist/scaffolder/core/extend.d.ts.map +1 -0
  81. package/dist/scaffolder/core/extend.js +94 -0
  82. package/dist/scaffolder/core/extend.js.map +1 -0
  83. package/dist/scaffolder/core/materialize.d.ts +71 -0
  84. package/dist/scaffolder/core/materialize.d.ts.map +1 -0
  85. package/dist/scaffolder/core/materialize.js +47 -0
  86. package/dist/scaffolder/core/materialize.js.map +1 -0
  87. package/dist/scaffolder/core/ports.d.ts +39 -0
  88. package/dist/scaffolder/core/ports.d.ts.map +1 -0
  89. package/dist/scaffolder/core/ports.js +33 -0
  90. package/dist/scaffolder/core/ports.js.map +1 -0
  91. package/dist/scaffolder/core/presence.d.ts +34 -0
  92. package/dist/scaffolder/core/presence.d.ts.map +1 -0
  93. package/dist/scaffolder/core/presence.js +29 -0
  94. package/dist/scaffolder/core/presence.js.map +1 -0
  95. package/dist/scaffolder/core/three-way-merge.d.ts +113 -0
  96. package/dist/scaffolder/core/three-way-merge.d.ts.map +1 -0
  97. package/dist/scaffolder/core/three-way-merge.js +184 -0
  98. package/dist/scaffolder/core/three-way-merge.js.map +1 -0
  99. package/dist/scaffolder/index.d.ts +25 -0
  100. package/dist/scaffolder/index.d.ts.map +1 -0
  101. package/dist/scaffolder/index.js +24 -0
  102. package/dist/scaffolder/index.js.map +1 -0
  103. package/frontend/templates/components/PermissionMatrix.vue +134 -0
  104. package/frontend/templates/i18n/en.json +61 -0
  105. package/frontend/templates/i18n/nl.json +61 -0
  106. package/frontend/templates/middleware/permission.ts +54 -0
  107. package/frontend/templates/pages/access-assignments.vue +151 -0
  108. package/frontend/templates/pages/role-editor.vue +169 -0
  109. package/frontend/templates/pages/roles-list.vue +84 -0
  110. package/frontend/templates/plugins/authz.client.ts +108 -0
  111. package/frontend/templates/runtime.ts +60 -0
  112. package/package.json +76 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Backend mechanisme (pinned dependency) — flow-services die de `access-control`-kit orkestreren.
3
+ * Puur: geen HTTP, geen SQL van zichzelf; poorten via injectie; events geëmit. Ze voegen GEEN nieuw
4
+ * mechanisme toe — RBAC-resolutie/cyclusdetectie/ReBAC/PDP komen uit de kit.
5
+ *
6
+ * Stories: US-Z0201/0202/0203 (rollen), US-Z0301/0302/0303 (toewijzing), US-Z0401/0402 (resolutie),
7
+ * US-Z0403 (PDP), US-Z0501/0502 (ReBAC).
8
+ */
9
+ import { RebacChecker } from '@seifer-webapp-factory/kits/backend/access-control';
10
+ import { AuthzError, AUTHZ_MANAGE, } from '../../contract/index.js';
11
+ import { effectivePermissions } from './policy.js';
12
+ const toRole = (r) => ({
13
+ id: r.id, key: r.key, name: r.name, permissions: r.permissions, parentRoleId: r.parentRoleId,
14
+ });
15
+ /** US-Z0201/0202/0203 — rollenbeheer (CRUD + hiërarchie + catalogus-sync). */
16
+ export class RoleService {
17
+ #store;
18
+ #catalogKeys;
19
+ #events;
20
+ #clock;
21
+ constructor(deps) {
22
+ this.#store = deps.store;
23
+ this.#catalogKeys = new Set(deps.catalog.map((p) => p.key));
24
+ this.#events = deps.events;
25
+ this.#clock = deps.clock;
26
+ }
27
+ async list() {
28
+ return (await this.#store.listRoles()).map(toRole);
29
+ }
30
+ async create(actor, input) {
31
+ this.#assertKnownPermissions(input.permissions);
32
+ this.#assertNoEscalation(actor, input.permissions);
33
+ if (input.parentRoleId !== null && (await this.#store.getRole(input.parentRoleId)) === null) {
34
+ throw new AuthzError('role_not_found', 'onbekende bovenliggende rol');
35
+ }
36
+ const created = await this.#store.createRole(input);
37
+ // Rebuild om een cyclus (via de nieuwe rol) fail-fast te detecteren; rollback bij een cyclus.
38
+ try {
39
+ effectivePermissions(await this.#store.listRoles(), [created.key]);
40
+ }
41
+ catch (error) {
42
+ await this.#store.deleteRole(created.id);
43
+ throw error;
44
+ }
45
+ this.#events.emit({
46
+ name: 'role.created', occurredAt: this.#iso(), actorId: actor.id, roleId: created.id, roleKey: created.key,
47
+ });
48
+ return toRole(created);
49
+ }
50
+ async update(actor, id, patch) {
51
+ const existing = await this.#store.getRole(id);
52
+ if (existing === null)
53
+ throw new AuthzError('role_not_found');
54
+ if (patch.permissions !== undefined) {
55
+ this.#assertKnownPermissions(patch.permissions);
56
+ this.#assertNoEscalation(actor, patch.permissions);
57
+ }
58
+ // Valideer de kandidaat-hiërarchie in-memory vóór persisteren (cyclus → role_cycle).
59
+ const candidate = (await this.#store.listRoles()).map((r) => r.id === id ? { ...r, ...this.#applied(r, patch) } : r);
60
+ effectivePermissions(candidate, [existing.key]);
61
+ const updated = await this.#store.updateRole(id, patch);
62
+ this.#events.emit({ name: 'role.updated', occurredAt: this.#iso(), actorId: actor.id, roleId: id });
63
+ return toRole(updated);
64
+ }
65
+ async remove(actor, id) {
66
+ if ((await this.#store.getRole(id)) === null)
67
+ throw new AuthzError('role_not_found');
68
+ await this.#store.deleteRole(id);
69
+ this.#events.emit({ name: 'role.deleted', occurredAt: this.#iso(), actorId: actor.id, roleId: id });
70
+ }
71
+ /** US-Z0203 — de code-declared catalogus is de bron; management vereist `authz.manage` (surface-guard). */
72
+ permissions() {
73
+ return [...this.#catalogKeys].map((key) => ({ key, description: key }));
74
+ }
75
+ #applied(role, patch) {
76
+ return {
77
+ name: patch.name ?? role.name,
78
+ permissions: patch.permissions ?? role.permissions,
79
+ parentRoleId: patch.parentRoleId === undefined ? role.parentRoleId : patch.parentRoleId,
80
+ };
81
+ }
82
+ #assertKnownPermissions(permissions) {
83
+ for (const p of permissions) {
84
+ if (!this.#catalogKeys.has(p))
85
+ throw new AuthzError('permission_unknown', 'onbekende permissie', { permissions: [p] });
86
+ }
87
+ }
88
+ /** US-Z0302 — een actor kan geen permissie toekennen die zij zelf niet bezit. */
89
+ #assertNoEscalation(actor, permissions) {
90
+ for (const p of permissions) {
91
+ if (!actor.permissions.has(p))
92
+ throw new AuthzError('escalation_denied', 'permissie boven eigen niveau');
93
+ }
94
+ }
95
+ #iso() {
96
+ return this.#clock.now().toISOString();
97
+ }
98
+ }
99
+ /** US-Z0301/0302/0303 — rol-toewijzing met escalation- en self-lockout-guards. */
100
+ export class AssignmentService {
101
+ #store;
102
+ #cache;
103
+ #events;
104
+ #clock;
105
+ constructor(deps) {
106
+ this.#store = deps.store;
107
+ this.#cache = deps.cache;
108
+ this.#events = deps.events;
109
+ this.#clock = deps.clock;
110
+ }
111
+ async subjectRoles(subjectId) {
112
+ return (await this.#store.rolesForSubject(subjectId)).map(toRole);
113
+ }
114
+ async assign(actor, subjectId, roleId) {
115
+ const role = await this.#store.getRole(roleId);
116
+ if (role === null)
117
+ throw new AuthzError('role_not_found');
118
+ // US-Z0302: geen rol toekennen waarvan de effectieve permissies het eigen niveau overstijgen.
119
+ const rolePerms = effectivePermissions(await this.#store.listRoles(), [role.key]);
120
+ for (const p of rolePerms) {
121
+ if (!actor.permissions.has(p))
122
+ throw new AuthzError('escalation_denied', 'rol boven eigen niveau');
123
+ }
124
+ const assigned = await this.#store.assignRole(subjectId, roleId);
125
+ if (!assigned)
126
+ throw new AuthzError('assignment_exists');
127
+ await this.#cache.invalidate(subjectId);
128
+ this.#events.emit({ name: 'role.assigned', occurredAt: this.#iso(), actorId: actor.id, subjectId, roleId });
129
+ }
130
+ async revoke(actor, subjectId, roleId) {
131
+ const role = await this.#store.getRole(roleId);
132
+ if (role === null)
133
+ throw new AuthzError('role_not_found');
134
+ await this.#assertNoSelfLockout(actor, subjectId, role);
135
+ await this.#store.revokeRole(subjectId, roleId); // idempotent: geen fout als er niets was
136
+ await this.#cache.invalidate(subjectId);
137
+ this.#events.emit({ name: 'role.revoked', occurredAt: this.#iso(), actorId: actor.id, subjectId, roleId });
138
+ }
139
+ /** US-Z0303 — een actor mag zichzelf niet de laatste `authz.manage`-rol ontnemen. */
140
+ async #assertNoSelfLockout(actor, subjectId, role) {
141
+ if (subjectId !== actor.id)
142
+ return;
143
+ const allRoles = await this.#store.listRoles();
144
+ if (!effectivePermissions(allRoles, [role.key]).has(AUTHZ_MANAGE))
145
+ return;
146
+ const remaining = (await this.#store.rolesForSubject(subjectId)).filter((r) => r.id !== role.id);
147
+ const stillManages = effectivePermissions(allRoles, remaining.map((r) => r.key)).has(AUTHZ_MANAGE);
148
+ if (!stillManages)
149
+ throw new AuthzError('self_lockout', 'laatste beheer-rol niet intrekbaar');
150
+ }
151
+ #iso() {
152
+ return this.#clock.now().toISOString();
153
+ }
154
+ }
155
+ /** US-Z0401/0402 — resolveert een subject naar effectieve permissies, met cache + invalidatie. */
156
+ export class PermissionResolver {
157
+ #store;
158
+ #cache;
159
+ constructor(deps) {
160
+ this.#store = deps.store;
161
+ this.#cache = deps.cache;
162
+ }
163
+ async resolve(subjectId) {
164
+ const cached = await this.#cache.get(subjectId);
165
+ if (cached !== null)
166
+ return cached;
167
+ const [roles, allRoles] = await Promise.all([this.#store.rolesForSubject(subjectId), this.#store.listRoles()]);
168
+ const roleKeys = roles.map((r) => r.key);
169
+ const permissions = [...effectivePermissions(allRoles, roleKeys)];
170
+ const result = { subjectId, roleKeys, permissions };
171
+ await this.#cache.set(subjectId, result);
172
+ return result;
173
+ }
174
+ async has(subjectId, permission) {
175
+ return (await this.resolve(subjectId)).permissions.includes(permission);
176
+ }
177
+ }
178
+ /** Adapter: overbrugt de PolicyStore-relaties naar de kit-`RelationResolver` (US-Z0502). */
179
+ class StoreRelationResolver {
180
+ store;
181
+ constructor(store) {
182
+ this.store = store;
183
+ }
184
+ relationsFrom(node) {
185
+ return this.store.relationsFrom(node);
186
+ }
187
+ }
188
+ /** US-Z0403 — Policy Decision Point: default-deny beslissing + veilige reden voor /authz/check. */
189
+ export class AuthorizationPdp {
190
+ #resolver;
191
+ #rebac;
192
+ constructor(deps) {
193
+ this.#resolver = deps.resolver;
194
+ this.#rebac = deps.rebacEnabled ? new RebacChecker(new StoreRelationResolver(deps.store)) : null;
195
+ }
196
+ async check(subjectId, request) {
197
+ // RBAC-vorm: heeft het subject de permissie? Default-deny.
198
+ if (request.permission !== undefined) {
199
+ const allowed = await this.#resolver.has(subjectId, request.permission);
200
+ return { allowed, reason: allowed ? 'toegestaan' : 'geweigerd' };
201
+ }
202
+ // PDP/ReBAC-vorm: ownership tegen een resource (alleen als ReBAC aan staat).
203
+ if (request.action !== undefined) {
204
+ if (this.#rebac === null || request.resource === undefined) {
205
+ return { allowed: false, reason: 'geweigerd' };
206
+ }
207
+ const result = await this.#rebac.check(subjectId, request.resource.id, { relations: ['owner'] });
208
+ return { allowed: result.allowed, reason: result.allowed ? 'toegestaan' : 'geweigerd' };
209
+ }
210
+ return { allowed: false, reason: 'geweigerd' };
211
+ }
212
+ }
213
+ /** US-Z0501 — ReBAC-relatietuples schrijven/verwijderen (achter config-toggle). */
214
+ export class RelationService {
215
+ #store;
216
+ #enabled;
217
+ constructor(deps) {
218
+ this.#store = deps.store;
219
+ this.#enabled = deps.rebacEnabled;
220
+ }
221
+ async write(relation) {
222
+ this.#assertEnabled();
223
+ await this.#store.writeRelation(relation);
224
+ }
225
+ async remove(relation) {
226
+ this.#assertEnabled();
227
+ await this.#store.removeRelation(relation);
228
+ }
229
+ #assertEnabled() {
230
+ if (!this.#enabled)
231
+ throw new AuthzError('invalid_relation', 'ReBAC staat uit');
232
+ }
233
+ }
234
+ //# sourceMappingURL=services.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../../backend/src/services.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,433 @@
1
+ import type { z } from 'zod';
2
+ import type { AuthzErrorCode } from './errors.js';
3
+ /**
4
+ * US-Z0101/Z0104/Z0105 — de machine-leesbare endpoint-catalogus (12 endpoints). Backend leidt hier
5
+ * route + validatie + vereiste permissie uit af; frontend leidt hier zijn getypte client uit af. Eén
6
+ * bron, geen drift. `backendRoutes` in de manifest wordt hieruit afgeleid (US-Z0801).
7
+ */
8
+ export interface EndpointDescriptor<Req extends z.ZodTypeAny | null, Res extends z.ZodTypeAny> {
9
+ readonly method: 'POST' | 'GET' | 'PATCH' | 'DELETE';
10
+ readonly path: string;
11
+ readonly request: Req;
12
+ readonly response: Res;
13
+ /** Foutcodes die dit endpoint kan retourneren (uit de gedeelde taxonomie). */
14
+ readonly errors: readonly AuthzErrorCode[];
15
+ /** Vereist een geauthenticeerde sessie (het `Subject` uit de authentication-module). */
16
+ readonly auth: boolean;
17
+ /**
18
+ * Permissie die het huidige subject moet bezitten om dit endpoint aan te roepen. Beheer-endpoints
19
+ * vereisen `authz.manage` (no-catalog-leak, US-Z0703); `null` = geen extra permissie boven `auth`.
20
+ */
21
+ readonly requiredPermission: string | null;
22
+ }
23
+ export declare const AUTHZ_ENDPOINTS: {
24
+ readonly listRoles: {
25
+ readonly method: "GET";
26
+ readonly path: "/authz/roles";
27
+ readonly request: null;
28
+ readonly response: z.ZodObject<{
29
+ roles: z.ZodArray<z.ZodObject<{
30
+ id: z.ZodString;
31
+ key: z.ZodString;
32
+ name: z.ZodString;
33
+ permissions: z.ZodArray<z.ZodString, "many">;
34
+ parentRoleId: z.ZodNullable<z.ZodString>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ id: string;
37
+ key: string;
38
+ name: string;
39
+ permissions: string[];
40
+ parentRoleId: string | null;
41
+ }, {
42
+ id: string;
43
+ key: string;
44
+ name: string;
45
+ permissions: string[];
46
+ parentRoleId: string | null;
47
+ }>, "many">;
48
+ }, "strip", z.ZodTypeAny, {
49
+ roles: {
50
+ id: string;
51
+ key: string;
52
+ name: string;
53
+ permissions: string[];
54
+ parentRoleId: string | null;
55
+ }[];
56
+ }, {
57
+ roles: {
58
+ id: string;
59
+ key: string;
60
+ name: string;
61
+ permissions: string[];
62
+ parentRoleId: string | null;
63
+ }[];
64
+ }>;
65
+ readonly errors: readonly ["forbidden", "unauthenticated"];
66
+ readonly auth: true;
67
+ readonly requiredPermission: "authz.manage";
68
+ };
69
+ readonly createRole: {
70
+ readonly method: "POST";
71
+ readonly path: "/authz/roles";
72
+ readonly request: z.ZodObject<{
73
+ key: z.ZodString;
74
+ name: z.ZodString;
75
+ permissions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
76
+ parentRoleId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ key: string;
79
+ name: string;
80
+ permissions: string[];
81
+ parentRoleId: string | null;
82
+ }, {
83
+ key: string;
84
+ name: string;
85
+ permissions?: string[] | undefined;
86
+ parentRoleId?: string | null | undefined;
87
+ }>;
88
+ readonly response: z.ZodObject<{
89
+ id: z.ZodString;
90
+ key: z.ZodString;
91
+ name: z.ZodString;
92
+ permissions: z.ZodArray<z.ZodString, "many">;
93
+ parentRoleId: z.ZodNullable<z.ZodString>;
94
+ }, "strip", z.ZodTypeAny, {
95
+ id: string;
96
+ key: string;
97
+ name: string;
98
+ permissions: string[];
99
+ parentRoleId: string | null;
100
+ }, {
101
+ id: string;
102
+ key: string;
103
+ name: string;
104
+ permissions: string[];
105
+ parentRoleId: string | null;
106
+ }>;
107
+ readonly errors: readonly ["forbidden", "unauthenticated", "permission_unknown", "role_cycle", "escalation_denied", "validation_failed"];
108
+ readonly auth: true;
109
+ readonly requiredPermission: "authz.manage";
110
+ };
111
+ readonly updateRole: {
112
+ readonly method: "PATCH";
113
+ readonly path: "/authz/roles/:id";
114
+ readonly request: z.ZodObject<{
115
+ name: z.ZodOptional<z.ZodString>;
116
+ permissions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
117
+ parentRoleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
+ }, "strip", z.ZodTypeAny, {
119
+ name?: string | undefined;
120
+ permissions?: string[] | undefined;
121
+ parentRoleId?: string | null | undefined;
122
+ }, {
123
+ name?: string | undefined;
124
+ permissions?: string[] | undefined;
125
+ parentRoleId?: string | null | undefined;
126
+ }>;
127
+ readonly response: z.ZodObject<{
128
+ id: z.ZodString;
129
+ key: z.ZodString;
130
+ name: z.ZodString;
131
+ permissions: z.ZodArray<z.ZodString, "many">;
132
+ parentRoleId: z.ZodNullable<z.ZodString>;
133
+ }, "strip", z.ZodTypeAny, {
134
+ id: string;
135
+ key: string;
136
+ name: string;
137
+ permissions: string[];
138
+ parentRoleId: string | null;
139
+ }, {
140
+ id: string;
141
+ key: string;
142
+ name: string;
143
+ permissions: string[];
144
+ parentRoleId: string | null;
145
+ }>;
146
+ readonly errors: readonly ["forbidden", "unauthenticated", "role_not_found", "permission_unknown", "role_cycle", "escalation_denied", "validation_failed"];
147
+ readonly auth: true;
148
+ readonly requiredPermission: "authz.manage";
149
+ };
150
+ readonly deleteRole: {
151
+ readonly method: "DELETE";
152
+ readonly path: "/authz/roles/:id";
153
+ readonly request: null;
154
+ readonly response: z.ZodObject<{
155
+ ok: z.ZodLiteral<true>;
156
+ }, "strip", z.ZodTypeAny, {
157
+ ok: true;
158
+ }, {
159
+ ok: true;
160
+ }>;
161
+ readonly errors: readonly ["forbidden", "unauthenticated", "role_not_found"];
162
+ readonly auth: true;
163
+ readonly requiredPermission: "authz.manage";
164
+ };
165
+ readonly listPermissions: {
166
+ readonly method: "GET";
167
+ readonly path: "/authz/permissions";
168
+ readonly request: null;
169
+ readonly response: z.ZodObject<{
170
+ permissions: z.ZodArray<z.ZodObject<{
171
+ key: z.ZodString;
172
+ description: z.ZodString;
173
+ }, "strip", z.ZodTypeAny, {
174
+ key: string;
175
+ description: string;
176
+ }, {
177
+ key: string;
178
+ description: string;
179
+ }>, "many">;
180
+ }, "strip", z.ZodTypeAny, {
181
+ permissions: {
182
+ key: string;
183
+ description: string;
184
+ }[];
185
+ }, {
186
+ permissions: {
187
+ key: string;
188
+ description: string;
189
+ }[];
190
+ }>;
191
+ readonly errors: readonly ["forbidden", "unauthenticated"];
192
+ readonly auth: true;
193
+ readonly requiredPermission: "authz.manage";
194
+ };
195
+ readonly subjectRoles: {
196
+ readonly method: "GET";
197
+ readonly path: "/authz/subjects/:id/roles";
198
+ readonly request: null;
199
+ readonly response: z.ZodObject<{
200
+ subjectId: z.ZodString;
201
+ roles: z.ZodArray<z.ZodObject<{
202
+ id: z.ZodString;
203
+ key: z.ZodString;
204
+ name: z.ZodString;
205
+ permissions: z.ZodArray<z.ZodString, "many">;
206
+ parentRoleId: z.ZodNullable<z.ZodString>;
207
+ }, "strip", z.ZodTypeAny, {
208
+ id: string;
209
+ key: string;
210
+ name: string;
211
+ permissions: string[];
212
+ parentRoleId: string | null;
213
+ }, {
214
+ id: string;
215
+ key: string;
216
+ name: string;
217
+ permissions: string[];
218
+ parentRoleId: string | null;
219
+ }>, "many">;
220
+ }, "strip", z.ZodTypeAny, {
221
+ roles: {
222
+ id: string;
223
+ key: string;
224
+ name: string;
225
+ permissions: string[];
226
+ parentRoleId: string | null;
227
+ }[];
228
+ subjectId: string;
229
+ }, {
230
+ roles: {
231
+ id: string;
232
+ key: string;
233
+ name: string;
234
+ permissions: string[];
235
+ parentRoleId: string | null;
236
+ }[];
237
+ subjectId: string;
238
+ }>;
239
+ readonly errors: readonly ["forbidden", "unauthenticated"];
240
+ readonly auth: true;
241
+ readonly requiredPermission: "authz.manage";
242
+ };
243
+ readonly assignRole: {
244
+ readonly method: "POST";
245
+ readonly path: "/authz/assignments";
246
+ readonly request: z.ZodObject<{
247
+ subjectId: z.ZodString;
248
+ roleId: z.ZodString;
249
+ }, "strip", z.ZodTypeAny, {
250
+ subjectId: string;
251
+ roleId: string;
252
+ }, {
253
+ subjectId: string;
254
+ roleId: string;
255
+ }>;
256
+ readonly response: z.ZodObject<{
257
+ ok: z.ZodLiteral<true>;
258
+ }, "strip", z.ZodTypeAny, {
259
+ ok: true;
260
+ }, {
261
+ ok: true;
262
+ }>;
263
+ readonly errors: readonly ["forbidden", "unauthenticated", "role_not_found", "assignment_exists", "escalation_denied"];
264
+ readonly auth: true;
265
+ readonly requiredPermission: "authz.manage";
266
+ };
267
+ readonly revokeRole: {
268
+ readonly method: "DELETE";
269
+ readonly path: "/authz/assignments";
270
+ readonly request: z.ZodObject<{
271
+ subjectId: z.ZodString;
272
+ roleId: z.ZodString;
273
+ }, "strip", z.ZodTypeAny, {
274
+ subjectId: string;
275
+ roleId: string;
276
+ }, {
277
+ subjectId: string;
278
+ roleId: string;
279
+ }>;
280
+ readonly response: z.ZodObject<{
281
+ ok: z.ZodLiteral<true>;
282
+ }, "strip", z.ZodTypeAny, {
283
+ ok: true;
284
+ }, {
285
+ ok: true;
286
+ }>;
287
+ readonly errors: readonly ["forbidden", "unauthenticated", "role_not_found", "self_lockout"];
288
+ readonly auth: true;
289
+ readonly requiredPermission: "authz.manage";
290
+ };
291
+ readonly mePermissions: {
292
+ readonly method: "GET";
293
+ readonly path: "/authz/me/permissions";
294
+ readonly request: null;
295
+ readonly response: z.ZodObject<{
296
+ subjectId: z.ZodString;
297
+ roles: z.ZodArray<z.ZodString, "many">;
298
+ permissions: z.ZodArray<z.ZodString, "many">;
299
+ }, "strip", z.ZodTypeAny, {
300
+ permissions: string[];
301
+ roles: string[];
302
+ subjectId: string;
303
+ }, {
304
+ permissions: string[];
305
+ roles: string[];
306
+ subjectId: string;
307
+ }>;
308
+ readonly errors: readonly ["unauthenticated"];
309
+ readonly auth: true;
310
+ readonly requiredPermission: null;
311
+ };
312
+ readonly check: {
313
+ readonly method: "POST";
314
+ readonly path: "/authz/check";
315
+ readonly request: z.ZodEffects<z.ZodObject<{
316
+ permission: z.ZodOptional<z.ZodString>;
317
+ action: z.ZodOptional<z.ZodString>;
318
+ resource: z.ZodOptional<z.ZodObject<{
319
+ id: z.ZodString;
320
+ type: z.ZodOptional<z.ZodString>;
321
+ }, "strip", z.ZodTypeAny, {
322
+ id: string;
323
+ type?: string | undefined;
324
+ }, {
325
+ id: string;
326
+ type?: string | undefined;
327
+ }>>;
328
+ }, "strip", z.ZodTypeAny, {
329
+ permission?: string | undefined;
330
+ action?: string | undefined;
331
+ resource?: {
332
+ id: string;
333
+ type?: string | undefined;
334
+ } | undefined;
335
+ }, {
336
+ permission?: string | undefined;
337
+ action?: string | undefined;
338
+ resource?: {
339
+ id: string;
340
+ type?: string | undefined;
341
+ } | undefined;
342
+ }>, {
343
+ permission?: string | undefined;
344
+ action?: string | undefined;
345
+ resource?: {
346
+ id: string;
347
+ type?: string | undefined;
348
+ } | undefined;
349
+ }, {
350
+ permission?: string | undefined;
351
+ action?: string | undefined;
352
+ resource?: {
353
+ id: string;
354
+ type?: string | undefined;
355
+ } | undefined;
356
+ }>;
357
+ readonly response: z.ZodObject<{
358
+ allowed: z.ZodBoolean;
359
+ reason: z.ZodString;
360
+ }, "strip", z.ZodTypeAny, {
361
+ allowed: boolean;
362
+ reason: string;
363
+ }, {
364
+ allowed: boolean;
365
+ reason: string;
366
+ }>;
367
+ readonly errors: readonly ["unauthenticated", "validation_failed"];
368
+ readonly auth: true;
369
+ readonly requiredPermission: null;
370
+ };
371
+ readonly writeRelation: {
372
+ readonly method: "POST";
373
+ readonly path: "/authz/relations";
374
+ readonly request: z.ZodObject<{
375
+ subjectId: z.ZodString;
376
+ relation: z.ZodString;
377
+ objectType: z.ZodString;
378
+ objectId: z.ZodString;
379
+ }, "strip", z.ZodTypeAny, {
380
+ subjectId: string;
381
+ relation: string;
382
+ objectType: string;
383
+ objectId: string;
384
+ }, {
385
+ subjectId: string;
386
+ relation: string;
387
+ objectType: string;
388
+ objectId: string;
389
+ }>;
390
+ readonly response: z.ZodObject<{
391
+ ok: z.ZodLiteral<true>;
392
+ }, "strip", z.ZodTypeAny, {
393
+ ok: true;
394
+ }, {
395
+ ok: true;
396
+ }>;
397
+ readonly errors: readonly ["forbidden", "unauthenticated", "invalid_relation"];
398
+ readonly auth: true;
399
+ readonly requiredPermission: "authz.manage";
400
+ };
401
+ readonly removeRelation: {
402
+ readonly method: "DELETE";
403
+ readonly path: "/authz/relations";
404
+ readonly request: z.ZodObject<{
405
+ subjectId: z.ZodString;
406
+ relation: z.ZodString;
407
+ objectType: z.ZodString;
408
+ objectId: z.ZodString;
409
+ }, "strip", z.ZodTypeAny, {
410
+ subjectId: string;
411
+ relation: string;
412
+ objectType: string;
413
+ objectId: string;
414
+ }, {
415
+ subjectId: string;
416
+ relation: string;
417
+ objectType: string;
418
+ objectId: string;
419
+ }>;
420
+ readonly response: z.ZodObject<{
421
+ ok: z.ZodLiteral<true>;
422
+ }, "strip", z.ZodTypeAny, {
423
+ ok: true;
424
+ }, {
425
+ ok: true;
426
+ }>;
427
+ readonly errors: readonly ["forbidden", "unauthenticated", "invalid_relation"];
428
+ readonly auth: true;
429
+ readonly requiredPermission: "authz.manage";
430
+ };
431
+ };
432
+ export type AuthzEndpointName = keyof typeof AUTHZ_ENDPOINTS;
433
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../contract/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAe7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CACjC,GAAG,SAAS,CAAC,CAAC,UAAU,GAAG,IAAI,EAC/B,GAAG,SAAS,CAAC,CAAC,UAAU;IAExB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5C;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqD8D,CAAC;AAE3F,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC"}