@icure/api 8.10.2 → 8.11.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 (289) hide show
  1. package/icc-api/api/IccPatientApi.d.ts +1 -1
  2. package/icc-api/api/IccPatientApi.js +4 -2
  3. package/icc-api/api/IccPatientApi.js.map +1 -1
  4. package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +11 -0
  5. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +75 -13
  6. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -1
  7. package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +14 -0
  8. package/icc-x-api/crypto/SecurityMetadataDecryptor.js +28 -0
  9. package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -1
  10. package/icc-x-api/icc-patient-x-api.d.ts +4 -1
  11. package/icc-x-api/icc-patient-x-api.js +5 -2
  12. package/icc-x-api/icc-patient-x-api.js.map +1 -1
  13. package/package.json +1 -1
  14. package/test/benchmarks/lzma-benchmark.spec.d.ts +1 -0
  15. package/test/benchmarks/lzma-benchmark.spec.js +131 -0
  16. package/test/benchmarks/lzma-benchmark.spec.js.map +1 -0
  17. package/test/benchmarks/lzma-compat.spec.d.ts +1 -0
  18. package/test/benchmarks/lzma-compat.spec.js +187 -0
  19. package/test/benchmarks/lzma-compat.spec.js.map +1 -0
  20. package/test/benchmarks/playwright.config.d.ts +2 -0
  21. package/test/benchmarks/playwright.config.js +18 -0
  22. package/test/benchmarks/playwright.config.js.map +1 -0
  23. package/test/icc-api/api/IccAgendaApi.d.ts +1 -0
  24. package/test/icc-api/api/IccAgendaApi.js +64 -0
  25. package/test/icc-api/api/IccAgendaApi.js.map +1 -0
  26. package/test/icc-api/api/IccAnonymousAccessApi.d.ts +1 -0
  27. package/test/icc-api/api/IccAnonymousAccessApi.js +58 -0
  28. package/test/icc-api/api/IccAnonymousAccessApi.js.map +1 -0
  29. package/test/icc-api/api/IccCalendarItemApi.d.ts +1 -0
  30. package/test/icc-api/api/IccCalendarItemApi.js +67 -0
  31. package/test/icc-api/api/IccCalendarItemApi.js.map +1 -0
  32. package/test/icc-api/api/IccCalendarItemTypeApi.d.ts +1 -0
  33. package/test/icc-api/api/IccCalendarItemTypeApi.js +96 -0
  34. package/test/icc-api/api/IccCalendarItemTypeApi.js.map +1 -0
  35. package/test/icc-api/api/IccCodeApi.d.ts +1 -0
  36. package/test/icc-api/api/IccCodeApi.js +38 -0
  37. package/test/icc-api/api/IccCodeApi.js.map +1 -0
  38. package/test/icc-api/api/IccDocumentApi.d.ts +1 -0
  39. package/test/icc-api/api/IccDocumentApi.js +199 -0
  40. package/test/icc-api/api/IccDocumentApi.js.map +1 -0
  41. package/test/icc-api/api/IccGroupApi.d.ts +1 -0
  42. package/test/icc-api/api/IccGroupApi.js +50 -0
  43. package/test/icc-api/api/IccGroupApi.js.map +1 -0
  44. package/test/icc-api/api/IccKeywordApi.d.ts +1 -0
  45. package/test/icc-api/api/IccKeywordApi.js +64 -0
  46. package/test/icc-api/api/IccKeywordApi.js.map +1 -0
  47. package/test/icc-api/api/IccMedicalLocationApi.d.ts +1 -0
  48. package/test/icc-api/api/IccMedicalLocationApi.js +64 -0
  49. package/test/icc-api/api/IccMedicalLocationApi.js.map +1 -0
  50. package/test/icc-api/api/IccPlaceApi.d.ts +1 -0
  51. package/test/icc-api/api/IccPlaceApi.js +64 -0
  52. package/test/icc-api/api/IccPlaceApi.js.map +1 -0
  53. package/test/icc-api/api/IccRecoveryDataApi.d.ts +1 -0
  54. package/test/icc-api/api/IccRecoveryDataApi.js +95 -0
  55. package/test/icc-api/api/IccRecoveryDataApi.js.map +1 -0
  56. package/test/icc-api/api/IccRoleApi.d.ts +1 -0
  57. package/test/icc-api/api/IccRoleApi.js +34 -0
  58. package/test/icc-api/api/IccRoleApi.js.map +1 -0
  59. package/test/icc-api/api/IccUserApi.d.ts +1 -0
  60. package/test/icc-api/api/IccUserApi.js +96 -0
  61. package/test/icc-api/api/IccUserApi.js.map +1 -0
  62. package/test/icc-api/e2e/IccCalendarItemApi.d.ts +1 -0
  63. package/test/icc-api/e2e/IccCalendarItemApi.js +46 -0
  64. package/test/icc-api/e2e/IccCalendarItemApi.js.map +1 -0
  65. package/test/icc-api/model/modelHelpersTest.d.ts +1 -0
  66. package/test/icc-api/model/modelHelpersTest.js +45 -0
  67. package/test/icc-api/model/modelHelpersTest.js.map +1 -0
  68. package/test/icc-x-api/auth/group-switch-test.d.ts +1 -0
  69. package/test/icc-x-api/auth/group-switch-test.js +81 -0
  70. package/test/icc-x-api/auth/group-switch-test.js.map +1 -0
  71. package/test/icc-x-api/auth/jwt-concurrency-test.d.ts +2 -0
  72. package/test/icc-x-api/auth/jwt-concurrency-test.js +112 -0
  73. package/test/icc-x-api/auth/jwt-concurrency-test.js.map +1 -0
  74. package/test/icc-x-api/auth/jwt-provider-test.d.ts +1 -0
  75. package/test/icc-x-api/auth/jwt-provider-test.js +197 -0
  76. package/test/icc-x-api/auth/jwt-provider-test.js.map +1 -0
  77. package/test/icc-x-api/auth/smart-auth-provider-test.d.ts +1 -0
  78. package/test/icc-x-api/auth/smart-auth-provider-test.js +224 -0
  79. package/test/icc-x-api/auth/smart-auth-provider-test.js.map +1 -0
  80. package/test/icc-x-api/autofix-anonymity-test.d.ts +1 -0
  81. package/test/icc-x-api/autofix-anonymity-test.js +122 -0
  82. package/test/icc-x-api/autofix-anonymity-test.js.map +1 -0
  83. package/test/icc-x-api/confidential-entities-test.d.ts +1 -0
  84. package/test/icc-x-api/confidential-entities-test.js +168 -0
  85. package/test/icc-x-api/confidential-entities-test.js.map +1 -0
  86. package/test/icc-x-api/crud/comprehensive-crud-test.d.ts +1 -0
  87. package/test/icc-x-api/crud/comprehensive-crud-test.js +276 -0
  88. package/test/icc-x-api/crud/comprehensive-crud-test.js.map +1 -0
  89. package/test/icc-x-api/crud/entities-crud-test-interface.d.ts +16 -0
  90. package/test/icc-x-api/crud/entities-crud-test-interface.js +407 -0
  91. package/test/icc-x-api/crud/entities-crud-test-interface.js.map +1 -0
  92. package/test/icc-x-api/crypto/anonymous-delegations-test.d.ts +1 -0
  93. package/test/icc-x-api/crypto/anonymous-delegations-test.js +587 -0
  94. package/test/icc-x-api/crypto/anonymous-delegations-test.js.map +1 -0
  95. package/test/icc-x-api/crypto/concurrency.d.ts +1 -0
  96. package/test/icc-x-api/crypto/concurrency.js +35 -0
  97. package/test/icc-x-api/crypto/concurrency.js.map +1 -0
  98. package/test/icc-x-api/crypto/crypto-utils.d.ts +1 -0
  99. package/test/icc-x-api/crypto/crypto-utils.js +79 -0
  100. package/test/icc-x-api/crypto/crypto-utils.js.map +1 -0
  101. package/test/icc-x-api/crypto/cryptoTest.d.ts +2 -0
  102. package/test/icc-x-api/crypto/cryptoTest.js +402 -0
  103. package/test/icc-x-api/crypto/cryptoTest.js.map +1 -0
  104. package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.d.ts +1 -0
  105. package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js +166 -0
  106. package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js.map +1 -0
  107. package/test/icc-x-api/crypto/exchange-data-manager-test.d.ts +1 -0
  108. package/test/icc-x-api/crypto/exchange-data-manager-test.js +674 -0
  109. package/test/icc-x-api/crypto/exchange-data-manager-test.js.map +1 -0
  110. package/test/icc-x-api/crypto/full-crypto-test.d.ts +1 -0
  111. package/test/icc-x-api/crypto/full-crypto-test.js +454 -0
  112. package/test/icc-x-api/crypto/full-crypto-test.js.map +1 -0
  113. package/test/icc-x-api/crypto/legacy-metadata-migration-test.d.ts +1 -0
  114. package/test/icc-x-api/crypto/legacy-metadata-migration-test.js +379 -0
  115. package/test/icc-x-api/crypto/legacy-metadata-migration-test.js.map +1 -0
  116. package/test/icc-x-api/crypto/secure-delegations-manager-test.d.ts +1 -0
  117. package/test/icc-x-api/crypto/secure-delegations-manager-test.js +278 -0
  118. package/test/icc-x-api/crypto/secure-delegations-manager-test.js.map +1 -0
  119. package/test/icc-x-api/crypto/shamir.d.ts +2 -0
  120. package/test/icc-x-api/crypto/shamir.js +167 -0
  121. package/test/icc-x-api/crypto/shamir.js.map +1 -0
  122. package/test/icc-x-api/crypto/share-deduplication-test.d.ts +1 -0
  123. package/test/icc-x-api/crypto/share-deduplication-test.js +250 -0
  124. package/test/icc-x-api/crypto/share-deduplication-test.js.map +1 -0
  125. package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.d.ts +1 -0
  126. package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js +71 -0
  127. package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js.map +1 -0
  128. package/test/icc-x-api/crypto/soft-deleted-data-owners.d.ts +2 -0
  129. package/test/icc-x-api/crypto/soft-deleted-data-owners.js +113 -0
  130. package/test/icc-x-api/crypto/soft-deleted-data-owners.js.map +1 -0
  131. package/test/icc-x-api/crypto/user-encryption-keys-manager-test.d.ts +1 -0
  132. package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js +246 -0
  133. package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js.map +1 -0
  134. package/test/icc-x-api/entity-with-attachments-api-test.d.ts +1 -0
  135. package/test/icc-x-api/entity-with-attachments-api-test.js +142 -0
  136. package/test/icc-x-api/entity-with-attachments-api-test.js.map +1 -0
  137. package/test/icc-x-api/filters/filters.d.ts +1 -0
  138. package/test/icc-x-api/filters/filters.js +49 -0
  139. package/test/icc-x-api/filters/filters.js.map +1 -0
  140. package/test/icc-x-api/filters/healthelement.d.ts +1 -0
  141. package/test/icc-x-api/filters/healthelement.js +333 -0
  142. package/test/icc-x-api/filters/healthelement.js.map +1 -0
  143. package/test/icc-x-api/icc-accesslog-x-api.d.ts +1 -0
  144. package/test/icc-x-api/icc-accesslog-x-api.js +106 -0
  145. package/test/icc-x-api/icc-accesslog-x-api.js.map +1 -0
  146. package/test/icc-x-api/icc-application-settings-x-api.d.ts +1 -0
  147. package/test/icc-x-api/icc-application-settings-x-api.js +91 -0
  148. package/test/icc-x-api/icc-application-settings-x-api.js.map +1 -0
  149. package/test/icc-x-api/icc-auth-api.d.ts +1 -0
  150. package/test/icc-x-api/icc-auth-api.js +47 -0
  151. package/test/icc-x-api/icc-auth-api.js.map +1 -0
  152. package/test/icc-x-api/icc-calendar-item-x-api.d.ts +1 -0
  153. package/test/icc-x-api/icc-calendar-item-x-api.js +150 -0
  154. package/test/icc-x-api/icc-calendar-item-x-api.js.map +1 -0
  155. package/test/icc-x-api/icc-code-x-api-test.d.ts +1 -0
  156. package/test/icc-x-api/icc-code-x-api-test.js +74 -0
  157. package/test/icc-x-api/icc-code-x-api-test.js.map +1 -0
  158. package/test/icc-x-api/icc-contact-x-api.d.ts +1 -0
  159. package/test/icc-x-api/icc-contact-x-api.js +355 -0
  160. package/test/icc-x-api/icc-contact-x-api.js.map +1 -0
  161. package/test/icc-x-api/icc-document-x-api.d.ts +1 -0
  162. package/test/icc-x-api/icc-document-x-api.js +76 -0
  163. package/test/icc-x-api/icc-document-x-api.js.map +1 -0
  164. package/test/icc-x-api/icc-form-x-api.d.ts +1 -0
  165. package/test/icc-x-api/icc-form-x-api.js +413 -0
  166. package/test/icc-x-api/icc-form-x-api.js.map +1 -0
  167. package/test/icc-x-api/icc-hcparty-x-api-test.d.ts +1 -0
  168. package/test/icc-x-api/icc-hcparty-x-api-test.js +43 -0
  169. package/test/icc-x-api/icc-hcparty-x-api-test.js.map +1 -0
  170. package/test/icc-x-api/icc-helement-x-api-test.d.ts +1 -0
  171. package/test/icc-x-api/icc-helement-x-api-test.js +155 -0
  172. package/test/icc-x-api/icc-helement-x-api-test.js.map +1 -0
  173. package/test/icc-x-api/icc-invoice-x-api.d.ts +1 -0
  174. package/test/icc-x-api/icc-invoice-x-api.js +99 -0
  175. package/test/icc-x-api/icc-invoice-x-api.js.map +1 -0
  176. package/test/icc-x-api/icc-maintenance-task-x-api-test.d.ts +1 -0
  177. package/test/icc-x-api/icc-maintenance-task-x-api-test.js +222 -0
  178. package/test/icc-x-api/icc-maintenance-task-x-api-test.js.map +1 -0
  179. package/test/icc-x-api/icc-message-x-api.d.ts +1 -0
  180. package/test/icc-x-api/icc-message-x-api.js +54 -0
  181. package/test/icc-x-api/icc-message-x-api.js.map +1 -0
  182. package/test/icc-x-api/icc-patient-x-api-test.d.ts +1 -0
  183. package/test/icc-x-api/icc-patient-x-api-test.js +209 -0
  184. package/test/icc-x-api/icc-patient-x-api-test.js.map +1 -0
  185. package/test/icc-x-api/icc-recovery-x-api.d.ts +1 -0
  186. package/test/icc-x-api/icc-recovery-x-api.js +175 -0
  187. package/test/icc-x-api/icc-recovery-x-api.js.map +1 -0
  188. package/test/icc-x-api/icc-topic-x-api.d.ts +1 -0
  189. package/test/icc-x-api/icc-topic-x-api.js +269 -0
  190. package/test/icc-x-api/icc-topic-x-api.js.map +1 -0
  191. package/test/icc-x-api/icc-user-x-api-test.d.ts +1 -0
  192. package/test/icc-x-api/icc-user-x-api-test.js +99 -0
  193. package/test/icc-x-api/icc-user-x-api-test.js.map +1 -0
  194. package/test/icc-x-api/keyless-api.d.ts +1 -0
  195. package/test/icc-x-api/keyless-api.js +125 -0
  196. package/test/icc-x-api/keyless-api.js.map +1 -0
  197. package/test/icc-x-api/patient-user.d.ts +2 -0
  198. package/test/icc-x-api/patient-user.js +103 -0
  199. package/test/icc-x-api/patient-user.js.map +1 -0
  200. package/test/icc-x-api/storage/storage.d.ts +1 -0
  201. package/test/icc-x-api/storage/storage.js +48 -0
  202. package/test/icc-x-api/storage/storage.js.map +1 -0
  203. package/test/icc-x-api/test-api-no-parent.d.ts +1 -0
  204. package/test/icc-x-api/test-api-no-parent.js +79 -0
  205. package/test/icc-x-api/test-api-no-parent.js.map +1 -0
  206. package/test/icc-x-api/test-legacy-data-support.d.ts +1 -0
  207. package/test/icc-x-api/test-legacy-data-support.js +375 -0
  208. package/test/icc-x-api/test-legacy-data-support.js.map +1 -0
  209. package/test/icc-x-api/utils/date-encode-test.d.ts +1 -0
  210. package/test/icc-x-api/utils/date-encode-test.js +150 -0
  211. package/test/icc-x-api/utils/date-encode-test.js.map +1 -0
  212. package/test/icc-x-api/utils/graph-test.d.ts +1 -0
  213. package/test/icc-x-api/utils/graph-test.js +54 -0
  214. package/test/icc-x-api/utils/graph-test.js.map +1 -0
  215. package/test/icc-x-api/utils/lru-temporised-async-cache-test.d.ts +1 -0
  216. package/test/icc-x-api/utils/lru-temporised-async-cache-test.js +364 -0
  217. package/test/icc-x-api/utils/lru-temporised-async-cache-test.js.map +1 -0
  218. package/test/icc-x-api/utils/lzma-benchmark-test.d.ts +1 -0
  219. package/test/icc-x-api/utils/lzma-benchmark-test.js +132 -0
  220. package/test/icc-x-api/utils/lzma-benchmark-test.js.map +1 -0
  221. package/test/icc-x-api/utils/lzma-compat-test.d.ts +1 -0
  222. package/test/icc-x-api/utils/lzma-compat-test.js +218 -0
  223. package/test/icc-x-api/utils/lzma-compat-test.js.map +1 -0
  224. package/test/icc-x-api/utils/mutex-test.d.ts +1 -0
  225. package/test/icc-x-api/utils/mutex-test.js +114 -0
  226. package/test/icc-x-api/utils/mutex-test.js.map +1 -0
  227. package/test/icc-x-api/utils/to-moment-test.d.ts +1 -0
  228. package/test/icc-x-api/utils/to-moment-test.js +110 -0
  229. package/test/icc-x-api/utils/to-moment-test.js.map +1 -0
  230. package/test/support/CSM-185.d.ts +1 -0
  231. package/test/support/CSM-185.js +124 -0
  232. package/test/support/CSM-185.js.map +1 -0
  233. package/test/support/CSM-243.d.ts +1 -0
  234. package/test/support/CSM-243.js +120 -0
  235. package/test/support/CSM-243.js.map +1 -0
  236. package/test/support/CSM-543.d.ts +1 -0
  237. package/test/support/CSM-543.js +164 -0
  238. package/test/support/CSM-543.js.map +1 -0
  239. package/test/support/CSM-729.d.ts +1 -0
  240. package/test/support/CSM-729.js +225 -0
  241. package/test/support/CSM-729.js.map +1 -0
  242. package/test/support/CSM-814.d.ts +1 -0
  243. package/test/support/CSM-814.js +475 -0
  244. package/test/support/CSM-814.js.map +1 -0
  245. package/test/support/CSM-87.d.ts +0 -0
  246. package/test/support/CSM-87.js +21 -0
  247. package/test/support/CSM-87.js.map +1 -0
  248. package/test/support/CSM-93.d.ts +1 -0
  249. package/test/support/CSM-93.js +112 -0
  250. package/test/support/CSM-93.js.map +1 -0
  251. package/test/utils/FakeDataOwnerApi.d.ts +32 -0
  252. package/test/utils/FakeDataOwnerApi.js +136 -0
  253. package/test/utils/FakeDataOwnerApi.js.map +1 -0
  254. package/test/utils/FakeEncryptionKeysManager.d.ts +36 -0
  255. package/test/utils/FakeEncryptionKeysManager.js +97 -0
  256. package/test/utils/FakeEncryptionKeysManager.js.map +1 -0
  257. package/test/utils/FakeExchangeDataApi.d.ts +32 -0
  258. package/test/utils/FakeExchangeDataApi.js +92 -0
  259. package/test/utils/FakeExchangeDataApi.js.map +1 -0
  260. package/test/utils/FakeExchangeDataManager.d.ts +48 -0
  261. package/test/utils/FakeExchangeDataManager.js +82 -0
  262. package/test/utils/FakeExchangeDataManager.js.map +1 -0
  263. package/test/utils/FakeExchangeDataMapManager.d.ts +12 -0
  264. package/test/utils/FakeExchangeDataMapManager.js +38 -0
  265. package/test/utils/FakeExchangeDataMapManager.js.map +1 -0
  266. package/test/utils/FakeGenericApi.d.ts +16 -0
  267. package/test/utils/FakeGenericApi.js +65 -0
  268. package/test/utils/FakeGenericApi.js.map +1 -0
  269. package/test/utils/KeylessCryptoStrategies.d.ts +23 -0
  270. package/test/utils/KeylessCryptoStrategies.js +26 -0
  271. package/test/utils/KeylessCryptoStrategies.js.map +1 -0
  272. package/test/utils/TestApi.d.ts +3 -0
  273. package/test/utils/TestApi.js +30 -0
  274. package/test/utils/TestApi.js.map +1 -0
  275. package/test/utils/TestCollectionUtils.d.ts +1 -0
  276. package/test/utils/TestCollectionUtils.js +310 -0
  277. package/test/utils/TestCollectionUtils.js.map +1 -0
  278. package/test/utils/TestCryptoStrategies.d.ts +42 -0
  279. package/test/utils/TestCryptoStrategies.js +80 -0
  280. package/test/utils/TestCryptoStrategies.js.map +1 -0
  281. package/test/utils/TestStorage.d.ts +23 -0
  282. package/test/utils/TestStorage.js +61 -0
  283. package/test/utils/TestStorage.js.map +1 -0
  284. package/test/utils/roles.d.ts +14 -0
  285. package/test/utils/roles.js +345 -0
  286. package/test/utils/roles.js.map +1 -0
  287. package/test/utils/test_utils.d.ts +87 -0
  288. package/test/utils/test_utils.js +452 -0
  289. package/test/utils/test_utils.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSM-814.js","sourceRoot":"","sources":["../../../test/support/CSM-814.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHcpHierarchyApis, createNewHcpApi, getEnvironmentInitializer, setLocalStorage, TestUtils } from '../utils/test_utils'\nimport { randomUUID, webcrypto } from 'crypto'\nimport { expect, use as chaiUse } from 'chai'\nimport 'isomorphic-fetch'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { IcureApi, ShaVersion } from '../../icc-x-api'\nimport { IccPatientApi } from '../../icc-api'\nimport { HealthcareParty } from '../../icc-api/model/HealthcareParty'\nimport { Patient } from '../../icc-api/model/Patient'\nimport { User } from '../../icc-api/model/User'\nimport { testStorageWithKeys } from '../utils/TestStorage'\nimport { TestCryptoStrategies } from '../utils/TestCryptoStrategies'\nimport * as chaiAsPromised from 'chai-as-promised'\nimport initMasterApi = TestUtils.initMasterApi\n\nchaiUse(chaiAsPromised)\n\nsetLocalStorage(fetch)\n\nlet env: TestVars\n\nlet hierarchyApis: Awaited<ReturnType<typeof createHcpHierarchyApis>>\n\n/*\n * A legacy (v7-native) owner fixture: an RSA keypair plus the ciphertexts (self and to-parent\n * exchange keys, delegation/encryption keys, encryptedSelf) produced once by the legacy SDK v7\n * (@icure/api 7.1.32) via test-scripts/generate-csm-814-legacy-patient.ts. The owner creates a\n * patient with one secret id and immediately shares it with a parent P - this is the \"patient\n * already has a secret id, already shared with a delegate such as a parent\" precondition of\n * CSM-814. None of these ciphertexts are derived from the owner's/parent's ids, only from the\n * keys, so the ids can (and should) be generated fresh at test time to avoid conflicts when\n * running the suite multiple times against the same (non-wiped) backend - see\n * legacyAesExchangeKeys/legacyPatientBase below, which weave the fixture's fixed ciphertexts\n * together with test-time-generated ids.\n *\n * Each entry in aesExchangeKeys is keyed by a \"fingerprint\" - the last 32 hex chars of a public\n * key's spki representation, not a cryptographic hash of anything - identifying which private key\n * can decrypt that entry. A self exchange key (A->A) only needs A's own fingerprint. An exchange\n * key towards someone else (A->P) has two entries: one decryptable by the recipient (P's\n * fingerprint), one decryptable by the sender's own key as a personal backup copy (A's own\n * fingerprint again, the same value already used for the self exchange key below).\n */\ninterface LegacyOwnerFixture {\n privateKey: string\n publicKey: string\n selfFingerprint: string\n selfExchangeKey: string\n toParentFingerprint: string\n toParentExchangeKey: string\n toParentExchangeKeyOwnCopy: string\n selfDelegationKey: string\n toParentDelegationKey: string\n selfEncryptionKey: string\n toParentEncryptionKey: string\n encryptedSelf: string\n}\n\nconst pPrivateKey =\n '308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282010100ba2cd9058441dccb3238ab4725e6536e7d8daba3a3590e226c350c84cd421b3f8cf63e4deb90eff1d7264f3d1facad0dc46e26237bd9afe476c992b1913ace05b3b5531f1d5d2618d01d7201c88b18eccfb16876a3cba3d1a928530de9e19f37a25ef41c069a7527493c603771ea638e5667c98cca585b99c91161e8eeccd17b58c649c156dcbbe02f0140565a1ea08ff72ef4466a3967e50b93a83d6a82084a40d050776b0a3bcafe3d0cdd4c56bf673d905b9fc800b146b990a2a33d0f1575c1c724c629d2c4978125e769631f6c5b86d7db1e4dbcf26edd2e383dd28bc3df7853581b5555fdc09b1a85e7a6b7b1981d63abf2e29c315d03f4e4e0dd735d25020301000102820100204165e645484df32c83d1f4f535870df515c6ff866d06fc62c7fc1fc41a287365be4204290486f5dd0347a63ce7236267be77c01d14959b5d1346659a56585c778aba58813362c6d8c3c93d52dbfa9908d0e15af0bcf6e87bc8bf3f015ef44164d1d3b449569866929331ce595fb518f3926ec2844a33b09cbbf4bd31266e4286b60f156d6ba2bf9dd429725d705c92b2ef9167cddea39a479629e400f8c6469b17facff14c4823b3d14a4bbbb739f4360e0635b443cd30ba6f35c260aa3ce6bbc4e6aa0e430061e464e8a5b5feac05ade105acebbbf39d7f31c6de9005fa701289688ee1c8892babab209d443f40c5da201aacaaa16d6b8163cc7c43cea54f02818100fb269017878b8f7ba9ddfa021a4a7996cf35259db2230e72404fdf8e3572cb56ba17af365b1c7c5550ab6a1be72a37a8f6acb2456b4252461f979c2a9b54e90e9e1de40d9a4f187b270bfa0818b9bc0afcc9a2145ba8767d55f5361b18c9c2e78597ed11e351447df68c7ce0118ef447873dd82783cb538cb011ead98c7ec4c702818100bdc51c817f4ca90e4786336f518b7c5d88042bb898bcfa28b6e54847ca9161497c7e9eef03ae5c618e7a5ab5720c77408f3c0950bf36b649fc7d4c8dcb01b032694d97d14e80550d2088c359f2da6ea41eb85dad76a4918e1aa548e0b3a2b8cefb80c3211c724c8404d7b5aaeeb63ff4b980468f32fbedad2ebc2a9489e00ab302818100c60d3df9e020d5305edf36852bf868f3dd48faf5e58131a6354307771c7cff0ed047571b55341c7426de5619d4ec7ce2184c4d74e2c5751de951e48bd0dc5fc0f03d80169e061bb71a2e9ea87ddf1203d41ea95ac6810d977f0e94f13f55f406215a924fd5e3c35055f9a98c052ca74434c93748c9ecb06134839ca09be36807028181008cc2fcd6017af79b23eaa3945ac440479070a78d919dfb60dfe94aa815d5a8783de41e37e45f1d1f2ff409fcb4d01254ccea176ed1a6dfa819a5477795b176e4adbf647158ed5029208cd17a92ecfb4cb98cbfcfbf456ac22179a0892c35f32774de99dea19f16aa867d0abff3b933cf6f197b3d14f051e837d6532f42e5f08902818100f80e6a6fdaf6e1a8292868bc386cfc8804451502b747b92ca506ad459537e8e7e0b58fd648836da034ef0ef59c81c3819913060408f9d7e6ec533ff39331914a9db2476dfe498e22c1774892c1d979f5ad1396d172edd416fb0467e5ae340c93c11ab47732c184c3a6e90df1e6a39742b401b02fa2fde1f7d50ec8b8a1dc9157' // pragma: allowlist secret\nconst pPublicKey =\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100ba2cd9058441dccb3238ab4725e6536e7d8daba3a3590e226c350c84cd421b3f8cf63e4deb90eff1d7264f3d1facad0dc46e26237bd9afe476c992b1913ace05b3b5531f1d5d2618d01d7201c88b18eccfb16876a3cba3d1a928530de9e19f37a25ef41c069a7527493c603771ea638e5667c98cca585b99c91161e8eeccd17b58c649c156dcbbe02f0140565a1ea08ff72ef4466a3967e50b93a83d6a82084a40d050776b0a3bcafe3d0cdd4c56bf673d905b9fc800b146b990a2a33d0f1575c1c724c629d2c4978125e769631f6c5b86d7db1e4dbcf26edd2e383dd28bc3df7853581b5555fdc09b1a85e7a6b7b1981d63abf2e29c315d03f4e4e0dd735d250203010001' // pragma: allowlist secret\n\nconst aFixture: LegacyOwnerFixture = {\n privateKey:\n '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100c35a740119a64b265b8524e44c2a548efc21b088f8df2575a6a89bf0f0a7c9fb7888ba3719d5433032d4a3c1290fc525e6874523c841aa43367a3bbb015f1b2e1b3b2cdd323369a9df80768a5583fb6b2b01ebe601d680e0ad2cb5cf8d853a49df2f95cb6cd0caf9eb9cb59d6161dd7fbd4a980166ec1972808b57ad75721ae9988b85fe23b7278f3efeb530805da70b7afd1f7a017bc0da2f75ff2df15240b57b29d4c178599d3b7324ff6e3016792695a5725f3cc9475d69fc8181f66587d3382906a912c7a1f28485fe98b2faf06cb6c2877d1195f1147543a52ab919b912f3b2d7ee867715ba7faafd25522f091d4bfa00682f43aa5def879985d651862302030100010282010005b2cb447a25f68fd2f9cf302ed7634375aff3e46fc208346676a2d6aab33f13c5b36cebf38c75815febce950af549b4d49e5bb8a5fc485faa8b0c7197eef2c7856c6df8e56d484d44bd0c782926a222c13fe832fbb28a9fa990bb9c8d9af62ed00f8b95c201ee5e9c21579c148a6df9bb3a844e655d1586f206c4ecab7e10b24123ec6a9cc3089472dc3be93eb8af256ceefd5f609e020eb85bbf53aaf91dc0306df33321b2e4688320f3834d3b9e074545206ec18c3b011273edcddbc6135f2af9d71b6b41a2c331c96a08c90a24109b94a33e6a9c8905977a32ac25e78b16f9f6b27f5b66f6103de723ecc72a0db40b400408684da8143475317688298b3902818100fef04b985e01df81e290ab75db0836b662eb23b846908caff9c8e76da29280412cc713223234c6eab3a3d0f908a005343c11846addb672b999250763a4d2a76f67e83a2d9120d433a734a098320ec3afdfc082e3c27e3d06e12ab0dcef4d9a466727f3e7e2446d0fcf4908dd6784eb121f4e2fe72da118ee2945d2d547d9a65902818100c42aa765b54fa65e73f277b6c8e90a8b5f1186fd5cd57ffedfa0e535efa58e2b6832e466d119f669e0e1644f5f12ebd0298eaa995a96dc72574a19277e9e030dcf052136d3e811ea8db145b5d9dd11a097794dbf74015952eb1a04d96882e26dc23eafbd455bdad7e01fee889c713213c724f0bbc68ecaa997c34b126a8af8db0281801768f5681e69c99e61b1ab2cfd59f9bc31c529d8881249f8f6d4edfb714c469eb57fea4fdf905d1bbc3734bf497d783cddaf361ba21458e09621825632126df19af706309cfd08bf5d8145a5f422caf161788a0c6415b780e438495960581dec8d186c1b44f9c7920614cccd97edeab01553d6ae41d0633bab6a8ffba9c760b102818019c0efd12e889272fc0ded219626e23781f7af1d3c3edb5afec904ce9bf3c442769f97d4d7c6eccee1b33594260b39e24e52689b518554d3be1a004b6b181b96888347e506d504e5224d0fb5dc3065cc0b96e55a2944b4116ac433b6c73dc7b4593819a263a4b78a77e6394ebe1b2e53e2653b25abdfbb43a0a5070a17eabed902818100e27ed14daac47b6edbf202468e4aa43b9a8caca188235a7bf492ee3bdf72300f1d53cf3f5d09f1496000fa5b26e486f5c9d3e93e830dbbd409ddb67a07240d6bd25d0cadbc9ba9ade07144ee6b9ed05cb5d1e1c069098f661db6cd1e355a65bb3b2a28bbf16711f38afa3c9c8da28d4261bf9536a50b9368c7e7aec217e4aa91', // pragma: allowlist secret\n publicKey:\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100c35a740119a64b265b8524e44c2a548efc21b088f8df2575a6a89bf0f0a7c9fb7888ba3719d5433032d4a3c1290fc525e6874523c841aa43367a3bbb015f1b2e1b3b2cdd323369a9df80768a5583fb6b2b01ebe601d680e0ad2cb5cf8d853a49df2f95cb6cd0caf9eb9cb59d6161dd7fbd4a980166ec1972808b57ad75721ae9988b85fe23b7278f3efeb530805da70b7afd1f7a017bc0da2f75ff2df15240b57b29d4c178599d3b7324ff6e3016792695a5725f3cc9475d69fc8181f66587d3382906a912c7a1f28485fe98b2faf06cb6c2877d1195f1147543a52ab919b912f3b2d7ee867715ba7faafd25522f091d4bfa00682f43aa5def879985d65186230203010001', // pragma: allowlist secret\n selfFingerprint: '43aa5def879985d65186230203010001', // pragma: allowlist secret\n selfExchangeKey:\n '8a7cd219e185ba9ec3f47afeb5a8bd0e446f162bb69c74459b63ffb17af7ce55e33bdce2ac609734592b80241866599922cfc69f9d934a4cecb079c5f23d17e0604115b118946c72739b901c98af54ccbad4e53af24de9f989c39f9d60f39d88a974d6c8aa82f42385693db64ee76ea32cad323c2bd106fda80f9b681f113671876fa2f53f84113cb54a5e67db2a7faa882250b28568755feca69302f2d71f42d76fd63313e4db52f7b32a90c0b5633fc23ac4ed0c0e1861610be6e57980e3ede9de1998f467752938001ad2d89c3705b364545edda4f807fff7ed2abeffa8dbfca82952602209db0d026a6f64d7652847b6ddc0e32dd95547412cb0eaf86ad2', // pragma: allowlist secret\n toParentFingerprint: '9c315d03f4e4e0dd735d250203010001', // pragma: allowlist secret\n toParentExchangeKey:\n 'b1cfd3684b474ced80cf5cbb651f1228d0700c49ceda07e9b0a675d94ca737d3b93531881fdd68b65c97f0fd26b30a05346a0c194a23a90a809af31eb93c52f3d830f163e226b876c1eee4104d85be524ca35a8732243df381be8553713f3c987f1ee0cf04e8b9bb56d501012435722a634755e7aafae892f341feb61c9b6aafe36b1b425c3b0af770cba8de52ab861336f17c0ccea67b4b9b24b5fd46768876ea58764af11ff9a644777038087812519a2ef64425bf863ffb9091c5530aa5905e60224fa03eac99ff994b0727fda1dbb68200496d46df6b312255ae86614f99b47f5b5330567ee73f232aa1008ad48f434f179a4cd6ddd9c20d39058de4b453', // pragma: allowlist secret\n toParentExchangeKeyOwnCopy:\n '1531714e09925bf4864063efb6f7f8a6d9ae522568f1fe4eda5722fdb88cc8caaba6f1e791d97d269c8ccbd40a0ca6d7163a99aa160831c7beb571f1c21819c23b6211bb2ee2f745701bebb2492db5e77b210669e32bf9cc98f7e681b092da6b207aa40564c93be462c148a8a9e7876e4a0989937e135dfbfe0bb7539cd01ceef4da45e3e087b3b6bce89561c8e35c7962ff411a0fef01eda721bd01ec4b7efe12742fc22fe2c96d5c7176620ed0897dc0d1e7151d6c2ac9688c9b0fde3e03ff445814dcb60f52c8f0f59b2b414d2859324d5201637e78236352bf12bda0b134026b05b4b6948dfd20f859979b97141d13675766c08bef058ebb7c3a277b9e7b', // pragma: allowlist secret\n selfDelegationKey:\n 'f1b055534b35feb503ca2ce44e160b7b899bb2550789e409d212639cf536409eab05555fe38ee1c42d0eec740336c0a44cb6ca23b58f273e96a6d526711737bc8476fc4b630cd237373547cfc648c222d4fe22589c0baa9c8e3c5c0498e8efb9', // pragma: allowlist secret\n toParentDelegationKey:\n 'd298bad5544a61db3c796a7da8924fcd7545886c6431b8d5a1032a017dd211c7fef10ea6559671c8af8b3492656b4b999328e2420df2b6cb2833aca3ad02dfb11b633442f6a0a44abfbda8ec54785213b5bf38e1bcc30cc1a39051749238c954', // pragma: allowlist secret\n selfEncryptionKey:\n '46f02bcd460442dbfdc911b64f633cac3d81e6a2baaf3bca8f31c6ce86827d89be14a47fe3a466c51515ee439cc020384836789d72e3fa6dc1a09f23798ea6719af2a1da67bc3bd496bca7c9d1ae03482aa5a6e9d0a7dfd6954aac15f82b2b91', // pragma: allowlist secret\n toParentEncryptionKey:\n '21b7a2b03e63f5858a7cd7ffba8e3577daca71961a6095eb1d273156001f3023a629c41acff4b8d570c450429648b385d1b542343e0dd7e8241fea45b84af4938739daacfe882e2801f321b9ec95434983834642b75c5be4e75c731d661f1983', // pragma: allowlist secret\n encryptedSelf: 'HAQoMr0VAX9CrU1fBKzWSfUsXham+TFtlUSbb7e3iA0=', // pragma: allowlist secret\n}\n\nconst bFixture: LegacyOwnerFixture = {\n privateKey:\n '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100bca9f007e74c4f256437e5d81b0dd7d2a5c1c934dbe15968b0201415f7611f816d742da515f707433b70b8c2cf0fd0e1fad7ff55805e059126778d79759b1467ed41594881ca9ec69a5972280eb296191b4e6e641b4810df34fbca1cae31b1622db4e932b2b94ac4cbc2ecdfab979ae60ea9824a7e809cd539c3f28a6a2589a91277281082ab892e0f726b1cebed61c68bdfd4c93f8c48a285e875dbfb90a46a1a168b2b25e2115edfcf27040703212b8a76b4d206aab0bed4235b023a2ef415be40cf32864d2fb0e8313a16e98b4a1e0777035203f926b51456bb0441e20119631f7e4cd3ef5e1307fb48312a5c646e2a8105ecbe6a290a809fb18a0d170e59020301000102820100271bed339e397de0a8ed437ab06506bbd67b9ceb95b719b32f6b7eee6cc917e05b21adc29e9286516415825f73cffa03965dc742e0a8dceb91774fff0127a42bc50d7a6622edaf4b493cc882d0452a034b5b4f5bf621d2c98a70b59d8b68a6b64cf6472f28c86b5cef465997263977b5400dd881fbc64a7c930c710f4b60bbafd30a6ead5a6184a01b9fd4fcd5d5a4be5e89442b7f80897e35443f159da6de1f911c14324afea504f505ae95f84c2b0a4c5e142b32a1c7ac0415d165c77fda2cf5e696d5b7c937abc5afa002cf58c85ed6af540ce388488371e3903ad48444d1dca3a5d93912b44a94a9d21f0523986829cd752a5538b30c91ccf5696906339702818100e2352b516e5f0e44ecbf6361be811897e287318095827420c96e63d3e2adb2712386066dacc7962280bbc8890d02f97afb9816bab1cb1b5339d6def2e2b9cbb7ae2223528b0a04298f02546b629f232ba2bbd5f290c6552196c0f4dc4814e407d499444e874c9da04213a7249ecc5c327e4309d23cfd0d8947d7daddc9cc431302818100d582efe894ce249859262c0a27867c87e8b6fbe417b2bc27fd1542873d76582000b31c10f4c41074df8a175c97eabe08bd112a3503951939d28cd393c93465f619ed4e5b90aa4d4e5bc919a6c0bba298ad8f00dc317594ab545fb808ed2084bbfaad5631fd279c7adb9ae6e55874e0aceb4591e7a3ac82d8f84e80206a882a6302818100ba3dd86a751ae21eb1656a27a1b79c4e00fe1a2da9eafc3dba5a9eea66e967cf6ad60018f0766b1001399a83ec2894cb42b61790a2ad7cd3eafd141699c12b0f11d99d876a5e56caf8a98c63d590fc5e02dfefe8847626c53edfa33a724670f05983cf0f70aa0de55241e80d68890d27ad78f86f1633aa9f6a7d37ffff13a3ed0281807f064d50e3e6d8a2c2b71110617f836b202a6d25c06b97c17ab24148506aadf72c3363093b75c20ca64973a8a4c1059a1151baf89b4f03190188c2ff737ef702395e9375aa5587748cead19601a8200e1183b89147e39a356c171e58412b4d8cc0908b6d661d40dd5ef58355031155f1ca6f3364ca5d81e32fa7145734ca19dd028180491522dd3c2eb7b1e612c5bb0c321e910e4037bbe88e4221d8d5d3fc95915acab6404c08a5360723b057342152213c12707fde00beb43c7113b8f7150f88c80eca521867f49c9ebd37f3d3c32ac76bcb521f15d01921dac0bdadee2b248db73471b53bbce26cbbc50a4c0772d982dfa1984addbb560a58eb7f02a55484d09a13', // pragma: allowlist secret\n publicKey:\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100bca9f007e74c4f256437e5d81b0dd7d2a5c1c934dbe15968b0201415f7611f816d742da515f707433b70b8c2cf0fd0e1fad7ff55805e059126778d79759b1467ed41594881ca9ec69a5972280eb296191b4e6e641b4810df34fbca1cae31b1622db4e932b2b94ac4cbc2ecdfab979ae60ea9824a7e809cd539c3f28a6a2589a91277281082ab892e0f726b1cebed61c68bdfd4c93f8c48a285e875dbfb90a46a1a168b2b25e2115edfcf27040703212b8a76b4d206aab0bed4235b023a2ef415be40cf32864d2fb0e8313a16e98b4a1e0777035203f926b51456bb0441e20119631f7e4cd3ef5e1307fb48312a5c646e2a8105ecbe6a290a809fb18a0d170e590203010001', // pragma: allowlist secret\n selfFingerprint: '6a290a809fb18a0d170e590203010001', // pragma: allowlist secret\n selfExchangeKey:\n '2e0e20a809aa336805ad7f933d4dbc4a18194d130b89d01369c48330e90ea845f2c960077a33721004cc759921759e2d3b302ec6989889a6e76863fa8a24dea33f8d0543fc975a16642d7a5508a1a2216e10d776bec61bb1a64ab1716af8d8e1348525c404bc57a0f33978faca9bb59df571279aec39f028ba49966a8faec7c376143c8e753c19d89da739d3e9d52ec1e25418c5d1d8c2b677c02fe2587b8e6cfcf14a84909b6e9759cc4f60beebd9d087b438d2fe2ee98b64a86cb24ec7c7ff32686773c53a5ee9374770764a70e662926af23e9595f5bdd0e9b6e9b420aa46764f2fe1583b06c46fd3991a60baa5faa191d141631b76540d05ac99f918c8f2', // pragma: allowlist secret\n toParentFingerprint: '9c315d03f4e4e0dd735d250203010001', // pragma: allowlist secret\n toParentExchangeKey:\n 'a47381e623617b9f36272d0e9a9f7f3eb28232f10894d0d097d590399abf95a37a54a72fb063112bb0947828ce88a81e772aac1eac2fc31c3ea8e295c93319a08453ace46c863f389f3d7ce57d55c2642db4ffc8edf28d8bd957a80b940991ef237286df32e4cffc6efcf70f0c3b3a8f733742173dc0219f4a193dcd64c29e393d3c0ab4b21d69732c409bbe905ef460befda36b309d4097a63847db9fbfbebecf23eb768f3aed08d156f518ef9efc18ba5670312184d6f08ff4d20f5205aad6bc24bcd1b05cc92d14f7a0fc1c410b77a67b4619ac921f2fc96d2dbb779f5b029bd2f2a6894ae69f7b2047158936e009c5755ac5805b0fc8cf08ea84dd2d4d75', // pragma: allowlist secret\n toParentExchangeKeyOwnCopy:\n '91719b9311f00e8ea8880b5a4a2da4ca8e35e26d5f46d6640df5ad1bb4f61051547f90cf16c06b1480e5c73862920f33da8081c468d343c054b177e9b9b9680642fdb6dcdb49ad0a1fd0dde979bc2e5154781228d46cbcd2ad33756e372459eb2267fd6bdaba4cacb2f345acef94251521cc5320cd22606398163cd6f40e3d7b1be6832017513960bc4c24490b9f11458958ccc9ae376eee8501374a540c91ec60a98e6d3c9132288e032b7143f75c33b790a499e40052511e7cc282e8a20e59454df29cc3332296ce583d35fbf145ba9ab2268c30fb105df5ee291aa90b33a90a15f9b891294b1c952748d65031d00b2a7db17712f171bb6190a9483c47360e', // pragma: allowlist secret\n selfDelegationKey:\n '93a5601d3fd899ac9a7493f7222be465f77ee7925cc6fbf0ece66f799aaab0b19b80f9998ed1c738bf5672468a3de2cb6d6f2493a601c28dafcdbba8a50d0a1c67e70bd3a7786e423cba7601fa851b9b29ba15f8c5c97e92dd6bec338599c0a9', // pragma: allowlist secret\n toParentDelegationKey:\n '815d54c92b2a4b18194698c31343aa40ebe5f525b1fa1d178150fe50f5f39125ac400580d2a37df486c505960348d6ab9f8fa3e7ce94bccd23dc8622e5c285be2b0eed7b0142e00bfe81d8840eb64aad3eaa0b47373eecd78024f4c47b86bde3', // pragma: allowlist secret\n selfEncryptionKey:\n '11aa5c306539cae18625164724d4a7141be0bb5ebc888b9c6255f2aa6c93f7e96b1b5c38a0355a82d0d9667a3d4606eb73d733b02581a6f1cbc4dda9c71ee831ce5648be7f06443a830872974b73cfac6e6d5b0aaa04ecd186a2551f73203b10', // pragma: allowlist secret\n toParentEncryptionKey:\n '24fd6f9e63f75cbe7ee8d3d5b8c18befda21dc35b4cfed0860434ff296e10023534da97b00d5a09372c7264ac44c45a20f5c2a1858515f75a70a922009228c1245d6401ef1f9f7a30cf63f6db765ddfb7e12f27243691ff6c5116931c9479e6c', // pragma: allowlist secret\n encryptedSelf: 'zqX7C7Jxgm0Kx0XMByQqnn/F3QSD3wJabtxBX2bMM1U=', // pragma: allowlist secret\n}\n\nfunction legacyAesExchangeKeys(fixture: LegacyOwnerFixture, ownId: string, parentId: string): HealthcareParty['aesExchangeKeys'] {\n return {\n [fixture.publicKey]: {\n [ownId]: { [fixture.selfFingerprint]: fixture.selfExchangeKey },\n [parentId]: {\n [fixture.toParentFingerprint]: fixture.toParentExchangeKey,\n [fixture.selfFingerprint]: fixture.toParentExchangeKeyOwnCopy,\n },\n },\n }\n}\n\nfunction legacyPatientBase(fixture: LegacyOwnerFixture, ownId: string, parentId: string, firstName: string): Patient {\n return {\n id: randomUUID(),\n firstName,\n lastName: 'Doe',\n delegations: {\n [ownId]: [{ owner: ownId, delegatedTo: ownId, key: fixture.selfDelegationKey }],\n [parentId]: [{ owner: ownId, delegatedTo: parentId, key: fixture.toParentDelegationKey }],\n },\n encryptionKeys: {\n [ownId]: [{ owner: ownId, delegatedTo: ownId, key: fixture.selfEncryptionKey }],\n [parentId]: [{ owner: ownId, delegatedTo: parentId, key: fixture.toParentEncryptionKey }],\n },\n encryptedSelf: fixture.encryptedSelf,\n }\n}\n\n/**\n * Creates a data owner with a caller-provided (fixed or freshly generated) RSA keypair, an\n * optional parent and aesExchangeKeys (for legacy fixture owners), and an initialised api for it.\n * extraKeys lets the returned api locally hold another data owner's key too (e.g. the shared\n * parent's), simulating a device/session with access to multiple keys.\n */\nasync function createFixedKeyDataOwner(\n testSetupApi: IcureApi,\n id: string,\n opts: {\n firstName: string\n privateKey: string\n publicKey: string\n parentId?: string\n aesExchangeKeys?: HealthcareParty['aesExchangeKeys']\n autoDelegations?: string[]\n extraKeys?: { dataOwnerId: string; privateKey: string; publicKey: string }[]\n }\n): Promise<{ api: IcureApi; user: User }> {\n await testSetupApi.healthcarePartyApi.createHealthcareParty({\n id,\n firstName: opts.firstName,\n lastName: 'Doe',\n parentId: opts.parentId,\n publicKey: opts.publicKey,\n aesExchangeKeys: opts.aesExchangeKeys,\n })\n const login = `csm814-${opts.firstName.toLowerCase()}-${randomUUID()}`\n const password = randomUUID()\n await testSetupApi.userApi.createUser({\n id: randomUUID(),\n name: login,\n status: User.StatusEnum.ACTIVE,\n login,\n passwordHash: password,\n healthcarePartyId: id,\n autoDelegations: opts.autoDelegations ? { all: opts.autoDelegations } : undefined,\n email: `${login}@icure.com`,\n })\n const storage = await testStorageWithKeys([\n { dataOwnerId: id, pairs: [{ keyPair: { privateKey: opts.privateKey, publicKey: opts.publicKey }, shaVersion: ShaVersion.Sha1 }] },\n ...(opts.extraKeys ?? []).map((k) => ({\n dataOwnerId: k.dataOwnerId,\n pairs: [{ keyPair: { privateKey: k.privateKey, publicKey: k.publicKey }, shaVersion: ShaVersion.Sha1 }],\n })),\n ])\n const api = await IcureApi.initialise(env.iCureUrl, { username: login, password }, new TestCryptoStrategies(), webcrypto as any, fetch, {\n storage: storage.storage,\n keyStorage: storage.keyStorage,\n entryKeysFactory: storage.keyFactory,\n })\n const user = await api.userApi.getCurrentUser()\n return { api, user }\n}\n\n/** Creates a patient the normal (v8) way and immediately shares its secret id with parentId. */\nasync function createV8PatientSharedWithParent(ownerApi: IcureApi, ownerUser: User, parentId: string, firstName: string): Promise<Patient> {\n const created = await ownerApi.patientApi.createPatientWithUser(\n ownerUser,\n await ownerApi.patientApi.newInstance(ownerUser, { firstName, lastName: 'Doe' })\n )\n const secretIds = await ownerApi.patientApi.decryptSecretIdsOf(created)\n return await ownerApi.patientApi.shareWithMany(created, { [parentId]: { shareSecretIds: secretIds } })\n}\n\n/** Inserts a legacy (v7-native, already shared with parentId) patient directly from its fixture. */\nasync function createV7PatientSharedWithParent(\n ownerApi: IcureApi,\n fixture: LegacyOwnerFixture,\n ownerId: string,\n parentId: string,\n firstName: string\n): Promise<Patient> {\n return new IccPatientApi(env.iCureUrl, {}, ownerApi.authApi.authenticationProvider, fetch).createPatient(\n legacyPatientBase(fixture, ownerId, parentId, firstName)\n )\n}\n\n/**\n * Creates a fresh hcp (random keypair) and makes it a child of parentId, to establish the existing\n * relationship that operations such as mergePatients require between data owners in order to\n * authorize the operation (an entirely unrelated hcp gets a 403).\n *\n * By default this does NOT give the child a locally-held copy of the parent's key\n * (disableParentKeysInitialisation skips the startup check that would otherwise require one): in\n * tests where we only care about the authorization relationship, we don't want the child to also\n * be able to reach anything shared with the parent through a locally-cached parent key, which\n * would muddy visibility assertions.\n * Pass holdParentKey: true for tests that specifically want to exercise genuine hierarchical\n * inheritance (a child that has actually verified/cached its parent's key, like a properly\n * provisioned device in the same care organisation - as opposed to the confidentiality checks\n * elsewhere in this suite, which intentionally avoid this).\n */\nasync function createChildOfParent(\n testSetupApi: IcureApi,\n parentId: string,\n parentKeys?: { privateKey: string; publicKey: string }\n): Promise<{ api: IcureApi; user: User; id: string }> {\n const info = await createNewHcpApi(env)\n await testSetupApi.healthcarePartyApi.modifyHealthcareParty({\n ...(await testSetupApi.healthcarePartyApi.getHealthcareParty(info.credentials.dataOwnerId)),\n parentId,\n })\n const storage = await testStorageWithKeys([\n {\n dataOwnerId: info.credentials.dataOwnerId,\n pairs: [{ keyPair: { privateKey: info.credentials.privateKey, publicKey: info.credentials.publicKey }, shaVersion: ShaVersion.Sha1 }],\n },\n ...(parentKeys ? [{ dataOwnerId: parentId, pairs: [{ keyPair: parentKeys, shaVersion: ShaVersion.Sha1 }] }] : []),\n ])\n const api = await IcureApi.initialise(\n env.iCureUrl,\n { username: info.credentials.user, password: info.credentials.password },\n new TestCryptoStrategies(),\n webcrypto as any,\n fetch,\n { storage: storage.storage, keyStorage: storage.keyStorage, entryKeysFactory: storage.keyFactory, disableParentKeysInitialisation: !parentKeys }\n )\n const user = await api.userApi.getCurrentUser()\n return { api, user, id: info.credentials.dataOwnerId }\n}\n\ndescribe('CSM-814', async function () {\n before(async function () {\n this.timeout(600000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n hierarchyApis = await createHcpHierarchyApis(env)\n })\n\n it('A user should be able to share a just created patient secret id', async function () {\n const { childApi, childUser, child2Api, child2User, grandCredentials } = hierarchyApis\n const pat = await childApi.patientApi.createPatientWithUser(\n childUser,\n await childApi.patientApi.newInstance(childUser, {\n firstName: 'John',\n lastName: 'Doe',\n })\n )\n const initialSecretIds = await childApi.patientApi.decryptSecretIdsOf(await childApi.patientApi.getPatientWithUser(childUser, pat.id))\n expect(initialSecretIds).to.have.length(1)\n expect(await child2Api.patientApi.decryptSecretIdsOf(await child2Api.patientApi.getPatientWithUser(child2User, pat.id))).to.have.members(\n initialSecretIds\n )\n const newSecretId = randomUUID()\n const allSecretIds = [...initialSecretIds, newSecretId]\n await childApi.patientApi.shareWithMany(pat, {\n [grandCredentials.dataOwnerId]: {\n shareSecretIds: allSecretIds,\n },\n })\n expect(await childApi.patientApi.decryptSecretIdsOf(await childApi.patientApi.getPatientWithUser(childUser, pat.id))).to.have.members(\n allSecretIds\n )\n expect(await child2Api.patientApi.decryptSecretIdsOf(await child2Api.patientApi.getPatientWithUser(child2User, pat.id))).to.have.members(\n allSecretIds\n )\n })\n\n it('A user should be able to share the secret id of a just created patient and add a new secret id to a legacy patient created by an old sdk version, in the same operation', async function () {\n const testSetupApi = await initMasterApi(env)\n\n // P, the shared parent of A and B, and the delegate the legacy patient is already shared with.\n const pId = randomUUID()\n const { api: pApi, user: pUser } = await createFixedKeyDataOwner(testSetupApi, pId, {\n firstName: 'Jane',\n privateKey: pPrivateKey,\n publicKey: pPublicKey,\n })\n\n const aId = randomUUID()\n const { api: aApi, user: aUser } = await createFixedKeyDataOwner(testSetupApi, aId, {\n firstName: 'John',\n privateKey: aFixture.privateKey,\n publicKey: aFixture.publicKey,\n parentId: pId,\n aesExchangeKeys: legacyAesExchangeKeys(aFixture, aId, pId),\n autoDelegations: [pId],\n extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],\n })\n const patient = await createV7PatientSharedWithParent(aApi, aFixture, aId, pId, 'John')\n\n // B, a sibling of A under the same parent P. B does not have any direct access to the patient,\n // but has access to P's key (e.g. a shared workstation), so it should be able to decrypt\n // anything shared with P, both before and after the new secret id is added.\n const bInfo = await createNewHcpApi(env)\n await testSetupApi.healthcarePartyApi.modifyHealthcareParty({\n ...(await testSetupApi.healthcarePartyApi.getHealthcareParty(bInfo.credentials.dataOwnerId)),\n parentId: pId,\n })\n const bStorage = await testStorageWithKeys([\n { dataOwnerId: pId, pairs: [{ keyPair: { privateKey: pPrivateKey, publicKey: pPublicKey }, shaVersion: ShaVersion.Sha1 }] },\n {\n dataOwnerId: bInfo.credentials.dataOwnerId,\n pairs: [{ keyPair: { privateKey: bInfo.credentials.privateKey, publicKey: bInfo.credentials.publicKey }, shaVersion: ShaVersion.Sha1 }],\n },\n ])\n const bApi = await IcureApi.initialise(\n env.iCureUrl,\n { username: bInfo.credentials.user, password: bInfo.credentials.password },\n new TestCryptoStrategies(),\n webcrypto as any,\n fetch,\n {\n storage: bStorage.storage,\n keyStorage: bStorage.keyStorage,\n entryKeysFactory: bStorage.keyFactory,\n }\n )\n const bUser = await bApi.userApi.getCurrentUser()\n\n // P's own login can't yet resolve the pure-legacy (v7-native) delegation directly - that legacy\n // format is only self-service-resolvable by its owner (A) or by a session that already holds\n // the delegate's private key locally (B, standing in for a shared workstation), same as\n // test/icc-x-api/crypto/legacy-metadata-migration-test.ts never checks a bare \"p\" login against\n // pure legacy data either. Once A performs a real (v8) share below, P's own login resolves fine.\n const initialSecretIds = await aApi.patientApi.decryptSecretIdsOf(await aApi.patientApi.getPatientWithUser(aUser, patient.id!))\n expect(initialSecretIds).to.have.length(1)\n expect(await bApi.patientApi.decryptSecretIdsOf(await bApi.patientApi.getPatientWithUser(bUser, patient.id!))).to.have.members(initialSecretIds)\n\n const newSecretId = randomUUID()\n const allSecretIds = [...initialSecretIds, newSecretId]\n await aApi.patientApi.shareWithMany(patient, {\n [pId]: { shareSecretIds: allSecretIds },\n })\n\n expect(await aApi.patientApi.decryptSecretIdsOf(await aApi.patientApi.getPatientWithUser(aUser, patient.id!))).to.have.members(allSecretIds)\n expect(await pApi.patientApi.decryptSecretIdsOf(await pApi.patientApi.getPatientWithUser(pUser, patient.id!))).to.have.members(allSecretIds)\n expect(await bApi.patientApi.decryptSecretIdsOf(await bApi.patientApi.getPatientWithUser(bUser, patient.id!))).to.have.members(allSecretIds)\n })\n\n describe('mergePatients', function () {\n type Version = 'v8' | 'v7'\n type MergedBy = 'A' | 'B'\n const versions: Version[] = ['v8', 'v7']\n const mergedBys: MergedBy[] = ['A', 'B']\n const variants: { fromVersion: Version; intoVersion: Version; mergedBy: MergedBy }[] = versions.flatMap((fromVersion) =>\n versions.flatMap((intoVersion) => mergedBys.map((mergedBy) => ({ fromVersion, intoVersion, mergedBy })))\n )\n\n /**\n * Sets up a shared parent P and two sibling hcps A and B (each with their own fixed keypair,\n * both holding P's key locally too, standing in for a shared workstation - so that regardless\n * of which of A/B performs the merge, and regardless of how much direct access the merge\n * propagates to each side, both can fall back on P's key to reach anything shared with P).\n */\n async function setupParticipants(): Promise<{\n testSetupApi: IcureApi\n pId: string\n aId: string\n bId: string\n aApi: IcureApi\n aUser: User\n bApi: IcureApi\n bUser: User\n }> {\n const testSetupApi = await initMasterApi(env)\n\n const pId = randomUUID()\n await createFixedKeyDataOwner(testSetupApi, pId, { firstName: 'Jane', privateKey: pPrivateKey, publicKey: pPublicKey })\n\n const aId = randomUUID()\n const { api: aApi, user: aUser } = await createFixedKeyDataOwner(testSetupApi, aId, {\n firstName: 'John',\n privateKey: aFixture.privateKey,\n publicKey: aFixture.publicKey,\n parentId: pId,\n aesExchangeKeys: legacyAesExchangeKeys(aFixture, aId, pId),\n autoDelegations: [pId],\n extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],\n })\n\n const bId = randomUUID()\n const { api: bApi, user: bUser } = await createFixedKeyDataOwner(testSetupApi, bId, {\n firstName: 'Jack',\n privateKey: bFixture.privateKey,\n publicKey: bFixture.publicKey,\n parentId: pId,\n aesExchangeKeys: legacyAesExchangeKeys(bFixture, bId, pId),\n autoDelegations: [pId],\n extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],\n })\n\n return { testSetupApi, pId, aId, bId, aApi, aUser, bApi, bUser }\n }\n\n for (const variant of variants) {\n it(`merges a ${variant.fromVersion} patient owned by A into a ${variant.intoVersion} patient owned by B, both shared with the same parent P, merge performed by ${variant.mergedBy}`, async function () {\n const { pId, aId, bId, aApi, aUser, bApi, bUser } = await setupParticipants()\n\n const pA =\n variant.fromVersion === 'v8'\n ? await createV8PatientSharedWithParent(aApi, aUser, pId, 'John')\n : await createV7PatientSharedWithParent(aApi, aFixture, aId, pId, 'John')\n const pB =\n variant.intoVersion === 'v8'\n ? await createV8PatientSharedWithParent(bApi, bUser, pId, 'Jack')\n : await createV7PatientSharedWithParent(bApi, bFixture, bId, pId, 'Jack')\n\n const aSecretId = (await aApi.patientApi.decryptSecretIdsOf(pA))[0]\n const bSecretId = (await bApi.patientApi.decryptSecretIdsOf(pB))[0]\n expect(aSecretId).to.not.be.undefined\n expect(bSecretId).to.not.be.undefined\n const allSecretIds = [aSecretId, bSecretId]\n\n // Re-fetch right before merging: A's autoDelegations (and B's, symmetrically) may still be\n // asynchronously finishing an auto-share in the background after creation, which would\n // otherwise leave us holding a stale rev and make the merge fail with a 409 conflict.\n const freshPA = await aApi.patientApi.getPatientWithUser(aUser, pA.id!)\n const freshPB = await bApi.patientApi.getPatientWithUser(bUser, pB.id!)\n\n const merger = variant.mergedBy === 'A' ? aApi : bApi\n const otherId = variant.mergedBy === 'A' ? bId : aId\n const mergedInto = await merger.patientApi.mergePatients(freshPA, freshPB)\n\n // Documented merge metadata: `from` is soft-deleted and points to `into`; `into` records the merge.\n const fromAfterMerge = await aApi.patientApi.getPatientWithUser(aUser, pA.id!)\n expect(fromAfterMerge.deletionDate).to.not.be.undefined\n expect(fromAfterMerge.mergeToPatientId).to.equal(pB.id)\n expect(mergedInto.mergedIds).to.include(pA.id)\n\n // Per mergePatients' own documentation, the merge alone does not share the merged content\n // with users that only had access to one of the two original entities: the merger (who per\n // the docs gets full access to everything as a result of the merge) has to explicitly share\n // with the other sibling afterwards for both to end up with full access to both secret ids.\n await merger.patientApi.shareWithMany(mergedInto, { [otherId]: { shareSecretIds: allSecretIds } })\n\n expect(await aApi.patientApi.decryptSecretIdsOf(await aApi.patientApi.getPatientWithUser(aUser, mergedInto.id!))).to.have.members(\n allSecretIds\n )\n expect(await bApi.patientApi.decryptSecretIdsOf(await bApi.patientApi.getPatientWithUser(bUser, mergedInto.id!))).to.have.members(\n allSecretIds\n )\n })\n }\n })\n\n /*\n * mergePatients only merges the two entities' existing security metadata (secret id/encryption\n * key delegations) server-side, without decrypting anything: whatever a data owner could access\n * on one of the two original patients, it can still access on the merged patient, and nothing\n * more. In particular:\n * - a secret id that was never shared with anyone but its owner (e.g. a confidential secret id)\n * stays known only to that owner after the merge\n * - a secret id that was shared with a third party (here, a common parent P of A and B) is still\n * known to that third party after the merge\n * - none of this depends on which of A, B, or a completely unrelated third hcp performs the merge,\n * since the merger's own identity only matters for re-encrypting the `into` patient's content\n * for itself, not for the secret id metadata merge itself.\n */\n describe('mergePatients preserves secret id visibility independently of the merger', function () {\n const mergers = ['A', 'B', 'C'] as const\n\n for (const merger of mergers) {\n it(`keeps every secret id visible to exactly the data owners it was shared with before the merge, regardless of who performs it (merged by ${merger})`, async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n // A, B and the merger C are all children of the same parent P: mergePatients (like most\n // write operations) is only authorized between data owners that have some existing\n // relationship, so an entirely unrelated hcp couldn't perform the merge at all - C stands\n // in for \"anyone else in the same care organisation\", not a random stranger.\n const aInfo = await createChildOfParent(testSetupApi, pId)\n const bInfo = await createChildOfParent(testSetupApi, pId)\n const cInfo = await createChildOfParent(testSetupApi, pId)\n\n // PatientA: s1 stays confidential (known only to A), s2 gets shared with the parent P.\n const createdPA = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const s1 = (await aInfo.api.patientApi.decryptSecretIdsOf(createdPA))[0]\n const s2 = randomUUID()\n const pA = await aInfo.api.patientApi.shareWithMany(createdPA, { [pId]: { shareSecretIds: [s2] } })\n\n // PatientB: s3 stays confidential (known only to B), s4 gets shared with the same parent P.\n const createdPB = await bInfo.api.patientApi.createPatientWithUser(\n bInfo.user,\n await bInfo.api.patientApi.newInstance(bInfo.user, { firstName: 'Jack', lastName: 'Doe' })\n )\n const s3 = (await bInfo.api.patientApi.decryptSecretIdsOf(createdPB))[0]\n const s4 = randomUUID()\n const pB = await bInfo.api.patientApi.shareWithMany(createdPB, { [pId]: { shareSecretIds: [s4] } })\n\n const mergerApi = merger === 'A' ? aInfo.api : merger === 'B' ? bInfo.api : cInfo.api\n const freshPA = await aInfo.api.patientApi.getPatientWithUser(aInfo.user, pA.id!)\n const freshPB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, pB.id!)\n const merged = await mergerApi.patientApi.mergePatients(freshPA, freshPB)\n\n expect(await aInfo.api.patientApi.decryptSecretIdsOf(await aInfo.api.patientApi.getPatientWithUser(aInfo.user, merged.id!))).to.have.members([\n s1,\n s2,\n ])\n expect(await bInfo.api.patientApi.decryptSecretIdsOf(await bInfo.api.patientApi.getPatientWithUser(bInfo.user, merged.id!))).to.have.members([\n s3,\n s4,\n ])\n expect(await pInfo.api.patientApi.decryptSecretIdsOf(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id!))).to.have.members([\n s2,\n s4,\n ])\n })\n }\n })\n\n /*\n * mergePatients forcefully disables merging the `from` patient's encryption key into the `into`\n * patient (the `into` patient keeps only its own, pre-existing encryption key): the method\n * expects callers to be working with decrypted patients, so there is no need to end up with two\n * distinct encryption keys on the merged patient the way kraken would by default.\n * One consequence is a corner case: if the `into` patient's encryption key was never shared with\n * a party that *did* have the `from` patient's encryption key, that party loses the ability to\n * decrypt the merged patient's content (though not its secret ids, which are unaffected and still\n * merge normally) - a followup shareWith/shareWithMany restores it. Sharing only the encryption\n * key (shareSecretIds: []) again with someone who already has it is a harmless no-op, even when\n * the caller isn't the entity's original creator.\n */\n describe('mergePatients does not merge encryption keys, and a follow-up shareWith restores lost access', function () {\n it('drops the encryption key of the from patient, and a shareWith with empty shareSecretIds afterwards fixes decryption for whoever needs it', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n // A and B are children of the same parent P, so that A is authorized to merge B's patient\n // into its own (see the note above about mergePatients requiring an existing relationship).\n // B additionally holds P's key locally (holdParentKey), like a properly provisioned device\n // in the same care organisation, so that anything shared with P is genuinely, automatically\n // reachable by B too - this is what the redundant-reshare check below relies on.\n const aInfo = await createChildOfParent(testSetupApi, pId)\n const bInfo = await createChildOfParent(testSetupApi, pId, { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey })\n\n // PatientA created by hcpA, but for some reason not shared with the parent at all.\n const pA = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe', note: 'note from A' })\n )\n\n // PatientB created by hcpB and properly shared with the parent (secret id + encryption key).\n const createdPB = await bInfo.api.patientApi.createPatientWithUser(\n bInfo.user,\n await bInfo.api.patientApi.newInstance(bInfo.user, { firstName: 'Jack', lastName: 'Doe', note: 'note from B' })\n )\n const bSecretId = (await bInfo.api.patientApi.decryptSecretIdsOf(createdPB))[0]\n const pB = await bInfo.api.patientApi.shareWithMany(createdPB, { [pId]: { shareSecretIds: [bSecretId] } })\n expect(await pInfo.api.patientApi.decryptSecretIdsOf(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, pB.id!))).to.have.members([\n bSecretId,\n ])\n\n // hcpA merges PatientB into PatientA: PatientB's secret id still gets merged in (unaffected),\n // but PatientA's own encryption key is the only one that survives on the merged patient - so\n // even though the parent could decrypt PatientB's content a moment ago, it now can't decrypt\n // the merged patient's content at all (note comes back undefined), despite still being able to\n // find the merged-in secret id.\n const freshPA = await aInfo.api.patientApi.getPatientWithUser(aInfo.user, pA.id!)\n const freshPB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, pB.id!)\n const merged = await aInfo.api.patientApi.mergePatients(freshPB, freshPA)\n\n expect(await pInfo.api.patientApi.decryptSecretIdsOf(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id!))).to.have.members([\n bSecretId,\n ])\n expect((await pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id!)).note).to.be.undefined\n\n // hcpA shares just the encryption key with the parent to fix this: shareSecretIds is left\n // empty (no new secret id to share) and shareEncryptionKey defaults to IF_AVAILABLE, which\n // applies here since A currently holds the only surviving encryption key. This is a real\n // change (the parent never had access to this specific entity before), so the rev changes.\n const resharedByA = await aInfo.api.patientApi.shareWith(pId, merged, [])\n expect(resharedByA.rev).to.not.equal(merged.rev)\n\n // Redundant shareWith of an already-shared encryption key, this time performed by B rather\n // than A (the entity's current, and only, encryption key holder): B is a child of the same\n // parent P and genuinely holds P's key locally (like a properly provisioned device in the\n // same care organisation), so B can decrypt the A->P delegation and see that P already has\n // this encryption key directly. This is a harmless no-op - there is nothing new to grant, so\n // the rev stays unchanged, even though B itself never granted this access.\n const reshareAgain = await bInfo.api.patientApi.shareWith(pId, resharedByA, [])\n expect(reshareAgain.rev).to.equal(resharedByA.rev)\n\n // shareWithMany to a mix of delegates that already have the key (the parent, a no-op) and\n // delegates that don't yet (a fresh, unrelated hcp, a real change) also works cleanly -\n // explicitly (and, for the parent, wastefully) re-granting access that in a real hierarchy\n // might already be inherited, but not harmfully so. Since D's part is a real change, the rev\n // still changes overall, and D can now decrypt the content.\n const dInfo = await createNewHcpApi(env)\n const sharedWithBoth = await aInfo.api.patientApi.shareWithMany(reshareAgain, {\n [pId]: { shareSecretIds: [] },\n [dInfo.credentials.dataOwnerId]: { shareSecretIds: [] },\n })\n expect(sharedWithBoth.rev).to.not.equal(reshareAgain.rev)\n expect((await dInfo.api.patientApi.getPatientWithUser(dInfo.user, sharedWithBoth.id!)).note).to.equal('note from A')\n })\n })\n})\n"]}
