@rebasepro/server-core 0.5.0 → 0.6.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 (279) hide show
  1. package/dist/{server-core/src/api → api}/errors.d.ts +5 -2
  2. package/dist/{server-core/src/api → api}/rest/api-generator.d.ts +8 -2
  3. package/dist/{server-core/src/api → api}/types.d.ts +2 -0
  4. package/dist/auth/admin-user-ops.d.ts +79 -0
  5. package/dist/{server-core/src/auth → auth}/api-keys/index.d.ts +2 -2
  6. package/dist/{server-core/src/auth → auth}/auth-hooks.d.ts +37 -9
  7. package/dist/{server-core/src/auth → auth}/builtin-auth-adapter.d.ts +4 -4
  8. package/dist/{server-core/src/auth → auth}/index.d.ts +5 -2
  9. package/dist/auth/mfa-routes.d.ts +6 -0
  10. package/dist/auth/reset-password-admin.d.ts +29 -0
  11. package/dist/auth/session-routes.d.ts +25 -0
  12. package/dist/backend-CIxN4FVm.js +15 -0
  13. package/dist/backend-CIxN4FVm.js.map +1 -0
  14. package/dist/chunk-Dze3rakg.js +42 -0
  15. package/dist/{server-core/src/cron → cron}/cron-scheduler.d.ts +1 -1
  16. package/dist/dist-CZKP-Xz4.js +832 -0
  17. package/dist/dist-CZKP-Xz4.js.map +1 -0
  18. package/dist/env.d.ts +102 -0
  19. package/dist/from-VbwD7xRf.js +3849 -0
  20. package/dist/from-VbwD7xRf.js.map +1 -0
  21. package/dist/{server-core/src/index.d.ts → index.d.ts} +1 -0
  22. package/dist/index.es.js +60872 -50462
  23. package/dist/index.es.js.map +1 -1
  24. package/dist/index.umd.js +73156 -51298
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/init/docs.d.ts +4 -0
  27. package/dist/init/health.d.ts +2 -0
  28. package/dist/init/middlewares.d.ts +10 -0
  29. package/dist/init/shutdown.d.ts +11 -0
  30. package/dist/init/storage.d.ts +5 -0
  31. package/dist/{server-core/src/init.d.ts → init.d.ts} +4 -4
  32. package/dist/jwt-DHcQRGC3.js +4168 -0
  33. package/dist/jwt-DHcQRGC3.js.map +1 -0
  34. package/dist/logger-BYU66ENZ.js +94 -0
  35. package/dist/logger-BYU66ENZ.js.map +1 -0
  36. package/dist/ms-BeBSuOXN.js +125 -0
  37. package/dist/ms-BeBSuOXN.js.map +1 -0
  38. package/dist/multipart-parser-CedBDOeC.js +299 -0
  39. package/dist/multipart-parser-CedBDOeC.js.map +1 -0
  40. package/dist/src-COaj0G3P.js +1182 -0
  41. package/dist/src-COaj0G3P.js.map +1 -0
  42. package/dist/{server-core/src/storage → storage}/image-transform.d.ts +3 -1
  43. package/dist/utils/request-id.d.ts +4 -0
  44. package/package.json +29 -29
  45. package/src/api/collections_for_test/callbacks_test_collection.ts +7 -6
  46. package/src/api/errors.ts +75 -19
  47. package/src/api/graphql/graphql-schema-generator.ts +15 -10
  48. package/src/api/logs-routes.ts +5 -2
  49. package/src/api/rest/api-generator-count.test.ts +21 -10
  50. package/src/api/rest/api-generator.ts +102 -26
  51. package/src/api/rest/query-parser.ts +18 -12
  52. package/src/api/server.ts +12 -1
  53. package/src/api/types.ts +2 -0
  54. package/src/auth/adapter-middleware.ts +17 -10
  55. package/src/auth/admin-user-ops.ts +236 -0
  56. package/src/auth/api-keys/api-key-middleware.ts +15 -9
  57. package/src/auth/api-keys/api-key-permission-guard.ts +1 -1
  58. package/src/auth/api-keys/api-key-routes.ts +3 -3
  59. package/src/auth/api-keys/api-key-store.ts +14 -8
  60. package/src/auth/api-keys/index.ts +2 -2
  61. package/src/auth/apple-oauth.ts +4 -3
  62. package/src/auth/auth-hooks.ts +50 -10
  63. package/src/auth/bitbucket-oauth.ts +5 -4
  64. package/src/auth/builtin-auth-adapter.ts +60 -39
  65. package/src/auth/custom-auth-adapter.ts +4 -5
  66. package/src/auth/discord-oauth.ts +5 -4
  67. package/src/auth/facebook-oauth.ts +5 -4
  68. package/src/auth/github-oauth.ts +6 -5
  69. package/src/auth/gitlab-oauth.ts +5 -4
  70. package/src/auth/google-oauth.ts +2 -1
  71. package/src/auth/index.ts +6 -2
  72. package/src/auth/jwt.ts +5 -4
  73. package/src/auth/linkedin-oauth.ts +4 -3
  74. package/src/auth/mfa-routes.ts +299 -0
  75. package/src/auth/mfa.ts +2 -1
  76. package/src/auth/microsoft-oauth.ts +5 -4
  77. package/src/auth/middleware.ts +5 -4
  78. package/src/auth/rate-limiter.ts +1 -1
  79. package/src/auth/reset-password-admin.ts +144 -0
  80. package/src/auth/rls-scope.ts +1 -1
  81. package/src/auth/routes.ts +52 -596
  82. package/src/auth/session-routes.ts +341 -0
  83. package/src/auth/slack-oauth.ts +6 -5
  84. package/src/auth/spotify-oauth.ts +5 -4
  85. package/src/auth/twitter-oauth.ts +4 -3
  86. package/src/collections/loader.ts +5 -4
  87. package/src/cron/cron-scheduler.test.ts +23 -11
  88. package/src/cron/cron-scheduler.ts +14 -8
  89. package/src/cron/cron-store.ts +1 -1
  90. package/src/email/smtp-email-service.ts +3 -2
  91. package/src/env.ts +11 -10
  92. package/src/index.ts +1 -0
  93. package/src/init/docs.ts +47 -0
  94. package/src/init/health.ts +37 -0
  95. package/src/init/middlewares.ts +61 -0
  96. package/src/init/shutdown.ts +56 -0
  97. package/src/init/storage.ts +57 -0
  98. package/src/init.ts +85 -279
  99. package/src/serve-spa.ts +12 -5
  100. package/src/services/driver-registry.ts +4 -3
  101. package/src/storage/S3StorageController.ts +1 -2
  102. package/src/storage/image-transform.ts +25 -10
  103. package/src/storage/routes.ts +34 -11
  104. package/src/storage/storage-registry.ts +4 -3
  105. package/src/storage/tus-handler.ts +12 -12
  106. package/src/utils/request-id.ts +40 -0
  107. package/src/utils/request-logger.ts +6 -0
  108. package/test/api-generator.test.ts +90 -2
  109. package/test/api-key-permission-guard.test.ts +24 -12
  110. package/test/auth-routes.test.ts +5 -3
  111. package/test/backend-hooks-data.test.ts +99 -30
  112. package/test/custom-auth-adapter.test.ts +16 -15
  113. package/test/email-templates.test.ts +10 -5
  114. package/test/env.test.ts +10 -10
  115. package/test/function-loader.test.ts +7 -4
  116. package/test/graphql-schema-generator.test.ts +554 -0
  117. package/test/jwt-security.test.ts +1 -1
  118. package/test/query-parser.test.ts +0 -1
  119. package/test/reset-password-admin.test.ts +113 -0
  120. package/test/singleton.test.ts +5 -5
  121. package/test/smtp-email-service.test.ts +21 -21
  122. package/test/webhook-service.test.ts +22 -11
  123. package/tsconfig.json +2 -0
  124. package/tsconfig.prod.json +3 -0
  125. package/vite.config.ts +10 -5
  126. package/dist/common/src/collections/CollectionRegistry.d.ts +0 -56
  127. package/dist/common/src/collections/default-collections.d.ts +0 -9
  128. package/dist/common/src/collections/index.d.ts +0 -2
  129. package/dist/common/src/data/buildRebaseData.d.ts +0 -14
  130. package/dist/common/src/data/query_builder.d.ts +0 -55
  131. package/dist/common/src/index.d.ts +0 -4
  132. package/dist/common/src/util/builders.d.ts +0 -57
  133. package/dist/common/src/util/callbacks.d.ts +0 -6
  134. package/dist/common/src/util/collections.d.ts +0 -11
  135. package/dist/common/src/util/common.d.ts +0 -2
  136. package/dist/common/src/util/conditions.d.ts +0 -26
  137. package/dist/common/src/util/entities.d.ts +0 -58
  138. package/dist/common/src/util/enums.d.ts +0 -3
  139. package/dist/common/src/util/index.d.ts +0 -16
  140. package/dist/common/src/util/navigation_from_path.d.ts +0 -34
  141. package/dist/common/src/util/navigation_utils.d.ts +0 -20
  142. package/dist/common/src/util/parent_references_from_path.d.ts +0 -6
  143. package/dist/common/src/util/paths.d.ts +0 -14
  144. package/dist/common/src/util/permissions.d.ts +0 -14
  145. package/dist/common/src/util/references.d.ts +0 -2
  146. package/dist/common/src/util/relations.d.ts +0 -22
  147. package/dist/common/src/util/resolutions.d.ts +0 -72
  148. package/dist/common/src/util/storage.d.ts +0 -24
  149. package/dist/index-Cr1D21av.js +0 -49
  150. package/dist/index-Cr1D21av.js.map +0 -1
  151. package/dist/server-core/src/auth/admin-routes.d.ts +0 -27
  152. package/dist/server-core/src/env.d.ts +0 -137
  153. package/dist/types/src/controllers/analytics_controller.d.ts +0 -7
  154. package/dist/types/src/controllers/auth.d.ts +0 -104
  155. package/dist/types/src/controllers/client.d.ts +0 -168
  156. package/dist/types/src/controllers/collection_registry.d.ts +0 -46
  157. package/dist/types/src/controllers/customization_controller.d.ts +0 -60
  158. package/dist/types/src/controllers/data.d.ts +0 -207
  159. package/dist/types/src/controllers/data_driver.d.ts +0 -218
  160. package/dist/types/src/controllers/database_admin.d.ts +0 -11
  161. package/dist/types/src/controllers/dialogs_controller.d.ts +0 -36
  162. package/dist/types/src/controllers/effective_role.d.ts +0 -4
  163. package/dist/types/src/controllers/email.d.ts +0 -36
  164. package/dist/types/src/controllers/index.d.ts +0 -18
  165. package/dist/types/src/controllers/local_config_persistence.d.ts +0 -20
  166. package/dist/types/src/controllers/navigation.d.ts +0 -225
  167. package/dist/types/src/controllers/registry.d.ts +0 -63
  168. package/dist/types/src/controllers/side_dialogs_controller.d.ts +0 -67
  169. package/dist/types/src/controllers/side_entity_controller.d.ts +0 -97
  170. package/dist/types/src/controllers/snackbar.d.ts +0 -24
  171. package/dist/types/src/controllers/storage.d.ts +0 -171
  172. package/dist/types/src/index.d.ts +0 -4
  173. package/dist/types/src/rebase_context.d.ts +0 -122
  174. package/dist/types/src/types/auth_adapter.d.ts +0 -301
  175. package/dist/types/src/types/backend.d.ts +0 -571
  176. package/dist/types/src/types/backend_hooks.d.ts +0 -172
  177. package/dist/types/src/types/builders.d.ts +0 -15
  178. package/dist/types/src/types/chips.d.ts +0 -5
  179. package/dist/types/src/types/collections.d.ts +0 -961
  180. package/dist/types/src/types/component_ref.d.ts +0 -47
  181. package/dist/types/src/types/cron.d.ts +0 -102
  182. package/dist/types/src/types/data_source.d.ts +0 -64
  183. package/dist/types/src/types/database_adapter.d.ts +0 -94
  184. package/dist/types/src/types/entities.d.ts +0 -145
  185. package/dist/types/src/types/entity_actions.d.ts +0 -104
  186. package/dist/types/src/types/entity_callbacks.d.ts +0 -173
  187. package/dist/types/src/types/entity_link_builder.d.ts +0 -7
  188. package/dist/types/src/types/entity_overrides.d.ts +0 -10
  189. package/dist/types/src/types/entity_views.d.ts +0 -87
  190. package/dist/types/src/types/export_import.d.ts +0 -21
  191. package/dist/types/src/types/formex.d.ts +0 -40
  192. package/dist/types/src/types/index.d.ts +0 -28
  193. package/dist/types/src/types/locales.d.ts +0 -4
  194. package/dist/types/src/types/modify_collections.d.ts +0 -5
  195. package/dist/types/src/types/plugins.d.ts +0 -282
  196. package/dist/types/src/types/properties.d.ts +0 -1173
  197. package/dist/types/src/types/property_config.d.ts +0 -74
  198. package/dist/types/src/types/relations.d.ts +0 -336
  199. package/dist/types/src/types/slots.d.ts +0 -262
  200. package/dist/types/src/types/translations.d.ts +0 -900
  201. package/dist/types/src/types/user_management_delegate.d.ts +0 -86
  202. package/dist/types/src/types/websockets.d.ts +0 -78
  203. package/dist/types/src/users/index.d.ts +0 -1
  204. package/dist/types/src/users/user.d.ts +0 -50
  205. package/src/auth/admin-routes.ts +0 -534
  206. package/test/admin-routes.test.ts +0 -544
  207. package/test/backend-hooks-admin.test.ts +0 -388
  208. /package/dist/{server-core/src/api → api}/ast-schema-editor.d.ts +0 -0
  209. /package/dist/{server-core/src/api → api}/collections_for_test/callbacks_test_collection.d.ts +0 -0
  210. /package/dist/{server-core/src/api → api}/graphql/graphql-schema-generator.d.ts +0 -0
  211. /package/dist/{server-core/src/api → api}/graphql/index.d.ts +0 -0
  212. /package/dist/{server-core/src/api → api}/index.d.ts +0 -0
  213. /package/dist/{server-core/src/api → api}/logs-routes.d.ts +0 -0
  214. /package/dist/{server-core/src/api → api}/openapi-generator.d.ts +0 -0
  215. /package/dist/{server-core/src/api → api}/rest/index.d.ts +0 -0
  216. /package/dist/{server-core/src/api → api}/rest/query-parser.d.ts +0 -0
  217. /package/dist/{server-core/src/api → api}/schema-editor-routes.d.ts +0 -0
  218. /package/dist/{server-core/src/api → api}/server.d.ts +0 -0
  219. /package/dist/{server-core/src/auth → auth}/adapter-middleware.d.ts +0 -0
  220. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-middleware.d.ts +0 -0
  221. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-permission-guard.d.ts +0 -0
  222. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-routes.d.ts +0 -0
  223. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-store.d.ts +0 -0
  224. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-types.d.ts +0 -0
  225. /package/dist/{server-core/src/auth → auth}/apple-oauth.d.ts +0 -0
  226. /package/dist/{server-core/src/auth → auth}/bitbucket-oauth.d.ts +0 -0
  227. /package/dist/{server-core/src/auth → auth}/crypto-utils.d.ts +0 -0
  228. /package/dist/{server-core/src/auth → auth}/custom-auth-adapter.d.ts +0 -0
  229. /package/dist/{server-core/src/auth → auth}/discord-oauth.d.ts +0 -0
  230. /package/dist/{server-core/src/auth → auth}/facebook-oauth.d.ts +0 -0
  231. /package/dist/{server-core/src/auth → auth}/github-oauth.d.ts +0 -0
  232. /package/dist/{server-core/src/auth → auth}/gitlab-oauth.d.ts +0 -0
  233. /package/dist/{server-core/src/auth → auth}/google-oauth.d.ts +0 -0
  234. /package/dist/{server-core/src/auth → auth}/interfaces.d.ts +0 -0
  235. /package/dist/{server-core/src/auth → auth}/jwt.d.ts +0 -0
  236. /package/dist/{server-core/src/auth → auth}/linkedin-oauth.d.ts +0 -0
  237. /package/dist/{server-core/src/auth → auth}/mfa.d.ts +0 -0
  238. /package/dist/{server-core/src/auth → auth}/microsoft-oauth.d.ts +0 -0
  239. /package/dist/{server-core/src/auth → auth}/middleware.d.ts +0 -0
  240. /package/dist/{server-core/src/auth → auth}/password.d.ts +0 -0
  241. /package/dist/{server-core/src/auth → auth}/rate-limiter.d.ts +0 -0
  242. /package/dist/{server-core/src/auth → auth}/rls-scope.d.ts +0 -0
  243. /package/dist/{server-core/src/auth → auth}/routes.d.ts +0 -0
  244. /package/dist/{server-core/src/auth → auth}/slack-oauth.d.ts +0 -0
  245. /package/dist/{server-core/src/auth → auth}/spotify-oauth.d.ts +0 -0
  246. /package/dist/{server-core/src/auth → auth}/twitter-oauth.d.ts +0 -0
  247. /package/dist/{server-core/src/collections → collections}/BackendCollectionRegistry.d.ts +0 -0
  248. /package/dist/{server-core/src/collections → collections}/loader.d.ts +0 -0
  249. /package/dist/{server-core/src/cron → cron}/cron-loader.d.ts +0 -0
  250. /package/dist/{server-core/src/cron → cron}/cron-routes.d.ts +0 -0
  251. /package/dist/{server-core/src/cron → cron}/cron-store.d.ts +0 -0
  252. /package/dist/{server-core/src/cron → cron}/index.d.ts +0 -0
  253. /package/dist/{server-core/src/db → db}/interfaces.d.ts +0 -0
  254. /package/dist/{server-core/src/email → email}/index.d.ts +0 -0
  255. /package/dist/{server-core/src/email → email}/smtp-email-service.d.ts +0 -0
  256. /package/dist/{server-core/src/email → email}/templates.d.ts +0 -0
  257. /package/dist/{server-core/src/email → email}/types.d.ts +0 -0
  258. /package/dist/{server-core/src/functions → functions}/function-loader.d.ts +0 -0
  259. /package/dist/{server-core/src/functions → functions}/function-routes.d.ts +0 -0
  260. /package/dist/{server-core/src/functions → functions}/index.d.ts +0 -0
  261. /package/dist/{server-core/src/history → history}/history-routes.d.ts +0 -0
  262. /package/dist/{server-core/src/history → history}/index.d.ts +0 -0
  263. /package/dist/{server-core/src/serve-spa.d.ts → serve-spa.d.ts} +0 -0
  264. /package/dist/{server-core/src/services → services}/driver-registry.d.ts +0 -0
  265. /package/dist/{server-core/src/services → services}/webhook-service.d.ts +0 -0
  266. /package/dist/{server-core/src/singleton.d.ts → singleton.d.ts} +0 -0
  267. /package/dist/{server-core/src/storage → storage}/LocalStorageController.d.ts +0 -0
  268. /package/dist/{server-core/src/storage → storage}/S3StorageController.d.ts +0 -0
  269. /package/dist/{server-core/src/storage → storage}/index.d.ts +0 -0
  270. /package/dist/{server-core/src/storage → storage}/routes.d.ts +0 -0
  271. /package/dist/{server-core/src/storage → storage}/storage-registry.d.ts +0 -0
  272. /package/dist/{server-core/src/storage → storage}/tus-handler.d.ts +0 -0
  273. /package/dist/{server-core/src/storage → storage}/types.d.ts +0 -0
  274. /package/dist/{server-core/src/types → types}/index.d.ts +0 -0
  275. /package/dist/{server-core/src/utils → utils}/dev-port.d.ts +0 -0
  276. /package/dist/{server-core/src/utils → utils}/logger.d.ts +0 -0
  277. /package/dist/{server-core/src/utils → utils}/logging.d.ts +0 -0
  278. /package/dist/{server-core/src/utils → utils}/request-logger.d.ts +0 -0
  279. /package/dist/{server-core/src/utils → utils}/sql.d.ts +0 -0
