@digitaldefiance/node-express-suite 1.0.23 → 1.0.24

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 (629) hide show
  1. package/README.md +4 -0
  2. package/package.json +8 -7
  3. package/src/application-base.d.ts +112 -0
  4. package/src/application-base.d.ts.map +1 -0
  5. package/src/application-base.js +335 -0
  6. package/src/application-base.js.map +1 -0
  7. package/src/application.d.ts +20 -0
  8. package/src/application.d.ts.map +1 -0
  9. package/src/application.js +124 -0
  10. package/src/application.js.map +1 -0
  11. package/src/backup-code.d.ts +67 -0
  12. package/src/backup-code.d.ts.map +1 -0
  13. package/src/backup-code.js +238 -0
  14. package/src/backup-code.js.map +1 -0
  15. package/src/constants.d.ts +16 -0
  16. package/src/constants.d.ts.map +1 -0
  17. package/src/constants.js +54 -0
  18. package/src/constants.js.map +1 -0
  19. package/src/controllers/base.d.ts +63 -0
  20. package/src/controllers/base.d.ts.map +1 -0
  21. package/src/controllers/base.js +272 -0
  22. package/src/controllers/base.js.map +1 -0
  23. package/src/controllers/{index.ts → index.d.ts} +1 -0
  24. package/src/controllers/index.d.ts.map +1 -0
  25. package/src/controllers/index.js +6 -0
  26. package/src/controllers/index.js.map +1 -0
  27. package/src/controllers/user.d.ts +45 -0
  28. package/src/controllers/user.d.ts.map +1 -0
  29. package/src/controllers/user.js +748 -0
  30. package/src/controllers/user.js.map +1 -0
  31. package/src/decorators/base-controller.d.ts +14 -0
  32. package/src/decorators/base-controller.d.ts.map +1 -0
  33. package/src/decorators/base-controller.js +49 -0
  34. package/src/decorators/base-controller.js.map +1 -0
  35. package/src/decorators/controller.d.ts +32 -0
  36. package/src/decorators/controller.d.ts.map +1 -0
  37. package/src/decorators/controller.js +67 -0
  38. package/src/decorators/controller.js.map +1 -0
  39. package/src/decorators/{index.ts → index.d.ts} +1 -0
  40. package/src/decorators/index.d.ts.map +1 -0
  41. package/src/decorators/index.js +7 -0
  42. package/src/decorators/index.js.map +1 -0
  43. package/src/decorators/zod-validation.d.ts +5 -0
  44. package/src/decorators/zod-validation.d.ts.map +1 -0
  45. package/src/decorators/zod-validation.js +47 -0
  46. package/src/decorators/zod-validation.js.map +1 -0
  47. package/src/defaults.d.ts +7 -0
  48. package/src/defaults.d.ts.map +1 -0
  49. package/src/defaults.js +83 -0
  50. package/src/defaults.js.map +1 -0
  51. package/src/documents/base.d.ts +3 -0
  52. package/src/documents/base.d.ts.map +1 -0
  53. package/src/documents/base.js +3 -0
  54. package/src/documents/base.js.map +1 -0
  55. package/src/documents/email-token.d.ts +8 -0
  56. package/src/documents/email-token.d.ts.map +1 -0
  57. package/src/documents/email-token.js +3 -0
  58. package/src/documents/email-token.js.map +1 -0
  59. package/src/documents/{index.ts → index.d.ts} +1 -0
  60. package/src/documents/index.d.ts.map +1 -0
  61. package/src/documents/index.js +3 -0
  62. package/src/documents/index.js.map +1 -0
  63. package/src/documents/{mnemonic.ts → mnemonic.d.ts} +2 -5
  64. package/src/documents/mnemonic.d.ts.map +1 -0
  65. package/src/documents/mnemonic.js +3 -0
  66. package/src/documents/mnemonic.js.map +1 -0
  67. package/src/documents/{role.ts → role.d.ts} +2 -5
  68. package/src/documents/role.d.ts.map +1 -0
  69. package/src/documents/role.js +3 -0
  70. package/src/documents/role.js.map +1 -0
  71. package/src/documents/used-direct-login-token.d.ts +5 -0
  72. package/src/documents/used-direct-login-token.d.ts.map +1 -0
  73. package/src/documents/used-direct-login-token.js +3 -0
  74. package/src/documents/used-direct-login-token.js.map +1 -0
  75. package/src/documents/{user-role.ts → user-role.d.ts} +2 -5
  76. package/src/documents/user-role.d.ts.map +1 -0
  77. package/src/documents/user-role.js +3 -0
  78. package/src/documents/user-role.js.map +1 -0
  79. package/src/documents/{user.ts → user.d.ts} +2 -4
  80. package/src/documents/user.d.ts.map +1 -0
  81. package/src/documents/user.js +3 -0
  82. package/src/documents/user.js.map +1 -0
  83. package/src/enumerations/base-model-name.d.ts +38 -0
  84. package/src/enumerations/base-model-name.d.ts.map +1 -0
  85. package/src/enumerations/base-model-name.js +34 -0
  86. package/src/enumerations/base-model-name.js.map +1 -0
  87. package/src/enumerations/{index.ts → index.d.ts} +1 -0
  88. package/src/enumerations/index.d.ts.map +1 -0
  89. package/src/enumerations/index.js +8 -0
  90. package/src/enumerations/index.js.map +1 -0
  91. package/src/enumerations/length-encoding-type.d.ts +7 -0
  92. package/src/enumerations/length-encoding-type.d.ts.map +1 -0
  93. package/src/enumerations/length-encoding-type.js +11 -0
  94. package/src/enumerations/length-encoding-type.js.map +1 -0
  95. package/src/enumerations/schema-collection.d.ts +34 -0
  96. package/src/enumerations/schema-collection.d.ts.map +1 -0
  97. package/src/enumerations/schema-collection.js +38 -0
  98. package/src/enumerations/schema-collection.js.map +1 -0
  99. package/src/enumerations/symmetric-error-type.d.ts +5 -0
  100. package/src/enumerations/symmetric-error-type.d.ts.map +1 -0
  101. package/src/enumerations/symmetric-error-type.js +9 -0
  102. package/src/enumerations/symmetric-error-type.js.map +1 -0
  103. package/src/environment.d.ts +189 -0
  104. package/src/environment.d.ts.map +1 -0
  105. package/src/environment.js +620 -0
  106. package/src/environment.js.map +1 -0
  107. package/src/errors/express-validation.d.ts +9 -0
  108. package/src/errors/express-validation.d.ts.map +1 -0
  109. package/src/errors/express-validation.js +18 -0
  110. package/src/errors/express-validation.js.map +1 -0
  111. package/src/errors/{index.ts → index.d.ts} +1 -0
  112. package/src/errors/index.d.ts.map +1 -0
  113. package/src/errors/index.js +16 -0
  114. package/src/errors/index.js.map +1 -0
  115. package/src/errors/invalid-backup-code-version.d.ts +6 -0
  116. package/src/errors/invalid-backup-code-version.d.ts.map +1 -0
  117. package/src/errors/invalid-backup-code-version.js +15 -0
  118. package/src/errors/invalid-backup-code-version.js.map +1 -0
  119. package/src/errors/invalid-jwt-token.d.ts +5 -0
  120. package/src/errors/invalid-jwt-token.d.ts.map +1 -0
  121. package/src/errors/invalid-jwt-token.js +11 -0
  122. package/src/errors/invalid-jwt-token.js.map +1 -0
  123. package/src/errors/invalid-model.d.ts +6 -0
  124. package/src/errors/invalid-model.d.ts.map +1 -0
  125. package/src/errors/invalid-model.js +14 -0
  126. package/src/errors/invalid-model.js.map +1 -0
  127. package/src/errors/invalid-new-password.d.ts +5 -0
  128. package/src/errors/invalid-new-password.d.ts.map +1 -0
  129. package/src/errors/invalid-new-password.js +14 -0
  130. package/src/errors/invalid-new-password.js.map +1 -0
  131. package/src/errors/invalid-password.d.ts +5 -0
  132. package/src/errors/invalid-password.d.ts.map +1 -0
  133. package/src/errors/invalid-password.js +14 -0
  134. package/src/errors/invalid-password.js.map +1 -0
  135. package/src/errors/missing-validated-data.d.ts +7 -0
  136. package/src/errors/missing-validated-data.d.ts.map +1 -0
  137. package/src/errors/missing-validated-data.js +36 -0
  138. package/src/errors/missing-validated-data.js.map +1 -0
  139. package/src/errors/mnemonic-or-password-required.d.ts +5 -0
  140. package/src/errors/mnemonic-or-password-required.d.ts.map +1 -0
  141. package/src/errors/mnemonic-or-password-required.js +13 -0
  142. package/src/errors/mnemonic-or-password-required.js.map +1 -0
  143. package/src/errors/model-not-registered.d.ts +5 -0
  144. package/src/errors/model-not-registered.d.ts.map +1 -0
  145. package/src/errors/model-not-registered.js +12 -0
  146. package/src/errors/model-not-registered.js.map +1 -0
  147. package/src/errors/mongoose-validation.d.ts +11 -0
  148. package/src/errors/mongoose-validation.d.ts.map +1 -0
  149. package/src/errors/mongoose-validation.js +17 -0
  150. package/src/errors/mongoose-validation.js.map +1 -0
  151. package/src/errors/symmetric.d.ts +8 -0
  152. package/src/errors/symmetric.d.ts.map +1 -0
  153. package/src/errors/symmetric.js +23 -0
  154. package/src/errors/symmetric.js.map +1 -0
  155. package/src/errors/token-expired.d.ts +5 -0
  156. package/src/errors/token-expired.d.ts.map +1 -0
  157. package/src/errors/token-expired.js +11 -0
  158. package/src/errors/token-expired.js.map +1 -0
  159. package/src/get-language.d.ts +2 -0
  160. package/src/get-language.d.ts.map +1 -0
  161. package/src/get-language.js +30 -0
  162. package/src/get-language.js.map +1 -0
  163. package/src/get-timezone.d.ts +3 -0
  164. package/src/get-timezone.d.ts.map +1 -0
  165. package/src/get-timezone.js +31 -0
  166. package/src/get-timezone.js.map +1 -0
  167. package/src/{index.ts → index.d.ts} +1 -1
  168. package/src/index.d.ts.map +1 -0
  169. package/src/index.js +28 -0
  170. package/src/index.js.map +1 -0
  171. package/src/interfaces/{api-error-response.ts → api-error-response.d.ts} +2 -2
  172. package/src/interfaces/api-error-response.d.ts.map +1 -0
  173. package/src/interfaces/api-error-response.js +3 -0
  174. package/src/interfaces/api-error-response.js.map +1 -0
  175. package/src/interfaces/api-express-validation-error-response.d.ts +7 -0
  176. package/src/interfaces/api-express-validation-error-response.d.ts.map +1 -0
  177. package/src/interfaces/api-express-validation-error-response.js +3 -0
  178. package/src/interfaces/api-express-validation-error-response.js.map +1 -0
  179. package/src/interfaces/api-message-response.d.ts +4 -0
  180. package/src/interfaces/api-message-response.d.ts.map +1 -0
  181. package/src/interfaces/api-message-response.js +3 -0
  182. package/src/interfaces/api-message-response.js.map +1 -0
  183. package/src/interfaces/{api-mongo-validation-error-response.ts → api-mongo-validation-error-response.d.ts} +2 -2
  184. package/src/interfaces/api-mongo-validation-error-response.d.ts.map +1 -0
  185. package/src/interfaces/api-mongo-validation-error-response.js +3 -0
  186. package/src/interfaces/api-mongo-validation-error-response.js.map +1 -0
  187. package/src/interfaces/api-responses/{backup-codes-response.ts → backup-codes-response.d.ts} +2 -2
  188. package/src/interfaces/api-responses/backup-codes-response.d.ts.map +1 -0
  189. package/src/interfaces/api-responses/backup-codes-response.js +3 -0
  190. package/src/interfaces/api-responses/backup-codes-response.js.map +1 -0
  191. package/src/interfaces/api-responses/{challenge-response.ts → challenge-response.d.ts} +3 -3
  192. package/src/interfaces/api-responses/challenge-response.d.ts.map +1 -0
  193. package/src/interfaces/api-responses/challenge-response.js +3 -0
  194. package/src/interfaces/api-responses/challenge-response.js.map +1 -0
  195. package/src/interfaces/api-responses/{code-count-response.ts → code-count-response.d.ts} +2 -2
  196. package/src/interfaces/api-responses/code-count-response.d.ts.map +1 -0
  197. package/src/interfaces/api-responses/code-count-response.js +3 -0
  198. package/src/interfaces/api-responses/code-count-response.js.map +1 -0
  199. package/src/interfaces/api-responses/{index.ts → index.d.ts} +1 -0
  200. package/src/interfaces/api-responses/index.d.ts.map +1 -0
  201. package/src/interfaces/api-responses/index.js +11 -0
  202. package/src/interfaces/api-responses/index.js.map +1 -0
  203. package/src/interfaces/api-responses/{login-response.ts → login-response.d.ts} +4 -4
  204. package/src/interfaces/api-responses/login-response.d.ts.map +1 -0
  205. package/src/interfaces/api-responses/login-response.js +3 -0
  206. package/src/interfaces/api-responses/login-response.js.map +1 -0
  207. package/src/interfaces/api-responses/{mnemonic-response.ts → mnemonic-response.d.ts} +2 -2
  208. package/src/interfaces/api-responses/mnemonic-response.d.ts.map +1 -0
  209. package/src/interfaces/api-responses/mnemonic-response.js +3 -0
  210. package/src/interfaces/api-responses/mnemonic-response.js.map +1 -0
  211. package/src/interfaces/api-responses/{registration-response.ts → registration-response.d.ts} +3 -3
  212. package/src/interfaces/api-responses/registration-response.d.ts.map +1 -0
  213. package/src/interfaces/api-responses/registration-response.js +3 -0
  214. package/src/interfaces/api-responses/registration-response.js.map +1 -0
  215. package/src/interfaces/api-responses/{request-user-response.ts → request-user-response.d.ts} +2 -2
  216. package/src/interfaces/api-responses/request-user-response.d.ts.map +1 -0
  217. package/src/interfaces/api-responses/request-user-response.js +3 -0
  218. package/src/interfaces/api-responses/request-user-response.js.map +1 -0
  219. package/src/interfaces/{application.ts → application.d.ts} +7 -7
  220. package/src/interfaces/application.d.ts.map +1 -0
  221. package/src/interfaces/application.js +3 -0
  222. package/src/interfaces/application.js.map +1 -0
  223. package/src/interfaces/backend-objects/email-token.d.ts +4 -0
  224. package/src/interfaces/backend-objects/email-token.d.ts.map +1 -0
  225. package/src/interfaces/backend-objects/email-token.js +3 -0
  226. package/src/interfaces/backend-objects/email-token.js.map +1 -0
  227. package/src/interfaces/backend-objects/{index.ts → index.d.ts} +1 -0
  228. package/src/interfaces/backend-objects/index.d.ts.map +1 -0
  229. package/src/interfaces/backend-objects/index.js +8 -0
  230. package/src/interfaces/backend-objects/index.js.map +1 -0
  231. package/src/interfaces/backend-objects/{request-user.ts → request-user.d.ts} +2 -7
  232. package/src/interfaces/backend-objects/request-user.d.ts.map +1 -0
  233. package/src/interfaces/backend-objects/request-user.js +3 -0
  234. package/src/interfaces/backend-objects/request-user.js.map +1 -0
  235. package/src/interfaces/backend-objects/{role.ts → role.d.ts} +1 -1
  236. package/src/interfaces/backend-objects/role.d.ts.map +1 -0
  237. package/src/interfaces/backend-objects/role.js +3 -0
  238. package/src/interfaces/backend-objects/role.js.map +1 -0
  239. package/src/interfaces/backend-objects/user.d.ts +4 -0
  240. package/src/interfaces/backend-objects/user.d.ts.map +1 -0
  241. package/src/interfaces/backend-objects/user.js +3 -0
  242. package/src/interfaces/backend-objects/user.js.map +1 -0
  243. package/src/interfaces/checksum-config.d.ts +5 -0
  244. package/src/interfaces/checksum-config.d.ts.map +1 -0
  245. package/src/interfaces/checksum-config.js +3 -0
  246. package/src/interfaces/checksum-config.js.map +1 -0
  247. package/src/interfaces/checksum-consts.d.ts +11 -0
  248. package/src/interfaces/checksum-consts.d.ts.map +1 -0
  249. package/src/interfaces/checksum-consts.js +3 -0
  250. package/src/interfaces/checksum-consts.js.map +1 -0
  251. package/src/interfaces/{constants.ts → constants.d.ts} +5 -5
  252. package/src/interfaces/constants.d.ts.map +1 -0
  253. package/src/interfaces/constants.js +3 -0
  254. package/src/interfaces/constants.js.map +1 -0
  255. package/src/interfaces/create-user-basics.d.ts +18 -0
  256. package/src/interfaces/create-user-basics.d.ts.map +1 -0
  257. package/src/interfaces/create-user-basics.js +3 -0
  258. package/src/interfaces/create-user-basics.js.map +1 -0
  259. package/src/interfaces/csp-config.d.ts +14 -0
  260. package/src/interfaces/csp-config.d.ts.map +1 -0
  261. package/src/interfaces/csp-config.js +3 -0
  262. package/src/interfaces/csp-config.js.map +1 -0
  263. package/src/interfaces/deep-partial.d.ts +4 -0
  264. package/src/interfaces/deep-partial.d.ts.map +1 -0
  265. package/src/interfaces/deep-partial.js +3 -0
  266. package/src/interfaces/deep-partial.js.map +1 -0
  267. package/src/interfaces/{discriminator-collections.ts → discriminator-collections.d.ts} +3 -3
  268. package/src/interfaces/discriminator-collections.d.ts.map +1 -0
  269. package/src/interfaces/discriminator-collections.js +3 -0
  270. package/src/interfaces/discriminator-collections.js.map +1 -0
  271. package/src/interfaces/email-service.d.ts +4 -0
  272. package/src/interfaces/email-service.d.ts.map +1 -0
  273. package/src/interfaces/email-service.js +3 -0
  274. package/src/interfaces/email-service.js.map +1 -0
  275. package/src/interfaces/environment-mongo.d.ts +76 -0
  276. package/src/interfaces/environment-mongo.d.ts.map +1 -0
  277. package/src/interfaces/environment-mongo.js +3 -0
  278. package/src/interfaces/environment-mongo.js.map +1 -0
  279. package/src/interfaces/environment.d.ts +181 -0
  280. package/src/interfaces/environment.d.ts.map +1 -0
  281. package/src/interfaces/environment.js +3 -0
  282. package/src/interfaces/environment.js.map +1 -0
  283. package/src/interfaces/failable-result.d.ts +7 -0
  284. package/src/interfaces/failable-result.d.ts.map +1 -0
  285. package/src/interfaces/failable-result.js +3 -0
  286. package/src/interfaces/failable-result.js.map +1 -0
  287. package/src/interfaces/fec-consts.d.ts +5 -0
  288. package/src/interfaces/fec-consts.d.ts.map +1 -0
  289. package/src/interfaces/fec-consts.js +3 -0
  290. package/src/interfaces/fec-consts.js.map +1 -0
  291. package/src/interfaces/handleable-error-options.d.ts +7 -0
  292. package/src/interfaces/handleable-error-options.d.ts.map +1 -0
  293. package/src/interfaces/handleable-error-options.js +3 -0
  294. package/src/interfaces/handleable-error-options.js.map +1 -0
  295. package/src/interfaces/{index.ts → index.d.ts} +1 -0
  296. package/src/interfaces/index.d.ts.map +1 -0
  297. package/src/interfaces/index.js +33 -0
  298. package/src/interfaces/index.js.map +1 -0
  299. package/src/interfaces/jwt-consts.d.ts +11 -0
  300. package/src/interfaces/jwt-consts.d.ts.map +1 -0
  301. package/src/interfaces/jwt-consts.js +3 -0
  302. package/src/interfaces/jwt-consts.js.map +1 -0
  303. package/src/interfaces/jwt-sign-response.d.ts +11 -0
  304. package/src/interfaces/jwt-sign-response.d.ts.map +1 -0
  305. package/src/interfaces/jwt-sign-response.js +3 -0
  306. package/src/interfaces/jwt-sign-response.js.map +1 -0
  307. package/src/interfaces/mongo-errors.d.ts +5 -0
  308. package/src/interfaces/mongo-errors.d.ts.map +1 -0
  309. package/src/interfaces/mongo-errors.js +3 -0
  310. package/src/interfaces/mongo-errors.js.map +1 -0
  311. package/src/interfaces/request-user.d.ts +42 -0
  312. package/src/interfaces/request-user.d.ts.map +1 -0
  313. package/src/interfaces/request-user.js +3 -0
  314. package/src/interfaces/request-user.js.map +1 -0
  315. package/src/interfaces/required-string-keys.d.ts +22 -0
  316. package/src/interfaces/required-string-keys.d.ts.map +1 -0
  317. package/src/interfaces/required-string-keys.js +3 -0
  318. package/src/interfaces/required-string-keys.js.map +1 -0
  319. package/src/interfaces/schema.d.ts +29 -0
  320. package/src/interfaces/schema.d.ts.map +1 -0
  321. package/src/interfaces/schema.js +3 -0
  322. package/src/interfaces/schema.js.map +1 -0
  323. package/src/interfaces/server-init-result.d.ts +35 -0
  324. package/src/interfaces/server-init-result.d.ts.map +1 -0
  325. package/src/interfaces/server-init-result.js +3 -0
  326. package/src/interfaces/server-init-result.js.map +1 -0
  327. package/src/interfaces/status-code-response.d.ts +7 -0
  328. package/src/interfaces/status-code-response.d.ts.map +1 -0
  329. package/src/interfaces/status-code-response.js +3 -0
  330. package/src/interfaces/status-code-response.js.map +1 -0
  331. package/src/interfaces/symmetric-encryption-results.d.ts +3 -3
  332. package/src/interfaces/symmetric-encryption-results.d.ts.map +1 -1
  333. package/src/interfaces/symmetric-encryption-results.js.map +1 -1
  334. package/src/interfaces/{token-response.ts → token-response.d.ts} +2 -2
  335. package/src/interfaces/token-response.d.ts.map +1 -0
  336. package/src/interfaces/token-response.js +3 -0
  337. package/src/interfaces/token-response.js.map +1 -0
  338. package/src/middlewares/authenticate-crypto.d.ts +13 -0
  339. package/src/middlewares/authenticate-crypto.d.ts.map +1 -0
  340. package/src/middlewares/authenticate-crypto.js +146 -0
  341. package/src/middlewares/authenticate-crypto.js.map +1 -0
  342. package/src/middlewares/authenticate-token.d.ts +24 -0
  343. package/src/middlewares/authenticate-token.d.ts.map +1 -0
  344. package/src/middlewares/authenticate-token.js +102 -0
  345. package/src/middlewares/authenticate-token.js.map +1 -0
  346. package/src/middlewares/cleanup-crypto.d.ts +7 -0
  347. package/src/middlewares/cleanup-crypto.d.ts.map +1 -0
  348. package/src/middlewares/cleanup-crypto.js +32 -0
  349. package/src/middlewares/cleanup-crypto.js.map +1 -0
  350. package/src/middlewares/{index.ts → index.d.ts} +1 -0
  351. package/src/middlewares/index.d.ts.map +1 -0
  352. package/src/middlewares/index.js +8 -0
  353. package/src/middlewares/index.js.map +1 -0
  354. package/src/middlewares/set-global-context-language.d.ts +3 -0
  355. package/src/middlewares/set-global-context-language.d.ts.map +1 -0
  356. package/src/middlewares/set-global-context-language.js +14 -0
  357. package/src/middlewares/set-global-context-language.js.map +1 -0
  358. package/src/middlewares.d.ts +18 -0
  359. package/src/middlewares.d.ts.map +1 -0
  360. package/src/middlewares.js +74 -0
  361. package/src/middlewares.js.map +1 -0
  362. package/src/model-registry.d.ts +23 -0
  363. package/src/model-registry.d.ts.map +1 -0
  364. package/src/model-registry.js +47 -0
  365. package/src/model-registry.js.map +1 -0
  366. package/src/models/email-token.d.ts +11 -0
  367. package/src/models/email-token.d.ts.map +1 -0
  368. package/src/models/email-token.js +11 -0
  369. package/src/models/email-token.js.map +1 -0
  370. package/src/models/{index.ts → index.d.ts} +1 -0
  371. package/src/models/index.d.ts.map +1 -0
  372. package/src/models/index.js +10 -0
  373. package/src/models/index.js.map +1 -0
  374. package/src/models/mnemonic.d.ts +11 -0
  375. package/src/models/mnemonic.d.ts.map +1 -0
  376. package/src/models/mnemonic.js +11 -0
  377. package/src/models/mnemonic.js.map +1 -0
  378. package/src/models/role.d.ts +11 -0
  379. package/src/models/role.d.ts.map +1 -0
  380. package/src/models/role.js +11 -0
  381. package/src/models/role.js.map +1 -0
  382. package/src/models/used-direct-login-token.d.ts +11 -0
  383. package/src/models/used-direct-login-token.d.ts.map +1 -0
  384. package/src/models/used-direct-login-token.js +11 -0
  385. package/src/models/used-direct-login-token.js.map +1 -0
  386. package/src/models/user-role.d.ts +6 -0
  387. package/src/models/user-role.d.ts.map +1 -0
  388. package/src/models/user-role.js +10 -0
  389. package/src/models/user-role.js.map +1 -0
  390. package/src/models/user.d.ts +7 -0
  391. package/src/models/user.d.ts.map +1 -0
  392. package/src/models/user.js +11 -0
  393. package/src/models/user.js.map +1 -0
  394. package/src/registry/email-service-registry.d.ts +9 -0
  395. package/src/registry/email-service-registry.d.ts.map +1 -0
  396. package/src/registry/email-service-registry.js +18 -0
  397. package/src/registry/email-service-registry.js.map +1 -0
  398. package/src/registry/{index.ts → index.d.ts} +1 -0
  399. package/src/registry/index.d.ts.map +1 -0
  400. package/src/registry/index.js +6 -0
  401. package/src/registry/index.js.map +1 -0
  402. package/src/routers/api.d.ts +27 -0
  403. package/src/routers/api.d.ts.map +1 -0
  404. package/src/routers/api.js +52 -0
  405. package/src/routers/api.js.map +1 -0
  406. package/src/routers/app.d.ts +28 -0
  407. package/src/routers/app.d.ts.map +1 -0
  408. package/src/routers/app.js +186 -0
  409. package/src/routers/app.js.map +1 -0
  410. package/src/routers/base.d.ts +12 -0
  411. package/src/routers/base.d.ts.map +1 -0
  412. package/src/routers/base.js +14 -0
  413. package/src/routers/base.js.map +1 -0
  414. package/src/routers/{index.ts → index.d.ts} +1 -0
  415. package/src/routers/index.d.ts.map +1 -0
  416. package/src/routers/index.js +7 -0
  417. package/src/routers/index.js.map +1 -0
  418. package/src/schemas/email-token.d.ts +38 -0
  419. package/src/schemas/email-token.d.ts.map +1 -0
  420. package/src/schemas/email-token.js +54 -0
  421. package/src/schemas/email-token.js.map +1 -0
  422. package/src/schemas/{index.ts → index.d.ts} +2 -1
  423. package/src/schemas/index.d.ts.map +1 -0
  424. package/src/schemas/index.js +11 -0
  425. package/src/schemas/index.js.map +1 -0
  426. package/src/schemas/mnemonic.d.ts +20 -0
  427. package/src/schemas/mnemonic.d.ts.map +1 -0
  428. package/src/schemas/mnemonic.js +30 -0
  429. package/src/schemas/mnemonic.js.map +1 -0
  430. package/src/schemas/role.d.ts +32 -0
  431. package/src/schemas/role.d.ts.map +1 -0
  432. package/src/schemas/role.js +86 -0
  433. package/src/schemas/role.js.map +1 -0
  434. package/src/schemas/schema.d.ts +40 -0
  435. package/src/schemas/schema.d.ts.map +1 -0
  436. package/src/schemas/schema.js +62 -0
  437. package/src/schemas/schema.js.map +1 -0
  438. package/src/schemas/used-direct-login-token.d.ts +27 -0
  439. package/src/schemas/used-direct-login-token.d.ts.map +1 -0
  440. package/src/schemas/used-direct-login-token.js +23 -0
  441. package/src/schemas/used-direct-login-token.js.map +1 -0
  442. package/src/schemas/user-role.d.ts +29 -0
  443. package/src/schemas/user-role.d.ts.map +1 -0
  444. package/src/schemas/user-role.js +54 -0
  445. package/src/schemas/user-role.js.map +1 -0
  446. package/src/schemas/user.d.ts +21 -0
  447. package/src/schemas/user.d.ts.map +1 -0
  448. package/src/schemas/user.js +176 -0
  449. package/src/schemas/user.js.map +1 -0
  450. package/src/services/backup-code.d.ts +78 -0
  451. package/src/services/backup-code.d.ts.map +1 -0
  452. package/src/services/backup-code.js +184 -0
  453. package/src/services/backup-code.js.map +1 -0
  454. package/src/services/base.d.ts +13 -0
  455. package/src/services/base.d.ts.map +1 -0
  456. package/src/services/base.js +15 -0
  457. package/src/services/base.js.map +1 -0
  458. package/src/services/checksum.d.ts +67 -0
  459. package/src/services/checksum.d.ts.map +1 -0
  460. package/src/services/checksum.js +143 -0
  461. package/src/services/checksum.js.map +1 -0
  462. package/src/services/crc.d.ts +87 -0
  463. package/src/services/crc.d.ts.map +1 -0
  464. package/src/services/crc.js +198 -0
  465. package/src/services/crc.js.map +1 -0
  466. package/src/services/database-initialization.d.ts +105 -0
  467. package/src/services/database-initialization.d.ts.map +1 -0
  468. package/src/services/database-initialization.js +782 -0
  469. package/src/services/database-initialization.js.map +1 -0
  470. package/src/services/direct-login-token.d.ts +9 -0
  471. package/src/services/direct-login-token.d.ts.map +1 -0
  472. package/src/services/direct-login-token.js +41 -0
  473. package/src/services/direct-login-token.js.map +1 -0
  474. package/src/services/fec-usage-example.d.ts +38 -0
  475. package/src/services/fec-usage-example.d.ts.map +1 -0
  476. package/src/services/fec-usage-example.js +75 -0
  477. package/src/services/fec-usage-example.js.map +1 -0
  478. package/src/services/fec.d.ts +46 -0
  479. package/src/services/fec.d.ts.map +1 -0
  480. package/src/services/fec.js +192 -0
  481. package/src/services/fec.js.map +1 -0
  482. package/src/services/{index.ts → index.d.ts} +1 -0
  483. package/src/services/index.d.ts.map +1 -0
  484. package/src/services/index.js +22 -0
  485. package/src/services/index.js.map +1 -0
  486. package/src/services/jwt.d.ts +33 -0
  487. package/src/services/jwt.d.ts.map +1 -0
  488. package/src/services/jwt.js +91 -0
  489. package/src/services/jwt.js.map +1 -0
  490. package/src/services/key-wrapping.d.ts +60 -0
  491. package/src/services/key-wrapping.d.ts.map +1 -0
  492. package/src/services/key-wrapping.js +311 -0
  493. package/src/services/key-wrapping.js.map +1 -0
  494. package/src/services/mnemonic.d.ts +61 -0
  495. package/src/services/mnemonic.d.ts.map +1 -0
  496. package/src/services/mnemonic.js +115 -0
  497. package/src/services/mnemonic.js.map +1 -0
  498. package/src/services/request-user.d.ts +20 -0
  499. package/src/services/request-user.d.ts.map +1 -0
  500. package/src/services/request-user.js +50 -0
  501. package/src/services/request-user.js.map +1 -0
  502. package/src/services/role.d.ts +88 -0
  503. package/src/services/role.d.ts.map +1 -0
  504. package/src/services/role.js +263 -0
  505. package/src/services/role.js.map +1 -0
  506. package/src/services/symmetric.d.ts +42 -0
  507. package/src/services/symmetric.d.ts.map +1 -0
  508. package/src/services/symmetric.js +101 -0
  509. package/src/services/symmetric.js.map +1 -0
  510. package/src/services/system-user.d.ts +17 -0
  511. package/src/services/system-user.d.ts.map +1 -0
  512. package/src/services/system-user.js +46 -0
  513. package/src/services/system-user.js.map +1 -0
  514. package/src/services/user.d.ts +320 -0
  515. package/src/services/user.d.ts.map +1 -0
  516. package/src/services/user.js +1378 -0
  517. package/src/services/user.js.map +1 -0
  518. package/src/services/xor.d.ts +24 -0
  519. package/src/services/xor.d.ts.map +1 -0
  520. package/src/services/xor.js +37 -0
  521. package/src/services/xor.js.map +1 -0
  522. package/src/types.d.ts +66 -40
  523. package/src/types.d.ts.map +1 -0
  524. package/src/types.js +14 -0
  525. package/src/types.js.map +1 -0
  526. package/src/utils.d.ts +202 -0
  527. package/src/utils.d.ts.map +1 -0
  528. package/src/utils.js +784 -0
  529. package/src/utils.js.map +1 -0
  530. package/LICENSE +0 -21
  531. package/src/application-base.ts +0 -492
  532. package/src/application.ts +0 -254
  533. package/src/backup-code.ts +0 -336
  534. package/src/constants.ts +0 -69
  535. package/src/controllers/base.ts +0 -440
  536. package/src/controllers/user.ts +0 -1451
  537. package/src/decorators/base-controller.ts +0 -61
  538. package/src/decorators/controller.ts +0 -109
  539. package/src/decorators/zod-validation.ts +0 -57
  540. package/src/defaults.ts +0 -94
  541. package/src/documents/base.ts +0 -7
  542. package/src/documents/email-token.ts +0 -14
  543. package/src/documents/used-direct-login-token.ts +0 -7
  544. package/src/enumerations/base-model-name.ts +0 -41
  545. package/src/enumerations/length-encoding-type.ts +0 -6
  546. package/src/enumerations/schema-collection.ts +0 -33
  547. package/src/enumerations/symmetric-error-type.ts +0 -4
  548. package/src/environment.ts +0 -770
  549. package/src/errors/express-validation.ts +0 -21
  550. package/src/errors/invalid-backup-code-version.ts +0 -14
  551. package/src/errors/invalid-jwt-token.ts +0 -10
  552. package/src/errors/invalid-model.ts +0 -11
  553. package/src/errors/invalid-new-password.ts +0 -18
  554. package/src/errors/invalid-password.ts +0 -13
  555. package/src/errors/missing-validated-data.ts +0 -36
  556. package/src/errors/mnemonic-or-password-required.ts +0 -12
  557. package/src/errors/model-not-registered.ts +0 -11
  558. package/src/errors/mongoose-validation.ts +0 -34
  559. package/src/errors/symmetric.ts +0 -41
  560. package/src/errors/token-expired.ts +0 -10
  561. package/src/get-language.ts +0 -53
  562. package/src/get-timezone.ts +0 -45
  563. package/src/interfaces/api-express-validation-error-response.ts +0 -8
  564. package/src/interfaces/api-message-response.ts +0 -3
  565. package/src/interfaces/backend-objects/email-token.ts +0 -11
  566. package/src/interfaces/backend-objects/user.ts +0 -9
  567. package/src/interfaces/checksum-config.ts +0 -4
  568. package/src/interfaces/checksum-consts.ts +0 -13
  569. package/src/interfaces/create-user-basics.ts +0 -17
  570. package/src/interfaces/csp-config.ts +0 -35
  571. package/src/interfaces/deep-partial.ts +0 -3
  572. package/src/interfaces/email-service.ts +0 -8
  573. package/src/interfaces/environment-mongo.ts +0 -76
  574. package/src/interfaces/environment.ts +0 -181
  575. package/src/interfaces/failable-result.ts +0 -6
  576. package/src/interfaces/fec-consts.ts +0 -4
  577. package/src/interfaces/handleable-error-options.ts +0 -6
  578. package/src/interfaces/jwt-consts.ts +0 -23
  579. package/src/interfaces/jwt-sign-response.ts +0 -19
  580. package/src/interfaces/mongo-errors.ts +0 -5
  581. package/src/interfaces/request-user.ts +0 -50
  582. package/src/interfaces/required-string-keys.ts +0 -26
  583. package/src/interfaces/schema.ts +0 -31
  584. package/src/interfaces/server-init-result.ts +0 -37
  585. package/src/interfaces/status-code-response.ts +0 -7
  586. package/src/interfaces/symmetric-encryption-results.ts +0 -4
  587. package/src/middlewares/authenticate-crypto.ts +0 -243
  588. package/src/middlewares/authenticate-token.ts +0 -152
  589. package/src/middlewares/cleanup-crypto.ts +0 -40
  590. package/src/middlewares/set-global-context-language.ts +0 -24
  591. package/src/middlewares.ts +0 -120
  592. package/src/model-registry.ts +0 -75
  593. package/src/models/email-token.ts +0 -19
  594. package/src/models/mnemonic.ts +0 -19
  595. package/src/models/role.ts +0 -19
  596. package/src/models/used-direct-login-token.ts +0 -23
  597. package/src/models/user-role.ts +0 -17
  598. package/src/models/user.ts +0 -19
  599. package/src/registry/email-service-registry.ts +0 -24
  600. package/src/routers/api.ts +0 -151
  601. package/src/routers/app.ts +0 -258
  602. package/src/routers/base.ts +0 -17
  603. package/src/schemas/email-token.ts +0 -91
  604. package/src/schemas/mnemonic.ts +0 -37
  605. package/src/schemas/role.ts +0 -127
  606. package/src/schemas/schema.ts +0 -140
  607. package/src/schemas/used-direct-login-token.ts +0 -38
  608. package/src/schemas/user-role.ts +0 -75
  609. package/src/schemas/user.ts +0 -202
  610. package/src/services/backup-code.ts +0 -316
  611. package/src/services/base.ts +0 -33
  612. package/src/services/checksum.ts +0 -161
  613. package/src/services/crc.ts +0 -213
  614. package/src/services/database-initialization.ts +0 -1479
  615. package/src/services/db-init-cache.d.ts +0 -16
  616. package/src/services/direct-login-token.ts +0 -62
  617. package/src/services/fec-usage-example.ts +0 -102
  618. package/src/services/fec.ts +0 -296
  619. package/src/services/jwt.ts +0 -134
  620. package/src/services/key-wrapping.ts +0 -434
  621. package/src/services/mnemonic.ts +0 -167
  622. package/src/services/request-user.ts +0 -62
  623. package/src/services/role.ts +0 -396
  624. package/src/services/symmetric.ts +0 -139
  625. package/src/services/system-user.ts +0 -82
  626. package/src/services/user.ts +0 -2137
  627. package/src/services/xor.ts +0 -34
  628. package/src/types.ts +0 -128
  629. package/src/utils.ts +0 -1022
