@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.
Files changed (177) hide show
  1. package/dist/abilities.js +5 -24
  2. package/dist/index.js +8 -30
  3. package/dist/lib/assert-admin-actor.js +13 -74
  4. package/dist/lib/create-command.js +6 -16
  5. package/dist/modules/admin-account/commands.js +35 -24
  6. package/dist/modules/admin-account/components/change-password.d.ts +8 -0
  7. package/dist/modules/admin-account/components/change-password.js +192 -0
  8. package/dist/modules/admin-account/components/change-password.module.js +8 -0
  9. package/dist/modules/admin-account/components/change-password_module.css +27 -0
  10. package/dist/modules/admin-account/components/container.d.ts +29 -0
  11. package/dist/modules/admin-account/components/container.js +298 -0
  12. package/dist/modules/admin-account/components/container.module.js +28 -0
  13. package/dist/modules/admin-account/components/container_module.css +106 -0
  14. package/dist/modules/admin-account/components/update.d.ts +8 -0
  15. package/dist/modules/admin-account/components/update.js +207 -0
  16. package/dist/modules/admin-account/components/update.module.js +8 -0
  17. package/dist/modules/admin-account/components/update_module.css +27 -0
  18. package/dist/modules/admin-account/errors.js +14 -45
  19. package/dist/modules/admin-account/index.js +4 -34
  20. package/dist/modules/admin-account/schemas.js +25 -59
  21. package/dist/modules/admin-account/service.js +56 -61
  22. package/dist/modules/admin-permissions/abilities.js +6 -24
  23. package/dist/modules/admin-permissions/commands.js +42 -28
  24. package/dist/modules/admin-permissions/components/inspector.d.ts +4 -0
  25. package/dist/modules/admin-permissions/components/inspector.js +284 -0
  26. package/dist/modules/admin-permissions/components/inspector.module.js +56 -0
  27. package/dist/modules/admin-permissions/components/inspector_module.css +238 -0
  28. package/dist/modules/admin-permissions/dto.js +3 -16
  29. package/dist/modules/admin-permissions/errors.js +14 -27
  30. package/dist/modules/admin-permissions/index.js +6 -26
  31. package/dist/modules/admin-permissions/repository.js +1 -8
  32. package/dist/modules/admin-permissions/schemas.js +33 -70
  33. package/dist/modules/admin-permissions/service.js +88 -92
  34. package/dist/modules/admin-roles/abilities.js +8 -30
  35. package/dist/modules/admin-roles/commands.js +89 -55
  36. package/dist/modules/admin-roles/components/create.d.ts +7 -0
  37. package/dist/modules/admin-roles/components/create.js +177 -0
  38. package/dist/modules/admin-roles/components/create.module.js +8 -0
  39. package/dist/modules/admin-roles/components/create_module.css +27 -0
  40. package/dist/modules/admin-roles/components/permissions.d.ts +10 -0
  41. package/dist/modules/admin-roles/components/permissions.js +303 -0
  42. package/dist/modules/admin-roles/components/permissions.module.js +44 -0
  43. package/dist/modules/admin-roles/components/permissions_module.css +192 -0
  44. package/dist/modules/admin-roles/components/update.d.ts +8 -0
  45. package/dist/modules/admin-roles/components/update.js +166 -0
  46. package/dist/modules/admin-roles/components/update.module.js +8 -0
  47. package/dist/modules/admin-roles/components/update_module.css +27 -0
  48. package/dist/modules/admin-roles/dto.js +3 -16
  49. package/dist/modules/admin-roles/errors.js +16 -40
  50. package/dist/modules/admin-roles/index.js +6 -26
  51. package/dist/modules/admin-roles/repository.js +1 -8
  52. package/dist/modules/admin-roles/schemas.js +41 -71
  53. package/dist/modules/admin-roles/service.js +79 -82
  54. package/dist/modules/admin-users/abilities.js +9 -38
  55. package/dist/modules/admin-users/commands.js +92 -50
  56. package/dist/modules/admin-users/components/create.d.ts +8 -0
  57. package/dist/modules/admin-users/components/create.js +268 -0
  58. package/dist/modules/admin-users/components/create.module.js +10 -0
  59. package/dist/modules/admin-users/components/create_module.css +45 -0
  60. package/dist/modules/admin-users/components/roles.d.ts +11 -0
  61. package/dist/modules/admin-users/components/roles.js +148 -0
  62. package/dist/modules/admin-users/components/roles.module.js +18 -0
  63. package/dist/modules/admin-users/components/roles_module.css +75 -0
  64. package/dist/modules/admin-users/components/set-password.d.ts +8 -0
  65. package/dist/modules/admin-users/components/set-password.js +170 -0
  66. package/dist/modules/admin-users/components/set-password.module.js +9 -0
  67. package/dist/modules/admin-users/components/set-password_module.css +31 -0
  68. package/dist/modules/admin-users/components/update.d.ts +8 -0
  69. package/dist/modules/admin-users/components/update.js +254 -0
  70. package/dist/modules/admin-users/components/update.module.js +9 -0
  71. package/dist/modules/admin-users/components/update_module.css +34 -0
  72. package/dist/modules/admin-users/dto.js +3 -18
  73. package/dist/modules/admin-users/errors.js +17 -43
  74. package/dist/modules/admin-users/index.js +7 -27
  75. package/dist/modules/admin-users/repository.js +1 -8
  76. package/dist/modules/admin-users/schemas.js +44 -75
  77. package/dist/modules/admin-users/seed-super-admin.js +9 -34
  78. package/dist/modules/admin-users/service.js +76 -91
  79. package/dist/modules/auth/components/sign-in-form.d.ts +12 -0
  80. package/dist/modules/auth/components/sign-in-form.js +115 -0
  81. package/dist/modules/auth/components/sign-in-form.module.js +12 -0
  82. package/dist/modules/auth/components/sign-in-form_module.css +41 -0
  83. package/dist/modules/auth/index.js +3 -24
  84. package/dist/modules/auth/jwt-session-provider.js +179 -149
  85. package/dist/modules/auth/password.js +11 -53
  86. package/dist/modules/auth/phc.js +21 -54
  87. package/dist/modules/auth/refresh-tokens-repository.js +1 -8
  88. package/dist/modules/auth/resolve-actor.js +6 -28
  89. package/dist/services/admin-services-context.d.ts +16 -0
  90. package/dist/services/admin-services-context.js +13 -0
  91. package/dist/services/admin-services-types.d.ts +129 -0
  92. package/dist/services/admin-services-types.js +1 -0
  93. package/dist/store.js +1 -8
  94. package/dist/vendor/noble-argon2/_blake.js +277 -45
  95. package/dist/vendor/noble-argon2/_md.js +81 -136
  96. package/dist/vendor/noble-argon2/_u64.js +65 -67
  97. package/dist/vendor/noble-argon2/argon2.js +181 -342
  98. package/dist/vendor/noble-argon2/blake2.js +252 -327
  99. package/dist/vendor/noble-argon2/utils.js +110 -490
  100. package/dist/vendor/noble-argon2/utils.js.LICENSE.txt +1 -0
  101. package/package.json +89 -10
  102. package/src/abilities.ts +32 -0
  103. package/src/declarations.d.ts +4 -0
  104. package/src/index.ts +39 -0
  105. package/src/lib/assert-admin-actor.ts +90 -0
  106. package/src/lib/create-command.ts +109 -0
  107. package/src/modules/admin-account/commands.ts +76 -0
  108. package/src/modules/admin-account/components/change-password.module.css +40 -0
  109. package/src/modules/admin-account/components/change-password.tsx +232 -0
  110. package/src/modules/admin-account/components/container.module.css +158 -0
  111. package/src/modules/admin-account/components/container.tsx +229 -0
  112. package/src/modules/admin-account/components/update.module.css +40 -0
  113. package/src/modules/admin-account/components/update.tsx +263 -0
  114. package/src/modules/admin-account/errors.ts +75 -0
  115. package/src/modules/admin-account/index.ts +60 -0
  116. package/src/modules/admin-account/schemas.ts +84 -0
  117. package/src/modules/admin-account/service.ts +92 -0
  118. package/src/modules/admin-permissions/abilities.ts +46 -0
  119. package/src/modules/admin-permissions/commands.ts +103 -0
  120. package/src/modules/admin-permissions/components/inspector.module.css +326 -0
  121. package/src/modules/admin-permissions/components/inspector.tsx +298 -0
  122. package/src/modules/admin-permissions/dto.ts +28 -0
  123. package/src/modules/admin-permissions/errors.ts +57 -0
  124. package/src/modules/admin-permissions/index.ts +72 -0
  125. package/src/modules/admin-permissions/repository.ts +49 -0
  126. package/src/modules/admin-permissions/schemas.ts +128 -0
  127. package/src/modules/admin-permissions/service.ts +137 -0
  128. package/src/modules/admin-roles/abilities.ts +62 -0
  129. package/src/modules/admin-roles/commands.ts +161 -0
  130. package/src/modules/admin-roles/components/create.module.css +40 -0
  131. package/src/modules/admin-roles/components/create.tsx +218 -0
  132. package/src/modules/admin-roles/components/permissions.module.css +279 -0
  133. package/src/modules/admin-roles/components/permissions.tsx +396 -0
  134. package/src/modules/admin-roles/components/update.module.css +40 -0
  135. package/src/modules/admin-roles/components/update.tsx +218 -0
  136. package/src/modules/admin-roles/dto.ts +30 -0
  137. package/src/modules/admin-roles/errors.ts +76 -0
  138. package/src/modules/admin-roles/index.ts +81 -0
  139. package/src/modules/admin-roles/repository.ts +96 -0
  140. package/src/modules/admin-roles/schemas.ts +139 -0
  141. package/src/modules/admin-roles/service.ts +136 -0
  142. package/src/modules/admin-users/abilities.ts +76 -0
  143. package/src/modules/admin-users/commands.ts +157 -0
  144. package/src/modules/admin-users/components/create.module.css +63 -0
  145. package/src/modules/admin-users/components/create.tsx +323 -0
  146. package/src/modules/admin-users/components/roles.module.css +119 -0
  147. package/src/modules/admin-users/components/roles.tsx +172 -0
  148. package/src/modules/admin-users/components/set-password.module.css +46 -0
  149. package/src/modules/admin-users/components/set-password.tsx +199 -0
  150. package/src/modules/admin-users/components/update.module.css +49 -0
  151. package/src/modules/admin-users/components/update.tsx +328 -0
  152. package/src/modules/admin-users/dto.ts +39 -0
  153. package/src/modules/admin-users/errors.ts +84 -0
  154. package/src/modules/admin-users/index.ts +91 -0
  155. package/src/modules/admin-users/repository.ts +161 -0
  156. package/src/modules/admin-users/schemas.ts +168 -0
  157. package/src/modules/admin-users/seed-super-admin.ts +102 -0
  158. package/src/modules/admin-users/service.ts +166 -0
  159. package/src/modules/auth/components/sign-in-form.module.css +62 -0
  160. package/src/modules/auth/components/sign-in-form.tsx +132 -0
  161. package/src/modules/auth/index.ts +31 -0
  162. package/src/modules/auth/jwt-session-provider.ts +301 -0
  163. package/src/modules/auth/password.ts +94 -0
  164. package/src/modules/auth/phc.ts +121 -0
  165. package/src/modules/auth/refresh-tokens-repository.ts +74 -0
  166. package/src/modules/auth/resolve-actor.ts +42 -0
  167. package/src/services/admin-services-context.tsx +52 -0
  168. package/src/services/admin-services-types.ts +177 -0
  169. package/src/store.ts +32 -0
  170. package/src/vendor/noble-argon2/LICENSE +21 -0
  171. package/src/vendor/noble-argon2/README.md +87 -0
  172. package/src/vendor/noble-argon2/_blake.ts +58 -0
  173. package/src/vendor/noble-argon2/_md.ts +223 -0
  174. package/src/vendor/noble-argon2/_u64.ts +118 -0
  175. package/src/vendor/noble-argon2/argon2.ts +668 -0
  176. package/src/vendor/noble-argon2/blake2.ts +583 -0
  177. package/src/vendor/noble-argon2/utils.ts +849 -0
