@byline/admin 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +19 -0
  3. package/dist/abilities.d.ts +22 -0
  4. package/dist/abilities.d.ts.map +1 -0
  5. package/dist/abilities.js +29 -0
  6. package/dist/abilities.js.map +1 -0
  7. package/dist/index.d.ts +31 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +30 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/assert-admin-actor.d.ts +58 -0
  12. package/dist/lib/assert-admin-actor.d.ts.map +1 -0
  13. package/dist/lib/assert-admin-actor.js +82 -0
  14. package/dist/lib/assert-admin-actor.js.map +1 -0
  15. package/dist/modules/admin-account/commands.d.ts +30 -0
  16. package/dist/modules/admin-account/commands.d.ts.map +1 -0
  17. package/dist/modules/admin-account/commands.js +36 -0
  18. package/dist/modules/admin-account/commands.js.map +1 -0
  19. package/dist/modules/admin-account/errors.d.ts +52 -0
  20. package/dist/modules/admin-account/errors.d.ts.map +1 -0
  21. package/dist/modules/admin-account/errors.js +52 -0
  22. package/dist/modules/admin-account/errors.js.map +1 -0
  23. package/dist/modules/admin-account/index.d.ts +37 -0
  24. package/dist/modules/admin-account/index.d.ts.map +1 -0
  25. package/dist/modules/admin-account/index.js +35 -0
  26. package/dist/modules/admin-account/index.js.map +1 -0
  27. package/dist/modules/admin-account/schemas.d.ts +31 -0
  28. package/dist/modules/admin-account/schemas.d.ts.map +1 -0
  29. package/dist/modules/admin-account/schemas.js +69 -0
  30. package/dist/modules/admin-account/schemas.js.map +1 -0
  31. package/dist/modules/admin-account/service.d.ts +44 -0
  32. package/dist/modules/admin-account/service.d.ts.map +1 -0
  33. package/dist/modules/admin-account/service.js +76 -0
  34. package/dist/modules/admin-account/service.js.map +1 -0
  35. package/dist/modules/admin-permissions/abilities.d.ts +27 -0
  36. package/dist/modules/admin-permissions/abilities.d.ts.map +1 -0
  37. package/dist/modules/admin-permissions/abilities.js +40 -0
  38. package/dist/modules/admin-permissions/abilities.js.map +1 -0
  39. package/dist/modules/admin-permissions/commands.d.ts +30 -0
  40. package/dist/modules/admin-permissions/commands.d.ts.map +1 -0
  41. package/dist/modules/admin-permissions/commands.js +39 -0
  42. package/dist/modules/admin-permissions/commands.js.map +1 -0
  43. package/dist/modules/admin-permissions/dto.d.ts +18 -0
  44. package/dist/modules/admin-permissions/dto.d.ts.map +1 -0
  45. package/dist/modules/admin-permissions/dto.js +24 -0
  46. package/dist/modules/admin-permissions/dto.js.map +1 -0
  47. package/dist/modules/admin-permissions/errors.d.ts +34 -0
  48. package/dist/modules/admin-permissions/errors.d.ts.map +1 -0
  49. package/dist/modules/admin-permissions/errors.js +34 -0
  50. package/dist/modules/admin-permissions/errors.js.map +1 -0
  51. package/dist/modules/admin-permissions/index.d.ts +30 -0
  52. package/dist/modules/admin-permissions/index.d.ts.map +1 -0
  53. package/dist/modules/admin-permissions/index.js +27 -0
  54. package/dist/modules/admin-permissions/index.js.map +1 -0
  55. package/dist/modules/admin-permissions/repository.d.ts +48 -0
  56. package/dist/modules/admin-permissions/repository.d.ts.map +1 -0
  57. package/dist/modules/admin-permissions/repository.js +9 -0
  58. package/dist/modules/admin-permissions/repository.js.map +1 -0
  59. package/dist/modules/admin-permissions/schemas.d.ts +137 -0
  60. package/dist/modules/admin-permissions/schemas.d.ts.map +1 -0
  61. package/dist/modules/admin-permissions/schemas.js +99 -0
  62. package/dist/modules/admin-permissions/schemas.js.map +1 -0
  63. package/dist/modules/admin-permissions/service.d.ts +42 -0
  64. package/dist/modules/admin-permissions/service.d.ts.map +1 -0
  65. package/dist/modules/admin-permissions/service.js +114 -0
  66. package/dist/modules/admin-permissions/service.js.map +1 -0
  67. package/dist/modules/admin-roles/abilities.d.ts +33 -0
  68. package/dist/modules/admin-roles/abilities.d.ts.map +1 -0
  69. package/dist/modules/admin-roles/abilities.js +56 -0
  70. package/dist/modules/admin-roles/abilities.js.map +1 -0
  71. package/dist/modules/admin-roles/commands.d.ts +37 -0
  72. package/dist/modules/admin-roles/commands.d.ts.map +1 -0
  73. package/dist/modules/admin-roles/commands.js +70 -0
  74. package/dist/modules/admin-roles/commands.js.map +1 -0
  75. package/dist/modules/admin-roles/dto.d.ts +18 -0
  76. package/dist/modules/admin-roles/dto.d.ts.map +1 -0
  77. package/dist/modules/admin-roles/dto.js +27 -0
  78. package/dist/modules/admin-roles/dto.js.map +1 -0
  79. package/dist/modules/admin-roles/errors.d.ts +49 -0
  80. package/dist/modules/admin-roles/errors.d.ts.map +1 -0
  81. package/dist/modules/admin-roles/errors.js +49 -0
  82. package/dist/modules/admin-roles/errors.js.map +1 -0
  83. package/dist/modules/admin-roles/index.d.ts +30 -0
  84. package/dist/modules/admin-roles/index.d.ts.map +1 -0
  85. package/dist/modules/admin-roles/index.js +27 -0
  86. package/dist/modules/admin-roles/index.js.map +1 -0
  87. package/dist/modules/admin-roles/repository.d.ts +91 -0
  88. package/dist/modules/admin-roles/repository.d.ts.map +1 -0
  89. package/dist/modules/admin-roles/repository.js +9 -0
  90. package/dist/modules/admin-roles/repository.js.map +1 -0
  91. package/dist/modules/admin-roles/schemas.d.ts +99 -0
  92. package/dist/modules/admin-roles/schemas.d.ts.map +1 -0
  93. package/dist/modules/admin-roles/schemas.js +105 -0
  94. package/dist/modules/admin-roles/schemas.js.map +1 -0
  95. package/dist/modules/admin-roles/service.d.ts +49 -0
  96. package/dist/modules/admin-roles/service.d.ts.map +1 -0
  97. package/dist/modules/admin-roles/service.js +110 -0
  98. package/dist/modules/admin-roles/service.js.map +1 -0
  99. package/dist/modules/admin-users/abilities.d.ts +41 -0
  100. package/dist/modules/admin-users/abilities.d.ts.map +1 -0
  101. package/dist/modules/admin-users/abilities.js +70 -0
  102. package/dist/modules/admin-users/abilities.js.map +1 -0
  103. package/dist/modules/admin-users/commands.d.ts +45 -0
  104. package/dist/modules/admin-users/commands.d.ts.map +1 -0
  105. package/dist/modules/admin-users/commands.js +63 -0
  106. package/dist/modules/admin-users/commands.js.map +1 -0
  107. package/dist/modules/admin-users/dto.d.ts +20 -0
  108. package/dist/modules/admin-users/dto.d.ts.map +1 -0
  109. package/dist/modules/admin-users/dto.js +36 -0
  110. package/dist/modules/admin-users/dto.js.map +1 -0
  111. package/dist/modules/admin-users/errors.d.ts +53 -0
  112. package/dist/modules/admin-users/errors.d.ts.map +1 -0
  113. package/dist/modules/admin-users/errors.js +53 -0
  114. package/dist/modules/admin-users/errors.js.map +1 -0
  115. package/dist/modules/admin-users/index.d.ts +31 -0
  116. package/dist/modules/admin-users/index.d.ts.map +1 -0
  117. package/dist/modules/admin-users/index.js +28 -0
  118. package/dist/modules/admin-users/index.js.map +1 -0
  119. package/dist/modules/admin-users/repository.d.ts +147 -0
  120. package/dist/modules/admin-users/repository.d.ts.map +1 -0
  121. package/dist/modules/admin-users/repository.js +9 -0
  122. package/dist/modules/admin-users/repository.js.map +1 -0
  123. package/dist/modules/admin-users/schemas.d.ts +136 -0
  124. package/dist/modules/admin-users/schemas.d.ts.map +1 -0
  125. package/dist/modules/admin-users/schemas.js +137 -0
  126. package/dist/modules/admin-users/schemas.js.map +1 -0
  127. package/dist/modules/admin-users/seed-super-admin.d.ts +44 -0
  128. package/dist/modules/admin-users/seed-super-admin.d.ts.map +1 -0
  129. package/dist/modules/admin-users/seed-super-admin.js +70 -0
  130. package/dist/modules/admin-users/seed-super-admin.js.map +1 -0
  131. package/dist/modules/admin-users/service.d.ts +53 -0
  132. package/dist/modules/admin-users/service.d.ts.map +1 -0
  133. package/dist/modules/admin-users/service.js +143 -0
  134. package/dist/modules/admin-users/service.js.map +1 -0
  135. package/dist/modules/auth/index.d.ts +26 -0
  136. package/dist/modules/auth/index.d.ts.map +1 -0
  137. package/dist/modules/auth/index.js +25 -0
  138. package/dist/modules/auth/index.js.map +1 -0
  139. package/dist/modules/auth/jwt-session-provider.d.ts +47 -0
  140. package/dist/modules/auth/jwt-session-provider.d.ts.map +1 -0
  141. package/dist/modules/auth/jwt-session-provider.js +215 -0
  142. package/dist/modules/auth/jwt-session-provider.js.map +1 -0
  143. package/dist/modules/auth/password.d.ts +16 -0
  144. package/dist/modules/auth/password.d.ts.map +1 -0
  145. package/dist/modules/auth/password.js +48 -0
  146. package/dist/modules/auth/password.js.map +1 -0
  147. package/dist/modules/auth/refresh-tokens-repository.d.ts +71 -0
  148. package/dist/modules/auth/refresh-tokens-repository.d.ts.map +1 -0
  149. package/dist/modules/auth/refresh-tokens-repository.js +9 -0
  150. package/dist/modules/auth/refresh-tokens-repository.js.map +1 -0
  151. package/dist/modules/auth/resolve-actor.d.ts +25 -0
  152. package/dist/modules/auth/resolve-actor.d.ts.map +1 -0
  153. package/dist/modules/auth/resolve-actor.js +36 -0
  154. package/dist/modules/auth/resolve-actor.js.map +1 -0
  155. package/dist/store.d.ts +31 -0
  156. package/dist/store.d.ts.map +1 -0
  157. package/dist/store.js +9 -0
  158. package/dist/store.js.map +1 -0
  159. package/package.json +101 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { z } from 'zod';
