@spinajs/authz-http-admin 3.0.13 → 3.0.15

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 (188) hide show
  1. package/README.md +9 -8
  2. package/lib/cjs/controllers/AuthzAdminController.d.ts +35 -29
  3. package/lib/cjs/controllers/AuthzAdminController.d.ts.map +1 -1
  4. package/lib/cjs/controllers/AuthzAdminController.js +172 -175
  5. package/lib/cjs/controllers/AuthzAdminController.js.map +1 -1
  6. package/lib/cjs/dto/assignments.d.ts +33 -0
  7. package/lib/cjs/dto/assignments.d.ts.map +1 -0
  8. package/lib/cjs/dto/assignments.js +39 -0
  9. package/lib/cjs/dto/assignments.js.map +1 -0
  10. package/lib/cjs/dto/attributes.d.ts +20 -0
  11. package/lib/cjs/dto/attributes.d.ts.map +1 -0
  12. package/lib/cjs/dto/attributes.js +29 -0
  13. package/lib/cjs/dto/attributes.js.map +1 -0
  14. package/lib/cjs/dto/batch.d.ts +11 -0
  15. package/lib/cjs/dto/batch.d.ts.map +1 -0
  16. package/lib/cjs/dto/batch.js +10 -0
  17. package/lib/cjs/dto/batch.js.map +1 -0
  18. package/lib/cjs/dto/index.d.ts +9 -0
  19. package/lib/cjs/dto/index.d.ts.map +1 -0
  20. package/lib/cjs/dto/index.js +25 -0
  21. package/lib/cjs/dto/index.js.map +1 -0
  22. package/lib/cjs/dto/input.d.ts +8 -0
  23. package/lib/cjs/dto/input.d.ts.map +1 -0
  24. package/lib/cjs/dto/input.js +19 -0
  25. package/lib/cjs/dto/input.js.map +1 -0
  26. package/lib/cjs/dto/links.d.ts +28 -0
  27. package/lib/cjs/dto/links.d.ts.map +1 -0
  28. package/lib/cjs/dto/links.js +40 -0
  29. package/lib/cjs/dto/links.js.map +1 -0
  30. package/lib/cjs/dto/params.d.ts +19 -0
  31. package/lib/cjs/dto/params.d.ts.map +1 -0
  32. package/lib/cjs/dto/params.js +9 -0
  33. package/lib/cjs/dto/params.js.map +1 -0
  34. package/lib/cjs/dto/queries.d.ts +37 -0
  35. package/lib/cjs/dto/queries.d.ts.map +1 -0
  36. package/lib/cjs/dto/queries.js +70 -0
  37. package/lib/cjs/dto/queries.js.map +1 -0
  38. package/lib/cjs/dto/rules.d.ts +18 -0
  39. package/lib/cjs/dto/rules.d.ts.map +1 -0
  40. package/lib/cjs/dto/rules.js +34 -0
  41. package/lib/cjs/dto/rules.js.map +1 -0
  42. package/lib/cjs/index.d.ts +1 -0
  43. package/lib/cjs/index.d.ts.map +1 -1
  44. package/lib/cjs/index.js +1 -0
  45. package/lib/cjs/index.js.map +1 -1
  46. package/lib/cjs/routes/answers.d.ts +22 -0
  47. package/lib/cjs/routes/answers.d.ts.map +1 -0
  48. package/lib/cjs/routes/answers.js +121 -0
  49. package/lib/cjs/routes/answers.js.map +1 -0
  50. package/lib/cjs/routes/args.d.ts +59 -0
  51. package/lib/cjs/routes/args.d.ts.map +1 -0
  52. package/lib/cjs/routes/args.js +167 -0
  53. package/lib/cjs/routes/args.js.map +1 -0
  54. package/lib/cjs/routes/index.d.ts +3 -0
  55. package/lib/cjs/routes/index.d.ts.map +1 -1
  56. package/lib/cjs/routes/index.js +3 -0
  57. package/lib/cjs/routes/index.js.map +1 -1
  58. package/lib/cjs/routes/no-store.d.ts +10 -0
  59. package/lib/cjs/routes/no-store.d.ts.map +1 -0
  60. package/lib/cjs/routes/no-store.js +18 -0
  61. package/lib/cjs/routes/no-store.js.map +1 -0
  62. package/lib/cjs/routes/query.d.ts +6 -7
  63. package/lib/cjs/routes/query.d.ts.map +1 -1
  64. package/lib/cjs/routes/query.js +15 -62
  65. package/lib/cjs/routes/query.js.map +1 -1
  66. package/lib/cjs/schemas/answers.d.ts +7 -0
  67. package/lib/cjs/schemas/answers.d.ts.map +1 -0
  68. package/lib/cjs/schemas/answers.js +14 -0
  69. package/lib/cjs/schemas/answers.js.map +1 -0
  70. package/lib/cjs/schemas/commands.d.ts +4 -0
  71. package/lib/cjs/schemas/commands.d.ts.map +1 -1
  72. package/lib/cjs/schemas/commands.js +20 -12
  73. package/lib/cjs/schemas/commands.js.map +1 -1
  74. package/lib/cjs/schemas/document.d.ts +8 -17
  75. package/lib/cjs/schemas/document.d.ts.map +1 -1
  76. package/lib/cjs/schemas/document.js +53 -64
  77. package/lib/cjs/schemas/document.js.map +1 -1
  78. package/lib/cjs/schemas/index.d.ts +1 -1
  79. package/lib/cjs/schemas/index.d.ts.map +1 -1
  80. package/lib/cjs/schemas/index.js +1 -1
  81. package/lib/cjs/schemas/index.js.map +1 -1
  82. package/lib/cjs/schemas/primitives.d.ts +8 -1
  83. package/lib/cjs/schemas/primitives.d.ts.map +1 -1
  84. package/lib/cjs/schemas/primitives.js +25 -15
  85. package/lib/cjs/schemas/primitives.js.map +1 -1
  86. package/lib/cjs/schemas/provider.d.ts +4 -4
  87. package/lib/cjs/schemas/provider.d.ts.map +1 -1
  88. package/lib/cjs/schemas/provider.js +6 -6
  89. package/lib/cjs/schemas/provider.js.map +1 -1
  90. package/lib/mjs/controllers/AuthzAdminController.d.ts +35 -29
  91. package/lib/mjs/controllers/AuthzAdminController.d.ts.map +1 -1
  92. package/lib/mjs/controllers/AuthzAdminController.js +174 -177
  93. package/lib/mjs/controllers/AuthzAdminController.js.map +1 -1
  94. package/lib/mjs/dto/assignments.d.ts +33 -0
  95. package/lib/mjs/dto/assignments.d.ts.map +1 -0
  96. package/lib/mjs/dto/assignments.js +36 -0
  97. package/lib/mjs/dto/assignments.js.map +1 -0
  98. package/lib/mjs/dto/attributes.d.ts +20 -0
  99. package/lib/mjs/dto/attributes.d.ts.map +1 -0
  100. package/lib/mjs/dto/attributes.js +26 -0
  101. package/lib/mjs/dto/attributes.js.map +1 -0
  102. package/lib/mjs/dto/batch.d.ts +11 -0
  103. package/lib/mjs/dto/batch.d.ts.map +1 -0
  104. package/lib/mjs/dto/batch.js +7 -0
  105. package/lib/mjs/dto/batch.js.map +1 -0
  106. package/lib/mjs/dto/index.d.ts +9 -0
  107. package/lib/mjs/dto/index.d.ts.map +1 -0
  108. package/lib/mjs/dto/index.js +9 -0
  109. package/lib/mjs/dto/index.js.map +1 -0
  110. package/lib/mjs/dto/input.d.ts +8 -0
  111. package/lib/mjs/dto/input.d.ts.map +1 -0
  112. package/lib/mjs/dto/input.js +15 -0
  113. package/lib/mjs/dto/input.js.map +1 -0
  114. package/lib/mjs/dto/links.d.ts +28 -0
  115. package/lib/mjs/dto/links.d.ts.map +1 -0
  116. package/lib/mjs/dto/links.js +37 -0
  117. package/lib/mjs/dto/links.js.map +1 -0
  118. package/lib/mjs/dto/params.d.ts +19 -0
  119. package/lib/mjs/dto/params.d.ts.map +1 -0
  120. package/lib/mjs/dto/params.js +6 -0
  121. package/lib/mjs/dto/params.js.map +1 -0
  122. package/lib/mjs/dto/queries.d.ts +37 -0
  123. package/lib/mjs/dto/queries.d.ts.map +1 -0
  124. package/lib/mjs/dto/queries.js +66 -0
  125. package/lib/mjs/dto/queries.js.map +1 -0
  126. package/lib/mjs/dto/rules.d.ts +18 -0
  127. package/lib/mjs/dto/rules.d.ts.map +1 -0
  128. package/lib/mjs/dto/rules.js +31 -0
  129. package/lib/mjs/dto/rules.js.map +1 -0
  130. package/lib/mjs/index.d.ts +1 -0
  131. package/lib/mjs/index.d.ts.map +1 -1
  132. package/lib/mjs/index.js +1 -0
  133. package/lib/mjs/index.js.map +1 -1
  134. package/lib/mjs/routes/answers.d.ts +22 -0
  135. package/lib/mjs/routes/answers.d.ts.map +1 -0
  136. package/lib/mjs/routes/answers.js +115 -0
  137. package/lib/mjs/routes/answers.js.map +1 -0
  138. package/lib/mjs/routes/args.d.ts +59 -0
  139. package/lib/mjs/routes/args.d.ts.map +1 -0
  140. package/lib/mjs/routes/args.js +160 -0
  141. package/lib/mjs/routes/args.js.map +1 -0
  142. package/lib/mjs/routes/index.d.ts +3 -0
  143. package/lib/mjs/routes/index.d.ts.map +1 -1
  144. package/lib/mjs/routes/index.js +3 -0
  145. package/lib/mjs/routes/index.js.map +1 -1
  146. package/lib/mjs/routes/no-store.d.ts +10 -0
  147. package/lib/mjs/routes/no-store.d.ts.map +1 -0
  148. package/lib/mjs/routes/no-store.js +14 -0
  149. package/lib/mjs/routes/no-store.js.map +1 -0
  150. package/lib/mjs/routes/query.d.ts +6 -7
  151. package/lib/mjs/routes/query.d.ts.map +1 -1
  152. package/lib/mjs/routes/query.js +15 -62
  153. package/lib/mjs/routes/query.js.map +1 -1
  154. package/lib/mjs/schemas/answers.d.ts +7 -0
  155. package/lib/mjs/schemas/answers.d.ts.map +1 -0
  156. package/lib/mjs/schemas/answers.js +11 -0
  157. package/lib/mjs/schemas/answers.js.map +1 -0
  158. package/lib/mjs/schemas/commands.d.ts +4 -0
  159. package/lib/mjs/schemas/commands.d.ts.map +1 -1
  160. package/lib/mjs/schemas/commands.js +19 -12
  161. package/lib/mjs/schemas/commands.js.map +1 -1
  162. package/lib/mjs/schemas/document.d.ts +8 -17
  163. package/lib/mjs/schemas/document.d.ts.map +1 -1
  164. package/lib/mjs/schemas/document.js +53 -63
  165. package/lib/mjs/schemas/document.js.map +1 -1
  166. package/lib/mjs/schemas/index.d.ts +1 -1
  167. package/lib/mjs/schemas/index.d.ts.map +1 -1
  168. package/lib/mjs/schemas/index.js +1 -1
  169. package/lib/mjs/schemas/index.js.map +1 -1
  170. package/lib/mjs/schemas/primitives.d.ts +8 -1
  171. package/lib/mjs/schemas/primitives.d.ts.map +1 -1
  172. package/lib/mjs/schemas/primitives.js +22 -14
  173. package/lib/mjs/schemas/primitives.js.map +1 -1
  174. package/lib/mjs/schemas/provider.d.ts +4 -4
  175. package/lib/mjs/schemas/provider.d.ts.map +1 -1
  176. package/lib/mjs/schemas/provider.js +6 -6
  177. package/lib/mjs/schemas/provider.js.map +1 -1
  178. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  179. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  180. package/package.json +13 -12
  181. package/lib/cjs/schemas/bodies.d.ts +0 -17
  182. package/lib/cjs/schemas/bodies.d.ts.map +0 -1
  183. package/lib/cjs/schemas/bodies.js +0 -35
  184. package/lib/cjs/schemas/bodies.js.map +0 -1
  185. package/lib/mjs/schemas/bodies.d.ts +0 -17
  186. package/lib/mjs/schemas/bodies.d.ts.map +0 -1
  187. package/lib/mjs/schemas/bodies.js +0 -32
  188. package/lib/mjs/schemas/bodies.js.map +0 -1
