modelence 0.7.2 → 0.9.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/dist/app/authConfig.d.ts +68 -0
  2. package/dist/app/authConfig.d.ts.map +1 -0
  3. package/dist/app/authConfig.js +8 -0
  4. package/dist/app/authConfig.js.map +1 -0
  5. package/dist/app/backendApi.d.ts +29 -0
  6. package/dist/app/backendApi.d.ts.map +1 -0
  7. package/dist/app/backendApi.js +69 -0
  8. package/dist/app/backendApi.js.map +1 -0
  9. package/dist/app/email.d.ts +3 -0
  10. package/dist/app/email.d.ts.map +1 -0
  11. package/dist/app/email.js +8 -0
  12. package/dist/app/email.js.map +1 -0
  13. package/dist/app/emailConfig.d.ts +27 -0
  14. package/dist/app/emailConfig.d.ts.map +1 -0
  15. package/dist/app/emailConfig.js +8 -0
  16. package/dist/app/emailConfig.js.map +1 -0
  17. package/dist/app/index.d.ts +20 -0
  18. package/dist/app/index.d.ts.map +1 -0
  19. package/dist/app/index.js +258 -0
  20. package/dist/app/index.js.map +1 -0
  21. package/dist/app/loggerProcess.d.ts +5 -0
  22. package/dist/app/loggerProcess.d.ts.map +1 -0
  23. package/dist/app/loggerProcess.js +90 -0
  24. package/dist/app/loggerProcess.js.map +1 -0
  25. package/dist/app/metrics.d.ts +6 -0
  26. package/dist/app/metrics.d.ts.map +1 -0
  27. package/dist/app/metrics.js +92 -0
  28. package/dist/app/metrics.js.map +1 -0
  29. package/dist/app/module.d.ts +77 -0
  30. package/dist/app/module.d.ts.map +1 -0
  31. package/dist/app/module.js +46 -0
  32. package/dist/app/module.js.map +1 -0
  33. package/dist/app/server.d.ts +37 -0
  34. package/dist/app/server.d.ts.map +1 -0
  35. package/dist/app/server.js +198 -0
  36. package/dist/app/server.js.map +1 -0
  37. package/dist/app/state.d.ts +19 -0
  38. package/dist/app/state.d.ts.map +1 -0
  39. package/dist/app/state.js +27 -0
  40. package/dist/app/state.js.map +1 -0
  41. package/dist/app/websocketConfig.d.ts +7 -0
  42. package/dist/app/websocketConfig.d.ts.map +1 -0
  43. package/dist/app/websocketConfig.js +8 -0
  44. package/dist/app/websocketConfig.js.map +1 -0
  45. package/dist/auth/client/index.d.ts +69 -0
  46. package/dist/auth/client/index.d.ts.map +1 -0
  47. package/dist/auth/client/index.js +79 -0
  48. package/dist/auth/client/index.js.map +1 -0
  49. package/dist/auth/db.d.ts +176 -0
  50. package/dist/auth/db.d.ts.map +1 -0
  51. package/dist/auth/db.js +117 -0
  52. package/dist/auth/db.js.map +1 -0
  53. package/dist/auth/deleteUser.d.ts +5 -0
  54. package/dist/auth/deleteUser.d.ts.map +1 -0
  55. package/dist/auth/deleteUser.js +34 -0
  56. package/dist/auth/deleteUser.js.map +1 -0
  57. package/dist/auth/disposableEmails.d.ts +6 -0
  58. package/dist/auth/disposableEmails.d.ts.map +1 -0
  59. package/dist/auth/disposableEmails.js +47 -0
  60. package/dist/auth/disposableEmails.js.map +1 -0
  61. package/dist/auth/index.d.ts +7 -0
  62. package/dist/auth/index.d.ts.map +1 -0
  63. package/dist/auth/index.js +33 -0
  64. package/dist/auth/index.js.map +1 -0
  65. package/dist/auth/login.d.ts +9 -0
  66. package/dist/auth/login.d.ts.map +1 -0
  67. package/dist/auth/login.js +100 -0
  68. package/dist/auth/login.js.map +1 -0
  69. package/dist/auth/password.d.ts +14 -0
  70. package/dist/auth/password.d.ts.map +1 -0
  71. package/dist/auth/password.js +26 -0
  72. package/dist/auth/password.js.map +1 -0
  73. package/dist/auth/profile.d.ts +10 -0
  74. package/dist/auth/profile.d.ts.map +1 -0
  75. package/dist/auth/profile.js +13 -0
  76. package/dist/auth/profile.js.map +1 -0
  77. package/dist/auth/providers/github.d.ts +3 -0
  78. package/dist/auth/providers/github.d.ts.map +1 -0
  79. package/dist/auth/providers/github.js +122 -0
  80. package/dist/auth/providers/github.js.map +1 -0
  81. package/dist/auth/providers/google.d.ts +3 -0
  82. package/dist/auth/providers/google.d.ts.map +1 -0
  83. package/dist/auth/providers/google.js +108 -0
  84. package/dist/auth/providers/google.js.map +1 -0
  85. package/dist/auth/providers/oauth-common.d.ts +13 -0
  86. package/dist/auth/providers/oauth-common.d.ts.map +1 -0
  87. package/dist/auth/providers/oauth-common.js +109 -0
  88. package/dist/auth/providers/oauth-common.js.map +1 -0
  89. package/dist/auth/resetPassword.d.ts +10 -0
  90. package/dist/auth/resetPassword.d.ts.map +1 -0
  91. package/dist/auth/resetPassword.js +108 -0
  92. package/dist/auth/resetPassword.js.map +1 -0
  93. package/dist/auth/role.d.ts +8 -0
  94. package/dist/auth/role.d.ts.map +1 -0
  95. package/dist/auth/role.js +37 -0
  96. package/dist/auth/role.js.map +1 -0
  97. package/dist/auth/session.d.ts +24 -0
  98. package/dist/auth/session.d.ts.map +1 -0
  99. package/dist/auth/session.js +84 -0
  100. package/dist/auth/session.js.map +1 -0
  101. package/dist/auth/signup.d.ts +3 -0
  102. package/dist/auth/signup.d.ts.map +1 -0
  103. package/dist/auth/signup.js +89 -0
  104. package/dist/auth/signup.js.map +1 -0
  105. package/dist/auth/templates/emailVerficationTemplate.d.ts +6 -0
  106. package/dist/auth/templates/emailVerficationTemplate.d.ts.map +1 -0
  107. package/dist/auth/templates/emailVerficationTemplate.js +9 -0
  108. package/dist/auth/templates/emailVerficationTemplate.js.map +1 -0
  109. package/dist/auth/types.d.ts +22 -0
  110. package/dist/auth/types.d.ts.map +1 -0
  111. package/dist/auth/types.js +2 -0
  112. package/dist/auth/types.js.map +1 -0
  113. package/dist/auth/user.d.ts +5 -0
  114. package/dist/auth/user.d.ts.map +1 -0
  115. package/dist/auth/user.js +152 -0
  116. package/dist/auth/user.js.map +1 -0
  117. package/dist/auth/validators.d.ts +3 -0
  118. package/dist/auth/validators.d.ts.map +1 -0
  119. package/dist/auth/validators.js +8 -0
  120. package/dist/auth/validators.js.map +1 -0
  121. package/dist/auth/verification.d.ts +8 -0
  122. package/dist/auth/verification.d.ts.map +1 -0
  123. package/dist/auth/verification.js +94 -0
  124. package/dist/auth/verification.js.map +1 -0
  125. package/dist/bin/auth.d.ts +4 -0
  126. package/dist/bin/auth.d.ts.map +1 -0
  127. package/dist/bin/auth.js +48 -0
  128. package/dist/bin/auth.js.map +1 -0
  129. package/dist/bin/build.d.ts +2 -0
  130. package/dist/bin/build.d.ts.map +1 -0
  131. package/dist/bin/build.js +78 -0
  132. package/dist/bin/build.js.map +1 -0
  133. package/dist/bin/config.d.ts +11 -0
  134. package/dist/bin/config.d.ts.map +1 -0
  135. package/dist/bin/config.js +91 -0
  136. package/dist/bin/config.js.map +1 -0
  137. package/dist/bin/deploy.d.ts +6 -0
  138. package/dist/bin/deploy.d.ts.map +1 -0
  139. package/dist/bin/deploy.js +129 -0
  140. package/dist/bin/deploy.js.map +1 -0
  141. package/dist/bin/dev.d.ts +2 -0
  142. package/dist/bin/dev.d.ts.map +1 -0
  143. package/dist/bin/dev.js +14 -0
  144. package/dist/bin/dev.js.map +1 -0
  145. package/dist/bin/modelence.d.ts +3 -0
  146. package/dist/bin/modelence.d.ts.map +1 -0
  147. package/dist/bin/modelence.js +57 -3
  148. package/dist/bin/modelence.js.map +1 -1
  149. package/dist/bin/setup.d.ts +5 -0
  150. package/dist/bin/setup.d.ts.map +1 -0
  151. package/dist/bin/setup.js +91 -0
  152. package/dist/bin/setup.js.map +1 -0
  153. package/dist/bin/start.d.ts +2 -0
  154. package/dist/bin/start.d.ts.map +1 -0
  155. package/dist/bin/start.js +15 -0
  156. package/dist/bin/start.js.map +1 -0
  157. package/dist/client/AppProvider.d.ts +8 -0
  158. package/dist/client/AppProvider.d.ts.map +1 -0
  159. package/dist/client/AppProvider.js +31 -0
  160. package/dist/client/AppProvider.js.map +1 -0
  161. package/dist/client/errorHandler.d.ts +4 -0
  162. package/dist/client/errorHandler.d.ts.map +1 -0
  163. package/dist/client/errorHandler.js +10 -0
  164. package/dist/client/errorHandler.js.map +1 -0
  165. package/dist/client/localStorage.d.ts +3 -0
  166. package/dist/client/localStorage.d.ts.map +1 -0
  167. package/dist/client/localStorage.js +14 -0
  168. package/dist/client/localStorage.js.map +1 -0
  169. package/dist/client/method.d.ts +6 -0
  170. package/dist/client/method.d.ts.map +1 -0
  171. package/dist/client/method.js +52 -0
  172. package/dist/client/method.js.map +1 -0
  173. package/dist/client/renderApp.d.ts +9 -0
  174. package/dist/client/renderApp.d.ts.map +1 -0
  175. package/dist/client/renderApp.js +28 -0
  176. package/dist/client/renderApp.js.map +1 -0
  177. package/dist/client/session.d.ts +34 -0
  178. package/dist/client/session.d.ts.map +1 -0
  179. package/dist/client/session.js +83 -0
  180. package/dist/client/session.js.map +1 -0
  181. package/dist/client.d.ts +10 -133
  182. package/dist/client.d.ts.map +1 -0
  183. package/dist/client.js +14 -1
  184. package/dist/client.js.map +1 -1
  185. package/dist/config/client.d.ts +10 -0
  186. package/dist/config/client.d.ts.map +1 -0
  187. package/dist/config/client.js +14 -0
  188. package/dist/config/client.js.map +1 -0
  189. package/dist/config/server.d.ts +48 -0
  190. package/dist/config/server.d.ts.map +1 -0
  191. package/dist/config/server.js +85 -0
  192. package/dist/config/server.js.map +1 -0
  193. package/dist/config/sync.d.ts +2 -0
  194. package/dist/config/sync.d.ts.map +1 -0
  195. package/dist/config/sync.js +32 -0
  196. package/dist/config/sync.js.map +1 -0
  197. package/dist/config/types.d.ts +19 -0
  198. package/dist/config/types.d.ts.map +1 -0
  199. package/dist/config/types.js +2 -0
  200. package/dist/config/types.js.map +1 -0
  201. package/dist/cron/jobs.d.ts +13 -0
  202. package/dist/cron/jobs.d.ts.map +1 -0
  203. package/dist/cron/jobs.js +155 -0
  204. package/dist/cron/jobs.js.map +1 -0
  205. package/dist/cron/types.d.ts +29 -0
  206. package/dist/cron/types.d.ts.map +1 -0
  207. package/dist/cron/types.js +2 -0
  208. package/dist/cron/types.js.map +1 -0
  209. package/dist/data/schemaSerializer.d.ts +37 -0
  210. package/dist/data/schemaSerializer.d.ts.map +1 -0
  211. package/dist/data/schemaSerializer.js +104 -0
  212. package/dist/data/schemaSerializer.js.map +1 -0
  213. package/dist/{types-WgRbQ-tj.d.ts → data/store.d.ts} +13 -231
  214. package/dist/data/store.d.ts.map +1 -0
  215. package/dist/data/store.js +501 -0
  216. package/dist/data/store.js.map +1 -0
  217. package/dist/data/types.d.ts +47 -0
  218. package/dist/data/types.d.ts.map +1 -0
  219. package/dist/data/types.js +35 -0
  220. package/dist/data/types.js.map +1 -0
  221. package/dist/db/client.d.ts +5 -0
  222. package/dist/db/client.d.ts.map +1 -0
  223. package/dist/db/client.js +41 -0
  224. package/dist/db/client.js.map +1 -0
  225. package/dist/error.d.ts +16 -0
  226. package/dist/error.d.ts.map +1 -0
  227. package/dist/error.js +24 -0
  228. package/dist/error.js.map +1 -0
  229. package/dist/index.d.ts +6 -31
  230. package/dist/index.d.ts.map +1 -0
  231. package/dist/index.js +2 -1
  232. package/dist/index.js.map +1 -1
  233. package/dist/lock/db.d.ts +19 -0
  234. package/dist/lock/db.d.ts.map +1 -0
  235. package/dist/lock/db.js +28 -0
  236. package/dist/lock/db.js.map +1 -0
  237. package/dist/lock/helpers.d.ts +28 -0
  238. package/dist/lock/helpers.d.ts.map +1 -0
  239. package/dist/lock/helpers.js +107 -0
  240. package/dist/lock/helpers.js.map +1 -0
  241. package/dist/lock/index.d.ts +4 -0
  242. package/dist/lock/index.d.ts.map +1 -0
  243. package/dist/lock/index.js +4 -0
  244. package/dist/lock/index.js.map +1 -0
  245. package/dist/lock/module.d.ts +7 -0
  246. package/dist/lock/module.d.ts.map +1 -0
  247. package/dist/lock/module.js +9 -0
  248. package/dist/lock/module.js.map +1 -0
  249. package/dist/methods/index.d.ts +7 -0
  250. package/dist/methods/index.d.ts.map +1 -0
  251. package/dist/methods/index.js +65 -0
  252. package/dist/methods/index.js.map +1 -0
  253. package/dist/methods/serialize.d.ts +15 -0
  254. package/dist/methods/serialize.d.ts.map +1 -0
  255. package/dist/methods/serialize.js +56 -0
  256. package/dist/methods/serialize.js.map +1 -0
  257. package/dist/methods/types.d.ts +37 -0
  258. package/dist/methods/types.d.ts.map +1 -0
  259. package/dist/methods/types.js +2 -0
  260. package/dist/methods/types.js.map +1 -0
  261. package/dist/migration/db.d.ts +17 -0
  262. package/dist/migration/db.d.ts.map +1 -0
  263. package/dist/migration/db.js +13 -0
  264. package/dist/migration/db.js.map +1 -0
  265. package/dist/migration/index.d.ts +11 -0
  266. package/dist/migration/index.d.ts.map +1 -0
  267. package/dist/migration/index.js +85 -0
  268. package/dist/migration/index.js.map +1 -0
  269. package/dist/mongo.d.ts +2 -3
  270. package/dist/mongo.d.ts.map +1 -0
  271. package/dist/mongo.js +2 -1
  272. package/dist/mongo.js.map +1 -1
  273. package/dist/rate-limit/db.d.ts +29 -0
  274. package/dist/rate-limit/db.d.ts.map +1 -0
  275. package/dist/rate-limit/db.js +25 -0
  276. package/dist/rate-limit/db.js.map +1 -0
  277. package/dist/rate-limit/index.d.ts +4 -0
  278. package/dist/rate-limit/index.d.ts.map +1 -0
  279. package/dist/rate-limit/index.js +6 -0
  280. package/dist/rate-limit/index.js.map +1 -0
  281. package/dist/rate-limit/rules.d.ts +22 -0
  282. package/dist/rate-limit/rules.d.ts.map +1 -0
  283. package/dist/rate-limit/rules.js +112 -0
  284. package/dist/rate-limit/rules.js.map +1 -0
  285. package/dist/rate-limit/types.d.ts +12 -0
  286. package/dist/rate-limit/types.d.ts.map +1 -0
  287. package/dist/rate-limit/types.js +2 -0
  288. package/dist/rate-limit/types.js.map +1 -0
  289. package/dist/routes/handler.d.ts +4 -0
  290. package/dist/routes/handler.d.ts.map +1 -0
  291. package/dist/routes/handler.js +66 -0
  292. package/dist/routes/handler.js.map +1 -0
  293. package/dist/routes/types.d.ts +45 -0
  294. package/dist/routes/types.d.ts.map +1 -0
  295. package/dist/routes/types.js +2 -0
  296. package/dist/routes/types.js.map +1 -0
  297. package/dist/server.d.ts +19 -551
  298. package/dist/server.d.ts.map +1 -0
  299. package/dist/server.js +15 -18
  300. package/dist/server.js.map +1 -1
  301. package/dist/system/index.d.ts +4 -0
  302. package/dist/system/index.d.ts.map +1 -0
  303. package/dist/system/index.js +21 -0
  304. package/dist/system/index.js.map +1 -0
  305. package/dist/telemetry/index.d.ts +11 -0
  306. package/dist/telemetry/index.d.ts.map +1 -0
  307. package/dist/telemetry/index.js +79 -0
  308. package/dist/telemetry/index.js.map +1 -0
  309. package/dist/telemetry.d.ts +2 -11
  310. package/dist/telemetry.d.ts.map +1 -0
  311. package/dist/telemetry.js +1 -1
  312. package/dist/telemetry.js.map +1 -1
  313. package/dist/time.d.ts +8 -0
  314. package/dist/time.d.ts.map +1 -0
  315. package/dist/time.js +13 -0
  316. package/dist/time.js.map +1 -0
  317. package/dist/types/email.d.ts +25 -0
  318. package/dist/types/email.d.ts.map +1 -0
  319. package/dist/types/email.js +2 -0
  320. package/dist/types/email.js.map +1 -0
  321. package/dist/types/index.d.ts +14 -0
  322. package/dist/types/index.d.ts.map +1 -0
  323. package/dist/types/index.js +2 -0
  324. package/dist/types/index.js.map +1 -0
  325. package/dist/types.d.ts +10 -7
  326. package/dist/types.d.ts.map +1 -0
  327. package/dist/types.js +1 -1
  328. package/dist/types.js.map +1 -1
  329. package/dist/utils/index.d.ts +4 -0
  330. package/dist/utils/index.d.ts.map +1 -0
  331. package/dist/utils/index.js +15 -0
  332. package/dist/utils/index.js.map +1 -0
  333. package/dist/viteServer.d.ts +13 -0
  334. package/dist/viteServer.d.ts.map +1 -0
  335. package/dist/viteServer.js +132 -0
  336. package/dist/viteServer.js.map +1 -0
  337. package/dist/websocket/client.d.ts +9 -0
  338. package/dist/websocket/client.d.ts.map +1 -0
  339. package/dist/websocket/client.js +16 -0
  340. package/dist/websocket/client.js.map +1 -0
  341. package/dist/websocket/clientChannel.d.ts +9 -0
  342. package/dist/websocket/clientChannel.d.ts.map +1 -0
  343. package/dist/websocket/clientChannel.js +26 -0
  344. package/dist/websocket/clientChannel.js.map +1 -0
  345. package/dist/websocket/serverChannel.d.ts +14 -0
  346. package/dist/websocket/serverChannel.d.ts.map +1 -0
  347. package/dist/websocket/serverChannel.js +21 -0
  348. package/dist/websocket/serverChannel.js.map +1 -0
  349. package/dist/websocket/socketio/client.d.ts +4 -0
  350. package/dist/websocket/socketio/client.d.ts.map +1 -0
  351. package/dist/websocket/socketio/client.js +48 -0
  352. package/dist/websocket/socketio/client.js.map +1 -0
  353. package/dist/websocket/socketio/server.d.ts +10 -0
  354. package/dist/websocket/socketio/server.d.ts.map +1 -0
  355. package/dist/websocket/socketio/server.js +80 -0
  356. package/dist/websocket/socketio/server.js.map +1 -0
  357. package/dist/websocket/types.d.ts +45 -0
  358. package/dist/websocket/types.d.ts.map +1 -0
  359. package/dist/websocket/types.js +2 -0
  360. package/dist/websocket/types.js.map +1 -0
  361. package/package.json +5 -6
  362. package/dist/chunk-3S2FFBNS.js +0 -2
  363. package/dist/chunk-3S2FFBNS.js.map +0 -1
  364. package/dist/chunk-55J6XMHW.js +0 -2
  365. package/dist/chunk-55J6XMHW.js.map +0 -1
  366. package/dist/chunk-C3UESBRX.js +0 -2
  367. package/dist/chunk-C3UESBRX.js.map +0 -1
  368. package/dist/chunk-DO5TZLF5.js +0 -2
  369. package/dist/chunk-DO5TZLF5.js.map +0 -1
  370. package/dist/chunk-KUL6YKKP.js +0 -3
  371. package/dist/chunk-KUL6YKKP.js.map +0 -1
  372. package/dist/chunk-PB6WQQ4L.js +0 -3
  373. package/dist/chunk-PB6WQQ4L.js.map +0 -1
  374. package/dist/index-CwdohC5n.d.ts +0 -15
  375. package/dist/package-IIELPLTY.js +0 -2
  376. package/dist/package-IIELPLTY.js.map +0 -1
  377. package/dist/types-Ds1ESQSs.d.ts +0 -106