9
+ export declare const listAdminUsersRequestSchema: z.ZodObject<{
10
+ page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
11
+ pageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
12
+ query: z.ZodOptional<z.ZodString>;
13
+ order: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
14
+ email: "email";
15
+ given_name: "given_name";
16
+ family_name: "family_name";
17
+ username: "username";
18
+ created_at: "created_at";
19
+ updated_at: "updated_at";
20
+ }>>>;
21
+ desc: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
22
+ }, z.core.$strip>;
23
+ export type ListAdminUsersRequest = z.infer<typeof listAdminUsersRequestSchema>;
24
+ export declare const getAdminUserRequestSchema: z.ZodObject<{
25
+ id: z.ZodUUID;
26
+ }, z.core.$strip>;
27
+ export type GetAdminUserRequest = z.infer<typeof getAdminUserRequestSchema>;
28
+ export declare const createAdminUserRequestSchema: z.ZodObject<{
29
+ email: z.ZodPipe<z.ZodEmail, z.ZodTransform<string, string>>;
30
+ password: z.ZodString;
31
+ given_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
32
+ family_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
+ username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
34
+ is_super_admin: z.ZodOptional<z.ZodBoolean>;
35
+ is_enabled: z.ZodOptional<z.ZodBoolean>;
36
+ is_email_verified: z.ZodOptional<z.ZodBoolean>;
37
+ }, z.core.$strip>;
38
+ export type CreateAdminUserRequest = z.infer<typeof createAdminUserRequestSchema>;
39
+ export declare const updateAdminUserRequestSchema: z.ZodObject<{
40
+ id: z.ZodUUID;
41
+ vid: z.ZodNumber;
42
+ patch: z.ZodObject<{
43
+ email: z.ZodOptional<z.ZodPipe<z.ZodEmail, z.ZodTransform<string, string>>>;
44
+ given_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
45
+ family_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
46
+ username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
47
+ is_super_admin: z.ZodOptional<z.ZodBoolean>;
48
+ is_enabled: z.ZodOptional<z.ZodBoolean>;
49
+ is_email_verified: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strip>;
51
+ }, z.core.$strip>;
52
+ export type UpdateAdminUserRequest = z.infer<typeof updateAdminUserRequestSchema>;
53
+ export declare const setAdminUserPasswordRequestSchema: z.ZodObject<{
54
+ id: z.ZodUUID;
55
+ vid: z.ZodNumber;
56
+ password: z.ZodString;
57
+ }, z.core.$strip>;
58
+ export type SetAdminUserPasswordRequest = z.infer<typeof setAdminUserPasswordRequestSchema>;
59
+ export declare const enableAdminUserRequestSchema: z.ZodObject<{
60
+ id: z.ZodUUID;
61
+ }, z.core.$strip>;
62
+ export type EnableAdminUserRequest = z.infer<typeof enableAdminUserRequestSchema>;
63
+ export declare const disableAdminUserRequestSchema: z.ZodObject<{
64
+ id: z.ZodUUID;
65
+ }, z.core.$strip>;
66
+ export type DisableAdminUserRequest = z.infer<typeof disableAdminUserRequestSchema>;
67
+ export declare const deleteAdminUserRequestSchema: z.ZodObject<{
68
+ id: z.ZodUUID;
69
+ vid: z.ZodNumber;
70
+ }, z.core.$strip>;
71
+ export type DeleteAdminUserRequest = z.infer<typeof deleteAdminUserRequestSchema>;
72
+ /**
73
+ * Public shape of an admin user. Deliberately excludes `password_hash` —
74
+ * the DTO in `dto.ts` is responsible for producing exactly this shape
75
+ * from an `AdminUserRow`, so the schema acts as a contract check.
76
+ */
77
+ export declare const adminUserResponseSchema: z.ZodObject<{
78
+ id: z.ZodString;
79
+ vid: z.ZodNumber;
80
+ email: z.ZodString;
81
+ given_name: z.ZodNullable<z.ZodString>;
82
+ family_name: z.ZodNullable<z.ZodString>;
83
+ username: z.ZodNullable<z.ZodString>;
84
+ remember_me: z.ZodBoolean;
85
+ last_login: z.ZodNullable<z.ZodDate>;
86
+ last_login_ip: z.ZodNullable<z.ZodString>;
87
+ failed_login_attempts: z.ZodNumber;
88
+ is_super_admin: z.ZodBoolean;
89
+ is_enabled: z.ZodBoolean;
90
+ is_email_verified: z.ZodBoolean;
91
+ created_at: z.ZodDate;
92
+ updated_at: z.ZodDate;
93
+ }, z.core.$strip>;
94
+ export type AdminUserResponse = z.infer<typeof adminUserResponseSchema>;
95
+ export declare const adminUserListResponseSchema: z.ZodObject<{
96
+ users: z.ZodArray<z.ZodObject<{
97
+ id: z.ZodString;
98
+ vid: z.ZodNumber;
99
+ email: z.ZodString;
100
+ given_name: z.ZodNullable<z.ZodString>;
101
+ family_name: z.ZodNullable<z.ZodString>;
102
+ username: z.ZodNullable<z.ZodString>;
103
+ remember_me: z.ZodBoolean;
104
+ last_login: z.ZodNullable<z.ZodDate>;
105
+ last_login_ip: z.ZodNullable<z.ZodString>;
106
+ failed_login_attempts: z.ZodNumber;
107
+ is_super_admin: z.ZodBoolean;
108
+ is_enabled: z.ZodBoolean;
109
+ is_email_verified: z.ZodBoolean;
110
+ created_at: z.ZodDate;
111
+ updated_at: z.ZodDate;
112
+ }, z.core.$strip>>;
113
+ meta: z.ZodObject<{
114
+ total: z.ZodNumber;
115
+ total_pages: z.ZodNumber;
116
+ page: z.ZodNumber;
117
+ page_size: z.ZodNumber;
118
+ query: z.ZodString;
119
+ order: z.ZodEnum<{
120
+ email: "email";
121
+ given_name: "given_name";
122
+ family_name: "family_name";
123
+ username: "username";
124
+ created_at: "created_at";
125
+ updated_at: "updated_at";
126
+ }>;
127
+ desc: z.ZodBoolean;
128
+ }, z.core.$strip>;
129
+ }, z.core.$strip>;
130
+ export type AdminUserListResponse = z.infer<typeof adminUserListResponseSchema>;
131
+ /** Empty response for void-returning mutations (set-password, enable, disable, delete). */
132
+ export declare const okResponseSchema: z.ZodObject<{
133
+ ok: z.ZodLiteral<true>;
134
+ }, z.core.$strip>;
135
+ export type OkResponse = z.infer<typeof okResponseSchema>;
136
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-users/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAoDvB,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;iBAMtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,eAAO,MAAM,yBAAyB;;iBAEpC,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E,eAAO,MAAM,4BAA4B;;;;;;;;;iBASvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;iBAcvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,iCAAiC;;;;iBAI5C,CAAA;AACF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAA;AAE3F,eAAO,MAAM,4BAA4B;;iBAA6B,CAAA;AACtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,eAAO,MAAM,6BAA6B;;iBAA6B,CAAA;AACvE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AAEnF,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAMjF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;iBAgBlC,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAWtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,2FAA2F;AAC3F,eAAO,MAAM,gBAAgB;;iBAAoC,CAAA;AACjE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
@@ -0,0 +1,137 @@
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 { passwordSchema, uuidSchema } from '@byline/core/validation';
9
+ import { z } from 'zod';
10
+ /**
11
+ * Zod request/response schemas for the admin-users commands.
12
+ *
13
+ * Both input and output are validated — response validation keeps the
14
+ * admin surface honest about what it promises downstream clients. The
15
+ * DTO shaper in `dto.ts` produces values that match `adminUserResponseSchema`
16
+ * exactly; if the schema or the DTO drifts, tests catch it at the
17
+ * command boundary.
18
+ *
19
+ * `vid` is the optimistic-concurrency version — every write that touches
20
+ * content content takes the client-held `vid` and the adapter gates the
21
+ * write on it, throwing `ADMIN_USER_VERSION_CONFLICT` on mismatch.
22
+ *
23
+ * Password and uuid helpers come from `@byline/core/validation` — the
24
+ * shared primitives ported from the organisation's `@infonomic/shared`
25
+ * schemas so rules stay consistent across projects.
26
+ */
27
+ // ---------------------------------------------------------------------------
28
+ // Field-level schemas (re-used across requests)
29
+ // ---------------------------------------------------------------------------
30
+ const idSchema = uuidSchema;
31
+ const vidSchema = z
32
+ .number({ message: 'vid is required' })
33
+ .int({ message: 'vid must be an integer' })
34
+ .positive({ message: 'vid must be positive' });
35
+ const emailSchema = z
36
+ .email({ message: 'email must be a valid address' })
37
+ .min(3)
38
+ .max(254)
39
+ .transform((v) => v.toLowerCase());
40
+ const nameSchema = z.string().min(1).max(100);
41
+ const orderSchema = z.enum([
42
+ 'given_name',
43
+ 'family_name',
44
+ 'email',
45
+ 'username',
46
+ 'created_at',
47
+ 'updated_at',
48
+ ]);
49
+ // ---------------------------------------------------------------------------
50
+ // Requests
51
+ // ---------------------------------------------------------------------------
52
+ export const listAdminUsersRequestSchema = z.object({
53
+ page: z.number().int().min(1).optional().default(1),
54
+ pageSize: z.number().int().min(1).max(100).optional().default(20),
55
+ query: z.string().max(128).optional(),
56
+ order: orderSchema.optional().default('created_at'),
57
+ desc: z.boolean().optional().default(true),
58
+ });
59
+ export const getAdminUserRequestSchema = z.object({
60
+ id: idSchema,
61
+ });
62
+ export const createAdminUserRequestSchema = z.object({
63
+ email: emailSchema,
64
+ password: passwordSchema,
65
+ given_name: nameSchema.nullish(),
66
+ family_name: nameSchema.nullish(),
67
+ username: z.string().min(1).max(100).nullish(),
68
+ is_super_admin: z.boolean().optional(),
69
+ is_enabled: z.boolean().optional(),
70
+ is_email_verified: z.boolean().optional(),
71
+ });
72
+ export const updateAdminUserRequestSchema = z.object({
73
+ id: idSchema,
74
+ vid: vidSchema,
75
+ patch: z
76
+ .object({
77
+ email: emailSchema.optional(),
78
+ given_name: nameSchema.nullish(),
79
+ family_name: nameSchema.nullish(),
80
+ username: z.string().min(1).max(100).nullish(),
81
+ is_super_admin: z.boolean().optional(),
82
+ is_enabled: z.boolean().optional(),
83
+ is_email_verified: z.boolean().optional(),
84
+ })
85
+ .refine((p) => Object.keys(p).length > 0, { message: 'patch cannot be empty' }),
86
+ });
87
+ export const setAdminUserPasswordRequestSchema = z.object({
88
+ id: idSchema,
89
+ vid: vidSchema,
90
+ password: passwordSchema,
91
+ });
92
+ export const enableAdminUserRequestSchema = z.object({ id: idSchema });
93
+ export const disableAdminUserRequestSchema = z.object({ id: idSchema });
94
+ export const deleteAdminUserRequestSchema = z.object({
95
+ id: idSchema,
96
+ vid: vidSchema,
97
+ });
98
+ // ---------------------------------------------------------------------------
99
+ // Responses
100
+ // ---------------------------------------------------------------------------
101
+ /**
102
+ * Public shape of an admin user. Deliberately excludes `password_hash` —
103
+ * the DTO in `dto.ts` is responsible for producing exactly this shape
104
+ * from an `AdminUserRow`, so the schema acts as a contract check.
105
+ */
106
+ export const adminUserResponseSchema = z.object({
107
+ id: z.string(),
108
+ vid: z.number().int(),
109
+ email: z.string(),
110
+ given_name: z.string().nullable(),
111
+ family_name: z.string().nullable(),
112
+ username: z.string().nullable(),
113
+ remember_me: z.boolean(),
114
+ last_login: z.date().nullable(),
115
+ last_login_ip: z.string().nullable(),
116
+ failed_login_attempts: z.number().int(),
117
+ is_super_admin: z.boolean(),
118
+ is_enabled: z.boolean(),
119
+ is_email_verified: z.boolean(),
120
+ created_at: z.date(),
121
+ updated_at: z.date(),
122
+ });
123
+ export const adminUserListResponseSchema = z.object({
124
+ users: z.array(adminUserResponseSchema),
125
+ meta: z.object({
126
+ total: z.number().int().min(0),
127
+ total_pages: z.number().int().min(0),
128
+ page: z.number().int().min(1),
129
+ page_size: z.number().int().min(1),
130
+ query: z.string(),
131
+ order: orderSchema,
132
+ desc: z.boolean(),
133
+ }),
134
+ });
135
+ /** Empty response for void-returning mutations (set-password, enable, disable, delete). */
136
+ export const okResponseSchema = z.object({ ok: z.literal(true) });
137
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/modules/admin-users/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { AdminStore } from '../../store.js';
9
+ export interface SeedSuperAdminInput {
10
+ email: string;
11
+ /** Plaintext — hashed before insert. */
12
+ password: string;
13
+ given_name?: string;
14
+ family_name?: string;
15
+ /** Role machine_name. Defaults to `'super-admin'`. */
16
+ roleMachineName?: string;
17
+ /** Role display name. Defaults to `'Super Admin'`. */
18
+ roleName?: string;
19
+ }
20
+ export interface SeedSuperAdminResult {
21
+ userId: string;
22
+ roleId: string;
23
+ created: {
24
+ user: boolean;
25
+ role: boolean;
26
+ assignment: boolean;
27
+ };
28
+ }
29
+ /**
30
+ * Idempotently create the super-admin role + user and assign them to each
31
+ * other. Safe to re-run against an existing database — reports what was
32
+ * newly created via the `created` flags so scripts can log meaningfully.
33
+ *
34
+ * This is the only built-in seed we ship for auth. Everything else is
35
+ * configured through the admin UI (or directly via the repositories) once
36
+ * the super-admin is in.
37
+ *
38
+ * The user row has `is_super_admin: true` and `is_enabled: true` set
39
+ * explicitly — the default for `is_enabled` is false so UI-created
40
+ * accounts require deliberate enablement, but the seed always produces a
41
+ * usable account.
42
+ */
43
+ export declare function seedSuperAdmin(store: AdminStore, input: SeedSuperAdminInput): Promise<SeedSuperAdminResult>;
44
+ //# sourceMappingURL=seed-super-admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-super-admin.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-users/seed-super-admin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,IAAI,EAAE,OAAO,CAAA;QACb,IAAI,EAAE,OAAO,CAAA;QACb,UAAU,EAAE,OAAO,CAAA;KACpB,CAAA;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CAmD/B"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { hashPassword } from '../auth/password.js';
9
+ /**
10
+ * Idempotently create the super-admin role + user and assign them to each
11
+ * other. Safe to re-run against an existing database — reports what was
12
+ * newly created via the `created` flags so scripts can log meaningfully.
13
+ *
14
+ * This is the only built-in seed we ship for auth. Everything else is
15
+ * configured through the admin UI (or directly via the repositories) once
16
+ * the super-admin is in.
17
+ *
18
+ * The user row has `is_super_admin: true` and `is_enabled: true` set
19
+ * explicitly — the default for `is_enabled` is false so UI-created
20
+ * accounts require deliberate enablement, but the seed always produces a
21
+ * usable account.
22
+ */
23
+ export async function seedSuperAdmin(store, input) {
24
+ const roleMachineName = input.roleMachineName ?? 'super-admin';
25
+ const roleName = input.roleName ?? 'Super Admin';
26
+ // 1. Role
27
+ let role = await store.adminRoles.getByMachineName(roleMachineName);
28
+ let roleCreated = false;
29
+ if (!role) {
30
+ role = await store.adminRoles.create({
31
+ name: roleName,
32
+ machine_name: roleMachineName,
33
+ description: 'Built-in role held by the initial super-admin. Individual users also carry the is_super_admin flag.',
34
+ order: 0,
35
+ });
36
+ roleCreated = true;
37
+ }
38
+ // 2. User
39
+ let user = await store.adminUsers.getByEmail(input.email);
40
+ let userCreated = false;
41
+ if (!user) {
42
+ const passwordHash = await hashPassword(input.password);
43
+ user = await store.adminUsers.create({
44
+ email: input.email,
45
+ password_hash: passwordHash,
46
+ given_name: input.given_name ?? null,
47
+ family_name: input.family_name ?? null,
48
+ is_super_admin: true,
49
+ is_enabled: true,
50
+ is_email_verified: true,
51
+ });
52
+ userCreated = true;
53
+ }
54
+ // 3. Assignment (idempotent)
55
+ const existingRoles = await store.adminRoles.listRolesForUser(user.id);
56
+ const alreadyAssigned = existingRoles.some((r) => r.id === role.id);
57
+ if (!alreadyAssigned) {
58
+ await store.adminRoles.assignToUser(role.id, user.id);
59
+ }
60
+ return {
61
+ userId: user.id,
62
+ roleId: role.id,
63
+ created: {
64
+ user: userCreated,
65
+ role: roleCreated,
66
+ assignment: !alreadyAssigned,
67
+ },
68
+ };
69
+ }
70
+ //# sourceMappingURL=seed-super-admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-super-admin.js","sourceRoot":"","sources":["../../../src/modules/admin-users/seed-super-admin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAyBlD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAiB,EACjB,KAA0B;IAE1B,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,IAAI,aAAa,CAAA;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAA;IAEhD,UAAU;IACV,IAAI,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAA;IACnE,IAAI,WAAW,GAAG,KAAK,CAAA;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;YACnC,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,eAAe;YAC7B,WAAW,EACT,qGAAqG;YACvG,KAAK,EAAE,CAAC;SACT,CAAC,CAAA;QACF,WAAW,GAAG,IAAI,CAAA;IACpB,CAAC;IAED,UAAU;IACV,IAAI,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACzD,IAAI,WAAW,GAAG,KAAK,CAAA;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;YACnC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,aAAa,EAAE,YAAY;YAC3B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;YACtC,cAAc,EAAE,IAAI;YACpB,UAAU,EAAE,IAAI;YAChB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAA;QACF,WAAW,GAAG,IAAI,CAAA;IACpB,CAAC;IAED,6BAA6B;IAC7B,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACtE,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAA;IACnE,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACvD,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,CAAC,eAAe;SAC7B;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { AdminAuth } from '@byline/auth';
9
+ import type { AdminUsersRepository } from './repository.js';
10
+ import type { AdminUserListResponse, AdminUserResponse, CreateAdminUserRequest, DeleteAdminUserRequest, DisableAdminUserRequest, EnableAdminUserRequest, GetAdminUserRequest, ListAdminUsersRequest, SetAdminUserPasswordRequest, UpdateAdminUserRequest } from './schemas.js';
11
+ /**
12
+ * Business logic for administering admin users.
13
+ *
14
+ * The service owns four concerns the repository deliberately avoids:
15
+ *
16
+ * 1. **Password hashing.** `hashPassword` from `@byline/admin/auth`
17
+ * runs here so every write path (create, setPassword, future
18
+ * password-reset flows) hashes consistently.
19
+ * 2. **Domain invariants.** Email conflict detection on create/update,
20
+ * self-delete / self-disable prevention — rules the database
21
+ * cannot enforce on its own.
22
+ * 3. **DTO shaping.** Raw rows are shaped through `toAdminUser` so
23
+ * the response contract is owned in one place.
24
+ * 4. **Optimistic-concurrency plumbing.** The repo gates writes on
25
+ * `expectedVid`; the service just threads it from the validated
26
+ * request shape. Version conflicts surface as
27
+ * `AdminUsersError(VERSION_CONFLICT)` from the adapter; the service
28
+ * does not catch them.
29
+ *
30
+ * Commands call service methods after Zod-validating input and asserting
31
+ * abilities; internal callers (seeds, other services) can call service
32
+ * methods directly. Either way, the service is transport-agnostic.
33
+ *
34
+ * Service methods take the acting `AdminAuth` as an explicit first
35
+ * argument when they need it for invariants (self-delete checks). Reads
36
+ * do not need the actor — the ability check at the command boundary is
37
+ * sufficient.
38
+ */
39
+ export declare class AdminUsersService {
40
+ #private;
41
+ constructor(deps: {
42
+ repo: AdminUsersRepository;
43
+ });
44
+ listUsers(request: ListAdminUsersRequest): Promise<AdminUserListResponse>;
45
+ getUser(request: GetAdminUserRequest): Promise<AdminUserResponse>;
46
+ createUser(request: CreateAdminUserRequest): Promise<AdminUserResponse>;
47
+ updateUser(request: UpdateAdminUserRequest): Promise<AdminUserResponse>;
48
+ setPassword(request: SetAdminUserPasswordRequest): Promise<AdminUserResponse>;
49
+ enableUser(request: EnableAdminUserRequest): Promise<void>;
50
+ disableUser(actor: AdminAuth, request: DisableAdminUserRequest): Promise<void>;
51
+ deleteUser(actor: AdminAuth, request: DeleteAdminUserRequest): Promise<void>;
52
+ }
53
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/admin-users/service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAU7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACvB,MAAM,cAAc,CAAA;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,iBAAiB;;gBAGhB,IAAI,EAAE;QAAE,IAAI,EAAE,oBAAoB,CAAA;KAAE;IAI1C,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA4BzE,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAMjE,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsBvE,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAevE,WAAW,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQ7E,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9E,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAMnF"}
@@ -0,0 +1,143 @@
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 { hashPassword } from '../auth/password.js';
9
+ import { toAdminUser } from './dto.js';
10
+ import { ERR_ADMIN_USER_EMAIL_IN_USE, ERR_ADMIN_USER_NOT_FOUND, ERR_ADMIN_USER_SELF_DELETE, ERR_ADMIN_USER_SELF_DISABLE, } from './errors.js';
11
+ /**
12
+ * Business logic for administering admin users.
13
+ *
14
+ * The service owns four concerns the repository deliberately avoids:
15
+ *
16
+ * 1. **Password hashing.** `hashPassword` from `@byline/admin/auth`
17
+ * runs here so every write path (create, setPassword, future
18
+ * password-reset flows) hashes consistently.
19
+ * 2. **Domain invariants.** Email conflict detection on create/update,
20
+ * self-delete / self-disable prevention — rules the database
21
+ * cannot enforce on its own.
22
+ * 3. **DTO shaping.** Raw rows are shaped through `toAdminUser` so
23
+ * the response contract is owned in one place.
24
+ * 4. **Optimistic-concurrency plumbing.** The repo gates writes on
25
+ * `expectedVid`; the service just threads it from the validated
26
+ * request shape. Version conflicts surface as
27
+ * `AdminUsersError(VERSION_CONFLICT)` from the adapter; the service
28
+ * does not catch them.
29
+ *
30
+ * Commands call service methods after Zod-validating input and asserting
31
+ * abilities; internal callers (seeds, other services) can call service
32
+ * methods directly. Either way, the service is transport-agnostic.
33
+ *
34
+ * Service methods take the acting `AdminAuth` as an explicit first
35
+ * argument when they need it for invariants (self-delete checks). Reads
36
+ * do not need the actor — the ability check at the command boundary is
37
+ * sufficient.
38
+ */
39
+ export class AdminUsersService {
40
+ #repo;
41
+ constructor(deps) {
42
+ this.#repo = deps.repo;
43
+ }
44
+ async listUsers(request) {
45
+ // Run list + count in parallel — they hit the same indexes but
46
+ // there's no reason to serialise them.
47
+ const [rows, total] = await Promise.all([
48
+ this.#repo.list({
49
+ page: request.page,
50
+ pageSize: request.pageSize,
51
+ query: request.query,
52
+ order: request.order,
53
+ desc: request.desc,
54
+ }),
55
+ this.#repo.count({ query: request.query }),
56
+ ]);
57
+ const total_pages = Math.max(1, Math.ceil(total / request.pageSize));
58
+ return {
59
+ users: rows.map(toAdminUser),
60
+ meta: {
61
+ total,
62
+ total_pages,
63
+ page: request.page,
64
+ page_size: request.pageSize,
65
+ query: request.query ?? '',
66
+ order: request.order,
67
+ desc: request.desc,
68
+ },
69
+ };
70
+ }
71
+ async getUser(request) {
72
+ const row = await this.#repo.getById(request.id);
73
+ if (!row)
74
+ throw ERR_ADMIN_USER_NOT_FOUND();
75
+ return toAdminUser(row);
76
+ }
77
+ async createUser(request) {
78
+ // Pre-check for email conflict. The unique index on `email` is the
79
+ // ultimate backstop if a race beats this check; the pre-check exists
80
+ // so the common case returns a clean domain-specific error rather
81
+ // than a raw Postgres code.
82
+ const existing = await this.#repo.getByEmail(request.email);
83
+ if (existing)
84
+ throw ERR_ADMIN_USER_EMAIL_IN_USE();
85
+ const password_hash = await hashPassword(request.password);
86
+ const row = await this.#repo.create({
87
+ email: request.email,
88
+ password_hash,
89
+ given_name: request.given_name ?? null,
90
+ family_name: request.family_name ?? null,
91
+ username: request.username ?? null,
92
+ is_super_admin: request.is_super_admin,
93
+ is_enabled: request.is_enabled,
94
+ is_email_verified: request.is_email_verified,
95
+ });
96
+ return toAdminUser(row);
97
+ }
98
+ async updateUser(request) {
99
+ const current = await this.#repo.getById(request.id);
100
+ if (!current)
101
+ throw ERR_ADMIN_USER_NOT_FOUND();
102
+ // If email is being changed, check that the new address is not taken
103
+ // by another user.
104
+ if (request.patch.email != null && request.patch.email !== current.email) {
105
+ const owner = await this.#repo.getByEmail(request.patch.email);
106
+ if (owner && owner.id !== request.id)
107
+ throw ERR_ADMIN_USER_EMAIL_IN_USE();
108
+ }
109
+ const row = await this.#repo.update(request.id, request.vid, request.patch);
110
+ return toAdminUser(row);
111
+ }
112
+ async setPassword(request) {
113
+ const exists = await this.#repo.getById(request.id);
114
+ if (!exists)
115
+ throw ERR_ADMIN_USER_NOT_FOUND();
116
+ const password_hash = await hashPassword(request.password);
117
+ const row = await this.#repo.setPasswordHash(request.id, request.vid, password_hash);
118
+ return toAdminUser(row);
119
+ }
120
+ async enableUser(request) {
121
+ const exists = await this.#repo.getById(request.id);
122
+ if (!exists)
123
+ throw ERR_ADMIN_USER_NOT_FOUND();
124
+ await this.#repo.setEnabled(request.id, true);
125
+ }
126
+ async disableUser(actor, request) {
127
+ if (actor.id === request.id)
128
+ throw ERR_ADMIN_USER_SELF_DISABLE();
129
+ const exists = await this.#repo.getById(request.id);
130
+ if (!exists)
131
+ throw ERR_ADMIN_USER_NOT_FOUND();
132
+ await this.#repo.setEnabled(request.id, false);
133
+ }
134
+ async deleteUser(actor, request) {
135
+ if (actor.id === request.id)
136
+ throw ERR_ADMIN_USER_SELF_DELETE();
137
+ const exists = await this.#repo.getById(request.id);
138
+ if (!exists)
139
+ throw ERR_ADMIN_USER_NOT_FOUND();
140
+ await this.#repo.delete(request.id, request.vid);
141
+ }
142
+ }
143
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/admin-users/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +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
+ * `@byline/admin/auth` — session handling for the built-in admin realm.
10
+ *
11
+ * Hosts the reference `JwtSessionProvider` and the sign-in / refresh /
12
+ * revoke orchestration that consumes it, along with password hashing
13
+ * (`hashPassword` / `verifyPassword`) and the `RefreshTokensRepository`
14
+ * contract the provider drives.
15
+ *
16
+ * The `SessionProvider` **interface** lives in `@byline/auth` so the
17
+ * pluggability contract stays narrow; this module supplies the
18
+ * Byline-native implementation. Third-party providers (Lucia, WorkOS,
19
+ * Clerk, institutional SSO) should be shipped as separate packages
20
+ * against `@byline/auth` rather than added here.
21
+ */
22
+ export { JwtSessionProvider, type JwtSessionProviderConfig } from './jwt-session-provider.js';
23
+ export { hashPassword, verifyPassword } from './password.js';
24
+ export { resolveActor } from './resolve-actor.js';
25
+ export type { IssueRefreshTokenInput, RefreshTokenRow, RefreshTokensRepository, } from './refresh-tokens-repository.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAC7F,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,YAAY,EACV,sBAAsB,EACtB,eAAe,EACf,uBAAuB,GACxB,MAAM,gCAAgC,CAAA"}