@byline/admin 0.9.3

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 (159) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +19 -0
  3. package/dist/abilities.d.ts +22 -0
  4. package/dist/abilities.d.ts.map +1 -0
  5. package/dist/abilities.js +29 -0
  6. package/dist/abilities.js.map +1 -0
  7. package/dist/index.d.ts +31 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +30 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/assert-admin-actor.d.ts +58 -0
  12. package/dist/lib/assert-admin-actor.d.ts.map +1 -0
  13. package/dist/lib/assert-admin-actor.js +82 -0
  14. package/dist/lib/assert-admin-actor.js.map +1 -0
  15. package/dist/modules/admin-account/commands.d.ts +30 -0
  16. package/dist/modules/admin-account/commands.d.ts.map +1 -0
  17. package/dist/modules/admin-account/commands.js +36 -0
  18. package/dist/modules/admin-account/commands.js.map +1 -0
  19. package/dist/modules/admin-account/errors.d.ts +52 -0
  20. package/dist/modules/admin-account/errors.d.ts.map +1 -0
  21. package/dist/modules/admin-account/errors.js +52 -0
  22. package/dist/modules/admin-account/errors.js.map +1 -0
  23. package/dist/modules/admin-account/index.d.ts +37 -0
  24. package/dist/modules/admin-account/index.d.ts.map +1 -0
  25. package/dist/modules/admin-account/index.js +35 -0
  26. package/dist/modules/admin-account/index.js.map +1 -0
  27. package/dist/modules/admin-account/schemas.d.ts +31 -0
  28. package/dist/modules/admin-account/schemas.d.ts.map +1 -0
  29. package/dist/modules/admin-account/schemas.js +69 -0
  30. package/dist/modules/admin-account/schemas.js.map +1 -0
  31. package/dist/modules/admin-account/service.d.ts +44 -0
  32. package/dist/modules/admin-account/service.d.ts.map +1 -0
  33. package/dist/modules/admin-account/service.js +76 -0
  34. package/dist/modules/admin-account/service.js.map +1 -0
  35. package/dist/modules/admin-permissions/abilities.d.ts +27 -0
  36. package/dist/modules/admin-permissions/abilities.d.ts.map +1 -0
  37. package/dist/modules/admin-permissions/abilities.js +40 -0
  38. package/dist/modules/admin-permissions/abilities.js.map +1 -0
  39. package/dist/modules/admin-permissions/commands.d.ts +30 -0
  40. package/dist/modules/admin-permissions/commands.d.ts.map +1 -0
  41. package/dist/modules/admin-permissions/commands.js +39 -0
  42. package/dist/modules/admin-permissions/commands.js.map +1 -0
  43. package/dist/modules/admin-permissions/dto.d.ts +18 -0
  44. package/dist/modules/admin-permissions/dto.d.ts.map +1 -0
  45. package/dist/modules/admin-permissions/dto.js +24 -0
  46. package/dist/modules/admin-permissions/dto.js.map +1 -0
  47. package/dist/modules/admin-permissions/errors.d.ts +34 -0
  48. package/dist/modules/admin-permissions/errors.d.ts.map +1 -0
  49. package/dist/modules/admin-permissions/errors.js +34 -0
  50. package/dist/modules/admin-permissions/errors.js.map +1 -0
  51. package/dist/modules/admin-permissions/index.d.ts +30 -0
  52. package/dist/modules/admin-permissions/index.d.ts.map +1 -0
  53. package/dist/modules/admin-permissions/index.js +27 -0
  54. package/dist/modules/admin-permissions/index.js.map +1 -0
  55. package/dist/modules/admin-permissions/repository.d.ts +48 -0
  56. package/dist/modules/admin-permissions/repository.d.ts.map +1 -0
  57. package/dist/modules/admin-permissions/repository.js +9 -0
  58. package/dist/modules/admin-permissions/repository.js.map +1 -0
  59. package/dist/modules/admin-permissions/schemas.d.ts +137 -0
  60. package/dist/modules/admin-permissions/schemas.d.ts.map +1 -0
  61. package/dist/modules/admin-permissions/schemas.js +99 -0
  62. package/dist/modules/admin-permissions/schemas.js.map +1 -0
  63. package/dist/modules/admin-permissions/service.d.ts +42 -0
  64. package/dist/modules/admin-permissions/service.d.ts.map +1 -0
  65. package/dist/modules/admin-permissions/service.js +114 -0
  66. package/dist/modules/admin-permissions/service.js.map +1 -0
  67. package/dist/modules/admin-roles/abilities.d.ts +33 -0
  68. package/dist/modules/admin-roles/abilities.d.ts.map +1 -0
  69. package/dist/modules/admin-roles/abilities.js +56 -0
  70. package/dist/modules/admin-roles/abilities.js.map +1 -0
  71. package/dist/modules/admin-roles/commands.d.ts +37 -0
  72. package/dist/modules/admin-roles/commands.d.ts.map +1 -0
  73. package/dist/modules/admin-roles/commands.js +70 -0
  74. package/dist/modules/admin-roles/commands.js.map +1 -0
  75. package/dist/modules/admin-roles/dto.d.ts +18 -0
  76. package/dist/modules/admin-roles/dto.d.ts.map +1 -0
  77. package/dist/modules/admin-roles/dto.js +27 -0
  78. package/dist/modules/admin-roles/dto.js.map +1 -0
  79. package/dist/modules/admin-roles/errors.d.ts +49 -0
  80. package/dist/modules/admin-roles/errors.d.ts.map +1 -0
  81. package/dist/modules/admin-roles/errors.js +49 -0
  82. package/dist/modules/admin-roles/errors.js.map +1 -0
  83. package/dist/modules/admin-roles/index.d.ts +30 -0
  84. package/dist/modules/admin-roles/index.d.ts.map +1 -0
  85. package/dist/modules/admin-roles/index.js +27 -0
  86. package/dist/modules/admin-roles/index.js.map +1 -0
  87. package/dist/modules/admin-roles/repository.d.ts +91 -0
  88. package/dist/modules/admin-roles/repository.d.ts.map +1 -0
  89. package/dist/modules/admin-roles/repository.js +9 -0
  90. package/dist/modules/admin-roles/repository.js.map +1 -0
  91. package/dist/modules/admin-roles/schemas.d.ts +99 -0
  92. package/dist/modules/admin-roles/schemas.d.ts.map +1 -0
  93. package/dist/modules/admin-roles/schemas.js +105 -0
  94. package/dist/modules/admin-roles/schemas.js.map +1 -0
  95. package/dist/modules/admin-roles/service.d.ts +49 -0
  96. package/dist/modules/admin-roles/service.d.ts.map +1 -0
  97. package/dist/modules/admin-roles/service.js +110 -0
  98. package/dist/modules/admin-roles/service.js.map +1 -0
  99. package/dist/modules/admin-users/abilities.d.ts +41 -0
  100. package/dist/modules/admin-users/abilities.d.ts.map +1 -0
  101. package/dist/modules/admin-users/abilities.js +70 -0
  102. package/dist/modules/admin-users/abilities.js.map +1 -0
  103. package/dist/modules/admin-users/commands.d.ts +45 -0
  104. package/dist/modules/admin-users/commands.d.ts.map +1 -0
  105. package/dist/modules/admin-users/commands.js +63 -0
  106. package/dist/modules/admin-users/commands.js.map +1 -0
  107. package/dist/modules/admin-users/dto.d.ts +20 -0
  108. package/dist/modules/admin-users/dto.d.ts.map +1 -0
  109. package/dist/modules/admin-users/dto.js +36 -0
  110. package/dist/modules/admin-users/dto.js.map +1 -0
  111. package/dist/modules/admin-users/errors.d.ts +53 -0
  112. package/dist/modules/admin-users/errors.d.ts.map +1 -0
  113. package/dist/modules/admin-users/errors.js +53 -0
  114. package/dist/modules/admin-users/errors.js.map +1 -0
  115. package/dist/modules/admin-users/index.d.ts +31 -0
  116. package/dist/modules/admin-users/index.d.ts.map +1 -0
  117. package/dist/modules/admin-users/index.js +28 -0
  118. package/dist/modules/admin-users/index.js.map +1 -0
  119. package/dist/modules/admin-users/repository.d.ts +147 -0
  120. package/dist/modules/admin-users/repository.d.ts.map +1 -0
  121. package/dist/modules/admin-users/repository.js +9 -0
  122. package/dist/modules/admin-users/repository.js.map +1 -0
  123. package/dist/modules/admin-users/schemas.d.ts +136 -0
  124. package/dist/modules/admin-users/schemas.d.ts.map +1 -0
  125. package/dist/modules/admin-users/schemas.js +137 -0
  126. package/dist/modules/admin-users/schemas.js.map +1 -0
  127. package/dist/modules/admin-users/seed-super-admin.d.ts +44 -0
  128. package/dist/modules/admin-users/seed-super-admin.d.ts.map +1 -0
  129. package/dist/modules/admin-users/seed-super-admin.js +70 -0
  130. package/dist/modules/admin-users/seed-super-admin.js.map +1 -0
  131. package/dist/modules/admin-users/service.d.ts +53 -0
  132. package/dist/modules/admin-users/service.d.ts.map +1 -0
  133. package/dist/modules/admin-users/service.js +143 -0
  134. package/dist/modules/admin-users/service.js.map +1 -0
  135. package/dist/modules/auth/index.d.ts +26 -0
  136. package/dist/modules/auth/index.d.ts.map +1 -0
  137. package/dist/modules/auth/index.js +25 -0
  138. package/dist/modules/auth/index.js.map +1 -0
  139. package/dist/modules/auth/jwt-session-provider.d.ts +47 -0
  140. package/dist/modules/auth/jwt-session-provider.d.ts.map +1 -0
  141. package/dist/modules/auth/jwt-session-provider.js +215 -0
  142. package/dist/modules/auth/jwt-session-provider.js.map +1 -0
  143. package/dist/modules/auth/password.d.ts +16 -0
  144. package/dist/modules/auth/password.d.ts.map +1 -0
  145. package/dist/modules/auth/password.js +48 -0
  146. package/dist/modules/auth/password.js.map +1 -0
  147. package/dist/modules/auth/refresh-tokens-repository.d.ts +71 -0
  148. package/dist/modules/auth/refresh-tokens-repository.d.ts.map +1 -0
  149. package/dist/modules/auth/refresh-tokens-repository.js +9 -0
  150. package/dist/modules/auth/refresh-tokens-repository.js.map +1 -0
  151. package/dist/modules/auth/resolve-actor.d.ts +25 -0
  152. package/dist/modules/auth/resolve-actor.d.ts.map +1 -0
  153. package/dist/modules/auth/resolve-actor.js +36 -0
  154. package/dist/modules/auth/resolve-actor.js.map +1 -0
  155. package/dist/store.d.ts +31 -0
  156. package/dist/store.d.ts.map +1 -0
  157. package/dist/store.js +9 -0
  158. package/dist/store.js.map +1 -0
  159. package/package.json +101 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ /**
9
+ * `AdminRolesRepository` — role CRUD plus role ↔ user assignments.
10
+ *
11
+ * Deliberately does *not* cover per-role ability grants — those live on
12
+ * `AdminPermissionsRepository` (`modules/admin-permissions/repository.ts`),
13
+ * which owns the `byline_admin_permissions` table. The split follows the
14
+ * admin UI: role identity and membership live together; ability grants
15
+ * are a separate editor surface driven by the ability registry.
16
+ *
17
+ * **Optimistic concurrency.** `update`, `delete`, and `reorder` take an
18
+ * `expectedVid` and bump the stored `vid` on success. Adapters throw
19
+ * `AdminRolesError(VERSION_CONFLICT)` when the stored vid differs from
20
+ * the expected one — typical client response is to reload the form.
21
+ *
22
+ * `machine_name` is **immutable post-create**. The `UpdateAdminRoleInput`
23
+ * type omits it deliberately so renaming the slug is a deliberate
24
+ * separate operation if it ever ships.
25
+ */
26
+ export interface AdminRoleRow {
27
+ id: string;
28
+ vid: number;
29
+ name: string;
30
+ machine_name: string;
31
+ description: string | null;
32
+ order: number;
33
+ created_at: Date;
34
+ updated_at: Date;
35
+ }
36
+ export interface CreateAdminRoleInput {
37
+ name: string;
38
+ machine_name: string;
39
+ description?: string | null;
40
+ order?: number;
41
+ }
42
+ export interface UpdateAdminRoleInput {
43
+ name?: string;
44
+ description?: string | null;
45
+ order?: number;
46
+ }
47
+ export interface AdminRolesRepository {
48
+ create(input: CreateAdminRoleInput): Promise<AdminRoleRow>;
49
+ getById(id: string): Promise<AdminRoleRow | null>;
50
+ getByMachineName(machineName: string): Promise<AdminRoleRow | null>;
51
+ /** Roles ordered by their `order` column then `created_at`. No paging — the list is small by design. */
52
+ list(): Promise<AdminRoleRow[]>;
53
+ /**
54
+ * Content update with optimistic concurrency. Throws
55
+ * `AdminRolesError(VERSION_CONFLICT)` if the stored `vid` differs from
56
+ * `expectedVid`. Bumps `vid` on success and returns the fresh row.
57
+ */
58
+ update(id: string, expectedVid: number, patch: UpdateAdminRoleInput): Promise<AdminRoleRow>;
59
+ /**
60
+ * Delete with optimistic concurrency. Version-gated on `expectedVid` to
61
+ * prevent races against a concurrent update.
62
+ */
63
+ delete(id: string, expectedVid: number): Promise<void>;
64
+ /**
65
+ * Bulk reorder. The provided `ids` array fixes the new `order` value
66
+ * for each role to its index in the array. Runs in a single
67
+ * transaction. Roles not present in `ids` are left untouched.
68
+ *
69
+ * Vid-less by design — reorder mutates only the `order` column and
70
+ * the UX shape is always "drag, then save the whole list", which would
71
+ * pointlessly conflict with concurrent edits to other fields. Last
72
+ * writer on the order column wins.
73
+ */
74
+ reorder(ids: string[]): Promise<void>;
75
+ /** Assign a role to a user. Idempotent via the composite primary key. */
76
+ assignToUser(roleId: string, userId: string): Promise<void>;
77
+ unassignFromUser(roleId: string, userId: string): Promise<void>;
78
+ listRolesForUser(userId: string): Promise<AdminRoleRow[]>;
79
+ listUsersForRole(roleId: string): Promise<string[]>;
80
+ /**
81
+ * Replace the role-set for a user wholesale. Runs in a single
82
+ * transaction so the user is never observed mid-edit. Vid-less by
83
+ * design — assignments live in the join table, not on the user row,
84
+ * and the editor UX is "drag, save the whole list" rather than
85
+ * field-level concurrency. Caller is responsible for validating that
86
+ * `userId` and every `roleId` exist; the repo trusts its inputs and
87
+ * lets the FK constraint surface as the ultimate backstop.
88
+ */
89
+ setRolesForUser(userId: string, roleIds: readonly string[]): Promise<void>;
90
+ }
91
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-roles/repository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,IAAI,CAAA;IAChB,UAAU,EAAE,IAAI,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1D,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IACjD,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IACnE,wGAAwG;IACxG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;IAC/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC3F;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD;;;;;;;;;OASG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAErC,yEAAyE;IACzE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;IACzD,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACnD;;;;;;;;OAQG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3E"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/modules/admin-roles/repository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { z } from 'zod';
9
+ export declare const listAdminRolesRequestSchema: z.ZodOptional<z.ZodObject<{}, z.core.$strip>>;
10
+ export type ListAdminRolesRequest = z.infer<typeof listAdminRolesRequestSchema>;
11
+ export declare const getAdminRoleRequestSchema: z.ZodObject<{
12
+ id: z.ZodUUID;
13
+ }, z.core.$strip>;
14
+ export type GetAdminRoleRequest = z.infer<typeof getAdminRoleRequestSchema>;
15
+ export declare const createAdminRoleRequestSchema: z.ZodObject<{
16
+ name: z.ZodString;
17
+ machine_name: z.ZodString;
18
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ order: z.ZodOptional<z.ZodNumber>;
20
+ }, z.core.$strip>;
21
+ export type CreateAdminRoleRequest = z.infer<typeof createAdminRoleRequestSchema>;
22
+ export declare const updateAdminRoleRequestSchema: z.ZodObject<{
23
+ id: z.ZodUUID;
24
+ vid: z.ZodNumber;
25
+ patch: z.ZodObject<{
26
+ name: z.ZodOptional<z.ZodString>;
27
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
28
+ order: z.ZodOptional<z.ZodNumber>;
29
+ }, z.core.$strip>;
30
+ }, z.core.$strip>;
31
+ export type UpdateAdminRoleRequest = z.infer<typeof updateAdminRoleRequestSchema>;
32
+ export declare const deleteAdminRoleRequestSchema: z.ZodObject<{
33
+ id: z.ZodUUID;
34
+ vid: z.ZodNumber;
35
+ }, z.core.$strip>;
36
+ export type DeleteAdminRoleRequest = z.infer<typeof deleteAdminRoleRequestSchema>;
37
+ export declare const reorderAdminRolesRequestSchema: z.ZodObject<{
38
+ ids: z.ZodArray<z.ZodUUID>;
39
+ }, z.core.$strip>;
40
+ export type ReorderAdminRolesRequest = z.infer<typeof reorderAdminRolesRequestSchema>;
41
+ export declare const getRolesForUserRequestSchema: z.ZodObject<{
42
+ userId: z.ZodUUID;
43
+ }, z.core.$strip>;
44
+ export type GetRolesForUserRequest = z.infer<typeof getRolesForUserRequestSchema>;
45
+ export declare const setRolesForUserRequestSchema: z.ZodObject<{
46
+ userId: z.ZodUUID;
47
+ roleIds: z.ZodArray<z.ZodUUID>;
48
+ }, z.core.$strip>;
49
+ export type SetRolesForUserRequest = z.infer<typeof setRolesForUserRequestSchema>;
50
+ export declare const adminRoleResponseSchema: z.ZodObject<{
51
+ id: z.ZodString;
52
+ vid: z.ZodNumber;
53
+ name: z.ZodString;
54
+ machine_name: z.ZodString;
55
+ description: z.ZodNullable<z.ZodString>;
56
+ order: z.ZodNumber;
57
+ created_at: z.ZodDate;
58
+ updated_at: z.ZodDate;
59
+ }, z.core.$strip>;
60
+ export type AdminRoleResponse = z.infer<typeof adminRoleResponseSchema>;
61
+ export declare const adminRoleListResponseSchema: z.ZodObject<{
62
+ roles: z.ZodArray<z.ZodObject<{
63
+ id: z.ZodString;
64
+ vid: z.ZodNumber;
65
+ name: z.ZodString;
66
+ machine_name: z.ZodString;
67
+ description: z.ZodNullable<z.ZodString>;
68
+ order: z.ZodNumber;
69
+ created_at: z.ZodDate;
70
+ updated_at: z.ZodDate;
71
+ }, z.core.$strip>>;
72
+ }, z.core.$strip>;
73
+ export type AdminRoleListResponse = z.infer<typeof adminRoleListResponseSchema>;
74
+ /**
75
+ * User-roles editor payload. `userId` is echoed back so the caller can
76
+ * match async writes; `roles` is the authoritative role-set after the
77
+ * write, shaped as full role rows so the drawer renders names without a
78
+ * second fetch.
79
+ */
80
+ export declare const userRolesResponseSchema: z.ZodObject<{
81
+ userId: z.ZodString;
82
+ roles: z.ZodArray<z.ZodObject<{
83
+ id: z.ZodString;
84
+ vid: z.ZodNumber;
85
+ name: z.ZodString;
86
+ machine_name: z.ZodString;
87
+ description: z.ZodNullable<z.ZodString>;
88
+ order: z.ZodNumber;
89
+ created_at: z.ZodDate;
90
+ updated_at: z.ZodDate;
91
+ }, z.core.$strip>>;
92
+ }, z.core.$strip>;
93
+ export type UserRolesResponse = z.infer<typeof userRolesResponseSchema>;
94
+ /** Empty response for void-returning mutations (delete, reorder). */
95
+ export declare const okResponseSchema: z.ZodObject<{
96
+ ok: z.ZodLiteral<true>;
97
+ }, z.core.$strip>;
98
+ export type OkResponse = z.infer<typeof okResponseSchema>;
99
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-roles/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA2CvB,eAAO,MAAM,2BAA2B,+CAA0B,CAAA;AAClE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,eAAO,MAAM,yBAAyB;;iBAEpC,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E,eAAO,MAAM,4BAA4B;;;;;iBAKvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,4BAA4B;;;;;;;;iBAUvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,8BAA8B;;iBAEzC,CAAA;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAA;AAErF,eAAO,MAAM,4BAA4B;;iBAEvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAMjF,eAAO,MAAM,uBAAuB;;;;;;;;;iBASlC,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE,eAAO,MAAM,2BAA2B;;;;;;;;;;;iBAEtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBAGlC,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE,qEAAqE;AACrE,eAAO,MAAM,gBAAgB;;iBAAoC,CAAA;AACjE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { uuidSchema } from '@byline/core/validation';
9
+ import { z } from 'zod';
10
+ /**
11
+ * Zod request/response schemas for the admin-roles commands.
12
+ *
13
+ * `vid` gates writes for optimistic concurrency; `machine_name` is
14
+ * accepted only at create time and validated as a slug-shaped string.
15
+ *
16
+ * Reorder takes the full ordered id list — the index in the array
17
+ * becomes each role's new `order` value. The list-view UX is "drag,
18
+ * then save the whole order" so a partial-update payload would add no
19
+ * value and complicate atomicity.
20
+ */
21
+ // ---------------------------------------------------------------------------
22
+ // Field-level schemas
23
+ // ---------------------------------------------------------------------------
24
+ const idSchema = uuidSchema;
25
+ const vidSchema = z
26
+ .number({ message: 'vid is required' })
27
+ .int({ message: 'vid must be an integer' })
28
+ .positive({ message: 'vid must be positive' });
29
+ const nameSchema = z.string().min(1).max(128);
30
+ const machineNameSchema = z
31
+ .string()
32
+ .min(1)
33
+ .max(128)
34
+ .regex(/^[a-z0-9][a-z0-9_-]*$/, {
35
+ message: 'machine_name may contain lowercase letters, numbers, hyphens, and underscores only',
36
+ });
37
+ const descriptionSchema = z.string().max(2000).nullish();
38
+ const orderSchema = z.number().int().min(0);
39
+ // ---------------------------------------------------------------------------
40
+ // Requests
41
+ // ---------------------------------------------------------------------------
42
+ export const listAdminRolesRequestSchema = z.object({}).optional();
43
+ export const getAdminRoleRequestSchema = z.object({
44
+ id: idSchema,
45
+ });
46
+ export const createAdminRoleRequestSchema = z.object({
47
+ name: nameSchema,
48
+ machine_name: machineNameSchema,
49
+ description: descriptionSchema,
50
+ order: orderSchema.optional(),
51
+ });
52
+ export const updateAdminRoleRequestSchema = z.object({
53
+ id: idSchema,
54
+ vid: vidSchema,
55
+ patch: z
56
+ .object({
57
+ name: nameSchema.optional(),
58
+ description: descriptionSchema,
59
+ order: orderSchema.optional(),
60
+ })
61
+ .refine((p) => Object.keys(p).length > 0, { message: 'patch cannot be empty' }),
62
+ });
63
+ export const deleteAdminRoleRequestSchema = z.object({
64
+ id: idSchema,
65
+ vid: vidSchema,
66
+ });
67
+ export const reorderAdminRolesRequestSchema = z.object({
68
+ ids: z.array(idSchema).min(1, { message: 'at least one id is required' }),
69
+ });
70
+ export const getRolesForUserRequestSchema = z.object({
71
+ userId: idSchema,
72
+ });
73
+ export const setRolesForUserRequestSchema = z.object({
74
+ userId: idSchema,
75
+ roleIds: z.array(idSchema),
76
+ });
77
+ // ---------------------------------------------------------------------------
78
+ // Responses
79
+ // ---------------------------------------------------------------------------
80
+ export const adminRoleResponseSchema = z.object({
81
+ id: z.string(),
82
+ vid: z.number().int(),
83
+ name: z.string(),
84
+ machine_name: z.string(),
85
+ description: z.string().nullable(),
86
+ order: z.number().int(),
87
+ created_at: z.date(),
88
+ updated_at: z.date(),
89
+ });
90
+ export const adminRoleListResponseSchema = z.object({
91
+ roles: z.array(adminRoleResponseSchema),
92
+ });
93
+ /**
94
+ * User-roles editor payload. `userId` is echoed back so the caller can
95
+ * match async writes; `roles` is the authoritative role-set after the
96
+ * write, shaped as full role rows so the drawer renders names without a
97
+ * second fetch.
98
+ */
99
+ export const userRolesResponseSchema = z.object({
100
+ userId: z.string(),
101
+ roles: z.array(adminRoleResponseSchema),
102
+ });
103
+ /** Empty response for void-returning mutations (delete, reorder). */
104
+ export const okResponseSchema = z.object({ ok: z.literal(true) });
105
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/modules/admin-roles/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { AdminStore } from '../../store.js';
9
+ import type { AdminRoleListResponse, AdminRoleResponse, CreateAdminRoleRequest, DeleteAdminRoleRequest, GetAdminRoleRequest, GetRolesForUserRequest, ReorderAdminRolesRequest, SetRolesForUserRequest, UpdateAdminRoleRequest, UserRolesResponse } from './schemas.js';
10
+ /**
11
+ * Business logic for administering admin roles.
12
+ *
13
+ * Owns four concerns the repository deliberately avoids:
14
+ *
15
+ * 1. **Domain invariants.** `machine_name` uniqueness pre-check on
16
+ * create — the unique index is the ultimate backstop, but the
17
+ * pre-check produces a clean domain error rather than a raw
18
+ * Postgres code.
19
+ * 2. **DTO shaping.** Raw rows are shaped through `toAdminRole` so
20
+ * the response contract is owned in one place.
21
+ * 3. **Optimistic-concurrency plumbing.** The repo gates writes on
22
+ * `expectedVid`; the service threads it from the validated request
23
+ * shape. Version conflicts surface as
24
+ * `AdminRolesError(VERSION_CONFLICT)` from the adapter; the service
25
+ * does not catch them.
26
+ * 4. **Cross-table validation.** The user-roles editor validates the
27
+ * user and every referenced role exists before mutating the join
28
+ * table — clean errors over raw FK violations.
29
+ *
30
+ * Roles do not need a self-target invariant the way users do
31
+ * (no "self-delete" concept), so role-CRUD service methods are
32
+ * actor-agnostic and the ability check at the command boundary is the
33
+ * only authorisation.
34
+ */
35
+ export declare class AdminRolesService {
36
+ #private;
37
+ constructor(deps: {
38
+ store: AdminStore;
39
+ });
40
+ listRoles(): Promise<AdminRoleListResponse>;
41
+ getRole(request: GetAdminRoleRequest): Promise<AdminRoleResponse>;
42
+ createRole(request: CreateAdminRoleRequest): Promise<AdminRoleResponse>;
43
+ updateRole(request: UpdateAdminRoleRequest): Promise<AdminRoleResponse>;
44
+ deleteRole(request: DeleteAdminRoleRequest): Promise<void>;
45
+ reorderRoles(request: ReorderAdminRolesRequest): Promise<void>;
46
+ getRolesForUser(request: GetRolesForUserRequest): Promise<UserRolesResponse>;
47
+ setRolesForUser(request: SetRolesForUserRequest): Promise<UserRolesResponse>;
48
+ }
49
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-roles/service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,cAAc,CAAA;AAErB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,iBAAiB;;gBAGhB,IAAI,EAAE;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE;IAIjC,SAAS,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAK3C,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAMjE,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAevE,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOvE,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAO5E,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyBnF"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { toAdminRole } from './dto.js';
9
+ import { ERR_ADMIN_ROLE_MACHINE_NAME_IN_USE, ERR_ADMIN_ROLE_NOT_FOUND, ERR_ADMIN_ROLE_USER_NOT_FOUND, } from './errors.js';
10
+ /**
11
+ * Business logic for administering admin roles.
12
+ *
13
+ * Owns four concerns the repository deliberately avoids:
14
+ *
15
+ * 1. **Domain invariants.** `machine_name` uniqueness pre-check on
16
+ * create — the unique index is the ultimate backstop, but the
17
+ * pre-check produces a clean domain error rather than a raw
18
+ * Postgres code.
19
+ * 2. **DTO shaping.** Raw rows are shaped through `toAdminRole` so
20
+ * the response contract is owned in one place.
21
+ * 3. **Optimistic-concurrency plumbing.** The repo gates writes on
22
+ * `expectedVid`; the service threads it from the validated request
23
+ * shape. Version conflicts surface as
24
+ * `AdminRolesError(VERSION_CONFLICT)` from the adapter; the service
25
+ * does not catch them.
26
+ * 4. **Cross-table validation.** The user-roles editor validates the
27
+ * user and every referenced role exists before mutating the join
28
+ * table — clean errors over raw FK violations.
29
+ *
30
+ * Roles do not need a self-target invariant the way users do
31
+ * (no "self-delete" concept), so role-CRUD service methods are
32
+ * actor-agnostic and the ability check at the command boundary is the
33
+ * only authorisation.
34
+ */
35
+ export class AdminRolesService {
36
+ #store;
37
+ constructor(deps) {
38
+ this.#store = deps.store;
39
+ }
40
+ async listRoles() {
41
+ const rows = await this.#store.adminRoles.list();
42
+ return { roles: rows.map(toAdminRole) };
43
+ }
44
+ async getRole(request) {
45
+ const row = await this.#store.adminRoles.getById(request.id);
46
+ if (!row)
47
+ throw ERR_ADMIN_ROLE_NOT_FOUND();
48
+ return toAdminRole(row);
49
+ }
50
+ async createRole(request) {
51
+ // Pre-check for machine_name conflict so the common case returns a
52
+ // domain-specific error rather than the raw unique-violation code.
53
+ const existing = await this.#store.adminRoles.getByMachineName(request.machine_name);
54
+ if (existing)
55
+ throw ERR_ADMIN_ROLE_MACHINE_NAME_IN_USE();
56
+ const row = await this.#store.adminRoles.create({
57
+ name: request.name,
58
+ machine_name: request.machine_name,
59
+ description: request.description ?? null,
60
+ order: request.order,
61
+ });
62
+ return toAdminRole(row);
63
+ }
64
+ async updateRole(request) {
65
+ const current = await this.#store.adminRoles.getById(request.id);
66
+ if (!current)
67
+ throw ERR_ADMIN_ROLE_NOT_FOUND();
68
+ const row = await this.#store.adminRoles.update(request.id, request.vid, request.patch);
69
+ return toAdminRole(row);
70
+ }
71
+ async deleteRole(request) {
72
+ const exists = await this.#store.adminRoles.getById(request.id);
73
+ if (!exists)
74
+ throw ERR_ADMIN_ROLE_NOT_FOUND();
75
+ await this.#store.adminRoles.delete(request.id, request.vid);
76
+ }
77
+ async reorderRoles(request) {
78
+ await this.#store.adminRoles.reorder(request.ids);
79
+ }
80
+ async getRolesForUser(request) {
81
+ const user = await this.#store.adminUsers.getById(request.userId);
82
+ if (!user)
83
+ throw ERR_ADMIN_ROLE_USER_NOT_FOUND();
84
+ const rows = await this.#store.adminRoles.listRolesForUser(request.userId);
85
+ return { userId: request.userId, roles: rows.map(toAdminRole) };
86
+ }
87
+ async setRolesForUser(request) {
88
+ const user = await this.#store.adminUsers.getById(request.userId);
89
+ if (!user)
90
+ throw ERR_ADMIN_ROLE_USER_NOT_FOUND();
91
+ // Validate every referenced role exists. N round-trips, but role
92
+ // assignment payloads are small by design (typically < 10 roles)
93
+ // and surfacing a clean `notFound` beats a raw FK violation.
94
+ if (request.roleIds.length > 0) {
95
+ const found = await Promise.all(request.roleIds.map((id) => this.#store.adminRoles.getById(id)));
96
+ const missing = request.roleIds.filter((_, i) => found[i] == null);
97
+ if (missing.length > 0) {
98
+ throw ERR_ADMIN_ROLE_NOT_FOUND({
99
+ message: `One or more referenced roles do not exist: ${missing.join(', ')}`,
100
+ });
101
+ }
102
+ }
103
+ await this.#store.adminRoles.setRolesForUser(request.userId, request.roleIds);
104
+ // Return the freshly stored set, shaped — saves the editor a second
105
+ // round-trip and guards against any normalisation the repo might apply.
106
+ const stored = await this.#store.adminRoles.listRolesForUser(request.userId);
107
+ return { userId: request.userId, roles: stored.map(toAdminRole) };
108
+ }
109
+ }
110
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/admin-roles/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { AbilityRegistry } from '@byline/auth';
9
+ /**
10
+ * Ability keys for the admin-users module.
11
+ *
12
+ * Dot-notation rather than Modulus' colon-notation — keeps one consistent
13
+ * hierarchy across the whole platform alongside `collections.<path>.<verb>`
14
+ * from core.
15
+ *
16
+ * `changePassword` is split out from `update` deliberately: setting
17
+ * someone else's password is a higher-trust operation than editing their
18
+ * profile fields, and the role editor UI benefits from naming it
19
+ * explicitly. A role can grant `update` without implicitly granting
20
+ * `changePassword`.
21
+ *
22
+ * Self-service (changing *own* password, email, etc.) does **not** use
23
+ * any of these keys. That flow lives in the separate `account` module
24
+ * where the actor is the target by definition; the `admin.users.*` keys
25
+ * are strictly for administering other admin users.
26
+ */
27
+ export declare const ADMIN_USERS_ABILITIES: {
28
+ readonly read: "admin.users.read";
29
+ readonly create: "admin.users.create";
30
+ readonly update: "admin.users.update";
31
+ readonly delete: "admin.users.delete";
32
+ readonly changePassword: "admin.users.changePassword";
33
+ };
34
+ export type AdminUsersAbilityKey = (typeof ADMIN_USERS_ABILITIES)[keyof typeof ADMIN_USERS_ABILITIES];
35
+ /**
36
+ * Register every admin-users ability with the framework's `AbilityRegistry`.
37
+ * Called from `registerAdminAbilities(registry)` at package level, which
38
+ * the webapp wires into `initBylineCore()`.
39
+ */
40
+ export declare function registerAdminUsersAbilities(registry: AbilityRegistry): void;
41
+ //# sourceMappingURL=abilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abilities.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-users/abilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB;;;;;;CAMxB,CAAA;AAEV,MAAM,MAAM,oBAAoB,GAC9B,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAA;AAEpE;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CA+B3E"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ /**
9
+ * Ability keys for the admin-users module.
10
+ *
11
+ * Dot-notation rather than Modulus' colon-notation — keeps one consistent
12
+ * hierarchy across the whole platform alongside `collections.<path>.<verb>`
13
+ * from core.
14
+ *
15
+ * `changePassword` is split out from `update` deliberately: setting
16
+ * someone else's password is a higher-trust operation than editing their
17
+ * profile fields, and the role editor UI benefits from naming it
18
+ * explicitly. A role can grant `update` without implicitly granting
19
+ * `changePassword`.
20
+ *
21
+ * Self-service (changing *own* password, email, etc.) does **not** use
22
+ * any of these keys. That flow lives in the separate `account` module
23
+ * where the actor is the target by definition; the `admin.users.*` keys
24
+ * are strictly for administering other admin users.
25
+ */
26
+ export const ADMIN_USERS_ABILITIES = {
27
+ read: 'admin.users.read',
28
+ create: 'admin.users.create',
29
+ update: 'admin.users.update',
30
+ delete: 'admin.users.delete',
31
+ changePassword: 'admin.users.changePassword',
32
+ };
33
+ /**
34
+ * Register every admin-users ability with the framework's `AbilityRegistry`.
35
+ * Called from `registerAdminAbilities(registry)` at package level, which
36
+ * the webapp wires into `initBylineCore()`.
37
+ */
38
+ export function registerAdminUsersAbilities(registry) {
39
+ registry.register({
40
+ key: ADMIN_USERS_ABILITIES.read,
41
+ label: 'Read admin users',
42
+ group: 'admin.users',
43
+ source: 'admin',
44
+ });
45
+ registry.register({
46
+ key: ADMIN_USERS_ABILITIES.create,
47
+ label: 'Create admin users',
48
+ group: 'admin.users',
49
+ source: 'admin',
50
+ });
51
+ registry.register({
52
+ key: ADMIN_USERS_ABILITIES.update,
53
+ label: 'Update admin users',
54
+ group: 'admin.users',
55
+ source: 'admin',
56
+ });
57
+ registry.register({
58
+ key: ADMIN_USERS_ABILITIES.delete,
59
+ label: 'Delete admin users',
60
+ group: 'admin.users',
61
+ source: 'admin',
62
+ });
63
+ registry.register({
64
+ key: ADMIN_USERS_ABILITIES.changePassword,
65
+ label: "Change an admin user's password",
66
+ group: 'admin.users',
67
+ source: 'admin',
68
+ });
69
+ }
70
+ //# sourceMappingURL=abilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abilities.js","sourceRoot":"","sources":["../../../src/modules/admin-users/abilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,kBAAkB;IACxB,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,cAAc,EAAE,4BAA4B;CACpC,CAAA;AAKV;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAyB;IACnE,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,qBAAqB,CAAC,IAAI;QAC/B,KAAK,EAAE,kBAAkB;QACzB,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,qBAAqB,CAAC,MAAM;QACjC,KAAK,EAAE,oBAAoB;QAC3B,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,qBAAqB,CAAC,MAAM;QACjC,KAAK,EAAE,oBAAoB;QAC3B,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,qBAAqB,CAAC,MAAM;QACjC,KAAK,EAAE,oBAAoB;QAC3B,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,CAAC;QAChB,GAAG,EAAE,qBAAqB,CAAC,cAAc;QACzC,KAAK,EAAE,iCAAiC;QACxC,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;AACJ,CAAC"}