@futdevpro/nts-dynamo 1.15.140 → 1.15.141

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 (293) hide show
  1. package/README.md +27 -0
  2. package/__documentations/2026-08-18-standalone-account-security-and-privacy-bedrock.md +131 -0
  3. package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.d.ts +6 -0
  4. package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.d.ts.map +1 -0
  5. package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.js +10 -0
  6. package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.js.map +1 -0
  7. package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.d.ts +7 -0
  8. package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.d.ts.map +1 -0
  9. package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.js +11 -0
  10. package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.js.map +1 -0
  11. package/build/_modules/account-security/_enums/account-session-state.type-enum.d.ts +7 -0
  12. package/build/_modules/account-security/_enums/account-session-state.type-enum.d.ts.map +1 -0
  13. package/build/_modules/account-security/_enums/account-session-state.type-enum.js +11 -0
  14. package/build/_modules/account-security/_enums/account-session-state.type-enum.js.map +1 -0
  15. package/build/_modules/account-security/_models/account-challenge-adapter.interface.d.ts +9 -0
  16. package/build/_modules/account-security/_models/account-challenge-adapter.interface.d.ts.map +1 -0
  17. package/build/_modules/account-security/_models/account-challenge-adapter.interface.js +3 -0
  18. package/build/_modules/account-security/_models/account-challenge-adapter.interface.js.map +1 -0
  19. package/build/_modules/account-security/_models/account-challenge-issued.interface.d.ts +7 -0
  20. package/build/_modules/account-security/_models/account-challenge-issued.interface.d.ts.map +1 -0
  21. package/build/_modules/account-security/_models/account-challenge-issued.interface.js +3 -0
  22. package/build/_modules/account-security/_models/account-challenge-issued.interface.js.map +1 -0
  23. package/build/_modules/account-security/_models/account-challenge-record.interface.d.ts +13 -0
  24. package/build/_modules/account-security/_models/account-challenge-record.interface.d.ts.map +1 -0
  25. package/build/_modules/account-security/_models/account-challenge-record.interface.js +3 -0
  26. package/build/_modules/account-security/_models/account-challenge-record.interface.js.map +1 -0
  27. package/build/_modules/account-security/_models/account-challenge-result.interface.d.ts +8 -0
  28. package/build/_modules/account-security/_models/account-challenge-result.interface.d.ts.map +1 -0
  29. package/build/_modules/account-security/_models/account-challenge-result.interface.js +3 -0
  30. package/build/_modules/account-security/_models/account-challenge-result.interface.js.map +1 -0
  31. package/build/_modules/account-security/_models/account-challenge-settings.interface.d.ts +9 -0
  32. package/build/_modules/account-security/_models/account-challenge-settings.interface.d.ts.map +1 -0
  33. package/build/_modules/account-security/_models/account-challenge-settings.interface.js +3 -0
  34. package/build/_modules/account-security/_models/account-challenge-settings.interface.js.map +1 -0
  35. package/build/_modules/account-security/_models/account-password-policy.interface.d.ts +12 -0
  36. package/build/_modules/account-security/_models/account-password-policy.interface.d.ts.map +1 -0
  37. package/build/_modules/account-security/_models/account-password-policy.interface.js +3 -0
  38. package/build/_modules/account-security/_models/account-password-policy.interface.js.map +1 -0
  39. package/build/_modules/account-security/_models/account-password-verification.interface.d.ts +6 -0
  40. package/build/_modules/account-security/_models/account-password-verification.interface.d.ts.map +1 -0
  41. package/build/_modules/account-security/_models/account-password-verification.interface.js +3 -0
  42. package/build/_modules/account-security/_models/account-password-verification.interface.js.map +1 -0
  43. package/build/_modules/account-security/_models/account-refresh-token-record.interface.d.ts +13 -0
  44. package/build/_modules/account-security/_models/account-refresh-token-record.interface.d.ts.map +1 -0
  45. package/build/_modules/account-security/_models/account-refresh-token-record.interface.js +3 -0
  46. package/build/_modules/account-security/_models/account-refresh-token-record.interface.js.map +1 -0
  47. package/build/_modules/account-security/_models/account-session-adapter.interface.d.ts +19 -0
  48. package/build/_modules/account-security/_models/account-session-adapter.interface.d.ts.map +1 -0
  49. package/build/_modules/account-security/_models/account-session-adapter.interface.js +3 -0
  50. package/build/_modules/account-security/_models/account-session-adapter.interface.js.map +1 -0
  51. package/build/_modules/account-security/_models/account-session-claims.interface.d.ts +8 -0
  52. package/build/_modules/account-security/_models/account-session-claims.interface.d.ts.map +1 -0
  53. package/build/_modules/account-security/_models/account-session-claims.interface.js +3 -0
  54. package/build/_modules/account-security/_models/account-session-claims.interface.js.map +1 -0
  55. package/build/_modules/account-security/_models/account-session-context.interface.d.ts +7 -0
  56. package/build/_modules/account-security/_models/account-session-context.interface.d.ts.map +1 -0
  57. package/build/_modules/account-security/_models/account-session-context.interface.js +3 -0
  58. package/build/_modules/account-security/_models/account-session-context.interface.js.map +1 -0
  59. package/build/_modules/account-security/_models/account-session-create.interface.d.ts +8 -0
  60. package/build/_modules/account-security/_models/account-session-create.interface.d.ts.map +1 -0
  61. package/build/_modules/account-security/_models/account-session-create.interface.js +3 -0
  62. package/build/_modules/account-security/_models/account-session-create.interface.js.map +1 -0
  63. package/build/_modules/account-security/_models/account-session-record.interface.d.ts +21 -0
  64. package/build/_modules/account-security/_models/account-session-record.interface.d.ts.map +1 -0
  65. package/build/_modules/account-security/_models/account-session-record.interface.js +3 -0
  66. package/build/_modules/account-security/_models/account-session-record.interface.js.map +1 -0
  67. package/build/_modules/account-security/_models/account-session-rotate.interface.d.ts +11 -0
  68. package/build/_modules/account-security/_models/account-session-rotate.interface.d.ts.map +1 -0
  69. package/build/_modules/account-security/_models/account-session-rotate.interface.js +3 -0
  70. package/build/_modules/account-security/_models/account-session-rotate.interface.js.map +1 -0
  71. package/build/_modules/account-security/_models/account-session-settings.interface.d.ts +11 -0
  72. package/build/_modules/account-security/_models/account-session-settings.interface.d.ts.map +1 -0
  73. package/build/_modules/account-security/_models/account-session-settings.interface.js +3 -0
  74. package/build/_modules/account-security/_models/account-session-settings.interface.js.map +1 -0
  75. package/build/_modules/account-security/_models/account-session-token-pair.interface.d.ts +9 -0
  76. package/build/_modules/account-security/_models/account-session-token-pair.interface.d.ts.map +1 -0
  77. package/build/_modules/account-security/_models/account-session-token-pair.interface.js +3 -0
  78. package/build/_modules/account-security/_models/account-session-token-pair.interface.js.map +1 -0
  79. package/build/_modules/account-security/_models/account-session-view.interface.d.ts +13 -0
  80. package/build/_modules/account-security/_models/account-session-view.interface.d.ts.map +1 -0
  81. package/build/_modules/account-security/_models/account-session-view.interface.js +3 -0
  82. package/build/_modules/account-security/_models/account-session-view.interface.js.map +1 -0
  83. package/build/_modules/account-security/account-challenge.control-service.d.ts +24 -0
  84. package/build/_modules/account-security/account-challenge.control-service.d.ts.map +1 -0
  85. package/build/_modules/account-security/account-challenge.control-service.js +117 -0
  86. package/build/_modules/account-security/account-challenge.control-service.js.map +1 -0
  87. package/build/_modules/account-security/account-password.control-service.d.ts +24 -0
  88. package/build/_modules/account-security/account-password.control-service.d.ts.map +1 -0
  89. package/build/_modules/account-security/account-password.control-service.js +214 -0
  90. package/build/_modules/account-security/account-password.control-service.js.map +1 -0
  91. package/build/_modules/account-security/account-session.control-service.d.ts +39 -0
  92. package/build/_modules/account-security/account-session.control-service.d.ts.map +1 -0
  93. package/build/_modules/account-security/account-session.control-service.js +277 -0
  94. package/build/_modules/account-security/account-session.control-service.js.map +1 -0
  95. package/build/_modules/account-security/index.d.ts +24 -0
  96. package/build/_modules/account-security/index.d.ts.map +1 -0
  97. package/build/_modules/account-security/index.js +16 -0
  98. package/build/_modules/account-security/index.js.map +1 -0
  99. package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.d.ts +6 -0
  100. package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.d.ts.map +1 -0
  101. package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.js +10 -0
  102. package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.js.map +1 -0
  103. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.d.ts +11 -0
  104. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.d.ts.map +1 -0
  105. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.js +15 -0
  106. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.js.map +1 -0
  107. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.d.ts +8 -0
  108. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.d.ts.map +1 -0
  109. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.js +12 -0
  110. package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.js.map +1 -0
  111. package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.d.ts +16 -0
  112. package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.d.ts.map +1 -0
  113. package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.js +20 -0
  114. package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.js.map +1 -0
  115. package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.d.ts +10 -0
  116. package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.d.ts.map +1 -0
  117. package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.js +14 -0
  118. package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.js.map +1 -0
  119. package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.d.ts +12 -0
  120. package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.d.ts.map +1 -0
  121. package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.js +3 -0
  122. package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.js.map +1 -0
  123. package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.d.ts +7 -0
  124. package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.d.ts.map +1 -0
  125. package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.js +3 -0
  126. package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.js.map +1 -0
  127. package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.d.ts +15 -0
  128. package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.d.ts.map +1 -0
  129. package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.js +3 -0
  130. package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.js.map +1 -0
  131. package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.d.ts +7 -0
  132. package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.d.ts.map +1 -0
  133. package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.js +3 -0
  134. package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.js.map +1 -0
  135. package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.d.ts +13 -0
  136. package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.d.ts.map +1 -0
  137. package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.js +3 -0
  138. package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.js.map +1 -0
  139. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.d.ts +9 -0
  140. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.d.ts.map +1 -0
  141. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.js +3 -0
  142. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.js.map +1 -0
  143. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.d.ts +14 -0
  144. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.d.ts.map +1 -0
  145. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.js +3 -0
  146. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.js.map +1 -0
  147. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.d.ts +8 -0
  148. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.d.ts.map +1 -0
  149. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.js +3 -0
  150. package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.js.map +1 -0
  151. package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.d.ts +11 -0
  152. package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.d.ts.map +1 -0
  153. package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.js +3 -0
  154. package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.js.map +1 -0
  155. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.d.ts +13 -0
  156. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.d.ts.map +1 -0
  157. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.js +3 -0
  158. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.js.map +1 -0
  159. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.d.ts +9 -0
  160. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.d.ts.map +1 -0
  161. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.js +3 -0
  162. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.js.map +1 -0
  163. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.d.ts +7 -0
  164. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.d.ts.map +1 -0
  165. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.js +3 -0
  166. package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.js.map +1 -0
  167. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.d.ts +11 -0
  168. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.d.ts.map +1 -0
  169. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.js +3 -0
  170. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.js.map +1 -0
  171. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.d.ts +7 -0
  172. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.d.ts.map +1 -0
  173. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.js +3 -0
  174. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.js.map +1 -0
  175. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.d.ts +7 -0
  176. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.d.ts.map +1 -0
  177. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.js +3 -0
  178. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.js.map +1 -0
  179. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.d.ts +12 -0
  180. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.d.ts.map +1 -0
  181. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.js +3 -0
  182. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.js.map +1 -0
  183. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.d.ts +14 -0
  184. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.d.ts.map +1 -0
  185. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.js +3 -0
  186. package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.js.map +1 -0
  187. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.d.ts +15 -0
  188. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.d.ts.map +1 -0
  189. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.js +3 -0
  190. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.js.map +1 -0
  191. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.d.ts +9 -0
  192. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.d.ts.map +1 -0
  193. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.js +3 -0
  194. package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.js.map +1 -0
  195. package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.d.ts +7 -0
  196. package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.d.ts.map +1 -0
  197. package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.js +3 -0
  198. package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.js.map +1 -0
  199. package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.d.ts +10 -0
  200. package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.d.ts.map +1 -0
  201. package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.js +3 -0
  202. package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.js.map +1 -0
  203. package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.d.ts +7 -0
  204. package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.d.ts.map +1 -0
  205. package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.js +3 -0
  206. package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.js.map +1 -0
  207. package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.d.ts +21 -0
  208. package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.d.ts.map +1 -0
  209. package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.js +3 -0
  210. package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.js.map +1 -0
  211. package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.d.ts +8 -0
  212. package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.d.ts.map +1 -0
  213. package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.js +3 -0
  214. package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.js.map +1 -0
  215. package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.d.ts +20 -0
  216. package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.d.ts.map +1 -0
  217. package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.js +3 -0
  218. package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.js.map +1 -0
  219. package/build/_modules/privacy-lifecycle/index.d.ts +33 -0
  220. package/build/_modules/privacy-lifecycle/index.d.ts.map +1 -0
  221. package/build/_modules/privacy-lifecycle/index.js +18 -0
  222. package/build/_modules/privacy-lifecycle/index.js.map +1 -0
  223. package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.d.ts +28 -0
  224. package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.d.ts.map +1 -0
  225. package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.js +168 -0
  226. package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.js.map +1 -0
  227. package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.d.ts +42 -0
  228. package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.d.ts.map +1 -0
  229. package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.js +364 -0
  230. package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.js.map +1 -0
  231. package/package.json +19 -1
  232. package/src/_modules/account-security/_enums/account-challenge-purpose.type-enum.ts +5 -0
  233. package/src/_modules/account-security/_enums/account-refresh-token-state.type-enum.ts +6 -0
  234. package/src/_modules/account-security/_enums/account-session-state.type-enum.ts +6 -0
  235. package/src/_modules/account-security/_models/account-challenge-adapter.interface.ts +17 -0
  236. package/src/_modules/account-security/_models/account-challenge-issued.interface.ts +6 -0
  237. package/src/_modules/account-security/_models/account-challenge-record.interface.ts +13 -0
  238. package/src/_modules/account-security/_models/account-challenge-result.interface.ts +8 -0
  239. package/src/_modules/account-security/_models/account-challenge-settings.interface.ts +9 -0
  240. package/src/_modules/account-security/_models/account-password-policy.interface.ts +11 -0
  241. package/src/_modules/account-security/_models/account-password-verification.interface.ts +5 -0
  242. package/src/_modules/account-security/_models/account-refresh-token-record.interface.ts +13 -0
  243. package/src/_modules/account-security/_models/account-session-adapter.interface.ts +19 -0
  244. package/src/_modules/account-security/_models/account-session-claims.interface.ts +7 -0
  245. package/src/_modules/account-security/_models/account-session-context.interface.ts +6 -0
  246. package/src/_modules/account-security/_models/account-session-create.interface.ts +8 -0
  247. package/src/_modules/account-security/_models/account-session-record.interface.ts +21 -0
  248. package/src/_modules/account-security/_models/account-session-rotate.interface.ts +11 -0
  249. package/src/_modules/account-security/_models/account-session-settings.interface.ts +11 -0
  250. package/src/_modules/account-security/_models/account-session-token-pair.interface.ts +8 -0
  251. package/src/_modules/account-security/_models/account-session-view.interface.ts +13 -0
  252. package/src/_modules/account-security/account-challenge.control-service.spec.ts +195 -0
  253. package/src/_modules/account-security/account-challenge.control-service.ts +164 -0
  254. package/src/_modules/account-security/account-password.control-service.spec.ts +96 -0
  255. package/src/_modules/account-security/account-password.control-service.ts +288 -0
  256. package/src/_modules/account-security/account-session.control-service.spec.ts +294 -0
  257. package/src/_modules/account-security/account-session.control-service.ts +376 -0
  258. package/src/_modules/account-security/index.ts +31 -0
  259. package/src/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.ts +5 -0
  260. package/src/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.ts +10 -0
  261. package/src/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.ts +7 -0
  262. package/src/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.ts +15 -0
  263. package/src/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.ts +9 -0
  264. package/src/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.ts +12 -0
  265. package/src/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.ts +7 -0
  266. package/src/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.ts +15 -0
  267. package/src/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.ts +7 -0
  268. package/src/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.ts +13 -0
  269. package/src/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.ts +9 -0
  270. package/src/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.ts +14 -0
  271. package/src/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.ts +8 -0
  272. package/src/_modules/privacy-lifecycle/_models/privacy-contributor.interface.ts +17 -0
  273. package/src/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.ts +21 -0
  274. package/src/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.ts +9 -0
  275. package/src/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.ts +7 -0
  276. package/src/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.ts +10 -0
  277. package/src/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.ts +7 -0
  278. package/src/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.ts +7 -0
  279. package/src/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.ts +11 -0
  280. package/src/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.ts +13 -0
  281. package/src/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.ts +19 -0
  282. package/src/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.ts +9 -0
  283. package/src/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.ts +7 -0
  284. package/src/_modules/privacy-lifecycle/_models/privacy-request-open.interface.ts +10 -0
  285. package/src/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.ts +7 -0
  286. package/src/_modules/privacy-lifecycle/_models/privacy-request-record.interface.ts +21 -0
  287. package/src/_modules/privacy-lifecycle/_models/privacy-request-result.interface.ts +8 -0
  288. package/src/_modules/privacy-lifecycle/_models/privacy-request-view.interface.ts +20 -0
  289. package/src/_modules/privacy-lifecycle/index.ts +40 -0
  290. package/src/_modules/privacy-lifecycle/privacy-ledger.control-service.spec.ts +206 -0
  291. package/src/_modules/privacy-lifecycle/privacy-ledger.control-service.ts +253 -0
  292. package/src/_modules/privacy-lifecycle/privacy-lifecycle.control-service.spec.ts +353 -0
  293. package/src/_modules/privacy-lifecycle/privacy-lifecycle.control-service.ts +586 -0