@@ -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
 
@@ -123,8 +124,8 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
123
124
  let roles: string[] = payload.roles || [];
124
125
  try {
125
126
  roles = await authRepository.getUserRoleIds(payload.userId);
126
- } catch {
127
- // 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 });
128
129
  }
129
130
 
130
131
  const isAdmin = roles.some((r) => r === "admin" || r === "schema-admin");
@@ -135,7 +136,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
135
136
  displayName: payload.displayName ?? null,
136
137
  roles,
137
138
  isAdmin,
138
- rawToken: token,
139
+ rawToken: token
139
140
  };
140
141
  },
141
142
 
@@ -147,7 +148,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
147
148
  email: "service@rebase.internal",
148
149
  roles: ["admin"],
149
150
  isAdmin: true,
150
- rawToken: token,
151
+ rawToken: token
151
152
  };
152
153
  }
153
154
 
@@ -160,8 +161,8 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
160
161
  let roles: string[] = payload.roles || [];
161
162
  try {
162
163
  roles = await authRepository.getUserRoleIds(payload.userId);
163
- } catch {
164
- // 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 });
165
166
  }
166
167
 
167
168
  const isAdmin = roles.some((r) => r === "admin" || r === "schema-admin");
@@ -172,12 +173,11 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
172
173
  displayName: payload.displayName ?? null,
