@digitaldefiance/node-express-suite 3.7.5 → 3.7.6

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