@rebasepro/server-core 0.4.0 → 0.6.0

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 (282) hide show
  1. package/README.md +62 -25
  2. package/dist/{server-core/src/api → api}/errors.d.ts +20 -2
  3. package/dist/{server-core/src/api → api}/rest/api-generator.d.ts +8 -2
  4. package/dist/{server-core/src/api → api}/types.d.ts +2 -0
  5. package/dist/auth/admin-user-ops.d.ts +79 -0
  6. package/dist/{server-core/src/auth → auth}/api-keys/index.d.ts +2 -2
  7. package/dist/{server-core/src/auth → auth}/auth-hooks.d.ts +37 -9
  8. package/dist/{server-core/src/auth → auth}/builtin-auth-adapter.d.ts +4 -4
  9. package/dist/{server-core/src/auth → auth}/index.d.ts +5 -2
  10. package/dist/{server-core/src/auth → auth}/jwt.d.ts +10 -0
  11. package/dist/auth/mfa-routes.d.ts +6 -0
  12. package/dist/auth/reset-password-admin.d.ts +29 -0
  13. package/dist/auth/session-routes.d.ts +25 -0
  14. package/dist/backend-CIxN4FVm.js +15 -0
  15. package/dist/backend-CIxN4FVm.js.map +1 -0
  16. package/dist/chunk-Dze3rakg.js +42 -0
  17. package/dist/{server-core/src/cron → cron}/cron-scheduler.d.ts +1 -1
  18. package/dist/dist-CZKP-Xz4.js +832 -0
  19. package/dist/dist-CZKP-Xz4.js.map +1 -0
  20. package/dist/env.d.ts +102 -0
  21. package/dist/from-VbwD7xRf.js +3849 -0
  22. package/dist/from-VbwD7xRf.js.map +1 -0
  23. package/dist/{server-core/src/index.d.ts → index.d.ts} +1 -0
  24. package/dist/index.es.js +60871 -50424
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/index.umd.js +73151 -51256
  27. package/dist/index.umd.js.map +1 -1
  28. package/dist/init/docs.d.ts +4 -0
  29. package/dist/init/health.d.ts +2 -0
  30. package/dist/init/middlewares.d.ts +10 -0
  31. package/dist/init/shutdown.d.ts +11 -0
  32. package/dist/init/storage.d.ts +5 -0
  33. package/dist/{server-core/src/init.d.ts → init.d.ts} +4 -4
  34. package/dist/jwt-DHcQRGC3.js +4168 -0
  35. package/dist/jwt-DHcQRGC3.js.map +1 -0
  36. package/dist/logger-BYU66ENZ.js +94 -0
  37. package/dist/logger-BYU66ENZ.js.map +1 -0
  38. package/dist/ms-BeBSuOXN.js +125 -0
  39. package/dist/ms-BeBSuOXN.js.map +1 -0
  40. package/dist/multipart-parser-CedBDOeC.js +299 -0
  41. package/dist/multipart-parser-CedBDOeC.js.map +1 -0
  42. package/dist/src-COaj0G3P.js +1182 -0
  43. package/dist/src-COaj0G3P.js.map +1 -0
  44. package/dist/{server-core/src/storage → storage}/image-transform.d.ts +3 -1
  45. package/dist/utils/request-id.d.ts +4 -0
  46. package/package.json +29 -29
  47. package/src/api/collections_for_test/callbacks_test_collection.ts +7 -6
  48. package/src/api/errors.ts +95 -20
  49. package/src/api/graphql/graphql-schema-generator.ts +15 -10
  50. package/src/api/logs-routes.ts +5 -2
  51. package/src/api/openapi-generator.ts +1 -1
  52. package/src/api/rest/api-generator-count.test.ts +21 -10
  53. package/src/api/rest/api-generator.ts +151 -36
  54. package/src/api/rest/query-parser.ts +18 -12
  55. package/src/api/server.ts +13 -2
  56. package/src/api/types.ts +2 -0
  57. package/src/auth/adapter-middleware.ts +17 -10
  58. package/src/auth/admin-user-ops.ts +236 -0
  59. package/src/auth/api-keys/api-key-middleware.ts +15 -9
  60. package/src/auth/api-keys/api-key-permission-guard.ts +1 -1
  61. package/src/auth/api-keys/api-key-routes.ts +3 -3
  62. package/src/auth/api-keys/api-key-store.ts +14 -8
  63. package/src/auth/api-keys/index.ts +2 -2
  64. package/src/auth/apple-oauth.ts +4 -3
  65. package/src/auth/auth-hooks.ts +50 -10
  66. package/src/auth/bitbucket-oauth.ts +5 -4
  67. package/src/auth/builtin-auth-adapter.ts +64 -54
  68. package/src/auth/custom-auth-adapter.ts +4 -5
  69. package/src/auth/discord-oauth.ts +5 -4
  70. package/src/auth/facebook-oauth.ts +5 -4
  71. package/src/auth/github-oauth.ts +6 -5
  72. package/src/auth/gitlab-oauth.ts +5 -4
  73. package/src/auth/google-oauth.ts +2 -1
  74. package/src/auth/index.ts +6 -2
  75. package/src/auth/jwt.ts +15 -4
  76. package/src/auth/linkedin-oauth.ts +4 -3
  77. package/src/auth/mfa-routes.ts +299 -0
  78. package/src/auth/mfa.ts +2 -1
  79. package/src/auth/microsoft-oauth.ts +5 -4
  80. package/src/auth/middleware.ts +5 -4
  81. package/src/auth/rate-limiter.ts +1 -1
  82. package/src/auth/reset-password-admin.ts +144 -0
  83. package/src/auth/rls-scope.ts +1 -1
  84. package/src/auth/routes.ts +52 -600
  85. package/src/auth/session-routes.ts +341 -0
  86. package/src/auth/slack-oauth.ts +6 -5
  87. package/src/auth/spotify-oauth.ts +5 -4
  88. package/src/auth/twitter-oauth.ts +4 -3
  89. package/src/collections/loader.ts +5 -4
  90. package/src/cron/cron-scheduler.test.ts +23 -11
  91. package/src/cron/cron-scheduler.ts +14 -8
  92. package/src/cron/cron-store.ts +1 -1
  93. package/src/email/smtp-email-service.ts +3 -2
  94. package/src/env.ts +11 -10
  95. package/src/index.ts +1 -0
  96. package/src/init/docs.ts +47 -0
  97. package/src/init/health.ts +37 -0
  98. package/src/init/middlewares.ts +61 -0
  99. package/src/init/shutdown.ts +56 -0
  100. package/src/init/storage.ts +57 -0
  101. package/src/init.ts +93 -295
  102. package/src/serve-spa.ts +12 -5
  103. package/src/services/driver-registry.ts +4 -3
  104. package/src/storage/S3StorageController.ts +1 -2
  105. package/src/storage/image-transform.ts +25 -10
  106. package/src/storage/routes.ts +30 -11
  107. package/src/storage/storage-registry.ts +4 -3
  108. package/src/storage/tus-handler.ts +12 -12
  109. package/src/utils/request-id.ts +40 -0
  110. package/src/utils/request-logger.ts +6 -0
  111. package/test/api-generator.test.ts +90 -2
  112. package/test/api-key-permission-guard.test.ts +24 -12
  113. package/test/auth-routes.test.ts +5 -3
  114. package/test/backend-hooks-data.test.ts +99 -30
  115. package/test/custom-auth-adapter.test.ts +16 -15
  116. package/test/email-templates.test.ts +10 -5
  117. package/test/env.test.ts +10 -10
  118. package/test/function-loader.test.ts +7 -4
  119. package/test/graphql-schema-generator.test.ts +554 -0
  120. package/test/jwt-security.test.ts +1 -1
  121. package/test/query-parser.test.ts +0 -1
  122. package/test/reset-password-admin.test.ts +113 -0
  123. package/test/singleton.test.ts +5 -5
  124. package/test/smtp-email-service.test.ts +21 -21
  125. package/test/webhook-service.test.ts +22 -11
  126. package/tsconfig.json +2 -0
  127. package/tsconfig.prod.json +3 -0
  128. package/vite.config.ts +5 -5
  129. package/dist/common/src/collections/CollectionRegistry.d.ts +0 -56
  130. package/dist/common/src/collections/default-collections.d.ts +0 -9
  131. package/dist/common/src/collections/index.d.ts +0 -2
  132. package/dist/common/src/data/buildRebaseData.d.ts +0 -14
  133. package/dist/common/src/data/query_builder.d.ts +0 -55
  134. package/dist/common/src/index.d.ts +0 -4
  135. package/dist/common/src/util/builders.d.ts +0 -57
  136. package/dist/common/src/util/callbacks.d.ts +0 -6
  137. package/dist/common/src/util/collections.d.ts +0 -11
  138. package/dist/common/src/util/common.d.ts +0 -2
  139. package/dist/common/src/util/conditions.d.ts +0 -26
  140. package/dist/common/src/util/entities.d.ts +0 -58
  141. package/dist/common/src/util/enums.d.ts +0 -3
  142. package/dist/common/src/util/index.d.ts +0 -16
  143. package/dist/common/src/util/navigation_from_path.d.ts +0 -34
  144. package/dist/common/src/util/navigation_utils.d.ts +0 -20
  145. package/dist/common/src/util/parent_references_from_path.d.ts +0 -6
  146. package/dist/common/src/util/paths.d.ts +0 -14
  147. package/dist/common/src/util/permissions.d.ts +0 -6
  148. package/dist/common/src/util/references.d.ts +0 -2
  149. package/dist/common/src/util/relations.d.ts +0 -22
  150. package/dist/common/src/util/resolutions.d.ts +0 -72
  151. package/dist/common/src/util/storage.d.ts +0 -24
  152. package/dist/index-Cr1D21av.js +0 -49
  153. package/dist/index-Cr1D21av.js.map +0 -1
  154. package/dist/server-core/src/auth/admin-routes.d.ts +0 -27
  155. package/dist/server-core/src/env.d.ts +0 -137
  156. package/dist/types/src/controllers/analytics_controller.d.ts +0 -7
  157. package/dist/types/src/controllers/auth.d.ts +0 -104
  158. package/dist/types/src/controllers/client.d.ts +0 -168
  159. package/dist/types/src/controllers/collection_registry.d.ts +0 -46
  160. package/dist/types/src/controllers/customization_controller.d.ts +0 -60
  161. package/dist/types/src/controllers/data.d.ts +0 -207
  162. package/dist/types/src/controllers/data_driver.d.ts +0 -218
  163. package/dist/types/src/controllers/database_admin.d.ts +0 -11
  164. package/dist/types/src/controllers/dialogs_controller.d.ts +0 -36
  165. package/dist/types/src/controllers/effective_role.d.ts +0 -4
  166. package/dist/types/src/controllers/email.d.ts +0 -36
  167. package/dist/types/src/controllers/index.d.ts +0 -18
  168. package/dist/types/src/controllers/local_config_persistence.d.ts +0 -20
  169. package/dist/types/src/controllers/navigation.d.ts +0 -225
  170. package/dist/types/src/controllers/registry.d.ts +0 -63
  171. package/dist/types/src/controllers/side_dialogs_controller.d.ts +0 -67
  172. package/dist/types/src/controllers/side_entity_controller.d.ts +0 -97
  173. package/dist/types/src/controllers/snackbar.d.ts +0 -24
  174. package/dist/types/src/controllers/storage.d.ts +0 -171
  175. package/dist/types/src/index.d.ts +0 -4
  176. package/dist/types/src/rebase_context.d.ts +0 -122
  177. package/dist/types/src/types/auth_adapter.d.ts +0 -301
  178. package/dist/types/src/types/backend.d.ts +0 -536
  179. package/dist/types/src/types/backend_hooks.d.ts +0 -172
  180. package/dist/types/src/types/builders.d.ts +0 -15
  181. package/dist/types/src/types/chips.d.ts +0 -5
  182. package/dist/types/src/types/collections.d.ts +0 -941
  183. package/dist/types/src/types/component_ref.d.ts +0 -47
  184. package/dist/types/src/types/cron.d.ts +0 -102
  185. package/dist/types/src/types/data_source.d.ts +0 -64
  186. package/dist/types/src/types/database_adapter.d.ts +0 -94
  187. package/dist/types/src/types/entities.d.ts +0 -145
  188. package/dist/types/src/types/entity_actions.d.ts +0 -104
  189. package/dist/types/src/types/entity_callbacks.d.ts +0 -173
  190. package/dist/types/src/types/entity_link_builder.d.ts +0 -7
  191. package/dist/types/src/types/entity_overrides.d.ts +0 -10
  192. package/dist/types/src/types/entity_views.d.ts +0 -87
  193. package/dist/types/src/types/export_import.d.ts +0 -21
  194. package/dist/types/src/types/formex.d.ts +0 -40
  195. package/dist/types/src/types/index.d.ts +0 -28
  196. package/dist/types/src/types/locales.d.ts +0 -4
  197. package/dist/types/src/types/modify_collections.d.ts +0 -5
  198. package/dist/types/src/types/plugins.d.ts +0 -282
  199. package/dist/types/src/types/properties.d.ts +0 -1181
  200. package/dist/types/src/types/property_config.d.ts +0 -74
  201. package/dist/types/src/types/relations.d.ts +0 -336
  202. package/dist/types/src/types/slots.d.ts +0 -262
  203. package/dist/types/src/types/translations.d.ts +0 -900
  204. package/dist/types/src/types/user_management_delegate.d.ts +0 -86
  205. package/dist/types/src/types/websockets.d.ts +0 -78
  206. package/dist/types/src/users/index.d.ts +0 -1
  207. package/dist/types/src/users/user.d.ts +0 -50
  208. package/src/auth/admin-routes.ts +0 -534
  209. package/test/admin-routes.test.ts +0 -544
  210. package/test/backend-hooks-admin.test.ts +0 -388
  211. package/test.ts +0 -6
  212. /package/dist/{server-core/src/api → api}/ast-schema-editor.d.ts +0 -0
  213. /package/dist/{server-core/src/api → api}/collections_for_test/callbacks_test_collection.d.ts +0 -0
  214. /package/dist/{server-core/src/api → api}/graphql/graphql-schema-generator.d.ts +0 -0
  215. /package/dist/{server-core/src/api → api}/graphql/index.d.ts +0 -0
  216. /package/dist/{server-core/src/api → api}/index.d.ts +0 -0
  217. /package/dist/{server-core/src/api → api}/logs-routes.d.ts +0 -0
  218. /package/dist/{server-core/src/api → api}/openapi-generator.d.ts +0 -0
  219. /package/dist/{server-core/src/api → api}/rest/index.d.ts +0 -0
  220. /package/dist/{server-core/src/api → api}/rest/query-parser.d.ts +0 -0
  221. /package/dist/{server-core/src/api → api}/schema-editor-routes.d.ts +0 -0
  222. /package/dist/{server-core/src/api → api}/server.d.ts +0 -0
  223. /package/dist/{server-core/src/auth → auth}/adapter-middleware.d.ts +0 -0
  224. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-middleware.d.ts +0 -0
  225. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-permission-guard.d.ts +0 -0
  226. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-routes.d.ts +0 -0
  227. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-store.d.ts +0 -0
  228. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-types.d.ts +0 -0
  229. /package/dist/{server-core/src/auth → auth}/apple-oauth.d.ts +0 -0
  230. /package/dist/{server-core/src/auth → auth}/bitbucket-oauth.d.ts +0 -0
  231. /package/dist/{server-core/src/auth → auth}/crypto-utils.d.ts +0 -0
  232. /package/dist/{server-core/src/auth → auth}/custom-auth-adapter.d.ts +0 -0
  233. /package/dist/{server-core/src/auth → auth}/discord-oauth.d.ts +0 -0
  234. /package/dist/{server-core/src/auth → auth}/facebook-oauth.d.ts +0 -0
  235. /package/dist/{server-core/src/auth → auth}/github-oauth.d.ts +0 -0
  236. /package/dist/{server-core/src/auth → auth}/gitlab-oauth.d.ts +0 -0
  237. /package/dist/{server-core/src/auth → auth}/google-oauth.d.ts +0 -0
  238. /package/dist/{server-core/src/auth → auth}/interfaces.d.ts +0 -0
  239. /package/dist/{server-core/src/auth → auth}/linkedin-oauth.d.ts +0 -0
  240. /package/dist/{server-core/src/auth → auth}/mfa.d.ts +0 -0
  241. /package/dist/{server-core/src/auth → auth}/microsoft-oauth.d.ts +0 -0
  242. /package/dist/{server-core/src/auth → auth}/middleware.d.ts +0 -0
  243. /package/dist/{server-core/src/auth → auth}/password.d.ts +0 -0
  244. /package/dist/{server-core/src/auth → auth}/rate-limiter.d.ts +0 -0
  245. /package/dist/{server-core/src/auth → auth}/rls-scope.d.ts +0 -0
  246. /package/dist/{server-core/src/auth → auth}/routes.d.ts +0 -0
  247. /package/dist/{server-core/src/auth → auth}/slack-oauth.d.ts +0 -0
  248. /package/dist/{server-core/src/auth → auth}/spotify-oauth.d.ts +0 -0
  249. /package/dist/{server-core/src/auth → auth}/twitter-oauth.d.ts +0 -0
  250. /package/dist/{server-core/src/collections → collections}/BackendCollectionRegistry.d.ts +0 -0
  251. /package/dist/{server-core/src/collections → collections}/loader.d.ts +0 -0
  252. /package/dist/{server-core/src/cron → cron}/cron-loader.d.ts +0 -0
  253. /package/dist/{server-core/src/cron → cron}/cron-routes.d.ts +0 -0
  254. /package/dist/{server-core/src/cron → cron}/cron-store.d.ts +0 -0
  255. /package/dist/{server-core/src/cron → cron}/index.d.ts +0 -0
  256. /package/dist/{server-core/src/db → db}/interfaces.d.ts +0 -0
  257. /package/dist/{server-core/src/email → email}/index.d.ts +0 -0
  258. /package/dist/{server-core/src/email → email}/smtp-email-service.d.ts +0 -0
  259. /package/dist/{server-core/src/email → email}/templates.d.ts +0 -0
  260. /package/dist/{server-core/src/email → email}/types.d.ts +0 -0
  261. /package/dist/{server-core/src/functions → functions}/function-loader.d.ts +0 -0
  262. /package/dist/{server-core/src/functions → functions}/function-routes.d.ts +0 -0
  263. /package/dist/{server-core/src/functions → functions}/index.d.ts +0 -0
  264. /package/dist/{server-core/src/history → history}/history-routes.d.ts +0 -0
  265. /package/dist/{server-core/src/history → history}/index.d.ts +0 -0
  266. /package/dist/{server-core/src/serve-spa.d.ts → serve-spa.d.ts} +0 -0
  267. /package/dist/{server-core/src/services → services}/driver-registry.d.ts +0 -0
  268. /package/dist/{server-core/src/services → services}/webhook-service.d.ts +0 -0
  269. /package/dist/{server-core/src/singleton.d.ts → singleton.d.ts} +0 -0
  270. /package/dist/{server-core/src/storage → storage}/LocalStorageController.d.ts +0 -0
  271. /package/dist/{server-core/src/storage → storage}/S3StorageController.d.ts +0 -0
  272. /package/dist/{server-core/src/storage → storage}/index.d.ts +0 -0
  273. /package/dist/{server-core/src/storage → storage}/routes.d.ts +0 -0
  274. /package/dist/{server-core/src/storage → storage}/storage-registry.d.ts +0 -0
  275. /package/dist/{server-core/src/storage → storage}/tus-handler.d.ts +0 -0
  276. /package/dist/{server-core/src/storage → storage}/types.d.ts +0 -0
  277. /package/dist/{server-core/src/types → types}/index.d.ts +0 -0
  278. /package/dist/{server-core/src/utils → utils}/dev-port.d.ts +0 -0
  279. /package/dist/{server-core/src/utils → utils}/logger.d.ts +0 -0
  280. /package/dist/{server-core/src/utils → utils}/logging.d.ts +0 -0
  281. /package/dist/{server-core/src/utils → utils}/request-logger.d.ts +0 -0
  282. /package/dist/{server-core/src/utils → utils}/sql.d.ts +0 -0
