@rebasepro/server-mongodb 0.0.1-canary.09e5ec5

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 (286) hide show
  1. package/LICENSE +6 -0
  2. package/dist/ensure-collections-CNrcwVgY.js +74 -0
  3. package/dist/ensure-collections-CNrcwVgY.js.map +1 -0
  4. package/dist/ensure-history-collection-DBIiwmCm.js +15 -0
  5. package/dist/ensure-history-collection-DBIiwmCm.js.map +1 -0
  6. package/dist/index.es.js +1734 -0
  7. package/dist/index.es.js.map +1 -0
  8. package/dist/index.umd.js +2043 -0
  9. package/dist/index.umd.js.map +1 -0
  10. package/dist/server-core/src/api/ast-schema-editor.d.ts +22 -0
  11. package/dist/server-core/src/api/ast-schema-editor.d.ts.map +1 -0
  12. package/dist/server-core/src/api/errors.d.ts +36 -0
  13. package/dist/server-core/src/api/errors.d.ts.map +1 -0
  14. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +36 -0
  15. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts.map +1 -0
  16. package/dist/server-core/src/api/graphql/index.d.ts +2 -0
  17. package/dist/server-core/src/api/graphql/index.d.ts.map +1 -0
  18. package/dist/server-core/src/api/index.d.ts +10 -0
  19. package/dist/server-core/src/api/index.d.ts.map +1 -0
  20. package/dist/server-core/src/api/openapi-generator.d.ts +17 -0
  21. package/dist/server-core/src/api/openapi-generator.d.ts.map +1 -0
  22. package/dist/server-core/src/api/rest/api-generator.d.ts +65 -0
  23. package/dist/server-core/src/api/rest/api-generator.d.ts.map +1 -0
  24. package/dist/server-core/src/api/rest/index.d.ts +2 -0
  25. package/dist/server-core/src/api/rest/index.d.ts.map +1 -0
  26. package/dist/server-core/src/api/rest/query-parser.d.ts +10 -0
  27. package/dist/server-core/src/api/rest/query-parser.d.ts.map +1 -0
  28. package/dist/server-core/src/api/schema-editor-routes.d.ts +4 -0
  29. package/dist/server-core/src/api/schema-editor-routes.d.ts.map +1 -0
  30. package/dist/server-core/src/api/server.d.ts +41 -0
  31. package/dist/server-core/src/api/server.d.ts.map +1 -0
  32. package/dist/server-core/src/api/types.d.ts +91 -0
  33. package/dist/server-core/src/api/types.d.ts.map +1 -0
  34. package/dist/server-core/src/auth/admin-routes.d.ts +17 -0
  35. package/dist/server-core/src/auth/admin-routes.d.ts.map +1 -0
  36. package/dist/server-core/src/auth/apple-oauth.d.ts +31 -0
  37. package/dist/server-core/src/auth/apple-oauth.d.ts.map +1 -0
  38. package/dist/server-core/src/auth/bitbucket-oauth.d.ts +12 -0
  39. package/dist/server-core/src/auth/bitbucket-oauth.d.ts.map +1 -0
  40. package/dist/server-core/src/auth/discord-oauth.d.ts +15 -0
  41. package/dist/server-core/src/auth/discord-oauth.d.ts.map +1 -0
  42. package/dist/server-core/src/auth/facebook-oauth.d.ts +15 -0
  43. package/dist/server-core/src/auth/facebook-oauth.d.ts.map +1 -0
  44. package/dist/server-core/src/auth/github-oauth.d.ts +16 -0
  45. package/dist/server-core/src/auth/github-oauth.d.ts.map +1 -0
  46. package/dist/server-core/src/auth/gitlab-oauth.d.ts +14 -0
  47. package/dist/server-core/src/auth/gitlab-oauth.d.ts.map +1 -0
  48. package/dist/server-core/src/auth/google-oauth.d.ts +15 -0
  49. package/dist/server-core/src/auth/google-oauth.d.ts.map +1 -0
  50. package/dist/server-core/src/auth/index.d.ts +24 -0
  51. package/dist/server-core/src/auth/index.d.ts.map +1 -0
  52. package/dist/server-core/src/auth/interfaces.d.ts +310 -0
  53. package/dist/server-core/src/auth/interfaces.d.ts.map +1 -0
  54. package/dist/server-core/src/auth/jwt.d.ts +44 -0
  55. package/dist/server-core/src/auth/jwt.d.ts.map +1 -0
  56. package/dist/server-core/src/auth/linkedin-oauth.d.ts +19 -0
  57. package/dist/server-core/src/auth/linkedin-oauth.d.ts.map +1 -0
  58. package/dist/server-core/src/auth/microsoft-oauth.d.ts +17 -0
  59. package/dist/server-core/src/auth/microsoft-oauth.d.ts.map +1 -0
  60. package/dist/server-core/src/auth/middleware.d.ts +82 -0
  61. package/dist/server-core/src/auth/middleware.d.ts.map +1 -0
  62. package/dist/server-core/src/auth/password.d.ts +23 -0
  63. package/dist/server-core/src/auth/password.d.ts.map +1 -0
  64. package/dist/server-core/src/auth/rate-limiter.d.ts +32 -0
  65. package/dist/server-core/src/auth/rate-limiter.d.ts.map +1 -0
  66. package/dist/server-core/src/auth/routes.d.ts +28 -0
  67. package/dist/server-core/src/auth/routes.d.ts.map +1 -0
  68. package/dist/server-core/src/auth/slack-oauth.d.ts +13 -0
  69. package/dist/server-core/src/auth/slack-oauth.d.ts.map +1 -0
  70. package/dist/server-core/src/auth/spotify-oauth.d.ts +13 -0
  71. package/dist/server-core/src/auth/spotify-oauth.d.ts.map +1 -0
  72. package/dist/server-core/src/auth/twitter-oauth.d.ts +19 -0
  73. package/dist/server-core/src/auth/twitter-oauth.d.ts.map +1 -0
  74. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +14 -0
  75. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts.map +1 -0
  76. package/dist/server-core/src/collections/loader.d.ts +6 -0
  77. package/dist/server-core/src/collections/loader.d.ts.map +1 -0
  78. package/dist/server-core/src/cron/cron-loader.d.ts +18 -0
  79. package/dist/server-core/src/cron/cron-loader.d.ts.map +1 -0
  80. package/dist/server-core/src/cron/cron-routes.d.ts +15 -0
  81. package/dist/server-core/src/cron/cron-routes.d.ts.map +1 -0
  82. package/dist/server-core/src/cron/cron-scheduler.d.ts +62 -0
  83. package/dist/server-core/src/cron/cron-scheduler.d.ts.map +1 -0
  84. package/dist/server-core/src/cron/cron-store.d.ts +33 -0
  85. package/dist/server-core/src/cron/cron-store.d.ts.map +1 -0
  86. package/dist/server-core/src/cron/index.d.ts +7 -0
  87. package/dist/server-core/src/cron/index.d.ts.map +1 -0
  88. package/dist/server-core/src/db/interfaces.d.ts +19 -0
  89. package/dist/server-core/src/db/interfaces.d.ts.map +1 -0
  90. package/dist/server-core/src/email/index.d.ts +7 -0
  91. package/dist/server-core/src/email/index.d.ts.map +1 -0
  92. package/dist/server-core/src/email/smtp-email-service.d.ts +26 -0
  93. package/dist/server-core/src/email/smtp-email-service.d.ts.map +1 -0
  94. package/dist/server-core/src/email/templates.d.ts +43 -0
  95. package/dist/server-core/src/email/templates.d.ts.map +1 -0
  96. package/dist/server-core/src/email/types.d.ts +108 -0
  97. package/dist/server-core/src/email/types.d.ts.map +1 -0
  98. package/dist/server-core/src/functions/function-loader.d.ts +18 -0
  99. package/dist/server-core/src/functions/function-loader.d.ts.map +1 -0
  100. package/dist/server-core/src/functions/function-routes.d.ts +11 -0
  101. package/dist/server-core/src/functions/function-routes.d.ts.map +1 -0
  102. package/dist/server-core/src/functions/index.d.ts +4 -0
  103. package/dist/server-core/src/functions/index.d.ts.map +1 -0
  104. package/dist/server-core/src/history/history-routes.d.ts +24 -0
  105. package/dist/server-core/src/history/history-routes.d.ts.map +1 -0
  106. package/dist/server-core/src/history/index.d.ts +2 -0
  107. package/dist/server-core/src/history/index.d.ts.map +1 -0
  108. package/dist/server-core/src/index.d.ts +30 -0
  109. package/dist/server-core/src/index.d.ts.map +1 -0
  110. package/dist/server-core/src/init.d.ts +160 -0
  111. package/dist/server-core/src/init.d.ts.map +1 -0
  112. package/dist/server-core/src/serve-spa.d.ts +31 -0
  113. package/dist/server-core/src/serve-spa.d.ts.map +1 -0
  114. package/dist/server-core/src/services/driver-registry.d.ts +79 -0
  115. package/dist/server-core/src/services/driver-registry.d.ts.map +1 -0
  116. package/dist/server-core/src/singleton.d.ts +36 -0
  117. package/dist/server-core/src/singleton.d.ts.map +1 -0
  118. package/dist/server-core/src/storage/LocalStorageController.d.ts +47 -0
  119. package/dist/server-core/src/storage/LocalStorageController.d.ts.map +1 -0
  120. package/dist/server-core/src/storage/S3StorageController.d.ts +37 -0
  121. package/dist/server-core/src/storage/S3StorageController.d.ts.map +1 -0
  122. package/dist/server-core/src/storage/index.d.ts +26 -0
  123. package/dist/server-core/src/storage/index.d.ts.map +1 -0
  124. package/dist/server-core/src/storage/routes.d.ts +39 -0
  125. package/dist/server-core/src/storage/routes.d.ts.map +1 -0
  126. package/dist/server-core/src/storage/storage-registry.d.ts +79 -0
  127. package/dist/server-core/src/storage/storage-registry.d.ts.map +1 -0
  128. package/dist/server-core/src/storage/types.d.ts +104 -0
  129. package/dist/server-core/src/storage/types.d.ts.map +1 -0
  130. package/dist/server-core/src/types/index.d.ts +12 -0
  131. package/dist/server-core/src/types/index.d.ts.map +1 -0
  132. package/dist/server-core/src/utils/dev-port.d.ts +36 -0
  133. package/dist/server-core/src/utils/dev-port.d.ts.map +1 -0
  134. package/dist/server-core/src/utils/logger.d.ts +32 -0
  135. package/dist/server-core/src/utils/logger.d.ts.map +1 -0
  136. package/dist/server-core/src/utils/logging.d.ts +10 -0
  137. package/dist/server-core/src/utils/logging.d.ts.map +1 -0
  138. package/dist/server-core/src/utils/request-logger.d.ts +20 -0
  139. package/dist/server-core/src/utils/request-logger.d.ts.map +1 -0
  140. package/dist/server-core/src/utils/sql.d.ts +28 -0
  141. package/dist/server-core/src/utils/sql.d.ts.map +1 -0
  142. package/dist/server-mongodb/src/MongoBootstrapper.d.ts +18 -0
  143. package/dist/server-mongodb/src/MongoBootstrapper.d.ts.map +1 -0
  144. package/dist/server-mongodb/src/auth/ensure-collections.d.ts +3 -0
  145. package/dist/server-mongodb/src/auth/ensure-collections.d.ts.map +1 -0
  146. package/dist/server-mongodb/src/auth/services.d.ts +135 -0
  147. package/dist/server-mongodb/src/auth/services.d.ts.map +1 -0
  148. package/dist/server-mongodb/src/connection.d.ts +35 -0
  149. package/dist/server-mongodb/src/connection.d.ts.map +1 -0
  150. package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts +64 -0
  151. package/dist/server-mongodb/src/db/MongoConditionBuilder.d.ts.map +1 -0
  152. package/dist/server-mongodb/src/db/MongoEntityService.d.ts +98 -0
  153. package/dist/server-mongodb/src/db/MongoEntityService.d.ts.map +1 -0
  154. package/dist/server-mongodb/src/factory.d.ts +142 -0
  155. package/dist/server-mongodb/src/factory.d.ts.map +1 -0
  156. package/dist/server-mongodb/src/history/ensure-history-collection.d.ts +3 -0
  157. package/dist/server-mongodb/src/history/ensure-history-collection.d.ts.map +1 -0
  158. package/dist/server-mongodb/src/index.d.ts +18 -0
  159. package/dist/server-mongodb/src/index.d.ts.map +1 -0
  160. package/dist/server-mongodb/src/services/MongoDriver.d.ts +83 -0
  161. package/dist/server-mongodb/src/services/MongoDriver.d.ts.map +1 -0
  162. package/dist/server-mongodb/src/services/MongoHistoryService.d.ts +37 -0
  163. package/dist/server-mongodb/src/services/MongoHistoryService.d.ts.map +1 -0
  164. package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts +86 -0
  165. package/dist/server-mongodb/src/services/MongoRealtimeService.d.ts.map +1 -0
  166. package/dist/server-mongodb/src/useMongoDriver.d.ts +18 -0
  167. package/dist/server-mongodb/src/useMongoDriver.d.ts.map +1 -0
  168. package/dist/server-mongodb/src/utils.d.ts +10 -0
  169. package/dist/server-mongodb/src/utils.d.ts.map +1 -0
  170. package/dist/server-mongodb/src/websocket.d.ts +7 -0
  171. package/dist/server-mongodb/src/websocket.d.ts.map +1 -0
  172. package/dist/types/src/controllers/analytics_controller.d.ts +8 -0
  173. package/dist/types/src/controllers/analytics_controller.d.ts.map +1 -0
  174. package/dist/types/src/controllers/auth.d.ts +120 -0
  175. package/dist/types/src/controllers/auth.d.ts.map +1 -0
  176. package/dist/types/src/controllers/client.d.ts +171 -0
  177. package/dist/types/src/controllers/client.d.ts.map +1 -0
  178. package/dist/types/src/controllers/collection_registry.d.ts +46 -0
  179. package/dist/types/src/controllers/collection_registry.d.ts.map +1 -0
  180. package/dist/types/src/controllers/customization_controller.d.ts +61 -0
  181. package/dist/types/src/controllers/customization_controller.d.ts.map +1 -0
  182. package/dist/types/src/controllers/data.d.ts +169 -0
  183. package/dist/types/src/controllers/data.d.ts.map +1 -0
  184. package/dist/types/src/controllers/data_driver.d.ts +161 -0
  185. package/dist/types/src/controllers/data_driver.d.ts.map +1 -0
  186. package/dist/types/src/controllers/database_admin.d.ts +12 -0
  187. package/dist/types/src/controllers/database_admin.d.ts.map +1 -0
  188. package/dist/types/src/controllers/dialogs_controller.d.ts +37 -0
  189. package/dist/types/src/controllers/dialogs_controller.d.ts.map +1 -0
  190. package/dist/types/src/controllers/effective_role.d.ts +5 -0
  191. package/dist/types/src/controllers/effective_role.d.ts.map +1 -0
  192. package/dist/types/src/controllers/email.d.ts +35 -0
  193. package/dist/types/src/controllers/email.d.ts.map +1 -0
  194. package/dist/types/src/controllers/index.d.ts +19 -0
  195. package/dist/types/src/controllers/index.d.ts.map +1 -0
  196. package/dist/types/src/controllers/local_config_persistence.d.ts +21 -0
  197. package/dist/types/src/controllers/local_config_persistence.d.ts.map +1 -0
  198. package/dist/types/src/controllers/navigation.d.ts +214 -0
  199. package/dist/types/src/controllers/navigation.d.ts.map +1 -0
  200. package/dist/types/src/controllers/registry.d.ts +55 -0
  201. package/dist/types/src/controllers/registry.d.ts.map +1 -0
  202. package/dist/types/src/controllers/side_dialogs_controller.d.ts +68 -0
  203. package/dist/types/src/controllers/side_dialogs_controller.d.ts.map +1 -0
  204. package/dist/types/src/controllers/side_entity_controller.d.ts +91 -0
  205. package/dist/types/src/controllers/side_entity_controller.d.ts.map +1 -0
  206. package/dist/types/src/controllers/snackbar.d.ts +25 -0
  207. package/dist/types/src/controllers/snackbar.d.ts.map +1 -0
  208. package/dist/types/src/controllers/storage.d.ts +172 -0
  209. package/dist/types/src/controllers/storage.d.ts.map +1 -0
  210. package/dist/types/src/index.d.ts +5 -0
  211. package/dist/types/src/index.d.ts.map +1 -0
  212. package/dist/types/src/rebase_context.d.ts +106 -0
  213. package/dist/types/src/rebase_context.d.ts.map +1 -0
  214. package/dist/types/src/types/backend.d.ts +537 -0
  215. package/dist/types/src/types/backend.d.ts.map +1 -0
  216. package/dist/types/src/types/builders.d.ts +16 -0
  217. package/dist/types/src/types/builders.d.ts.map +1 -0
  218. package/dist/types/src/types/chips.d.ts +6 -0
  219. package/dist/types/src/types/chips.d.ts.map +1 -0
  220. package/dist/types/src/types/collections.d.ts +857 -0
  221. package/dist/types/src/types/collections.d.ts.map +1 -0
  222. package/dist/types/src/types/cron.d.ts +103 -0
  223. package/dist/types/src/types/cron.d.ts.map +1 -0
  224. package/dist/types/src/types/data_source.d.ts +65 -0
  225. package/dist/types/src/types/data_source.d.ts.map +1 -0
  226. package/dist/types/src/types/entities.d.ts +146 -0
  227. package/dist/types/src/types/entities.d.ts.map +1 -0
  228. package/dist/types/src/types/entity_actions.d.ts +99 -0
  229. package/dist/types/src/types/entity_actions.d.ts.map +1 -0
  230. package/dist/types/src/types/entity_callbacks.d.ts +174 -0
  231. package/dist/types/src/types/entity_callbacks.d.ts.map +1 -0
  232. package/dist/types/src/types/entity_link_builder.d.ts +8 -0
  233. package/dist/types/src/types/entity_link_builder.d.ts.map +1 -0
  234. package/dist/types/src/types/entity_overrides.d.ts +11 -0
  235. package/dist/types/src/types/entity_overrides.d.ts.map +1 -0
  236. package/dist/types/src/types/entity_views.d.ts +62 -0
  237. package/dist/types/src/types/entity_views.d.ts.map +1 -0
  238. package/dist/types/src/types/export_import.d.ts +22 -0
  239. package/dist/types/src/types/export_import.d.ts.map +1 -0
  240. package/dist/types/src/types/index.d.ts +24 -0
  241. package/dist/types/src/types/index.d.ts.map +1 -0
  242. package/dist/types/src/types/locales.d.ts +5 -0
  243. package/dist/types/src/types/locales.d.ts.map +1 -0
  244. package/dist/types/src/types/modify_collections.d.ts +6 -0
  245. package/dist/types/src/types/modify_collections.d.ts.map +1 -0
  246. package/dist/types/src/types/plugins.d.ts +280 -0
  247. package/dist/types/src/types/plugins.d.ts.map +1 -0
  248. package/dist/types/src/types/properties.d.ts +1177 -0
  249. package/dist/types/src/types/properties.d.ts.map +1 -0
  250. package/dist/types/src/types/property_config.d.ts +71 -0
  251. package/dist/types/src/types/property_config.d.ts.map +1 -0
  252. package/dist/types/src/types/relations.d.ts +337 -0
  253. package/dist/types/src/types/relations.d.ts.map +1 -0
  254. package/dist/types/src/types/slots.d.ts +253 -0
  255. package/dist/types/src/types/slots.d.ts.map +1 -0
  256. package/dist/types/src/types/translations.d.ts +871 -0
  257. package/dist/types/src/types/translations.d.ts.map +1 -0
  258. package/dist/types/src/types/user_management_delegate.d.ts +122 -0
  259. package/dist/types/src/types/user_management_delegate.d.ts.map +1 -0
  260. package/dist/types/src/types/websockets.d.ts +79 -0
  261. package/dist/types/src/types/websockets.d.ts.map +1 -0
  262. package/dist/types/src/users/index.d.ts +3 -0
  263. package/dist/types/src/users/index.d.ts.map +1 -0
  264. package/dist/types/src/users/roles.d.ts +23 -0
  265. package/dist/types/src/users/roles.d.ts.map +1 -0
  266. package/dist/types/src/users/user.d.ts +47 -0
  267. package/dist/types/src/users/user.d.ts.map +1 -0
  268. package/dist/websocket-BZlPuJrt.js +220 -0
  269. package/dist/websocket-BZlPuJrt.js.map +1 -0
  270. package/package.json +79 -0
  271. package/src/MongoBootstrapper.ts +177 -0
  272. package/src/auth/ensure-collections.ts +94 -0
  273. package/src/auth/services.ts +638 -0
  274. package/src/connection.ts +60 -0
  275. package/src/db/MongoConditionBuilder.ts +181 -0
  276. package/src/db/MongoEntityService.ts +350 -0
  277. package/src/factory.ts +289 -0
  278. package/src/history/ensure-history-collection.ts +19 -0
  279. package/src/index.ts +25 -0
  280. package/src/services/MongoDriver.ts +297 -0
  281. package/src/services/MongoDriver.ts.backup +266 -0
  282. package/src/services/MongoHistoryService.ts +154 -0
  283. package/src/services/MongoRealtimeService.ts +394 -0
  284. package/src/useMongoDriver.ts +519 -0
  285. package/src/utils.ts +28 -0
  286. package/src/websocket.ts +257 -0
