@digitaldefiance/node-express-suite 4.22.2 → 4.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. package/README.md +173 -407
  2. package/package.json +1 -5
  3. package/src/__tests__/fixtures/index.d.ts +1 -1
  4. package/src/__tests__/fixtures/index.d.ts.map +1 -1
  5. package/src/__tests__/fixtures/index.js +1 -2
  6. package/src/__tests__/fixtures/index.js.map +1 -1
  7. package/src/__tests__/helpers/index.d.ts +1 -3
  8. package/src/__tests__/helpers/index.d.ts.map +1 -1
  9. package/src/__tests__/helpers/index.js +1 -4
  10. package/src/__tests__/helpers/index.js.map +1 -1
  11. package/src/__tests__/index.d.ts.map +1 -1
  12. package/src/__tests__/index.js +1 -0
  13. package/src/__tests__/index.js.map +1 -1
  14. package/src/application.d.ts +8 -11
  15. package/src/application.d.ts.map +1 -1
  16. package/src/application.js +8 -17
  17. package/src/application.js.map +1 -1
  18. package/src/branded-responses/branded-api-responses.d.ts +10 -2
  19. package/src/branded-responses/branded-api-responses.d.ts.map +1 -1
  20. package/src/branded-responses/branded-api-responses.js +5 -0
  21. package/src/branded-responses/branded-api-responses.js.map +1 -1
  22. package/src/branded-responses/serializers.d.ts +4 -1
  23. package/src/branded-responses/serializers.d.ts.map +1 -1
  24. package/src/builders/index.d.ts +1 -1
  25. package/src/builders/index.d.ts.map +1 -1
  26. package/src/builders/index.js +1 -2
  27. package/src/builders/index.js.map +1 -1
  28. package/src/controllers/base.d.ts +5 -18
  29. package/src/controllers/base.d.ts.map +1 -1
  30. package/src/controllers/base.js +7 -62
  31. package/src/controllers/base.js.map +1 -1
  32. package/src/controllers/index.d.ts +1 -1
  33. package/src/controllers/index.d.ts.map +1 -1
  34. package/src/controllers/index.js +2 -1
  35. package/src/controllers/index.js.map +1 -1
  36. package/src/controllers/openapi.d.ts +3 -3
  37. package/src/controllers/openapi.d.ts.map +1 -1
  38. package/src/controllers/openapi.js.map +1 -1
  39. package/src/enumerations/index.d.ts +0 -2
  40. package/src/enumerations/index.d.ts.map +1 -1
  41. package/src/enumerations/index.js +0 -2
  42. package/src/enumerations/index.js.map +1 -1
  43. package/src/environment.d.ts +4 -3
  44. package/src/environment.d.ts.map +1 -1
  45. package/src/environment.js +3 -1
  46. package/src/environment.js.map +1 -1
  47. package/src/errors/index.d.ts +0 -3
  48. package/src/errors/index.d.ts.map +1 -1
  49. package/src/errors/index.js +0 -3
  50. package/src/errors/index.js.map +1 -1
  51. package/src/index.d.ts +1 -8
  52. package/src/index.d.ts.map +1 -1
  53. package/src/index.js +1 -11
  54. package/src/index.js.map +1 -1
  55. package/src/interfaces/controller-config.d.ts +1 -2
  56. package/src/interfaces/controller-config.d.ts.map +1 -1
  57. package/src/interfaces/document-store.d.ts +3 -2
  58. package/src/interfaces/document-store.d.ts.map +1 -1
  59. package/src/interfaces/document-store.js +3 -3
  60. package/src/interfaces/document-store.js.map +1 -1
  61. package/src/interfaces/environment.d.ts +3 -2
  62. package/src/interfaces/environment.d.ts.map +1 -1
  63. package/src/interfaces/index.d.ts +0 -11
  64. package/src/interfaces/index.d.ts.map +1 -1
  65. package/src/interfaces/index.js +0 -11
  66. package/src/interfaces/index.js.map +1 -1
  67. package/src/plugins/database-plugin.d.ts +12 -0
  68. package/src/plugins/database-plugin.d.ts.map +1 -1
  69. package/src/plugins/index.d.ts +0 -1
  70. package/src/plugins/index.d.ts.map +1 -1
  71. package/src/plugins/index.js +0 -1
  72. package/src/plugins/index.js.map +1 -1
  73. package/src/routers/index.d.ts +0 -1
  74. package/src/routers/index.d.ts.map +1 -1
  75. package/src/routers/index.js +0 -1
  76. package/src/routers/index.js.map +1 -1
  77. package/src/services/base.d.ts +10 -13
  78. package/src/services/base.d.ts.map +1 -1
  79. package/src/services/base.js +7 -21
  80. package/src/services/base.js.map +1 -1
  81. package/src/services/index.d.ts +0 -15
  82. package/src/services/index.d.ts.map +1 -1
  83. package/src/services/index.js +0 -15
  84. package/src/services/index.js.map +1 -1
  85. package/src/testing.d.ts +1 -1
  86. package/src/testing.d.ts.map +1 -1
  87. package/src/testing.js +1 -1
  88. package/src/testing.js.map +1 -1
  89. package/src/types.d.ts +6 -17
  90. package/src/types.d.ts.map +1 -1
  91. package/src/types.js.map +1 -1
  92. package/src/utils.d.ts +5 -34
  93. package/src/utils.d.ts.map +1 -1
  94. package/src/utils.js +24 -165
  95. package/src/utils.js.map +1 -1
  96. package/src/__tests__/fixtures/model-mocks.mock.d.ts +0 -12
  97. package/src/__tests__/fixtures/model-mocks.mock.d.ts.map +0 -1
  98. package/src/__tests__/fixtures/model-mocks.mock.js +0 -102
  99. package/src/__tests__/fixtures/model-mocks.mock.js.map +0 -1
  100. package/src/__tests__/helpers/application.mock.d.ts +0 -8
  101. package/src/__tests__/helpers/application.mock.d.ts.map +0 -1
  102. package/src/__tests__/helpers/application.mock.js +0 -85
  103. package/src/__tests__/helpers/application.mock.js.map +0 -1
  104. package/src/__tests__/helpers/setup-test-env.d.ts +0 -13
  105. package/src/__tests__/helpers/setup-test-env.d.ts.map +0 -1
  106. package/src/__tests__/helpers/setup-test-env.js +0 -133
  107. package/src/__tests__/helpers/setup-test-env.js.map +0 -1
  108. package/src/builders/application-builder.d.ts +0 -53
  109. package/src/builders/application-builder.d.ts.map +0 -1
  110. package/src/builders/application-builder.js +0 -91
  111. package/src/builders/application-builder.js.map +0 -1
  112. package/src/controllers/user.d.ts +0 -66
  113. package/src/controllers/user.d.ts.map +0 -1
  114. package/src/controllers/user.js +0 -949
  115. package/src/controllers/user.js.map +0 -1
  116. package/src/documents/base.d.ts +0 -15
  117. package/src/documents/base.d.ts.map +0 -1
  118. package/src/documents/base.js +0 -8
  119. package/src/documents/base.js.map +0 -1
  120. package/src/documents/email-token.d.ts +0 -15
  121. package/src/documents/email-token.d.ts.map +0 -1
  122. package/src/documents/email-token.js +0 -8
  123. package/src/documents/email-token.js.map +0 -1
  124. package/src/documents/index.d.ts +0 -8
  125. package/src/documents/index.d.ts.map +0 -1
  126. package/src/documents/index.js +0 -3
  127. package/src/documents/index.js.map +0 -1
  128. package/src/documents/mnemonic.d.ts +0 -16
  129. package/src/documents/mnemonic.d.ts.map +0 -1
  130. package/src/documents/mnemonic.js +0 -8
  131. package/src/documents/mnemonic.js.map +0 -1
  132. package/src/documents/role.d.ts +0 -15
  133. package/src/documents/role.d.ts.map +0 -1
  134. package/src/documents/role.js +0 -8
  135. package/src/documents/role.js.map +0 -1
  136. package/src/documents/used-direct-login-token.d.ts +0 -16
  137. package/src/documents/used-direct-login-token.d.ts.map +0 -1
  138. package/src/documents/used-direct-login-token.js +0 -8
  139. package/src/documents/used-direct-login-token.js.map +0 -1
  140. package/src/documents/user-role.d.ts +0 -16
  141. package/src/documents/user-role.d.ts.map +0 -1
  142. package/src/documents/user-role.js +0 -8
  143. package/src/documents/user-role.js.map +0 -1
  144. package/src/documents/user.d.ts +0 -16
  145. package/src/documents/user.d.ts.map +0 -1
  146. package/src/documents/user.js +0 -8
  147. package/src/documents/user.js.map +0 -1
  148. package/src/enumerations/base-model-name.d.ts +0 -43
  149. package/src/enumerations/base-model-name.d.ts.map +0 -1
  150. package/src/enumerations/base-model-name.js +0 -39
  151. package/src/enumerations/base-model-name.js.map +0 -1
  152. package/src/enumerations/schema-collection.d.ts +0 -39
  153. package/src/enumerations/schema-collection.d.ts.map +0 -1
  154. package/src/enumerations/schema-collection.js +0 -43
  155. package/src/enumerations/schema-collection.js.map +0 -1
  156. package/src/errors/invalid-model.d.ts +0 -18
  157. package/src/errors/invalid-model.d.ts.map +0 -1
  158. package/src/errors/invalid-model.js +0 -26
  159. package/src/errors/invalid-model.js.map +0 -1
  160. package/src/errors/model-not-registered.d.ts +0 -18
  161. package/src/errors/model-not-registered.d.ts.map +0 -1
  162. package/src/errors/model-not-registered.js +0 -26
  163. package/src/errors/model-not-registered.js.map +0 -1
  164. package/src/errors/mongoose-validation.d.ts +0 -28
  165. package/src/errors/mongoose-validation.d.ts.map +0 -1
  166. package/src/errors/mongoose-validation.js +0 -33
  167. package/src/errors/mongoose-validation.js.map +0 -1
  168. package/src/interfaces/api-mongo-validation-error-response.d.ts +0 -16
  169. package/src/interfaces/api-mongo-validation-error-response.d.ts.map +0 -1
  170. package/src/interfaces/api-mongo-validation-error-response.js +0 -8
  171. package/src/interfaces/api-mongo-validation-error-response.js.map +0 -1
  172. package/src/interfaces/database-init-result-tx.d.ts +0 -27
  173. package/src/interfaces/database-init-result-tx.d.ts.map +0 -1
  174. package/src/interfaces/database-init-result-tx.js +0 -3
  175. package/src/interfaces/database-init-result-tx.js.map +0 -1
  176. package/src/interfaces/db-init-result.d.ts +0 -16
  177. package/src/interfaces/db-init-result.d.ts.map +0 -1
  178. package/src/interfaces/db-init-result.js +0 -8
  179. package/src/interfaces/db-init-result.js.map +0 -1
  180. package/src/interfaces/discriminator-collections.d.ts +0 -17
  181. package/src/interfaces/discriminator-collections.d.ts.map +0 -1
  182. package/src/interfaces/discriminator-collections.js +0 -8
  183. package/src/interfaces/discriminator-collections.js.map +0 -1
  184. package/src/interfaces/environment-mongo.d.ts +0 -86
  185. package/src/interfaces/environment-mongo.d.ts.map +0 -1
  186. package/src/interfaces/environment-mongo.js +0 -8
  187. package/src/interfaces/environment-mongo.js.map +0 -1
  188. package/src/interfaces/models/email-token.d.ts +0 -12
  189. package/src/interfaces/models/email-token.d.ts.map +0 -1
  190. package/src/interfaces/models/email-token.js +0 -8
  191. package/src/interfaces/models/email-token.js.map +0 -1
  192. package/src/interfaces/models/index.d.ts +0 -8
  193. package/src/interfaces/models/index.d.ts.map +0 -1
  194. package/src/interfaces/models/index.js +0 -11
  195. package/src/interfaces/models/index.js.map +0 -1
  196. package/src/interfaces/models/mnemonic.d.ts +0 -13
  197. package/src/interfaces/models/mnemonic.d.ts.map +0 -1
  198. package/src/interfaces/models/mnemonic.js +0 -8
  199. package/src/interfaces/models/mnemonic.js.map +0 -1
  200. package/src/interfaces/models/role.d.ts +0 -12
  201. package/src/interfaces/models/role.d.ts.map +0 -1
  202. package/src/interfaces/models/role.js +0 -8
  203. package/src/interfaces/models/role.js.map +0 -1
  204. package/src/interfaces/models/token-role.d.ts +0 -19
  205. package/src/interfaces/models/token-role.d.ts.map +0 -1
  206. package/src/interfaces/models/token-role.js +0 -8
  207. package/src/interfaces/models/token-role.js.map +0 -1
  208. package/src/interfaces/models/used-direct-login-token.d.ts +0 -19
  209. package/src/interfaces/models/used-direct-login-token.d.ts.map +0 -1
  210. package/src/interfaces/models/used-direct-login-token.js +0 -8
  211. package/src/interfaces/models/used-direct-login-token.js.map +0 -1
  212. package/src/interfaces/models/user-role.d.ts +0 -19
  213. package/src/interfaces/models/user-role.d.ts.map +0 -1
  214. package/src/interfaces/models/user-role.js +0 -8
  215. package/src/interfaces/models/user-role.js.map +0 -1
  216. package/src/interfaces/models/user.d.ts +0 -21
  217. package/src/interfaces/models/user.d.ts.map +0 -1
  218. package/src/interfaces/models/user.js +0 -8
  219. package/src/interfaces/models/user.js.map +0 -1
  220. package/src/interfaces/mongo-application.d.ts +0 -35
  221. package/src/interfaces/mongo-application.d.ts.map +0 -1
  222. package/src/interfaces/mongo-application.js +0 -10
  223. package/src/interfaces/mongo-application.js.map +0 -1
  224. package/src/interfaces/mongo-errors.d.ts +0 -13
  225. package/src/interfaces/mongo-errors.d.ts.map +0 -1
  226. package/src/interfaces/mongo-errors.js +0 -8
  227. package/src/interfaces/mongo-errors.js.map +0 -1
  228. package/src/interfaces/mongoose-document-store.d.ts +0 -42
  229. package/src/interfaces/mongoose-document-store.d.ts.map +0 -1
  230. package/src/interfaces/mongoose-document-store.js +0 -10
  231. package/src/interfaces/mongoose-document-store.js.map +0 -1
  232. package/src/interfaces/schema.d.ts +0 -37
  233. package/src/interfaces/schema.d.ts.map +0 -1
  234. package/src/interfaces/schema.js +0 -8
  235. package/src/interfaces/schema.js.map +0 -1
  236. package/src/interfaces/server-init-result.d.ts +0 -45
  237. package/src/interfaces/server-init-result.d.ts.map +0 -1
  238. package/src/interfaces/server-init-result.js +0 -8
  239. package/src/interfaces/server-init-result.js.map +0 -1
  240. package/src/interfaces/test-environment.d.ts +0 -22
  241. package/src/interfaces/test-environment.d.ts.map +0 -1
  242. package/src/interfaces/test-environment.js +0 -8
  243. package/src/interfaces/test-environment.js.map +0 -1
  244. package/src/model-registry.d.ts +0 -79
  245. package/src/model-registry.d.ts.map +0 -1
  246. package/src/model-registry.js +0 -97
  247. package/src/model-registry.js.map +0 -1
  248. package/src/models/email-token.d.ts +0 -24
  249. package/src/models/email-token.d.ts.map +0 -1
  250. package/src/models/email-token.js +0 -16
  251. package/src/models/email-token.js.map +0 -1
  252. package/src/models/index.d.ts +0 -7
  253. package/src/models/index.d.ts.map +0 -1
  254. package/src/models/index.js +0 -10
  255. package/src/models/index.js.map +0 -1
  256. package/src/models/mnemonic.d.ts +0 -24
  257. package/src/models/mnemonic.d.ts.map +0 -1
  258. package/src/models/mnemonic.js +0 -27
  259. package/src/models/mnemonic.js.map +0 -1
  260. package/src/models/role.d.ts +0 -24
  261. package/src/models/role.d.ts.map +0 -1
  262. package/src/models/role.js +0 -27
  263. package/src/models/role.js.map +0 -1
  264. package/src/models/used-direct-login-token.d.ts +0 -24
  265. package/src/models/used-direct-login-token.d.ts.map +0 -1
  266. package/src/models/used-direct-login-token.js +0 -16
  267. package/src/models/used-direct-login-token.js.map +0 -1
  268. package/src/models/user-role.d.ts +0 -23
  269. package/src/models/user-role.d.ts.map +0 -1
  270. package/src/models/user-role.js +0 -26
  271. package/src/models/user-role.js.map +0 -1
  272. package/src/models/user.d.ts +0 -24
  273. package/src/models/user.d.ts.map +0 -1
  274. package/src/models/user.js +0 -27
  275. package/src/models/user.js.map +0 -1
  276. package/src/mongo-application-concrete.d.ts +0 -32
  277. package/src/mongo-application-concrete.d.ts.map +0 -1
  278. package/src/mongo-application-concrete.js +0 -49
  279. package/src/mongo-application-concrete.js.map +0 -1
  280. package/src/plugins/mongo-database-plugin.d.ts +0 -115
  281. package/src/plugins/mongo-database-plugin.d.ts.map +0 -1
  282. package/src/plugins/mongo-database-plugin.js +0 -234
  283. package/src/plugins/mongo-database-plugin.js.map +0 -1
  284. package/src/routers/api.d.ts +0 -60
  285. package/src/routers/api.d.ts.map +0 -1
  286. package/src/routers/api.js +0 -116
  287. package/src/routers/api.js.map +0 -1
  288. package/src/schemas/email-token.d.ts +0 -65
  289. package/src/schemas/email-token.d.ts.map +0 -1
  290. package/src/schemas/email-token.js +0 -68
  291. package/src/schemas/email-token.js.map +0 -1
  292. package/src/schemas/index.d.ts +0 -8
  293. package/src/schemas/index.d.ts.map +0 -1
  294. package/src/schemas/index.js +0 -11
  295. package/src/schemas/index.js.map +0 -1
  296. package/src/schemas/mnemonic.d.ts +0 -37
  297. package/src/schemas/mnemonic.d.ts.map +0 -1
  298. package/src/schemas/mnemonic.js +0 -41
  299. package/src/schemas/mnemonic.js.map +0 -1
  300. package/src/schemas/role.d.ts +0 -57
  301. package/src/schemas/role.d.ts.map +0 -1
  302. package/src/schemas/role.js +0 -102
  303. package/src/schemas/role.js.map +0 -1
  304. package/src/schemas/schema.d.ts +0 -62
  305. package/src/schemas/schema.d.ts.map +0 -1
  306. package/src/schemas/schema.js +0 -81
  307. package/src/schemas/schema.js.map +0 -1
  308. package/src/schemas/used-direct-login-token.d.ts +0 -49
  309. package/src/schemas/used-direct-login-token.d.ts.map +0 -1
  310. package/src/schemas/used-direct-login-token.js +0 -35
  311. package/src/schemas/used-direct-login-token.js.map +0 -1
  312. package/src/schemas/user-role.d.ts +0 -52
  313. package/src/schemas/user-role.d.ts.map +0 -1
  314. package/src/schemas/user-role.js +0 -67
  315. package/src/schemas/user-role.js.map +0 -1
  316. package/src/schemas/user.d.ts +0 -43
  317. package/src/schemas/user.d.ts.map +0 -1
  318. package/src/schemas/user.js +0 -214
  319. package/src/schemas/user.js.map +0 -1
  320. package/src/services/backup-code.d.ts +0 -120
  321. package/src/services/backup-code.d.ts.map +0 -1
  322. package/src/services/backup-code.js +0 -323
  323. package/src/services/backup-code.js.map +0 -1
  324. package/src/services/database-initialization.d.ts +0 -138
  325. package/src/services/database-initialization.d.ts.map +0 -1
  326. package/src/services/database-initialization.js +0 -913
  327. package/src/services/database-initialization.js.map +0 -1
  328. package/src/services/db-init-cache.d.ts +0 -18
  329. package/src/services/db-init-cache.d.ts.map +0 -1
  330. package/src/services/db-init-cache.js +0 -7
  331. package/src/services/db-init-cache.js.map +0 -1
  332. package/src/services/direct-login-token.d.ts +0 -28
  333. package/src/services/direct-login-token.d.ts.map +0 -1
  334. package/src/services/direct-login-token.js +0 -62
  335. package/src/services/direct-login-token.js.map +0 -1
  336. package/src/services/jwt.d.ts +0 -45
  337. package/src/services/jwt.d.ts.map +0 -1
  338. package/src/services/jwt.js +0 -105
  339. package/src/services/jwt.js.map +0 -1
  340. package/src/services/mnemonic.d.ts +0 -68
  341. package/src/services/mnemonic.d.ts.map +0 -1
  342. package/src/services/mnemonic.js +0 -120
  343. package/src/services/mnemonic.js.map +0 -1
  344. package/src/services/mongo-authentication-provider.d.ts +0 -27
  345. package/src/services/mongo-authentication-provider.d.ts.map +0 -1
  346. package/src/services/mongo-authentication-provider.js +0 -84
  347. package/src/services/mongo-authentication-provider.js.map +0 -1
  348. package/src/services/mongo-backup-code-store.d.ts +0 -40
  349. package/src/services/mongo-backup-code-store.d.ts.map +0 -1
  350. package/src/services/mongo-backup-code-store.js +0 -104
  351. package/src/services/mongo-backup-code-store.js.map +0 -1
  352. package/src/services/mongo-base.d.ts +0 -24
  353. package/src/services/mongo-base.d.ts.map +0 -1
  354. package/src/services/mongo-base.js +0 -28
  355. package/src/services/mongo-base.js.map +0 -1
  356. package/src/services/mongoose-collection.d.ts +0 -52
  357. package/src/services/mongoose-collection.d.ts.map +0 -1
  358. package/src/services/mongoose-collection.js +0 -326
  359. package/src/services/mongoose-collection.js.map +0 -1
  360. package/src/services/mongoose-database.d.ts +0 -64
  361. package/src/services/mongoose-database.d.ts.map +0 -1
  362. package/src/services/mongoose-database.js +0 -121
  363. package/src/services/mongoose-database.js.map +0 -1
  364. package/src/services/mongoose-document-store.d.ts +0 -109
  365. package/src/services/mongoose-document-store.d.ts.map +0 -1
  366. package/src/services/mongoose-document-store.js +0 -264
  367. package/src/services/mongoose-document-store.js.map +0 -1
  368. package/src/services/mongoose-session-adapter.d.ts +0 -39
  369. package/src/services/mongoose-session-adapter.d.ts.map +0 -1
  370. package/src/services/mongoose-session-adapter.js +0 -63
  371. package/src/services/mongoose-session-adapter.js.map +0 -1
  372. package/src/services/request-user.d.ts +0 -45
  373. package/src/services/request-user.d.ts.map +0 -1
  374. package/src/services/request-user.js +0 -90
  375. package/src/services/request-user.js.map +0 -1
  376. package/src/services/role.d.ts +0 -97
  377. package/src/services/role.d.ts.map +0 -1
  378. package/src/services/role.js +0 -289
  379. package/src/services/role.js.map +0 -1
  380. package/src/services/user.d.ts +0 -368
  381. package/src/services/user.d.ts.map +0 -1
  382. package/src/services/user.js +0 -1495
  383. package/src/services/user.js.map +0 -1
  384. package/src/transactions/index.d.ts +0 -2
  385. package/src/transactions/index.d.ts.map +0 -1
  386. package/src/transactions/index.js +0 -5
  387. package/src/transactions/index.js.map +0 -1
  388. package/src/transactions/transaction-manager.d.ts +0 -37
  389. package/src/transactions/transaction-manager.d.ts.map +0 -1
  390. package/src/transactions/transaction-manager.js +0 -50
  391. package/src/transactions/transaction-manager.js.map +0 -1
  392. package/src/types/mongoose-helpers.d.ts +0 -16
  393. package/src/types/mongoose-helpers.d.ts.map +0 -1
  394. package/src/types/mongoose-helpers.js +0 -8
  395. package/src/types/mongoose-helpers.js.map +0 -1
  396. package/src/utils/default-mongo-uri-validator.d.ts +0 -15
  397. package/src/utils/default-mongo-uri-validator.d.ts.map +0 -1
  398. package/src/utils/default-mongo-uri-validator.js +0 -46
  399. package/src/utils/default-mongo-uri-validator.js.map +0 -1