173
174
  roles,
174
175
  isAdmin,
175
- rawToken: token,
176
+ rawToken: token
176
177
  };
177
178
  },
178
179
 
179
- userManagement: createUserManagementFromRepo(authRepository, resolvedOps, authHooks),
180
-
180
+ userManagement: createUserManagementFromRepo(authRepository, resolvedOps),
181
181
 
182
182
 
183
183
  createAuthRoutes(): Hono<HonoEnv> | undefined {
@@ -188,18 +188,39 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
188
188
  allowRegistration,
189
189
  defaultRole,
190
190
  oauthProviders,
191
- authHooks,
191
+ authHooks
192
192
  });
193
193
  },
194
194
 
195
195
  createAdminRoutes(): Hono<HonoEnv> | undefined {
196
- return createAdminRoutes({
196
+ return createResetPasswordRoute({
197
197
  authRepo: authRepository,
198
198
  emailService,
199
199
  emailConfig,
200
200
  serviceKey,
201
- hooks,
202
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
203
224
  });
204
225
  },
205
226
 
@@ -225,9 +246,9 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
225
246
  profileUpdate: true,
226
247
  emailVerification: !!emailService?.isConfigured(),
227
248
  enabledProviders,
228
- needsSetup,
249
+ needsSetup
229
250
  };
230
- },
251
+ }
231
252
  };