@@ -0,0 +1,586 @@
1
+ import {
2
+ createHash,
3
+ randomUUID
4
+ } from 'crypto';
5
+
6
+ import { DyFM_Error } from '@futdevpro/fsm-dynamo';
7
+
8
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
9
+ import { DyNTS_PrivacyContributorAction_Type } from './_enums/privacy-contributor-action.type-enum';
10
+ import { DyNTS_PrivacyContributorOutcome_Type } from './_enums/privacy-contributor-outcome.type-enum';
11
+ import { DyNTS_PrivacyRequestState_Type } from './_enums/privacy-request-state.type-enum';
12
+ import { DyNTS_PrivacyRequest_Type } from './_enums/privacy-request.type-enum';
13
+ import { DyNTS_PrivacyContributorContext_Interface } from './_models/privacy-contributor-context.interface';
14
+ import { DyNTS_PrivacyContributorOutcome_Interface } from './_models/privacy-contributor-outcome.interface';
15
+ import { DyNTS_PrivacyContributorPlan_Interface } from './_models/privacy-contributor-plan.interface';
16
+ import { DyNTS_PrivacyContributor_Interface } from './_models/privacy-contributor.interface';
17
+ import { DyNTS_PrivacyLifecycleAdapter_Interface } from './_models/privacy-lifecycle-adapter.interface';
18
+ import { DyNTS_PrivacyLifecycleSettings_Interface } from './_models/privacy-lifecycle-settings.interface';
19
+ import { DyNTS_PrivacyRequestCreateResult_Interface } from './_models/privacy-request-create-result.interface';
20
+ import { DyNTS_PrivacyRequestOpen_Interface } from './_models/privacy-request-open.interface';
21
+ import {
22
+ DyNTS_PrivacyRequestPersistenceCreateResult_Interface
23
+ } from './_models/privacy-request-persistence-create-result.interface';
24
+ import { DyNTS_PrivacyRequestRecord_Interface } from './_models/privacy-request-record.interface';
25
+ import { DyNTS_PrivacyRequestResult_Interface } from './_models/privacy-request-result.interface';
26
+ import { DyNTS_PrivacyRequestView_Interface } from './_models/privacy-request-view.interface';
27
+
28
+ /** Coordinates identity-gated, resumable data-subject requests across product-owned data contributors. */
29
+ export class DyNTS_PrivacyLifecycle_ControlService {
30
+ private readonly adapter: DyNTS_PrivacyLifecycleAdapter_Interface;
31
+ private readonly contributors: DyNTS_PrivacyContributor_Interface[];
32
+ private readonly clock: () => Date;
33
+
34
+ /** Creates an orchestrator with a stable contributor registry. */
35
+ constructor(set: DyNTS_PrivacyLifecycleSettings_Interface) {
36
+ this.adapter = set.adapter;
37
+ this.contributors = [ ...set.contributors ]
38
+ .sort((first: DyNTS_PrivacyContributor_Interface, second: DyNTS_PrivacyContributor_Interface): number => (
39
+ first.contributorId.localeCompare(second.contributorId)
40
+ ));
41
+ this.clock = set.clock ?? ((): Date => new Date());
42
+ this.validateSettings();
43
+ }
44
+
45
+ /** Opens or safely replays a subject-scoped request without persisting the raw idempotency key. */
46
+ public async openRequest(
47
+ set: DyNTS_PrivacyRequestOpen_Interface
48
+ ): Promise<DyNTS_PrivacyRequestCreateResult_Interface> {
49
+ if (
50
+ !this.isBoundedText(set.subjectId, 256)
51
+ || !this.isBoundedText(set.organizationId, 256)
52
+ || !Object.values(DyNTS_PrivacyRequest_Type).includes(set.type)
53
+ ) {
54
+ throw this.buildError(400, 'REQUEST_INVALID', 'The privacy request is invalid.');
55
+ }
56
+
57
+ if (
58
+ !this.isBoundedText(set.idempotencyKey, 256)
59
+ || !this.isFutureDate(set.deadlineAt)
60
+ ) {
61
+ throw this.buildError(400, 'IDEMPOTENCY_KEY_INVALID', 'The privacy request key is invalid.');
62
+ }
63
+
64
+ const createdAt: string = this.clock().toISOString();
65
+ const request: DyNTS_PrivacyRequestRecord_Interface = {
66
+ requestId: randomUUID(),
67
+ subjectId: set.subjectId,
68
+ organizationId: set.organizationId,
69
+ type: set.type,
70
+ state: DyNTS_PrivacyRequestState_Type.received,
71
+ idempotencyHash: this.hashIdempotency(set),
72
+ revision: 0,
73
+ createdAt: createdAt,
74
+ deadlineAt: set.deadlineAt,
75
+ identityVerifiedAt: '',
76
+ scopedAt: '',
77
+ plannedAt: '',
78
+ executionStartedAt: '',
79
+ verifyingStartedAt: '',
80
+ completedAt: '',
81
+ };
82
+
83
+ const result: DyNTS_PrivacyRequestPersistenceCreateResult_Interface =
84
+ await this.adapter.createOrGetRequest(request);
85
+
86
+ if (
87
+ result.request.idempotencyHash !== request.idempotencyHash
88
+ || result.request.subjectId !== request.subjectId
89
+ || result.request.organizationId !== request.organizationId
90
+ || result.request.type !== request.type
91
+ ) {
92
+ throw this.buildError(409, 'IDEMPOTENCY_CONFLICT', 'The idempotency key belongs to another request.');
93
+ }
94
+
95
+ return { request: this.toRequestView(result.request), created: result.created };
96
+ }
97
+
98
+ /** Marks request identity verified after the application has completed its security challenge. */
99
+ public async verifyIdentity(
100
+ requestId: string,
101
+ subjectId: string
102
+ ): Promise<DyNTS_PrivacyRequestView_Interface> {
103
+ const request: DyNTS_PrivacyRequestRecord_Interface = await this.requireOwnedRequest(requestId, subjectId);
104
+
105
+ if (request.state === DyNTS_PrivacyRequestState_Type.identityVerified) {
106
+ return this.toRequestView(request);
107
+ }
108
+
109
+ if (request.state !== DyNTS_PrivacyRequestState_Type.received) {
110
+ throw this.buildError(409, 'IDENTITY_STATE_CONFLICT', 'The request cannot be identity-verified now.');
111
+ }
112
+
113
+ const replacement: DyNTS_PrivacyRequestRecord_Interface = await this.replaceState(
114
+ request,
115
+ DyNTS_PrivacyRequestState_Type.identityVerified,
116
+ {
117
+ identityVerifiedAt: this.clock().toISOString(),
118
+ }
119
+ );
120
+
121
+ return this.toRequestView(replacement);
122
+ }
123
+
124
+ /** Executes or resumes all contributors and never reports complete while one contributor failed. */
125
+ public async processRequest(
126
+ requestId: string,
127
+ subjectId: string
128
+ ): Promise<DyNTS_PrivacyRequestResult_Interface> {
129
+ let request: DyNTS_PrivacyRequestRecord_Interface = await this.requireOwnedRequest(requestId, subjectId);
130
+
131
+ if (request.state === DyNTS_PrivacyRequestState_Type.completed) {
132
+ return this.buildResult(request, await this.adapter.listContributorOutcomes(request.requestId));
133
+ }
134
+
135
+ if (
136
+ request.state !== DyNTS_PrivacyRequestState_Type.identityVerified
137
+ && request.state !== DyNTS_PrivacyRequestState_Type.scoped
138
+ && request.state !== DyNTS_PrivacyRequestState_Type.planned
139
+ && request.state !== DyNTS_PrivacyRequestState_Type.executing
140
+ && request.state !== DyNTS_PrivacyRequestState_Type.verifying
141
+ && request.state !== DyNTS_PrivacyRequestState_Type.partiallyCompleted
142
+ ) {
143
+ throw this.buildError(409, 'EXECUTION_STATE_CONFLICT', 'The request is not ready for execution.');
144
+ }
145
+
146
+ if (request.state === DyNTS_PrivacyRequestState_Type.identityVerified) {
147
+ request = await this.replaceState(request, DyNTS_PrivacyRequestState_Type.scoped, {
148
+ scopedAt: this.clock().toISOString(),
149
+ });
150
+ }
151
+
152
+ const context: DyNTS_PrivacyContributorContext_Interface = this.buildContext(request);
153
+ let plans: DyNTS_PrivacyContributorPlan_Interface[] = await this.adapter.listContributorPlans(request.requestId);
154
+
155
+ this.validateStoredPlans(plans);
156
+
157
+ if (
158
+ request.state === DyNTS_PrivacyRequestState_Type.scoped
159
+ || request.state === DyNTS_PrivacyRequestState_Type.partiallyCompleted
160
+ ) {
161
+ await this.planMissingContributors(request.requestId, context, plans);
162
+ plans = await this.adapter.listContributorPlans(request.requestId);
163
+ this.validateStoredPlans(plans);
164
+
165
+ if (!this.hasAllContributorPlans(plans)) {
166
+ request = await this.replaceState(request, DyNTS_PrivacyRequestState_Type.partiallyCompleted, {
167
+ completedAt: '',
168
+ });
169
+
170
+ return this.buildResult(request, await this.adapter.listContributorOutcomes(request.requestId));
171
+ }
172
+
173
+ request = await this.replaceState(request, DyNTS_PrivacyRequestState_Type.planned, {
174
+ plannedAt: this.clock().toISOString(),
175
+ });
176
+ }
177
+
178
+ if (request.state === DyNTS_PrivacyRequestState_Type.planned) {
179
+ this.validateStoredPlans(plans);
180
+ request = await this.replaceState(request, DyNTS_PrivacyRequestState_Type.executing, {
181
+ executionStartedAt: request.executionStartedAt || this.clock().toISOString(),
182
+ completedAt: '',
183
+ });
184
+ }
185
+
186
+ if (request.state === DyNTS_PrivacyRequestState_Type.executing) {
187
+ await this.executeMissingContributors(request.requestId, context, plans);
188
+ request = await this.replaceState(request, DyNTS_PrivacyRequestState_Type.verifying, {
189
+ verifyingStartedAt: this.clock().toISOString(),
190
+ });
191
+ }
192
+
193
+ let outcomes: DyNTS_PrivacyContributorOutcome_Interface[] =
194
+ await this.adapter.listContributorOutcomes(request.requestId);
195
+
196
+ if (request.state === DyNTS_PrivacyRequestState_Type.verifying) {
197
+ await this.verifyContributorOutcomes(context, plans, outcomes);
198
+ outcomes = await this.adapter.listContributorOutcomes(request.requestId);
199
+ }
200
+
201
+ const isComplete: boolean = this.contributors.every((contributor: DyNTS_PrivacyContributor_Interface): boolean => (
202
+ outcomes.some((outcome: DyNTS_PrivacyContributorOutcome_Interface): boolean => (
203
+ outcome.contributorId === contributor.contributorId
204
+ && outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.failed
205
+ ))
206
+ ));
207
+ const finalState: DyNTS_PrivacyRequestState_Type = isComplete
208
+ ? DyNTS_PrivacyRequestState_Type.completed
209
+ : DyNTS_PrivacyRequestState_Type.partiallyCompleted;
210
+
211
+ request = await this.replaceState(request, finalState, {
212
+ completedAt: isComplete ? this.clock().toISOString() : '',
213
+ });
214
+
215
+ return this.buildResult(request, outcomes);
216
+ }
217
+
218
+ /** Returns an owned request and its content-free contributor outcomes. */
219
+ public async getRequest(
220
+ requestId: string,
221
+ subjectId: string
222
+ ): Promise<DyNTS_PrivacyRequestResult_Interface> {
223
+ const request: DyNTS_PrivacyRequestRecord_Interface = await this.requireOwnedRequest(requestId, subjectId);
224
+
225
+ return this.buildResult(request, await this.adapter.listContributorOutcomes(request.requestId));
226
+ }
227
+
228
+ private async planMissingContributors(
229
+ requestId: string,
230
+ context: DyNTS_PrivacyContributorContext_Interface,
231
+ existingPlans: DyNTS_PrivacyContributorPlan_Interface[]
232
+ ): Promise<void> {
233
+ const plannedContributorIds: Set<string> = new Set(existingPlans.map((
234
+ plan: DyNTS_PrivacyContributorPlan_Interface
235
+ ): string => plan.contributorId));
236
+
237
+ for (const contributor of this.contributors) {
238
+ if (plannedContributorIds.has(contributor.contributorId)) {
239
+ continue;
240
+ }
241
+
242
+ try {
243
+ const plan: DyNTS_PrivacyContributorPlan_Interface = await contributor.plan(context);
244
+
245
+ this.validatePlan(contributor, plan);
246
+ await this.adapter.saveContributorPlan(requestId, plan);
247
+ } catch (error: unknown) {
248
+ await this.adapter.saveContributorOutcome(requestId, this.buildFailedOutcome(
249
+ contributor.contributorId,
250
+ DyNTS_PrivacyContributorAction_Type.noData,
251
+ error instanceof DyFM_Error ? 'CONTRIBUTOR_PLAN_INVALID' : 'CONTRIBUTOR_PLAN_FAILED'
252
+ ));
253
+ }
254
+ }
255
+ }
256
+
257
+ private async executeMissingContributors(
258
+ requestId: string,
259
+ context: DyNTS_PrivacyContributorContext_Interface,
260
+ plans: DyNTS_PrivacyContributorPlan_Interface[]
261
+ ): Promise<void> {
262
+ const existing: DyNTS_PrivacyContributorOutcome_Interface[] =
263
+ await this.adapter.listContributorOutcomes(requestId);
264
+ const completedContributorIds: Set<string> = new Set();
265
+
266
+ for (const contributor of this.contributors) {
267
+ const plan: DyNTS_PrivacyContributorPlan_Interface | undefined = plans.find((
268
+ item: DyNTS_PrivacyContributorPlan_Interface
269
+ ): boolean => item.contributorId === contributor.contributorId);
270
+ const outcome: DyNTS_PrivacyContributorOutcome_Interface | undefined = existing.find((
271
+ item: DyNTS_PrivacyContributorOutcome_Interface
272
+ ): boolean => item.contributorId === contributor.contributorId);
273
+
274
+ if (plan && outcome && this.isValidCompletedOutcome(contributor, plan, outcome)) {
275
+ completedContributorIds.add(contributor.contributorId);
276
+ }
277
+ }
278
+
279
+ for (const contributor of this.contributors) {
280
+ if (completedContributorIds.has(contributor.contributorId)) {
281
+ continue;
282
+ }
283
+
284
+ const plan: DyNTS_PrivacyContributorPlan_Interface | undefined = plans.find((
285
+ item: DyNTS_PrivacyContributorPlan_Interface
286
+ ): boolean => item.contributorId === contributor.contributorId);
287
+ const outcome: DyNTS_PrivacyContributorOutcome_Interface = plan
288
+ ? await this.executeContributor(contributor, context, plan)
289
+ : this.buildFailedOutcome(
290
+ contributor.contributorId,
291
+ DyNTS_PrivacyContributorAction_Type.noData,
292
+ 'CONTRIBUTOR_PLAN_MISSING'
293
+ );
294
+
295
+ await this.adapter.saveContributorOutcome(requestId, outcome);
296
+ }
297
+ }
298
+
299
+ private async executeContributor(
300
+ contributor: DyNTS_PrivacyContributor_Interface,
301
+ context: DyNTS_PrivacyContributorContext_Interface,
302
+ plan: DyNTS_PrivacyContributorPlan_Interface
303
+ ): Promise<DyNTS_PrivacyContributorOutcome_Interface> {
304
+ try {
305
+ const outcome: DyNTS_PrivacyContributorOutcome_Interface = await contributor.execute(context, plan);
306
+
307
+ this.validateOutcome(contributor, plan, outcome);
308
+
309
+ return { ...outcome };
310
+ } catch (error: unknown) {
311
+ return this.buildFailedOutcome(
312
+ contributor.contributorId,
313
+ plan.action,
314
+ error instanceof DyFM_Error ? 'CONTRIBUTOR_CONTRACT_FAILED' : 'CONTRIBUTOR_EXECUTION_FAILED'
315
+ );
316
+ }
317
+ }
318
+
319
+ private async verifyContributorOutcomes(
320
+ context: DyNTS_PrivacyContributorContext_Interface,
321
+ plans: DyNTS_PrivacyContributorPlan_Interface[],
322
+ outcomes: DyNTS_PrivacyContributorOutcome_Interface[]
323
+ ): Promise<void> {
324
+ for (const contributor of this.contributors) {
325
+ const outcome: DyNTS_PrivacyContributorOutcome_Interface | undefined = outcomes.find((
326
+ item: DyNTS_PrivacyContributorOutcome_Interface
327
+ ): boolean => item.contributorId === contributor.contributorId);
328
+ const plan: DyNTS_PrivacyContributorPlan_Interface | undefined = plans.find((
329
+ item: DyNTS_PrivacyContributorPlan_Interface
330
+ ): boolean => item.contributorId === contributor.contributorId);
331
+
332
+ if (!outcome || outcome.outcome === DyNTS_PrivacyContributorOutcome_Type.failed || !plan) {
333
+ continue;
334
+ }
335
+
336
+ try {
337
+ this.validateOutcome(contributor, plan, outcome);
338
+
339
+ if (!await contributor.verify(context, outcome)) {
340
+ await this.adapter.saveContributorOutcome(context.requestId, this.buildFailedOutcome(
341
+ contributor.contributorId,
342
+ outcome.action,
343
+ 'CONTRIBUTOR_VERIFY_FAILED'
344
+ ));
345
+ }
346
+ } catch {
347
+ await this.adapter.saveContributorOutcome(context.requestId, this.buildFailedOutcome(
348
+ contributor.contributorId,
349
+ outcome.action,
350
+ 'CONTRIBUTOR_VERIFY_FAILED'
351
+ ));
352
+ }
353
+ }
354
+ }
355
+
356
+ private validatePlan(
357
+ contributor: DyNTS_PrivacyContributor_Interface,
358
+ plan: DyNTS_PrivacyContributorPlan_Interface
359
+ ): void {
360
+ if (
361
+ plan.contributorId !== contributor.contributorId
362
+ || !this.isBoundedText(plan.contributorId, 128)
363
+ || !Object.values(DyNTS_PrivacyContributorAction_Type).includes(plan.action)
364
+ || (plan.action === DyNTS_PrivacyContributorAction_Type.retainWithBasis && !plan.retentionBasisCode)
365
+ || (plan.action !== DyNTS_PrivacyContributorAction_Type.retainWithBasis && !!plan.retentionBasisCode)
366
+ ) {
367
+ throw this.buildError(500, 'CONTRIBUTOR_PLAN_INVALID', 'A privacy contributor returned an invalid plan.');
368
+ }
369
+ }
370
+
371
+ private validateOutcome(
372
+ contributor: DyNTS_PrivacyContributor_Interface,
373
+ plan: DyNTS_PrivacyContributorPlan_Interface,
374
+ outcome: DyNTS_PrivacyContributorOutcome_Interface
375
+ ): void {
376
+ if (
377
+ outcome.contributorId !== contributor.contributorId
378
+ || outcome.action !== plan.action
379
+ || !Object.values(DyNTS_PrivacyContributorOutcome_Type).includes(outcome.outcome)
380
+ || !Number.isSafeInteger(outcome.processedRecordCount)
381
+ || outcome.processedRecordCount < 0
382
+ || (outcome.outcome === DyNTS_PrivacyContributorOutcome_Type.retainedWithBasis
383
+ && outcome.retentionBasisCode !== plan.retentionBasisCode)
384
+ || (outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.retainedWithBasis
385
+ && !!outcome.retentionBasisCode)
386
+ || (outcome.outcome === DyNTS_PrivacyContributorOutcome_Type.failed && !outcome.errorCode)
387
+ || (outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.failed && !!outcome.errorCode)
388
+ || (outcome.action === DyNTS_PrivacyContributorAction_Type.retainWithBasis
389
+ && outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.retainedWithBasis
390
+ && outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.failed)
391
+ || (outcome.action !== DyNTS_PrivacyContributorAction_Type.retainWithBasis
392
+ && outcome.outcome === DyNTS_PrivacyContributorOutcome_Type.retainedWithBasis)
393
+ || (!!outcome.artifactChecksum && !/^[a-f0-9]{64}$/u.test(outcome.artifactChecksum))
394
+ || !Number.isFinite(new Date(outcome.completedAt).getTime())
395
+ ) {
396
+ throw this.buildError(500, 'CONTRIBUTOR_OUTCOME_INVALID', 'A privacy contributor returned an invalid outcome.');
397
+ }
398
+ }
399
+
400
+ private buildFailedOutcome(
401
+ contributorId: string,
402
+ action: DyNTS_PrivacyContributorAction_Type,
403
+ errorCode: string
404
+ ): DyNTS_PrivacyContributorOutcome_Interface {
405
+ return {
406
+ contributorId: contributorId,
407
+ action: action,
408
+ outcome: DyNTS_PrivacyContributorOutcome_Type.failed,
409
+ retentionBasisCode: '',
410
+ artifactChecksum: '',
411
+ processedRecordCount: 0,
412
+ errorCode: errorCode,
413
+ completedAt: this.clock().toISOString(),
414
+ };
415
+ }
416
+
417
+ private async requireOwnedRequest(
418
+ requestId: string,
419
+ subjectId: string
420
+ ): Promise<DyNTS_PrivacyRequestRecord_Interface> {
421
+ const request: DyNTS_PrivacyRequestRecord_Interface | null = await this.adapter.findRequestById(requestId);
422
+
423
+ if (request?.subjectId !== subjectId) {
424
+ throw this.buildError(404, 'REQUEST_NOT_FOUND', 'The privacy request was not found.');
425
+ }
426
+
427
+ return request;
428
+ }
429
+
430
+ private async replaceState(
431
+ request: DyNTS_PrivacyRequestRecord_Interface,
432
+ state: DyNTS_PrivacyRequestState_Type,
433
+ dates: {
434
+ identityVerifiedAt?: string;
435
+ scopedAt?: string;
436
+ plannedAt?: string;
437
+ executionStartedAt?: string;
438
+ verifyingStartedAt?: string;
439
+ completedAt?: string;
440
+ }
441
+ ): Promise<DyNTS_PrivacyRequestRecord_Interface> {
442
+ const replacement: DyNTS_PrivacyRequestRecord_Interface = {
443
+ ...request,
444
+ ...dates,
445
+ state: state,
446
+ revision: request.revision + 1,
447
+ };
448
+ const didReplace: boolean = await this.adapter.replaceRequest(replacement, request.revision);
449
+
450
+ if (!didReplace) {
451
+ throw this.buildError(409, 'REQUEST_REVISION_CONFLICT', 'The privacy request changed concurrently.');
452
+ }
453
+
454
+ return replacement;
455
+ }
456
+
457
+ private buildContext(request: DyNTS_PrivacyRequestRecord_Interface): DyNTS_PrivacyContributorContext_Interface {
458
+ return {
459
+ requestId: request.requestId,
460
+ subjectId: request.subjectId,
461
+ organizationId: request.organizationId,
462
+ type: request.type,
463
+ };
464
+ }
465
+
466
+ private buildResult(
467
+ request: DyNTS_PrivacyRequestRecord_Interface,
468
+ outcomes: DyNTS_PrivacyContributorOutcome_Interface[]
469
+ ): DyNTS_PrivacyRequestResult_Interface {
470
+ if (outcomes.some((outcome: DyNTS_PrivacyContributorOutcome_Interface): boolean => (
471
+ !this.contributors.some((contributor: DyNTS_PrivacyContributor_Interface): boolean => (
472
+ contributor.contributorId === outcome.contributorId
473
+ ))
474
+ ))) {
475
+ throw this.buildError(500, 'CONTRIBUTOR_OUTCOME_UNKNOWN', 'An unknown contributor outcome was stored.');
476
+ }
477
+
478
+ return {
479
+ request: this.toRequestView(request),
480
+ outcomes: [ ...outcomes ].sort((
481
+ first: DyNTS_PrivacyContributorOutcome_Interface,
482
+ second: DyNTS_PrivacyContributorOutcome_Interface
483
+ ): number => (
484
+ first.contributorId.localeCompare(second.contributorId)
485
+ )),
486
+ };
487
+ }
488
+
489
+ private toRequestView(request: DyNTS_PrivacyRequestRecord_Interface): DyNTS_PrivacyRequestView_Interface {
490
+ return {
491
+ requestId: request.requestId,
492
+ subjectId: request.subjectId,
493
+ organizationId: request.organizationId,
494
+ type: request.type,
495
+ state: request.state,
496
+ revision: request.revision,
497
+ createdAt: request.createdAt,
498
+ deadlineAt: request.deadlineAt,
499
+ identityVerifiedAt: request.identityVerifiedAt,
500
+ scopedAt: request.scopedAt,
501
+ plannedAt: request.plannedAt,
502
+ executionStartedAt: request.executionStartedAt,
503
+ verifyingStartedAt: request.verifyingStartedAt,
504
+ completedAt: request.completedAt,
505
+ };
506
+ }
507
+
508
+ private hashIdempotency(set: DyNTS_PrivacyRequestOpen_Interface): string {
509
+ return createHash('sha256')
510
+ .update(`${set.subjectId}\u0000${set.organizationId}\u0000${set.type}\u0000${set.idempotencyKey}`)
511
+ .digest('hex');
512
+ }
513
+
514
+ private isFutureDate(value: string): boolean {
515
+ const timestamp: number = new Date(value).getTime();
516
+
517
+ return Number.isFinite(timestamp) && timestamp > this.clock().getTime();
518
+ }
519
+
520
+ private isBoundedText(value: string, maxLength: number): boolean {
521
+ return typeof value === 'string' && !!value && value.length <= maxLength && !value.includes('\u0000');
522
+ }
523
+
524
+ private hasAllContributorPlans(plans: DyNTS_PrivacyContributorPlan_Interface[]): boolean {
525
+ return this.contributors.every((contributor: DyNTS_PrivacyContributor_Interface): boolean => (
526
+ plans.some((plan: DyNTS_PrivacyContributorPlan_Interface): boolean => (
527
+ plan.contributorId === contributor.contributorId
528
+ ))
529
+ ));
530
+ }
531
+
532
+ private validateStoredPlans(plans: DyNTS_PrivacyContributorPlan_Interface[]): void {
533
+ for (const plan of plans) {
534
+ const contributor: DyNTS_PrivacyContributor_Interface | undefined = this.contributors.find((
535
+ item: DyNTS_PrivacyContributor_Interface
536
+ ): boolean => item.contributorId === plan.contributorId);
537
+
538
+ if (!contributor) {
539
+ throw this.buildError(500, 'CONTRIBUTOR_PLAN_UNKNOWN', 'An unknown privacy contributor plan was stored.');
540
+ }
541
+
542
+ this.validatePlan(contributor, plan);
543
+ }
544
+ }
545
+
546
+ private isValidCompletedOutcome(
547
+ contributor: DyNTS_PrivacyContributor_Interface,
548
+ plan: DyNTS_PrivacyContributorPlan_Interface,
549
+ outcome: DyNTS_PrivacyContributorOutcome_Interface
550
+ ): boolean {
551
+ try {
552
+ this.validateOutcome(contributor, plan, outcome);
553
+
554
+ return outcome.outcome !== DyNTS_PrivacyContributorOutcome_Type.failed;
555
+ } catch {
556
+ return false;
557
+ }
558
+ }
559
+
560
+ private validateSettings(): void {
561
+ const contributorIds: string[] = this.contributors.map((item: DyNTS_PrivacyContributor_Interface): string => (
562
+ item.contributorId
563
+ ));
564
+
565
+ if (
566
+ !this.adapter
567
+ || !this.contributors.length
568
+ || contributorIds.some((contributorId: string): boolean => !contributorId)
569
+ || new Set(contributorIds).size !== contributorIds.length
570
+ ) {
571
+ throw this.buildError(500, 'SETTINGS_INVALID', 'The privacy lifecycle settings are invalid.');
572
+ }
573
+ }
574
+
575
+ private buildError(status: number, errorCode: string, message: string): DyFM_Error {
576
+ return new DyFM_Error({
577
+ status: status,
578
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|PRIVACY_LIFECYCLE|${errorCode}`,
579
+ message: message,
580
+ userMessage: status < 500
581
+ ? message
582
+ : 'The privacy request could not be processed safely. Please try again later.',
583
+ issuerService: this.constructor.name,
584
+ });
585
+ }
586
+ }