@byline/admin 2.3.3 → 2.4.1
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.
- package/dist/abilities.js +5 -24
- package/dist/index.js +8 -30
- package/dist/lib/assert-admin-actor.js +13 -74
- package/dist/lib/create-command.js +6 -16
- package/dist/modules/admin-account/commands.js +35 -24
- package/dist/modules/admin-account/components/change-password.d.ts +8 -0
- package/dist/modules/admin-account/components/change-password.js +192 -0
- package/dist/modules/admin-account/components/change-password.module.js +8 -0
- package/dist/modules/admin-account/components/change-password_module.css +27 -0
- package/dist/modules/admin-account/components/container.d.ts +29 -0
- package/dist/modules/admin-account/components/container.js +298 -0
- package/dist/modules/admin-account/components/container.module.js +28 -0
- package/dist/modules/admin-account/components/container_module.css +106 -0
- package/dist/modules/admin-account/components/update.d.ts +8 -0
- package/dist/modules/admin-account/components/update.js +207 -0
- package/dist/modules/admin-account/components/update.module.js +8 -0
- package/dist/modules/admin-account/components/update_module.css +27 -0
- package/dist/modules/admin-account/errors.js +14 -45
- package/dist/modules/admin-account/index.js +4 -34
- package/dist/modules/admin-account/schemas.js +25 -59
- package/dist/modules/admin-account/service.js +56 -61
- package/dist/modules/admin-permissions/abilities.js +6 -24
- package/dist/modules/admin-permissions/commands.js +42 -28
- package/dist/modules/admin-permissions/components/inspector.d.ts +4 -0
- package/dist/modules/admin-permissions/components/inspector.js +284 -0
- package/dist/modules/admin-permissions/components/inspector.module.js +56 -0
- package/dist/modules/admin-permissions/components/inspector_module.css +238 -0
- package/dist/modules/admin-permissions/dto.js +3 -16
- package/dist/modules/admin-permissions/errors.js +14 -27
- package/dist/modules/admin-permissions/index.js +6 -26
- package/dist/modules/admin-permissions/repository.js +1 -8
- package/dist/modules/admin-permissions/schemas.js +33 -70
- package/dist/modules/admin-permissions/service.js +88 -92
- package/dist/modules/admin-roles/abilities.js +8 -30
- package/dist/modules/admin-roles/commands.js +89 -55
- package/dist/modules/admin-roles/components/create.d.ts +7 -0
- package/dist/modules/admin-roles/components/create.js +177 -0
- package/dist/modules/admin-roles/components/create.module.js +8 -0
- package/dist/modules/admin-roles/components/create_module.css +27 -0
- package/dist/modules/admin-roles/components/permissions.d.ts +10 -0
- package/dist/modules/admin-roles/components/permissions.js +303 -0
- package/dist/modules/admin-roles/components/permissions.module.js +44 -0
- package/dist/modules/admin-roles/components/permissions_module.css +192 -0
- package/dist/modules/admin-roles/components/update.d.ts +8 -0
- package/dist/modules/admin-roles/components/update.js +166 -0
- package/dist/modules/admin-roles/components/update.module.js +8 -0
- package/dist/modules/admin-roles/components/update_module.css +27 -0
- package/dist/modules/admin-roles/dto.js +3 -16
- package/dist/modules/admin-roles/errors.js +16 -40
- package/dist/modules/admin-roles/index.js +6 -26
- package/dist/modules/admin-roles/repository.js +1 -8
- package/dist/modules/admin-roles/schemas.js +41 -71
- package/dist/modules/admin-roles/service.js +79 -82
- package/dist/modules/admin-users/abilities.js +9 -38
- package/dist/modules/admin-users/commands.js +92 -50
- package/dist/modules/admin-users/components/create.d.ts +8 -0
- package/dist/modules/admin-users/components/create.js +268 -0
- package/dist/modules/admin-users/components/create.module.js +10 -0
- package/dist/modules/admin-users/components/create_module.css +45 -0
- package/dist/modules/admin-users/components/roles.d.ts +11 -0
- package/dist/modules/admin-users/components/roles.js +148 -0
- package/dist/modules/admin-users/components/roles.module.js +18 -0
- package/dist/modules/admin-users/components/roles_module.css +75 -0
- package/dist/modules/admin-users/components/set-password.d.ts +8 -0
- package/dist/modules/admin-users/components/set-password.js +170 -0
- package/dist/modules/admin-users/components/set-password.module.js +9 -0
- package/dist/modules/admin-users/components/set-password_module.css +31 -0
- package/dist/modules/admin-users/components/update.d.ts +8 -0
- package/dist/modules/admin-users/components/update.js +254 -0
- package/dist/modules/admin-users/components/update.module.js +9 -0
- package/dist/modules/admin-users/components/update_module.css +34 -0
- package/dist/modules/admin-users/dto.js +3 -18
- package/dist/modules/admin-users/errors.js +17 -43
- package/dist/modules/admin-users/index.js +7 -27
- package/dist/modules/admin-users/repository.js +1 -8
- package/dist/modules/admin-users/schemas.js +44 -75
- package/dist/modules/admin-users/seed-super-admin.js +9 -34
- package/dist/modules/admin-users/service.js +76 -91
- package/dist/modules/auth/components/sign-in-form.d.ts +12 -0
- package/dist/modules/auth/components/sign-in-form.js +115 -0
- package/dist/modules/auth/components/sign-in-form.module.js +12 -0
- package/dist/modules/auth/components/sign-in-form_module.css +41 -0
- package/dist/modules/auth/index.js +3 -24
- package/dist/modules/auth/jwt-session-provider.js +179 -149
- package/dist/modules/auth/password.js +11 -53
- package/dist/modules/auth/phc.js +21 -54
- package/dist/modules/auth/refresh-tokens-repository.js +1 -8
- package/dist/modules/auth/resolve-actor.js +6 -28
- package/dist/services/admin-services-context.d.ts +16 -0
- package/dist/services/admin-services-context.js +13 -0
- package/dist/services/admin-services-types.d.ts +129 -0
- package/dist/services/admin-services-types.js +1 -0
- package/dist/store.js +1 -8
- package/dist/vendor/noble-argon2/_blake.js +277 -45
- package/dist/vendor/noble-argon2/_md.js +81 -136
- package/dist/vendor/noble-argon2/_u64.js +65 -67
- package/dist/vendor/noble-argon2/argon2.js +181 -342
- package/dist/vendor/noble-argon2/blake2.js +252 -327
- package/dist/vendor/noble-argon2/utils.js +110 -490
- package/dist/vendor/noble-argon2/utils.js.LICENSE.txt +1 -0
- package/package.json +89 -10
- package/src/abilities.ts +32 -0
- package/src/declarations.d.ts +4 -0
- package/src/index.ts +39 -0
- package/src/lib/assert-admin-actor.ts +90 -0
- package/src/lib/create-command.ts +109 -0
- package/src/modules/admin-account/commands.ts +76 -0
- package/src/modules/admin-account/components/change-password.module.css +40 -0
- package/src/modules/admin-account/components/change-password.tsx +232 -0
- package/src/modules/admin-account/components/container.module.css +158 -0
- package/src/modules/admin-account/components/container.tsx +229 -0
- package/src/modules/admin-account/components/update.module.css +40 -0
- package/src/modules/admin-account/components/update.tsx +263 -0
- package/src/modules/admin-account/errors.ts +75 -0
- package/src/modules/admin-account/index.ts +60 -0
- package/src/modules/admin-account/schemas.ts +84 -0
- package/src/modules/admin-account/service.ts +92 -0
- package/src/modules/admin-permissions/abilities.ts +46 -0
- package/src/modules/admin-permissions/commands.ts +103 -0
- package/src/modules/admin-permissions/components/inspector.module.css +326 -0
- package/src/modules/admin-permissions/components/inspector.tsx +298 -0
- package/src/modules/admin-permissions/dto.ts +28 -0
- package/src/modules/admin-permissions/errors.ts +57 -0
- package/src/modules/admin-permissions/index.ts +72 -0
- package/src/modules/admin-permissions/repository.ts +49 -0
- package/src/modules/admin-permissions/schemas.ts +128 -0
- package/src/modules/admin-permissions/service.ts +137 -0
- package/src/modules/admin-roles/abilities.ts +62 -0
- package/src/modules/admin-roles/commands.ts +161 -0
- package/src/modules/admin-roles/components/create.module.css +40 -0
- package/src/modules/admin-roles/components/create.tsx +218 -0
- package/src/modules/admin-roles/components/permissions.module.css +279 -0
- package/src/modules/admin-roles/components/permissions.tsx +396 -0
- package/src/modules/admin-roles/components/update.module.css +40 -0
- package/src/modules/admin-roles/components/update.tsx +218 -0
- package/src/modules/admin-roles/dto.ts +30 -0
- package/src/modules/admin-roles/errors.ts +76 -0
- package/src/modules/admin-roles/index.ts +81 -0
- package/src/modules/admin-roles/repository.ts +96 -0
- package/src/modules/admin-roles/schemas.ts +139 -0
- package/src/modules/admin-roles/service.ts +136 -0
- package/src/modules/admin-users/abilities.ts +76 -0
- package/src/modules/admin-users/commands.ts +157 -0
- package/src/modules/admin-users/components/create.module.css +63 -0
- package/src/modules/admin-users/components/create.tsx +323 -0
- package/src/modules/admin-users/components/roles.module.css +119 -0
- package/src/modules/admin-users/components/roles.tsx +172 -0
- package/src/modules/admin-users/components/set-password.module.css +46 -0
- package/src/modules/admin-users/components/set-password.tsx +199 -0
- package/src/modules/admin-users/components/update.module.css +49 -0
- package/src/modules/admin-users/components/update.tsx +328 -0
- package/src/modules/admin-users/dto.ts +39 -0
- package/src/modules/admin-users/errors.ts +84 -0
- package/src/modules/admin-users/index.ts +91 -0
- package/src/modules/admin-users/repository.ts +161 -0
- package/src/modules/admin-users/schemas.ts +168 -0
- package/src/modules/admin-users/seed-super-admin.ts +102 -0
- package/src/modules/admin-users/service.ts +166 -0
- package/src/modules/auth/components/sign-in-form.module.css +62 -0
- package/src/modules/auth/components/sign-in-form.tsx +132 -0
- package/src/modules/auth/index.ts +31 -0
- package/src/modules/auth/jwt-session-provider.ts +301 -0
- package/src/modules/auth/password.ts +94 -0
- package/src/modules/auth/phc.ts +121 -0
- package/src/modules/auth/refresh-tokens-repository.ts +74 -0
- package/src/modules/auth/resolve-actor.ts +42 -0
- package/src/services/admin-services-context.tsx +52 -0
- package/src/services/admin-services-types.ts +177 -0
- package/src/store.ts +32 -0
- package/src/vendor/noble-argon2/LICENSE +21 -0
- package/src/vendor/noble-argon2/README.md +87 -0
- package/src/vendor/noble-argon2/_blake.ts +58 -0
- package/src/vendor/noble-argon2/_md.ts +223 -0
- package/src/vendor/noble-argon2/_u64.ts +118 -0
- package/src/vendor/noble-argon2/argon2.ts +668 -0
- package/src/vendor/noble-argon2/blake2.ts +583 -0
- package/src/vendor/noble-argon2/utils.ts +849 -0
|
@@ -1,83 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
// ---------------------------------------------------------------------------
|
|
1
|
+
import { uuidSchema } from "@byline/core/validation";
|
|
2
|
+
import { z } from "zod";
|
|
24
3
|
const idSchema = uuidSchema;
|
|
25
|
-
const vidSchema = z
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
4
|
+
const vidSchema = z.number({
|
|
5
|
+
message: 'vid is required'
|
|
6
|
+
}).int({
|
|
7
|
+
message: 'vid must be an integer'
|
|
8
|
+
}).positive({
|
|
9
|
+
message: 'vid must be positive'
|
|
10
|
+
});
|
|
29
11
|
const nameSchema = z.string().min(1).max(128);
|
|
30
|
-
const machineNameSchema = z
|
|
31
|
-
|
|
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',
|
|
12
|
+
const machineNameSchema = z.string().min(1).max(128).regex(/^[a-z0-9][a-z0-9_-]*$/, {
|
|
13
|
+
message: 'machine_name may contain lowercase letters, numbers, hyphens, and underscores only'
|
|
36
14
|
});
|
|
37
15
|
const descriptionSchema = z.string().max(2000).nullish();
|
|
38
16
|
const orderSchema = z.number().int().min(0);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export const listAdminRolesRequestSchema = z.object({}).optional();
|
|
43
|
-
export const getAdminRoleRequestSchema = z.object({
|
|
44
|
-
id: idSchema,
|
|
17
|
+
const listAdminRolesRequestSchema = z.object({}).optional();
|
|
18
|
+
const getAdminRoleRequestSchema = z.object({
|
|
19
|
+
id: idSchema
|
|
45
20
|
});
|
|
46
|
-
|
|
21
|
+
const createAdminRoleRequestSchema = z.object({
|
|
47
22
|
name: nameSchema,
|
|
48
23
|
machine_name: machineNameSchema,
|
|
49
24
|
description: descriptionSchema,
|
|
50
|
-
order: orderSchema.optional()
|
|
25
|
+
order: orderSchema.optional()
|
|
51
26
|
});
|
|
52
|
-
|
|
27
|
+
const updateAdminRoleRequestSchema = z.object({
|
|
53
28
|
id: idSchema,
|
|
54
29
|
vid: vidSchema,
|
|
55
|
-
patch: z
|
|
56
|
-
.object({
|
|
30
|
+
patch: z.object({
|
|
57
31
|
name: nameSchema.optional(),
|
|
58
32
|
description: descriptionSchema,
|
|
59
|
-
order: orderSchema.optional()
|
|
33
|
+
order: orderSchema.optional()
|
|
34
|
+
}).refine((p)=>Object.keys(p).length > 0, {
|
|
35
|
+
message: 'patch cannot be empty'
|
|
60
36
|
})
|
|
61
|
-
.refine((p) => Object.keys(p).length > 0, { message: 'patch cannot be empty' }),
|
|
62
37
|
});
|
|
63
|
-
|
|
38
|
+
const deleteAdminRoleRequestSchema = z.object({
|
|
64
39
|
id: idSchema,
|
|
65
|
-
vid: vidSchema
|
|
40
|
+
vid: vidSchema
|
|
66
41
|
});
|
|
67
|
-
|
|
68
|
-
ids: z.array(idSchema).min(1, {
|
|
42
|
+
const reorderAdminRolesRequestSchema = z.object({
|
|
43
|
+
ids: z.array(idSchema).min(1, {
|
|
44
|
+
message: 'at least one id is required'
|
|
45
|
+
})
|
|
69
46
|
});
|
|
70
|
-
|
|
71
|
-
userId: idSchema
|
|
47
|
+
const getRolesForUserRequestSchema = z.object({
|
|
48
|
+
userId: idSchema
|
|
72
49
|
});
|
|
73
|
-
|
|
50
|
+
const setRolesForUserRequestSchema = z.object({
|
|
74
51
|
userId: idSchema,
|
|
75
|
-
roleIds: z.array(idSchema)
|
|
52
|
+
roleIds: z.array(idSchema)
|
|
76
53
|
});
|
|
77
|
-
|
|
78
|
-
// Responses
|
|
79
|
-
// ---------------------------------------------------------------------------
|
|
80
|
-
export const adminRoleResponseSchema = z.object({
|
|
54
|
+
const adminRoleResponseSchema = z.object({
|
|
81
55
|
id: z.string(),
|
|
82
56
|
vid: z.number().int(),
|
|
83
57
|
name: z.string(),
|
|
@@ -85,20 +59,16 @@ export const adminRoleResponseSchema = z.object({
|
|
|
85
59
|
description: z.string().nullable(),
|
|
86
60
|
order: z.number().int(),
|
|
87
61
|
created_at: z.date(),
|
|
88
|
-
updated_at: z.date()
|
|
62
|
+
updated_at: z.date()
|
|
89
63
|
});
|
|
90
|
-
|
|
91
|
-
roles: z.array(adminRoleResponseSchema)
|
|
64
|
+
const adminRoleListResponseSchema = z.object({
|
|
65
|
+
roles: z.array(adminRoleResponseSchema)
|
|
92
66
|
});
|
|
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({
|
|
67
|
+
const userRolesResponseSchema = z.object({
|
|
100
68
|
userId: z.string(),
|
|
101
|
-
roles: z.array(adminRoleResponseSchema)
|
|
69
|
+
roles: z.array(adminRoleResponseSchema)
|
|
70
|
+
});
|
|
71
|
+
const okResponseSchema = z.object({
|
|
72
|
+
ok: z.literal(true)
|
|
102
73
|
});
|
|
103
|
-
|
|
104
|
-
export const okResponseSchema = z.object({ ok: z.literal(true) });
|
|
74
|
+
export { adminRoleListResponseSchema, adminRoleResponseSchema, createAdminRoleRequestSchema, deleteAdminRoleRequestSchema, getAdminRoleRequestSchema, getRolesForUserRequestSchema, listAdminRolesRequestSchema, okResponseSchema, reorderAdminRolesRequestSchema, setRolesForUserRequestSchema, updateAdminRoleRequestSchema, userRolesResponseSchema };
|
|
@@ -1,109 +1,106 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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;
|
|
1
|
+
import { toAdminRole } from "./dto.js";
|
|
2
|
+
import { ERR_ADMIN_ROLE_MACHINE_NAME_IN_USE, ERR_ADMIN_ROLE_NOT_FOUND, ERR_ADMIN_ROLE_USER_NOT_FOUND } from "./errors.js";
|
|
3
|
+
function _check_private_redeclaration(obj, privateCollection) {
|
|
4
|
+
if (privateCollection.has(obj)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
5
|
+
}
|
|
6
|
+
function _class_apply_descriptor_get(receiver, descriptor) {
|
|
7
|
+
if (descriptor.get) return descriptor.get.call(receiver);
|
|
8
|
+
return descriptor.value;
|
|
9
|
+
}
|
|
10
|
+
function _class_apply_descriptor_set(receiver, descriptor, value) {
|
|
11
|
+
if (descriptor.set) descriptor.set.call(receiver, value);
|
|
12
|
+
else {
|
|
13
|
+
if (!descriptor.writable) throw new TypeError("attempted to set read only private field");
|
|
14
|
+
descriptor.value = value;
|
|
39
15
|
}
|
|
16
|
+
}
|
|
17
|
+
function _class_extract_field_descriptor(receiver, privateMap, action) {
|
|
18
|
+
if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");
|
|
19
|
+
return privateMap.get(receiver);
|
|
20
|
+
}
|
|
21
|
+
function _class_private_field_get(receiver, privateMap) {
|
|
22
|
+
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
|
|
23
|
+
return _class_apply_descriptor_get(receiver, descriptor);
|
|
24
|
+
}
|
|
25
|
+
function _class_private_field_init(obj, privateMap, value) {
|
|
26
|
+
_check_private_redeclaration(obj, privateMap);
|
|
27
|
+
privateMap.set(obj, value);
|
|
28
|
+
}
|
|
29
|
+
function _class_private_field_set(receiver, privateMap, value) {
|
|
30
|
+
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
|
|
31
|
+
_class_apply_descriptor_set(receiver, descriptor, value);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
var _store = /*#__PURE__*/ new WeakMap();
|
|
35
|
+
class AdminRolesService {
|
|
40
36
|
async listRoles() {
|
|
41
|
-
const rows = await this
|
|
42
|
-
return {
|
|
37
|
+
const rows = await _class_private_field_get(this, _store).adminRoles.list();
|
|
38
|
+
return {
|
|
39
|
+
roles: rows.map(toAdminRole)
|
|
40
|
+
};
|
|
43
41
|
}
|
|
44
42
|
async getRole(request) {
|
|
45
|
-
const row = await this
|
|
46
|
-
if (!row)
|
|
47
|
-
throw ERR_ADMIN_ROLE_NOT_FOUND();
|
|
43
|
+
const row = await _class_private_field_get(this, _store).adminRoles.getById(request.id);
|
|
44
|
+
if (!row) throw ERR_ADMIN_ROLE_NOT_FOUND();
|
|
48
45
|
return toAdminRole(row);
|
|
49
46
|
}
|
|
50
47
|
async createRole(request) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
if (existing)
|
|
55
|
-
throw ERR_ADMIN_ROLE_MACHINE_NAME_IN_USE();
|
|
56
|
-
const row = await this.#store.adminRoles.create({
|
|
48
|
+
const existing = await _class_private_field_get(this, _store).adminRoles.getByMachineName(request.machine_name);
|
|
49
|
+
if (existing) throw ERR_ADMIN_ROLE_MACHINE_NAME_IN_USE();
|
|
50
|
+
const row = await _class_private_field_get(this, _store).adminRoles.create({
|
|
57
51
|
name: request.name,
|
|
58
52
|
machine_name: request.machine_name,
|
|
59
53
|
description: request.description ?? null,
|
|
60
|
-
order: request.order
|
|
54
|
+
order: request.order
|
|
61
55
|
});
|
|
62
56
|
return toAdminRole(row);
|
|
63
57
|
}
|
|
64
58
|
async updateRole(request) {
|
|
65
|
-
const current = await this
|
|
66
|
-
if (!current)
|
|
67
|
-
|
|
68
|
-
const row = await this.#store.adminRoles.update(request.id, request.vid, request.patch);
|
|
59
|
+
const current = await _class_private_field_get(this, _store).adminRoles.getById(request.id);
|
|
60
|
+
if (!current) throw ERR_ADMIN_ROLE_NOT_FOUND();
|
|
61
|
+
const row = await _class_private_field_get(this, _store).adminRoles.update(request.id, request.vid, request.patch);
|
|
69
62
|
return toAdminRole(row);
|
|
70
63
|
}
|
|
71
64
|
async deleteRole(request) {
|
|
72
|
-
const exists = await this
|
|
73
|
-
if (!exists)
|
|
74
|
-
|
|
75
|
-
await this.#store.adminRoles.delete(request.id, request.vid);
|
|
65
|
+
const exists = await _class_private_field_get(this, _store).adminRoles.getById(request.id);
|
|
66
|
+
if (!exists) throw ERR_ADMIN_ROLE_NOT_FOUND();
|
|
67
|
+
await _class_private_field_get(this, _store).adminRoles.delete(request.id, request.vid);
|
|
76
68
|
}
|
|
77
69
|
async reorderRoles(request) {
|
|
78
|
-
await this
|
|
70
|
+
await _class_private_field_get(this, _store).adminRoles.reorder(request.ids);
|
|
79
71
|
}
|
|
80
72
|
async getRolesForUser(request) {
|
|
81
|
-
const user = await this
|
|
82
|
-
if (!user)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
const user = await _class_private_field_get(this, _store).adminUsers.getById(request.userId);
|
|
74
|
+
if (!user) throw ERR_ADMIN_ROLE_USER_NOT_FOUND();
|
|
75
|
+
const rows = await _class_private_field_get(this, _store).adminRoles.listRolesForUser(request.userId);
|
|
76
|
+
return {
|
|
77
|
+
userId: request.userId,
|
|
78
|
+
roles: rows.map(toAdminRole)
|
|
79
|
+
};
|
|
86
80
|
}
|
|
87
81
|
async setRolesForUser(request) {
|
|
88
|
-
const user = await this
|
|
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.
|
|
82
|
+
const user = await _class_private_field_get(this, _store).adminUsers.getById(request.userId);
|
|
83
|
+
if (!user) throw ERR_ADMIN_ROLE_USER_NOT_FOUND();
|
|
94
84
|
if (request.roleIds.length > 0) {
|
|
95
|
-
const found = await Promise.all(request.roleIds.map((id)
|
|
96
|
-
const missing = request.roleIds.filter((_, i)
|
|
97
|
-
if (missing.length > 0) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
}
|
|
85
|
+
const found = await Promise.all(request.roleIds.map((id)=>_class_private_field_get(this, _store).adminRoles.getById(id)));
|
|
86
|
+
const missing = request.roleIds.filter((_, i)=>null == found[i]);
|
|
87
|
+
if (missing.length > 0) throw ERR_ADMIN_ROLE_NOT_FOUND({
|
|
88
|
+
message: `One or more referenced roles do not exist: ${missing.join(', ')}`
|
|
89
|
+
});
|
|
102
90
|
}
|
|
103
|
-
await this
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
await _class_private_field_get(this, _store).adminRoles.setRolesForUser(request.userId, request.roleIds);
|
|
92
|
+
const stored = await _class_private_field_get(this, _store).adminRoles.listRolesForUser(request.userId);
|
|
93
|
+
return {
|
|
94
|
+
userId: request.userId,
|
|
95
|
+
roles: stored.map(toAdminRole)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
constructor(deps){
|
|
99
|
+
_class_private_field_init(this, _store, {
|
|
100
|
+
writable: true,
|
|
101
|
+
value: void 0
|
|
102
|
+
});
|
|
103
|
+
_class_private_field_set(this, _store, deps.store);
|
|
108
104
|
}
|
|
109
105
|
}
|
|
106
|
+
export { AdminRolesService };
|
|
@@ -1,69 +1,40 @@
|
|
|
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 = {
|
|
1
|
+
const ADMIN_USERS_ABILITIES = {
|
|
27
2
|
read: 'admin.users.read',
|
|
28
3
|
create: 'admin.users.create',
|
|
29
4
|
update: 'admin.users.update',
|
|
30
5
|
delete: 'admin.users.delete',
|
|
31
|
-
changePassword: 'admin.users.changePassword'
|
|
6
|
+
changePassword: 'admin.users.changePassword'
|
|
32
7
|
};
|
|
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) {
|
|
8
|
+
function registerAdminUsersAbilities(registry) {
|
|
39
9
|
registry.register({
|
|
40
10
|
key: ADMIN_USERS_ABILITIES.read,
|
|
41
11
|
label: 'Read admin users',
|
|
42
12
|
group: 'admin.users',
|
|
43
|
-
source: 'admin'
|
|
13
|
+
source: 'admin'
|
|
44
14
|
});
|
|
45
15
|
registry.register({
|
|
46
16
|
key: ADMIN_USERS_ABILITIES.create,
|
|
47
17
|
label: 'Create admin users',
|
|
48
18
|
group: 'admin.users',
|
|
49
|
-
source: 'admin'
|
|
19
|
+
source: 'admin'
|
|
50
20
|
});
|
|
51
21
|
registry.register({
|
|
52
22
|
key: ADMIN_USERS_ABILITIES.update,
|
|
53
23
|
label: 'Update admin users',
|
|
54
24
|
group: 'admin.users',
|
|
55
|
-
source: 'admin'
|
|
25
|
+
source: 'admin'
|
|
56
26
|
});
|
|
57
27
|
registry.register({
|
|
58
28
|
key: ADMIN_USERS_ABILITIES.delete,
|
|
59
29
|
label: 'Delete admin users',
|
|
60
30
|
group: 'admin.users',
|
|
61
|
-
source: 'admin'
|
|
31
|
+
source: 'admin'
|
|
62
32
|
});
|
|
63
33
|
registry.register({
|
|
64
34
|
key: ADMIN_USERS_ABILITIES.changePassword,
|
|
65
35
|
label: "Change an admin user's password",
|
|
66
36
|
group: 'admin.users',
|
|
67
|
-
source: 'admin'
|
|
37
|
+
source: 'admin'
|
|
68
38
|
});
|
|
69
39
|
}
|
|
40
|
+
export { ADMIN_USERS_ABILITIES, registerAdminUsersAbilities };
|
|
@@ -1,71 +1,113 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* Copyright (c) Infonomic Company Limited
|
|
7
|
-
*/
|
|
8
|
-
import { createCommand } from '../../lib/create-command.js';
|
|
9
|
-
import { ADMIN_USERS_ABILITIES } from './abilities.js';
|
|
10
|
-
import { adminUserListResponseSchema, adminUserResponseSchema, createAdminUserRequestSchema, deleteAdminUserRequestSchema, disableAdminUserRequestSchema, enableAdminUserRequestSchema, getAdminUserRequestSchema, listAdminUsersRequestSchema, okResponseSchema, setAdminUserPasswordRequestSchema, updateAdminUserRequestSchema, } from './schemas.js';
|
|
11
|
-
import { AdminUsersService } from './service.js';
|
|
1
|
+
import { createCommand } from "../../lib/create-command.js";
|
|
2
|
+
import { ADMIN_USERS_ABILITIES } from "./abilities.js";
|
|
3
|
+
import { adminUserListResponseSchema, adminUserResponseSchema, createAdminUserRequestSchema, deleteAdminUserRequestSchema, disableAdminUserRequestSchema, enableAdminUserRequestSchema, getAdminUserRequestSchema, listAdminUsersRequestSchema, okResponseSchema, setAdminUserPasswordRequestSchema, updateAdminUserRequestSchema } from "./schemas.js";
|
|
4
|
+
import { AdminUsersService } from "./service.js";
|
|
12
5
|
function serviceOf(deps) {
|
|
13
|
-
return new AdminUsersService({
|
|
6
|
+
return new AdminUsersService({
|
|
7
|
+
repo: deps.store.adminUsers
|
|
8
|
+
});
|
|
14
9
|
}
|
|
15
|
-
|
|
10
|
+
const listAdminUsersCommand = createCommand({
|
|
16
11
|
method: 'listAdminUsers',
|
|
17
|
-
auth: {
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
auth: {
|
|
13
|
+
ability: ADMIN_USERS_ABILITIES.read
|
|
14
|
+
},
|
|
15
|
+
schemas: {
|
|
16
|
+
input: listAdminUsersRequestSchema,
|
|
17
|
+
output: adminUserListResponseSchema
|
|
18
|
+
},
|
|
19
|
+
handler: ({ input, deps })=>serviceOf(deps).listUsers(input)
|
|
20
20
|
});
|
|
21
|
-
|
|
21
|
+
const getAdminUserCommand = createCommand({
|
|
22
22
|
method: 'getAdminUser',
|
|
23
|
-
auth: {
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
auth: {
|
|
24
|
+
ability: ADMIN_USERS_ABILITIES.read
|
|
25
|
+
},
|
|
26
|
+
schemas: {
|
|
27
|
+
input: getAdminUserRequestSchema,
|
|
28
|
+
output: adminUserResponseSchema
|
|
29
|
+
},
|
|
30
|
+
handler: ({ input, deps })=>serviceOf(deps).getUser(input)
|
|
26
31
|
});
|
|
27
|
-
|
|
32
|
+
const createAdminUserCommand = createCommand({
|
|
28
33
|
method: 'createAdminUser',
|
|
29
|
-
auth: {
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
auth: {
|
|
35
|
+
ability: ADMIN_USERS_ABILITIES.create
|
|
36
|
+
},
|
|
37
|
+
schemas: {
|
|
38
|
+
input: createAdminUserRequestSchema,
|
|
39
|
+
output: adminUserResponseSchema
|
|
40
|
+
},
|
|
41
|
+
handler: ({ input, deps })=>serviceOf(deps).createUser(input)
|
|
32
42
|
});
|
|
33
|
-
|
|
43
|
+
const updateAdminUserCommand = createCommand({
|
|
34
44
|
method: 'updateAdminUser',
|
|
35
|
-
auth: {
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
auth: {
|
|
46
|
+
ability: ADMIN_USERS_ABILITIES.update
|
|
47
|
+
},
|
|
48
|
+
schemas: {
|
|
49
|
+
input: updateAdminUserRequestSchema,
|
|
50
|
+
output: adminUserResponseSchema
|
|
51
|
+
},
|
|
52
|
+
handler: ({ input, deps })=>serviceOf(deps).updateUser(input)
|
|
38
53
|
});
|
|
39
|
-
|
|
54
|
+
const setAdminUserPasswordCommand = createCommand({
|
|
40
55
|
method: 'setAdminUserPassword',
|
|
41
|
-
auth: {
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
auth: {
|
|
57
|
+
ability: ADMIN_USERS_ABILITIES.changePassword
|
|
58
|
+
},
|
|
59
|
+
schemas: {
|
|
60
|
+
input: setAdminUserPasswordRequestSchema,
|
|
61
|
+
output: adminUserResponseSchema
|
|
62
|
+
},
|
|
63
|
+
handler: ({ input, deps })=>serviceOf(deps).setPassword(input)
|
|
44
64
|
});
|
|
45
|
-
|
|
65
|
+
const enableAdminUserCommand = createCommand({
|
|
46
66
|
method: 'enableAdminUser',
|
|
47
|
-
auth: {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
auth: {
|
|
68
|
+
ability: ADMIN_USERS_ABILITIES.update
|
|
69
|
+
},
|
|
70
|
+
schemas: {
|
|
71
|
+
input: enableAdminUserRequestSchema,
|
|
72
|
+
output: okResponseSchema
|
|
52
73
|
},
|
|
74
|
+
handler: async ({ input, deps })=>{
|
|
75
|
+
await serviceOf(deps).enableUser(input);
|
|
76
|
+
return {
|
|
77
|
+
ok: true
|
|
78
|
+
};
|
|
79
|
+
}
|
|
53
80
|
});
|
|
54
|
-
|
|
81
|
+
const disableAdminUserCommand = createCommand({
|
|
55
82
|
method: 'disableAdminUser',
|
|
56
|
-
auth: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
auth: {
|
|
84
|
+
ability: ADMIN_USERS_ABILITIES.update
|
|
85
|
+
},
|
|
86
|
+
schemas: {
|
|
87
|
+
input: disableAdminUserRequestSchema,
|
|
88
|
+
output: okResponseSchema
|
|
61
89
|
},
|
|
90
|
+
handler: async ({ input, deps, actor })=>{
|
|
91
|
+
await serviceOf(deps).disableUser(actor, input);
|
|
92
|
+
return {
|
|
93
|
+
ok: true
|
|
94
|
+
};
|
|
95
|
+
}
|
|
62
96
|
});
|
|
63
|
-
|
|
97
|
+
const deleteAdminUserCommand = createCommand({
|
|
64
98
|
method: 'deleteAdminUser',
|
|
65
|
-
auth: {
|
|
66
|
-
|
|
67
|
-
handler: async ({ input, deps, actor }) => {
|
|
68
|
-
await serviceOf(deps).deleteUser(actor, input);
|
|
69
|
-
return { ok: true };
|
|
99
|
+
auth: {
|
|
100
|
+
ability: ADMIN_USERS_ABILITIES["delete"]
|
|
70
101
|
},
|
|
102
|
+
schemas: {
|
|
103
|
+
input: deleteAdminUserRequestSchema,
|
|
104
|
+
output: okResponseSchema
|
|
105
|
+
},
|
|
106
|
+
handler: async ({ input, deps, actor })=>{
|
|
107
|
+
await serviceOf(deps).deleteUser(actor, input);
|
|
108
|
+
return {
|
|
109
|
+
ok: true
|
|
110
|
+
};
|
|
111
|
+
}
|
|
71
112
|
});
|
|
113
|
+
export { createAdminUserCommand, deleteAdminUserCommand, disableAdminUserCommand, enableAdminUserCommand, getAdminUserCommand, listAdminUsersCommand, setAdminUserPasswordCommand, updateAdminUserCommand };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AdminUserResponse } from '../index.js';
|
|
2
|
+
interface CreateAdminUserProps {
|
|
3
|
+
onClose?: () => void;
|
|
4
|
+
/** Called on successful create with the new user so the parent can navigate. */
|
|
5
|
+
onSuccess?: (user: AdminUserResponse) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function CreateAdminUser({ onClose, onSuccess }: CreateAdminUserProps): import("react").JSX.Element;
|
|
8
|
+
export {};
|