232
253
 
233
254
  return adapter;
@@ -235,7 +256,7 @@ export function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): Auth
235
256
 
236
257
  // ─── Internal Helpers ────────────────────────────────────────────────────────
237
258
 
238
- function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: ResolvedAuthOperations, authHooks?: AuthHooks): UserManagementAdapter {
259
+ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: ResolvedAuthHooks): UserManagementAdapter {
239
260
  return {
240
261
  async listUsers(options?: AuthUserListOptions): Promise<AuthUserListResult> {
241
262
  const result = await repo.listUsersPaginated({
@@ -244,13 +265,13 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
244
265
  search: options?.search,
245
266
  orderBy: options?.orderBy,
246
267
  orderDir: options?.orderDir,
247
- roleId: options?.roleId,
268
+ roleId: options?.roleId
248
269
  });
249
270
  return {
250
271
  users: result.users.map(toAuthUserData),
251
272
  total: result.total,
252
273
  limit: result.limit,
253
- offset: result.offset,
274
+ offset: result.offset
254
275
  };
255
276
  },
256
277
 
@@ -266,17 +287,17 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
266
287
  passwordHash,
267
288
  displayName: data.displayName,
268
289
  photoUrl: data.photoUrl,
269
- metadata: data.metadata,
290
+ metadata: data.metadata
270
291
  };
271
- if (authHooks?.beforeUserCreate) {
272
- createData = await authHooks.beforeUserCreate(createData);
292
+ if (resolvedOps.beforeUserCreate) {
293
+ createData = await resolvedOps.beforeUserCreate(createData);
273
294
  }
274
295
  const user = await repo.createUser(createData);
275
- if (authHooks?.afterUserCreate) {
296
+ if (resolvedOps.afterUserCreate) {
276
297
  try {
277
- await authHooks.afterUserCreate(user);
298
+ await resolvedOps.afterUserCreate(user);
278
299
  } catch (err) {
279
- console.error("[AuthHooks] afterUserCreate error:", err instanceof Error ? err.message : err);
300
+ logger.error("[AuthHooks] afterUserCreate error", { error: err instanceof Error ? err.message : err });
280
301
  }
281
302
  }
282
303
  return toAuthUserData(user);
@@ -297,16 +318,16 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
297
318
 
298
319
  async deleteUser(id: string): Promise<void> {
299
320
  // Call beforeUserDelete hook (throw to prevent deletion)
300
- if (authHooks?.beforeUserDelete) {
301
- await authHooks.beforeUserDelete(id);
321
+ if (resolvedOps.beforeUserDelete) {
322
+ await resolvedOps.beforeUserDelete(id);
302
323
  }
303
324
 
304
325
  await repo.deleteUser(id);
305
326
 
306
327
  // Fire afterUserDelete hook (fire-and-forget)
307
- if (authHooks?.afterUserDelete) {
308
- authHooks.afterUserDelete(id).catch(err => {
309
- 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 });
310
331
  });
311
332
  }
312
333
  },
@@ -317,7 +338,7 @@ function createUserManagementFromRepo(repo: AuthRepository, resolvedOps: Resolve
317
338
 
318
339
  async setUserRoles(userId: string, roleIds: string[]): Promise<void> {
319
340
  await repo.setUserRoles(userId, roleIds);
320
- },
341
+ }
321
342
  };
322
343
  }