@@ -0,0 +1,638 @@
1
+ import { Db, ObjectId } from "mongodb";
2
+
3
+ /** Loose document type that allows string _id values (Rebase convention). */
4
+ export interface MongoDoc { _id?: string; [key: string]: any; }
5
+ import {
6
+ UserRepository,
7
+ RoleRepository,
8
+ TokenRepository,
9
+ AuthRepository,
10
+ UserData,
11
+ CreateUserData,
12
+ RoleData,
13
+ CreateRoleData,
14
+ RefreshTokenInfo,
15
+ PasswordResetTokenInfo,
16
+ UserIdentityData,
17
+ ListUsersOptions,
18
+ PaginatedUsersResult
19
+ // @ts-ignore
20
+ } from "@rebasepro/server-core";
21
+
22
+ export type Role = RoleData;
23
+
24
+ function toUser(doc: any): UserData {
25
+ return {
26
+ id: doc._id || doc.id,
27
+ email: doc.email,
28
+ passwordHash: doc.passwordHash ?? null,
29
+ displayName: doc.displayName ?? null,
30
+ photoUrl: doc.photoUrl ?? null,
31
+ emailVerified: doc.emailVerified ?? false,
32
+ emailVerificationToken: doc.emailVerificationToken ?? null,
33
+ emailVerificationSentAt: doc.emailVerificationSentAt ? new Date(doc.emailVerificationSentAt) : null,
34
+ createdAt: new Date(doc.createdAt),
35
+ updatedAt: new Date(doc.updatedAt)
36
+ };
37
+ }
38
+
39
+ export class MongoUserService implements UserRepository {
40
+ constructor(private db: Db) {}
41
+
42
+ private get collection() {
43
+ return this.db.collection<MongoDoc>("rebase_users");
44
+ }
45
+
46
+ private get identitiesCollection() {
47
+ return this.db.collection<MongoDoc>("rebase_user_identities");
48
+ }
49
+
50
+ private get userRolesCollection() {
51
+ return this.db.collection<MongoDoc>("rebase_user_roles");
52
+ }
53
+
54
+ private get rolesCollection() {
55
+ return this.db.collection<MongoDoc>("rebase_roles");
56
+ }
57
+
58
+ async createUser(data: CreateUserData): Promise<UserData> {
59
+ const id = new ObjectId().toString();
60
+ const now = new Date();
61
+ const doc = {
62
+ _id: id,
63
+ id,
64
+ email: data.email.toLowerCase(),
65
+ passwordHash: data.passwordHash ?? null,
66
+ displayName: data.displayName ?? null,
67
+ photoUrl: data.photoUrl ?? null,
68
+ emailVerified: data.emailVerified ?? false,
69
+ createdAt: now,
70
+ updatedAt: now
71
+ };
72
+ await this.collection.insertOne(doc);
73
+ return toUser(doc);
74
+ }
75
+
76
+ async getUserById(id: string): Promise<UserData | null> {
77
+ const doc = await this.collection.findOne({ id });
78
+ return doc ? toUser(doc) : null;
79
+ }
80
+
81
+ async getUserByEmail(email: string): Promise<UserData | null> {
82
+ const doc = await this.collection.findOne({ email: email.toLowerCase() });
83
+ return doc ? toUser(doc) : null;
84
+ }
85
+
86
+ async getUserByIdentity(provider: string, providerId: string): Promise<UserData | null> {
87
+ const identity = await this.identitiesCollection.findOne({ provider, providerId });
88
+ if (!identity) return null;
89
+ return this.getUserById(identity.userId);
90
+ }
91
+
92
+ async getUserIdentities(userId: string): Promise<UserIdentityData[]> {
93
+ const docs = await this.identitiesCollection.find({ userId }).toArray();
94
+ return docs.map(doc => ({
95
+ id: doc.id,
96
+ userId: doc.userId,
97
+ provider: doc.provider,
98
+ providerId: doc.providerId,
99
+ profileData: doc.profileData ?? null,
100
+ createdAt: new Date(doc.createdAt),
101
+ updatedAt: new Date(doc.updatedAt)
102
+ }));
103
+ }
104
+
105
+ async linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void> {
106
+ const now = new Date();
107
+ await this.identitiesCollection.updateOne(
108
+ { provider, providerId },
109
+ {
110
+ $setOnInsert: {
111
+ _id: new ObjectId().toString(),
112
+ id: new ObjectId().toString(),
113
+ userId,
114
+ provider,
115
+ providerId,
116
+ createdAt: now
117
+ },
118
+ $set: {
119
+ profileData: profileData ?? null,
120
+ updatedAt: now
121
+ }
122
+ },
123
+ { upsert: true }
124
+ );
125
+ }
126
+
127
+ async updateUser(id: string, data: Partial<Omit<CreateUserData, "id">>): Promise<UserData | null> {
128
+ const updateData: Record<string, unknown> = { ...data, updatedAt: new Date() };
129
+ if (typeof updateData.email === "string") updateData.email = updateData.email.toLowerCase();
130
+
131
+ await this.collection.updateOne({ id }, { $set: updateData });
132
+ return this.getUserById(id);
133
+ }
134
+
135
+ async deleteUser(id: string): Promise<void> {
136
+ await this.collection.deleteOne({ id });
137
+ await this.identitiesCollection.deleteMany({ userId: id });
138
+ await this.userRolesCollection.deleteMany({ userId: id });
139
+ }
140
+
141
+ async listUsers(): Promise<UserData[]> {
142
+ const docs = await this.collection.find().toArray();
143
+ return docs.map(toUser);
144
+ }
145
+
146
+ async listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult> {
147
+ const limit = options?.limit ?? 25;
148
+ const offset = options?.offset ?? 0;
149
+ const search = options?.search?.trim() || "";
150
+ const orderBy = options?.orderBy || "createdAt";
151
+ const orderDir = options?.orderDir || "desc";
152
+ const roleId = options?.roleId;
153
+
154
+ const query: Record<string, unknown> = {};
155
+
156
+ if (search) {
157
+ query.$or = [
158
+ { email: { $regex: search, $options: "i" } },
159
+ { displayName: { $regex: search, $options: "i" } }
160
+ ];
161
+ }
162
+
163
+ if (roleId) {
164
+ const userRoles = await this.userRolesCollection.find({ roleId }).toArray();
165
+ const userIds = userRoles.map(ur => ur.userId);
166
+ query.id = { $in: userIds };
167
+ }
168
+
169
+ const sort: Record<string, 1 | -1> = {};
170
+ sort[orderBy] = orderDir === "asc" ? 1 : -1;
171
+
172
+ const total = await this.collection.countDocuments(query);
173
+ const docs = await this.collection.find(query).sort(sort).skip(offset).limit(limit).toArray();
174
+
175
+ return {
176
+ users: docs.map(toUser),
177
+ total,
178
+ limit,
179
+ offset
180
+ };
181
+ }
182
+
183
+ async updatePassword(id: string, passwordHash: string): Promise<void> {
184
+ await this.collection.updateOne(
185
+ { id },
186
+ { $set: { passwordHash, updatedAt: new Date() } }
187
+ );
188
+ }
189
+
190
+ async setEmailVerified(id: string, verified: boolean): Promise<void> {
191
+ await this.collection.updateOne(
192
+ { id },
193
+ { $set: { emailVerified: verified, emailVerificationToken: null, updatedAt: new Date() } }
194
+ );
195
+ }
196
+
197
+ async setVerificationToken(id: string, token: string | null): Promise<void> {
198
+ await this.collection.updateOne(
199
+ { id },
200
+ { $set: { emailVerificationToken: token, emailVerificationSentAt: token ? new Date() : null, updatedAt: new Date() } }
201
+ );
202
+ }
203
+
204
+ async getUserByVerificationToken(token: string): Promise<UserData | null> {
205
+ const doc = await this.collection.findOne({ emailVerificationToken: token });
206
+ return doc ? toUser(doc) : null;
207
+ }
208
+
209
+ async getUserRoles(userId: string): Promise<RoleData[]> {
210
+ const userRoles = await this.userRolesCollection.find({ userId }).toArray();
211
+ const roleIds = userRoles.map(ur => ur.roleId);
212
+ if (roleIds.length === 0) return [];
213
+
214
+ const roles = await this.rolesCollection.find({ id: { $in: roleIds } }).toArray();
215
+ return roles.map(r => ({
216
+ id: r.id,
217
+ name: r.name,
218
+ isAdmin: r.isAdmin ?? false,
219
+ defaultPermissions: r.defaultPermissions ?? null,
220
+ collectionPermissions: r.collectionPermissions ?? null,
221
+ config: r.config ?? null
222
+ }));
223
+ }
224
+
225
+ async getUserRoleIds(userId: string): Promise<string[]> {
226
+ const userRoles = await this.userRolesCollection.find({ userId }).toArray();
227
+ return userRoles.map(ur => ur.roleId);
228
+ }
229
+
230
+ async setUserRoles(userId: string, roleIds: string[]): Promise<void> {
231
+ await this.userRolesCollection.deleteMany({ userId });
232
+ if (roleIds.length > 0) {
233
+ const docs = roleIds.map(roleId => ({
234
+ _id: new ObjectId().toString(),
235
+ userId,
236
+ roleId
237
+ }));
238
+ await this.userRolesCollection.insertMany(docs);
239
+ }
240
+ }
241
+
242
+ async assignDefaultRole(userId: string, roleId: string): Promise<void> {
243
+ await this.userRolesCollection.updateOne(
244
+ { userId, roleId },
245
+ { $setOnInsert: { _id: new ObjectId().toString(), userId, roleId } },
246
+ { upsert: true }
247
+ );
248
+ }
249
+
250
+ async getUserWithRoles(userId: string): Promise<{ user: UserData; roles: RoleData[] } | null> {
251
+ const user = await this.getUserById(userId);
252
+ if (!user) return null;
253
+ const roles = await this.getUserRoles(userId);
254
+ return { user, roles };
255
+ }
256
+ }
257
+
258
+ export class MongoRoleService implements RoleRepository {
259
+ constructor(private db: Db) {}
260
+
261
+ private get collection() {
262
+ return this.db.collection<MongoDoc>("rebase_roles");
263
+ }
264
+
265
+ async getRoleById(id: string): Promise<RoleData | null> {
266
+ const doc = await this.collection.findOne({ id });
267
+ if (!doc) return null;
268
+ return {
269
+ id: doc.id,
270
+ name: doc.name,
271
+ isAdmin: doc.isAdmin ?? false,
272
+ defaultPermissions: doc.defaultPermissions ?? null,
273
+ collectionPermissions: doc.collectionPermissions ?? null,
274
+ config: doc.config ?? null
275
+ };
276
+ }
277
+
278
+ async listRoles(): Promise<RoleData[]> {
279
+ const docs = await this.collection.find().sort({ name: 1 }).toArray();
280
+ return docs.map(doc => ({
281
+ id: doc.id,
282
+ name: doc.name,
283
+ isAdmin: doc.isAdmin ?? false,
284
+ defaultPermissions: doc.defaultPermissions ?? null,
285
+ collectionPermissions: doc.collectionPermissions ?? null,
286
+ config: doc.config ?? null
287
+ }));
288
+ }
289
+
290
+ async createRole(data: CreateRoleData): Promise<RoleData> {
291
+ const doc = {
292
+ _id: data.id,
293
+ id: data.id,
294
+ name: data.name,
295
+ isAdmin: data.isAdmin ?? false,
296
+ defaultPermissions: data.defaultPermissions ?? null,
297
+ collectionPermissions: data.collectionPermissions ?? null,
298
+ config: data.config ?? null
299
+ };
300
+ await this.collection.insertOne(doc);
301
+ return { ...doc } as RoleData;
302
+ }
303
+
304
+ async updateRole(id: string, data: Partial<Omit<RoleData, "id">>): Promise<RoleData | null> {
305
+ await this.collection.updateOne({ id }, { $set: data });
306
+ return this.getRoleById(id);
307
+ }
308
+
309
+ async deleteRole(id: string): Promise<void> {
310
+ await this.collection.deleteOne({ id });
311
+ await this.db.collection("rebase_user_roles").deleteMany({ roleId: id });
312
+ }
313
+ }
314
+
315
+ export class MongoRefreshTokenService {
316
+ constructor(private db: Db) {}
317
+
318
+ private get collection() {
319
+ return this.db.collection<MongoDoc>("rebase_refresh_tokens");
320
+ }
321
+
322
+ async createToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {
323
+ const safeUserAgent = userAgent || "";
324
+ const safeIpAddress = ipAddress || "";
325
+
326
+ await this.collection.deleteMany({
327
+ userId,
328
+ userAgent: safeUserAgent,
329
+ ipAddress: safeIpAddress
330
+ });
331
+
332
+ await this.collection.insertOne({
333
+ _id: new ObjectId().toString(),
334
+ id: new ObjectId().toString(),
335
+ userId,
336
+ tokenHash,
337
+ expiresAt,
338
+ createdAt: new Date(),
339
+ userAgent: safeUserAgent,
340
+ ipAddress: safeIpAddress
341
+ });
342
+ }
343
+
344
+ async findByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {
345
+ const doc = await this.collection.findOne({ tokenHash });
346
+ if (!doc) return null;
347
+ return {
348
+ id: doc.id,
349
+ userId: doc.userId,
350
+ tokenHash: doc.tokenHash,
351
+ expiresAt: new Date(doc.expiresAt),
352
+ createdAt: new Date(doc.createdAt),
353
+ userAgent: doc.userAgent,
354
+ ipAddress: doc.ipAddress
355
+ };
356
+ }
357
+
358
+ async deleteByHash(tokenHash: string): Promise<void> {
359
+ await this.collection.deleteOne({ tokenHash });
360
+ }
361
+
362
+ async deleteAllForUser(userId: string): Promise<void> {
363
+ await this.collection.deleteMany({ userId });
364
+ }
365
+
366
+ async listForUser(userId: string): Promise<RefreshTokenInfo[]> {
367
+ const docs = await this.collection.find({ userId }).sort({ createdAt: 1 }).toArray();
368
+ return docs.map(doc => ({
369
+ id: doc.id,
370
+ userId: doc.userId,
371
+ tokenHash: doc.tokenHash,
372
+ expiresAt: new Date(doc.expiresAt),
373
+ createdAt: new Date(doc.createdAt),
374
+ userAgent: doc.userAgent,
375
+ ipAddress: doc.ipAddress
376
+ }));
377
+ }
378
+
379
+ async deleteById(id: string, userId: string): Promise<void> {
380
+ await this.collection.deleteOne({ id, userId });
381
+ }
382
+ }
383
+
384
+ export class MongoPasswordResetTokenService {
385
+ constructor(private db: Db) {}
386
+
387
+ private get collection() {
388
+ return this.db.collection<MongoDoc>("rebase_password_reset_tokens");
389
+ }
390
+
391
+ async createToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {
392
+ await this.collection.deleteMany({ userId, usedAt: null });
393
+
394
+ await this.collection.insertOne({
395
+ _id: new ObjectId().toString(),
396
+ userId,
397
+ tokenHash,
398
+ expiresAt,
399
+ usedAt: null
400
+ });
401
+ }
402
+
403
+ async findValidByHash(tokenHash: string): Promise<{ userId: string; expiresAt: Date } | null> {
404
+ const doc = await this.collection.findOne({
405
+ tokenHash,
406
+ usedAt: null,
407
+ expiresAt: { $gt: new Date() }
408
+ });
409
+
410
+ if (!doc) return null;
411
+
412
+ return {
413
+ userId: doc.userId,
414
+ expiresAt: new Date(doc.expiresAt)
415
+ };
416
+ }
417
+
418
+ async markAsUsed(tokenHash: string): Promise<void> {
419
+ await this.collection.updateOne(
420
+ { tokenHash },
421
+ { $set: { usedAt: new Date() } }
422
+ );
423
+ }
424
+
425
+ async deleteAllForUser(userId: string): Promise<void> {
426
+ await this.collection.deleteMany({ userId });
427
+ }
428
+
429
+ async deleteExpired(): Promise<void> {
430
+ await this.collection.deleteMany({ expiresAt: { $lt: new Date() } });
431
+ }
432
+ }
433
+
434
+ export class MongoTokenRepository implements TokenRepository {
435
+ private refreshTokenService: MongoRefreshTokenService;
436
+ private passwordResetTokenService: MongoPasswordResetTokenService;
437
+
438
+ constructor(private db: Db) {
439
+ this.refreshTokenService = new MongoRefreshTokenService(db);
440
+ this.passwordResetTokenService = new MongoPasswordResetTokenService(db);
441
+ }
442
+
443
+ async createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {
444
+ await this.refreshTokenService.createToken(userId, tokenHash, expiresAt, userAgent, ipAddress);
445
+ }
446
+
447
+ async findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {
448
+ return this.refreshTokenService.findByHash(tokenHash);
449
+ }
450
+
451
+ async deleteRefreshToken(tokenHash: string): Promise<void> {
452
+ await this.refreshTokenService.deleteByHash(tokenHash);
453
+ }
454
+
455
+ async deleteAllRefreshTokensForUser(userId: string): Promise<void> {
456
+ await this.refreshTokenService.deleteAllForUser(userId);
457
+ }
458
+
459
+ async listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]> {
460
+ return this.refreshTokenService.listForUser(userId);
461
+ }
462
+
463
+ async deleteRefreshTokenById(id: string, userId: string): Promise<void> {
464
+ await this.refreshTokenService.deleteById(id, userId);
465
+ }
466
+
467
+ async createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {
468
+ await this.passwordResetTokenService.createToken(userId, tokenHash, expiresAt);
469
+ }
470
+
471
+ async findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null> {
472
+ return this.passwordResetTokenService.findValidByHash(tokenHash);
473
+ }
474
+
475
+ async markPasswordResetTokenUsed(tokenHash: string): Promise<void> {
476
+ await this.passwordResetTokenService.markAsUsed(tokenHash);
477
+ }
478
+
479
+ async deleteAllPasswordResetTokensForUser(userId: string): Promise<void> {
480
+ await this.passwordResetTokenService.deleteAllForUser(userId);
481
+ }
482
+
483
+ async deleteExpiredTokens(): Promise<void> {
484
+ await this.passwordResetTokenService.deleteExpired();
485
+ }
486
+ }
487
+
488
+ export class MongoAuthRepository implements AuthRepository {
489
+ private userService: MongoUserService;
490
+ private roleService: MongoRoleService;
491
+ private tokenRepository: MongoTokenRepository;
492
+
493
+ constructor(private db: Db) {
494
+ this.userService = new MongoUserService(db);
495
+ this.roleService = new MongoRoleService(db);
496
+ this.tokenRepository = new MongoTokenRepository(db);
497
+ }
498
+
499
+ async createUser(data: CreateUserData): Promise<UserData> {
500
+ return this.userService.createUser(data);
501
+ }
502
+
503
+ async getUserById(id: string): Promise<UserData | null> {
504
+ return this.userService.getUserById(id);
505
+ }
506
+
507
+ async getUserByEmail(email: string): Promise<UserData | null> {
508
+ return this.userService.getUserByEmail(email);
509
+ }
510
+
511
+ async getUserByIdentity(provider: string, providerId: string): Promise<UserData | null> {
512
+ return this.userService.getUserByIdentity(provider, providerId);
513
+ }
514
+
515
+ async getUserIdentities(userId: string): Promise<UserIdentityData[]> {
516
+ return this.userService.getUserIdentities(userId);
517
+ }
518
+
519
+ async linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void> {
520
+ return this.userService.linkUserIdentity(userId, provider, providerId, profileData);
521
+ }
522
+
523
+ async updateUser(id: string, data: Partial<Omit<CreateUserData, "id">>): Promise<UserData | null> {
524
+ return this.userService.updateUser(id, data);
525
+ }
526
+
527
+ async deleteUser(id: string): Promise<void> {
528
+ await this.userService.deleteUser(id);
529
+ }
530
+
531
+ async listUsers(): Promise<UserData[]> {
532
+ return this.userService.listUsers();
533
+ }
534
+
535
+ async listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult> {
536
+ return this.userService.listUsersPaginated(options);
537
+ }
538
+
539
+ async updatePassword(id: string, passwordHash: string): Promise<void> {
540
+ await this.userService.updatePassword(id, passwordHash);
541
+ }
542
+
543
+ async setEmailVerified(id: string, verified: boolean): Promise<void> {
544
+ await this.userService.setEmailVerified(id, verified);
545
+ }
546
+
547
+ async setVerificationToken(id: string, token: string | null): Promise<void> {
548
+ await this.userService.setVerificationToken(id, token);
549
+ }
550
+
551
+ async getUserByVerificationToken(token: string): Promise<UserData | null> {
552
+ return this.userService.getUserByVerificationToken(token);
553
+ }
554
+
555
+ async getUserRoles(userId: string): Promise<RoleData[]> {
556
+ return this.userService.getUserRoles(userId);
557
+ }
558
+
559
+ async getUserRoleIds(userId: string): Promise<string[]> {
560
+ return this.userService.getUserRoleIds(userId);
561
+ }
562
+
563
+ async setUserRoles(userId: string, roleIds: string[]): Promise<void> {
564
+ await this.userService.setUserRoles(userId, roleIds);
565
+ }
566
+
567
+ async assignDefaultRole(userId: string, roleId: string): Promise<void> {
568
+ await this.userService.assignDefaultRole(userId, roleId);
569
+ }
570
+
571
+ async getUserWithRoles(userId: string): Promise<{ user: UserData; roles: RoleData[] } | null> {
572
+ return this.userService.getUserWithRoles(userId);
573
+ }
574
+
575
+ async getRoleById(id: string): Promise<RoleData | null> {
576
+ return this.roleService.getRoleById(id);
577
+ }
578
+
579
+ async listRoles(): Promise<RoleData[]> {
580
+ return this.roleService.listRoles();
581
+ }
582
+
583
+ async createRole(data: CreateRoleData): Promise<RoleData> {
584
+ return this.roleService.createRole(data);
585
+ }
586
+
587
+ async updateRole(id: string, data: Partial<Omit<RoleData, "id">>): Promise<RoleData | null> {
588
+ return this.roleService.updateRole(id, data);
589
+ }
590
+
591
+ async deleteRole(id: string): Promise<void> {
592
+ await this.roleService.deleteRole(id);
593
+ }
594
+
595
+ async createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void> {
596
+ await this.tokenRepository.createRefreshToken(userId, tokenHash, expiresAt, userAgent, ipAddress);
597
+ }
598
+
599
+ async findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null> {
600
+ return this.tokenRepository.findRefreshTokenByHash(tokenHash);
601
+ }
602
+
603
+ async deleteRefreshToken(tokenHash: string): Promise<void> {
604
+ await this.tokenRepository.deleteRefreshToken(tokenHash);
605
+ }
606
+
607
+ async deleteAllRefreshTokensForUser(userId: string): Promise<void> {
608
+ await this.tokenRepository.deleteAllRefreshTokensForUser(userId);
609
+ }
610
+
611
+ async listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]> {
612
+ return this.tokenRepository.listRefreshTokensForUser(userId);
613
+ }
614
+
615
+ async deleteRefreshTokenById(id: string, userId: string): Promise<void> {
616
+ await this.tokenRepository.deleteRefreshTokenById(id, userId);
617
+ }
618
+
619
+ async createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void> {
620
+ await this.tokenRepository.createPasswordResetToken(userId, tokenHash, expiresAt);
621
+ }
622
+
623
+ async findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null> {
624
+ return this.tokenRepository.findValidPasswordResetToken(tokenHash);
625
+ }
626
+
627
+ async markPasswordResetTokenUsed(tokenHash: string): Promise<void> {
628
+ await this.tokenRepository.markPasswordResetTokenUsed(tokenHash);
629
+ }
630
+
631
+ async deleteAllPasswordResetTokensForUser(userId: string): Promise<void> {
632
+ await this.tokenRepository.deleteAllPasswordResetTokensForUser(userId);
633
+ }
634
+
635
+ async deleteExpiredTokens(): Promise<void> {
636
+ await this.tokenRepository.deleteExpiredTokens();
637
+ }
638
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MongoDB Connection
3
+ *
4
+ * Wraps MongoDB connection to implement the DatabaseConnection interface.
5
+ */
6
+
7
+ import { Db, MongoClient } from "mongodb";
8
+ import { DatabaseConnection } from "@rebasepro/types";
9
+
10
+ /**
11
+ * MongoDB database connection wrapper that implements DatabaseConnection interface.
12
+ */
13
+ export class MongoDBConnection implements DatabaseConnection {
14
+ readonly type = "mongodb";
15
+
16
+ constructor(
17
+ public readonly db: Db,
18
+ public readonly client: MongoClient
19
+ ) { }
20
+
21
+ get isConnected(): boolean {
22
+ // MongoClient doesn't have a direct isConnected property in v6+
23
+ // We check if the client topology is connected
24
+ try {
25
+ const clientInternal = this.client as unknown as Record<string, { isConnected?: () => boolean } | undefined>;
26
+ return clientInternal.topology?.isConnected?.() ?? false;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+
32
+ async close(): Promise<void> {
33
+ await this.client.close();
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Create a MongoDB database connection from a connection string.
39
+ *
40
+ * @param connectionString - MongoDB connection string (e.g., mongodb://localhost:27017)
41
+ * @param databaseName - Name of the database to use
42
+ * @returns Promise resolving to MongoDBConnection
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const connection = await createMongoDBConnection(
47
+ * "mongodb://localhost:27017",
48
+ * "my_database"
49
+ * );
50
+ * ```
51
+ */
52
+ export async function createMongoDBConnection(
53
+ connectionString: string,
54
+ databaseName: string
55
+ ): Promise<MongoDBConnection> {
56
+ const client = new MongoClient(connectionString);
57
+ await client.connect();
58
+ const db = client.db(databaseName);
59
+ return new MongoDBConnection(db, client);
60
+ }