@rebasepro/server-core 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 (300) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +40 -0
  3. package/build-errors.txt +52 -0
  4. package/coverage/clover.xml +3739 -0
  5. package/coverage/coverage-final.json +31 -0
  6. package/coverage/lcov-report/base.css +224 -0
  7. package/coverage/lcov-report/block-navigation.js +87 -0
  8. package/coverage/lcov-report/favicon.png +0 -0
  9. package/coverage/lcov-report/index.html +266 -0
  10. package/coverage/lcov-report/prettify.css +1 -0
  11. package/coverage/lcov-report/prettify.js +2 -0
  12. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  13. package/coverage/lcov-report/sorter.js +210 -0
  14. package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +952 -0
  15. package/coverage/lcov-report/src/api/errors.ts.html +472 -0
  16. package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +1069 -0
  17. package/coverage/lcov-report/src/api/graphql/index.html +116 -0
  18. package/coverage/lcov-report/src/api/index.html +176 -0
  19. package/coverage/lcov-report/src/api/openapi-generator.ts.html +565 -0
  20. package/coverage/lcov-report/src/api/rest/api-generator.ts.html +994 -0
  21. package/coverage/lcov-report/src/api/rest/index.html +131 -0
  22. package/coverage/lcov-report/src/api/rest/query-parser.ts.html +550 -0
  23. package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +202 -0
  24. package/coverage/lcov-report/src/api/server.ts.html +823 -0
  25. package/coverage/lcov-report/src/auth/admin-routes.ts.html +973 -0
  26. package/coverage/lcov-report/src/auth/index.html +176 -0
  27. package/coverage/lcov-report/src/auth/jwt.ts.html +574 -0
  28. package/coverage/lcov-report/src/auth/middleware.ts.html +745 -0
  29. package/coverage/lcov-report/src/auth/password.ts.html +310 -0
  30. package/coverage/lcov-report/src/auth/services.ts.html +2074 -0
  31. package/coverage/lcov-report/src/collections/index.html +116 -0
  32. package/coverage/lcov-report/src/collections/loader.ts.html +232 -0
  33. package/coverage/lcov-report/src/db/auth-schema.ts.html +523 -0
  34. package/coverage/lcov-report/src/db/data-transformer.ts.html +1753 -0
  35. package/coverage/lcov-report/src/db/entityService.ts.html +700 -0
  36. package/coverage/lcov-report/src/db/index.html +146 -0
  37. package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +4048 -0
  38. package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +883 -0
  39. package/coverage/lcov-report/src/db/services/RelationService.ts.html +3121 -0
  40. package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +442 -0
  41. package/coverage/lcov-report/src/db/services/index.html +176 -0
  42. package/coverage/lcov-report/src/db/services/index.ts.html +124 -0
  43. package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +1960 -0
  44. package/coverage/lcov-report/src/index.html +116 -0
  45. package/coverage/lcov-report/src/services/driver-registry.ts.html +631 -0
  46. package/coverage/lcov-report/src/services/index.html +131 -0
  47. package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +3025 -0
  48. package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +1189 -0
  49. package/coverage/lcov-report/src/storage/S3StorageController.ts.html +970 -0
  50. package/coverage/lcov-report/src/storage/index.html +161 -0
  51. package/coverage/lcov-report/src/storage/storage-registry.ts.html +646 -0
  52. package/coverage/lcov-report/src/storage/types.ts.html +451 -0
  53. package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +3082 -0
  54. package/coverage/lcov-report/src/utils/index.html +116 -0
  55. package/coverage/lcov.info +7179 -0
  56. package/dist/common/src/collections/CollectionRegistry.d.ts +56 -0
  57. package/dist/common/src/collections/index.d.ts +1 -0
  58. package/dist/common/src/data/buildRebaseData.d.ts +14 -0
  59. package/dist/common/src/index.d.ts +3 -0
  60. package/dist/common/src/util/builders.d.ts +57 -0
  61. package/dist/common/src/util/callbacks.d.ts +6 -0
  62. package/dist/common/src/util/collections.d.ts +11 -0
  63. package/dist/common/src/util/common.d.ts +2 -0
  64. package/dist/common/src/util/conditions.d.ts +26 -0
  65. package/dist/common/src/util/entities.d.ts +58 -0
  66. package/dist/common/src/util/enums.d.ts +3 -0
  67. package/dist/common/src/util/index.d.ts +16 -0
  68. package/dist/common/src/util/navigation_from_path.d.ts +34 -0
  69. package/dist/common/src/util/navigation_utils.d.ts +20 -0
  70. package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
  71. package/dist/common/src/util/paths.d.ts +14 -0
  72. package/dist/common/src/util/permissions.d.ts +5 -0
  73. package/dist/common/src/util/references.d.ts +2 -0
  74. package/dist/common/src/util/relations.d.ts +22 -0
  75. package/dist/common/src/util/resolutions.d.ts +72 -0
  76. package/dist/common/src/util/storage.d.ts +24 -0
  77. package/dist/index-DXVBFp5V.js +37 -0
  78. package/dist/index-DXVBFp5V.js.map +1 -0
  79. package/dist/index.es.js +49934 -0
  80. package/dist/index.es.js.map +1 -0
  81. package/dist/index.umd.js +49968 -0
  82. package/dist/index.umd.js.map +1 -0
  83. package/dist/server-core/src/api/ast-schema-editor.d.ts +21 -0
  84. package/dist/server-core/src/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
  85. package/dist/server-core/src/api/errors.d.ts +35 -0
  86. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +35 -0
  87. package/dist/server-core/src/api/graphql/index.d.ts +1 -0
  88. package/dist/server-core/src/api/index.d.ts +9 -0
  89. package/dist/server-core/src/api/openapi-generator.d.ts +16 -0
  90. package/dist/server-core/src/api/rest/api-generator.d.ts +64 -0
  91. package/dist/server-core/src/api/rest/index.d.ts +1 -0
  92. package/dist/server-core/src/api/rest/query-parser.d.ts +9 -0
  93. package/dist/server-core/src/api/schema-editor-routes.d.ts +3 -0
  94. package/dist/server-core/src/api/server.d.ts +40 -0
  95. package/dist/server-core/src/api/types.d.ts +90 -0
  96. package/dist/server-core/src/auth/admin-routes.d.ts +16 -0
  97. package/dist/server-core/src/auth/apple-oauth.d.ts +30 -0
  98. package/dist/server-core/src/auth/bitbucket-oauth.d.ts +11 -0
  99. package/dist/server-core/src/auth/discord-oauth.d.ts +14 -0
  100. package/dist/server-core/src/auth/facebook-oauth.d.ts +14 -0
  101. package/dist/server-core/src/auth/github-oauth.d.ts +15 -0
  102. package/dist/server-core/src/auth/gitlab-oauth.d.ts +13 -0
  103. package/dist/server-core/src/auth/google-oauth.d.ts +14 -0
  104. package/dist/server-core/src/auth/index.d.ts +23 -0
  105. package/dist/server-core/src/auth/interfaces.d.ts +309 -0
  106. package/dist/server-core/src/auth/jwt.d.ts +43 -0
  107. package/dist/server-core/src/auth/linkedin-oauth.d.ts +18 -0
  108. package/dist/server-core/src/auth/microsoft-oauth.d.ts +16 -0
  109. package/dist/server-core/src/auth/middleware.d.ts +81 -0
  110. package/dist/server-core/src/auth/password.d.ts +22 -0
  111. package/dist/server-core/src/auth/rate-limiter.d.ts +31 -0
  112. package/dist/server-core/src/auth/routes.d.ts +27 -0
  113. package/dist/server-core/src/auth/slack-oauth.d.ts +12 -0
  114. package/dist/server-core/src/auth/spotify-oauth.d.ts +12 -0
  115. package/dist/server-core/src/auth/twitter-oauth.d.ts +18 -0
  116. package/dist/server-core/src/bootstrappers/index.d.ts +0 -0
  117. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +13 -0
  118. package/dist/server-core/src/collections/loader.d.ts +5 -0
  119. package/dist/server-core/src/cron/cron-loader.d.ts +17 -0
  120. package/dist/server-core/src/cron/cron-routes.d.ts +14 -0
  121. package/dist/server-core/src/cron/cron-scheduler.d.ts +61 -0
  122. package/dist/server-core/src/cron/cron-store.d.ts +32 -0
  123. package/dist/server-core/src/cron/index.d.ts +6 -0
  124. package/dist/server-core/src/db/interfaces.d.ts +18 -0
  125. package/dist/server-core/src/email/index.d.ts +6 -0
  126. package/dist/server-core/src/email/smtp-email-service.d.ts +25 -0
  127. package/dist/server-core/src/email/templates.d.ts +42 -0
  128. package/dist/server-core/src/email/types.d.ts +107 -0
  129. package/dist/server-core/src/functions/function-loader.d.ts +17 -0
  130. package/dist/server-core/src/functions/function-routes.d.ts +10 -0
  131. package/dist/server-core/src/functions/index.d.ts +3 -0
  132. package/dist/server-core/src/history/history-routes.d.ts +23 -0
  133. package/dist/server-core/src/history/index.d.ts +1 -0
  134. package/dist/server-core/src/index.d.ts +29 -0
  135. package/dist/server-core/src/init.d.ts +159 -0
  136. package/dist/server-core/src/serve-spa.d.ts +30 -0
  137. package/dist/server-core/src/services/driver-registry.d.ts +78 -0
  138. package/dist/server-core/src/singleton.d.ts +35 -0
  139. package/dist/server-core/src/storage/LocalStorageController.d.ts +46 -0
  140. package/dist/server-core/src/storage/S3StorageController.d.ts +36 -0
  141. package/dist/server-core/src/storage/index.d.ts +25 -0
  142. package/dist/server-core/src/storage/routes.d.ts +38 -0
  143. package/dist/server-core/src/storage/storage-registry.d.ts +78 -0
  144. package/dist/server-core/src/storage/types.d.ts +103 -0
  145. package/dist/server-core/src/types/index.d.ts +11 -0
  146. package/dist/server-core/src/utils/dev-port.d.ts +35 -0
  147. package/dist/server-core/src/utils/logger.d.ts +31 -0
  148. package/dist/server-core/src/utils/logging.d.ts +9 -0
  149. package/dist/server-core/src/utils/request-logger.d.ts +19 -0
  150. package/dist/server-core/src/utils/sql.d.ts +27 -0
  151. package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
  152. package/dist/types/src/controllers/auth.d.ts +119 -0
  153. package/dist/types/src/controllers/client.d.ts +170 -0
  154. package/dist/types/src/controllers/collection_registry.d.ts +45 -0
  155. package/dist/types/src/controllers/customization_controller.d.ts +60 -0
  156. package/dist/types/src/controllers/data.d.ts +168 -0
  157. package/dist/types/src/controllers/data_driver.d.ts +160 -0
  158. package/dist/types/src/controllers/database_admin.d.ts +11 -0
  159. package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
  160. package/dist/types/src/controllers/effective_role.d.ts +4 -0
  161. package/dist/types/src/controllers/email.d.ts +34 -0
  162. package/dist/types/src/controllers/index.d.ts +18 -0
  163. package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
  164. package/dist/types/src/controllers/navigation.d.ts +213 -0
  165. package/dist/types/src/controllers/registry.d.ts +54 -0
  166. package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
  167. package/dist/types/src/controllers/side_entity_controller.d.ts +90 -0
  168. package/dist/types/src/controllers/snackbar.d.ts +24 -0
  169. package/dist/types/src/controllers/storage.d.ts +171 -0
  170. package/dist/types/src/index.d.ts +4 -0
  171. package/dist/types/src/rebase_context.d.ts +105 -0
  172. package/dist/types/src/types/backend.d.ts +536 -0
  173. package/dist/types/src/types/builders.d.ts +15 -0
  174. package/dist/types/src/types/chips.d.ts +5 -0
  175. package/dist/types/src/types/collections.d.ts +856 -0
  176. package/dist/types/src/types/cron.d.ts +102 -0
  177. package/dist/types/src/types/data_source.d.ts +64 -0
  178. package/dist/types/src/types/entities.d.ts +145 -0
  179. package/dist/types/src/types/entity_actions.d.ts +98 -0
  180. package/dist/types/src/types/entity_callbacks.d.ts +173 -0
  181. package/dist/types/src/types/entity_link_builder.d.ts +7 -0
  182. package/dist/types/src/types/entity_overrides.d.ts +10 -0
  183. package/dist/types/src/types/entity_views.d.ts +61 -0
  184. package/dist/types/src/types/export_import.d.ts +21 -0
  185. package/dist/types/src/types/index.d.ts +23 -0
  186. package/dist/types/src/types/locales.d.ts +4 -0
  187. package/dist/types/src/types/modify_collections.d.ts +5 -0
  188. package/dist/types/src/types/plugins.d.ts +279 -0
  189. package/dist/types/src/types/properties.d.ts +1176 -0
  190. package/dist/types/src/types/property_config.d.ts +70 -0
  191. package/dist/types/src/types/relations.d.ts +336 -0
  192. package/dist/types/src/types/slots.d.ts +252 -0
  193. package/dist/types/src/types/translations.d.ts +870 -0
  194. package/dist/types/src/types/user_management_delegate.d.ts +121 -0
  195. package/dist/types/src/types/websockets.d.ts +78 -0
  196. package/dist/types/src/users/index.d.ts +2 -0
  197. package/dist/types/src/users/roles.d.ts +22 -0
  198. package/dist/types/src/users/user.d.ts +46 -0
  199. package/history_diff.log +385 -0
  200. package/jest.config.cjs +16 -0
  201. package/package.json +86 -0
  202. package/scratch.ts +9 -0
  203. package/src/api/ast-schema-editor.ts +289 -0
  204. package/src/api/collections_for_test/callbacks_test_collection.ts +60 -0
  205. package/src/api/errors.ts +179 -0
  206. package/src/api/graphql/graphql-schema-generator.ts +336 -0
  207. package/src/api/graphql/index.ts +2 -0
  208. package/src/api/index.ts +11 -0
  209. package/src/api/openapi-generator.ts +715 -0
  210. package/src/api/rest/api-generator.ts +472 -0
  211. package/src/api/rest/index.ts +2 -0
  212. package/src/api/rest/query-parser.ts +155 -0
  213. package/src/api/schema-editor-routes.ts +41 -0
  214. package/src/api/server.ts +248 -0
  215. package/src/api/types.ts +90 -0
  216. package/src/auth/admin-routes.ts +529 -0
  217. package/src/auth/apple-oauth.ts +130 -0
  218. package/src/auth/bitbucket-oauth.ts +82 -0
  219. package/src/auth/discord-oauth.ts +83 -0
  220. package/src/auth/facebook-oauth.ts +72 -0
  221. package/src/auth/github-oauth.ts +110 -0
  222. package/src/auth/gitlab-oauth.ts +70 -0
  223. package/src/auth/google-oauth.ts +48 -0
  224. package/src/auth/index.ts +34 -0
  225. package/src/auth/interfaces.ts +363 -0
  226. package/src/auth/jwt.ts +181 -0
  227. package/src/auth/linkedin-oauth.ts +81 -0
  228. package/src/auth/microsoft-oauth.ts +88 -0
  229. package/src/auth/middleware.ts +384 -0
  230. package/src/auth/password.ts +77 -0
  231. package/src/auth/rate-limiter.ts +129 -0
  232. package/src/auth/routes.ts +788 -0
  233. package/src/auth/slack-oauth.ts +71 -0
  234. package/src/auth/spotify-oauth.ts +67 -0
  235. package/src/auth/twitter-oauth.ts +120 -0
  236. package/src/bootstrappers/index.ts +1 -0
  237. package/src/collections/BackendCollectionRegistry.ts +20 -0
  238. package/src/collections/loader.ts +49 -0
  239. package/src/cron/cron-loader.ts +89 -0
  240. package/src/cron/cron-routes.test.ts +265 -0
  241. package/src/cron/cron-routes.ts +85 -0
  242. package/src/cron/cron-scheduler.test.ts +421 -0
  243. package/src/cron/cron-scheduler.ts +413 -0
  244. package/src/cron/cron-store.ts +163 -0
  245. package/src/cron/index.ts +6 -0
  246. package/src/db/interfaces.ts +60 -0
  247. package/src/email/index.ts +18 -0
  248. package/src/email/smtp-email-service.ts +91 -0
  249. package/src/email/templates.ts +388 -0
  250. package/src/email/types.ts +105 -0
  251. package/src/functions/function-loader.ts +119 -0
  252. package/src/functions/function-routes.ts +31 -0
  253. package/src/functions/index.ts +3 -0
  254. package/src/history/history-routes.ts +129 -0
  255. package/src/history/index.ts +2 -0
  256. package/src/index.ts +66 -0
  257. package/src/init.ts +727 -0
  258. package/src/serve-spa.ts +81 -0
  259. package/src/services/driver-registry.ts +182 -0
  260. package/src/singleton.test.ts +28 -0
  261. package/src/singleton.ts +70 -0
  262. package/src/storage/LocalStorageController.ts +365 -0
  263. package/src/storage/S3StorageController.ts +298 -0
  264. package/src/storage/index.ts +43 -0
  265. package/src/storage/routes.ts +264 -0
  266. package/src/storage/storage-registry.ts +187 -0
  267. package/src/storage/types.ts +134 -0
  268. package/src/types/index.ts +27 -0
  269. package/src/utils/dev-port.ts +176 -0
  270. package/src/utils/logger.ts +143 -0
  271. package/src/utils/logging.ts +38 -0
  272. package/src/utils/request-logger.ts +66 -0
  273. package/src/utils/sql.ts +38 -0
  274. package/test/admin-routes.test.ts +640 -0
  275. package/test/api-generator.test.ts +501 -0
  276. package/test/ast-schema-editor.test.ts +63 -0
  277. package/test/auth-middleware-hono.test.ts +556 -0
  278. package/test/auth-routes.test.ts +1047 -0
  279. package/test/driver-registry.test.ts +282 -0
  280. package/test/error-propagation.test.ts +226 -0
  281. package/test/errors-hono.test.ts +133 -0
  282. package/test/errors.test.ts +155 -0
  283. package/test/jwt-security.test.ts +182 -0
  284. package/test/jwt.test.ts +324 -0
  285. package/test/middleware.test.ts +300 -0
  286. package/test/password.test.ts +165 -0
  287. package/test/query-parser.test.ts +263 -0
  288. package/test/rate-limiter.test.ts +102 -0
  289. package/test/safe-compare.test.ts +66 -0
  290. package/test/singleton.test.ts +59 -0
  291. package/test/storage-local.test.ts +271 -0
  292. package/test/storage-registry.test.ts +282 -0
  293. package/test/storage-routes.test.ts +222 -0
  294. package/test/storage-s3.test.ts +304 -0
  295. package/test-ast.ts +28 -0
  296. package/test.ts +6 -0
  297. package/test_output.txt +1133 -0
  298. package/tsconfig.json +49 -0
  299. package/tsconfig.prod.json +20 -0
  300. package/vite.config.ts +80 -0
