@byline/admin 2.4.0 → 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
@@ -0,0 +1,170 @@
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 set_password_module from "./set-password.module.js";
11
+ const setPasswordFormSchema = z.object({
12
+ password: passwordSchema,
13
+ confirm: z.string({
14
+ message: 'Please confirm the password'
15
+ })
16
+ }).refine((v)=>v.password === v.confirm, {
17
+ message: 'Passwords do not match',
18
+ path: [
19
+ 'confirm'
20
+ ]
21
+ });
22
+ function SetPassword({ user, onClose, onSuccess }) {
23
+ const { setAdminUserPassword } = useBylineAdminServices();
24
+ const [formError, setFormError] = useState(null);
25
+ const [successMessage, setSuccessMessage] = useState(null);
26
+ const form = useForm({
27
+ defaultValues: {
28
+ password: '',
29
+ confirm: ''
30
+ },
31
+ validationLogic: revalidateLogic({
32
+ mode: 'blur',
33
+ modeAfterSubmission: 'change'
34
+ }),
35
+ validators: {
36
+ onDynamic: setPasswordFormSchema
37
+ },
38
+ onSubmit: async ({ value })=>{
39
+ setFormError(null);
40
+ setSuccessMessage(null);
41
+ try {
42
+ const updated = await setAdminUserPassword({
43
+ data: {
44
+ id: user.id,
45
+ vid: user.vid,
46
+ password: value.password
47
+ }
48
+ });
49
+ setSuccessMessage('Password updated.');
50
+ form.reset({
51
+ password: '',
52
+ confirm: ''
53
+ });
54
+ onSuccess?.(updated);
55
+ } catch (err) {
56
+ const code = getErrorCode(err);
57
+ if ('admin.users.versionConflict' === code) return void setFormError('This user has been modified elsewhere since you opened this form. Reload to refresh and try again.');
58
+ if ('admin.users.notFound' === code) return void setFormError('This user no longer exists.');
59
+ setFormError('Could not set the password. Please try again.');
60
+ }
61
+ }
62
+ });
63
+ return /*#__PURE__*/ jsx("div", {
64
+ className: classnames('byline-user-set-password-wrap', set_password_module.wrap),
65
+ children: /*#__PURE__*/ jsxs("form", {
66
+ noValidate: true,
67
+ onSubmit: (event)=>{
68
+ event.preventDefault();
69
+ event.stopPropagation();
70
+ form.handleSubmit();
71
+ },
72
+ className: classnames('byline-user-set-password-form', set_password_module.form),
73
+ children: [
74
+ formError ? /*#__PURE__*/ jsx(Alert, {
75
+ intent: "danger",
76
+ children: formError
77
+ }) : null,
78
+ successMessage ? /*#__PURE__*/ jsx(Alert, {
79
+ intent: "success",
80
+ children: successMessage
81
+ }) : null,
82
+ /*#__PURE__*/ jsxs("p", {
83
+ className: "muted",
84
+ children: [
85
+ "Sets a new password for",
86
+ ' ',
87
+ /*#__PURE__*/ jsx("span", {
88
+ className: classnames('byline-user-set-password-target', set_password_module.target),
89
+ children: user.email
90
+ }),
91
+ ". The user will need to sign in again with the new password."
92
+ ]
93
+ }),
94
+ /*#__PURE__*/ jsx(form.Field, {
95
+ name: "password",
96
+ children: (field)=>/*#__PURE__*/ jsx(InputPassword, {
97
+ label: "New password",
98
+ id: "password",
99
+ name: field.name,
100
+ value: field.state.value,
101
+ onBlur: field.handleBlur,
102
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
103
+ error: field.state.meta.errors.length > 0,
104
+ errorText: firstError(field.state.meta.errors),
105
+ autoComplete: "new-password",
106
+ required: true
107
+ })
108
+ }),
109
+ /*#__PURE__*/ jsx(form.Field, {
110
+ name: "confirm",
111
+ children: (field)=>/*#__PURE__*/ jsx(InputPassword, {
112
+ label: "Confirm new password",
113
+ id: "confirm",
114
+ name: field.name,
115
+ value: field.state.value,
116
+ onBlur: field.handleBlur,
117
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
118
+ error: field.state.meta.errors.length > 0,
119
+ errorText: firstError(field.state.meta.errors),
120
+ autoComplete: "new-password",
121
+ required: true
122
+ })
123
+ }),
124
+ /*#__PURE__*/ jsxs("div", {
125
+ className: classnames('byline-user-set-password-actions', set_password_module.actions),
126
+ children: [
127
+ /*#__PURE__*/ jsx(Button, {
128
+ type: "button",
129
+ intent: "secondary",
130
+ size: "sm",
131
+ onClick: onClose,
132
+ className: classnames('byline-user-set-password-action', set_password_module.action),
133
+ children: successMessage ? 'Close' : 'Cancel'
134
+ }),
135
+ /*#__PURE__*/ jsx(form.Subscribe, {
136
+ selector: (state)=>({
137
+ canSubmit: state.canSubmit,
138
+ isSubmitting: state.isSubmitting,
139
+ isDirty: state.isDirty
140
+ }),
141
+ children: ({ canSubmit, isSubmitting })=>/*#__PURE__*/ jsx(Button, {
142
+ size: "sm",
143
+ intent: "primary",
144
+ type: "submit",
145
+ disabled: !canSubmit || isSubmitting,
146
+ className: classnames('byline-user-set-password-action', set_password_module.action),
147
+ children: true === isSubmitting ? /*#__PURE__*/ jsx(LoaderEllipsis, {
148
+ size: 42
149
+ }) : 'Save'
150
+ })
151
+ })
152
+ ]
153
+ })
154
+ ]
155
+ })
156
+ });
157
+ }
158
+ function firstError(errors) {
159
+ for (const err of errors){
160
+ if ('string' == typeof err) return err;
161
+ if (err && 'object' == typeof err && 'message' in err) {
162
+ const msg = err.message;
163
+ if ('string' == typeof msg) return msg;
164
+ }
165
+ }
166
+ }
167
+ function getErrorCode(err) {
168
+ return 'string' == typeof err?.code ? err.code : null;
169
+ }
170
+ export { SetPassword };
@@ -0,0 +1,9 @@
1
+ import "./set-password_module.css";
2
+ const set_password_module = {
3
+ wrap: "wrap-SImk1V",
4
+ form: "form-ZNsJjL",
5
+ target: "target-NYVQqz",
6
+ actions: "actions-hvHeN5",
7
+ action: "action-nZwAQA"
8
+ };
9
+ export default set_password_module;
@@ -0,0 +1,31 @@
1
+ :is(.wrap-SImk1V, .byline-user-set-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-ZNsJjL, .byline-user-set-password-form) {
10
+ gap: var(--spacing-16);
11
+ padding-top: var(--spacing-8);
12
+ flex-direction: column;
13
+ display: flex;
14
+ }
15
+
16
+ :is(.target-NYVQqz, .byline-user-set-password-target) {
17
+ font-weight: var(--font-weight-semibold);
18
+ }
19
+
20
+ :is(.actions-hvHeN5, .byline-user-set-password-actions) {
21
+ justify-content: flex-end;
22
+ align-items: center;
23
+ gap: var(--spacing-8);
24
+ margin-top: var(--spacing-16);
25
+ display: flex;
26
+ }
27
+
28
+ :is(.action-nZwAQA, .byline-user-set-password-action) {
29
+ min-width: 4rem;
30
+ }
31
+
@@ -0,0 +1,8 @@
1
+ import type { AdminUserResponse } from '../index.js';
2
+ interface UpdateUserProps {
3
+ user: AdminUserResponse;
4
+ onClose?: () => void;
5
+ onSuccess?: (user: AdminUserResponse) => void;
6
+ }
7
+ export declare function UpdateUser({ user, onClose, onSuccess }: UpdateUserProps): import("react").JSX.Element;
8
+ export {};
@@ -0,0 +1,254 @@
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 { Alert, Button, Checkbox, Input, LoaderEllipsis } from "@byline/ui/react";
6
+ import classnames from "classnames";
7
+ import { z } from "zod";
8
+ import { useBylineAdminServices } from "../../../services/admin-services-context.js";
9
+ import update_module from "./update.module.js";
10
+ const updateUserSchema = z.object({
11
+ given_name: z.string().max(100, 'Given name must not exceed 100 characters'),
12
+ family_name: z.string().max(100, 'Family name must not exceed 100 characters'),
13
+ username: z.string().max(100, 'Username must not exceed 100 characters'),
14
+ email: z.email({
15
+ message: 'Enter a valid email address'
16
+ }).min(3).max(254, 'Email must not exceed 254 characters'),
17
+ is_super_admin: z.boolean(),
18
+ is_enabled: z.boolean(),
19
+ is_email_verified: z.boolean()
20
+ });
21
+ function defaultsFrom(user) {
22
+ return {
23
+ given_name: user.given_name ?? '',
24
+ family_name: user.family_name ?? '',
25
+ username: user.username ?? '',
26
+ email: user.email,
27
+ is_super_admin: user.is_super_admin,
28
+ is_enabled: user.is_enabled,
29
+ is_email_verified: user.is_email_verified
30
+ };
31
+ }
32
+ function buildPatch(values, user) {
33
+ const patch = {};
34
+ const normaliseText = (value)=>value.trim().length > 0 ? value : null;
35
+ const nextGiven = normaliseText(values.given_name);
36
+ const nextFamily = normaliseText(values.family_name);
37
+ const nextUsername = normaliseText(values.username);
38
+ if (nextGiven !== user.given_name) patch.given_name = nextGiven;
39
+ if (nextFamily !== user.family_name) patch.family_name = nextFamily;
40
+ if (nextUsername !== user.username) patch.username = nextUsername;
41
+ if (values.email !== user.email) patch.email = values.email;
42
+ if (values.is_super_admin !== user.is_super_admin) patch.is_super_admin = values.is_super_admin;
43
+ if (values.is_enabled !== user.is_enabled) patch.is_enabled = values.is_enabled;
44
+ if (values.is_email_verified !== user.is_email_verified) patch.is_email_verified = values.is_email_verified;
45
+ return patch;
46
+ }
47
+ function UpdateUser({ user, onClose, onSuccess }) {
48
+ const { updateAdminUser } = useBylineAdminServices();
49
+ const [formError, setFormError] = useState(null);
50
+ const [successMessage, setSuccessMessage] = useState(null);
51
+ const form = useForm({
52
+ defaultValues: defaultsFrom(user),
53
+ validationLogic: revalidateLogic({
54
+ mode: 'blur',
55
+ modeAfterSubmission: 'change'
56
+ }),
57
+ validators: {
58
+ onDynamic: updateUserSchema
59
+ },
60
+ onSubmit: async ({ value })=>{
61
+ setFormError(null);
62
+ setSuccessMessage(null);
63
+ const patch = buildPatch(value, user);
64
+ if (0 === Object.keys(patch).length) return void setSuccessMessage('No changes to save.');
65
+ try {
66
+ const updated = await updateAdminUser({
67
+ data: {
68
+ id: user.id,
69
+ vid: user.vid,
70
+ patch
71
+ }
72
+ });
73
+ setSuccessMessage('Saved.');
74
+ onSuccess?.(updated);
75
+ } catch (err) {
76
+ const code = getErrorCode(err);
77
+ if ('admin.users.emailInUse' === code) return void form.setFieldMeta('email', (meta)=>({
78
+ ...meta,
79
+ errorMap: {
80
+ ...meta.errorMap,
81
+ onServer: 'This email is already in use.'
82
+ },
83
+ errors: [
84
+ 'This email is already in use.'
85
+ ]
86
+ }));
87
+ if ('admin.users.versionConflict' === code) return void setFormError('This user has been modified elsewhere since you opened this form. Reload to get the latest values and try again.');
88
+ if ('admin.users.notFound' === code) return void setFormError('This user no longer exists.');
89
+ setFormError('Could not save changes. Please try again.');
90
+ }
91
+ }
92
+ });
93
+ return /*#__PURE__*/ jsx("div", {
94
+ className: classnames('byline-user-update-wrap', update_module.wrap),
95
+ children: /*#__PURE__*/ jsxs("form", {
96
+ noValidate: true,
97
+ onSubmit: (event)=>{
98
+ event.preventDefault();
99
+ event.stopPropagation();
100
+ form.handleSubmit();
101
+ },
102
+ className: classnames('byline-user-update-form', update_module.form),
103
+ children: [
104
+ formError ? /*#__PURE__*/ jsx(Alert, {
105
+ intent: "danger",
106
+ children: formError
107
+ }) : null,
108
+ successMessage ? /*#__PURE__*/ jsx(Alert, {
109
+ intent: "success",
110
+ children: successMessage
111
+ }) : null,
112
+ /*#__PURE__*/ jsx(form.Field, {
113
+ name: "given_name",
114
+ children: (field)=>/*#__PURE__*/ jsx(Input, {
115
+ label: "Given name",
116
+ id: "given_name",
117
+ name: field.name,
118
+ value: field.state.value,
119
+ onBlur: field.handleBlur,
120
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
121
+ error: field.state.meta.errors.length > 0,
122
+ errorText: firstError(field.state.meta.errors),
123
+ autoComplete: "given-name"
124
+ })
125
+ }),
126
+ /*#__PURE__*/ jsx(form.Field, {
127
+ name: "family_name",
128
+ children: (field)=>/*#__PURE__*/ jsx(Input, {
129
+ label: "Family name",
130
+ id: "family_name",
131
+ name: field.name,
132
+ value: field.state.value,
133
+ onBlur: field.handleBlur,
134
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
135
+ error: field.state.meta.errors.length > 0,
136
+ errorText: firstError(field.state.meta.errors),
137
+ autoComplete: "family-name"
138
+ })
139
+ }),
140
+ /*#__PURE__*/ jsx(form.Field, {
141
+ name: "username",
142
+ children: (field)=>/*#__PURE__*/ jsx(Input, {
143
+ label: "Username",
144
+ id: "username",
145
+ name: field.name,
146
+ value: field.state.value,
147
+ onBlur: field.handleBlur,
148
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
149
+ error: field.state.meta.errors.length > 0,
150
+ errorText: firstError(field.state.meta.errors),
151
+ helpText: "Optional. Leave blank to clear.",
152
+ autoComplete: "username"
153
+ })
154
+ }),
155
+ /*#__PURE__*/ jsx(form.Field, {
156
+ name: "email",
157
+ children: (field)=>/*#__PURE__*/ jsx(Input, {
158
+ label: "Email",
159
+ id: "email",
160
+ name: field.name,
161
+ type: "email",
162
+ value: field.state.value,
163
+ onBlur: field.handleBlur,
164
+ onChange: (e)=>field.handleChange(e.currentTarget.value),
165
+ error: field.state.meta.errors.length > 0,
166
+ errorText: firstError(field.state.meta.errors),
167
+ autoComplete: "email",
168
+ required: true
169
+ })
170
+ }),
171
+ /*#__PURE__*/ jsxs("div", {
172
+ className: classnames('byline-user-update-flags', update_module.flags),
173
+ children: [
174
+ /*#__PURE__*/ jsx(form.Field, {
175
+ name: "is_enabled",
176
+ children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
177
+ id: "is_enabled",
178
+ name: field.name,
179
+ label: "Enabled",
180
+ checked: field.state.value,
181
+ onCheckedChange: (checked)=>field.handleChange(true === checked),
182
+ helpText: "Disabled accounts cannot sign in."
183
+ })
184
+ }),
185
+ /*#__PURE__*/ jsx(form.Field, {
186
+ name: "is_email_verified",
187
+ children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
188
+ id: "is_email_verified",
189
+ name: field.name,
190
+ label: "Email verified",
191
+ checked: field.state.value,
192
+ onCheckedChange: (checked)=>field.handleChange(true === checked)
193
+ })
194
+ }),
195
+ /*#__PURE__*/ jsx(form.Field, {
196
+ name: "is_super_admin",
197
+ children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
198
+ id: "is_super_admin",
199
+ name: field.name,
200
+ label: "Super admin",
201
+ checked: field.state.value,
202
+ onCheckedChange: (checked)=>field.handleChange(true === checked),
203
+ helpText: "Super admins bypass every ability check — grant with care."
204
+ })
205
+ })
206
+ ]
207
+ }),
208
+ /*#__PURE__*/ jsxs("div", {
209
+ className: classnames('byline-user-update-actions', update_module.actions),
210
+ children: [
211
+ /*#__PURE__*/ jsx(Button, {
212
+ type: "button",
213
+ intent: "secondary",
214
+ size: "sm",
215
+ onClick: onClose,
216
+ className: classnames('byline-user-update-action', update_module.action),
217
+ children: successMessage ? 'Close' : 'Cancel'
218
+ }),
219
+ /*#__PURE__*/ jsx(form.Subscribe, {
220
+ selector: (state)=>({
221
+ canSubmit: state.canSubmit,
222
+ isSubmitting: state.isSubmitting,
223
+ isDirty: state.isDirty
224
+ }),
225
+ children: ({ canSubmit, isSubmitting })=>/*#__PURE__*/ jsx(Button, {
226
+ size: "sm",
227
+ intent: "primary",
228
+ type: "submit",
229
+ disabled: !canSubmit || isSubmitting,
230
+ className: classnames('byline-user-update-action', update_module.action),
231
+ children: true === isSubmitting ? /*#__PURE__*/ jsx(LoaderEllipsis, {
232
+ size: 42
233
+ }) : 'Save'
234
+ })
235
+ })
236
+ ]
237
+ })
238
+ ]
239
+ })
240
+ });
241
+ }
242
+ function firstError(errors) {
243
+ for (const err of errors){
244
+ if ('string' == typeof err) return err;
245
+ if (err && 'object' == typeof err && 'message' in err) {
246
+ const msg = err.message;
247
+ if ('string' == typeof msg) return msg;
248
+ }
249
+ }
250
+ }
251
+ function getErrorCode(err) {
252
+ return 'string' == typeof err?.code ? err.code : null;
253
+ }
254
+ export { UpdateUser };
@@ -0,0 +1,9 @@
1
+ import "./update_module.css";
2
+ const update_module = {
3
+ wrap: "wrap-nz82Of",
4
+ form: "form-jCTlkq",
5
+ flags: "flags-Drwubn",
6
+ actions: "actions-yzizIs",
7
+ action: "action-peiHA8"
8
+ };
9
+ export default update_module;
@@ -0,0 +1,34 @@
1
+ :is(.wrap-nz82Of, .byline-user-update-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-jCTlkq, .byline-user-update-form) {
10
+ gap: var(--spacing-16);
11
+ padding-top: var(--spacing-8);
12
+ flex-direction: column;
13
+ display: flex;
14
+ }
15
+
16
+ :is(.flags-Drwubn, .byline-user-update-flags) {
17
+ gap: var(--spacing-8);
18
+ padding: var(--spacing-4);
19
+ flex-direction: column;
20
+ display: flex;
21
+ }
22
+
23
+ :is(.actions-yzizIs, .byline-user-update-actions) {
24
+ justify-content: flex-end;
25
+ align-items: center;
26
+ gap: var(--spacing-8);
27
+ margin-top: var(--spacing-16);
28
+ display: flex;
29
+ }
30
+
31
+ :is(.action-peiHA8, .byline-user-update-action) {
32
+ min-width: 4rem;
33
+ }
34
+
@@ -1,20 +1,4 @@
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
- * Shape an `AdminUserRow` into its public `AdminUserResponse` form.
10
- *
11
- * The row type from the repository already omits `password_hash`, so
12
- * this is effectively an identity map — the indirection exists so that
13
- * if internal fields ever get added to the row (e.g. tenant id,
14
- * soft-delete timestamp), they are explicitly opted out of the public
15
- * shape here rather than leaking by default.
16
- */
17
- export function toAdminUser(row) {
1
+ function toAdminUser(row) {
18
2
  return {
19
3
  id: row.id,
20
4
  vid: row.vid,
@@ -30,6 +14,7 @@ export function toAdminUser(row) {
30
14
  is_enabled: row.is_enabled,
31
15
  is_email_verified: row.is_email_verified,
32
16
  created_at: row.created_at,
33
- updated_at: row.updated_at,
17
+ updated_at: row.updated_at
34
18
  };
35
19
  }
20
+ export { toAdminUser };
@@ -1,52 +1,26 @@
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
- * Module-local error codes for admin-users.
10
- *
11
- * Follows the same `code + factory` shape used by `AuthError` in
12
- * `@byline/auth`, but with its own class so consumers can distinguish
13
- * admin-users-specific failures from generic auth failures (e.g. to
14
- * translate `EMAIL_IN_USE` into a 409 at a transport boundary while
15
- * `FORBIDDEN` maps to 403).
16
- *
17
- * The codes are intentionally prefixed — `admin.users.*` — so they sort
18
- * alongside the matching ability keys in logs and admin UI messages.
19
- */
20
- export const AdminUsersErrorCodes = {
1
+ const AdminUsersErrorCodes = {
21
2
  NOT_FOUND: 'admin.users.notFound',
22
3
  EMAIL_IN_USE: 'admin.users.emailInUse',
23
4
  SELF_DELETE_FORBIDDEN: 'admin.users.selfDeleteForbidden',
24
5
  SELF_DISABLE_FORBIDDEN: 'admin.users.selfDisableForbidden',
25
- VERSION_CONFLICT: 'admin.users.versionConflict',
6
+ VERSION_CONFLICT: 'admin.users.versionConflict'
26
7
  };
27
- export class AdminUsersError extends Error {
28
- code;
29
- constructor(code, options) {
30
- super(options.message, options.cause != null ? { cause: options.cause } : undefined);
8
+ class AdminUsersError extends Error {
9
+ constructor(code, options){
10
+ super(options.message, null != options.cause ? {
11
+ cause: options.cause
12
+ } : void 0);
31
13
  this.name = 'AdminUsersError';
32
14
  this.code = code;
33
15
  }
34
16
  }
35
- const make = (code, defaultMessage) => (options) => new AdminUsersError(code, {
36
- message: options?.message ?? defaultMessage,
37
- cause: options?.cause,
38
- });
39
- /** The referenced admin user id does not exist. */
40
- export const ERR_ADMIN_USER_NOT_FOUND = make(AdminUsersErrorCodes.NOT_FOUND, 'admin user not found');
41
- /** Creating or updating an admin user conflicts with an existing email. */
42
- export const ERR_ADMIN_USER_EMAIL_IN_USE = make(AdminUsersErrorCodes.EMAIL_IN_USE, 'email already in use');
43
- /** The actor attempted to delete their own admin-user row. */
44
- export const ERR_ADMIN_USER_SELF_DELETE = make(AdminUsersErrorCodes.SELF_DELETE_FORBIDDEN, 'cannot delete your own admin account');
45
- /** The actor attempted to disable their own admin-user row. */
46
- export const ERR_ADMIN_USER_SELF_DISABLE = make(AdminUsersErrorCodes.SELF_DISABLE_FORBIDDEN, 'cannot disable your own admin account');
47
- /**
48
- * The stored `vid` does not match the client-supplied `expectedVid` —
49
- * the caller is holding a stale version of the row. Typical admin-UI
50
- * response is to reload the edit form with the current values.
51
- */
52
- export const ERR_ADMIN_USER_VERSION_CONFLICT = make(AdminUsersErrorCodes.VERSION_CONFLICT, 'admin user has been modified elsewhere — please reload and try again');
17
+ const make = (code, defaultMessage)=>(options)=>new AdminUsersError(code, {
18
+ message: options?.message ?? defaultMessage,
19
+ cause: options?.cause
20
+ });
21
+ const ERR_ADMIN_USER_NOT_FOUND = make(AdminUsersErrorCodes.NOT_FOUND, 'admin user not found');
22
+ const ERR_ADMIN_USER_EMAIL_IN_USE = make(AdminUsersErrorCodes.EMAIL_IN_USE, 'email already in use');
23
+ const ERR_ADMIN_USER_SELF_DELETE = make(AdminUsersErrorCodes.SELF_DELETE_FORBIDDEN, 'cannot delete your own admin account');
24
+ const ERR_ADMIN_USER_SELF_DISABLE = make(AdminUsersErrorCodes.SELF_DISABLE_FORBIDDEN, 'cannot disable your own admin account');
25
+ const ERR_ADMIN_USER_VERSION_CONFLICT = make(AdminUsersErrorCodes.VERSION_CONFLICT, 'admin user has been modified elsewhere — please reload and try again');
26
+ export { AdminUsersError, AdminUsersErrorCodes, ERR_ADMIN_USER_EMAIL_IN_USE, ERR_ADMIN_USER_NOT_FOUND, ERR_ADMIN_USER_SELF_DELETE, ERR_ADMIN_USER_SELF_DISABLE, ERR_ADMIN_USER_VERSION_CONFLICT };
@@ -1,27 +1,7 @@
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/admin-users` — admin user CRUD.
10
- *
11
- * Exports the adapter-facing `AdminUsersRepository` contract, ability
12
- * keys, transport-agnostic commands, the `AdminUsersService`, the seed
13
- * helper, and the module's error types. Commands are the recommended
14
- * entry point for any caller; the service is exposed for internal uses
15
- * (seeds, other services) that want to skip Zod/ability overhead.
16
- *
17
- * Password hashing is owned by `@byline/admin/auth`; this module takes
18
- * pre-hashed `password_hash` strings on the repository boundary so the
19
- * adapter never sees plaintext.
20
- */
21
- export { ADMIN_USERS_ABILITIES, registerAdminUsersAbilities, } from './abilities.js';
22
- export { createAdminUserCommand, deleteAdminUserCommand, disableAdminUserCommand, enableAdminUserCommand, getAdminUserCommand, listAdminUsersCommand, setAdminUserPasswordCommand, updateAdminUserCommand, } from './commands.js';
23
- export { toAdminUser } from './dto.js';
24
- export { AdminUsersError, AdminUsersErrorCodes, ERR_ADMIN_USER_EMAIL_IN_USE, ERR_ADMIN_USER_NOT_FOUND, ERR_ADMIN_USER_SELF_DELETE, ERR_ADMIN_USER_SELF_DISABLE, ERR_ADMIN_USER_VERSION_CONFLICT, } from './errors.js';
25
- export { adminUserListResponseSchema, adminUserResponseSchema, createAdminUserRequestSchema, deleteAdminUserRequestSchema, disableAdminUserRequestSchema, enableAdminUserRequestSchema, getAdminUserRequestSchema, listAdminUsersRequestSchema, okResponseSchema, setAdminUserPasswordRequestSchema, updateAdminUserRequestSchema, } from './schemas.js';
26
- export { seedSuperAdmin, } from './seed-super-admin.js';
27
- export { AdminUsersService } from './service.js';
1
+ export { ADMIN_USERS_ABILITIES, registerAdminUsersAbilities } from "./abilities.js";
2
+ export { createAdminUserCommand, deleteAdminUserCommand, disableAdminUserCommand, enableAdminUserCommand, getAdminUserCommand, listAdminUsersCommand, setAdminUserPasswordCommand, updateAdminUserCommand } from "./commands.js";
3
+ export { toAdminUser } from "./dto.js";
4
+ export { AdminUsersError, AdminUsersErrorCodes, ERR_ADMIN_USER_EMAIL_IN_USE, ERR_ADMIN_USER_NOT_FOUND, ERR_ADMIN_USER_SELF_DELETE, ERR_ADMIN_USER_SELF_DISABLE, ERR_ADMIN_USER_VERSION_CONFLICT } from "./errors.js";
5
+ export { adminUserListResponseSchema, adminUserResponseSchema, createAdminUserRequestSchema, deleteAdminUserRequestSchema, disableAdminUserRequestSchema, enableAdminUserRequestSchema, getAdminUserRequestSchema, listAdminUsersRequestSchema, okResponseSchema, setAdminUserPasswordRequestSchema, updateAdminUserRequestSchema } from "./schemas.js";
6
+ export { seedSuperAdmin } from "./seed-super-admin.js";
7
+ export { AdminUsersService } from "./service.js";