@@ -44,6 +44,7 @@ import {
44
44
  } from "./password";
45
45
  import type { PasswordValidationResult } from "./password";
46
46
  import type { AuthRepository, UserData, CreateUserData } from "./interfaces";
47
+ import type { EmailService, EmailConfig } from "../email";
47
48
 
48
49
  /**
49
50
  * Authentication method identifier for lifecycle hooks.
@@ -205,28 +206,67 @@ export interface AuthHooks {
205
206
  * This is fire-and-forget — errors are logged but do not fail the request.
206
207
  */
207
208
  afterUserDelete?(userId: string): Promise<void>;
209
+
210
+ /**
211
+ * Optional hook to customize or override the default user creation flow via the admin panel/REST API.
212
+ * When provided, this replaces the built-in password generation, hashing, and invitation email logic.
213
+ */
214
+ onAdminCreateUser?(
215
+ values: Record<string, unknown>,
216
+ ctx: {
217
+ authRepo: AuthRepository;
218
+ emailService?: EmailService;
219
+ emailConfig?: EmailConfig;
220
+ hashPassword: (password: string) => Promise<string>;
221
+ }
222
+ ): Promise<{
223
+ values: Record<string, unknown>;
224
+ temporaryPassword?: string;
225
+ invitationSent?: boolean;
226
+ }>;
227
+
228
+ /**
229
+ * Optional hook to customize or override the default password reset flow via the admin panel.
230
+ * When provided, this replaces the built-in password reset token generation, hashing, and email logic.
231
+ */
232
+ onAdminResetPassword?(
233
+ userId: string,
234
+ ctx: {
235
+ authRepo: AuthRepository;
236
+ emailService?: EmailService;
237
+ emailConfig?: EmailConfig;
238
+ }
239
+ ): Promise<{
240
+ temporaryPassword?: string;
241
+ invitationSent?: boolean;
242
+ }>;
208
243
  }