@@ -0,0 +1,82 @@
1
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
+ import { z } from "zod";
3
+
4
+ /**
5
+ * Creates a Bitbucket OAuth Provider integration (OAuth 2.0 consumer).
6
+ */
7
+ export function createBitbucketProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<{ code: string; redirectUri: string }> {
8
+ return {
9
+ id: "bitbucket",
10
+ schema: z.object({
11
+ code: z.string().min(1, "Auth code is required"),
12
+ redirectUri: z.string().url("Valid redirect URI is required")
13
+ }),
14
+ verify: async (payload: { code: string; redirectUri: string }): Promise<OAuthProviderProfile | null> => {
15
+ try {
16
+ const basicAuth = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64");
17
+
18
+ const tokenResponse = await fetch("https://bitbucket.org/site/oauth2/access_token", {
19
+ method: "POST",
20
+ headers: {
21
+ "Content-Type": "application/x-www-form-urlencoded",
22
+ "Authorization": `Basic ${basicAuth}`
23
+ },
24
+ body: new URLSearchParams({
25
+ grant_type: "authorization_code",
26
+ code: payload.code,
27
+ redirect_uri: payload.redirectUri
28
+ })
29
+ });
30
+
31
+ if (!tokenResponse.ok) {
32
+ console.error("Failed to get Bitbucket access token:", await tokenResponse.text());
33
+ return null;
34
+ }
35
+
36
+ const tokenData = await tokenResponse.json() as { access_token: string };
37
+ const accessToken = tokenData.access_token;
38
+
39
+ const profileResponse = await fetch("https://api.bitbucket.org/2.0/user", {
40
+ headers: { "Authorization": `Bearer ${accessToken}` }
41
+ });
42
+
43
+ if (!profileResponse.ok) {
44
+ console.error("Failed to get Bitbucket user info:", await profileResponse.text());
45
+ return null;
46
+ }
47
+
48
+ const p = await profileResponse.json() as {
49
+ uuid: string; display_name?: string; username?: string;
50
+ links?: { avatar?: { href?: string } };
51
+ };
52
+
53
+ // Bitbucket doesn't return email in user profile — fetch from /emails endpoint
54
+ const emailsResponse = await fetch("https://api.bitbucket.org/2.0/user/emails", {
55
+ headers: { "Authorization": `Bearer ${accessToken}` }
56
+ });
57
+
58
+ let email: string | null = null;
59
+ if (emailsResponse.ok) {
60
+ const emailData = await emailsResponse.json() as {
61
+ values: Array<{ email: string; is_primary: boolean; is_confirmed: boolean }>;
62
+ };
63
+ const primary = emailData.values.find(e => e.is_primary && e.is_confirmed)
64
+ || emailData.values.find(e => e.is_confirmed);
65
+ email = primary?.email || null;
66
+ }
67
+
68
+ if (!email) { console.error("Bitbucket user has no verified email"); return null; }
69
+
70
+ return {
71
+ providerId: p.uuid,
72
+ email,
73
+ displayName: p.display_name || p.username || null,
74
+ photoUrl: p.links?.avatar?.href || null
75
+ };
76
+ } catch (error) {
77
+ console.error("Bitbucket OAuth error:", error);
78
+ return null;
79
+ }
80
+ }
81
+ };
82
+ }
@@ -0,0 +1,83 @@
1
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
+ import { z } from "zod";
3
+
4
+ /**
5
+ * Creates a Discord OAuth2 Provider integration.
6
+ *
7
+ * Uses the authorization code flow. Requires the "identify" and "email"
8
+ * scopes to retrieve the user's email and profile information.
9
+ */
10
+ export function createDiscordProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<{ code: string; redirectUri: string }> {
11
+ return {
12
+ id: "discord",
13
+ schema: z.object({
14
+ code: z.string().min(1, "Auth code is required"),
15
+ redirectUri: z.string().url("Valid redirect URI is required")
16
+ }),
17
+ verify: async (payload: { code: string; redirectUri: string }): Promise<OAuthProviderProfile | null> => {
18
+ try {
19
+ // Exchange code for access token
20
+ const tokenResponse = await fetch("https://discord.com/api/v10/oauth2/token", {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
23
+ body: new URLSearchParams({
24
+ client_id: config.clientId,
25
+ client_secret: config.clientSecret,
26
+ grant_type: "authorization_code",
27
+ code: payload.code,
28
+ redirect_uri: payload.redirectUri
29
+ })
30
+ });
31
+
32
+ if (!tokenResponse.ok) {
33
+ console.error("Failed to get Discord access token:", await tokenResponse.text());
34
+ return null;
35
+ }
36
+
37
+ const tokenData = await tokenResponse.json() as { access_token: string };
38
+ const accessToken = tokenData.access_token;
39
+
40
+ // Fetch user profile
41
+ const profileResponse = await fetch("https://discord.com/api/v10/users/@me", {
42
+ headers: { "Authorization": `Bearer ${accessToken}` }
43
+ });
44
+
45
+ if (!profileResponse.ok) {
46
+ console.error("Failed to get Discord user info:", await profileResponse.text());
47
+ return null;
48
+ }
49
+
50
+ const profileData = await profileResponse.json() as {
51
+ id: string;
52
+ username: string;
53
+ global_name?: string | null;
54
+ avatar?: string | null;
55
+ email?: string | null;
56
+ verified?: boolean;
57
+ };
58
+
59
+ if (!profileData.email) {
60
+ console.error("Discord user has no email (email scope may not have been granted)");
61
+ return null;
62
+ }
63
+
64
+ // Build avatar URL
65
+ let photoUrl: string | null = null;
66
+ if (profileData.avatar) {
67
+ const ext = profileData.avatar.startsWith("a_") ? "gif" : "png";
68
+ photoUrl = `https://cdn.discordapp.com/avatars/${profileData.id}/${profileData.avatar}.${ext}?size=256`;
69
+ }
70
+
71
+ return {
72
+ providerId: profileData.id,
73
+ email: profileData.email,
74
+ displayName: profileData.global_name || profileData.username || null,
75
+ photoUrl
76
+ };
77
+ } catch (error) {
78
+ console.error("Discord OAuth error:", error);
79
+ return null;
80
+ }
81
+ }
82
+ };
83
+ }
@@ -0,0 +1,72 @@
1
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
+ import { z } from "zod";
3
+
4
+ /**
5
+ * Creates a Facebook / Meta OAuth Provider integration.
6
+ *
7
+ * Uses the authorization code flow to exchange a code for an access token,
8
+ * then fetches user profile from the Facebook Graph API.
9
+ */
10
+ export function createFacebookProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<{ code: string; redirectUri: string }> {
11
+ return {
12
+ id: "facebook",
13
+ schema: z.object({
14
+ code: z.string().min(1, "Auth code is required"),
15
+ redirectUri: z.string().url("Valid redirect URI is required")
16
+ }),
17
+ verify: async (payload: { code: string; redirectUri: string }): Promise<OAuthProviderProfile | null> => {
18
+ try {
19
+ // Exchange code for access token
20
+ const tokenUrl = new URL("https://graph.facebook.com/v19.0/oauth/access_token");
21
+ tokenUrl.searchParams.set("client_id", config.clientId);
22
+ tokenUrl.searchParams.set("client_secret", config.clientSecret);
23
+ tokenUrl.searchParams.set("redirect_uri", payload.redirectUri);
24
+ tokenUrl.searchParams.set("code", payload.code);
25
+
26
+ const tokenResponse = await fetch(tokenUrl.toString());
27
+
28
+ if (!tokenResponse.ok) {
29
+ console.error("Failed to get Facebook access token:", await tokenResponse.text());
30
+ return null;
31
+ }
32
+
33
+ const tokenData = await tokenResponse.json() as { access_token: string };
34
+ const accessToken = tokenData.access_token;
35
+
36
+ // Fetch user profile with email and profile picture
37
+ const profileUrl = new URL("https://graph.facebook.com/v19.0/me");
38
+ profileUrl.searchParams.set("fields", "id,name,email,picture.type(large)");
39
+ profileUrl.searchParams.set("access_token", accessToken);
40
+
41
+ const profileResponse = await fetch(profileUrl.toString());
42
+
43
+ if (!profileResponse.ok) {
44
+ console.error("Failed to get Facebook user info:", await profileResponse.text());
45
+ return null;
46
+ }
47
+
48
+ const profileData = await profileResponse.json() as {
49
+ id: string;
50
+ name?: string;
51
+ email?: string;
52
+ picture?: { data?: { url?: string } };
53
+ };
54
+
55
+ if (!profileData.email) {
56
+ console.error("Facebook user has no email (email permission may not have been granted)");
57
+ return null;
58
+ }
59
+
60
+ return {
61
+ providerId: profileData.id,
62
+ email: profileData.email,
63
+ displayName: profileData.name || null,
64
+ photoUrl: profileData.picture?.data?.url || null
65
+ };
66
+ } catch (error) {
67
+ console.error("Facebook OAuth error:", error);
68
+ return null;
69
+ }
70
+ }
71
+ };
72
+ }
@@ -0,0 +1,110 @@
1
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
+ import { z } from "zod";
3
+
4
+ /**
5
+ * Creates a GitHub OAuth Provider integration.
6
+ *
7
+ * Flow: Frontend receives an authorization `code` via the GitHub OAuth redirect.
8
+ * This provider exchanges the code for an access token, then fetches the user's
9
+ * profile and primary email from the GitHub API.
10
+ */
11
+ export function createGitHubProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<{ code: string; redirectUri: string }> {
12
+ return {
13
+ id: "github",
14
+ schema: z.object({
15
+ code: z.string().min(1, "Auth code is required"),
16
+ redirectUri: z.string().url("Valid redirect URI is required")
17
+ }),
18
+ verify: async (payload: { code: string; redirectUri: string }): Promise<OAuthProviderProfile | null> => {
19
+ try {
20
+ // Exchange code for access token
21
+ const tokenResponse = await fetch("https://github.com/login/oauth/access_token", {
22
+ method: "POST",
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ "Accept": "application/json"
26
+ },
27
+ body: JSON.stringify({
28
+ client_id: config.clientId,
29
+ client_secret: config.clientSecret,
30
+ code: payload.code,
31
+ redirect_uri: payload.redirectUri
32
+ })
33
+ });
34
+
35
+ if (!tokenResponse.ok) {
36
+ console.error("Failed to get GitHub access token:", await tokenResponse.text());
37
+ return null;
38
+ }
39
+
40
+ const tokenData = await tokenResponse.json() as { access_token?: string; error?: string };
41
+ if (tokenData.error || !tokenData.access_token) {
42
+ console.error("GitHub token exchange error:", tokenData.error);
43
+ return null;
44
+ }
45
+
46
+ const accessToken = tokenData.access_token;
47
+
48
+ // Fetch user profile
49
+ const profileResponse = await fetch("https://api.github.com/user", {
50
+ headers: {
51
+ "Authorization": `Bearer ${accessToken}`,
52
+ "Accept": "application/vnd.github+json",
53
+ "User-Agent": "Rebase-Auth"
54
+ }
55
+ });
56
+
57
+ if (!profileResponse.ok) {
58
+ console.error("Failed to get GitHub user info:", await profileResponse.text());
59
+ return null;
60
+ }
61
+
62
+ const profileData = await profileResponse.json() as {
63
+ id: number;
64
+ login: string;
65
+ name?: string | null;
66
+ avatar_url?: string | null;
67
+ email?: string | null;
68
+ };
69
+
70
+ // GitHub may not return email in profile if it's private.
71
+ // Fetch from /user/emails endpoint instead.
72
+ let email = profileData.email;
73
+ if (!email) {
74
+ const emailsResponse = await fetch("https://api.github.com/user/emails", {
75
+ headers: {
76
+ "Authorization": `Bearer ${accessToken}`,
77
+ "Accept": "application/vnd.github+json",
78
+ "User-Agent": "Rebase-Auth"
79
+ }
80
+ });
81
+
82
+ if (emailsResponse.ok) {
83
+ const emails = await emailsResponse.json() as Array<{
84
+ email: string;
85
+ primary: boolean;
86
+ verified: boolean;
87
+ }>;
88
+ const primary = emails.find(e => e.primary && e.verified) || emails.find(e => e.verified);
89
+ email = primary?.email || null;
90
+ }
91
+ }
92
+
93
+ if (!email) {
94
+ console.error("GitHub user has no verified email");
95
+ return null;
96
+ }
97
+
98
+ return {
99
+ providerId: String(profileData.id),
100
+ email,
101
+ displayName: profileData.name || profileData.login || null,
102
+ photoUrl: profileData.avatar_url || null
103
+ };
104
+ } catch (error) {
105
+ console.error("GitHub OAuth error:", error);
106
+ return null;
107
+ }
108
+ }
109
+ };
110
+ }
@@ -0,0 +1,70 @@
1
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
2
+ import { z } from "zod";
3
+
4
+ /**
5
+ * Creates a GitLab OAuth Provider integration.
6
+ * Works with both GitLab.com and self-hosted instances.
7
+ */
8
+ export function createGitLabProvider(config: {
9
+ clientId: string;
10
+ clientSecret: string;
11
+ baseUrl?: string;
12
+ }): OAuthProvider<{ code: string; redirectUri: string }> {
13
+ const gitlabUrl = (config.baseUrl || "https://gitlab.com").replace(/\/$/, "");
14
+
15
+ return {
16
+ id: "gitlab",
17
+ schema: z.object({
18
+ code: z.string().min(1, "Auth code is required"),
19
+ redirectUri: z.string().url("Valid redirect URI is required")
20
+ }),
21
+ verify: async (payload: { code: string; redirectUri: string }): Promise<OAuthProviderProfile | null> => {
22
+ try {
23
+ const tokenResponse = await fetch(`${gitlabUrl}/oauth/token`, {
24
+ method: "POST",
25
+ headers: { "Content-Type": "application/json" },
26
+ body: JSON.stringify({
27
+ client_id: config.clientId,
28
+ client_secret: config.clientSecret,
29
+ code: payload.code,
30
+ grant_type: "authorization_code",
31
+ redirect_uri: payload.redirectUri
32
+ })
33
+ });
34
+
35
+ if (!tokenResponse.ok) {
36
+ console.error("Failed to get GitLab access token:", await tokenResponse.text());
37
+ return null;
38
+ }
39
+
40
+ const tokenData = await tokenResponse.json() as { access_token: string };
41
+
42
+ const profileResponse = await fetch(`${gitlabUrl}/api/v4/user`, {
43
+ headers: { "Authorization": `Bearer ${tokenData.access_token}` }
44
+ });
45
+
46
+ if (!profileResponse.ok) {
47
+ console.error("Failed to get GitLab user info:", await profileResponse.text());
48
+ return null;
49
+ }
50
+
51
+ const p = await profileResponse.json() as {
52
+ id: number; username: string; name?: string;
53
+ email: string; avatar_url?: string | null;
54
+ };
55
+
56
+ if (!p.email) { console.error("GitLab user has no email"); return null; }
57
+
58
+ return {
59
+ providerId: String(p.id),
60
+ email: p.email,
61
+ displayName: p.name || p.username || null,
62
+ photoUrl: p.avatar_url || null
63
+ };
64
+ } catch (error) {
65
+ console.error("GitLab OAuth error:", error);
66
+ return null;
67
+ }
68
+ }
69
+ };
70
+ }
@@ -0,0 +1,48 @@
1
+ import { OAuth2Client } from "google-auth-library/build/src/index.js";
2
+ import type { OAuthProvider, OAuthProviderProfile } from "./interfaces";
3
+ import { z } from "zod";
4
+
5
+ export interface GoogleUserInfo {
6
+ googleId: string;
7
+ email: string;
8
+ displayName: string | null;
9
+ photoUrl: string | null;
10
+ emailVerified: boolean;
11
+ }
12
+
13
+ /**
14
+ * Creates a Google OAuth Provider integration
15
+ */
16
+ export function createGoogleProvider(clientId: string): OAuthProvider<{ idToken: string }> {
17
+ const googleClient = new OAuth2Client(clientId);
18
+
19
+ return {
20
+ id: "google",
21
+ schema: z.object({
22
+ idToken: z.string().min(1, "ID token is required")
23
+ }),
24
+ verify: async (payload: { idToken: string }): Promise<OAuthProviderProfile | null> => {
25
+ try {
26
+ const ticket = await googleClient.verifyIdToken({
27
+ idToken: payload.idToken,
28
+ audience: clientId
29
+ });
30
+
31
+ const content = ticket.getPayload();
32
+ if (!content) {
33
+ return null;
34
+ }
35
+
36
+ return {
37
+ providerId: content.sub,
38
+ email: content.email || "",
39
+ displayName: content.name || null,
40
+ photoUrl: content.picture || null
41
+ };
42
+ } catch (error) {
43
+ console.error("Failed to verify Google ID token:", error);
44
+ return null;
45
+ }
46
+ }
47
+ };
48
+ }
@@ -0,0 +1,34 @@
1
+ // Auth module exports
2
+ export * from "./interfaces";
3
+
4
+ export { configureJwt, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry } from "./jwt";
5
+ export type { JwtConfig, AccessTokenPayload } from "./jwt";
6
+
7
+ export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
8
+ export type { PasswordValidationResult } from "./password";
9
+
10
+ // OAuth Providers
11
+ export { createGoogleProvider } from "./google-oauth";
12
+ export { createLinkedinProvider } from "./linkedin-oauth";
13
+ export { createGitHubProvider } from "./github-oauth";
14
+ export { createMicrosoftProvider } from "./microsoft-oauth";
15
+ export { createAppleProvider } from "./apple-oauth";
16
+ export { createFacebookProvider } from "./facebook-oauth";
17
+ export { createTwitterProvider } from "./twitter-oauth";
18
+ export { createDiscordProvider } from "./discord-oauth";
19
+ export { createGitLabProvider } from "./gitlab-oauth";
20
+ export { createBitbucketProvider } from "./bitbucket-oauth";
21
+ export { createSlackProvider } from "./slack-oauth";
22
+ export { createSpotifyProvider } from "./spotify-oauth";
23
+
24
+ export { requireAuth, requireAdmin, optionalAuth, extractUserFromToken, createAuthMiddleware } from "./middleware";
25
+ export type { AuthMiddlewareOptions, AuthResult } from "./middleware";
26
+
27
+
28
+ export { createAuthRoutes } from "./routes";
29
+ export type { AuthModuleConfig } from "./routes";
30
+
31
+ export { createAdminRoutes } from "./admin-routes";
32
+
33
+
34
+ export { createRateLimiter, defaultAuthLimiter, strictAuthLimiter } from "./rate-limiter";