File without changes
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ describe('CSM-87', function () {
12
+ return __awaiter(this, void 0, void 0, function* () {
13
+ it('An hcp should be able to load his key with `loadKeyPairsAsJwkInBrowserLocalStorage` and then create shamir partitions for himself', function () {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ // This test does not apply to v7 or higher: it was a bug related to a specific method
16
+ this.skip();
17
+ });
18
+ });
19
+ });
20
+ });
21
+ //# sourceMappingURL=CSM-87.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSM-87.js","sourceRoot":"","sources":["../../../test/support/CSM-87.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,QAAQ,CAAC,QAAQ,EAAE;;QACjB,EAAE,CAAC,mIAAmI,EAAE;;gBACtI,sFAAsF;gBACtF,IAAI,CAAC,IAAI,EAAE,CAAA;YACb,CAAC;SAAA,CAAC,CAAA;IACJ,CAAC;CAAA,CAAC,CAAA","sourcesContent":["describe('CSM-87', async function () {\n it('An hcp should be able to load his key with `loadKeyPairsAsJwkInBrowserLocalStorage` and then create shamir partitions for himself', async function () {\n // This test does not apply to v7 or higher: it was a bug related to a specific method\n this.skip()\n })\n})\n"]}
@@ -0,0 +1 @@
1
+ import 'isomorphic-fetch';
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const test_utils_1 = require("../utils/test_utils");
13
+ const icc_x_api_1 = require("../../icc-x-api");
14
+ const crypto_1 = require("crypto");
15
+ const chai_1 = require("chai");
16
+ require("isomorphic-fetch");
17
+ const FilterChainMaintenanceTask_1 = require("../../icc-api/model/FilterChainMaintenanceTask");
18
+ const MaintenanceTaskAfterDateFilter_1 = require("../../icc-x-api/filters/MaintenanceTaskAfterDateFilter");
19
+ const Service_1 = require("../../icc-api/model/Service");
20
+ const types_1 = require("@icure/test-setup/types");
21
+ const TestCryptoStrategies_1 = require("../utils/TestCryptoStrategies");
22
+ const KeyPairUpdateRequest_1 = require("../../icc-x-api/maintenance/KeyPairUpdateRequest");
23
+ const chaiAsPromised = require("chai-as-promised");
24
+ const TestStorage_1 = require("../utils/TestStorage");
25
+ var initApi = test_utils_1.TestUtils.initApi;
26
+ (0, test_utils_1.setLocalStorage)(fetch);
27
+ (0, chai_1.use)(chaiAsPromised);
28
+ let env;
29
+ describe('CSM-93', function () {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ before(function () {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ this.timeout(600000);
34
+ const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
35
+ env = yield initializer.execute((0, types_1.getEnvVariables)());
36
+ });
37
+ });
38
+ it('A patient should be able retrieve existing data after give access back', function () {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ var _a;
41
+ const hcpApis = yield initApi(env, test_utils_1.hcp1Username);
42
+ const hcpUser = yield hcpApis.userApi.getCurrentUser();
43
+ const patApis = yield initApi(env, test_utils_1.patUsername);
44
+ const patUser = yield patApis.userApi.getCurrentUser();
45
+ const patientNote = 'Some secret note';
46
+ const p2 = yield hcpApis.patientApi.createPatientWithUser(hcpUser, yield hcpApis.patientApi.newInstance(hcpUser, {
47
+ firstName: 'John',
48
+ lastName: 'Doe',
49
+ note: patientNote,
50
+ }, { additionalDelegates: { [patUser.patientId]: 'WRITE' } }));
51
+ yield patApis.cryptoApi.forceReload();
52
+ const heNote = 'Another secret note';
53
+ const he = yield patApis.healthcareElementApi.createHealthElementWithUser(patUser, yield patApis.healthcareElementApi.newInstance(patUser, p2, { note: heNote }, { additionalDelegates: { [hcpUser.healthcarePartyId]: 'WRITE' } }));
54
+ const ctcData = 'Some data';
55
+ const ctcDescr = 'Some description';
56
+ const ctc = yield hcpApis.contactApi.createContactWithUser(hcpUser, yield hcpApis.contactApi.newInstance(hcpUser, p2, {
57
+ services: [new Service_1.Service({ label: 'svc', content: { fr: { stringValue: ctcData } } })],
58
+ descr: ctcDescr,
59
+ }, { additionalDelegates: { [patUser.patientId]: 'WRITE' } }));
60
+ function checkContactDecrypted(ctc) {
61
+ var _a, _b, _c, _d;
62
+ (0, chai_1.expect)((_d = (_c = (_b = (_a = ctc.services) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.fr) === null || _d === void 0 ? void 0 : _d.stringValue).to.equal(ctcData);
63
+ (0, chai_1.expect)(ctc.descr).to.equal(ctcDescr);
64
+ }
65
+ function checkContactEncrypted(ctc) {
66
+ var _a, _b;
67
+ (0, chai_1.expect)((_a = ctc.services) === null || _a === void 0 ? void 0 : _a[0]).to.not.be.undefined;
68
+ (0, chai_1.expect)(Object.keys((_b = ctc.services[0].content) !== null && _b !== void 0 ? _b : {})).to.be.empty;
69
+ (0, chai_1.expect)(ctc.descr).to.be.undefined;
70
+ }
71
+ (0, chai_1.expect)((yield hcpApis.patientApi.getPatientWithUser(hcpUser, p2.id)).note).to.equal(patientNote);
72
+ (0, chai_1.expect)((yield patApis.patientApi.getPatientWithUser(patUser, p2.id)).note).to.equal(patientNote);
73
+ (0, chai_1.expect)((yield hcpApis.healthcareElementApi.getHealthElementWithUser(hcpUser, he.id)).note).to.equal(heNote);
74
+ (0, chai_1.expect)((yield patApis.healthcareElementApi.getHealthElementWithUser(patUser, he.id)).note).to.equal(heNote);
75
+ checkContactDecrypted(yield hcpApis.contactApi.getContactWithUser(hcpUser, ctc.id));
76
+ checkContactDecrypted(yield patApis.contactApi.getContactWithUser(patUser, ctc.id));
77
+ const startTimestamp = new Date().getTime();
78
+ const newPair = yield patApis.cryptoApi.primitives.RSA.generateKeyPair(icc_x_api_1.ShaVersion.Sha256);
79
+ const patApisLost = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: env.dataOwnerDetails[test_utils_1.patUsername].user, password: env.dataOwnerDetails[test_utils_1.patUsername].password }, new TestCryptoStrategies_1.TestCryptoStrategies(newPair), crypto_1.webcrypto, fetch, {
80
+ createMaintenanceTasksOnNewKey: true,
81
+ storage: new TestStorage_1.TestStorage(),
82
+ keyStorage: new TestStorage_1.TestKeyStorage(),
83
+ });
84
+ if (!(0, test_utils_1.isLiteTest)()) {
85
+ yield (0, chai_1.expect)(patApisLost.patientApi.getPatientWithUser(patUser, p2.id)).to.be.rejected;
86
+ yield (0, chai_1.expect)(patApisLost.healthcareElementApi.getHealthElementWithUser(patUser, he.id)).to.be.rejected;
87
+ yield (0, chai_1.expect)(patApisLost.contactApi.getContactWithUser(patUser, ctc.id)).to.be.rejected;
88
+ }
89
+ // The patient had to create a new aes exchange key to share the maintenance task with the hcp:
90
+ // If you don't clear the cache of the hcp he will not be able to decrypt the maintenance task
91
+ yield hcpApis.cryptoApi.forceReload();
92
+ const foundTasks = (_a = (yield hcpApis.maintenanceTaskApi.filterMaintenanceTasksByWithUser(hcpUser, undefined, undefined, new FilterChainMaintenanceTask_1.FilterChainMaintenanceTask({
93
+ filter: new MaintenanceTaskAfterDateFilter_1.MaintenanceTaskAfterDateFilter({
94
+ healthcarePartyId: hcpUser.healthcarePartyId,
95
+ date: startTimestamp - 1,
96
+ }),
97
+ }))).rows) !== null && _a !== void 0 ? _a : [];
98
+ (0, chai_1.expect)(foundTasks.length).to.equal(1);
99
+ const task = KeyPairUpdateRequest_1.KeyPairUpdateRequest.fromMaintenanceTask(foundTasks[0]);
100
+ (0, chai_1.expect)(task.concernedDataOwnerId).to.equal(patUser.patientId);
101
+ (0, chai_1.expect)(task.newPublicKey).to.equal((0, icc_x_api_1.ua2hex)(yield hcpApis.cryptoApi.primitives.RSA.exportKey(newPair.publicKey, 'spki')));
102
+ yield hcpApis.icureMaintenanceTaskApi.applyKeyPairUpdate(task);
103
+ // Clear the caches to ensure the user uses the latest version of the exchange keys with the 'give access back' data
104
+ yield patApisLost.cryptoApi.forceReload();
105
+ (0, chai_1.expect)((yield patApisLost.patientApi.getPatientWithUser(patUser, p2.id)).note).to.equal(patientNote);
106
+ (0, chai_1.expect)((yield patApisLost.healthcareElementApi.getHealthElementWithUser(patUser, he.id)).note).to.equal(heNote);
107
+ checkContactDecrypted(yield patApisLost.contactApi.getContactWithUser(patUser, ctc.id));
108
+ });
109
+ });
110
+ });
111
+ });
112
+ //# sourceMappingURL=CSM-93.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSM-93.js","sourceRoot":"","sources":["../../../test/support/CSM-93.ts"],"names":[],"mappings":"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","sourcesContent":["import { getEnvironmentInitializer, hcp1Username, isLiteTest, patUsername, setLocalStorage, TestUtils } from '../utils/test_utils'\nimport { IcureApi, ShaVersion, ua2hex } from '../../icc-x-api'\nimport { webcrypto } from 'crypto'\nimport { expect, use as chaiUse } from 'chai'\nimport 'isomorphic-fetch'\nimport { FilterChainMaintenanceTask } from '../../icc-api/model/FilterChainMaintenanceTask'\nimport { MaintenanceTask } from '../../icc-api/model/MaintenanceTask'\nimport { MaintenanceTaskAfterDateFilter } from '../../icc-x-api/filters/MaintenanceTaskAfterDateFilter'\nimport { Service } from '../../icc-api/model/Service'\nimport { Contact } from '../../icc-api/model/Contact'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { TestCryptoStrategies } from '../utils/TestCryptoStrategies'\nimport { KeyPairUpdateRequest } from '../../icc-x-api/maintenance/KeyPairUpdateRequest'\nimport * as chaiAsPromised from 'chai-as-promised'\nimport { TestKeyStorage, TestStorage } from '../utils/TestStorage'\nimport initApi = TestUtils.initApi\n\nsetLocalStorage(fetch)\nchaiUse(chaiAsPromised)\n\nlet env: TestVars\n\ndescribe('CSM-93', async function () {\n before(async function () {\n this.timeout(600000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n })\n\n it('A patient should be able retrieve existing data after give access back', async function () {\n const hcpApis = await initApi(env, hcp1Username)\n const hcpUser = await hcpApis.userApi.getCurrentUser()\n const patApis = await initApi(env, patUsername)\n const patUser = await patApis.userApi.getCurrentUser()\n const patientNote = 'Some secret note'\n const p2 = await hcpApis.patientApi.createPatientWithUser(\n hcpUser,\n await hcpApis.patientApi.newInstance(\n hcpUser,\n {\n firstName: 'John',\n lastName: 'Doe',\n note: patientNote,\n },\n { additionalDelegates: { [patUser.patientId!]: 'WRITE' } }\n )\n )\n await patApis.cryptoApi.forceReload()\n const heNote = 'Another secret note'\n const he = await patApis.healthcareElementApi.createHealthElementWithUser(\n patUser,\n await patApis.healthcareElementApi.newInstance(\n patUser,\n p2,\n { note: heNote },\n { additionalDelegates: { [hcpUser.healthcarePartyId!]: 'WRITE' } }\n )\n )\n const ctcData = 'Some data'\n const ctcDescr = 'Some description'\n const ctc = await hcpApis.contactApi.createContactWithUser(\n hcpUser,\n await hcpApis.contactApi.newInstance(\n hcpUser,\n p2,\n {\n services: [new Service({ label: 'svc', content: { fr: { stringValue: ctcData } } })],\n descr: ctcDescr,\n },\n { additionalDelegates: { [patUser.patientId!]: 'WRITE' } }\n )\n )\n function checkContactDecrypted(ctc: Contact) {\n expect(ctc.services?.[0]?.content?.fr?.stringValue).to.equal(ctcData)\n expect(ctc.descr).to.equal(ctcDescr)\n }\n function checkContactEncrypted(ctc: Contact) {\n expect(ctc.services?.[0]).to.not.be.undefined\n expect(Object.keys(ctc.services![0].content ?? {})).to.be.empty\n expect(ctc.descr).to.be.undefined\n }\n expect((await hcpApis.patientApi.getPatientWithUser(hcpUser, p2.id!)).note).to.equal(patientNote)\n expect((await patApis.patientApi.getPatientWithUser(patUser, p2.id!)).note).to.equal(patientNote)\n expect((await hcpApis.healthcareElementApi.getHealthElementWithUser(hcpUser, he.id!)).note).to.equal(heNote)\n expect((await patApis.healthcareElementApi.getHealthElementWithUser(patUser, he.id!)).note).to.equal(heNote)\n checkContactDecrypted(await hcpApis.contactApi.getContactWithUser(hcpUser, ctc!.id!))\n checkContactDecrypted(await patApis.contactApi.getContactWithUser(patUser, ctc!.id!))\n const startTimestamp = new Date().getTime()\n const newPair = await patApis.cryptoApi.primitives.RSA.generateKeyPair(ShaVersion.Sha256)\n const patApisLost = await IcureApi.initialise(\n env.iCureUrl,\n { username: env.dataOwnerDetails[patUsername].user, password: env.dataOwnerDetails[patUsername].password },\n new TestCryptoStrategies(newPair),\n webcrypto as any,\n fetch,\n {\n createMaintenanceTasksOnNewKey: true,\n storage: new TestStorage(),\n keyStorage: new TestKeyStorage(),\n }\n )\n if (!isLiteTest()) {\n await expect(patApisLost.patientApi.getPatientWithUser(patUser, p2.id!)).to.be.rejected\n await expect(patApisLost.healthcareElementApi.getHealthElementWithUser(patUser, he.id!)).to.be.rejected\n await expect(patApisLost.contactApi.getContactWithUser(patUser, ctc!.id!)).to.be.rejected\n }\n // The patient had to create a new aes exchange key to share the maintenance task with the hcp:\n // If you don't clear the cache of the hcp he will not be able to decrypt the maintenance task\n await hcpApis.cryptoApi.forceReload()\n const foundTasks =\n (\n await hcpApis.maintenanceTaskApi.filterMaintenanceTasksByWithUser(\n hcpUser,\n undefined,\n undefined,\n new FilterChainMaintenanceTask({\n filter: new MaintenanceTaskAfterDateFilter({\n healthcarePartyId: hcpUser.healthcarePartyId!,\n date: startTimestamp - 1,\n }),\n })\n )\n ).rows ?? []\n expect(foundTasks.length).to.equal(1)\n const task = KeyPairUpdateRequest.fromMaintenanceTask(foundTasks[0] as MaintenanceTask)\n expect(task.concernedDataOwnerId).to.equal(patUser.patientId)\n expect(task.newPublicKey).to.equal(ua2hex(await hcpApis.cryptoApi.primitives.RSA.exportKey(newPair.publicKey, 'spki')))\n await hcpApis.icureMaintenanceTaskApi.applyKeyPairUpdate(task)\n // Clear the caches to ensure the user uses the latest version of the exchange keys with the 'give access back' data\n await patApisLost.cryptoApi.forceReload()\n expect((await patApisLost.patientApi.getPatientWithUser(patUser, p2.id!)).note).to.equal(patientNote)\n expect((await patApisLost.healthcareElementApi.getHealthElementWithUser(patUser, he.id!)).note).to.equal(heNote)\n checkContactDecrypted(await patApisLost.contactApi.getContactWithUser(patUser, ctc!.id!))\n })\n})\n"]}
@@ -0,0 +1,32 @@
1
+ import { DataOwner, DataOwnerOrStub, IccDataOwnerXApi } from '../../icc-x-api/icc-data-owner-x-api';
2
+ import { KeyPair } from '../../icc-x-api/crypto/RSA';
3
+ import { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum';
4
+ import { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType';
5
+ import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
6
+ import { User } from '../../icc-api/model/User';
7
+ export declare class FakeDataOwnerApi extends IccDataOwnerXApi {
8
+ private readonly selfId;
9
+ private readonly data;
10
+ private readonly primitives;
11
+ constructor(self: DataOwner & {
12
+ type: DataOwnerTypeEnum;
13
+ }, others?: (DataOwner & {
14
+ type: DataOwnerTypeEnum;
15
+ })[]);
16
+ getCurrentDataOwnerId(): Promise<string>;
17
+ getCurrentDataOwnerHierarchyIds(): Promise<string[]>;
18
+ getCurrentDataOwnerHierarchyIdsFrom(parentId: string): Promise<string[]>;
19
+ getCurrentDataOwner(): Promise<DataOwnerWithType>;
20
+ getCurrentDataOwnerHierarchy(): Promise<DataOwnerWithType[]>;
21
+ getCurrentDataOwnerType(): Promise<DataOwnerTypeEnum>;
22
+ getHexPublicKeysWithSha1Of(dataOwner: DataOwnerOrStub): Set<string>;
23
+ getHexPublicKeysWithSha256Of(dataOwner: DataOwnerOrStub): Set<string>;
24
+ getCurrentDataOwnerStub(): Promise<CryptoActorStubWithType>;
25
+ getDataOwnerIdOf(user: User): string;
26
+ getDataOwner(ownerId: string): Promise<DataOwnerWithType>;
27
+ clearCurrentDataOwnerIdsCache(): void;
28
+ modifyCryptoActorStub(stub: CryptoActorStubWithType): Promise<CryptoActorStubWithType>;
29
+ getCryptoActorStub(ownerId: string): Promise<CryptoActorStubWithType>;
30
+ addPublicKeyForOwner(dataOwnerId: string, keyPair: KeyPair<CryptoKey>): Promise<void>;
31
+ private mapObject;
32
+ }
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FakeDataOwnerApi = void 0;
13
+ const icc_data_owner_x_api_1 = require("../../icc-x-api/icc-data-owner-x-api");
14
+ const FakeGenericApi_1 = require("./FakeGenericApi");
15
+ const CryptoPrimitives_1 = require("../../icc-x-api/crypto/CryptoPrimitives");
16
+ const crypto_1 = require("crypto");
17
+ const icc_x_api_1 = require("../../icc-x-api");
18
+ const DataOwnerTypeEnum_1 = require("../../icc-api/model/DataOwnerTypeEnum");
19
+ const CryptoActorStub_1 = require("../../icc-api/model/CryptoActorStub");
20
+ class FakeDataOwnerApi extends icc_data_owner_x_api_1.IccDataOwnerXApi {
21
+ constructor(self, others = []) {
22
+ super('fake', {}, null, null);
23
+ this.data = new FakeGenericApi_1.FakeGenericApi();
24
+ this.primitives = new CryptoPrimitives_1.WebCryptoPrimitives(crypto_1.webcrypto);
25
+ this.selfId = self.id;
26
+ this.data.createObject(self);
27
+ others.forEach((x) => this.data.createObject(x));
28
+ }
29
+ getCurrentDataOwnerId() {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ return this.selfId;
32
+ });
33
+ }
34
+ getCurrentDataOwnerHierarchyIds() {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ let res = [this.selfId];
37
+ let latestCheck = this.data.getById(this.selfId);
38
+ while (latestCheck && latestCheck.parentId) {
39
+ const currId = latestCheck.parentId;
40
+ latestCheck = this.data.getById(currId);
41
+ res = [currId, ...res];
42
+ }
43
+ return res;
44
+ });
45
+ }
46
+ getCurrentDataOwnerHierarchyIdsFrom(parentId) {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const res = [];
49
+ for (const dataOwnerId of yield this.getCurrentDataOwnerHierarchyIds()) {
50
+ res.push(dataOwnerId);
51
+ if (dataOwnerId === parentId)
52
+ return res;
53
+ }
54
+ throw new Error(`${parentId} is not part of the data owner hierarchy for the current user`);
55
+ });
56
+ }
57
+ getCurrentDataOwner() {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ return this.mapObject(this.data.getById(this.selfId));
60
+ });
61
+ }
62
+ getCurrentDataOwnerHierarchy() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ return (yield this.getCurrentDataOwnerHierarchyIds()).map((id) => this.mapObject(this.data.getById(id)));
65
+ });
66
+ }
67
+ getCurrentDataOwnerType() {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ return this.data.getById(this.selfId).type;
70
+ });
71
+ }
72
+ getHexPublicKeysWithSha1Of(dataOwner) {
73
+ return super.getHexPublicKeysWithSha1Of(dataOwner);
74
+ }
75
+ getHexPublicKeysWithSha256Of(dataOwner) {
76
+ return super.getHexPublicKeysWithSha256Of(dataOwner);
77
+ }
78
+ getCurrentDataOwnerStub() {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ return CryptoActorStub_1.CryptoActorStubWithType.fromDataOwner(yield this.getCurrentDataOwner());
81
+ });
82
+ }
83
+ getDataOwnerIdOf(user) {
84
+ return super.getDataOwnerIdOf(user);
85
+ }
86
+ getDataOwner(ownerId) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ return this.mapObject(this.data.getById(ownerId));
89
+ });
90
+ }
91
+ clearCurrentDataOwnerIdsCache() {
92
+ super.clearCurrentDataOwnerIdsCache();
93
+ }
94
+ modifyCryptoActorStub(stub) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const existing = this.data.getById(stub.stub.id);
97
+ if (!existing)
98
+ throw new Error('Data owner not found.');
99
+ if (existing.type !== stub.type)
100
+ throw new Error('Unexpected type for data owner.');
101
+ return CryptoActorStub_1.CryptoActorStubWithType.fromDataOwner(this.mapObject(this.data.modifyObject(Object.assign(Object.assign({}, existing), stub.stub))));
102
+ });
103
+ }
104
+ getCryptoActorStub(ownerId) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ return CryptoActorStub_1.CryptoActorStubWithType.fromDataOwner(yield this.getDataOwner(ownerId));
107
+ });
108
+ }
109
+ addPublicKeyForOwner(dataOwnerId, keyPair) {
110
+ return __awaiter(this, void 0, void 0, function* () {
111
+ const retrieved = yield this.getCryptoActorStub(dataOwnerId);
112
+ const publicHex = (0, icc_x_api_1.ua2hex)(yield this.primitives.RSA.exportKey(keyPair.publicKey, 'spki'));
113
+ yield this.modifyCryptoActorStub({
114
+ type: retrieved.type,
115
+ stub: Object.assign(Object.assign({}, retrieved.stub), { publicKeysForOaepWithSha256: [...(retrieved.stub.publicKeysForOaepWithSha256 || []), publicHex] }),
116
+ });
117
+ });
118
+ }
119
+ mapObject(x) {
120
+ const type = x.type;
121
+ delete x.type;
122
+ if (type === DataOwnerTypeEnum_1.DataOwnerTypeEnum.Patient) {
123
+ return { type, dataOwner: x };
124
+ }
125
+ else if (type === DataOwnerTypeEnum_1.DataOwnerTypeEnum.Device) {
126
+ return { type, dataOwner: x };
127
+ }
128
+ else if (type === DataOwnerTypeEnum_1.DataOwnerTypeEnum.Hcp) {
129
+ return { type, dataOwner: x };
130
+ }
131
+ else
132
+ throw new Error('Unexpected type for data owner.');
133
+ }
134
+ }
135
+ exports.FakeDataOwnerApi = FakeDataOwnerApi;
136
+ //# sourceMappingURL=FakeDataOwnerApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FakeDataOwnerApi.js","sourceRoot":"","sources":["../../../test/utils/FakeDataOwnerApi.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwner, DataOwnerOrStub, IccDataOwnerXApi } from '../../icc-x-api/icc-data-owner-x-api'\nimport { FakeGenericApi } from './FakeGenericApi'\nimport { Patient } from '../../icc-api/model/Patient'\nimport { Device } from '../../icc-api/model/Device'\nimport { HealthcareParty } from '../../icc-api/model/HealthcareParty'\nimport { KeyPair } from '../../icc-x-api/crypto/RSA'\nimport { CryptoPrimitives, WebCryptoPrimitives } from '../../icc-x-api/crypto/CryptoPrimitives'\nimport { webcrypto } from 'crypto'\nimport { ua2hex } from '../../icc-x-api'\nimport { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum'\nimport { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { User } from '../../icc-api/model/User'\n\nexport class FakeDataOwnerApi extends IccDataOwnerXApi {\n private readonly selfId: string\n private readonly data = new FakeGenericApi<DataOwner & { type: DataOwnerTypeEnum }>()\n private readonly primitives = new WebCryptoPrimitives(webcrypto as any)\n\n constructor(self: DataOwner & { type: DataOwnerTypeEnum }, others: (DataOwner & { type: DataOwnerTypeEnum })[] = []) {\n super('fake', {}, null as any, null as any)\n this.selfId = self.id!\n this.data.createObject(self)\n others.forEach((x) => this.data.createObject(x))\n }\n\n async getCurrentDataOwnerId(): Promise<string> {\n return this.selfId\n }\n\n async getCurrentDataOwnerHierarchyIds(): Promise<string[]> {\n let res = [this.selfId]\n let latestCheck = this.data.getById(this.selfId)\n while (latestCheck && (latestCheck as any).parentId) {\n const currId: string = (latestCheck as any).parentId\n latestCheck = this.data.getById(currId)!\n res = [currId, ...res]\n }\n return res\n }\n\n async getCurrentDataOwnerHierarchyIdsFrom(parentId: string): Promise<string[]> {\n const res = []\n for (const dataOwnerId of await this.getCurrentDataOwnerHierarchyIds()) {\n res.push(dataOwnerId)\n if (dataOwnerId === parentId) return res\n }\n throw new Error(`${parentId} is not part of the data owner hierarchy for the current user`)\n }\n\n async getCurrentDataOwner(): Promise<DataOwnerWithType> {\n return this.mapObject(this.data.getById(this.selfId)!)\n }\n\n async getCurrentDataOwnerHierarchy(): Promise<DataOwnerWithType[]> {\n return (await this.getCurrentDataOwnerHierarchyIds()).map((id) => this.mapObject(this.data.getById(id)!))\n }\n\n async getCurrentDataOwnerType(): Promise<DataOwnerTypeEnum> {\n return this.data.getById(this.selfId)!.type\n }\n\n getHexPublicKeysWithSha1Of(dataOwner: DataOwnerOrStub): Set<string> {\n return super.getHexPublicKeysWithSha1Of(dataOwner)\n }\n\n getHexPublicKeysWithSha256Of(dataOwner: DataOwnerOrStub): Set<string> {\n return super.getHexPublicKeysWithSha256Of(dataOwner)\n }\n\n async getCurrentDataOwnerStub(): Promise<CryptoActorStubWithType> {\n return CryptoActorStubWithType.fromDataOwner(await this.getCurrentDataOwner())\n }\n\n getDataOwnerIdOf(user: User): string {\n return super.getDataOwnerIdOf(user)\n }\n\n async getDataOwner(ownerId: string): Promise<DataOwnerWithType> {\n return this.mapObject(this.data.getById(ownerId)!)\n }\n\n clearCurrentDataOwnerIdsCache() {\n super.clearCurrentDataOwnerIdsCache()\n }\n\n async modifyCryptoActorStub(stub: CryptoActorStubWithType): Promise<CryptoActorStubWithType> {\n const existing = this.data.getById(stub.stub.id!)\n if (!existing) throw new Error('Data owner not found.')\n if (existing.type !== stub.type) throw new Error('Unexpected type for data owner.')\n return CryptoActorStubWithType.fromDataOwner(this.mapObject(this.data.modifyObject({ ...existing, ...stub.stub })))\n }\n\n async getCryptoActorStub(ownerId: string): Promise<CryptoActorStubWithType> {\n return CryptoActorStubWithType.fromDataOwner(await this.getDataOwner(ownerId))\n }\n\n async addPublicKeyForOwner(dataOwnerId: string, keyPair: KeyPair<CryptoKey>) {\n const retrieved = await this.getCryptoActorStub(dataOwnerId)\n const publicHex = ua2hex(await this.primitives.RSA.exportKey(keyPair.publicKey, 'spki'))\n await this.modifyCryptoActorStub({\n type: retrieved.type,\n stub: {\n ...retrieved.stub,\n publicKeysForOaepWithSha256: [...(retrieved.stub.publicKeysForOaepWithSha256 || []), publicHex],\n },\n })\n }\n\n private mapObject(x: DataOwner & { type: DataOwnerTypeEnum }): DataOwnerWithType {\n const type = x.type\n delete (x as any).type\n if (type === DataOwnerTypeEnum.Patient) {\n return { type, dataOwner: x as Patient }\n } else if (type === DataOwnerTypeEnum.Device) {\n return { type, dataOwner: x as Device }\n } else if (type === DataOwnerTypeEnum.Hcp) {\n return { type, dataOwner: x as HealthcareParty }\n } else throw new Error('Unexpected type for data owner.')\n }\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { UserEncryptionKeysManager } from '../../icc-x-api/crypto/UserEncryptionKeysManager';
2
+ import { DataOwner } from '../../icc-x-api/icc-data-owner-x-api';
3
+ import { KeyPair } from '../../icc-x-api/crypto/RSA';
4
+ import { CryptoPrimitives } from '../../icc-x-api/crypto/CryptoPrimitives';
5
+ export declare class FakeEncryptionKeysManager extends UserEncryptionKeysManager {
6
+ private readonly keys;
7
+ constructor(keys: {
8
+ [fingerprint: string]: {
9
+ pair: KeyPair<CryptoKey>;
10
+ verified: boolean;
11
+ };
12
+ });
13
+ static create(primitives: CryptoPrimitives, verifiedKeys: KeyPair<CryptoKey>[], unverifiedKeys?: KeyPair<CryptoKey>[]): Promise<FakeEncryptionKeysManager>;
14
+ getCurrentUserAvailablePublicKeysHex(verifiedOnly: boolean): Promise<string[]>;
15
+ getCurrentUserHierarchyAvailablePublicKeysHex(): Promise<string[]>;
16
+ getKeyPairForFingerprint(fingerprint: string): {
17
+ pair: KeyPair<CryptoKey>;
18
+ verified: boolean;
19
+ } | undefined;
20
+ initialiseKeys(): Promise<{
21
+ newKeyPair: KeyPair<CryptoKey>;
22
+ newKeyFingerprint: string;
23
+ } | undefined>;
24
+ reloadKeys(): Promise<void>;
25
+ getSelfVerifiedKeys(): {
26
+ fingerprint: string;
27
+ pair: KeyPair<CryptoKey>;
28
+ }[];
29
+ getVerifiedPublicKeysFor(dataOwner: DataOwner): Promise<string[]>;
30
+ getDecryptionKeys(): {
31
+ [p: string]: KeyPair<CryptoKey>;
32
+ };
33
+ deleteKey(fp: string): void;
34
+ addOrUpdateKey(primitives: CryptoPrimitives, pair: KeyPair<CryptoKey>, verified: boolean): Promise<void>;
35
+ unverifyExistingKeysAndCreateNewVerified(primitives: CryptoPrimitives): Promise<void>;
36
+ }