@@ -13,96 +13,50 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  import { AuthzAdminFailure, AuthzDomains } from '@spinajs/authz';
14
14
  import { Config } from '@spinajs/configuration';
15
15
  import { Autoinject } from '@spinajs/di';
16
- import { BadRequestResponse, BaseController, BasePath, Conflict, Del, ForbiddenResponse, Get, NotFound, Ok, Patch, Policy, Post, Put, Req, ServerError } from '@spinajs/http';
17
- import { IsAuthenticated, UnknownAuthzDomain, resolveAuthzDomain } from '@spinajs/authz-http';
18
- import { isPlainObject } from '@spinajs/util';
16
+ import { BaseController, BasePath, Body, Del, Get, Middleware, OnError, Param, Patch, Policy, Post, Put } from '@spinajs/http';
17
+ import { CurrentPrincipal, IsAuthenticated, UnknownAuthzDomain } from '@spinajs/authz-http';
18
+ import { InvalidArgument } from '@spinajs/exceptions';
19
+ import { ValidationFailed } from '@spinajs/validation';
19
20
  import '../schemas/provider.js';
20
- import { decodeCommand, decodeCommands } from '../routes/decode.js';
21
+ import { AuthzAssignmentGrant, AuthzAssignmentPatch } from '../dto/assignments.js';
22
+ import { AuthzAttributesBody, AuthzAttributesPatch } from '../dto/attributes.js';
23
+ import { AuthzLinkCreate, AuthzLinkPatch } from '../dto/links.js';
24
+ import { ID_PARAM, TYPE_PARAM } from '../dto/params.js';
25
+ import { AuthzAssignmentsQuery, AuthzHoldersQuery, AuthzListQuery, AuthzOffsetListQuery, AuthzWriteOptionsQuery } from '../dto/queries.js';
26
+ import { AuthzPolicyBody, AuthzRuleBody } from '../dto/rules.js';
27
+ import { adminInputAnswer, refused, respond } from '../routes/answers.js';
28
+ import { AdminBatch, AdminBody, AdminDomain, AdminQuery } from '../routes/args.js';
29
+ import { decodeCommand } from '../routes/decode.js';
30
+ import { NoStore } from '../routes/no-store.js';
21
31
  import { readAssignmentsQuery, readHoldersQuery, readPageQuery, readWriteOptions } from '../routes/query.js';
