@byline/admin 2.4.0 → 2.4.2
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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/admin",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "2.4.
|
|
5
|
+
"version": "2.4.2",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"main": "dist/index.js",
|
|
29
29
|
"index": "dist/index.js",
|
|
30
30
|
"types": "dist/index.d.ts",
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"**/*.css"
|
|
33
|
+
],
|
|
31
34
|
"exports": {
|
|
32
35
|
".": {
|
|
33
36
|
"types": "./dist/index.d.ts",
|
|
@@ -59,28 +62,104 @@
|
|
|
59
62
|
"import": "./dist/modules/admin-account/index.js",
|
|
60
63
|
"require": "./dist/modules/admin-account/index.js"
|
|
61
64
|
},
|
|
65
|
+
"./services": {
|
|
66
|
+
"types": "./dist/services/admin-services-context.d.ts",
|
|
67
|
+
"import": "./dist/services/admin-services-context.js",
|
|
68
|
+
"require": "./dist/services/admin-services-context.js"
|
|
69
|
+
},
|
|
70
|
+
"./admin-users/components/create": {
|
|
71
|
+
"types": "./dist/modules/admin-users/components/create.d.ts",
|
|
72
|
+
"import": "./dist/modules/admin-users/components/create.js",
|
|
73
|
+
"require": "./dist/modules/admin-users/components/create.js"
|
|
74
|
+
},
|
|
75
|
+
"./admin-users/components/update": {
|
|
76
|
+
"types": "./dist/modules/admin-users/components/update.d.ts",
|
|
77
|
+
"import": "./dist/modules/admin-users/components/update.js",
|
|
78
|
+
"require": "./dist/modules/admin-users/components/update.js"
|
|
79
|
+
},
|
|
80
|
+
"./admin-users/components/roles": {
|
|
81
|
+
"types": "./dist/modules/admin-users/components/roles.d.ts",
|
|
82
|
+
"import": "./dist/modules/admin-users/components/roles.js",
|
|
83
|
+
"require": "./dist/modules/admin-users/components/roles.js"
|
|
84
|
+
},
|
|
85
|
+
"./admin-users/components/set-password": {
|
|
86
|
+
"types": "./dist/modules/admin-users/components/set-password.d.ts",
|
|
87
|
+
"import": "./dist/modules/admin-users/components/set-password.js",
|
|
88
|
+
"require": "./dist/modules/admin-users/components/set-password.js"
|
|
89
|
+
},
|
|
90
|
+
"./admin-roles/components/create": {
|
|
91
|
+
"types": "./dist/modules/admin-roles/components/create.d.ts",
|
|
92
|
+
"import": "./dist/modules/admin-roles/components/create.js",
|
|
93
|
+
"require": "./dist/modules/admin-roles/components/create.js"
|
|
94
|
+
},
|
|
95
|
+
"./admin-roles/components/update": {
|
|
96
|
+
"types": "./dist/modules/admin-roles/components/update.d.ts",
|
|
97
|
+
"import": "./dist/modules/admin-roles/components/update.js",
|
|
98
|
+
"require": "./dist/modules/admin-roles/components/update.js"
|
|
99
|
+
},
|
|
100
|
+
"./admin-roles/components/permissions": {
|
|
101
|
+
"types": "./dist/modules/admin-roles/components/permissions.d.ts",
|
|
102
|
+
"import": "./dist/modules/admin-roles/components/permissions.js",
|
|
103
|
+
"require": "./dist/modules/admin-roles/components/permissions.js"
|
|
104
|
+
},
|
|
105
|
+
"./admin-permissions/components/inspector": {
|
|
106
|
+
"types": "./dist/modules/admin-permissions/components/inspector.d.ts",
|
|
107
|
+
"import": "./dist/modules/admin-permissions/components/inspector.js",
|
|
108
|
+
"require": "./dist/modules/admin-permissions/components/inspector.js"
|
|
109
|
+
},
|
|
110
|
+
"./admin-account/components/container": {
|
|
111
|
+
"types": "./dist/modules/admin-account/components/container.d.ts",
|
|
112
|
+
"import": "./dist/modules/admin-account/components/container.js",
|
|
113
|
+
"require": "./dist/modules/admin-account/components/container.js"
|
|
114
|
+
},
|
|
115
|
+
"./admin-account/components/update": {
|
|
116
|
+
"types": "./dist/modules/admin-account/components/update.d.ts",
|
|
117
|
+
"import": "./dist/modules/admin-account/components/update.js",
|
|
118
|
+
"require": "./dist/modules/admin-account/components/update.js"
|
|
119
|
+
},
|
|
120
|
+
"./admin-account/components/change-password": {
|
|
121
|
+
"types": "./dist/modules/admin-account/components/change-password.d.ts",
|
|
122
|
+
"import": "./dist/modules/admin-account/components/change-password.js",
|
|
123
|
+
"require": "./dist/modules/admin-account/components/change-password.js"
|
|
124
|
+
},
|
|
125
|
+
"./auth/components/sign-in-form": {
|
|
126
|
+
"types": "./dist/modules/auth/components/sign-in-form.d.ts",
|
|
127
|
+
"import": "./dist/modules/auth/components/sign-in-form.js",
|
|
128
|
+
"require": "./dist/modules/auth/components/sign-in-form.js"
|
|
129
|
+
},
|
|
62
130
|
"./package.json": "./package.json"
|
|
63
131
|
},
|
|
64
132
|
"files": [
|
|
65
|
-
"dist"
|
|
133
|
+
"dist/",
|
|
134
|
+
"src/"
|
|
66
135
|
],
|
|
67
136
|
"dependencies": {
|
|
137
|
+
"@tanstack/react-form-start": "^1.32.0",
|
|
138
|
+
"classnames": "^2.5.1",
|
|
68
139
|
"jose": "^6.2.3",
|
|
69
140
|
"uuid": "^14.0.0",
|
|
70
141
|
"zod": "^4.4.3",
|
|
71
|
-
"@byline/auth": "2.4.
|
|
72
|
-
"@byline/core": "2.4.
|
|
142
|
+
"@byline/auth": "2.4.2",
|
|
143
|
+
"@byline/core": "2.4.2",
|
|
144
|
+
"@byline/ui": "2.4.2"
|
|
145
|
+
},
|
|
146
|
+
"peerDependencies": {
|
|
147
|
+
"react": "^19.0.0",
|
|
148
|
+
"react-dom": "^19.0.0"
|
|
73
149
|
},
|
|
74
150
|
"devDependencies": {
|
|
75
151
|
"@biomejs/biome": "2.4.15",
|
|
152
|
+
"@rsbuild/plugin-react": "^2.0.0",
|
|
153
|
+
"@rslib/core": "^0.21.5",
|
|
76
154
|
"@types/node": "^25.9.1",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
155
|
+
"@types/react": "19.2.15",
|
|
156
|
+
"@types/react-dom": "19.2.3",
|
|
157
|
+
"react": "19.2.6",
|
|
158
|
+
"react-dom": "19.2.6",
|
|
80
159
|
"rimraf": "^6.1.3",
|
|
81
|
-
"tsc-alias": "^1.8.17",
|
|
82
160
|
"tsx": "^4.22.3",
|
|
83
161
|
"typescript": "6.0.3",
|
|
162
|
+
"typescript-plugin-css-modules": "^5.2.0",
|
|
84
163
|
"vitest": "^4.1.7"
|
|
85
164
|
},
|
|
86
165
|
"publishConfig": {
|
|
@@ -89,8 +168,8 @@
|
|
|
89
168
|
"registry": "https://registry.npmjs.org/"
|
|
90
169
|
},
|
|
91
170
|
"scripts": {
|
|
92
|
-
"dev": "
|
|
93
|
-
"build": "
|
|
171
|
+
"dev": "rslib build --watch",
|
|
172
|
+
"build": "rslib build",
|
|
94
173
|
"clean": "node scripts/clean.js node_modules dist build .turbo",
|
|
95
174
|
"lint": "biome check --write --unsafe --diagnostic-level=error",
|
|
96
175
|
"test": "vitest run --mode=node",
|
package/src/abilities.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
import type { AbilityRegistry } from '@byline/auth'
|
|
10
|
+
|
|
11
|
+
import { registerAdminPermissionsAbilities } from './modules/admin-permissions/abilities.js'
|
|
12
|
+
import { registerAdminRolesAbilities } from './modules/admin-roles/abilities.js'
|
|
13
|
+
import { registerAdminUsersAbilities } from './modules/admin-users/abilities.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register every ability contributed by the admin subsystem.
|
|
17
|
+
*
|
|
18
|
+
* Called once at `initBylineCore()` time from the webapp config. Each
|
|
19
|
+
* admin module contributes its own registrar (`registerAdminUsersAbilities`,
|
|
20
|
+
* `registerAdminRolesAbilities`, …); this function fans out to them so
|
|
21
|
+
* the webapp wiring stays a single line.
|
|
22
|
+
*
|
|
23
|
+
* Admin does not self-register from core to keep the `@byline/core`
|
|
24
|
+
* package free of a dependency on `@byline/admin` — the registration
|
|
25
|
+
* call is an opt-in at the composition root.
|
|
26
|
+
*/
|
|
27
|
+
export function registerAdminAbilities(registry: AbilityRegistry): void {
|
|
28
|
+
registerAdminUsersAbilities(registry)
|
|
29
|
+
registerAdminRolesAbilities(registry)
|
|
30
|
+
registerAdminPermissionsAbilities(registry)
|
|
31
|
+
// registerAccountAbilities(registry) — added when that module lands
|
|
32
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* `@byline/admin` — the admin subsystem.
|
|
11
|
+
*
|
|
12
|
+
* Concrete implementation of the admin side of Byline: admin users,
|
|
13
|
+
* roles, permissions, account self-service, and the built-in JWT
|
|
14
|
+
* session provider. Depends on `@byline/auth` (the Actor / RequestContext
|
|
15
|
+
* / SessionProvider contract) and `@byline/core` (collection and lifecycle
|
|
16
|
+
* machinery). Third-party session providers (Lucia, WorkOS, Clerk, SSO)
|
|
17
|
+
* are intentionally kept out of this package — they live as separate
|
|
18
|
+
* adapters against `@byline/auth` directly.
|
|
19
|
+
*
|
|
20
|
+
* Prefer the per-module subpath exports (`@byline/admin/admin-users`,
|
|
21
|
+
* `@byline/admin/auth`, etc.) over the root barrel; this root exists so
|
|
22
|
+
* the package is importable as a single unit when that is convenient.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export { registerAdminAbilities } from './abilities.js'
|
|
26
|
+
export { assertAdminActor, requireAdminActor } from './lib/assert-admin-actor.js'
|
|
27
|
+
export {
|
|
28
|
+
type Command,
|
|
29
|
+
type CreateCommandAuthSpec,
|
|
30
|
+
type CreateCommandHandlerArgs,
|
|
31
|
+
type CreateCommandSpec,
|
|
32
|
+
createCommand,
|
|
33
|
+
} from './lib/create-command.js'
|
|
34
|
+
export * from './modules/admin-account/index.js'
|
|
35
|
+
export * from './modules/admin-permissions/index.js'
|
|
36
|
+
export * from './modules/admin-roles/index.js'
|
|
37
|
+
export * from './modules/admin-users/index.js'
|
|
38
|
+
export * from './modules/auth/index.js'
|
|
39
|
+
export type { AdminStore } from './store.js'
|
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
import { type AdminAuth, ERR_UNAUTHENTICATED, isAdminAuth, type RequestContext } from '@byline/auth'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Gate every admin command behind three checks, in order:
|
|
13
|
+
*
|
|
14
|
+
* 1. `context` exists. No in-process call may reach an admin command
|
|
15
|
+
* without threading a `RequestContext` — seeds/tests pass
|
|
16
|
+
* `createSuperAdminContext()`.
|
|
17
|
+
* 2. `context.actor` is an `AdminAuth`. Anonymous admin calls are
|
|
18
|
+
* rejected outright — admin actions are never public. A `UserAuth`
|
|
19
|
+
* (end-user identity) also fails here: it may sign in against the
|
|
20
|
+
* app realm, but it does not have an admin identity.
|
|
21
|
+
* 3. The actor holds the required ability. `AdminAuth.assertAbility`
|
|
22
|
+
* short-circuits on `isSuperAdmin: true`; otherwise the flat
|
|
23
|
+
* ability set is consulted.
|
|
24
|
+
*
|
|
25
|
+
* Returns the narrowed `AdminAuth` so callers can use it without a
|
|
26
|
+
* second type guard — the typical shape is:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* export async function deleteAdminUserCommand(context, input, deps) {
|
|
30
|
+
* const parsed = deleteAdminUserRequestSchema.parse(input)
|
|
31
|
+
* const actor = assertAdminActor(context, ADMIN_USERS_ABILITIES.delete)
|
|
32
|
+
* return service.deleteUser(actor, parsed)
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* The three failures produce distinct error codes:
|
|
37
|
+
* - missing context / missing actor / wrong actor type → `ERR_UNAUTHENTICATED`
|
|
38
|
+
* - ability missing → `ERR_FORBIDDEN`
|
|
39
|
+
* (thrown from `AdminAuth.assertAbility`)
|
|
40
|
+
*/
|
|
41
|
+
export function assertAdminActor(context: RequestContext | undefined, ability: string): AdminAuth {
|
|
42
|
+
const actor = requireAdminActor(context, `admin action requiring '${ability}'`)
|
|
43
|
+
actor.assertAbility(ability)
|
|
44
|
+
return actor
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Authentication-only counterpart of `assertAdminActor`. Runs the same
|
|
49
|
+
* three checks (context present, actor present, actor is `AdminAuth`)
|
|
50
|
+
* but **does not** assert any ability key.
|
|
51
|
+
*
|
|
52
|
+
* Used by self-service commands where the actor is the target by
|
|
53
|
+
* definition — `@byline/admin/admin-account` for "change my own
|
|
54
|
+
* password" / "update my own profile". For those flows there is no
|
|
55
|
+
* meaningful ability to gate against; the security property is "you
|
|
56
|
+
* may only mutate your own row," and the commands enforce that by
|
|
57
|
+
* sourcing the target id from `actor.id` rather than from the
|
|
58
|
+
* request payload.
|
|
59
|
+
*
|
|
60
|
+
* Reasoning is described as part of the request narrative so the
|
|
61
|
+
* `ERR_UNAUTHENTICATED` message stays useful when it surfaces in logs
|
|
62
|
+
* — the helper has no `ability` argument to fall back on.
|
|
63
|
+
*/
|
|
64
|
+
export function requireAdminActor(
|
|
65
|
+
context: RequestContext | undefined,
|
|
66
|
+
reasonForLog: string
|
|
67
|
+
): AdminAuth {
|
|
68
|
+
if (!context) {
|
|
69
|
+
throw ERR_UNAUTHENTICATED({
|
|
70
|
+
message:
|
|
71
|
+
`missing requestContext on ${reasonForLog}. Pass createSuperAdminContext() ` +
|
|
72
|
+
`from @byline/auth for scripts/tests, or construct a request-scoped context from your ` +
|
|
73
|
+
`session provider in the admin webapp.`,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const { actor } = context
|
|
78
|
+
if (actor == null) {
|
|
79
|
+
throw ERR_UNAUTHENTICATED({
|
|
80
|
+
message: `anonymous caller cannot perform ${reasonForLog}`,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
if (!isAdminAuth(actor)) {
|
|
84
|
+
throw ERR_UNAUTHENTICATED({
|
|
85
|
+
message: `non-admin actor cannot perform ${reasonForLog}`,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return actor
|
|
90
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
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
|
+
import type { AdminAuth, RequestContext } from '@byline/auth'
|
|
10
|
+
import type { ZodType } from 'zod'
|
|
11
|
+
|
|
12
|
+
import { assertAdminActor, requireAdminActor } from './assert-admin-actor.js'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `createCommand` — the wrapper that folds the four-step admin command
|
|
16
|
+
* contract (validate → authorise → invoke → shape) into a single
|
|
17
|
+
* declaration.
|
|
18
|
+
*
|
|
19
|
+
* Implements Phase 1 of `docs/CORE-COMPOSITION.md`. Today's scope is
|
|
20
|
+
* `@byline/admin`-internal: it gates against admin actor identity using
|
|
21
|
+
* the existing `assertAdminActor` / `requireAdminActor` helpers, which
|
|
22
|
+
* inherit the super-admin bypass from `AdminAuth.assertAbility`.
|
|
23
|
+
*
|
|
24
|
+
* The `auth` slot is a discriminated union:
|
|
25
|
+
*
|
|
26
|
+
* - `{ ability }` — full admin gate. Requires an `AdminAuth`
|
|
27
|
+
* actor holding the named ability. Maps to
|
|
28
|
+
* `assertAdminActor`.
|
|
29
|
+
* - `{ authenticated }` — identity gate only. Requires an `AdminAuth`
|
|
30
|
+
* actor but does not assert any ability. Used
|
|
31
|
+
* by self-service commands in `admin-account`
|
|
32
|
+
* where the security property is "you may
|
|
33
|
+
* only mutate your own row" and the target
|
|
34
|
+
* id is sourced from `actor.id`.
|
|
35
|
+
*
|
|
36
|
+
* The handler receives an args object so it can cherry-pick what it
|
|
37
|
+
* needs without positional ordering — `context` for downstream calls
|
|
38
|
+
* that need the full request context, `input` (already Zod-parsed),
|
|
39
|
+
* `deps` (typed by the module), and `actor` (already narrowed to
|
|
40
|
+
* `AdminAuth` by the auth step).
|
|
41
|
+
*
|
|
42
|
+
* The returned command preserves today's `(context, input, deps) =>
|
|
43
|
+
* Promise<Output>` signature so existing server-fn call sites keep
|
|
44
|
+
* working without change.
|
|
45
|
+
*
|
|
46
|
+
* Collection-document operations (create / update / delete / status /
|
|
47
|
+
* upload) are gated through a separate helper, `assertActorCanPerform`,
|
|
48
|
+
* which fires inside the `document-lifecycle` service functions in
|
|
49
|
+
* `@byline/core`. They do not flow through this wrapper today; if the
|
|
50
|
+
* two enforcement paths ever converge, the `auth` discriminator can
|
|
51
|
+
* grow a `collection` variant without breaking existing call sites.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
export type CreateCommandAuthSpec =
|
|
55
|
+
| { readonly ability: string; readonly authenticated?: never }
|
|
56
|
+
| { readonly authenticated: true; readonly ability?: never }
|
|
57
|
+
|
|
58
|
+
export interface CreateCommandHandlerArgs<TInput, TDeps> {
|
|
59
|
+
readonly context: RequestContext
|
|
60
|
+
readonly input: TInput
|
|
61
|
+
readonly deps: TDeps
|
|
62
|
+
readonly actor: AdminAuth
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface CreateCommandSpec<TInput, TOutput, TDeps> {
|
|
66
|
+
/**
|
|
67
|
+
* Stable identifier for the command, used in error messages and
|
|
68
|
+
* future telemetry (Phase 1 of `CORE-COMPOSITION.md` calls out
|
|
69
|
+
* uniform logging as a downstream benefit of the wrapper).
|
|
70
|
+
*/
|
|
71
|
+
readonly method: string
|
|
72
|
+
readonly auth: CreateCommandAuthSpec
|
|
73
|
+
readonly schemas: {
|
|
74
|
+
readonly input: ZodType<TInput>
|
|
75
|
+
readonly output: ZodType<TOutput>
|
|
76
|
+
}
|
|
77
|
+
readonly handler: (args: CreateCommandHandlerArgs<TInput, TDeps>) => Promise<TOutput> | TOutput
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type Command<_TInput, TOutput, TDeps> = (
|
|
81
|
+
context: RequestContext | undefined,
|
|
82
|
+
input: unknown,
|
|
83
|
+
deps: TDeps
|
|
84
|
+
) => Promise<TOutput>
|
|
85
|
+
|
|
86
|
+
export function createCommand<TInput, TOutput, TDeps>(
|
|
87
|
+
spec: CreateCommandSpec<TInput, TOutput, TDeps>
|
|
88
|
+
): Command<TInput, TOutput, TDeps> {
|
|
89
|
+
return async function command(
|
|
90
|
+
context: RequestContext | undefined,
|
|
91
|
+
input: unknown,
|
|
92
|
+
deps: TDeps
|
|
93
|
+
): Promise<TOutput> {
|
|
94
|
+
const parsed = spec.schemas.input.parse(input ?? {}) as TInput
|
|
95
|
+
const actor =
|
|
96
|
+
spec.auth.ability !== undefined
|
|
97
|
+
? assertAdminActor(context, spec.auth.ability)
|
|
98
|
+
: requireAdminActor(context, spec.method)
|
|
99
|
+
// `context` is non-null after the auth step — both helpers throw
|
|
100
|
+
// `ERR_UNAUTHENTICATED` when the request context is missing.
|
|
101
|
+
const result = await spec.handler({
|
|
102
|
+
context: context as RequestContext,
|
|
103
|
+
input: parsed,
|
|
104
|
+
deps,
|
|
105
|
+
actor,
|
|
106
|
+
})
|
|
107
|
+
return spec.schemas.output.parse(result) as TOutput
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
import { type Command, createCommand } from '../../lib/create-command.js'
|
|
10
|
+
import { adminUserResponseSchema } from '../admin-users/schemas.js'
|
|
11
|
+
import {
|
|
12
|
+
changeAccountPasswordRequestSchema,
|
|
13
|
+
getAccountRequestSchema,
|
|
14
|
+
updateAccountRequestSchema,
|
|
15
|
+
} from './schemas.js'
|
|
16
|
+
import { AdminAccountService } from './service.js'
|
|
17
|
+
import type { AdminStore } from '../../store.js'
|
|
18
|
+
import type {
|
|
19
|
+
AccountResponse,
|
|
20
|
+
ChangeAccountPasswordRequest,
|
|
21
|
+
GetAccountRequest,
|
|
22
|
+
UpdateAccountRequest,
|
|
23
|
+
} from './schemas.js'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Transport-agnostic commands for admin-account self-service.
|
|
27
|
+
*
|
|
28
|
+
* Same `createCommand` shape as the other admin modules, with one
|
|
29
|
+
* deliberate difference: `auth` is `{ authenticated: true }` rather than
|
|
30
|
+
* `{ ability }`. There is no ability key to gate against — the security
|
|
31
|
+
* property is "you may only mutate your own row," enforced structurally
|
|
32
|
+
* by sourcing the target id from `actor.id` rather than from the request
|
|
33
|
+
* payload. The request schemas do not accept an `id` field, so a caller
|
|
34
|
+
* has no way to express "operate on someone else."
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export interface AdminAccountCommandDeps {
|
|
38
|
+
store: AdminStore
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function serviceOf(deps: AdminAccountCommandDeps): AdminAccountService {
|
|
42
|
+
return new AdminAccountService({ repo: deps.store.adminUsers })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const getAccountCommand: Command<
|
|
46
|
+
GetAccountRequest,
|
|
47
|
+
AccountResponse,
|
|
48
|
+
AdminAccountCommandDeps
|
|
49
|
+
> = createCommand({
|
|
50
|
+
method: 'getAccount',
|
|
51
|
+
auth: { authenticated: true },
|
|
52
|
+
schemas: { input: getAccountRequestSchema, output: adminUserResponseSchema },
|
|
53
|
+
handler: ({ deps, actor }) => serviceOf(deps).getAccount(actor.id),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export const updateAccountCommand: Command<
|
|
57
|
+
UpdateAccountRequest,
|
|
58
|
+
AccountResponse,
|
|
59
|
+
AdminAccountCommandDeps
|
|
60
|
+
> = createCommand({
|
|
61
|
+
method: 'updateAccount',
|
|
62
|
+
auth: { authenticated: true },
|
|
63
|
+
schemas: { input: updateAccountRequestSchema, output: adminUserResponseSchema },
|
|
64
|
+
handler: ({ input, deps, actor }) => serviceOf(deps).updateAccount(actor.id, input),
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
export const changeAccountPasswordCommand: Command<
|
|
68
|
+
ChangeAccountPasswordRequest,
|
|
69
|
+
AccountResponse,
|
|
70
|
+
AdminAccountCommandDeps
|
|
71
|
+
> = createCommand({
|
|
72
|
+
method: 'changeAccountPassword',
|
|
73
|
+
auth: { authenticated: true },
|
|
74
|
+
schemas: { input: changeAccountPasswordRequestSchema, output: adminUserResponseSchema },
|
|
75
|
+
handler: ({ input, deps, actor }) => serviceOf(deps).changePassword(actor.id, input),
|
|
76
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChangeAccountPassword — self-service password-change form (drawer body).
|
|
3
|
+
*
|
|
4
|
+
* Override handles:
|
|
5
|
+
* .byline-account-change-password-wrap — outer container
|
|
6
|
+
* .byline-account-change-password-form — vertical-stack form element
|
|
7
|
+
* .byline-account-change-password-actions — Cancel/Save row
|
|
8
|
+
* .byline-account-change-password-action — buttons in the actions row
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
.wrap,
|
|
12
|
+
:global(.byline-account-change-password-wrap) {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
gap: var(--spacing-8);
|
|
16
|
+
padding: var(--spacing-4);
|
|
17
|
+
margin-top: var(--spacing-4);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.form,
|
|
21
|
+
:global(.byline-account-change-password-form) {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: var(--spacing-16);
|
|
25
|
+
padding-top: var(--spacing-8);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.actions,
|
|
29
|
+
:global(.byline-account-change-password-actions) {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: flex-end;
|
|
33
|
+
gap: var(--spacing-8);
|
|
34
|
+
margin-top: var(--spacing-16);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.action,
|
|
38
|
+
:global(.byline-account-change-password-action) {
|
|
39
|
+
min-width: 4rem;
|
|
40
|
+
}
|