@@ -1,1451 +0,0 @@
1
- /// <reference path="../types.d.ts" />
2
-
3
- import {
4
- ECIES,
5
- EmailString,
6
- SecureString,
7
- UINT64_SIZE,
8
- } from '@digitaldefiance/ecies-lib';
9
- import {
10
- CoreLanguageCode,
11
- HandleableError,
12
- isValidTimezone,
13
- LanguageCodes,
14
- } from '@digitaldefiance/i18n-lib';
15
- import {
16
- Member as BackendMember,
17
- ECIESService,
18
- } from '@digitaldefiance/node-ecies-lib';
19
- import {
20
- AccountStatus,
21
- Constants as AppConstants,
22
- EmailTokenType,
23
- GenericValidationError,
24
- getSuiteCoreTranslation,
25
- ITokenRole,
26
- ITokenUser,
27
- IUserBase,
28
- SuiteCoreStringKey,
29
- UsernameOrEmailRequiredError,
30
- } from '@digitaldefiance/suite-core-lib';
31
- import type { NextFunction, Request, Response } from 'express';
32
- import { body } from 'express-validator';
33
- import { Types } from 'mongoose';
34
- import { z } from 'zod';
35
- import { BackupCode } from '../backup-code';
36
- import { DecoratorBaseController } from '../decorators/base-controller';
37
- import { Controller, Get, Post } from '../decorators/controller';
38
- import { IBaseDocument } from '../documents';
39
- import { IUserDocument } from '../documents/user';
40
- import { BaseModelName } from '../enumerations/base-model-name';
41
- import { Environment } from '../environment';
42
- import { MnemonicOrPasswordRequiredError } from '../errors/mnemonic-or-password-required';
43
- import {
44
- IApiChallengeResponse,
45
- IApiCodeCountResponse,
46
- IApiLoginResponse,
47
- IApiMessageResponse,
48
- IApiMnemonicResponse,
49
- IApiRegistrationResponse,
50
- IApiRequestUserResponse,
51
- IConstants,
52
- } from '../interfaces';
53
- import { IApiBackupCodesResponse } from '../interfaces/api-responses/backup-codes-response';
54
- import type { IApplication } from '../interfaces/application';
55
- import { IStatusCodeResponse } from '../interfaces/status-code-response';
56
- import { findAuthToken } from '../middlewares/authenticate-token';
57
- import { BackupCodeService } from '../services/backup-code';
58
- import { JwtService } from '../services/jwt';
59
- import { RequestUserService } from '../services/request-user';
60
- import { RoleService } from '../services/role';
61
- import { SystemUserService } from '../services/system-user';
62
- import { UserService } from '../services/user';
63
- import { ApiErrorResponse } from '../types';
64
- import { requireValidatedFieldsAsync, withTransaction } from '../utils';
65
-
66
- const isString = (v: unknown): v is string => typeof v === 'string';
67
-
68
- const RegisterSchema = z.object({
69
- username: z.string(),
70
- email: z.string(),
71
- timezone: z.string(),
72
- password: z.string().min(8).optional(),
73
- });
74
-
75
- const EmailLoginChallengeSchema = z.object({
76
- token: z.string(),
77
- signature: z.string(),
78
- email: z.string().optional(),
79
- username: z.string().optional(),
80
- });
81
-
82
- const DirectLoginChallengeSchema = z.object({
83
- challenge: z.string(),
84
- signature: z.string(),
85
- email: z.string().optional(),
86
- username: z.string().optional(),
87
- });
88
-
89
- @Controller()
90
- export class UserController<
91
- I extends Types.ObjectId | string = Types.ObjectId,
92
- D extends Date = Date,
93
- S extends string = string,
94
- A extends string = string,
95
- TUser extends IUserBase<I, D, S, A> = IUserBase<I, D, S, A>,
96
- TTokenRole extends ITokenRole<I, D> = ITokenRole<I, D>,
97
- TTokenUser extends ITokenUser = ITokenUser,
98
- TApplication extends IApplication<
99
- any,
100
- Types.ObjectId,
101
- IBaseDocument<any, Types.ObjectId>,
102
- Environment,
103
- IConstants
104
- > = IApplication<
105
- any,
106
- Types.ObjectId,
107
- IBaseDocument<any, Types.ObjectId>,
108
- Environment,
109
- IConstants
110
- >,
111
- TLanguage extends CoreLanguageCode = CoreLanguageCode,
112
- > extends DecoratorBaseController<TLanguage> {
113
- protected readonly userService: UserService<
114
- any,
115
- I,
116
- D,
117
- S,
118
- A,
119
- any,
120
- any,
121
- any,
122
- TUser,
123
- TTokenRole,
124
- TApplication
125
- >;
126
- protected readonly jwtService: JwtService<
127
- I,
128
- D,
129
- TTokenRole,
130
- TTokenUser,
131
- TApplication
132
- >;
133
- protected readonly backupCodeService: BackupCodeService<
134
- I,
135
- D,
136
- TTokenRole,
137
- TApplication
138
- >;
139
- protected readonly roleService: RoleService<I, D, TTokenRole>;
140
- protected readonly eciesService: ECIESService;
141
- protected readonly systemUser: BackendMember;
142
-
143
- constructor(
144
- application: IApplication<
145
- any,
146
- Types.ObjectId,
147
- IBaseDocument<any, Types.ObjectId>,
148
- Environment,
149
- IConstants
150
- >,
151
- jwtService: JwtService<I, D, TTokenRole, TTokenUser, TApplication>,
152
- userService: UserService<
153
- any,
154
- I,
155
- D,
156
- S,
157
- A,
158
- any,
159
- any,
160
- any,
161
- TUser,
162
- TTokenRole,
163
- TApplication
164
- >,
165
- backupCodeService: BackupCodeService<I, D, TTokenRole, TApplication>,
166
- roleService: RoleService<I, D, TTokenRole>,
167
- eciesService: ECIESService,
168
- ) {
169
- super(application);
170
- this.jwtService = jwtService;
171
- this.userService = userService;
172
- this.backupCodeService = backupCodeService;
173
- this.roleService = roleService;
174
- this.eciesService = eciesService;
175
- this.systemUser = SystemUserService.getSystemUser(application.environment);
176
- }
177
-
178
- @Get('/verify', { auth: true })
179
- async tokenVerifiedResponse(
180
- req: Request,
181
- res: Response,
182
- next: NextFunction,
183
- ): Promise<IStatusCodeResponse<IApiRequestUserResponse | ApiErrorResponse>> {
184
- if (!req.user) {
185
- throw new HandleableError(
186
- new Error(
187
- getSuiteCoreTranslation(SuiteCoreStringKey.Common_NoUserOnRequest),
188
- ),
189
- {
190
- statusCode: 401,
191
- },
192
- );
193
- }
194
- return {
195
- statusCode: 200,
196
- response: {
197
- message: getSuiteCoreTranslation(
198
- SuiteCoreStringKey.Validation_TokenValid,
199
- ),
200
- user: req.user,
201
- },
202
- };
203
- }
204
-
205
- @Get('/refresh-token', { auth: true })
206
- async refreshToken(
207
- req: Request,
208
- res: Response,
209
- next: NextFunction,
210
- ): Promise<IStatusCodeResponse<IApiLoginResponse | ApiErrorResponse>> {
211
- const token = findAuthToken(req.headers);
212
- if (!token) {
213
- throw new GenericValidationError(
214
- getSuiteCoreTranslation(SuiteCoreStringKey.Validation_TokenMissing),
215
- );
216
- }
217
-
218
- const tokenUser = await this.jwtService.verifyToken(token);
219
- if (!tokenUser) {
220
- throw new GenericValidationError(
221
- getSuiteCoreTranslation(SuiteCoreStringKey.Validation_TokenInvalid),
222
- );
223
- }
224
-
225
- const UserModel = this.application.getModel<IUserDocument>(
226
- BaseModelName.User,
227
- );
228
- const userDoc = await UserModel.findById(tokenUser.userId, {
229
- password: 0,
230
- });
231
- if (!userDoc || userDoc.accountStatus !== AccountStatus.Active) {
232
- throw new GenericValidationError(
233
- getSuiteCoreTranslation(SuiteCoreStringKey.Validation_UserNotFound),
234
- );
235
- }
236
- const { token: newToken, roles } = await this.jwtService.signToken(
237
- userDoc,
238
- this.application.environment.jwtSecret,
239
- (req.user?.siteLanguage as string) ?? LanguageCodes.EN_US,
240
- );
241
-
242
- return {
243
- statusCode: 200,
244
- response: {
245
- message: getSuiteCoreTranslation(SuiteCoreStringKey.TokenRefreshed),
246
- user: RequestUserService.makeRequestUserDTO(userDoc, roles),
247
- token: newToken,
248
- serverPublicKey: this.application.environment.systemPublicKeyHex ?? '',
249
- },
250
- headers: {
251
- Authorization: `Bearer ${newToken}`,
252
- },
253
- };
254
- }
255
-
256
- @Post('/register', {
257
- schema: RegisterSchema,
258
- validation: (validationLanguage: TLanguage) => [
259
- body('username')
260
- .matches(AppConstants.UsernameRegex)
261
- .withMessage(
262
- getSuiteCoreTranslation(
263
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
264
- undefined,
265
- validationLanguage,
266
- ),
267
- ),
268
- body('email')
269
- .isEmail()
270
- .withMessage(
271
- getSuiteCoreTranslation(
272
- SuiteCoreStringKey.Validation_InvalidEmail,
273
- undefined,
274
- validationLanguage,
275
- ),
276
- ),
277
- body('timezone')
278
- .isString()
279
- .custom((value) => isValidTimezone(value))
280
- .withMessage(
281
- getSuiteCoreTranslation(
282
- SuiteCoreStringKey.Validation_TimezoneInvalid,
283
- undefined,
284
- validationLanguage,
285
- ),
286
- ),
287
- body('password')
288
- .optional()
289
- .matches(AppConstants.PasswordRegex)
290
- .withMessage(
291
- getSuiteCoreTranslation(
292
- SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate,
293
- ),
294
- ),
295
- ],
296
- })
297
- async register(
298
- req: Request,
299
- res: Response,
300
- next: NextFunction,
301
- ): Promise<IStatusCodeResponse<IApiRegistrationResponse | ApiErrorResponse>> {
302
- return await withTransaction(
303
- this.application.db.connection,
304
- this.application.environment.mongo.useTransactions,
305
- undefined,
306
- async (sess) => {
307
- return await requireValidatedFieldsAsync(
308
- req,
309
- RegisterSchema,
310
- async ({ username, email, timezone, password }) => {
311
- if (
312
- !isString(username) ||
313
- !isString(email) ||
314
- !isString(timezone)
315
- ) {
316
- throw new GenericValidationError(
317
- getSuiteCoreTranslation(
318
- SuiteCoreStringKey.Validation_MissingValidatedData,
319
- ),
320
- );
321
- }
322
-
323
- const { user, mnemonic, backupCodes } =
324
- await this.userService.newUser(
325
- this.systemUser,
326
- {
327
- username: username.trim(),
328
- email: email.trim(),
329
- timezone: timezone,
330
- },
331
- undefined,
332
- undefined,
333
- sess,
334
- this.application.environment.debug,
335
- password as string | undefined,
336
- );
337
-
338
- await this.userService.createAndSendEmailToken(
339
- user,
340
- EmailTokenType.AccountVerification,
341
- sess,
342
- this.application.environment.debug,
343
- );
344
-
345
- return {
346
- statusCode: 201,
347
- response: {
348
- message: getSuiteCoreTranslation(
349
- SuiteCoreStringKey.Registration_Success,
350
- { MNEMONIC: mnemonic },
351
- ),
352
- mnemonic,
353
- backupCodes,
354
- },
355
- };
356
- },
357
- );
358
- },
359
- {
360
- timeoutMs: this.application.environment.mongo.transactionTimeout * 30,
361
- },
362
- );
363
- }
364
-
365
- @Post('/account-verification', {
366
- validation: (validationLanguage: TLanguage) => [
367
- body('token')
368
- .not()
369
- .isEmpty()
370
- .withMessage(
371
- getSuiteCoreTranslation(
372
- SuiteCoreStringKey.Validation_TokenRequired,
373
- undefined,
374
- validationLanguage,
375
- ),
376
- )
377
- .matches(new RegExp(`^[a-f0-9]{${AppConstants.EmailTokenLength * 2}}$`))
378
- .withMessage(
379
- getSuiteCoreTranslation(
380
- SuiteCoreStringKey.Validation_InvalidToken,
381
- undefined,
382
- validationLanguage,
383
- ),
384
- ),
385
- ],
386
- })
387
- async completeAccountVerification(
388
- req: Request,
389
- res: Response,
390
- next: NextFunction,
391
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
392
- const { token } = this.validatedBody;
393
-
394
- return await withTransaction(
395
- this.application.db.connection,
396
- this.application.environment.mongo.useTransactions,
397
- undefined,
398
- async (sess) => {
399
- await this.userService.verifyAccountTokenAndComplete(
400
- token as string,
401
- sess,
402
- );
403
- return {
404
- statusCode: 200,
405
- response: {
406
- message: getSuiteCoreTranslation(
407
- SuiteCoreStringKey.EmailVerification_Success,
408
- ),
409
- },
410
- };
411
- },
412
- );
413
- }
414
-
415
- @Post('/language', {
416
- auth: true,
417
- validation: (validationLanguage: TLanguage) => [
418
- body('language')
419
- .isString()
420
- .withMessage(
421
- getSuiteCoreTranslation(
422
- SuiteCoreStringKey.Validation_InvalidLanguage,
423
- undefined,
424
- validationLanguage,
425
- ),
426
- )
427
- .isIn(Object.values(LanguageCodes))
428
- .withMessage(
429
- getSuiteCoreTranslation(
430
- SuiteCoreStringKey.Validation_InvalidLanguage,
431
- undefined,
432
- validationLanguage,
433
- ),
434
- ),
435
- ],
436
- })
437
- async setLanguage(
438
- req: Request,
439
- res: Response,
440
- next: NextFunction,
441
- ): Promise<IStatusCodeResponse<IApiRequestUserResponse | ApiErrorResponse>> {
442
- return await withTransaction(
443
- this.application.db.connection,
444
- this.application.environment.mongo.useTransactions,
445
- undefined,
446
- async (sess) => {
447
- const { language } = this.validatedBody;
448
- if (!req.user) {
449
- throw new HandleableError(
450
- new Error(
451
- getSuiteCoreTranslation(
452
- SuiteCoreStringKey.Common_NoUserOnRequest,
453
- ),
454
- ),
455
- { statusCode: 401 },
456
- );
457
- }
458
-
459
- const user = await this.userService.updateSiteLanguage(
460
- req.user.id,
461
- language as string,
462
- sess,
463
- );
464
-
465
- return {
466
- statusCode: 200,
467
- response: {
468
- message: getSuiteCoreTranslation(
469
- SuiteCoreStringKey.LanguageUpdate_Success,
470
- ),
471
- user,
472
- },
473
- };
474
- },
475
- );
476
- }
477
-
478
- @Get('/backup-codes', { auth: true })
479
- async getBackupCodeCount(
480
- req: Request,
481
- res: Response,
482
- next: NextFunction,
483
- ): Promise<IStatusCodeResponse<IApiCodeCountResponse | ApiErrorResponse>> {
484
- if (!req.user) {
485
- throw new HandleableError(
486
- new Error(
487
- getSuiteCoreTranslation(SuiteCoreStringKey.Common_NoUserOnRequest),
488
- ),
489
- { statusCode: 401 },
490
- );
491
- }
492
-
493
- const UserModel = this.application.getModel<IUserDocument>(
494
- BaseModelName.User,
495
- );
496
- const user = await UserModel.findById(req.user.id);
497
-
498
- return {
499
- statusCode: 200,
500
- response: {
501
- message: 'Backup codes retrieved',
502
- codeCount: user?.backupCodes?.length || 0,
503
- } as IApiCodeCountResponse,
504
- };
505
- }
506
-
507
- @Post('/backup-codes', {
508
- auth: true,
509
- cryptoAuth: true,
510
- validation: (validationLanguage: TLanguage) => [
511
- body().custom((value, { req }) => {
512
- if (!req.body?.password && !req.body?.mnemonic) {
513
- throw new MnemonicOrPasswordRequiredError();
514
- }
515
- return true;
516
- }),
517
- body('password')
518
- .optional()
519
- .notEmpty()
520
- .withMessage(
521
- getSuiteCoreTranslation(
522
- SuiteCoreStringKey.Validation_CurrentPasswordRequired,
523
- undefined,
524
- validationLanguage,
525
- ),
526
- ),
527
- body('mnemonic')
528
- .optional()
529
- .notEmpty()
530
- .withMessage(
531
- getSuiteCoreTranslation(
532
- SuiteCoreStringKey.Validation_MnemonicRequired,
533
- undefined,
534
- validationLanguage,
535
- ),
536
- )
537
- .matches(AppConstants.MnemonicRegex)
538
- .withMessage(
539
- getSuiteCoreTranslation(
540
- SuiteCoreStringKey.Validation_MnemonicRegex,
541
- undefined,
542
- validationLanguage,
543
- ),
544
- ),
545
- ],
546
- })
547
- async resetBackupCodes(
548
- req: Request,
549
- res: Response,
550
- next: NextFunction,
551
- ): Promise<IStatusCodeResponse<IApiBackupCodesResponse | ApiErrorResponse>> {
552
- if (!req.user || !req.eciesUser || !req.eciesUser.hasPrivateKey) {
553
- throw new HandleableError(
554
- new Error(
555
- getSuiteCoreTranslation(SuiteCoreStringKey.Common_NoUserOnRequest),
556
- ),
557
- { statusCode: 401 },
558
- );
559
- }
560
-
561
- const newBackupCodes = await this.userService.resetUserBackupCodes(
562
- req.eciesUser,
563
- this.systemUser,
564
- );
565
- const codes = newBackupCodes.map((c) => c.notNullValue);
566
- newBackupCodes.forEach((c) => c.dispose());
567
-
568
- return {
569
- statusCode: 200,
570
- response: {
571
- message: getSuiteCoreTranslation(
572
- SuiteCoreStringKey.BackupCodeRecovery_YourNewCodes,
573
- ),
574
- backupCodes: codes,
575
- },
576
- };
577
- }
578
-
579
- @Post('/recover-mnemonic', {
580
- auth: true,
581
- cryptoAuth: true,
582
- validation: (validationLanguage: TLanguage) => [
583
- body('password')
584
- .isString()
585
- .withMessage(
586
- getSuiteCoreTranslation(
587
- SuiteCoreStringKey.Validation_CurrentPasswordRequired,
588
- undefined,
589
- validationLanguage,
590
- ),
591
- ),
592
- ],
593
- })
594
- async recoverMnemonic(
595
- req: Request,
596
- res: Response,
597
- next: NextFunction,
598
- ): Promise<IStatusCodeResponse<IApiMnemonicResponse | ApiErrorResponse>> {
599
- return await withTransaction(
600
- this.application.db.connection,
601
- this.application.environment.mongo.useTransactions,
602
- undefined,
603
- async (sess) => {
604
- if (!req.user) {
605
- throw new HandleableError(
606
- new Error(
607
- getSuiteCoreTranslation(
608
- SuiteCoreStringKey.Validation_InvalidCredentials,
609
- ),
610
- ),
611
- { statusCode: 401 },
612
- );
613
- } else if (!req.eciesUser) {
614
- throw new HandleableError(
615
- new Error(
616
- getSuiteCoreTranslation(
617
- SuiteCoreStringKey.Validation_MnemonicOrPasswordRequired,
618
- ),
619
- ),
620
- { statusCode: 401 },
621
- );
622
- }
623
-
624
- const { password } = this.validatedBody;
625
- if (!isString(password)) {
626
- throw new GenericValidationError(
627
- getSuiteCoreTranslation(
628
- SuiteCoreStringKey.Validation_MissingValidatedData,
629
- ),
630
- );
631
- }
632
-
633
- const userDoc = await this.userService.findUserById(
634
- new Types.ObjectId(req.user.id),
635
- true,
636
- sess,
637
- );
638
-
639
- const mnemonic = await this.userService.recoverMnemonic(
640
- req.eciesUser,
641
- userDoc.mnemonicRecovery,
642
- );
643
-
644
- return {
645
- statusCode: 200,
646
- response: {
647
- message: getSuiteCoreTranslation(
648
- SuiteCoreStringKey.MnemonicRecovery_Success,
649
- ),
650
- mnemonic: mnemonic.notNullValue,
651
- },
652
- };
653
- },
654
- );
655
- }
656
-
657
- @Post('/change-password', {
658
- auth: true,
659
- validation: (validationLanguage: TLanguage) => [
660
- body('currentPassword')
661
- .notEmpty()
662
- .withMessage(
663
- getSuiteCoreTranslation(
664
- SuiteCoreStringKey.Validation_Required,
665
- undefined,
666
- validationLanguage,
667
- ),
668
- ),
669
- body('newPassword')
670
- .matches(AppConstants.PasswordRegex)
671
- .withMessage(
672
- getSuiteCoreTranslation(
673
- SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate,
674
- ),
675
- )
676
- .notEmpty()
677
- .withMessage(
678
- getSuiteCoreTranslation(
679
- SuiteCoreStringKey.Validation_Required,
680
- undefined,
681
- validationLanguage,
682
- ),
683
- ),
684
- ],
685
- })
686
- async changePassword(
687
- req: Request,
688
- res: Response,
689
- next: NextFunction,
690
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
691
- return await withTransaction(
692
- this.application.db.connection,
693
- this.application.environment.mongo.useTransactions,
694
- undefined,
695
- async (sess) => {
696
- const { currentPassword, newPassword } = this.validatedBody;
697
- if (!req.user) {
698
- throw new HandleableError(
699
- new Error(
700
- getSuiteCoreTranslation(
701
- SuiteCoreStringKey.Common_NoUserOnRequest,
702
- ),
703
- ),
704
- { statusCode: 401 },
705
- );
706
- }
707
-
708
- if (!isString(currentPassword) || !isString(newPassword)) {
709
- throw new GenericValidationError(
710
- getSuiteCoreTranslation(
711
- SuiteCoreStringKey.Validation_MissingValidatedData,
712
- ),
713
- );
714
- }
715
-
716
- await this.userService.changePassword(
717
- req.user.id,
718
- currentPassword,
719
- newPassword,
720
- sess,
721
- );
722
-
723
- return {
724
- statusCode: 200,
725
- response: {
726
- message: getSuiteCoreTranslation(
727
- SuiteCoreStringKey.PasswordChange_Success,
728
- ),
729
- },
730
- };
731
- },
732
- );
733
- }
734
-
735
- @Post('/request-direct-login')
736
- async requestDirectLogin(
737
- req: Request,
738
- res: Response,
739
- next: NextFunction,
740
- ): Promise<IStatusCodeResponse<IApiChallengeResponse | ApiErrorResponse>> {
741
- const challenge = this.userService.generateDirectLoginChallenge();
742
- return {
743
- statusCode: 200,
744
- response: {
745
- challenge: challenge,
746
- message: getSuiteCoreTranslation(
747
- SuiteCoreStringKey.Login_ChallengeGenerated,
748
- ),
749
- serverPublicKey: this.application.environment.systemPublicKeyHex ?? '',
750
- },
751
- };
752
- }
753
-
754
- @Post('/direct-challenge', {
755
- schema: DirectLoginChallengeSchema,
756
- validation: (validationLanguage: TLanguage) => [
757
- body('challenge')
758
- .not()
759
- .isEmpty()
760
- .withMessage(
761
- getSuiteCoreTranslation(
762
- SuiteCoreStringKey.Validation_InvalidChallenge,
763
- undefined,
764
- validationLanguage,
765
- ),
766
- )
767
- .matches(
768
- new RegExp(
769
- `^[a-f0-9]{${(UINT64_SIZE + 32 + ECIES.SIGNATURE_SIZE) * 2}}$`,
770
- ),
771
- )
772
- .withMessage(
773
- getSuiteCoreTranslation(
774
- SuiteCoreStringKey.Validation_InvalidChallenge,
775
- undefined,
776
- validationLanguage,
777
- ),
778
- ),
779
- body('signature')
780
- .not()
781
- .isEmpty()
782
- .withMessage(
783
- getSuiteCoreTranslation(
784
- SuiteCoreStringKey.Validation_InvalidSignature,
785
- ),
786
- )
787
- .matches(new RegExp(`^[a-f0-9]{${ECIES.SIGNATURE_SIZE * 2}}$`))
788
- .withMessage(SuiteCoreStringKey.Validation_InvalidSignature),
789
- body().custom((value, { req }) => {
790
- if (!req.body.username && !req.body.email) {
791
- throw new UsernameOrEmailRequiredError();
792
- }
793
- return true;
794
- }),
795
- body('username')
796
- .optional()
797
- .matches(AppConstants.UsernameRegex)
798
- .withMessage(
799
- getSuiteCoreTranslation(
800
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
801
- undefined,
802
- validationLanguage,
803
- ),
804
- ),
805
- body('email')
806
- .optional()
807
- .isEmail()
808
- .withMessage(
809
- getSuiteCoreTranslation(
810
- SuiteCoreStringKey.Validation_InvalidEmail,
811
- undefined,
812
- validationLanguage,
813
- ),
814
- ),
815
- ],
816
- })
817
- async directLoginChallenge(
818
- req: Request,
819
- res: Response,
820
- next: NextFunction,
821
- ): Promise<IStatusCodeResponse<IApiLoginResponse | ApiErrorResponse>> {
822
- return await withTransaction(
823
- this.application.db.connection,
824
- this.application.environment.mongo.useTransactions,
825
- undefined,
826
- async (sess) => {
827
- const { username, email, challenge, signature } = this.validatedBody;
828
-
829
- const { userDoc } = await this.userService.verifyDirectLoginChallenge(
830
- String(challenge),
831
- String(signature) as any,
832
- username ? String(username) : undefined,
833
- email ? String(email) : undefined,
834
- sess,
835
- );
836
-
837
- const { token: jwtToken, roles } = await this.jwtService.signToken(
838
- userDoc,
839
- this.application.environment.jwtSecret,
840
- (req.user?.siteLanguage as string) ?? LanguageCodes.EN_US,
841
- );
842
-
843
- return {
844
- statusCode: 200,
845
- response: {
846
- user: userDoc as any,
847
- token: jwtToken,
848
- serverPublicKey:
849
- this.application.environment.systemPublicKeyHex ?? '',
850
- message: getSuiteCoreTranslation(
851
- SuiteCoreStringKey.LoggedIn_Success,
852
- ),
853
- },
854
- };
855
- },
856
- );
857
- }
858
-
859
- @Post('/request-email-login', {
860
- validation: (validationLanguage: TLanguage) => [
861
- body().custom((value, { req }) => {
862
- if (!req.body.username && !req.body.email) {
863
- throw new UsernameOrEmailRequiredError();
864
- }
865
- return true;
866
- }),
867
- body('username')
868
- .optional()
869
- .matches(AppConstants.UsernameRegex)
870
- .withMessage(
871
- getSuiteCoreTranslation(
872
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
873
- undefined,
874
- validationLanguage,
875
- ),
876
- ),
877
- body('email')
878
- .optional()
879
- .isEmail()
880
- .withMessage(
881
- getSuiteCoreTranslation(
882
- SuiteCoreStringKey.Validation_InvalidEmail,
883
- undefined,
884
- validationLanguage,
885
- ),
886
- ),
887
- ],
888
- })
889
- async requestEmailLogin(
890
- req: Request,
891
- res: Response,
892
- next: NextFunction,
893
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
894
- const { username, email } = this.validatedBody;
895
-
896
- try {
897
- await withTransaction(
898
- this.application.db.connection,
899
- this.application.environment.mongo.useTransactions,
900
- undefined,
901
- async (sess) => {
902
- const userDoc = await this.userService.findUser(
903
- email as string,
904
- username as string,
905
- sess,
906
- );
907
- await this.userService.createAndSendEmailToken(
908
- userDoc,
909
- EmailTokenType.LoginRequest,
910
- sess,
911
- this.application.environment.debug,
912
- );
913
- },
914
- );
915
- } catch (error) {
916
- // Suppress user-related errors for security
917
- }
918
-
919
- return {
920
- statusCode: 200,
921
- response: {
922
- message: getSuiteCoreTranslation(SuiteCoreStringKey.Email_TokenSent),
923
- },
924
- };
925
- }
926
-
927
- @Post('/email-challenge', {
928
- schema: EmailLoginChallengeSchema,
929
- validation: (validationLanguage: TLanguage) => [
930
- body('token')
931
- .not()
932
- .isEmpty()
933
- .withMessage(
934
- getSuiteCoreTranslation(
935
- SuiteCoreStringKey.Validation_TokenRequired,
936
- undefined,
937
- validationLanguage,
938
- ),
939
- )
940
- .matches(new RegExp(`^[a-f0-9]{${AppConstants.EmailTokenLength * 2}}$`))
941
- .withMessage(
942
- getSuiteCoreTranslation(
943
- SuiteCoreStringKey.Validation_InvalidToken,
944
- undefined,
945
- validationLanguage,
946
- ),
947
- ),
948
- body('signature')
949
- .not()
950
- .isEmpty()
951
- .withMessage(
952
- getSuiteCoreTranslation(
953
- SuiteCoreStringKey.Validation_InvalidSignature,
954
- ),
955
- )
956
- .matches(new RegExp(`^[a-f0-9]{${ECIES.SIGNATURE_SIZE * 2}}$`))
957
- .withMessage(SuiteCoreStringKey.Validation_InvalidSignature),
958
- body().custom((value, { req }) => {
959
- if (!req.body.username && !req.body.email) {
960
- throw new UsernameOrEmailRequiredError();
961
- }
962
- return true;
963
- }),
964
- body('username')
965
- .optional()
966
- .matches(AppConstants.UsernameRegex)
967
- .withMessage(
968
- getSuiteCoreTranslation(
969
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
970
- undefined,
971
- validationLanguage,
972
- ),
973
- ),
974
- body('email')
975
- .optional()
976
- .isEmail()
977
- .withMessage(
978
- getSuiteCoreTranslation(
979
- SuiteCoreStringKey.Validation_InvalidEmail,
980
- undefined,
981
- validationLanguage,
982
- ),
983
- ),
984
- ],
985
- })
986
- async emailLoginChallenge(
987
- req: Request,
988
- res: Response,
989
- next: NextFunction,
990
- ): Promise<IStatusCodeResponse<IApiLoginResponse | ApiErrorResponse>> {
991
- return await withTransaction(
992
- this.application.db.connection,
993
- this.application.environment.mongo.useTransactions,
994
- undefined,
995
- async (sess) => {
996
- const { token, signature } = this.validatedBody;
997
-
998
- const userDoc = await this.userService.validateEmailLoginTokenChallenge(
999
- String(token),
1000
- String(signature) as any,
1001
- sess,
1002
- );
1003
-
1004
- const { token: jwtToken, roles } = await this.jwtService.signToken(
1005
- userDoc,
1006
- this.application.environment.jwtSecret,
1007
- (req.user?.siteLanguage as string) ?? LanguageCodes.EN_US,
1008
- );
1009
-
1010
- return {
1011
- statusCode: 200,
1012
- response: {
1013
- user: userDoc as any,
1014
- token: jwtToken,
1015
- serverPublicKey:
1016
- this.application.environment.systemPublicKeyHex ?? '',
1017
- message: getSuiteCoreTranslation(
1018
- SuiteCoreStringKey.LoggedIn_Success,
1019
- ),
1020
- },
1021
- };
1022
- },
1023
- );
1024
- }
1025
-
1026
- @Post('/resend-verification', {
1027
- validation: (validationLanguage: TLanguage) => [
1028
- body().custom((value, { req }) => {
1029
- if (!req.body.username && !req.body.email) {
1030
- throw new UsernameOrEmailRequiredError();
1031
- }
1032
- return true;
1033
- }),
1034
- body('username')
1035
- .optional()
1036
- .isString()
1037
- .matches(AppConstants.UsernameRegex)
1038
- .withMessage(
1039
- getSuiteCoreTranslation(
1040
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
1041
- undefined,
1042
- validationLanguage,
1043
- ),
1044
- ),
1045
- body('email').optional().isEmail(),
1046
- ],
1047
- })
1048
- async resendVerification(
1049
- req: Request,
1050
- res: Response,
1051
- next: NextFunction,
1052
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
1053
- return await withTransaction(
1054
- this.application.db.connection,
1055
- this.application.environment.mongo.useTransactions,
1056
- undefined,
1057
- async (sess) => {
1058
- const { username, email } = this.validatedBody;
1059
-
1060
- const UserModel = this.application.getModel<IUserDocument>(
1061
- BaseModelName.User,
1062
- );
1063
- let query: { username?: string; email?: string } = {};
1064
- if (isString(username)) query.username = username;
1065
- else if (isString(email)) query.email = email;
1066
- else {
1067
- throw new GenericValidationError(
1068
- getSuiteCoreTranslation(
1069
- SuiteCoreStringKey.Validation_MissingValidatedData,
1070
- ),
1071
- );
1072
- }
1073
-
1074
- const user = await UserModel.findOne(query).session(sess ?? null);
1075
- if (!user) {
1076
- throw new GenericValidationError(
1077
- getSuiteCoreTranslation(SuiteCoreStringKey.Validation_UserNotFound),
1078
- { statusCode: 404 },
1079
- );
1080
- }
1081
-
1082
- await this.userService.resendEmailToken(
1083
- user._id.toString(),
1084
- EmailTokenType.AccountVerification,
1085
- sess,
1086
- this.application.environment.debug,
1087
- );
1088
-
1089
- return {
1090
- statusCode: 200,
1091
- response: {
1092
- message: getSuiteCoreTranslation(
1093
- SuiteCoreStringKey.EmailVerification_Resent,
1094
- ),
1095
- },
1096
- };
1097
- },
1098
- );
1099
- }
1100
-
1101
- @Post('/backup-code', {
1102
- validation: (validationLanguage: TLanguage) => [
1103
- body('email').optional().isEmail(),
1104
- body('username')
1105
- .optional()
1106
- .matches(AppConstants.UsernameRegex)
1107
- .withMessage(
1108
- getSuiteCoreTranslation(
1109
- SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate,
1110
- undefined,
1111
- validationLanguage,
1112
- ),
1113
- ),
1114
- body('code')
1115
- .custom((value) => {
1116
- const normalized = BackupCode.normalizeCode(value);
1117
- return (
1118
- AppConstants.BACKUP_CODES.DisplayRegex.test(value) ||
1119
- AppConstants.BACKUP_CODES.NormalizedHexRegex.test(normalized)
1120
- );
1121
- })
1122
- .withMessage(
1123
- getSuiteCoreTranslation(
1124
- SuiteCoreStringKey.Validation_InvalidBackupCode,
1125
- undefined,
1126
- validationLanguage,
1127
- ),
1128
- ),
1129
- body('recoverMnemonic').isBoolean().optional(),
1130
- body('newPassword')
1131
- .optional()
1132
- .matches(AppConstants.PasswordRegex)
1133
- .withMessage(
1134
- getSuiteCoreTranslation(
1135
- SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate,
1136
- undefined,
1137
- validationLanguage,
1138
- ),
1139
- ),
1140
- ],
1141
- })
1142
- async useBackupCodeLogin(
1143
- req: Request,
1144
- res: Response,
1145
- next: NextFunction,
1146
- ): Promise<IStatusCodeResponse<IApiLoginResponse | ApiErrorResponse>> {
1147
- return await withTransaction(
1148
- this.application.db.connection,
1149
- this.application.environment.mongo.useTransactions,
1150
- undefined,
1151
- async (sess) => {
1152
- const { code, newPassword, email, username } = this.validatedBody;
1153
-
1154
- if (!code) {
1155
- throw new GenericValidationError(
1156
- getSuiteCoreTranslation(
1157
- SuiteCoreStringKey.Validation_MissingValidatedData,
1158
- ),
1159
- );
1160
- }
1161
-
1162
- const recoverMnemonic =
1163
- this.validatedBody?.['recoverMnemonic'] === 'true' ||
1164
- this.validatedBody?.['recoverMnemonic'] === true;
1165
-
1166
- const userDoc = await this.userService.findUser(
1167
- email as string,
1168
- username as string,
1169
- sess,
1170
- );
1171
-
1172
- const {
1173
- user,
1174
- userDoc: updatedUserDoc,
1175
- codeCount,
1176
- } = await this.backupCodeService.recoverKeyWithBackupCode(
1177
- userDoc,
1178
- code as string,
1179
- newPassword ? new SecureString(newPassword as string) : undefined,
1180
- sess,
1181
- );
1182
-
1183
- let mnemonic: SecureString | undefined;
1184
- if (recoverMnemonic) {
1185
- const memberType = await this.roleService.getMemberType(
1186
- updatedUserDoc,
1187
- sess,
1188
- );
1189
- const freshUser = new BackendMember(
1190
- this.eciesService,
1191
- memberType,
1192
- updatedUserDoc.username,
1193
- new EmailString(updatedUserDoc.email),
1194
- Buffer.from(updatedUserDoc.publicKey, 'hex'),
1195
- user.privateKey,
1196
- undefined,
1197
- updatedUserDoc._id,
1198
- new Date(updatedUserDoc.createdAt),
1199
- new Date(updatedUserDoc.updatedAt),
1200
- );
1201
- mnemonic = await this.userService.recoverMnemonic(
1202
- freshUser,
1203
- updatedUserDoc.mnemonicRecovery,
1204
- );
1205
- }
1206
-
1207
- const { token, roles } = await this.jwtService.signToken(
1208
- userDoc,
1209
- this.application.environment.jwtSecret,
1210
- LanguageCodes.EN_US,
1211
- );
1212
-
1213
- this.userService.updateLastLogin(updatedUserDoc._id).catch(() => {});
1214
-
1215
- return {
1216
- statusCode: 200,
1217
- response: {
1218
- user: RequestUserService.makeRequestUserDTO(userDoc, roles),
1219
- token: token,
1220
- message: getSuiteCoreTranslation(
1221
- SuiteCoreStringKey.BackupCodeRecovery_Success,
1222
- ),
1223
- codeCount,
1224
- ...(recoverMnemonic && mnemonic
1225
- ? { mnemonic: mnemonic.value }
1226
- : {}),
1227
- serverPublicKey:
1228
- this.application.environment.systemPublicKeyHex ?? '',
1229
- },
1230
- };
1231
- },
1232
- );
1233
- }
1234
-
1235
- @Post('/forgot-password', {
1236
- validation: (validationLanguage: TLanguage) => [
1237
- body('email')
1238
- .isEmail()
1239
- .withMessage(
1240
- getSuiteCoreTranslation(
1241
- SuiteCoreStringKey.Validation_InvalidEmail,
1242
- undefined,
1243
- validationLanguage,
1244
- ),
1245
- ),
1246
- ],
1247
- })
1248
- async forgotPassword(
1249
- req: Request,
1250
- res: Response,
1251
- next: NextFunction,
1252
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
1253
- return await withTransaction(
1254
- this.application.db.connection,
1255
- this.application.environment.mongo.useTransactions,
1256
- undefined,
1257
- async (sess) => {
1258
- const { email } = this.validatedBody;
1259
-
1260
- const UserModel = this.application.getModel<IUserDocument>(
1261
- BaseModelName.User,
1262
- );
1263
- if (!isString(email)) {
1264
- throw new GenericValidationError(
1265
- getSuiteCoreTranslation(
1266
- SuiteCoreStringKey.Validation_MissingValidatedData,
1267
- ),
1268
- );
1269
- }
1270
-
1271
- const user = await UserModel.findOne({
1272
- email: email.toLowerCase(),
1273
- }).session(sess ?? null);
1274
-
1275
- if (!user || !user.passwordWrappedPrivateKey) {
1276
- return {
1277
- statusCode: 200,
1278
- response: {
1279
- message: getSuiteCoreTranslation(
1280
- SuiteCoreStringKey.PasswordReset_Success,
1281
- ),
1282
- },
1283
- };
1284
- }
1285
-
1286
- await this.userService.createAndSendEmailToken(
1287
- user,
1288
- EmailTokenType.PasswordReset,
1289
- sess,
1290
- this.application.environment.debug,
1291
- );
1292
-
1293
- return {
1294
- statusCode: 200,
1295
- response: {
1296
- message: getSuiteCoreTranslation(
1297
- SuiteCoreStringKey.PasswordReset_Success,
1298
- ),
1299
- },
1300
- };
1301
- },
1302
- );
1303
- }
1304
-
1305
- @Get('/verify-reset-token')
1306
- async verifyResetToken(
1307
- req: Request,
1308
- res: Response,
1309
- next: NextFunction,
1310
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
1311
- const token = req.query['token'] as string;
1312
- if (!token) {
1313
- throw new GenericValidationError(
1314
- getSuiteCoreTranslation(SuiteCoreStringKey.Validation_TokenMissing),
1315
- );
1316
- }
1317
-
1318
- return await withTransaction(
1319
- this.application.db.connection,
1320
- this.application.environment.mongo.useTransactions,
1321
- undefined,
1322
- async (sess) => {
1323
- await this.userService.verifyEmailToken(
1324
- token,
1325
- EmailTokenType.PasswordReset,
1326
- sess,
1327
- );
1328
- return {
1329
- statusCode: 200,
1330
- response: {
1331
- message: 'Token is valid',
1332
- },
1333
- };
1334
- },
1335
- );
1336
- }
1337
-
1338
- @Post('/reset-password', {
1339
- validation: (validationLanguage: TLanguage) => [
1340
- body('token')
1341
- .not()
1342
- .isEmpty()
1343
- .withMessage(
1344
- getSuiteCoreTranslation(
1345
- SuiteCoreStringKey.Validation_TokenRequired,
1346
- undefined,
1347
- validationLanguage,
1348
- ),
1349
- )
1350
- .matches(new RegExp(`^[a-f0-9]{${AppConstants.EmailTokenLength * 2}}$`))
1351
- .withMessage(
1352
- getSuiteCoreTranslation(
1353
- SuiteCoreStringKey.Validation_InvalidToken,
1354
- undefined,
1355
- validationLanguage,
1356
- ),
1357
- ),
1358
- body('newPassword')
1359
- .optional()
1360
- .isLength({ min: 8 })
1361
- .withMessage(
1362
- getSuiteCoreTranslation(
1363
- SuiteCoreStringKey.Validation_PasswordMinLengthTemplate,
1364
- undefined,
1365
- validationLanguage,
1366
- ),
1367
- )
1368
- .matches(AppConstants.PasswordRegex)
1369
- .withMessage(
1370
- getSuiteCoreTranslation(
1371
- SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate,
1372
- undefined,
1373
- validationLanguage,
1374
- ),
1375
- ),
1376
- body('password')
1377
- .optional()
1378
- .isLength({ min: 8 })
1379
- .withMessage(
1380
- getSuiteCoreTranslation(
1381
- SuiteCoreStringKey.Validation_PasswordMinLengthTemplate,
1382
- undefined,
1383
- validationLanguage,
1384
- ),
1385
- )
1386
- .matches(AppConstants.PasswordRegex)
1387
- .withMessage(
1388
- getSuiteCoreTranslation(
1389
- SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate,
1390
- undefined,
1391
- validationLanguage,
1392
- ),
1393
- ),
1394
- body('currentPassword').optional().isString(),
1395
- body('mnemonic').optional().isString(),
1396
- ],
1397
- })
1398
- async resetPassword(
1399
- req: Request,
1400
- res: Response,
1401
- next: NextFunction,
1402
- ): Promise<IStatusCodeResponse<IApiMessageResponse | ApiErrorResponse>> {
1403
- return await withTransaction(
1404
- this.application.db.connection,
1405
- this.application.environment.mongo.useTransactions,
1406
- undefined,
1407
- async (sess) => {
1408
- const { token, newPassword, password, currentPassword, mnemonic } =
1409
- this.validatedBody;
1410
- const selectedNewPassword = (newPassword ?? password) as
1411
- | string
1412
- | undefined;
1413
-
1414
- if (!isString(token) || !isString(selectedNewPassword)) {
1415
- throw new GenericValidationError(
1416
- getSuiteCoreTranslation(
1417
- SuiteCoreStringKey.Validation_MissingValidatedData,
1418
- ),
1419
- );
1420
- }
1421
-
1422
- const credential =
1423
- (mnemonic as string | undefined) ??
1424
- (currentPassword as string | undefined);
1425
- if (!isString(credential)) {
1426
- throw new GenericValidationError(
1427
- getSuiteCoreTranslation(
1428
- SuiteCoreStringKey.Validation_MissingValidatedData,
1429
- ),
1430
- );
1431
- }
1432
-
1433
- await this.userService.resetPasswordWithToken(
1434
- token as string,
1435
- selectedNewPassword,
1436
- credential,
1437
- sess,
1438
- );
1439
-
1440
- return {
1441
- statusCode: 200,
1442
- response: {
1443
- message: getSuiteCoreTranslation(
1444
- SuiteCoreStringKey.PasswordChange_Success,
1445
- ),
1446
- },
1447
- };
1448
- },
1449
- );
1450
- }
1451
- }