323
344
 
@@ -330,6 +351,6 @@ function toAuthUserData(user: { id: string; email: string; displayName?: string
330
351
  emailVerified: user.emailVerified,
331
352
  metadata: user.metadata,
332
353
  createdAt: user.createdAt,
333
- updatedAt: user.updatedAt,
354
+ updatedAt: user.updatedAt
334
355
  };
335
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
  }
package/src/auth/index.ts CHANGED
@@ -7,9 +7,12 @@ export type { JwtConfig, AccessTokenPayload } from "./jwt";
7
7
  export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
8
8
  export type { PasswordValidationResult } from "./password";
9
9
 
10
- export type { AuthHooks, AuthMethod, ResolvedAuthOperations } from "./auth-hooks";
10
+ export type { AuthHooks, AuthMethod, ResolvedAuthHooks } from "./auth-hooks";
11
11
  export { resolveAuthHooks } from "./auth-hooks";
12
12
 
13
+ export { generateSecurePassword, generateSecureToken, hashToken, prepareAdminUserValues, finalizeAdminUserCreation } from "./admin-user-ops";
14
+ export type { AdminUserContext, AdminUserPrepareResult } from "./admin-user-ops";
15
+
13
16
  // OAuth Providers
14
17
  export { createGoogleProvider } from "./google-oauth";