209
244
 
210
245
  /**
211
- * Resolved auth operationsevery method is guaranteed to exist.
246
+ * Resolved auth hookspassword operations are guaranteed to exist,
247
+ * all other hooks are passed through as-is (optional).
248
+ *
212
249
  * Created by `resolveAuthHooks()` which merges user hooks
213
250
  * with built-in defaults.
251
+ *
252
+ * Consumers should use the resolved object exclusively —
253
+ * never access the raw `AuthHooks` directly.
214
254
  */
215
- export interface ResolvedAuthOperations {
216
- hashPassword(password: string): Promise<string>;
217
- verifyPassword(password: string, storedHash: string): Promise<boolean>;
218
- validatePasswordStrength(password: string): PasswordValidationResult;
219
- }
255
+ export type ResolvedAuthHooks =
256
+ Required<Pick<AuthHooks, "hashPassword" | "verifyPassword" | "validatePasswordStrength">>
257
+ & Omit<AuthHooks, "hashPassword" | "verifyPassword" | "validatePasswordStrength">;
220
258
 
221
259
  /**
222
260
  * Merge user-provided hooks with the built-in defaults to produce
223
- * a complete set of resolved operations.
261
+ * a complete set of resolved hooks.
224
262
  *
225
263
  * This is the single point where defaults are applied — all consumers
226
- * call this once and use the resolved operations throughout.
264
+ * call this once and use the resolved hooks throughout.
227
265
  */