@@ -1,214 +0,0 @@
1
- "use strict";
2
- /**
3
- * @fileoverview User schema factory for MongoDB with comprehensive validation.
4
- * Creates schema for user management with authentication and preferences.
5
- * @module schemas/user
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.UserSchema = void 0;
9
- exports.createUserSchema = createUserSchema;
10
- const tslib_1 = require("tslib");
11
- const i18n_lib_1 = require("@digitaldefiance/i18n-lib");
12
- const mongoose_types_1 = require("@digitaldefiance/mongoose-types");
13
- const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
14
- const currency_codes_1 = require("currency-codes");
15
- const validator_1 = tslib_1.__importDefault(require("validator"));
16
- const constants_1 = require("../constants");
17
- const enumerations_1 = require("../enumerations");
18
- /**
19
- * Creates a user schema with custom or default constants.
20
- * Includes validation for username, email, timezone, currency, and language.
21
- * @template T - Constants type extending IConstants
22
- * @param {Function} [usernameValidationMessage] - Custom username validation message
23
- * @param {Function} [emailValidationMessage] - Custom email validation message
24
- * @param {Function} [timezoneValidationMessage] - Custom timezone validation message
25
- * @param {Function} [currencyValidationMessage] - Custom currency validation message
26
- * @param {readonly string[]} [supportedLanguages] - Supported language codes
27
- * @param {any} idType - ID type for references (defaults to ObjectId)
28
- * @param {T} constants - Constants for validation (defaults to AppConstants)
29
- * @returns {Schema} Configured user schema with timestamps
30
- */
31
- function createUserSchema(usernameValidationMessage, emailValidationMessage, timezoneValidationMessage, currencyValidationMessage, supportedLanguages, idType = mongoose_types_1.Schema.Types.ObjectId, constants = constants_1.LocalhostConstants) {
32
- const definition = {
33
- /**
34
- * The unique identifier for the user
35
- */
36
- username: {
37
- type: String,
38
- required: true,
39
- unique: true,
40
- validate: {
41
- validator: (v) => constants.UsernameRegex.test(v),
42
- message: usernameValidationMessage ||
43
- (() => (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate)),
44
- },
45
- },
46
- /**
47
- * The email address for the user
48
- */
49
- email: {
50
- type: String,
51
- required: true,
52
- unique: true,
53
- validate: {
54
- validator: (v) => validator_1.default.isEmail(v),
55
- message: emailValidationMessage ||
56
- ((props) => (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Error_InvalidEmailTemplate, { email: props.value })),
57
- },
58
- },
59
- /**
60
- * The user's public key, stored in hex format.
61
- */
62
- publicKey: {
63
- type: String,
64
- required: true,
65
- unique: true,
66
- },
67
- /**
68
- * The timezone for the user
69
- */
70
- timezone: {
71
- type: String,
72
- required: true,
73
- default: 'UTC',
74
- validate: {
75
- validator: function (v) {
76
- return (0, i18n_lib_1.isValidTimezone)(v);
77
- },
78
- message: timezoneValidationMessage ||
79
- ((props) => (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Common_NotValidTimeZoneTemplate, { timezone: props.value })),
80
- },
81
- },
82
- currency: {
83
- type: String,
84
- required: true,
85
- default: 'USD',
86
- validate: {
87
- validator: function (v) {
88
- return (0, currency_codes_1.codes)().includes(v);
89
- },
90
- message: currencyValidationMessage ||
91
- ((props) => (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Common_NotValidCurrencyTemplate, { currency: props.value })),
92
- },
93
- },
94
- /**
95
- * The language of the site for the user
96
- */
97
- siteLanguage: {
98
- type: String,
99
- enum: supportedLanguages || Object.values(i18n_lib_1.LanguageCodes),
100
- default: i18n_lib_1.LanguageCodes.EN_US,
101
- required: true,
102
- },
103
- /**
104
- * Whether the user prefers dark mode
105
- */
106
- darkMode: {
107
- type: Boolean,
108
- default: false,
109
- required: true,
110
- },
111
- /**
112
- * Whether to enable direct challenge login for the user
113
- */
114
- directChallenge: {
115
- type: Boolean,
116
- default: true,
117
- required: true,
118
- },
119
- /**
120
- * The date the user last logged in
121
- */
122
- lastLogin: { type: Date, required: false },
123
- /**
124
- * Whether the user has verified their email address
125
- */
126
- emailVerified: { type: Boolean, default: false },
127
- /**
128
- * The status of the user's account
129
- */
130
- accountStatus: {
131
- type: String,
132
- enum: Object.values(suite_core_lib_1.AccountStatus),
133
- default: suite_core_lib_1.AccountStatus.PendingEmailVerification,
134
- },
135
- /**
136
- * The user who created the user.
137
- */
138
- createdBy: {
139
- type: idType,
140
- ref: enumerations_1.BaseModelName.User,
141
- required: true,
142
- immutable: true,
143
- },
144
- /**
145
- * The user who last updated the user.
146
- */
147
- updatedBy: {
148
- type: idType,
149
- ref: enumerations_1.BaseModelName.User,
150
- optional: true,
151
- },
152
- /**
153
- * The date/time the user was deleted.
154
- */
155
- deletedAt: { type: Date, optional: true },
156
- /**
157
- * The user who deleted the user.
158
- */
159
- deletedBy: {
160
- type: idType,
161
- ref: enumerations_1.BaseModelName.User,
162
- optional: true,
163
- },
164
- /**
165
- * Reference to the mnemonic document
166
- */
167
- mnemonicId: {
168
- type: idType,
169
- ref: enumerations_1.BaseModelName.Mnemonic,
170
- required: false,
171
- },
172
- /**
173
- * Copy of the mnemonic encrypted with the user's public key
174
- */
175
- mnemonicRecovery: {
176
- type: String,
177
- required: false,
178
- },
179
- /**
180
- * Password-wrapped ECIES private key (Option B)
181
- */
182
- passwordWrappedPrivateKey: {
183
- type: {
184
- salt: { type: String, required: true },
185
- iv: { type: String, required: true },
186
- authTag: { type: String, required: true },
187
- ciphertext: { type: String, required: true },
188
- iterations: { type: Number, required: true },
189
- },
190
- required: false,
191
- },
192
- /**
193
- * Array of backup codes to recover mnemonic/private key
194
- */
195
- backupCodes: {
196
- type: [
197
- {
198
- version: { type: String, required: true },
199
- checksumSalt: { type: String, required: true },
200
- checksum: { type: String, required: true },
201
- encrypted: { type: String, required: true },
202
- },
203
- ],
204
- default: [],
205
- },
206
- };
207
- return new mongoose_types_1.Schema(definition, { timestamps: true });
208
- }
209
- /**
210
- * Default user schema with base configuration.
211
- * Pre-configured schema with standard validation and supported languages.
212
- */
213
- exports.UserSchema = createUserSchema();
214
- //# sourceMappingURL=user.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-node-express-suite/src/schemas/user.ts"],"names":[],"mappings":"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"}
@@ -1,120 +0,0 @@
1
- /**
2
- * @fileoverview Backup code service for secure account recovery.
3
- * Implements v1.0.0 backup code scheme with Argon2id KDF and HKDF-SHA256 checksums.
4
- *
5
- * Storage-agnostic: accepts an optional {@link IBackupCodeStore} for persistence.
6
- * When no store is provided, falls back to direct UserDocument manipulation
7
- * (backward-compatible Mongoose path).
8
- *
9
- * @module services/backup-code
10
- */
11
- import { SecureString } from '@digitaldefiance/ecies-lib';
12
- import { ClientSession } from '@digitaldefiance/mongoose-types';
13
- import { Member as BackendMember, ECIESService, PlatformID } from '@digitaldefiance/node-ecies-lib';
14
- import { IBackupCode, ITokenRole } from '@digitaldefiance/suite-core-lib';
15
- import { UserDocument } from '../documents';
16
- import { IApplication } from '../interfaces/application';
17
- import type { IBackupCodeStore, IBackupCodeUserRecord } from '../interfaces/backup-code-store';
18
- import { BaseService } from './base';
19
- import { KeyWrappingService } from './index';
20
- import { RoleService } from './role';
21
- /**
22
- * Service for backup code generation, validation, and key recovery.
23
- * Implements secure backup code scheme with constant-time validation and key wrapping.
24
- *
25
- * Storage is abstracted via {@link IBackupCodeStore}. When a store is provided,
26
- * all persistence goes through the store interface. When omitted, the service
27
- * falls back to direct UserDocument manipulation for backward compatibility
28
- * with existing Mongoose-based consumers.
29
- *
30
- * @template TID - Platform ID type (defaults to Buffer)
31
- * @template TDate - Date type (defaults to Date)
32
- * @template TTokenRole - Token role interface type
33
- * @template TApplication - Application interface type
34
- * @extends {BaseService<TID>}
35
- */
36
- export declare class BackupCodeService<TID extends PlatformID = Buffer, TDate extends Date = Date, TTokenRole extends ITokenRole<TID, TDate> = ITokenRole<TID, TDate>, TApplication extends IApplication<TID> = IApplication<TID>> extends BaseService<TID> {
37
- private readonly eciesService;
38
- private systemUser?;
39
- private readonly keyWrappingService;
40
- private readonly roleService;
41
- private readonly store?;
42
- /**
43
- * Construct a BackupCodeService.
44
- * @param application - The application instance
45
- * @param eciesService - ECIES cryptographic service
46
- * @param keyWrappingService - Key wrapping service for password-based key protection
47
- * @param roleService - Role service for member type resolution
48
- * @param store - Optional storage adapter. When omitted, falls back to direct
49
- * UserDocument manipulation (Mongoose). Provide an IBackupCodeStore implementation
50
- * for non-Mongoose backends (e.g. BrightDB).
51
- */
52
- constructor(application: TApplication, eciesService: ECIESService<TID>, keyWrappingService: KeyWrappingService, roleService: RoleService<TID, TDate, TTokenRole>, store?: IBackupCodeStore<TID>);
53
- /**
54
- * Get the lazily-initialized system user for key wrapping/unwrapping.
55
- */
56
- private getSystemUser;
57
- /**
58
- * Forcibly set the system user (for database initialization)
59
- * @param user
60
- */
61
- setSystemUser(user: BackendMember<TID>): void;
62
- /**
63
- * v1: Consume (validate and remove) a backup code via constant-time checksum match.
64
- */
65
- useBackupCodeV1(encryptedBackupCodes: Array<IBackupCode>, backupCode: string): {
66
- newCodesArray: Array<IBackupCode>;
67
- code: IBackupCode;
68
- };
69
- /**
70
- * Consume a backup code by first detecting the version and then dispatching to the appropriate handler.
71
- */
72
- useBackupCode(encryptedBackupCodes: Array<IBackupCode>, backupCode: string): {
73
- newCodesArray: Array<IBackupCode>;
74
- code: IBackupCode;
75
- };
76
- /**
77
- * Recover a user's private key using a backup code.
78
- * Storage-agnostic: uses IBackupCodeStore when available, otherwise
79
- * falls back to the legacy UserDocument path.
80
- *
81
- * @param userOrId - Either a UserDocument (legacy) or a user ID (store-based)
82
- * @param backupCode - The plaintext backup code
83
- * @param newPassword - Optional new password to re-wrap the private key
84
- * @param session - Optional database session for transactional consistency
85
- */
86
- recoverKeyWithBackupCodeV1(userOrId: UserDocument<string, TID> | TID, backupCode: string, newPassword?: SecureString, session?: ClientSession): Promise<{
87
- userDoc?: UserDocument<string, TID>;
88
- userRecord?: IBackupCodeUserRecord<TID>;
89
- user: BackendMember<TID>;
90
- codeCount: number;
91
- }>;
92
- /**
93
- * Recover a user's private key using a backup code (version-dispatched).
94
- * Accepts either a UserDocument (legacy) or a user ID (store-based).
95
- */
96
- recoverKeyWithBackupCode(userOrId: UserDocument<string, TID> | TID, backupCode: string, newPassword?: SecureString, session?: ClientSession): Promise<{
97
- userDoc?: UserDocument<string, TID>;
98
- userRecord?: IBackupCodeUserRecord<TID>;
99
- user: BackendMember<TID>;
100
- codeCount: number;
101
- }>;
102
- /**
103
- * Rewrap system-wrapped AEAD blobs from old system key to new one.
104
- *
105
- * When a store is provided, uses the store's fetchBatch/updateUserRecord.
106
- * Otherwise falls back to the legacy callback-based approach.
107
- */
108
- rewrapAllUsersBackupCodes(fetchBatchOrOldSystem: ((afterId?: string, limit?: number) => Promise<UserDocument<string, TID>[]>) | BackendMember, saveUserOrNewSystem: ((user: UserDocument<string, TID>) => Promise<void>) | BackendMember, oldSystemOrOptions?: BackendMember | {
109
- batchSize?: number;
110
- onProgress?: (count: number) => void;
111
- }, newSystemOrUndefined?: BackendMember, options?: {
112
- batchSize?: number;
113
- onProgress?: (count: number) => void;
114
- }): Promise<number>;
115
- private _recoverViaStore;
116
- private _recoverViaUserDoc;
117
- private _rewrapViaStore;
118
- private _rewrapViaCallbacks;
119
- }
120
- //# sourceMappingURL=backup-code.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"backup-code.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-node-express-suite/src/services/backup-code.ts"],"names":[],"mappings":"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"}
@@ -1,323 +0,0 @@
1
- "use strict";
2
- /**
3
- * @fileoverview Backup code service for secure account recovery.
4
- * Implements v1.0.0 backup code scheme with Argon2id KDF and HKDF-SHA256 checksums.
5
- *
6
- * Storage-agnostic: accepts an optional {@link IBackupCodeStore} for persistence.
7
- * When no store is provided, falls back to direct UserDocument manipulation
8
- * (backward-compatible Mongoose path).
9
- *
10
- * @module services/backup-code
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.BackupCodeService = void 0;
14
- const ecies_lib_1 = require("@digitaldefiance/ecies-lib");
15
- const node_ecies_lib_1 = require("@digitaldefiance/node-ecies-lib");
16
- const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
17
- const crypto_1 = require("crypto");
18
- const backup_code_1 = require("../backup-code");
19
- const constants_1 = require("../constants");
20
- const invalid_backup_code_version_1 = require("../errors/invalid-backup-code-version");
21
- const base_1 = require("./base");
22
- const symmetric_1 = require("./symmetric");
23
- const system_user_1 = require("./system-user");
24
- /**
25
- * Service for backup code generation, validation, and key recovery.
26
- * Implements secure backup code scheme with constant-time validation and key wrapping.
27
- *
28
- * Storage is abstracted via {@link IBackupCodeStore}. When a store is provided,
29
- * all persistence goes through the store interface. When omitted, the service
30
- * falls back to direct UserDocument manipulation for backward compatibility
31
- * with existing Mongoose-based consumers.
32
- *
33
- * @template TID - Platform ID type (defaults to Buffer)
34
- * @template TDate - Date type (defaults to Date)
35
- * @template TTokenRole - Token role interface type
36
- * @template TApplication - Application interface type
37
- * @extends {BaseService<TID>}
38
- */
39
- class BackupCodeService extends base_1.BaseService {
40
- eciesService;
41
- systemUser;
42
- keyWrappingService;
43
- roleService;
44
- store;
45
- /**
46
- * Construct a BackupCodeService.
47
- * @param application - The application instance
48
- * @param eciesService - ECIES cryptographic service
49
- * @param keyWrappingService - Key wrapping service for password-based key protection
50
- * @param roleService - Role service for member type resolution
51
- * @param store - Optional storage adapter. When omitted, falls back to direct
52
- * UserDocument manipulation (Mongoose). Provide an IBackupCodeStore implementation
53
- * for non-Mongoose backends (e.g. BrightDB).
54
- */
55
- constructor(application, eciesService, keyWrappingService, roleService, store) {
56
- super(application);
57
- this.eciesService = eciesService;
58
- this.keyWrappingService = keyWrappingService;
59
- this.roleService = roleService;
60
- this.store = store;
61
- }
62
- /**
63
- * Get the lazily-initialized system user for key wrapping/unwrapping.
64
- */
65
- getSystemUser() {
66
- if (!this.systemUser) {
67
- this.systemUser = system_user_1.SystemUserService.getSystemUser(this.application.environment, this.application.constants);
68
- }
69
- return this.systemUser;
70
- }
71
- /**
72
- * Forcibly set the system user (for database initialization)
73
- * @param user
74
- */
75
- setSystemUser(user) {
76
- this.systemUser = user;
77
- }
78
- // ── Pure crypto operations (no storage dependency) ─────────────────────
79
- /**
80
- * v1: Consume (validate and remove) a backup code via constant-time checksum match.
81
- */
82
- useBackupCodeV1(encryptedBackupCodes, backupCode) {
83
- const normalizedCode = backup_code_1.BackupCode.normalizeCode(backupCode);
84
- if (!constants_1.LocalhostConstants.BACKUP_CODES.NormalizedHexRegex.test(normalizedCode)) {
85
- throw new suite_core_lib_1.InvalidBackupCodeError();
86
- }
87
- const codeBytes = Buffer.from(normalizedCode, 'utf8');
88
- try {
89
- for (const code of encryptedBackupCodes) {
90
- if (code.version !== backup_code_1.BackupCode.BackupCodeVersion)
91
- continue;
92
- const checksumSalt = Buffer.from(code.checksumSalt, 'hex');
93
- const expected = backup_code_1.BackupCode.hkdfSha256(codeBytes, checksumSalt, Buffer.from('backup-checksum'), 32);
94
- if (code.checksum.length === expected.length * 2 &&
95
- (0, crypto_1.timingSafeEqual)(Buffer.from(code.checksum, 'hex'), expected)) {
96
- const checksumHex = expected.toString('hex');
97
- return {
98
- newCodesArray: encryptedBackupCodes.filter((c) => c.checksum !== checksumHex),
99
- code,
100
- };
101
- }
102
- }
103
- throw new suite_core_lib_1.InvalidBackupCodeError();
104
- }
105
- finally {
106
- codeBytes.fill(0);
107
- }
108
- }
109
- /**
110
- * Consume a backup code by first detecting the version and then dispatching to the appropriate handler.
111
- */
112
- useBackupCode(encryptedBackupCodes, backupCode) {
113
- const version = backup_code_1.BackupCode.detectBackupCodeVersion(encryptedBackupCodes, backupCode);
114
- switch (version) {
115
- case backup_code_1.BackupCode.BackupCodeVersion:
116
- return this.useBackupCodeV1(encryptedBackupCodes.filter((c) => c.version === backup_code_1.BackupCode.BackupCodeVersion), backupCode);
117
- default:
118
- throw new invalid_backup_code_version_1.InvalidBackupCodeVersionError(version);
119
- }
120
- }
121
- // ── Storage-agnostic recovery ──────────────────────────────────────────
122
- /**
123
- * Recover a user's private key using a backup code.
124
- * Storage-agnostic: uses IBackupCodeStore when available, otherwise
125
- * falls back to the legacy UserDocument path.
126
- *
127
- * @param userOrId - Either a UserDocument (legacy) or a user ID (store-based)
128
- * @param backupCode - The plaintext backup code
129
- * @param newPassword - Optional new password to re-wrap the private key
130
- * @param session - Optional database session for transactional consistency
131
- */
132
- async recoverKeyWithBackupCodeV1(userOrId, backupCode, newPassword, session) {
133
- // Store-based path
134
- if (this.store && !userOrId.save) {
135
- return this._recoverViaStore(userOrId, backupCode, newPassword);
136
- }
137
- // Legacy Mongoose path
138
- return this._recoverViaUserDoc(userOrId, backupCode, newPassword, session);
139
- }
140
- /**
141
- * Recover a user's private key using a backup code (version-dispatched).
142
- * Accepts either a UserDocument (legacy) or a user ID (store-based).
143
- */
144
- async recoverKeyWithBackupCode(userOrId, backupCode, newPassword, session) {
145
- // Determine backup codes source
146
- let backupCodes;
147
- if (this.store && !userOrId.save) {
148
- const record = await this.store.getUserRecord(userOrId);
149
- if (!record)
150
- throw new suite_core_lib_1.InvalidBackupCodeError();
151
- backupCodes = record.backupCodes;
152
- }
153
- else {
154
- backupCodes = userOrId.backupCodes;
155
- }
156
- const version = backup_code_1.BackupCode.detectBackupCodeVersion(backupCodes, backupCode);
157
- switch (version) {
158
- case backup_code_1.BackupCode.BackupCodeVersion:
159
- return this.recoverKeyWithBackupCodeV1(userOrId, backupCode, newPassword, session);
160
- default:
161
- throw new invalid_backup_code_version_1.InvalidBackupCodeVersionError(version);
162
- }
163
- }
164
- // ── Rewrap (key rotation) ─────────────────────────────────────────────
165
- /**
166
- * Rewrap system-wrapped AEAD blobs from old system key to new one.
167
- *
168
- * When a store is provided, uses the store's fetchBatch/updateUserRecord.
169
- * Otherwise falls back to the legacy callback-based approach.
170
- */
171
- async rewrapAllUsersBackupCodes(fetchBatchOrOldSystem, saveUserOrNewSystem, oldSystemOrOptions, newSystemOrUndefined, options) {
172
- // Detect which overload is being used
173
- if (this.store && typeof fetchBatchOrOldSystem !== 'function') {
174
- // Store-based: rewrapAllUsersBackupCodes(oldSystem, newSystem, options?)
175
- return this._rewrapViaStore(fetchBatchOrOldSystem, saveUserOrNewSystem, oldSystemOrOptions);
176
- }
177
- // Legacy callback-based: rewrapAllUsersBackupCodes(fetchBatch, saveUser, oldSystem, newSystem, options?)
178
- return this._rewrapViaCallbacks(fetchBatchOrOldSystem, saveUserOrNewSystem, oldSystemOrOptions, newSystemOrUndefined, options);
179
- }
180
- // ── Private: store-based recovery ─────────────────────────────────────
181
- async _recoverViaStore(userId, backupCode, newPassword) {
182
- const store = this.store;
183
- const record = await store.getUserRecord(userId);
184
- if (!record)
185
- throw new suite_core_lib_1.InvalidBackupCodeError();
186
- const normalizedCode = backup_code_1.BackupCode.normalizeCode(backupCode);
187
- const { code, newCodesArray } = this.useBackupCodeV1(record.backupCodes, normalizedCode);
188
- let decryptionKey;
189
- try {
190
- const adminMember = this.getSystemUser();
191
- decryptionKey = await backup_code_1.BackupCode.getBackupKeyV1(code.checksumSalt, normalizedCode, this.application.constants);
192
- const privateKeyUnwrapped = await adminMember.decryptData(Buffer.from(code.encrypted, 'hex'));
193
- const decryptedPrivateKey = new ecies_lib_1.SecureBuffer(symmetric_1.SymmetricService.decryptBuffer(privateKeyUnwrapped, decryptionKey));
194
- const memberType = await store.getMemberType(userId);
195
- const user = new node_ecies_lib_1.Member(this.eciesService, memberType, record.username, new ecies_lib_1.EmailString(record.email), Buffer.from(record.publicKey, 'hex'), decryptedPrivateKey, undefined, record._id, new Date(record.createdAt), new Date(record.updatedAt));
196
- const updates = {
197
- backupCodes: newCodesArray,
198
- };
199
- if (newPassword) {
200
- updates.passwordWrappedPrivateKey = this.keyWrappingService.wrapSecret(decryptedPrivateKey, newPassword, this.application.constants);
201
- }
202
- await store.updateUserRecord(userId, updates);
203
- // Update the record in-place for the caller
204
- record.backupCodes = newCodesArray;
205
- if (updates.passwordWrappedPrivateKey) {
206
- record.passwordWrappedPrivateKey = updates.passwordWrappedPrivateKey;
207
- }
208
- return { userRecord: record, user, codeCount: newCodesArray.length };
209
- }
210
- finally {
211
- if (decryptionKey)
212
- decryptionKey.fill(0);
213
- }
214
- }
215
- // ── Private: legacy Mongoose recovery ─────────────────────────────────
216
- async _recoverViaUserDoc(userDoc, backupCode, newPassword, session) {
217
- const normalizedCode = backup_code_1.BackupCode.normalizeCode(backupCode);
218
- return await this.withTransaction(async (sess) => {
219
- const { code, newCodesArray } = this.useBackupCodeV1(userDoc.backupCodes, normalizedCode);
220
- userDoc.backupCodes = newCodesArray;
221
- let decryptionKey;
222
- try {
223
- const adminMember = this.getSystemUser();
224
- decryptionKey = await backup_code_1.BackupCode.getBackupKeyV1(code.checksumSalt, normalizedCode, this.application.constants);
225
- const privateKeyUnwrapped = await adminMember.decryptData(Buffer.from(code.encrypted, 'hex'));
226
- const decryptedPrivateKey = new ecies_lib_1.SecureBuffer(symmetric_1.SymmetricService.decryptBuffer(privateKeyUnwrapped, decryptionKey));
227
- const memberType = await this.roleService.getMemberType(userDoc, session);
228
- const user = new node_ecies_lib_1.Member(this.eciesService, memberType, userDoc.username, new ecies_lib_1.EmailString(userDoc.email), Buffer.from(userDoc.publicKey, 'hex'), decryptedPrivateKey, undefined, userDoc._id, new Date(userDoc.createdAt), new Date(userDoc.updatedAt));
229
- if (!newPassword) {
230
- await userDoc.save({ session: sess });
231
- return {
232
- userDoc,
233
- user,
234
- codeCount: newCodesArray.length,
235
- };
236
- }
237
- const wrapped = this.keyWrappingService.wrapSecret(decryptedPrivateKey, newPassword, this.application.constants);
238
- userDoc.passwordWrappedPrivateKey = wrapped;
239
- await userDoc.save({ session: sess });
240
- return { userDoc, user, codeCount: newCodesArray.length };
241
- }
242
- finally {
243
- if (decryptionKey)
244
- decryptionKey.fill(0);
245
- }
246
- }, session, {
247
- timeoutMs: this.application.environment.mongo.transactionTimeout * 5,
248
- });
249
- }
250
- // ── Private: store-based rewrap ───────────────────────────────────────
251
- async _rewrapViaStore(oldSystem, newSystem, options) {
252
- const store = this.store;
253
- const batchSize = options?.batchSize ?? 500;
254
- let processed = 0;
255
- let afterId;
256
- for (;;) {
257
- const records = await store.fetchBatch(afterId, batchSize);
258
- if (!records.length)
259
- break;
260
- for (const record of records) {
261
- let modified = false;
262
- for (const bc of record.backupCodes ?? []) {
263
- try {
264
- const sealed = await oldSystem.decryptData(Buffer.from(bc.encrypted, 'hex'));
265
- const rewrapped = (await newSystem.encryptData(sealed)).toString('hex');
266
- if (rewrapped !== bc.encrypted) {
267
- bc.encrypted = rewrapped;
268
- modified = true;
269
- }
270
- }
271
- catch (e) {
272
- throw new Error(`Failed to rewrap backup code for user ${record._id}: ${e.message}`);
273
- }
274
- }
275
- if (modified) {
276
- await store.updateUserRecord(record._id, {
277
- backupCodes: record.backupCodes,
278
- });
279
- processed++;
280
- options?.onProgress?.(processed);
281
- }
282
- }
283
- afterId = records[records.length - 1]?._id?.toString() ?? undefined;
284
- }
285
- return processed;
286
- }
287
- // ── Private: legacy callback-based rewrap ─────────────────────────────
288
- async _rewrapViaCallbacks(fetchBatch, saveUser, oldSystem, newSystem, options) {
289
- const batchSize = options?.batchSize ?? 500;
290
- let processed = 0;
291
- let afterId;
292
- for (;;) {
293
- const users = await fetchBatch(afterId, batchSize);
294
- if (!users.length)
295
- break;
296
- for (const user of users) {
297
- let modified = false;
298
- for (const bc of user.backupCodes ?? []) {
299
- try {
300
- const sealed = await oldSystem.decryptData(Buffer.from(bc.encrypted, 'hex'));
301
- const rewrapped = (await newSystem.encryptData(sealed)).toString('hex');
302
- if (rewrapped !== bc.encrypted) {
303
- bc.encrypted = rewrapped;
304
- modified = true;
305
- }
306
- }
307
- catch (e) {
308
- throw new Error(`Failed to rewrap backup code for user ${user._id}: ${e.message}`);
309
- }
310
- }
311
- if (modified) {
312
- await saveUser(user);
313
- processed++;
314
- options?.onProgress?.(processed);
315
- }
316
- }
317
- afterId = users[users.length - 1]?._id?.toString() ?? undefined;
318
- }
319
- return processed;
320
- }
321
- }
322
- exports.BackupCodeService = BackupCodeService;
323
- //# sourceMappingURL=backup-code.js.map