15
18
  export type { GoogleProviderConfig } from "./google-oauth";
@@ -32,7 +35,8 @@ export type { AuthMiddlewareOptions, AuthResult } from "./middleware";
32
35
  export { createAuthRoutes } from "./routes";
33
36
  export type { AuthModuleConfig } from "./routes";
34
37
 
35
- export { createAdminRoutes } from "./admin-routes";
38
+ export { createResetPasswordRoute } from "./reset-password-admin";
39
+ export type { ResetPasswordRouteConfig } from "./reset-password-admin";
36
40
 
37
41
 
38
42
  export { createRateLimiter, defaultAuthLimiter, strictAuthLimiter, createApiKeyRateLimiter, apiKeyKeyGenerator } from "./rate-limiter";
package/src/auth/jwt.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import jwt from "jsonwebtoken";
2
2
  import { createHash, randomBytes } from "crypto";
3
+ import { logger } from "../utils/logger";
3
4
 
4
5
  export interface JwtConfig {
5
6
  secret: string;
@@ -62,14 +63,14 @@ export function configureJwt(config: JwtConfig): void {
62
63
  if (!config.secret || config.secret.length < 32) {
63
64
  throw new Error(
64
65
  "JWT secret is too short. Must be at least 32 characters. " +
65
- "Generate one with: node -e \"console.log(require('crypto').randomBytes(48).toString('base64'))\""
66
+ "Generate one with: node -e \"logger.info(require('crypto').randomBytes(48).toString('base64'))\""
66
67
  );
67
68
  }
68
69
 
69
70
  if (weakSecrets.has(config.secret.toLowerCase())) {
70
71
  throw new Error(
71
72
  "JWT secret is a known default/weak value. Please use a strong, randomly generated secret. " +
72
- "Generate one with: node -e \"console.log(require('crypto').randomBytes(48).toString('base64'))\""
73
+ "Generate one with: node -e \"logger.info(require('crypto').randomBytes(48).toString('base64'))\""
73
74
  );
74
75
  }
75
76
 
@@ -148,7 +149,7 @@ export function verifyAccessToken(token: string): AccessTokenPayload | null {
148
149
  const decoded = jwt.verify(token, jwtConfig.secret, { algorithms: ["HS256"] }) as { userId?: string; uid?: string; sub?: string; roles?: string[]; aal?: string };
149
150
  const id = decoded.userId || decoded.uid || decoded.sub;
150
151
  if (!id) {
151
- console.error("[JWT] Verification failed: missing id in payload", decoded);
152
+ logger.error("[JWT] Verification failed: missing id in payload", { detail: decoded });
152
153
  return null;
153
154
  }
154
155
 
@@ -160,7 +161,7 @@ export function verifyAccessToken(token: string): AccessTokenPayload | null {
160
161
  aal
161
162
  };
162
163
  } catch (error) {
163
- console.error("[JWT] Verification failed:", error, "Token start:", token.substring(0, 15));
164
+ logger.error("[JWT] Verification failed", { error: error, detail: token.substring(0, 15) });
164
165
  return null;
165
166
  }
166
167
  }
@@ -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
  export interface LinkedinUserInfo {
5
6
  linkedinId: string;
@@ -38,7 +39,7 @@ export function createLinkedinProvider(config: { clientId: string, clientSecret:
38
39
 
39
40
  if (!tokenResponse.ok) {
40
41
  const errBody = await tokenResponse.text();
41
- console.error("Failed to get LinkedIn access token:", errBody);
42
+ logger.error("Failed to get LinkedIn access token", { detail: errBody });
42
43
  return null;
43
44
  }
44
45
 
@@ -54,7 +55,7 @@ export function createLinkedinProvider(config: { clientId: string, clientSecret:
54
55
 
55
56
  if (!profileResponse.ok) {
56
57
  const errBody = await profileResponse.text();
57
- console.error("Failed to get LinkedIn user info:", errBody);
58
+ logger.error("Failed to get LinkedIn user info", { detail: errBody });
58
59
  return null;
59
60
  }
60
61
 
@@ -73,7 +74,7 @@ export function createLinkedinProvider(config: { clientId: string, clientSecret:
73
74
  photoUrl: profileData.picture || null
74
75
  };
75
76
  } catch (error) {
76
- console.error("LinkedIn OAuth error:", error);
77
+ logger.error("LinkedIn OAuth error", { error: error });
77
78
  return null;
78
79
  }
79
80
  }