228
- export function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthOperations {
266
+ export function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthHooks {
229
267
  return {
268
+ ...hooks,
269
+
230
270
  hashPassword: hooks?.hashPassword
231
271
  ?? defaultHashPassword,
232
272
 
@@ -234,6 +274,6 @@ export function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthOperations {
234
274
  ?? defaultVerifyPassword,
235
275
 
236
276
  validatePasswordStrength: hooks?.validatePasswordStrength
237
- ?? defaultValidatePasswordStrength,
277
+ ?? defaultValidatePasswordStrength
238
278
  };
239
279
  }
@@ -1,5 +1,6 @@
1
1
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
2
  import { z } from "zod";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  /**
5
6
  * Creates a Bitbucket OAuth Provider integration (OAuth 2.0 consumer).
@@ -29,7 +30,7 @@ export function createBitbucketProvider(config: { clientId: string; clientSecret
29
30
  });
30
31
 
31
32
  if (!tokenResponse.ok) {
32
- console.error("Failed to get Bitbucket access token:", await tokenResponse.text());
33
+ logger.error("Failed to get Bitbucket access token", { detail: await tokenResponse.text() });
33
34
  return null;
34
35
  }
35
36
 
@@ -41,7 +42,7 @@ export function createBitbucketProvider(config: { clientId: string; clientSecret
41
42
  });
42
43
 
43
44
  if (!profileResponse.ok) {
44
- console.error("Failed to get Bitbucket user info:", await profileResponse.text());
45
+ logger.error("Failed to get Bitbucket user info", { detail: await profileResponse.text() });
45
46
  return null;
46
47
  }
47
48
 
@@ -65,7 +66,7 @@ export function createBitbucketProvider(config: { clientId: string; clientSecret
65
66
  email = primary?.email || null;
66
67
  }
67
68
 
68
- if (!email) { console.error("Bitbucket user has no verified email"); return null; }
69
+ if (!email) { logger.error("Bitbucket user has no verified email"); return null; }
69
70
 
70
71
  return {
71
72
  providerId: p.uuid,
@@ -74,7 +75,7 @@ export function createBitbucketProvider(config: { clientId: string; clientSecret
74
75
  photoUrl: p.links?.avatar?.href || null
75
76
  };
76
77
  } catch (error) {
77
- console.error("Bitbucket OAuth error:", error);
78
+ logger.error("Bitbucket OAuth error", { error: error });
78
79
  return null;
79
80
  }
80
81
  }
@@ -6,7 +6,7 @@
6
6
  * when the user passes a plain `RebaseAuthConfig` object.
7
7
  *
8
8
  * This is NOT a rewrite — it delegates to the existing `createAuthRoutes()`,
9
- * `createAdminRoutes()`, and `verifyAccessToken()` functions. The goal is to
9
+ * `createResetPasswordRoute()`, and `verifyAccessToken()` functions. The goal is to
10
10
  * present the same functionality through the pluggable `AuthAdapter` contract.
11
11
  */
12
12
 
@@ -19,21 +19,22 @@ import type {
19
19
  AuthUserListResult,
20
20
  AuthUserData,
21
21
  AuthCreateUserData,
22
- BootstrappedAuth,
23
- BackendHooks,
22
+ BootstrappedAuth
24
23
  } from "@rebasepro/types";
25
24
 
26
25
  import type { Hono } from "hono";
27
26
  import { verifyAccessToken } from "./jwt";
28
27
  import type { AccessTokenPayload } from "./jwt";
29
28
  import { createAuthRoutes } from "./routes";
30
- import { createAdminRoutes } from "./admin-routes";
29
+ import { createResetPasswordRoute } from "./reset-password-admin";
30
+ import { prepareAdminUserValues, finalizeAdminUserCreation } from "./admin-user-ops";
31
31
  import type { AuthRepository, OAuthProvider } from "./interfaces";
32
- import type { AuthHooks, ResolvedAuthOperations } from "./auth-hooks";
32
+ import type { AuthHooks, ResolvedAuthHooks } from "./auth-hooks";
33
33
  import { resolveAuthHooks } from "./auth-hooks";
34
34
  import type { EmailService, EmailConfig } from "../email";
35
35
  import type { HonoEnv } from "../api/types";
36
36
  import { safeCompare } from "./crypto-utils";
37
+ import { logger } from "../utils/logger";
37
38
 
38
39
  /**
39
40
  * Configuration for the built-in Rebase auth adapter.
@@ -57,10 +58,10 @@ export interface BuiltinAuthAdapterConfig {
57
58
  oauthProviders?: OAuthProvider<any>[];
58
59
  /** Static service key for server-to-server auth. */
59
60
  serviceKey?: string;
60
- /** Backend hooks for intercepting admin data. */
61
- hooks?: BackendHooks;
62
61
  /** Auth hooks for customizing password, credentials, lifecycle, etc. */
63
62
  authHooks?: AuthHooks;
63
+ /** The parsed auth config from the collection (if `auth` is an object, not just `true`). */
64
+ collectionAuthConfig?: import("@rebasepro/types").AuthCollectionConfig;
64
65
  }
65
66
 
66
67
  /**
@@ -79,8 +80,8 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
79
80
  defaultRole,
80
81
  oauthProviders = [],
81
82
  serviceKey,
82
- hooks,
83
83
  authHooks,
84
+ collectionAuthConfig
84
85
  } = config;
85
86
 
86
87
  const resolvedOps = resolveAuthHooks(authHooks);
@@ -109,7 +110,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
109
110
  email: "service@rebase.internal",
110
111
  roles: ["admin"],
111
112
  isAdmin: true,
112
- rawToken: token,
113
+ rawToken: token
113
114
  };
114
115
  }
115
116
 
@@ -119,29 +120,23 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
119
120
  return null;
120
121
  }
121
122
 
122
- // The decoded JWT may contain additional claims beyond the typed payload
123
- const extendedPayload = payload as AccessTokenPayload & {
124
- email?: string;
125
- displayName?: string;
126
- };
127
-
128
123
  // Resolve roles from the repository
129
124
  let roles: string[] = payload.roles || [];
130
125
  try {
131
126
  roles = await authRepository.getUserRoleIds(payload.userId);
132
- } catch {
133
- // Fall back to token roles if repository lookup fails
127
+ } catch (err: unknown) {
128
+ logger.warn("Role lookup from repository failed, using token roles as fallback", { userId: payload.userId, error: err });
134
129
  }
135
130
 
136
131
  const isAdmin = roles.some((r) => r === "admin" || r === "schema-admin");
137
132
 
138
133
  return {
139
134
  uid: payload.userId,
140
- email: extendedPayload.email ?? "",
141
- displayName: extendedPayload.displayName ?? null,
135
+ email: payload.email ?? "",
136
+ displayName: payload.displayName ?? null,
142
137
  roles,
143
138
  isAdmin,
144
- rawToken: token,
139
+ rawToken: token
145
140
  };
146
141
  },
147
142
 
@@ -153,7 +148,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
153
148
  email: "service@rebase.internal",
154
149
  roles: ["admin"],
155
150
  isAdmin: true,
156
- rawToken: token,
151
+ rawToken: token
157
152
  };
158
153
  }
159
154
 
@@ -163,32 +158,26 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
163
158
  return null;
164
159
  }
165
160
 
166
- const extendedPayload = payload as AccessTokenPayload & {
167
- email?: string;
168
- displayName?: string;
169
- };
170
-
171
161
  let roles: string[] = payload.roles || [];
172
162
  try {
173
163
  roles = await authRepository.getUserRoleIds(payload.userId);
174
- } catch {
175
- // Fall back to token roles if repository lookup fails
164
+ } catch (err: unknown) {
165
+ logger.warn("Role lookup from repository failed, using token roles as fallback", { userId: payload.userId, error: err });
176
166
  }
177
167
 
178
168
  const isAdmin = roles.some((r) => r === "admin" || r === "schema-admin");
179
169
 
180
170
  return {
181
171
  uid: payload.userId,
182
- email: extendedPayload.email ?? "",
183
- displayName: extendedPayload.displayName ?? null,
172
+ email: payload.email ?? "",
173
+ displayName: payload.displayName ?? null,
184
174
  roles,
185
175
  isAdmin,
186
- rawToken: token,
176
+ rawToken: token
187
177
  };
188
178
  },
189
179
 
190
- userManagement: createUserManagementFromRepo(authRepository, resolvedOps, authHooks),
191
-
180
+ userManagement: createUserManagementFromRepo(authRepository, resolvedOps),
192
181
 
193
182
 
194
183
  createAuthRoutes(): Hono<HonoEnv> | undefined {
@@ -199,18 +188,39 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
199
188
  allowRegistration,
200
189
  defaultRole,
201
190
  oauthProviders,
202
- authHooks,
191
+ authHooks
203
192
  });
204
193
  },
205
194
 
206
195
  createAdminRoutes(): Hono<HonoEnv> | undefined {
207
- return createAdminRoutes({
196
+ return createResetPasswordRoute({
208
197
  authRepo: authRepository,
209
198
  emailService,
210
199
  emailConfig,
211
200
  serviceKey,
212
- hooks,
213
201
  authHooks,
202
+ collectionAuthConfig
203
+ });
204
+ },
205
+
206
+ async prepareUserCreation(values, collectionAuth) {
207
+ const parsedCollectionAuth = collectionAuth as import("@rebasepro/types").AuthCollectionConfig | undefined;
208
+ return prepareAdminUserValues(values, {
209
+ authRepo: authRepository,
210
+ emailService,
211
+ emailConfig,
212
+ resolvedHooks: resolvedOps,
213
+ collectionAuthConfig: parsedCollectionAuth ?? collectionAuthConfig
214
+ });
215
+ },
216
+
217
+ async finalizeUserCreation(entity, clearPassword) {
218
+ return finalizeAdminUserCreation(entity, clearPassword, {
219
+ authRepo: authRepository,
220
+ emailService,
221
+ emailConfig,
222
+ resolvedHooks: resolvedOps,
223
+ collectionAuthConfig
214
224
  });
215
225
  },
216
226
 
@@ -236,9 +246,9 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
236
246
  profileUpdate: true,
237
247
  emailVerification: !!emailService?.isConfigured(),
238
248
  enabledProviders,
239
- needsSetup,
249
+ needsSetup
240
250
  };
241
- },
251
+ }
242
252
  };
243
253
 
244
254
  return adapter;
@@ -246,7 +256,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
246
256
 
247
257
  // ─── Internal Helpers ────────────────────────────────────────────────────────
248
258
 
249
- function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: ResolvedAuthOperations, authHooks?: AuthHooks): UserManagementAdapter {
259
+ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: ResolvedAuthHooks): UserManagementAdapter {
250
260
  return {
251
261
  async listUsers(options?: AuthUserListOptions): Promise<AuthUserListResult> {
252
262
  const result = await repo.listUsersPaginated({
@@ -255,13 +265,13 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
255
265
  search: options?.search,
256
266
  orderBy: options?.orderBy,
257
267
  orderDir: options?.orderDir,
258
- roleId: options?.roleId,
268
+ roleId: options?.roleId
259
269
  });
260
270
  return {
261
271
  users: result.users.map(toAuthUserData),
262
272
  total: result.total,
263
273
  limit: result.limit,
264
- offset: result.offset,
274
+ offset: result.offset
265
275
  };
266
276
  },
267
277
 
@@ -277,17 +287,17 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
277
287
  passwordHash,
278
288
  displayName: data.displayName,
279
289
  photoUrl: data.photoUrl,
280
- metadata: data.metadata,
290
+ metadata: data.metadata
281
291
  };
282
- if (authHooks?.beforeUserCreate) {
283
- createData = await authHooks.beforeUserCreate(createData);
292
+ if (resolvedOps.beforeUserCreate) {
293
+ createData = await resolvedOps.beforeUserCreate(createData);
284
294
  }
285
295
  const user = await repo.createUser(createData);
286
- if (authHooks?.afterUserCreate) {
296
+ if (resolvedOps.afterUserCreate) {
287
297
  try {
288
- await authHooks.afterUserCreate(user);
298
+ await resolvedOps.afterUserCreate(user);
289
299
  } catch (err) {
290
- console.error("[AuthHooks] afterUserCreate error:", err instanceof Error ? err.message : err);
300
+ logger.error("[AuthHooks] afterUserCreate error", { error: err instanceof Error ? err.message : err });
291
301
  }
292
302
  }
293
303
  return toAuthUserData(user);
@@ -308,16 +318,16 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
308
318
 
309
319
  async deleteUser(id: string): Promise<void> {
310
320
  // Call beforeUserDelete hook (throw to prevent deletion)
311
- if (authHooks?.beforeUserDelete) {
312
- await authHooks.beforeUserDelete(id);
321
+ if (resolvedOps.beforeUserDelete) {
322
+ await resolvedOps.beforeUserDelete(id);
313
323
  }
314
324
 
315
325
  await repo.deleteUser(id);
316
326
 
317
327
  // Fire afterUserDelete hook (fire-and-forget)
318
- if (authHooks?.afterUserDelete) {
319
- authHooks.afterUserDelete(id).catch(err => {
320
- console.error("[AuthHooks] afterUserDelete error:", err instanceof Error ? err.message : err);
328
+ if (resolvedOps.afterUserDelete) {
329
+ resolvedOps.afterUserDelete(id).catch(err => {
330
+ logger.error("[AuthHooks] afterUserDelete error", { error: err instanceof Error ? err.message : err });
321
331
  });
322
332
  }
323
333
  },
@@ -328,7 +338,7 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
328
338
 
329
339
  async setUserRoles(userId: string, roleIds: string[]): Promise<void> {
330
340
  await repo.setUserRoles(userId, roleIds);
331
- },
341
+ }
332
342
  };
333
343
  }
334
344
 
@@ -341,6 +351,6 @@ function toAuthUserData(user: { id: string; email: string; displayName?: string
341
351
  emailVerified: user.emailVerified,
342
352
  metadata: user.metadata,
343
353
  createdAt: user.createdAt,
344
- updatedAt: user.updatedAt,
354
+ updatedAt: user.updatedAt
345
355
  };
346
356
  }
@@ -29,7 +29,7 @@
29
29
  import type {
30
30
  AuthAdapter,
31
31
  AuthAdapterCapabilities,
32
- CustomAuthAdapterOptions,
32
+ CustomAuthAdapterOptions
33
33
  } from "@rebasepro/types";
34
34
 
35
35
  /**
@@ -52,7 +52,7 @@ export function createCustomAuthAdapter(options: CustomAuthAdapterOptions): Auth
52
52
  profileUpdate: false,
53
53
  emailVerification: false,
54
54
  enabledProviders: [],
55
- ...options.capabilities,
55
+ ...options.capabilities
56
56
  };
57
57
 
58
58
  const resolvedVerifyToken = options.verifyToken
@@ -60,7 +60,7 @@ export function createCustomAuthAdapter(options: CustomAuthAdapterOptions): Auth
60
60
  // Synthesize a minimal Request so adapters that only implement
61
61
  // verifyRequest still work for WebSocket token verification.
62
62
  const syntheticRequest = new Request("http://localhost/_ws_auth", {
63
- headers: { Authorization: `Bearer ${token}` },
63
+ headers: { Authorization: `Bearer ${token}` }
64
64
  });
65
65
  return options.verifyRequest(syntheticRequest);
66
66
  });
@@ -77,9 +77,8 @@ export function createCustomAuthAdapter(options: CustomAuthAdapterOptions): Auth
77
77
  userManagement: options.userManagement,
78
78
 
79
79
 
80
-
81
80
  getCapabilities() {
82
81
  return defaultCapabilities;
83
- },
82
+ }
84
83
  };
85
84
  }
@@ -1,5 +1,6 @@
1
1
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
2
  import { z } from "zod";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  /**
5
6
  * Creates a Discord OAuth2 Provider integration.
@@ -30,7 +31,7 @@ export function createDiscordProvider(config: { clientId: string; clientSecret:
30
31
  });
31
32
 
32
33
  if (!tokenResponse.ok) {
33
- console.error("Failed to get Discord access token:", await tokenResponse.text());
34
+ logger.error("Failed to get Discord access token", { detail: await tokenResponse.text() });
34
35
  return null;
35
36
  }
36
37
 
@@ -43,7 +44,7 @@ export function createDiscordProvider(config: { clientId: string; clientSecret:
43
44
  });
44
45
 
45
46
  if (!profileResponse.ok) {
46
- console.error("Failed to get Discord user info:", await profileResponse.text());
47
+ logger.error("Failed to get Discord user info", { detail: await profileResponse.text() });
47
48
  return null;
48
49
  }
49
50
 
@@ -57,7 +58,7 @@ export function createDiscordProvider(config: { clientId: string; clientSecret:
57
58
  };
58
59
 
59
60
  if (!profileData.email) {
60
- console.error("Discord user has no email (email scope may not have been granted)");
61
+ logger.error("Discord user has no email (email scope may not have been granted)");
61
62
  return null;
62
63
  }
63
64
 
@@ -75,7 +76,7 @@ export function createDiscordProvider(config: { clientId: string; clientSecret:
75
76
  photoUrl
76
77
  };
77
78
  } catch (error) {
78
- console.error("Discord OAuth error:", error);
79
+ logger.error("Discord OAuth error", { error: error });
79
80
  return null;
80
81
  }
81
82
  }
@@ -1,5 +1,6 @@
1
1
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
2
  import { z } from "zod";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  /**
5
6
  * Creates a Facebook / Meta OAuth Provider integration.
@@ -26,7 +27,7 @@ export function createFacebookProvider(config: { clientId: string; clientSecret:
26
27
  const tokenResponse = await fetch(tokenUrl.toString());
27
28
 
28
29
  if (!tokenResponse.ok) {
29
- console.error("Failed to get Facebook access token:", await tokenResponse.text());
30
+ logger.error("Failed to get Facebook access token", { detail: await tokenResponse.text() });
30
31
  return null;
31
32
  }
32
33
 
@@ -41,7 +42,7 @@ export function createFacebookProvider(config: { clientId: string; clientSecret:
41
42
  const profileResponse = await fetch(profileUrl.toString());
42
43
 
43
44
  if (!profileResponse.ok) {
44
- console.error("Failed to get Facebook user info:", await profileResponse.text());
45
+ logger.error("Failed to get Facebook user info", { detail: await profileResponse.text() });
45
46
  return null;
46
47
  }
47
48
 
@@ -53,7 +54,7 @@ export function createFacebookProvider(config: { clientId: string; clientSecret:
53
54
  };
54
55
 
55
56
  if (!profileData.email) {
56
- console.error("Facebook user has no email (email permission may not have been granted)");
57
+ logger.error("Facebook user has no email (email permission may not have been granted)");
57
58
  return null;
58
59
  }
59
60
 
@@ -64,7 +65,7 @@ export function createFacebookProvider(config: { clientId: string; clientSecret:
64
65
  photoUrl: profileData.picture?.data?.url || null
65
66
  };
66
67
  } catch (error) {
67
- console.error("Facebook OAuth error:", error);
68
+ logger.error("Facebook OAuth error", { error: error });
68
69
  return null;
69
70
  }
70
71
  }
@@ -1,5 +1,6 @@
1
1
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
2
  import { z } from "zod";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  /**
5
6
  * Creates a GitHub OAuth Provider integration.
@@ -33,13 +34,13 @@ export function createGitHubProvider(config: { clientId: string; clientSecret: s
33
34
  });
34
35
 
35
36
  if (!tokenResponse.ok) {
36
- console.error("Failed to get GitHub access token:", await tokenResponse.text());
37
+ logger.error("Failed to get GitHub access token", { detail: await tokenResponse.text() });
37
38
  return null;
38
39
  }
39
40
 
40
41
  const tokenData = await tokenResponse.json() as { access_token?: string; error?: string };
41
42
  if (tokenData.error || !tokenData.access_token) {
42
- console.error("GitHub token exchange error:", tokenData.error);
43
+ logger.error("GitHub token exchange error", { detail: tokenData.error });
43
44
  return null;
44
45
  }
45
46
 
@@ -55,7 +56,7 @@ export function createGitHubProvider(config: { clientId: string; clientSecret: s
55
56
  });
56
57
 
57
58
  if (!profileResponse.ok) {
58
- console.error("Failed to get GitHub user info:", await profileResponse.text());
59
+ logger.error("Failed to get GitHub user info", { detail: await profileResponse.text() });
59
60
  return null;
60
61
  }
61
62
 
@@ -91,7 +92,7 @@ export function createGitHubProvider(config: { clientId: string; clientSecret: s
91
92
  }
92
93
 
93
94
  if (!email) {
94
- console.error("GitHub user has no verified email");
95
+ logger.error("GitHub user has no verified email");
95
96
  return null;
96
97
  }
97
98
 
@@ -102,7 +103,7 @@ export function createGitHubProvider(config: { clientId: string; clientSecret: s
102
103
  photoUrl: profileData.avatar_url || null
103
104
  };
104
105
  } catch (error) {
105
- console.error("GitHub OAuth error:", error);
106
+ logger.error("GitHub OAuth error", { error: error });
106
107
  return null;
107
108
  }
108
109
  }
@@ -1,5 +1,6 @@
1
1
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
2
  import { z } from "zod";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  /**
5
6
  * Creates a GitLab OAuth Provider integration.
@@ -33,7 +34,7 @@ export function createGitLabProvider(config: {
33
34
  });
34
35
 
35
36
  if (!tokenResponse.ok) {
36
- console.error("Failed to get GitLab access token:", await tokenResponse.text());
37
+ logger.error("Failed to get GitLab access token", { detail: await tokenResponse.text() });
37
38
  return null;
38
39
  }
39
40
 
@@ -44,7 +45,7 @@ export function createGitLabProvider(config: {
44
45
  });
45
46
 
46
47
  if (!profileResponse.ok) {
47
- console.error("Failed to get GitLab user info:", await profileResponse.text());
48
+ logger.error("Failed to get GitLab user info", { detail: await profileResponse.text() });
48
49
  return null;
49
50
  }
50
51
 
@@ -53,7 +54,7 @@ export function createGitLabProvider(config: {
53
54
  email: string; avatar_url?: string | null;
54
55
  };
55
56
 
56
- if (!p.email) { console.error("GitLab user has no email"); return null; }
57
+ if (!p.email) { logger.error("GitLab user has no email"); return null; }
57
58
 
58
59
  return {
59
60
  providerId: String(p.id),
@@ -62,7 +63,7 @@ export function createGitLabProvider(config: {
62
63
  photoUrl: p.avatar_url || null
63
64
  };
64
65
  } catch (error) {
65
- console.error("GitLab OAuth error:", error);
66
+ logger.error("GitLab OAuth error", { error: error });
66
67
  return null;
67
68
  }
68
69
  }
@@ -1,6 +1,7 @@
1
1
  import { OAuth2Client } from "google-auth-library/build/src/index.js";
2
2
  import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
3
3
  import { z } from "zod";
4
+ import { logger } from "../utils/logger";
4
5
 
5
6
  export interface GoogleUserInfo {
6
7
  googleId: string;
@@ -210,7 +211,7 @@ export function createGoogleProvider(config: GoogleProviderConfig | string): OAu
210
211
 
211
212
  throw new Error("No valid Google credential provided (expected idToken, accessToken, or code+redirectUri)");
212
213
  } catch (error) {
213
- console.error("Google OAuth verification failed:", error);
214
+ logger.error("Google OAuth verification failed", { error: error });
214
215
  throw error;
215
216
  }
216
217
  }