@@ -0,0 +1,100 @@
1
+ import { z } from 'zod';
2
+ import { usersCollection } from './db';
3
+ import { clearSessionUser, setSessionUser } from './session';
4
+ import { sendVerificationEmail } from './verification';
5
+ import { getEmailConfig } from '../app/emailConfig';
6
+ import { consumeRateLimit } from '../server';
7
+ import { validateEmail } from './validators';
8
+ import { getAuthConfig } from '../app/authConfig';
9
+ import { comparePassword } from './password';
10
+ export async function handleLoginWithPassword(args, { user, session, connectionInfo }) {
11
+ try {
12
+ if (!session) {
13
+ throw new Error('Session is not initialized');
14
+ }
15
+ const ip = connectionInfo?.ip;
16
+ if (ip) {
17
+ await consumeRateLimit({
18
+ bucket: 'signin',
19
+ type: 'ip',
20
+ value: ip,
21
+ });
22
+ }
23
+ const email = validateEmail(args.email);
24
+ // password is accepted just as a string, so users can still sign in if the password validation rules are changed
25
+ const password = z.string().parse(args.password);
26
+ // TODO: add rate limiting by email (and perhaps IP address overall)
27
+ if (user) {
28
+ // TODO: handle cases where a user is already logged in
29
+ }
30
+ const userDoc = await usersCollection.findOne({ 'emails.address': email, status: { $nin: ['deleted', 'disabled'] } }, { collation: { locale: 'en', strength: 2 } });
31
+ const passwordHash = userDoc?.authMethods?.password?.hash;
32
+ if (!passwordHash) {
33
+ throw incorrectCredentialsError();
34
+ }
35
+ const emailDoc = userDoc.emails?.find((e) => e.address === email);
36
+ if (!emailDoc?.verified && getEmailConfig()?.provider) {
37
+ if (ip) {
38
+ try {
39
+ await consumeRateLimit({
40
+ bucket: 'verification',
41
+ type: 'user',
42
+ value: userDoc._id.toString(),
43
+ });
44
+ }
45
+ catch {
46
+ throw new Error("Your email address hasn't been verified yet. Please use the verification email we've send earlier to your inbox.");
47
+ }
48
+ }
49
+ await sendVerificationEmail({
50
+ userId: userDoc?._id,
51
+ email,
52
+ baseUrl: connectionInfo?.baseUrl,
53
+ });
54
+ throw new Error("Your email address hasn't been verified yet. We've sent a new verification email to your inbox.");
55
+ }
56
+ const isValidPassword = await comparePassword(password, passwordHash);
57
+ if (!isValidPassword) {
58
+ throw incorrectCredentialsError();
59
+ }
60
+ await setSessionUser(session.authToken, userDoc._id);
61
+ getAuthConfig().onAfterLogin?.({
62
+ user: userDoc,
63
+ session,
64
+ connectionInfo,
65
+ });
66
+ getAuthConfig().login?.onSuccess?.(userDoc);
67
+ return {
68
+ user: {
69
+ id: userDoc._id,
70
+ handle: userDoc.handle,
71
+ },
72
+ };
73
+ }
74
+ catch (error) {
75
+ if (error instanceof Error) {
76
+ getAuthConfig().onLoginError?.({
77
+ error,
78
+ session,
79
+ connectionInfo,
80
+ });
81
+ getAuthConfig().login?.onError?.(error);
82
+ }
83
+ throw error;
84
+ }
85
+ }
86
+ export async function handleLogout(args, { session }) {
87
+ if (!session) {
88
+ throw new Error('Session is not initialized');
89
+ }
90
+ await clearSessionUser(session.authToken);
91
+ }
92
+ /*
93
+ It is important to return the same exact error both in case the email
94
+ or password is incorrect so that the client cannot tell the difference,
95
+ otherwise it would allow for an enumeration attack.
96
+ */
97
+ function incorrectCredentialsError() {
98
+ return new Error('Incorrect email/password combination');
99
+ }
100
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Hash a password using Node.js native crypto scrypt algorithm
3
+ * @param password - The password to hash
4
+ * @returns A string containing the salt and hash separated by a colon
5
+ */
6
+ export declare function hashPassword(password: string): Promise<string>;
7
+ /**
8
+ * Compare a password with a hash
9
+ * @param password - The password to check
10
+ * @param hash - The hash to compare against (format: "salt:hash")
11
+ * @returns True if the password matches the hash
12
+ */
13
+ export declare function comparePassword(password: string, hash: string): Promise<boolean>;
14
+ //# sourceMappingURL=password.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpE;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKtF"}
@@ -0,0 +1,26 @@
1
+ import { scrypt, randomBytes, timingSafeEqual } from 'crypto';
2
+ import { promisify } from 'util';
3
+ const scryptAsync = promisify(scrypt);
4
+ /**
5
+ * Hash a password using Node.js native crypto scrypt algorithm
6
+ * @param password - The password to hash
7
+ * @returns A string containing the salt and hash separated by a colon
8
+ */
9
+ export async function hashPassword(password) {
10
+ const salt = randomBytes(16).toString('hex');
11
+ const derivedKey = (await scryptAsync(password, salt, 64));
12
+ return `${salt}:${derivedKey.toString('hex')}`;
13
+ }
14
+ /**
15
+ * Compare a password with a hash
16
+ * @param password - The password to check
17
+ * @param hash - The hash to compare against (format: "salt:hash")
18
+ * @returns True if the password matches the hash
19
+ */
20
+ export async function comparePassword(password, hash) {
21
+ const [salt, key] = hash.split(':');
22
+ const keyBuffer = Buffer.from(key, 'hex');
23
+ const derivedKey = (await scryptAsync(password, salt, 64));
24
+ return timingSafeEqual(keyBuffer, derivedKey);
25
+ }
26
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,CAAC,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAW,CAAC;IACrE,OAAO,GAAG,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAY;IAClE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,CAAC,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAW,CAAC;IACrE,OAAO,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Args, Context } from '../methods/types';
2
+ export declare function getOwnProfile(_args: Args, { user }: Context): Promise<{
3
+ handle: string;
4
+ emails: {
5
+ address: string;
6
+ verified: boolean;
7
+ }[] | undefined;
8
+ authMethods: string[];
9
+ }>;
10
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/auth/profile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAsB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO;;;;;;;GAYjE"}
@@ -0,0 +1,13 @@
1
+ import { usersCollection } from './db';
2
+ export async function getOwnProfile(_args, { user }) {
3
+ if (!user) {
4
+ throw new Error('Not authenticated');
5
+ }
6
+ const profile = await usersCollection.requireById(user.id);
7
+ return {
8
+ handle: profile.handle,
9
+ emails: profile.emails,
10
+ authMethods: Object.keys(profile.authMethods || {}),
11
+ };
12
+ }
13
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/auth/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAW,EAAE,EAAE,IAAI,EAAW;IAChE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE3D,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare function getRouter(): import("express-serve-static-core").Router;
2
+ export default getRouter;
3
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"AA6HA,iBAAS,SAAS,+CA2DjB;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { getConfig } from '../../server';
2
+ import { time } from '../../time';
3
+ import { randomBytes } from 'crypto';
4
+ import { Router } from 'express';
5
+ import { getRedirectUri, handleOAuthUserAuthentication, validateOAuthCode, } from './oauth-common';
6
+ async function exchangeCodeForToken(code, clientId, clientSecret, redirectUri) {
7
+ const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
8
+ method: 'POST',
9
+ headers: {
10
+ 'Content-Type': 'application/json',
11
+ Accept: 'application/json',
12
+ },
13
+ body: JSON.stringify({
14
+ client_id: clientId,
15
+ client_secret: clientSecret,
16
+ code,
17
+ redirect_uri: redirectUri,
18
+ }),
19
+ });
20
+ if (!tokenResponse.ok) {
21
+ throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);
22
+ }
23
+ return tokenResponse.json();
24
+ }
25
+ async function fetchGitHubUserInfo(accessToken) {
26
+ const userInfoResponse = await fetch('https://api.github.com/user', {
27
+ headers: {
28
+ Authorization: `Bearer ${accessToken}`,
29
+ Accept: 'application/vnd.github.v3+json',
30
+ },
31
+ });
32
+ if (!userInfoResponse.ok) {
33
+ throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);
34
+ }
35
+ return userInfoResponse.json();
36
+ }
37
+ async function handleGitHubAuthenticationCallback(req, res) {
38
+ const code = validateOAuthCode(req.query.code);
39
+ const state = req.query.state;
40
+ const storedState = req.cookies.authStateGithub;
41
+ if (!code) {
42
+ res.status(400).json({ error: 'Missing authorization code' });
43
+ return;
44
+ }
45
+ if (!state || !storedState || state !== storedState) {
46
+ res.status(400).json({ error: 'Invalid OAuth state - possible CSRF attack' });
47
+ return;
48
+ }
49
+ res.clearCookie('authStateGithub');
50
+ const githubClientId = String(getConfig('_system.user.auth.github.clientId'));
51
+ const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));
52
+ const redirectUri = getRedirectUri('github');
53
+ try {
54
+ // Exchange code for access token
55
+ const tokenData = await exchangeCodeForToken(code, githubClientId, githubClientSecret, redirectUri);
56
+ // Fetch user info
57
+ const githubUser = await fetchGitHubUserInfo(tokenData.access_token);
58
+ // Use the public email from user profile
59
+ const githubEmail = githubUser.email || '';
60
+ if (!githubEmail) {
61
+ res.status(400).json({
62
+ error: 'Unable to retrieve email from GitHub. Please ensure your email is public or grant email permissions.',
63
+ });
64
+ return;
65
+ }
66
+ const userData = {
67
+ id: String(githubUser.id),
68
+ email: githubEmail,
69
+ emailVerified: true, // Assume public email is verified
70
+ providerName: 'github',
71
+ };
72
+ await handleOAuthUserAuthentication(req, res, userData);
73
+ }
74
+ catch (error) {
75
+ console.error('GitHub OAuth error:', error);
76
+ res.status(500).json({ error: 'Authentication failed' });
77
+ }
78
+ }
79
+ function getRouter() {
80
+ const githubAuthRouter = Router();
81
+ // Middleware to check if GitHub auth is enabled and configured
82
+ const checkGitHubEnabled = (_req, res, next) => {
83
+ const githubEnabled = Boolean(getConfig('_system.user.auth.github.enabled'));
84
+ const githubClientId = String(getConfig('_system.user.auth.github.clientId'));
85
+ const githubClientSecret = String(getConfig('_system.user.auth.github.clientSecret'));
86
+ if (!githubEnabled || !githubClientId || !githubClientSecret) {
87
+ res.status(503).json({ error: 'GitHub authentication is not configured' });
88
+ return;
89
+ }
90
+ next();
91
+ };
92
+ // Initiate OAuth flow
93
+ githubAuthRouter.get('/api/_internal/auth/github', checkGitHubEnabled, (req, res) => {
94
+ const githubClientId = String(getConfig('_system.user.auth.github.clientId'));
95
+ const redirectUri = getRedirectUri('github');
96
+ const githubScopes = getConfig('_system.user.auth.github.scopes');
97
+ const scopes = githubScopes
98
+ ? String(githubScopes)
99
+ .split(',')
100
+ .map((s) => s.trim())
101
+ .join(' ')
102
+ : 'user:email';
103
+ const state = randomBytes(32).toString('hex');
104
+ res.cookie('authStateGithub', state, {
105
+ httpOnly: true,
106
+ secure: process.env.NODE_ENV === 'production',
107
+ sameSite: 'lax',
108
+ maxAge: time.minutes(10), // 10 minutes
109
+ });
110
+ const authUrl = new URL('https://github.com/login/oauth/authorize');
111
+ authUrl.searchParams.append('client_id', githubClientId);
112
+ authUrl.searchParams.append('redirect_uri', redirectUri);
113
+ authUrl.searchParams.append('scope', scopes);
114
+ authUrl.searchParams.append('state', state);
115
+ res.redirect(authUrl.toString());
116
+ });
117
+ // Handle OAuth callback
118
+ githubAuthRouter.get('/api/_internal/auth/github/callback', checkGitHubEnabled, handleGitHubAuthenticationCallback);
119
+ return githubAuthRouter;
120
+ }
121
+ export default getRouter;
122
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare function getRouter(): import("express-serve-static-core").Router;
2
+ export default getRouter;
3
+ //# sourceMappingURL=google.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"AAmHA,iBAAS,SAAS,+CAsDjB;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { getConfig } from '../../server';
2
+ import { time } from '../../time';
3
+ import { randomBytes } from 'crypto';
4
+ import { Router } from 'express';
5
+ import { getRedirectUri, handleOAuthUserAuthentication, validateOAuthCode, } from './oauth-common';
6
+ async function exchangeCodeForToken(code, clientId, clientSecret, redirectUri) {
7
+ const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
8
+ method: 'POST',
9
+ headers: {
10
+ 'Content-Type': 'application/x-www-form-urlencoded',
11
+ },
12
+ body: new URLSearchParams({
13
+ code,
14
+ client_id: clientId,
15
+ client_secret: clientSecret,
16
+ redirect_uri: redirectUri,
17
+ grant_type: 'authorization_code',
18
+ }),
19
+ });
20
+ if (!tokenResponse.ok) {
21
+ throw new Error(`Failed to exchange code for token: ${tokenResponse.statusText}`);
22
+ }
23
+ return tokenResponse.json();
24
+ }
25
+ async function fetchGoogleUserInfo(accessToken) {
26
+ const userInfoResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
27
+ headers: {
28
+ Authorization: `Bearer ${accessToken}`,
29
+ },
30
+ });
31
+ if (!userInfoResponse.ok) {
32
+ throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);
33
+ }
34
+ return userInfoResponse.json();
35
+ }
36
+ async function handleGoogleAuthenticationCallback(req, res) {
37
+ const code = validateOAuthCode(req.query.code);
38
+ const state = req.query.state;
39
+ const storedState = req.cookies.authStateGoogle;
40
+ if (!code) {
41
+ res.status(400).json({ error: 'Missing authorization code' });
42
+ return;
43
+ }
44
+ if (!state || !storedState || state !== storedState) {
45
+ res.status(400).json({ error: 'Invalid OAuth state - possible CSRF attack' });
46
+ return;
47
+ }
48
+ res.clearCookie('authStateGoogle');
49
+ const googleClientId = String(getConfig('_system.user.auth.google.clientId'));
50
+ const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));
51
+ const redirectUri = getRedirectUri('google');
52
+ try {
53
+ // Exchange code for tokens
54
+ const tokenData = await exchangeCodeForToken(code, googleClientId, googleClientSecret, redirectUri);
55
+ // Fetch user info
56
+ const googleUser = await fetchGoogleUserInfo(tokenData.access_token);
57
+ const userData = {
58
+ id: googleUser.id,
59
+ email: googleUser.email,
60
+ emailVerified: googleUser.verified_email,
61
+ providerName: 'google',
62
+ };
63
+ await handleOAuthUserAuthentication(req, res, userData);
64
+ }
65
+ catch (error) {
66
+ console.error('Google OAuth error:', error);
67
+ res.status(500).json({ error: 'Authentication failed' });
68
+ }
69
+ }
70
+ function getRouter() {
71
+ const googleAuthRouter = Router();
72
+ // Middleware to check if Google auth is enabled and configured
73
+ const checkGoogleEnabled = (_req, res, next) => {
74
+ const googleEnabled = Boolean(getConfig('_system.user.auth.google.enabled'));
75
+ const googleClientId = String(getConfig('_system.user.auth.google.clientId'));
76
+ const googleClientSecret = String(getConfig('_system.user.auth.google.clientSecret'));
77
+ if (!googleEnabled || !googleClientId || !googleClientSecret) {
78
+ res.status(503).json({ error: 'Google authentication is not configured' });
79
+ return;
80
+ }
81
+ next();
82
+ };
83
+ // Initiate OAuth flow
84
+ googleAuthRouter.get('/api/_internal/auth/google', checkGoogleEnabled, (req, res) => {
85
+ const googleClientId = String(getConfig('_system.user.auth.google.clientId'));
86
+ const redirectUri = getRedirectUri('google');
87
+ const state = randomBytes(32).toString('hex');
88
+ res.cookie('authStateGoogle', state, {
89
+ httpOnly: true,
90
+ secure: process.env.NODE_ENV === 'production',
91
+ sameSite: 'lax',
92
+ maxAge: time.minutes(10), // 10 minutes
93
+ });
94
+ const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
95
+ authUrl.searchParams.append('client_id', googleClientId);
96
+ authUrl.searchParams.append('redirect_uri', redirectUri);
97
+ authUrl.searchParams.append('response_type', 'code');
98
+ authUrl.searchParams.append('scope', 'profile email');
99
+ authUrl.searchParams.append('access_type', 'online');
100
+ authUrl.searchParams.append('state', state);
101
+ res.redirect(authUrl.toString());
102
+ });
103
+ // Handle OAuth callback
104
+ googleAuthRouter.get('/api/_internal/auth/google/callback', checkGoogleEnabled, handleGoogleAuthenticationCallback);
105
+ return googleAuthRouter;
106
+ }
107
+ export default getRouter;
108
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type Request, type Response } from 'express';
2
+ import { ObjectId } from 'mongodb';
3
+ export interface OAuthUserData {
4
+ id: string;
5
+ email: string;
6
+ emailVerified: boolean;
7
+ providerName: 'google' | 'github';
8
+ }
9
+ export declare function authenticateUser(res: Response, userId: ObjectId): Promise<void>;
10
+ export declare function getRedirectUri(provider: string): string;
11
+ export declare function handleOAuthUserAuthentication(req: Request, res: Response, userData: OAuthUserData): Promise<void>;
12
+ export declare function validateOAuthCode(code: unknown): string | null;
13
+ //# sourceMappingURL=oauth-common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-common.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/oauth-common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAOnC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACnC;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,iBAUrE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAsB,6BAA6B,CACjD,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAqGf;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK9D"}
@@ -0,0 +1,109 @@
1
+ import { usersCollection } from '../../auth/db';
2
+ import { createSession } from '../../auth/session';
3
+ import { getAuthConfig } from '../../app/authConfig';
4
+ import { getCallContext } from '../../app/server';
5
+ import { getConfig } from '../../config/server';
6
+ export async function authenticateUser(res, userId) {
7
+ const { authToken } = await createSession(userId);
8
+ res.cookie('authToken', authToken, {
9
+ httpOnly: true,
10
+ secure: process.env.NODE_ENV === 'production',
11
+ sameSite: 'strict',
12
+ });
13
+ res.status(301);
14
+ res.redirect('/');
15
+ }
16
+ export function getRedirectUri(provider) {
17
+ return `${getConfig('_system.site.url')}/api/_internal/auth/${provider}/callback`;
18
+ }
19
+ export async function handleOAuthUserAuthentication(req, res, userData) {
20
+ const existingUser = await usersCollection.findOne({
21
+ [`authMethods.${userData.providerName}.id`]: userData.id,
22
+ });
23
+ const { session, connectionInfo } = await getCallContext(req);
24
+ try {
25
+ if (existingUser) {
26
+ await authenticateUser(res, existingUser._id);
27
+ getAuthConfig().onAfterLogin?.({
28
+ user: existingUser,
29
+ session,
30
+ connectionInfo,
31
+ });
32
+ getAuthConfig().login?.onSuccess?.(existingUser);
33
+ return;
34
+ }
35
+ }
36
+ catch (error) {
37
+ if (error instanceof Error) {
38
+ getAuthConfig().login?.onError?.(error);
39
+ getAuthConfig().onLoginError?.({
40
+ error,
41
+ session,
42
+ connectionInfo,
43
+ });
44
+ }
45
+ throw error;
46
+ }
47
+ try {
48
+ if (!userData.email) {
49
+ res.status(400).json({
50
+ error: `Email address is required for ${userData.providerName} authentication.`,
51
+ });
52
+ return;
53
+ }
54
+ const existingUserByEmail = await usersCollection.findOne({ 'emails.address': userData.email }, { collation: { locale: 'en', strength: 2 } });
55
+ // TODO: check if the email is verified
56
+ if (existingUserByEmail) {
57
+ // TODO: handle case with an HTML page
58
+ res.status(400).json({
59
+ error: 'User with this email already exists. Please log in instead.',
60
+ });
61
+ return;
62
+ }
63
+ // If the user does not exist, create a new user
64
+ const newUser = await usersCollection.insertOne({
65
+ handle: userData.email,
66
+ status: 'active',
67
+ emails: [
68
+ {
69
+ address: userData.email,
70
+ verified: userData.emailVerified,
71
+ },
72
+ ],
73
+ createdAt: new Date(),
74
+ authMethods: {
75
+ [userData.providerName]: {
76
+ id: userData.id,
77
+ },
78
+ },
79
+ });
80
+ await authenticateUser(res, newUser.insertedId);
81
+ const userDocument = await usersCollection.findOne({ _id: newUser.insertedId }, { readPreference: 'primary' });
82
+ if (userDocument) {
83
+ getAuthConfig().onAfterSignup?.({
84
+ user: userDocument,
85
+ session,
86
+ connectionInfo,
87
+ });
88
+ getAuthConfig().signup?.onSuccess?.(userDocument);
89
+ }
90
+ }
91
+ catch (error) {
92
+ if (error instanceof Error) {
93
+ getAuthConfig().onSignupError?.({
94
+ error,
95
+ session,
96
+ connectionInfo,
97
+ });
98
+ getAuthConfig().signup?.onError?.(error);
99
+ }
100
+ throw error;
101
+ }
102
+ }
103
+ export function validateOAuthCode(code) {
104
+ if (!code || typeof code !== 'string') {
105
+ return null;
106
+ }
107
+ return code;
108
+ }
109
+ //# sourceMappingURL=oauth-common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-common.js","sourceRoot":"","sources":["../../../src/auth/providers/oauth-common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Args, Context } from '../methods/types';
2
+ export declare function handleSendResetPasswordToken(args: Args, { connectionInfo }: Context): Promise<{
3
+ success: boolean;
4
+ message: string;
5
+ }>;
6
+ export declare function handleResetPassword(args: Args, {}: Context): Promise<{
7
+ success: boolean;
8
+ message: string;
9
+ }>;
10
+ //# sourceMappingURL=resetPassword.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resetPassword.d.ts","sourceRoot":"","sources":["../../src/auth/resetPassword.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAqChD,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,EAAE,OAAO;;;GAyDzF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO;;;GAuChE"}