package/dist/abilities.js CHANGED
@@ -1,28 +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
- import { registerAdminPermissionsAbilities } from './modules/admin-permissions/abilities.js';
9
- import { registerAdminRolesAbilities } from './modules/admin-roles/abilities.js';
10
- import { registerAdminUsersAbilities } from './modules/admin-users/abilities.js';
11
- /**
12
- * Register every ability contributed by the admin subsystem.
13
- *
14
- * Called once at `initBylineCore()` time from the webapp config. Each
15
- * admin module contributes its own registrar (`registerAdminUsersAbilities`,
16
- * `registerAdminRolesAbilities`, …); this function fans out to them so
17
- * the webapp wiring stays a single line.
18
- *
19
- * Admin does not self-register from core to keep the `@byline/core`
20
- * package free of a dependency on `@byline/admin` — the registration
21
- * call is an opt-in at the composition root.
22
- */
23
- export function registerAdminAbilities(registry) {
1
+ import { registerAdminPermissionsAbilities } from "./modules/admin-permissions/abilities.js";
2
+ import { registerAdminRolesAbilities } from "./modules/admin-roles/abilities.js";
3
+ import { registerAdminUsersAbilities } from "./modules/admin-users/abilities.js";
4
+ function registerAdminAbilities(registry) {
24
5
  registerAdminUsersAbilities(registry);
25
6
  registerAdminRolesAbilities(registry);
26
7
  registerAdminPermissionsAbilities(registry);
27
- // registerAccountAbilities(registry) — added when that module lands
28
8
  }
9
+ export { registerAdminAbilities };
package/dist/index.js CHANGED
@@ -1,30 +1,8 @@
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
- * `@byline/admin` — the admin subsystem.
10
- *
11
- * Concrete implementation of the admin side of Byline: admin users,
12
- * roles, permissions, account self-service, and the built-in JWT
13
- * session provider. Depends on `@byline/auth` (the Actor / RequestContext
14
- * / SessionProvider contract) and `@byline/core` (collection and lifecycle
15
- * machinery). Third-party session providers (Lucia, WorkOS, Clerk, SSO)
16
- * are intentionally kept out of this package — they live as separate
17
- * adapters against `@byline/auth` directly.
18
- *
19
- * Prefer the per-module subpath exports (`@byline/admin/admin-users`,
20
- * `@byline/admin/auth`, etc.) over the root barrel; this root exists so
21
- * the package is importable as a single unit when that is convenient.
22
- */
23
- export { registerAdminAbilities } from './abilities.js';
24
- export { assertAdminActor, requireAdminActor } from './lib/assert-admin-actor.js';
25
- export { createCommand, } from './lib/create-command.js';
26
- export * from './modules/admin-account/index.js';
27
- export * from './modules/admin-permissions/index.js';
28
- export * from './modules/admin-roles/index.js';
29
- export * from './modules/admin-users/index.js';
30
- export * from './modules/auth/index.js';
1
+ export * from "./modules/admin-account/index.js";
2
+ export * from "./modules/admin-permissions/index.js";
3
+ export * from "./modules/admin-roles/index.js";
4
+ export * from "./modules/admin-users/index.js";
5
+ export * from "./modules/auth/index.js";
6
+ export { registerAdminAbilities } from "./abilities.js";
7
+ export { assertAdminActor, requireAdminActor } from "./lib/assert-admin-actor.js";
8
+ export { createCommand } from "./lib/create-command.js";
@@ -1,81 +1,20 @@
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 { ERR_UNAUTHENTICATED, isAdminAuth } from '@byline/auth';
9
- /**
10
- * Gate every admin command behind three checks, in order:
11
- *
12
- * 1. `context` exists. No in-process call may reach an admin command
13
- * without threading a `RequestContext` — seeds/tests pass
14
- * `createSuperAdminContext()`.
15
- * 2. `context.actor` is an `AdminAuth`. Anonymous admin calls are
16
- * rejected outright — admin actions are never public. A `UserAuth`
17
- * (end-user identity) also fails here: it may sign in against the
18
- * app realm, but it does not have an admin identity.
19
- * 3. The actor holds the required ability. `AdminAuth.assertAbility`
20
- * short-circuits on `isSuperAdmin: true`; otherwise the flat
21
- * ability set is consulted.
22
- *
23
- * Returns the narrowed `AdminAuth` so callers can use it without a
24
- * second type guard — the typical shape is:
25
- *
26
- * ```ts
27
- * export async function deleteAdminUserCommand(context, input, deps) {
28
- * const parsed = deleteAdminUserRequestSchema.parse(input)
29
- * const actor = assertAdminActor(context, ADMIN_USERS_ABILITIES.delete)
30
- * return service.deleteUser(actor, parsed)
31
- * }
32
- * ```
33
- *
34
- * The three failures produce distinct error codes:
35
- * - missing context / missing actor / wrong actor type → `ERR_UNAUTHENTICATED`
36
- * - ability missing → `ERR_FORBIDDEN`
37
- * (thrown from `AdminAuth.assertAbility`)
38
- */
39
- export function assertAdminActor(context, ability) {
1
+ import { ERR_UNAUTHENTICATED, isAdminAuth } from "@byline/auth";
2
+ function assertAdminActor(context, ability) {
40
3
  const actor = requireAdminActor(context, `admin action requiring '${ability}'`);
41
4
  actor.assertAbility(ability);
42
5
  return actor;
43
6
  }
44
- /**
45
- * Authentication-only counterpart of `assertAdminActor`. Runs the same
46
- * three checks (context present, actor present, actor is `AdminAuth`)
47
- * but **does not** assert any ability key.
48
- *
49
- * Used by self-service commands where the actor is the target by
50
- * definition — `@byline/admin/admin-account` for "change my own
51
- * password" / "update my own profile". For those flows there is no
52
- * meaningful ability to gate against; the security property is "you
53
- * may only mutate your own row," and the commands enforce that by
54
- * sourcing the target id from `actor.id` rather than from the
55
- * request payload.
56
- *
57
- * Reasoning is described as part of the request narrative so the
58
- * `ERR_UNAUTHENTICATED` message stays useful when it surfaces in logs
59
- * — the helper has no `ability` argument to fall back on.
60
- */
61
- export function requireAdminActor(context, reasonForLog) {
62
- if (!context) {
63
- throw ERR_UNAUTHENTICATED({
64
- message: `missing requestContext on ${reasonForLog}. Pass createSuperAdminContext() ` +
65
- `from @byline/auth for scripts/tests, or construct a request-scoped context from your ` +
66
- `session provider in the admin webapp.`,
67
- });
68
- }
7
+ function requireAdminActor(context, reasonForLog) {
8
+ if (!context) throw ERR_UNAUTHENTICATED({
9
+ message: `missing requestContext on ${reasonForLog}. Pass createSuperAdminContext() from @byline/auth for scripts/tests, or construct a request-scoped context from your session provider in the admin webapp.`
10
+ });
69
11
  const { actor } = context;
70
- if (actor == null) {
71
- throw ERR_UNAUTHENTICATED({
72
- message: `anonymous caller cannot perform ${reasonForLog}`,
73
- });
74
- }
75
- if (!isAdminAuth(actor)) {
76
- throw ERR_UNAUTHENTICATED({
77
- message: `non-admin actor cannot perform ${reasonForLog}`,
78
- });
79
- }
12
+ if (null == actor) throw ERR_UNAUTHENTICATED({
13
+ message: `anonymous caller cannot perform ${reasonForLog}`
14
+ });
15
+ if (!isAdminAuth(actor)) throw ERR_UNAUTHENTICATED({
16
+ message: `non-admin actor cannot perform ${reasonForLog}`
17
+ });
80
18
  return actor;
81
19
  }
20
+ export { assertAdminActor, requireAdminActor };
@@ -1,25 +1,15 @@
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 { assertAdminActor, requireAdminActor } from './assert-admin-actor.js';
9
- export function createCommand(spec) {
10
- return async function command(context, input, deps) {
1
+ import { assertAdminActor, requireAdminActor } from "./assert-admin-actor.js";
2
+ function createCommand(spec) {
3
+ return async function(context, input, deps) {
11
4
  const parsed = spec.schemas.input.parse(input ?? {});
12
- const actor = spec.auth.ability !== undefined
13
- ? assertAdminActor(context, spec.auth.ability)
14
- : requireAdminActor(context, spec.method);
15
- // `context` is non-null after the auth step — both helpers throw
16
- // `ERR_UNAUTHENTICATED` when the request context is missing.
5
+ const actor = void 0 !== spec.auth.ability ? assertAdminActor(context, spec.auth.ability) : requireAdminActor(context, spec.method);
17
6
  const result = await spec.handler({
18
7
  context: context,
19
8
  input: parsed,
20
9
  deps,
21
- actor,
10
+ actor
22
11
  });
23
12
  return spec.schemas.output.parse(result);
24
13
  };
25
14
  }
15
+ export { createCommand };
@@ -1,32 +1,43 @@
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 { createCommand } from '../../lib/create-command.js';
9
- import { adminUserResponseSchema } from '../admin-users/schemas.js';
10
- import { changeAccountPasswordRequestSchema, getAccountRequestSchema, updateAccountRequestSchema, } from './schemas.js';
11
- import { AdminAccountService } from './service.js';
1
+ import { createCommand } from "../../lib/create-command.js";
2
+ import { adminUserResponseSchema } from "../admin-users/schemas.js";
3
+ import { changeAccountPasswordRequestSchema, getAccountRequestSchema, updateAccountRequestSchema } from "./schemas.js";
4
+ import { AdminAccountService } from "./service.js";
12
5
  function serviceOf(deps) {
13
- return new AdminAccountService({ repo: deps.store.adminUsers });
6
+ return new AdminAccountService({
7
+ repo: deps.store.adminUsers
8
+ });
14
9
  }
15
- export const getAccountCommand = createCommand({
10
+ const getAccountCommand = createCommand({
16
11
  method: 'getAccount',
17
- auth: { authenticated: true },
18
- schemas: { input: getAccountRequestSchema, output: adminUserResponseSchema },
19
- handler: ({ deps, actor }) => serviceOf(deps).getAccount(actor.id),
12
+ auth: {
13
+ authenticated: true
14
+ },
15
+ schemas: {
16
+ input: getAccountRequestSchema,
17
+ output: adminUserResponseSchema
18
+ },
19
+ handler: ({ deps, actor })=>serviceOf(deps).getAccount(actor.id)
20
20
  });
21
- export const updateAccountCommand = createCommand({
21
+ const updateAccountCommand = createCommand({
22
22
  method: 'updateAccount',
23
- auth: { authenticated: true },
24
- schemas: { input: updateAccountRequestSchema, output: adminUserResponseSchema },
25
- handler: ({ input, deps, actor }) => serviceOf(deps).updateAccount(actor.id, input),
23
+ auth: {
24
+ authenticated: true
25
+ },
26
+ schemas: {
27
+ input: updateAccountRequestSchema,
28
+ output: adminUserResponseSchema
29
+ },
30
+ handler: ({ input, deps, actor })=>serviceOf(deps).updateAccount(actor.id, input)
26
31
  });
27
- export const changeAccountPasswordCommand = createCommand({
32
+ const changeAccountPasswordCommand = createCommand({
28
33
  method: 'changeAccountPassword',
29
- auth: { authenticated: true },
30
- schemas: { input: changeAccountPasswordRequestSchema, output: adminUserResponseSchema },
31
- handler: ({ input, deps, actor }) => serviceOf(deps).changePassword(actor.id, input),
34
+ auth: {
35
+ authenticated: true
36
+ },
37
+ schemas: {
38
+ input: changeAccountPasswordRequestSchema,
39
+ output: adminUserResponseSchema
40
+ },
41
+ handler: ({ input, deps, actor })=>serviceOf(deps).changePassword(actor.id, input)
32
42
  });
43
+ export { changeAccountPasswordCommand, getAccountCommand, updateAccountCommand };
@@ -0,0 +1,8 @@
1
+ import type { AccountResponse } from '../index.js';
2
+ interface ChangePasswordProps {
3
+ account: AccountResponse;
4
+ onClose?: () => void;
5
+ onSuccess?: (account: AccountResponse) => void;
6
+ }
7
+ export declare function ChangeAccountPassword({ account, onClose, onSuccess }: ChangePasswordProps): import("react").JSX.Element;
8
+ export {};
@@ -0,0 +1,192 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { revalidateLogic, useForm } from "@tanstack/react-form-start";
5
+ import { passwordSchema } from "@byline/core/validation";
6
+ import { Alert, Button, InputPassword, LoaderEllipsis } from "@byline/ui/react";
7
+ import classnames from "classnames";
8
+ import { z } from "zod";
9
+ import { useBylineAdminServices } from "../../../services/admin-services-context.js";
10
+ import change_password_module from "./change-password.module.js";
11
+ const changePasswordFormSchema = z.object({
12
+ currentPassword: z.string().min(1, {
13
+ message: 'Please enter your current password'
14
+ }),
15
+ newPassword: passwordSchema,
16
+ confirm: z.string({
17
+ message: 'Please confirm the new password'
18
+ })
19
+ }).refine((v)=>v.newPassword === v.confirm, {
20
+ message: 'New passwords do not match',
21
+ path: [
22
+ 'confirm'
23
+ ]
24
+ });
25
+ function ChangeAccountPassword({ account, onClose, onSuccess }) {
26
+ const { changeAccountPassword } = useBylineAdminServices();
27
+ const [formError, setFormError] = useState(null);
28
+ const [successMessage, setSuccessMessage] = useState(null);
29
+ const form = useForm({
30
+ defaultValues: {
31
+ currentPassword: '',
32
+ newPassword: '',
33
+ confirm: ''
34
+ },
35
+ validationLogic: revalidateLogic({
36
+ mode: 'blur',
37
+ modeAfterSubmission: 'change'
38
+ }),
39
+ validators: {
40
+ onDynamic: changePasswordFormSchema
41
+ },
42
+ onSubmit: async ({ value })=>{
43
+ setFormError(null);
44
+ setSuccessMessage(null);
45
+ try {
46
+ const updated = await changeAccountPassword({
47
+ data: {
48
+ vid: account.vid,
49
+ currentPassword: value.currentPassword,
50
+ newPassword: value.newPassword
51
+ }
52
+ });
53
+ setSuccessMessage('Password updated.');
54
+ form.reset({
55
+ currentPassword: '',
56
+ newPassword: '',
57
+ confirm: ''
58
+ });
59
+ onSuccess?.(updated);
60
+ } catch (err) {
61
+ const code = getErrorCode(err);
62
+ if ('admin.account.invalidCurrentPassword' === code) return void form.setFieldMeta('currentPassword', (meta)=>({
63
+ ...meta,
64
+ errorMap: {
65
+ ...meta.errorMap,
66
+ onServer: 'Current password is incorrect.'
67
+ },
68
+ errors: [
69
+ 'Current password is incorrect.'
70
+ ]
71
+ }));
72
+ if ('admin.users.versionConflict' === code) return void setFormError('Your account has been modified elsewhere since you opened this form. Reload to refresh and try again.');
73
+ if ('admin.account.notFound' === code) return void setFormError('Your admin account could not be found. Please sign in again.');
74
+ setFormError('Could not change the password. Please try again.');
75
+ }
76
+ }
77
+ });
78
+ return /*#__PURE__*/ jsx("div", {
79
+ className: classnames('byline-account-change-password-wrap', change_password_module.wrap),
80
+ children: /*#__PURE__*/ jsxs("form", {
81
+ noValidate: true,
82
+ onSubmit: (event)=>{
83
+ event.preventDefault();
84
+ event.stopPropagation();
85
+ form.handleSubmit();
86
+ },
87
+ className: classnames('byline-account-change-password-form', change_password_module.form),
88
+ children: [
89
+ formError ? /*#__PURE__*/ jsx(Alert, {
90
+ intent: "danger",
91
+ children: formError
92
+ }) : null,
93
+ successMessage ? /*#__PURE__*/ jsx(Alert, {
94
+ intent: "success",
95
+ children: successMessage
96
+ }) : null,
97
+ /*#__PURE__*/ jsx("p", {
98
+ className: "muted",
99
+ children: "Other active sessions will continue to work until their tokens expire. Sign out elsewhere if you suspect another device has been compromised."
100
+ }),
101
+ /*#__PURE__*/ jsx(form.Field, {
102
+ name: "currentPassword",
103
+ children: (field)=>/*#__PURE__*/ jsx(InputPassword, {
104
+ label: "Current password",
105
+ id: "currentPassword",
106
+ name: field.name,
107
+ value: field.state.value,
108
+ onBlur: field.handleBlur,
109
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
110
+ error: field.state.meta.errors.length > 0,
111
+ errorText: firstError(field.state.meta.errors),
112
+ autoComplete: "current-password",
113
+ required: true
114
+ })
115
+ }),
116
+ /*#__PURE__*/ jsx(form.Field, {
117
+ name: "newPassword",
118
+ children: (field)=>/*#__PURE__*/ jsx(InputPassword, {
119
+ label: "New password",
120
+ id: "newPassword",
121
+ name: field.name,
122
+ value: field.state.value,
123
+ onBlur: field.handleBlur,
124
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
125
+ error: field.state.meta.errors.length > 0,
126
+ errorText: firstError(field.state.meta.errors),
127
+ autoComplete: "new-password",
128
+ required: true
129
+ })
130
+ }),
131
+ /*#__PURE__*/ jsx(form.Field, {
132
+ name: "confirm",
133
+ children: (field)=>/*#__PURE__*/ jsx(InputPassword, {
134
+ label: "Confirm new password",
135
+ id: "confirm",
136
+ name: field.name,
137
+ value: field.state.value,
138
+ onBlur: field.handleBlur,
139
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
140
+ error: field.state.meta.errors.length > 0,
141
+ errorText: firstError(field.state.meta.errors),
142
+ autoComplete: "new-password",
143
+ required: true
144
+ })
145
+ }),
146
+ /*#__PURE__*/ jsxs("div", {
147
+ className: classnames('byline-account-change-password-actions', change_password_module.actions),
148
+ children: [
149
+ /*#__PURE__*/ jsx(Button, {
150
+ type: "button",
151
+ intent: "secondary",
152
+ size: "sm",
153
+ onClick: onClose,
154
+ className: classnames('byline-account-change-password-action', change_password_module.action),
155
+ children: successMessage ? 'Close' : 'Cancel'
156
+ }),
157
+ /*#__PURE__*/ jsx(form.Subscribe, {
158
+ selector: (state)=>({
159
+ canSubmit: state.canSubmit,
160
+ isSubmitting: state.isSubmitting,
161
+ isDirty: state.isDirty
162
+ }),
163
+ children: ({ canSubmit, isSubmitting })=>/*#__PURE__*/ jsx(Button, {
164
+ size: "sm",
165
+ intent: "primary",
166
+ type: "submit",
167
+ disabled: !canSubmit || isSubmitting,
168
+ className: classnames('byline-account-change-password-action', change_password_module.action),
169
+ children: true === isSubmitting ? /*#__PURE__*/ jsx(LoaderEllipsis, {
170
+ size: 42
171
+ }) : 'Save'
172
+ })
173
+ })
174
+ ]
175
+ })
176
+ ]
177
+ })
178
+ });
179
+ }
180
+ function firstError(errors) {
181
+ for (const err of errors){
182
+ if ('string' == typeof err) return err;
183
+ if (err && 'object' == typeof err && 'message' in err) {
184
+ const msg = err.message;
185
+ if ('string' == typeof msg) return msg;
186
+ }
187
+ }
188
+ }
189
+ function getErrorCode(err) {
190
+ return 'string' == typeof err?.code ? err.code : null;
191
+ }
192
+ export { ChangeAccountPassword };
@@ -0,0 +1,8 @@
1
+ import "./change-password_module.css";
2
+ const change_password_module = {
3
+ wrap: "wrap-S1VOJs",
4
+ form: "form-W_yW2Y",
5
+ actions: "actions-vW3jby",
6
+ action: "action-DnlRqk"
7
+ };
8
+ export default change_password_module;
@@ -0,0 +1,27 @@
1
+ :is(.wrap-S1VOJs, .byline-account-change-password-wrap) {
2
+ gap: var(--spacing-8);
3
+ padding: var(--spacing-4);
4
+ margin-top: var(--spacing-4);
5
+ flex-direction: column;
6
+ display: flex;
7
+ }
8
+
9
+ :is(.form-W_yW2Y, .byline-account-change-password-form) {
10
+ gap: var(--spacing-16);
11
+ padding-top: var(--spacing-8);
12
+ flex-direction: column;
13
+ display: flex;
14
+ }
15
+
16
+ :is(.actions-vW3jby, .byline-account-change-password-actions) {
17
+ justify-content: flex-end;
18
+ align-items: center;
19
+ gap: var(--spacing-8);
20
+ margin-top: var(--spacing-16);
21
+ display: flex;
22
+ }
23
+
24
+ :is(.action-DnlRqk, .byline-account-change-password-action) {
25
+ min-width: 4rem;
26
+ }
27
+
@@ -0,0 +1,29 @@
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
+ * Self-service account container.
10
+ *
11
+ * Same drawer pattern as `admin-users/ui/container.tsx` but
12
+ * narrower: only Profile and Password sections (no Roles, no
13
+ * Delete) — those are admin-only actions on someone else, not
14
+ * self-service. Each card surfaces the read-only summary plus an
15
+ * "Edit" affordance that opens the matching drawer.
16
+ *
17
+ * Forms lift the fresh `AccountResponse` back into local state on
18
+ * success so the container's bumped `vid` is in hand for any
19
+ * subsequent edit without a refetch.
20
+ *
21
+ * Stable override handles: see `container.module.css`.
22
+ */
23
+ import type React from 'react';
24
+ import type { AccountResponse } from '../index.js';
25
+ interface AccountSelfContainerProps {
26
+ account: AccountResponse;
27
+ }
28
+ export declare function AccountSelfContainer({ account }: AccountSelfContainerProps): React.JSX.Element;
29
+ export {};