22
- import { adminErrorStatus, resultsStatus } from '../routes/status.js';
23
- const PATCH_KEYS = ['tags', 'addTags', 'removeTags', 'expiresAt'];
32
+ import { resultsStatus } from '../routes/status.js';
24
33
  const PATCH_KINDS = { tags: 'assignment.setTags', addTags: 'assignment.addTags', removeTags: 'assignment.removeTags' };
25
- function respond(status, body) {
26
- switch (status) {
27
- case 200:
28
- return new Ok(body);
29
- case 403:
30
- return new ForbiddenResponse(body);
31
- case 404:
32
- return new NotFound(body);
33
- case 409:
34
- return new Conflict(body);
35
- case 500:
36
- return new ServerError(body);
37
- default:
38
- return new BadRequestResponse(body);
39
- }
40
- }
41
- function refused(e) {
42
- return respond(adminErrorStatus(e.code), { error: { code: e.code, message: e.message, ...(e.field === undefined ? {} : { field: e.field }) } });
43
- }
44
- function badRequest(message, field) {
45
- throw new AuthzAdminFailure('invalid_request', message, field);
46
- }
47
- function objectBody(body, what) {
48
- if (!isPlainObject(body))
49
- badRequest(`the body must be ${what}`);
50
- return body;
51
- }
52
- /** The body of PUT /authz/rules/:id or /authz/policies/:id with the path id; an id in the body must equal it. */
53
- function withPathId(body, id, what) {
54
- const o = objectBody(body, what);
55
- if (o.id !== undefined && o.id !== id)
56
- badRequest(`the body id ${JSON.stringify(o.id)} is not the path id ${JSON.stringify(id)}`, 'id');
57
- return { ...o, id };
34
+ /** A body the route runs under its path id; an id in the body must equal it. */
35
+ function withPathId(body, id) {
36
+ if (body.id !== undefined && body.id !== id)
37
+ throw new AuthzAdminFailure('invalid_request', `the body id ${JSON.stringify(body.id)} is not the path id ${JSON.stringify(id)}`, 'id');
38
+ return { ...body, id };
58
39
  }
59
40
  // The routes serve the RBAC and ABAC commands, whose AuthzCommandMap entries this package does not import.
60
41
  const byId = (kind, id) => ({ kind, id });
61
- const LINK_PATCH_KEYS = ['expiresAt', 'attributes', 'role', 'tags'];
62
- /** PATCH /authz/links/:id as one link.update; like the assignment patch, a key it does not serve is refused, not ignored. */
63
- function linkUpdate(body, id) {
64
- const patch = withPathId(body, id, 'an object { expiresAt?, attributes?, role?, tags? }');
65
- const unknown = Object.keys(patch).find((k) => k !== 'id' && !LINK_PATCH_KEYS.includes(k));
66
- if (unknown !== undefined)
67
- badRequest(`a link patch takes ${LINK_PATCH_KEYS.join(', ')}, not ${JSON.stringify(unknown)}`, unknown);
68
- if (!LINK_PATCH_KEYS.some((k) => k in patch))
69
- badRequest(`a link patch needs one of ${LINK_PATCH_KEYS.join(', ')}`);
70
- return decodeCommand({ ...patch, kind: 'link.update' });
71
- }
72
- /** For answers that may hold a link token: no proxy or browser cache may keep one. Set first, so it goes out with any answer the route gives. */
73
- function noStore(req) {
74
- req.res?.setHeader('Cache-Control', 'no-store');
75
- req.res?.setHeader('Pragma', 'no-cache');
76
- }
77
- const query = (req) => (req.query ?? {});
78
- const param = (req, name) => req.params[name];
79
- const actorOf = (req) => req.storage.Principal;
80
- const scopeOf = (req) => ({ type: param(req, 'type'), id: param(req, 'id') });
42
+ const asCommand = (c) => decodeCommand(c);
81
43
  /**
82
44
  * Admin routes over the management API of the configured domain (`authz.http.admin.domain`).
83
45
  *
84
46
  * The routes check authentication only: the actor is always the request principal, and every
85
- * permission, validation and guard check runs in AuthzAdmin, as for an in-process caller (design
86
- * §6.6.5). A refused request answers `{ error: { code, message, field? } }`; a write answers
87
- * `{ results }`, one entry per command.
47
+ * permission and guard check runs in AuthzAdmin, as for an in-process caller (design §6.6.5). The
48
+ * inputs are DTOs checked against their schemas first; a refused request answers
49
+ * `{ error: { code, message, field? } }`, a write `{ results }`, one entry per command.
88
50
  *
89
51
  * @tags Authz admin
90
52
  */
91
53
  let AuthzAdminController = class AuthzAdminController extends BaseController {
92
54
  /**
93
- * Runs a route on the AuthzAdmin of the domain the AuthzDomainResolver names for `req`, `authz.http.admin.domain` being its fallback and the domain without a request.
94
- * An AuthzAdminFailure becomes its status with `{ error }`, a domain no live domain bears 403 `unknown_domain`, anything else propagates.
55
+ * Runs a route on the AuthzAdmin of `domain` (the one `@AdminDomain()` resolved), `authz.http.admin.domain` without one.
56
+ * An AuthzAdminFailure becomes its status with `{ error }`, anything else propagates.
95
57
  */
96
- async guarded(fn, req) {
97
- let admin;
98
- try {
99
- admin = (await this.Domains.service(req ? await resolveAuthzDomain(req, this.AdminDomain) : this.AdminDomain)).admin();
100
- }
101
- catch (e) {
102
- if (e instanceof UnknownAuthzDomain)
103
- return respond(403, { error: { code: 'unknown_domain', message: e.message } });
104
- throw e;
105
- }
58
+ async guarded(fn, domain) {
59
+ const admin = (await this.Domains.service(domain ?? this.AdminDomain)).admin();
106
60
  try {
107
61
  return await fn(admin);
108
62
  }
@@ -113,14 +67,11 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
113
67
  }
114
68
  }
115
69
  /** One batch built from the route, with the options of the query string. */
116
- single(req, build) {
117
- return this.guarded(async (admin) => {
118
- const opts = readWriteOptions(query(req));
119
- return results(await admin.execute(actorOf(req), build(), opts));
120
- }, req);
70
+ single(domain, actor, options, build) {
71
+ return this.guarded(async (admin) => results(await admin.execute(actor, build(), readWriteOptions(options))), domain);
121
72
  }
122
- list(req, build) {
123
- return this.guarded(async (admin) => respond(200, await admin.list(actorOf(req), build())), req);
73
+ list(domain, actor, build) {
74
+ return this.guarded(async (admin) => respond(200, await admin.list(actor, build())), domain);
124
75
  }
125
76
  /**
126
77
  * Run a batch of commands
@@ -135,16 +86,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
135
86
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
136
87
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
137
88
  */
138
- async commands(req) {
139
- noStore(req);
140
- return this.guarded(async (admin) => {
141
- const body = objectBody(req.body, 'an object { commands, reason?, idempotencyKey?, dryRun? }');
142
- const opts = {};
143
- for (const key of ['reason', 'idempotencyKey', 'dryRun'])
144
- if (key in body)
145
- opts[key] = body[key];
146
- return results(await admin.execute(actorOf(req), decodeCommands(body.commands), opts));
147
- }, req);
89
+ async commands(domain, actor, batch) {
90
+ return this.guarded(async (admin) => results(await admin.execute(actor, batch.commands, batch.options)), domain);
148
91
  }
149
92
  /**
150
93
  * List assignments
@@ -155,8 +98,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
155
98
  * @response 401 Unauthorized: a valid session or token is required
156
99
  * @response 403 {AuthzAdminError} forbidden: the caller lacks the read permission at the scope
157
100
  */
158
- async listAssignments(req) {
159
- return this.list(req, () => readAssignmentsQuery(query(req)));
101
+ async listAssignments(domain, actor, query) {
102
+ return this.list(domain, actor, () => readAssignmentsQuery(query));
160
103
  }
161
104
  /**
162
105
  * List holders
@@ -167,8 +110,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
167
110
  * @response 401 Unauthorized: a valid session or token is required
168
111
  * @response 403 {AuthzAdminError} forbidden: the caller lacks authz:holders.read at the resource, or the resource is unknown
169
112
  */
170
- async listHolders(req) {
171
- return this.list(req, () => readHoldersQuery(query(req)));
113
+ async listHolders(domain, actor, query) {
114
+ return this.list(domain, actor, () => readHoldersQuery(query));
172
115
  }
173
116
  /**
174
117
  * Grant a role
@@ -183,8 +126,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
183
126
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
184
127
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
185
128
  */
186
- async grant(req) {
187
- return this.single(req, () => [decodeCommand({ ...objectBody(req.body, 'the fields of assignment.grant'), kind: 'assignment.grant' })]);
129
+ async grant(domain, actor, body, options) {
130
+ return this.single(domain, actor, options, () => [asCommand({ ...body, kind: 'assignment.grant' })]);
188
131
  }
189
132
  /**
190
133
  * Change an assignment
@@ -199,21 +142,14 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
199
142
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
200
143
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
201
144
  */
202
- async patchAssignment(req) {
203
- return this.single(req, () => {
204
- const body = objectBody(req.body, 'an object { tags?, addTags?, removeTags?, expiresAt? }');
205
- const unknown = Object.keys(body).find((k) => !PATCH_KEYS.includes(k));
206
- if (unknown !== undefined)
207
- badRequest(`an assignment patch takes ${PATCH_KEYS.join(', ')}, not ${JSON.stringify(unknown)}`, unknown);
208
- const id = param(req, 'id');
145
+ async patchAssignment(domain, actor, id, body, options) {
146
+ return this.single(domain, actor, options, () => {
209
147
  const commands = [];
210
148
  for (const key of ['tags', 'addTags', 'removeTags'])
211
- if (key in body)
149
+ if (body[key] !== undefined)
212
150
  commands.push({ kind: PATCH_KINDS[key], id, tags: body[key] });
213
- if ('expiresAt' in body)
214
- commands.push(decodeCommand({ kind: 'assignment.setExpiry', id, expiresAt: body.expiresAt }));
215
- if (commands.length === 0)
216
- badRequest(`an assignment patch needs one of ${PATCH_KEYS.join(', ')}`);
151
+ if (body.expiresAt !== undefined)
152
+ commands.push(asCommand({ kind: 'assignment.setExpiry', id, expiresAt: body.expiresAt }));
217
153
  return commands;
218
154
  });
219
155
  }
@@ -229,8 +165,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
229
165
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
230
166
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
231
167
  */
232
- async revoke(req) {
233
- return this.single(req, () => [byId('assignment.revoke', param(req, 'id'))]);
168
+ async revoke(domain, actor, id, options) {
169
+ return this.single(domain, actor, options, () => [byId('assignment.revoke', id)]);
234
170
  }
235
171
  /**
236
172
  * List share links
@@ -241,8 +177,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
241
177
  * @response 401 Unauthorized: a valid session or token is required
242
178
  * @response 403 {AuthzAdminError} forbidden: the caller lacks the read permission at the scope
243
179
  */
244
- async listLinks(req) {
245
- return this.list(req, () => readPageQuery('links', query(req)));
180
+ async listLinks(domain, actor, query) {
181
+ return this.list(domain, actor, () => readPageQuery('links', query));
246
182
  }
247
183
  /**
248
184
  * Create a share link
@@ -257,9 +193,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
257
193
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
258
194
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
259
195
  */
260
- async createLink(req) {
261
- noStore(req);
262
- return this.single(req, () => [decodeCommand({ ...objectBody(req.body, 'the fields of link.create'), kind: 'link.create' })]);
196
+ async createLink(domain, actor, body, options) {
197
+ return this.single(domain, actor, options, () => [asCommand({ ...body, kind: 'link.create' })]);
263
198
  }
264
199
  /**
265
200
  * Change a share link
@@ -274,8 +209,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
274
209
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
275
210
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
276
211
  */
277
- async patchLink(req) {
278
- return this.single(req, () => [linkUpdate(req.body, param(req, 'id'))]);
212
+ async patchLink(domain, actor, id, body, options) {
213
+ return this.single(domain, actor, options, () => [asCommand({ ...withPathId(body, id), kind: 'link.update' })]);
279
214
  }
280
215
  /**
281
216
  * Revoke a share link
@@ -289,8 +224,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
289
224
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
290
225
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
291
226
  */
292
- async revokeLink(req) {
293
- return this.single(req, () => [byId('link.revoke', param(req, 'id'))]);
227
+ async revokeLink(domain, actor, id, options) {
228
+ return this.single(domain, actor, options, () => [byId('link.revoke', id)]);
294
229
  }
295
230
  /**
296
231
  * List rules
@@ -301,8 +236,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
301
236
  * @response 401 Unauthorized: a valid session or token is required
302
237
  * @response 403 {AuthzAdminError} forbidden: the caller lacks the read permission at the scope
303
238
  */
304
- async listRules(req) {
305
- return this.list(req, () => readPageQuery('rules', query(req)));
239
+ async listRules(domain, actor, query) {
240
+ return this.list(domain, actor, () => readPageQuery('rules', query));
306
241
  }
307
242
  /**
308
243
  * Put a rule
@@ -317,8 +252,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
317
252
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
318
253
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
319
254
  */
320
- async putRule(req) {
321
- return this.single(req, () => [decodeCommand({ kind: 'rule.put', rule: withPathId(req.body, param(req, 'id'), 'a rule') })]);
255
+ async putRule(domain, actor, id, body, options) {
256
+ return this.single(domain, actor, options, () => [asCommand({ kind: 'rule.put', rule: withPathId(body, id) })]);
322
257
  }
323
258
  /**
324
259
  * Delete a rule
@@ -332,8 +267,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
332
267
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
333
268
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
334
269
  */
335
- async deleteRule(req) {
336
- return this.single(req, () => [byId('rule.delete', param(req, 'id'))]);
270
+ async deleteRule(domain, actor, id, options) {
271
+ return this.single(domain, actor, options, () => [byId('rule.delete', id)]);
337
272
  }
338
273
  /**
339
274
  * List policies
@@ -344,8 +279,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
344
279
  * @response 401 Unauthorized: a valid session or token is required
345
280
  * @response 403 {AuthzAdminError} forbidden: the caller lacks the read permission at the scope
346
281
  */
347
- async listPolicies(req) {
348
- return this.list(req, () => readPageQuery('policies', query(req)));
282
+ async listPolicies(domain, actor, query) {
283
+ return this.list(domain, actor, () => readPageQuery('policies', query));
349
284
  }
350
285
  /**
351
286
  * Put a policy
@@ -360,8 +295,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
360
295
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
361
296
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
362
297
  */
363
- async putPolicy(req) {
364
- return this.single(req, () => [decodeCommand({ kind: 'policy.put', policy: withPathId(req.body, param(req, 'id'), 'a policy') })]);
298
+ async putPolicy(domain, actor, id, body, options) {
299
+ return this.single(domain, actor, options, () => [asCommand({ kind: 'policy.put', policy: withPathId(body, id) })]);
365
300
  }
366
301
  /**
367
302
  * Delete a policy
@@ -375,8 +310,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
375
310
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
376
311
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
377
312
  */
378
- async deletePolicy(req) {
379
- return this.single(req, () => [byId('policy.delete', param(req, 'id'))]);
313
+ async deletePolicy(domain, actor, id, options) {
314
+ return this.single(domain, actor, options, () => [byId('policy.delete', id)]);
380
315
  }
381
316
  /**
382
317
  * Read scope attributes
@@ -386,8 +321,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
386
321
  * @response 401 Unauthorized: a valid session or token is required
387
322
  * @response 403 {AuthzAdminError} forbidden: the caller lacks the read permission at the scope
388
323
  */
389
- async attributes(req) {
390
- return this.list(req, () => ({ kind: 'attributes', scope: scopeOf(req) }));
324
+ async attributes(domain, actor, type, id) {
325
+ return this.list(domain, actor, () => ({ kind: 'attributes', scope: { type, id } }));
391
326
  }
392
327
  /**
393
328
  * Merge scope attributes
@@ -402,8 +337,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
402
337
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
403
338
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
404
339
  */
405
- async patchAttributes(req) {
406
- return this.single(req, () => [{ kind: 'scope.setAttributes', scope: scopeOf(req), patch: req.body }]);
340
+ async patchAttributes(domain, actor, type, id, body, options) {
341
+ return this.single(domain, actor, options, () => [{ kind: 'scope.setAttributes', scope: { type, id }, patch: { ...body } }]);
407
342
  }
408
343
  /**
409
344
  * Replace scope attributes
@@ -418,8 +353,8 @@ let AuthzAdminController = class AuthzAdminController extends BaseController {
418
353
  * @response 409 {AuthzAdminError} conflict: the row changed or exists already
419
354
  * @response 500 {AuthzAdminError} hook_error: an action hook threw or timed out
420
355
  */
421
- async replaceAttributes(req) {
422
- return this.single(req, () => [{ kind: 'scope.replaceAttributes', scope: scopeOf(req), attributes: req.body }]);
356
+ async replaceAttributes(domain, actor, type, id, body, options) {
357
+ return this.single(domain, actor, options, () => [{ kind: 'scope.replaceAttributes', scope: { type, id }, attributes: { ...body } }]);
423
358
  }
424
359
  };
425
360
  __decorate([
@@ -432,140 +367,202 @@ __decorate([
432
367
  ], AuthzAdminController.prototype, "Domains", void 0);
433
368
  __decorate([
434
369
  Post('commands'),
435
- __param(0, Req()),
370
+ Middleware(NoStore),
371
+ __param(0, AdminDomain()),
372
+ __param(1, CurrentPrincipal()),
373
+ __param(2, AdminBatch()),
436
374
  __metadata("design:type", Function),
437
- __metadata("design:paramtypes", [Object]),
375
+ __metadata("design:paramtypes", [String, Object, Object]),
438
376
  __metadata("design:returntype", Promise)
439
377
  ], AuthzAdminController.prototype, "commands", null);
440
378
  __decorate([
441
379
  Get('assignments'),
442
- __param(0, Req()),
380
+ __param(0, AdminDomain()),
381
+ __param(1, CurrentPrincipal()),
382
+ __param(2, AdminQuery()),
443
383
  __metadata("design:type", Function),
444
- __metadata("design:paramtypes", [Object]),
384
+ __metadata("design:paramtypes", [String, Object, AuthzAssignmentsQuery]),
445
385
  __metadata("design:returntype", Promise)
446
386
  ], AuthzAdminController.prototype, "listAssignments", null);
447
387
  __decorate([
448
388
  Get('holders'),
449
- __param(0, Req()),
389
+ __param(0, AdminDomain()),
390
+ __param(1, CurrentPrincipal()),
391
+ __param(2, AdminQuery()),
450
392
  __metadata("design:type", Function),
451
- __metadata("design:paramtypes", [Object]),
393
+ __metadata("design:paramtypes", [String, Object, AuthzHoldersQuery]),
452
394
  __metadata("design:returntype", Promise)
453
395
  ], AuthzAdminController.prototype, "listHolders", null);
454
396
  __decorate([
455
397
  Post('assignments'),
456
- __param(0, Req()),
398
+ __param(0, AdminDomain()),
399
+ __param(1, CurrentPrincipal()),
400
+ __param(2, Body({ required: true })),
401
+ __param(3, AdminQuery()),
457
402
  __metadata("design:type", Function),
458
- __metadata("design:paramtypes", [Object]),
403
+ __metadata("design:paramtypes", [String, Object, AuthzAssignmentGrant, AuthzWriteOptionsQuery]),
459
404
  __metadata("design:returntype", Promise)
460
405
  ], AuthzAdminController.prototype, "grant", null);
461
406
  __decorate([
462
407
  Patch('assignments/:id'),
463
- __param(0, Req()),
408
+ __param(0, AdminDomain()),
409
+ __param(1, CurrentPrincipal()),
410
+ __param(2, Param(ID_PARAM)),
411
+ __param(3, Body({ required: true })),
412
+ __param(4, AdminQuery()),
464
413
  __metadata("design:type", Function),
465
- __metadata("design:paramtypes", [Object]),
414
+ __metadata("design:paramtypes", [String, Object, String, AuthzAssignmentPatch, AuthzWriteOptionsQuery]),
466
415
  __metadata("design:returntype", Promise)
467
416
  ], AuthzAdminController.prototype, "patchAssignment", null);
468
417
  __decorate([
469
418
  Del('assignments/:id'),
470
- __param(0, Req()),
419
+ __param(0, AdminDomain()),
420
+ __param(1, CurrentPrincipal()),
421
+ __param(2, Param(ID_PARAM)),
422
+ __param(3, AdminQuery()),
471
423
  __metadata("design:type", Function),
472
- __metadata("design:paramtypes", [Object]),
424
+ __metadata("design:paramtypes", [String, Object, String, AuthzWriteOptionsQuery]),
473
425
  __metadata("design:returntype", Promise)
474
426
  ], AuthzAdminController.prototype, "revoke", null);
475
427
  __decorate([
476
428
  Get('links'),
477
- __param(0, Req()),
429
+ __param(0, AdminDomain()),
430
+ __param(1, CurrentPrincipal()),
431
+ __param(2, AdminQuery()),
478
432
  __metadata("design:type", Function),
479
- __metadata("design:paramtypes", [Object]),
433
+ __metadata("design:paramtypes", [String, Object, AuthzListQuery]),
480
434
  __metadata("design:returntype", Promise)
481
435
  ], AuthzAdminController.prototype, "listLinks", null);
482
436
  __decorate([
483
437
  Post('links'),
484
- __param(0, Req()),
438
+ Middleware(NoStore),
439
+ __param(0, AdminDomain()),
440
+ __param(1, CurrentPrincipal()),
441
+ __param(2, Body({ required: true })),
442
+ __param(3, AdminQuery()),
485
443
  __metadata("design:type", Function),
486
- __metadata("design:paramtypes", [Object]),
444
+ __metadata("design:paramtypes", [String, Object, AuthzLinkCreate, AuthzWriteOptionsQuery]),
487
445
  __metadata("design:returntype", Promise)
488
446
  ], AuthzAdminController.prototype, "createLink", null);
489
447
  __decorate([
490
448
  Patch('links/:id'),
491
- __param(0, Req()),
449
+ __param(0, AdminDomain()),
450
+ __param(1, CurrentPrincipal()),
451
+ __param(2, Param(ID_PARAM)),
452
+ __param(3, Body({ required: true })),
453
+ __param(4, AdminQuery()),
492
454
  __metadata("design:type", Function),
493
- __metadata("design:paramtypes", [Object]),
455
+ __metadata("design:paramtypes", [String, Object, String, AuthzLinkPatch, AuthzWriteOptionsQuery]),
494
456
  __metadata("design:returntype", Promise)
495
457
  ], AuthzAdminController.prototype, "patchLink", null);
496
458
  __decorate([
497
459
  Del('links/:id'),
498
- __param(0, Req()),
460
+ __param(0, AdminDomain()),
461
+ __param(1, CurrentPrincipal()),
462
+ __param(2, Param(ID_PARAM)),
463
+ __param(3, AdminQuery()),
499
464
  __metadata("design:type", Function),
500
- __metadata("design:paramtypes", [Object]),
465
+ __metadata("design:paramtypes", [String, Object, String, AuthzWriteOptionsQuery]),
501
466
  __metadata("design:returntype", Promise)
502
467
  ], AuthzAdminController.prototype, "revokeLink", null);
503
468
  __decorate([
504
469
  Get('rules'),
505
- __param(0, Req()),
470
+ __param(0, AdminDomain()),
471
+ __param(1, CurrentPrincipal()),
472
+ __param(2, AdminQuery()),
506
473
  __metadata("design:type", Function),
507
- __metadata("design:paramtypes", [Object]),
474
+ __metadata("design:paramtypes", [String, Object, AuthzListQuery]),
508
475
  __metadata("design:returntype", Promise)
509
476
  ], AuthzAdminController.prototype, "listRules", null);
510
477
  __decorate([
511
478
  Put('rules/:id'),
512
- __param(0, Req()),
479
+ __param(0, AdminDomain()),
480
+ __param(1, CurrentPrincipal()),
481
+ __param(2, Param(ID_PARAM)),
482
+ __param(3, Body({ required: true })),
483
+ __param(4, AdminQuery()),
513
484
  __metadata("design:type", Function),
514
- __metadata("design:paramtypes", [Object]),
485
+ __metadata("design:paramtypes", [String, Object, String, AuthzRuleBody, AuthzWriteOptionsQuery]),
515
486
  __metadata("design:returntype", Promise)
516
487
  ], AuthzAdminController.prototype, "putRule", null);
517
488
  __decorate([
518
489
  Del('rules/:id'),
519
- __param(0, Req()),
490
+ __param(0, AdminDomain()),
491
+ __param(1, CurrentPrincipal()),
492
+ __param(2, Param(ID_PARAM)),
493
+ __param(3, AdminQuery()),
520
494
  __metadata("design:type", Function),
521
- __metadata("design:paramtypes", [Object]),
495
+ __metadata("design:paramtypes", [String, Object, String, AuthzWriteOptionsQuery]),
522
496
  __metadata("design:returntype", Promise)
523
497
  ], AuthzAdminController.prototype, "deleteRule", null);
524
498
  __decorate([
525
499
  Get('policies'),
526
- __param(0, Req()),
500
+ __param(0, AdminDomain()),
501
+ __param(1, CurrentPrincipal()),
502
+ __param(2, AdminQuery()),
527
503
  __metadata("design:type", Function),
528
- __metadata("design:paramtypes", [Object]),
504
+ __metadata("design:paramtypes", [String, Object, AuthzOffsetListQuery]),
529
505
  __metadata("design:returntype", Promise)
530
506
  ], AuthzAdminController.prototype, "listPolicies", null);
531
507
  __decorate([
532
508
  Put('policies/:id'),
533
- __param(0, Req()),
509
+ __param(0, AdminDomain()),
510
+ __param(1, CurrentPrincipal()),
511
+ __param(2, Param(ID_PARAM)),
512
+ __param(3, Body({ required: true })),
513
+ __param(4, AdminQuery()),
534
514
  __metadata("design:type", Function),
535
- __metadata("design:paramtypes", [Object]),
515
+ __metadata("design:paramtypes", [String, Object, String, AuthzPolicyBody, AuthzWriteOptionsQuery]),
536
516
  __metadata("design:returntype", Promise)
537
517
  ], AuthzAdminController.prototype, "putPolicy", null);
538
518
  __decorate([
539
519
  Del('policies/:id'),
540
- __param(0, Req()),
520
+ __param(0, AdminDomain()),
521
+ __param(1, CurrentPrincipal()),
522
+ __param(2, Param(ID_PARAM)),
523
+ __param(3, AdminQuery()),
541
524
  __metadata("design:type", Function),
542
- __metadata("design:paramtypes", [Object]),
525
+ __metadata("design:paramtypes", [String, Object, String, AuthzWriteOptionsQuery]),
543
526
  __metadata("design:returntype", Promise)
544
527
  ], AuthzAdminController.prototype, "deletePolicy", null);
545
528
  __decorate([
546
529
  Get('scopes/:type/:id/attributes'),
547
- __param(0, Req()),
530
+ __param(0, AdminDomain()),
531
+ __param(1, CurrentPrincipal()),
532
+ __param(2, Param(TYPE_PARAM)),
533
+ __param(3, Param(ID_PARAM)),
548
534
  __metadata("design:type", Function),
549
- __metadata("design:paramtypes", [Object]),
535
+ __metadata("design:paramtypes", [String, Object, String, String]),
550
536
  __metadata("design:returntype", Promise)
551
537
  ], AuthzAdminController.prototype, "attributes", null);
552
538
  __decorate([
553
539
  Patch('scopes/:type/:id/attributes'),
554
- __param(0, Req()),
540
+ __param(0, AdminDomain()),
541
+ __param(1, CurrentPrincipal()),
542
+ __param(2, Param(TYPE_PARAM)),
543
+ __param(3, Param(ID_PARAM)),
544
+ __param(4, AdminBody()),
545
+ __param(5, AdminQuery()),
555
546
  __metadata("design:type", Function),
556
- __metadata("design:paramtypes", [Object]),
547
+ __metadata("design:paramtypes", [String, Object, String, String, AuthzAttributesPatch, AuthzWriteOptionsQuery]),
557
548
  __metadata("design:returntype", Promise)
558
549
  ], AuthzAdminController.prototype, "patchAttributes", null);
559
550
  __decorate([
560
551
  Put('scopes/:type/:id/attributes'),
561
- __param(0, Req()),
552
+ __param(0, AdminDomain()),
553
+ __param(1, CurrentPrincipal()),
554
+ __param(2, Param(TYPE_PARAM)),
555
+ __param(3, Param(ID_PARAM)),
556
+ __param(4, AdminBody()),
557
+ __param(5, AdminQuery()),
562
558
  __metadata("design:type", Function),
563
- __metadata("design:paramtypes", [Object]),
559
+ __metadata("design:paramtypes", [String, Object, String, String, AuthzAttributesBody, AuthzWriteOptionsQuery]),
564
560
  __metadata("design:returntype", Promise)
565
561
  ], AuthzAdminController.prototype, "replaceAttributes", null);
566
562
  AuthzAdminController = __decorate([
567
563
  Policy(IsAuthenticated),
568
- BasePath({ config: 'authz.http.admin.basePath', default: 'authz' })
564
+ BasePath({ config: 'authz.http.admin.basePath', default: 'authz' }),
565
+ OnError([ValidationFailed, InvalidArgument, AuthzAdminFailure, UnknownAuthzDomain], adminInputAnswer, { stages: ['arguments'] })
569
566
  ], AuthzAdminController);
570
567
  export { AuthzAdminController };
571
568
  function results(r) {