@protontech/drive-sdk 0.0.10

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 (594) hide show
  1. package/README.md +17 -0
  2. package/dist/cache/index.d.ts +2 -0
  3. package/dist/cache/index.js +6 -0
  4. package/dist/cache/index.js.map +1 -0
  5. package/dist/cache/interface.d.ts +105 -0
  6. package/dist/cache/interface.js +3 -0
  7. package/dist/cache/interface.js.map +1 -0
  8. package/dist/cache/memoryCache.d.ts +18 -0
  9. package/dist/cache/memoryCache.js +78 -0
  10. package/dist/cache/memoryCache.js.map +1 -0
  11. package/dist/cache/memoryCache.test.d.ts +1 -0
  12. package/dist/cache/memoryCache.test.js +121 -0
  13. package/dist/cache/memoryCache.test.js.map +1 -0
  14. package/dist/config.d.ts +2 -0
  15. package/dist/config.js +11 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/crypto/driveCrypto.d.ts +209 -0
  18. package/dist/crypto/driveCrypto.js +364 -0
  19. package/dist/crypto/driveCrypto.js.map +1 -0
  20. package/dist/crypto/driveCrypto.test.d.ts +1 -0
  21. package/dist/crypto/driveCrypto.test.js +42 -0
  22. package/dist/crypto/driveCrypto.test.js.map +1 -0
  23. package/dist/crypto/hmac.d.ts +22 -0
  24. package/dist/crypto/hmac.js +44 -0
  25. package/dist/crypto/hmac.js.map +1 -0
  26. package/dist/crypto/index.d.ts +6 -0
  27. package/dist/crypto/index.js +13 -0
  28. package/dist/crypto/index.js.map +1 -0
  29. package/dist/crypto/interface.d.ts +125 -0
  30. package/dist/crypto/interface.js +10 -0
  31. package/dist/crypto/interface.js.map +1 -0
  32. package/dist/crypto/openPGPCrypto.d.ts +145 -0
  33. package/dist/crypto/openPGPCrypto.js +250 -0
  34. package/dist/crypto/openPGPCrypto.js.map +1 -0
  35. package/dist/crypto/utils.d.ts +2 -0
  36. package/dist/crypto/utils.js +35 -0
  37. package/dist/crypto/utils.js.map +1 -0
  38. package/dist/errors.d.ts +138 -0
  39. package/dist/errors.js +163 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/index.d.ts +24 -0
  42. package/dist/index.js +48 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/interface/account.d.ts +36 -0
  45. package/dist/interface/account.js +3 -0
  46. package/dist/interface/account.js.map +1 -0
  47. package/dist/interface/author.d.ts +26 -0
  48. package/dist/interface/author.js +3 -0
  49. package/dist/interface/author.js.map +1 -0
  50. package/dist/interface/devices.d.ts +18 -0
  51. package/dist/interface/devices.js +10 -0
  52. package/dist/interface/devices.js.map +1 -0
  53. package/dist/interface/download.d.ts +29 -0
  54. package/dist/interface/download.js +3 -0
  55. package/dist/interface/download.js.map +1 -0
  56. package/dist/interface/events.d.ts +26 -0
  57. package/dist/interface/events.js +11 -0
  58. package/dist/interface/events.js.map +1 -0
  59. package/dist/interface/httpClient.d.ts +38 -0
  60. package/dist/interface/httpClient.js +3 -0
  61. package/dist/interface/httpClient.js.map +1 -0
  62. package/dist/interface/index.d.ts +43 -0
  63. package/dist/interface/index.js +22 -0
  64. package/dist/interface/index.js.map +1 -0
  65. package/dist/interface/nodes.d.ts +161 -0
  66. package/dist/interface/nodes.js +21 -0
  67. package/dist/interface/nodes.js.map +1 -0
  68. package/dist/interface/result.d.ts +9 -0
  69. package/dist/interface/result.js +11 -0
  70. package/dist/interface/result.js.map +1 -0
  71. package/dist/interface/sharing.d.ts +73 -0
  72. package/dist/interface/sharing.js +9 -0
  73. package/dist/interface/sharing.js.map +1 -0
  74. package/dist/interface/telemetry.d.ts +61 -0
  75. package/dist/interface/telemetry.js +18 -0
  76. package/dist/interface/telemetry.js.map +1 -0
  77. package/dist/interface/thumbnail.d.ts +17 -0
  78. package/dist/interface/thumbnail.js +9 -0
  79. package/dist/interface/thumbnail.js.map +1 -0
  80. package/dist/interface/upload.d.ts +16 -0
  81. package/dist/interface/upload.js +3 -0
  82. package/dist/interface/upload.js.map +1 -0
  83. package/dist/internal/apiService/apiService.d.ts +51 -0
  84. package/dist/internal/apiService/apiService.js +305 -0
  85. package/dist/internal/apiService/apiService.js.map +1 -0
  86. package/dist/internal/apiService/apiService.test.d.ts +1 -0
  87. package/dist/internal/apiService/apiService.test.js +237 -0
  88. package/dist/internal/apiService/apiService.test.js.map +1 -0
  89. package/dist/internal/apiService/coreTypes.d.ts +24438 -0
  90. package/dist/internal/apiService/coreTypes.js +7 -0
  91. package/dist/internal/apiService/coreTypes.js.map +1 -0
  92. package/dist/internal/apiService/driveTypes.d.ts +11840 -0
  93. package/dist/internal/apiService/driveTypes.js +7 -0
  94. package/dist/internal/apiService/driveTypes.js.map +1 -0
  95. package/dist/internal/apiService/errorCodes.d.ts +30 -0
  96. package/dist/internal/apiService/errorCodes.js +11 -0
  97. package/dist/internal/apiService/errorCodes.js.map +1 -0
  98. package/dist/internal/apiService/errors.d.ts +19 -0
  99. package/dist/internal/apiService/errors.js +76 -0
  100. package/dist/internal/apiService/errors.js.map +1 -0
  101. package/dist/internal/apiService/errors.test.d.ts +1 -0
  102. package/dist/internal/apiService/errors.test.js +69 -0
  103. package/dist/internal/apiService/errors.test.js.map +1 -0
  104. package/dist/internal/apiService/index.d.ts +7 -0
  105. package/dist/internal/apiService/index.js +30 -0
  106. package/dist/internal/apiService/index.js.map +1 -0
  107. package/dist/internal/apiService/observerStream.d.ts +3 -0
  108. package/dist/internal/apiService/observerStream.js +15 -0
  109. package/dist/internal/apiService/observerStream.js.map +1 -0
  110. package/dist/internal/apiService/transformers.d.ts +4 -0
  111. package/dist/internal/apiService/transformers.js +48 -0
  112. package/dist/internal/apiService/transformers.js.map +1 -0
  113. package/dist/internal/batchLoading.d.ts +34 -0
  114. package/dist/internal/batchLoading.js +68 -0
  115. package/dist/internal/batchLoading.js.map +1 -0
  116. package/dist/internal/batchLoading.test.d.ts +1 -0
  117. package/dist/internal/batchLoading.test.js +50 -0
  118. package/dist/internal/batchLoading.test.js.map +1 -0
  119. package/dist/internal/devices/apiService.d.ts +38 -0
  120. package/dist/internal/devices/apiService.js +105 -0
  121. package/dist/internal/devices/apiService.js.map +1 -0
  122. package/dist/internal/devices/cryptoService.d.ts +30 -0
  123. package/dist/internal/devices/cryptoService.js +47 -0
  124. package/dist/internal/devices/cryptoService.js.map +1 -0
  125. package/dist/internal/devices/index.d.ts +15 -0
  126. package/dist/internal/devices/index.js +22 -0
  127. package/dist/internal/devices/index.js.map +1 -0
  128. package/dist/internal/devices/interface.d.ts +31 -0
  129. package/dist/internal/devices/interface.js +3 -0
  130. package/dist/internal/devices/interface.js.map +1 -0
  131. package/dist/internal/devices/manager.d.ts +18 -0
  132. package/dist/internal/devices/manager.js +103 -0
  133. package/dist/internal/devices/manager.js.map +1 -0
  134. package/dist/internal/devices/manager.test.d.ts +1 -0
  135. package/dist/internal/devices/manager.test.js +100 -0
  136. package/dist/internal/devices/manager.test.js.map +1 -0
  137. package/dist/internal/download/apiService.d.ts +27 -0
  138. package/dist/internal/download/apiService.js +110 -0
  139. package/dist/internal/download/apiService.js.map +1 -0
  140. package/dist/internal/download/controller.d.ts +8 -0
  141. package/dist/internal/download/controller.js +22 -0
  142. package/dist/internal/download/controller.js.map +1 -0
  143. package/dist/internal/download/cryptoService.d.ts +17 -0
  144. package/dist/internal/download/cryptoService.js +82 -0
  145. package/dist/internal/download/cryptoService.js.map +1 -0
  146. package/dist/internal/download/fileDownloader.d.ts +33 -0
  147. package/dist/internal/download/fileDownloader.js +226 -0
  148. package/dist/internal/download/fileDownloader.js.map +1 -0
  149. package/dist/internal/download/fileDownloader.test.d.ts +1 -0
  150. package/dist/internal/download/fileDownloader.test.js +324 -0
  151. package/dist/internal/download/fileDownloader.test.js.map +1 -0
  152. package/dist/internal/download/index.d.ts +10 -0
  153. package/dist/internal/download/index.js +82 -0
  154. package/dist/internal/download/index.js.map +1 -0
  155. package/dist/internal/download/interface.d.ts +35 -0
  156. package/dist/internal/download/interface.js +3 -0
  157. package/dist/internal/download/interface.js.map +1 -0
  158. package/dist/internal/download/queue.d.ts +5 -0
  159. package/dist/internal/download/queue.js +31 -0
  160. package/dist/internal/download/queue.js.map +1 -0
  161. package/dist/internal/download/telemetry.d.ts +14 -0
  162. package/dist/internal/download/telemetry.js +106 -0
  163. package/dist/internal/download/telemetry.js.map +1 -0
  164. package/dist/internal/download/telemetry.test.d.ts +1 -0
  165. package/dist/internal/download/telemetry.test.js +111 -0
  166. package/dist/internal/download/telemetry.test.js.map +1 -0
  167. package/dist/internal/download/thumbnailDownloader.d.ts +19 -0
  168. package/dist/internal/download/thumbnailDownloader.js +198 -0
  169. package/dist/internal/download/thumbnailDownloader.js.map +1 -0
  170. package/dist/internal/download/thumbnailDownloader.test.d.ts +1 -0
  171. package/dist/internal/download/thumbnailDownloader.test.js +179 -0
  172. package/dist/internal/download/thumbnailDownloader.test.js.map +1 -0
  173. package/dist/internal/errors.d.ts +6 -0
  174. package/dist/internal/errors.js +28 -0
  175. package/dist/internal/errors.js.map +1 -0
  176. package/dist/internal/errors.test.d.ts +1 -0
  177. package/dist/internal/errors.test.js +22 -0
  178. package/dist/internal/errors.test.js.map +1 -0
  179. package/dist/internal/events/apiService.d.ts +18 -0
  180. package/dist/internal/events/apiService.js +81 -0
  181. package/dist/internal/events/apiService.js.map +1 -0
  182. package/dist/internal/events/cache.d.ts +28 -0
  183. package/dist/internal/events/cache.js +67 -0
  184. package/dist/internal/events/cache.js.map +1 -0
  185. package/dist/internal/events/cache.test.d.ts +1 -0
  186. package/dist/internal/events/cache.test.js +43 -0
  187. package/dist/internal/events/cache.test.js.map +1 -0
  188. package/dist/internal/events/coreEventManager.d.ts +25 -0
  189. package/dist/internal/events/coreEventManager.js +63 -0
  190. package/dist/internal/events/coreEventManager.js.map +1 -0
  191. package/dist/internal/events/eventManager.d.ts +62 -0
  192. package/dist/internal/events/eventManager.js +159 -0
  193. package/dist/internal/events/eventManager.js.map +1 -0
  194. package/dist/internal/events/eventManager.test.d.ts +1 -0
  195. package/dist/internal/events/eventManager.test.js +120 -0
  196. package/dist/internal/events/eventManager.test.js.map +1 -0
  197. package/dist/internal/events/index.d.ts +50 -0
  198. package/dist/internal/events/index.js +117 -0
  199. package/dist/internal/events/index.js.map +1 -0
  200. package/dist/internal/events/interface.d.ts +47 -0
  201. package/dist/internal/events/interface.js +12 -0
  202. package/dist/internal/events/interface.js.map +1 -0
  203. package/dist/internal/events/volumeEventManager.d.ts +27 -0
  204. package/dist/internal/events/volumeEventManager.js +69 -0
  205. package/dist/internal/events/volumeEventManager.js.map +1 -0
  206. package/dist/internal/nodes/apiService.d.ts +54 -0
  207. package/dist/internal/nodes/apiService.js +308 -0
  208. package/dist/internal/nodes/apiService.js.map +1 -0
  209. package/dist/internal/nodes/apiService.test.d.ts +1 -0
  210. package/dist/internal/nodes/apiService.test.js +344 -0
  211. package/dist/internal/nodes/apiService.test.js.map +1 -0
  212. package/dist/internal/nodes/cache.d.ts +57 -0
  213. package/dist/internal/nodes/cache.js +226 -0
  214. package/dist/internal/nodes/cache.js.map +1 -0
  215. package/dist/internal/nodes/cache.test.d.ts +1 -0
  216. package/dist/internal/nodes/cache.test.js +160 -0
  217. package/dist/internal/nodes/cache.test.js.map +1 -0
  218. package/dist/internal/nodes/cryptoCache.d.ts +16 -0
  219. package/dist/internal/nodes/cryptoCache.js +50 -0
  220. package/dist/internal/nodes/cryptoCache.js.map +1 -0
  221. package/dist/internal/nodes/cryptoCache.test.d.ts +1 -0
  222. package/dist/internal/nodes/cryptoCache.test.js +79 -0
  223. package/dist/internal/nodes/cryptoCache.test.js.map +1 -0
  224. package/dist/internal/nodes/cryptoService.d.ts +75 -0
  225. package/dist/internal/nodes/cryptoService.js +409 -0
  226. package/dist/internal/nodes/cryptoService.js.map +1 -0
  227. package/dist/internal/nodes/cryptoService.test.d.ts +1 -0
  228. package/dist/internal/nodes/cryptoService.test.js +698 -0
  229. package/dist/internal/nodes/cryptoService.test.js.map +1 -0
  230. package/dist/internal/nodes/events.d.ts +91 -0
  231. package/dist/internal/nodes/events.js +243 -0
  232. package/dist/internal/nodes/events.js.map +1 -0
  233. package/dist/internal/nodes/events.test.d.ts +1 -0
  234. package/dist/internal/nodes/events.test.js +318 -0
  235. package/dist/internal/nodes/events.test.js.map +1 -0
  236. package/dist/internal/nodes/extendedAttributes.d.ts +23 -0
  237. package/dist/internal/nodes/extendedAttributes.js +117 -0
  238. package/dist/internal/nodes/extendedAttributes.js.map +1 -0
  239. package/dist/internal/nodes/extendedAttributes.test.d.ts +1 -0
  240. package/dist/internal/nodes/extendedAttributes.test.js +176 -0
  241. package/dist/internal/nodes/extendedAttributes.test.js.map +1 -0
  242. package/dist/internal/nodes/index.d.ts +26 -0
  243. package/dist/internal/nodes/index.js +40 -0
  244. package/dist/internal/nodes/index.js.map +1 -0
  245. package/dist/internal/nodes/index.test.d.ts +1 -0
  246. package/dist/internal/nodes/index.test.js +112 -0
  247. package/dist/internal/nodes/index.test.js.map +1 -0
  248. package/dist/internal/nodes/interface.d.ts +135 -0
  249. package/dist/internal/nodes/interface.js +3 -0
  250. package/dist/internal/nodes/interface.js.map +1 -0
  251. package/dist/internal/nodes/mediaTypes.d.ts +2 -0
  252. package/dist/internal/nodes/mediaTypes.js +13 -0
  253. package/dist/internal/nodes/mediaTypes.js.map +1 -0
  254. package/dist/internal/nodes/nodesAccess.d.ts +49 -0
  255. package/dist/internal/nodes/nodesAccess.js +332 -0
  256. package/dist/internal/nodes/nodesAccess.js.map +1 -0
  257. package/dist/internal/nodes/nodesAccess.test.d.ts +1 -0
  258. package/dist/internal/nodes/nodesAccess.test.js +487 -0
  259. package/dist/internal/nodes/nodesAccess.test.js.map +1 -0
  260. package/dist/internal/nodes/nodesManagement.d.ts +33 -0
  261. package/dist/internal/nodes/nodesManagement.js +222 -0
  262. package/dist/internal/nodes/nodesManagement.js.map +1 -0
  263. package/dist/internal/nodes/nodesManagement.test.d.ts +1 -0
  264. package/dist/internal/nodes/nodesManagement.test.js +178 -0
  265. package/dist/internal/nodes/nodesManagement.test.js.map +1 -0
  266. package/dist/internal/nodes/nodesRevisions.d.ts +18 -0
  267. package/dist/internal/nodes/nodesRevisions.js +55 -0
  268. package/dist/internal/nodes/nodesRevisions.js.map +1 -0
  269. package/dist/internal/nodes/validations.d.ts +4 -0
  270. package/dist/internal/nodes/validations.js +21 -0
  271. package/dist/internal/nodes/validations.js.map +1 -0
  272. package/dist/internal/photos/albums.d.ts +13 -0
  273. package/dist/internal/photos/albums.js +30 -0
  274. package/dist/internal/photos/albums.js.map +1 -0
  275. package/dist/internal/photos/apiService.d.ts +8 -0
  276. package/dist/internal/photos/apiService.js +18 -0
  277. package/dist/internal/photos/apiService.js.map +1 -0
  278. package/dist/internal/photos/cache.d.ts +6 -0
  279. package/dist/internal/photos/cache.js +15 -0
  280. package/dist/internal/photos/cache.js.map +1 -0
  281. package/dist/internal/photos/index.d.ts +9 -0
  282. package/dist/internal/photos/index.js +18 -0
  283. package/dist/internal/photos/index.js.map +1 -0
  284. package/dist/internal/photos/interface.d.ts +6 -0
  285. package/dist/internal/photos/interface.js +3 -0
  286. package/dist/internal/photos/interface.js.map +1 -0
  287. package/dist/internal/photos/photosTimeline.d.ts +10 -0
  288. package/dist/internal/photos/photosTimeline.js +20 -0
  289. package/dist/internal/photos/photosTimeline.js.map +1 -0
  290. package/dist/internal/sdkEvents.d.ts +12 -0
  291. package/dist/internal/sdkEvents.js +44 -0
  292. package/dist/internal/sdkEvents.js.map +1 -0
  293. package/dist/internal/sdkEvents.test.d.ts +1 -0
  294. package/dist/internal/sdkEvents.test.js +45 -0
  295. package/dist/internal/sdkEvents.test.js.map +1 -0
  296. package/dist/internal/shares/apiService.d.ts +51 -0
  297. package/dist/internal/shares/apiService.js +128 -0
  298. package/dist/internal/shares/apiService.js.map +1 -0
  299. package/dist/internal/shares/cache.d.ts +15 -0
  300. package/dist/internal/shares/cache.js +63 -0
  301. package/dist/internal/shares/cache.js.map +1 -0
  302. package/dist/internal/shares/cache.test.d.ts +1 -0
  303. package/dist/internal/shares/cache.test.js +54 -0
  304. package/dist/internal/shares/cache.test.js.map +1 -0
  305. package/dist/internal/shares/cryptoCache.d.ts +20 -0
  306. package/dist/internal/shares/cryptoCache.js +35 -0
  307. package/dist/internal/shares/cryptoCache.js.map +1 -0
  308. package/dist/internal/shares/cryptoCache.test.d.ts +1 -0
  309. package/dist/internal/shares/cryptoCache.test.js +58 -0
  310. package/dist/internal/shares/cryptoCache.test.js.map +1 -0
  311. package/dist/internal/shares/cryptoService.d.ts +42 -0
  312. package/dist/internal/shares/cryptoService.js +126 -0
  313. package/dist/internal/shares/cryptoService.js.map +1 -0
  314. package/dist/internal/shares/cryptoService.test.d.ts +1 -0
  315. package/dist/internal/shares/cryptoService.test.js +120 -0
  316. package/dist/internal/shares/cryptoService.test.js.map +1 -0
  317. package/dist/internal/shares/index.d.ts +15 -0
  318. package/dist/internal/shares/index.js +26 -0
  319. package/dist/internal/shares/index.js.map +1 -0
  320. package/dist/internal/shares/interface.d.ts +94 -0
  321. package/dist/internal/shares/interface.js +11 -0
  322. package/dist/internal/shares/interface.js.map +1 -0
  323. package/dist/internal/shares/manager.d.ts +68 -0
  324. package/dist/internal/shares/manager.js +186 -0
  325. package/dist/internal/shares/manager.js.map +1 -0
  326. package/dist/internal/shares/manager.test.d.ts +1 -0
  327. package/dist/internal/shares/manager.test.js +176 -0
  328. package/dist/internal/shares/manager.test.js.map +1 -0
  329. package/dist/internal/sharing/apiService.d.ts +80 -0
  330. package/dist/internal/sharing/apiService.js +325 -0
  331. package/dist/internal/sharing/apiService.js.map +1 -0
  332. package/dist/internal/sharing/cache.d.ts +37 -0
  333. package/dist/internal/sharing/cache.js +105 -0
  334. package/dist/internal/sharing/cache.js.map +1 -0
  335. package/dist/internal/sharing/cache.test.d.ts +1 -0
  336. package/dist/internal/sharing/cache.test.js +82 -0
  337. package/dist/internal/sharing/cache.test.js.map +1 -0
  338. package/dist/internal/sharing/cryptoService.d.ts +112 -0
  339. package/dist/internal/sharing/cryptoService.js +269 -0
  340. package/dist/internal/sharing/cryptoService.js.map +1 -0
  341. package/dist/internal/sharing/events.d.ts +57 -0
  342. package/dist/internal/sharing/events.js +153 -0
  343. package/dist/internal/sharing/events.js.map +1 -0
  344. package/dist/internal/sharing/events.test.d.ts +1 -0
  345. package/dist/internal/sharing/events.test.js +246 -0
  346. package/dist/internal/sharing/events.test.js.map +1 -0
  347. package/dist/internal/sharing/index.d.ts +20 -0
  348. package/dist/internal/sharing/index.js +30 -0
  349. package/dist/internal/sharing/index.js.map +1 -0
  350. package/dist/internal/sharing/interface.d.ts +169 -0
  351. package/dist/internal/sharing/interface.js +9 -0
  352. package/dist/internal/sharing/interface.js.map +1 -0
  353. package/dist/internal/sharing/sharingAccess.d.ts +32 -0
  354. package/dist/internal/sharing/sharingAccess.js +119 -0
  355. package/dist/internal/sharing/sharingAccess.js.map +1 -0
  356. package/dist/internal/sharing/sharingAccess.test.d.ts +1 -0
  357. package/dist/internal/sharing/sharingAccess.test.js +84 -0
  358. package/dist/internal/sharing/sharingAccess.test.js.map +1 -0
  359. package/dist/internal/sharing/sharingManagement.d.ts +43 -0
  360. package/dist/internal/sharing/sharingManagement.js +439 -0
  361. package/dist/internal/sharing/sharingManagement.js.map +1 -0
  362. package/dist/internal/sharing/sharingManagement.test.d.ts +1 -0
  363. package/dist/internal/sharing/sharingManagement.test.js +788 -0
  364. package/dist/internal/sharing/sharingManagement.test.js.map +1 -0
  365. package/dist/internal/uids.d.ts +38 -0
  366. package/dist/internal/uids.js +85 -0
  367. package/dist/internal/uids.js.map +1 -0
  368. package/dist/internal/upload/apiService.d.ts +65 -0
  369. package/dist/internal/upload/apiService.js +137 -0
  370. package/dist/internal/upload/apiService.js.map +1 -0
  371. package/dist/internal/upload/blockVerifier.d.ts +16 -0
  372. package/dist/internal/upload/blockVerifier.js +33 -0
  373. package/dist/internal/upload/blockVerifier.js.map +1 -0
  374. package/dist/internal/upload/chunkStreamReader.d.ts +13 -0
  375. package/dist/internal/upload/chunkStreamReader.js +46 -0
  376. package/dist/internal/upload/chunkStreamReader.js.map +1 -0
  377. package/dist/internal/upload/chunkStreamReader.test.d.ts +1 -0
  378. package/dist/internal/upload/chunkStreamReader.test.js +75 -0
  379. package/dist/internal/upload/chunkStreamReader.test.js.map +1 -0
  380. package/dist/internal/upload/controller.d.ts +8 -0
  381. package/dist/internal/upload/controller.js +25 -0
  382. package/dist/internal/upload/controller.js.map +1 -0
  383. package/dist/internal/upload/cryptoService.d.ts +29 -0
  384. package/dist/internal/upload/cryptoService.js +104 -0
  385. package/dist/internal/upload/cryptoService.js.map +1 -0
  386. package/dist/internal/upload/digests.d.ts +8 -0
  387. package/dist/internal/upload/digests.js +22 -0
  388. package/dist/internal/upload/digests.js.map +1 -0
  389. package/dist/internal/upload/fileUploader.d.ts +65 -0
  390. package/dist/internal/upload/fileUploader.js +463 -0
  391. package/dist/internal/upload/fileUploader.js.map +1 -0
  392. package/dist/internal/upload/fileUploader.test.d.ts +1 -0
  393. package/dist/internal/upload/fileUploader.test.js +393 -0
  394. package/dist/internal/upload/fileUploader.test.js.map +1 -0
  395. package/dist/internal/upload/index.d.ts +16 -0
  396. package/dist/internal/upload/index.js +77 -0
  397. package/dist/internal/upload/index.js.map +1 -0
  398. package/dist/internal/upload/interface.d.ts +117 -0
  399. package/dist/internal/upload/interface.js +3 -0
  400. package/dist/internal/upload/interface.js.map +1 -0
  401. package/dist/internal/upload/manager.d.ts +31 -0
  402. package/dist/internal/upload/manager.js +250 -0
  403. package/dist/internal/upload/manager.js.map +1 -0
  404. package/dist/internal/upload/manager.test.d.ts +1 -0
  405. package/dist/internal/upload/manager.test.js +349 -0
  406. package/dist/internal/upload/manager.test.js.map +1 -0
  407. package/dist/internal/upload/queue.d.ts +5 -0
  408. package/dist/internal/upload/queue.js +32 -0
  409. package/dist/internal/upload/queue.js.map +1 -0
  410. package/dist/internal/upload/telemetry.d.ts +15 -0
  411. package/dist/internal/upload/telemetry.js +111 -0
  412. package/dist/internal/upload/telemetry.js.map +1 -0
  413. package/dist/internal/upload/telemetry.test.d.ts +1 -0
  414. package/dist/internal/upload/telemetry.test.js +107 -0
  415. package/dist/internal/upload/telemetry.test.js.map +1 -0
  416. package/dist/internal/utils.d.ts +1 -0
  417. package/dist/internal/utils.js +13 -0
  418. package/dist/internal/utils.js.map +1 -0
  419. package/dist/internal/wait.d.ts +3 -0
  420. package/dist/internal/wait.js +28 -0
  421. package/dist/internal/wait.js.map +1 -0
  422. package/dist/internal/wait.test.d.ts +1 -0
  423. package/dist/internal/wait.test.js +21 -0
  424. package/dist/internal/wait.test.js.map +1 -0
  425. package/dist/protonDriveClient.d.ts +593 -0
  426. package/dist/protonDriveClient.js +768 -0
  427. package/dist/protonDriveClient.js.map +1 -0
  428. package/dist/protonDrivePhotosClient.d.ts +16 -0
  429. package/dist/protonDrivePhotosClient.js +46 -0
  430. package/dist/protonDrivePhotosClient.js.map +1 -0
  431. package/dist/telemetry.d.ts +187 -0
  432. package/dist/telemetry.js +297 -0
  433. package/dist/telemetry.js.map +1 -0
  434. package/dist/tests/logger.d.ts +2 -0
  435. package/dist/tests/logger.js +12 -0
  436. package/dist/tests/logger.js.map +1 -0
  437. package/dist/tests/telemetry.d.ts +2 -0
  438. package/dist/tests/telemetry.js +11 -0
  439. package/dist/tests/telemetry.js.map +1 -0
  440. package/dist/transformers.d.ts +17 -0
  441. package/dist/transformers.js +77 -0
  442. package/dist/transformers.js.map +1 -0
  443. package/dist/version.d.ts +1 -0
  444. package/dist/version.js +6 -0
  445. package/dist/version.js.map +1 -0
  446. package/package.json +49 -0
  447. package/src/cache/index.ts +2 -0
  448. package/src/cache/interface.ts +104 -0
  449. package/src/cache/memoryCache.test.ts +150 -0
  450. package/src/cache/memoryCache.ts +85 -0
  451. package/src/config.ts +9 -0
  452. package/src/crypto/driveCrypto.test.ts +45 -0
  453. package/src/crypto/driveCrypto.ts +696 -0
  454. package/src/crypto/hmac.ts +46 -0
  455. package/src/crypto/index.ts +6 -0
  456. package/src/crypto/interface.ts +230 -0
  457. package/src/crypto/openPGPCrypto.ts +398 -0
  458. package/src/crypto/utils.ts +40 -0
  459. package/src/errors.ts +168 -0
  460. package/src/index.ts +30 -0
  461. package/src/interface/account.ts +38 -0
  462. package/src/interface/author.ts +29 -0
  463. package/src/interface/devices.ts +21 -0
  464. package/src/interface/download.ts +32 -0
  465. package/src/interface/events.ts +30 -0
  466. package/src/interface/httpClient.ts +42 -0
  467. package/src/interface/index.ts +46 -0
  468. package/src/interface/nodes.ts +168 -0
  469. package/src/interface/result.ts +11 -0
  470. package/src/interface/sharing.ts +87 -0
  471. package/src/interface/telemetry.ts +107 -0
  472. package/src/interface/thumbnail.ts +14 -0
  473. package/src/interface/upload.ts +19 -0
  474. package/src/internal/apiService/apiService.test.ts +285 -0
  475. package/src/internal/apiService/apiService.ts +353 -0
  476. package/src/internal/apiService/coreTypes.ts +24439 -0
  477. package/src/internal/apiService/driveTypes.ts +11841 -0
  478. package/src/internal/apiService/errorCodes.ts +38 -0
  479. package/src/internal/apiService/errors.test.ts +63 -0
  480. package/src/internal/apiService/errors.ts +91 -0
  481. package/src/internal/apiService/index.ts +7 -0
  482. package/src/internal/apiService/observerStream.ts +10 -0
  483. package/src/internal/apiService/transformers.ts +45 -0
  484. package/src/internal/batchLoading.test.ts +58 -0
  485. package/src/internal/batchLoading.ts +74 -0
  486. package/src/internal/devices/apiService.ts +142 -0
  487. package/src/internal/devices/cryptoService.ts +65 -0
  488. package/src/internal/devices/index.ts +31 -0
  489. package/src/internal/devices/interface.ts +28 -0
  490. package/src/internal/devices/manager.test.ts +129 -0
  491. package/src/internal/devices/manager.ts +113 -0
  492. package/src/internal/download/apiService.ts +145 -0
  493. package/src/internal/download/controller.ts +22 -0
  494. package/src/internal/download/cryptoService.ts +96 -0
  495. package/src/internal/download/fileDownloader.test.ts +381 -0
  496. package/src/internal/download/fileDownloader.ts +266 -0
  497. package/src/internal/download/index.ts +122 -0
  498. package/src/internal/download/interface.ts +38 -0
  499. package/src/internal/download/queue.ts +30 -0
  500. package/src/internal/download/telemetry.test.ts +134 -0
  501. package/src/internal/download/telemetry.ts +115 -0
  502. package/src/internal/download/thumbnailDownloader.test.ts +226 -0
  503. package/src/internal/download/thumbnailDownloader.ts +250 -0
  504. package/src/internal/errors.test.ts +21 -0
  505. package/src/internal/errors.ts +28 -0
  506. package/src/internal/events/apiService.ts +87 -0
  507. package/src/internal/events/cache.test.ts +47 -0
  508. package/src/internal/events/cache.ts +80 -0
  509. package/src/internal/events/coreEventManager.ts +69 -0
  510. package/src/internal/events/eventManager.test.ts +139 -0
  511. package/src/internal/events/eventManager.ts +168 -0
  512. package/src/internal/events/index.ts +131 -0
  513. package/src/internal/events/interface.ts +51 -0
  514. package/src/internal/events/volumeEventManager.ts +74 -0
  515. package/src/internal/nodes/apiService.test.ts +394 -0
  516. package/src/internal/nodes/apiService.ts +455 -0
  517. package/src/internal/nodes/cache.test.ts +197 -0
  518. package/src/internal/nodes/cache.ts +240 -0
  519. package/src/internal/nodes/cryptoCache.test.ts +92 -0
  520. package/src/internal/nodes/cryptoCache.ts +47 -0
  521. package/src/internal/nodes/cryptoService.test.ts +814 -0
  522. package/src/internal/nodes/cryptoService.ts +550 -0
  523. package/src/internal/nodes/events.test.ts +383 -0
  524. package/src/internal/nodes/events.ts +271 -0
  525. package/src/internal/nodes/extendedAttributes.test.ts +177 -0
  526. package/src/internal/nodes/extendedAttributes.ts +180 -0
  527. package/src/internal/nodes/index.test.ts +135 -0
  528. package/src/internal/nodes/index.ts +52 -0
  529. package/src/internal/nodes/interface.ts +152 -0
  530. package/src/internal/nodes/mediaTypes.ts +10 -0
  531. package/src/internal/nodes/nodesAccess.test.ts +555 -0
  532. package/src/internal/nodes/nodesAccess.ts +360 -0
  533. package/src/internal/nodes/nodesManagement.test.ts +221 -0
  534. package/src/internal/nodes/nodesManagement.ts +272 -0
  535. package/src/internal/nodes/nodesRevisions.ts +58 -0
  536. package/src/internal/nodes/validations.ts +26 -0
  537. package/src/internal/photos/albums.ts +29 -0
  538. package/src/internal/photos/apiService.ts +16 -0
  539. package/src/internal/photos/cache.ts +11 -0
  540. package/src/internal/photos/index.ts +23 -0
  541. package/src/internal/photos/interface.ts +7 -0
  542. package/src/internal/photos/photosTimeline.ts +18 -0
  543. package/src/internal/sdkEvents.test.ts +55 -0
  544. package/src/internal/sdkEvents.ts +52 -0
  545. package/src/internal/shares/apiService.ts +176 -0
  546. package/src/internal/shares/cache.test.ts +58 -0
  547. package/src/internal/shares/cache.ts +64 -0
  548. package/src/internal/shares/cryptoCache.test.ts +70 -0
  549. package/src/internal/shares/cryptoCache.ts +35 -0
  550. package/src/internal/shares/cryptoService.test.ts +137 -0
  551. package/src/internal/shares/cryptoService.ts +143 -0
  552. package/src/internal/shares/index.ts +35 -0
  553. package/src/internal/shares/interface.ts +104 -0
  554. package/src/internal/shares/manager.test.ts +210 -0
  555. package/src/internal/shares/manager.ts +213 -0
  556. package/src/internal/sharing/apiService.ts +483 -0
  557. package/src/internal/sharing/cache.test.ts +99 -0
  558. package/src/internal/sharing/cache.ts +109 -0
  559. package/src/internal/sharing/cryptoService.ts +378 -0
  560. package/src/internal/sharing/events.test.ts +268 -0
  561. package/src/internal/sharing/events.ts +166 -0
  562. package/src/internal/sharing/index.ts +43 -0
  563. package/src/internal/sharing/interface.ts +177 -0
  564. package/src/internal/sharing/sharingAccess.test.ts +102 -0
  565. package/src/internal/sharing/sharingAccess.ts +133 -0
  566. package/src/internal/sharing/sharingManagement.test.ts +895 -0
  567. package/src/internal/sharing/sharingManagement.ts +521 -0
  568. package/src/internal/uids.ts +83 -0
  569. package/src/internal/upload/apiService.ts +243 -0
  570. package/src/internal/upload/blockVerifier.ts +40 -0
  571. package/src/internal/upload/chunkStreamReader.test.ts +89 -0
  572. package/src/internal/upload/chunkStreamReader.ts +49 -0
  573. package/src/internal/upload/controller.ts +25 -0
  574. package/src/internal/upload/cryptoService.ts +162 -0
  575. package/src/internal/upload/digests.ts +18 -0
  576. package/src/internal/upload/fileUploader.test.ts +513 -0
  577. package/src/internal/upload/fileUploader.ts +576 -0
  578. package/src/internal/upload/index.ts +126 -0
  579. package/src/internal/upload/interface.ts +128 -0
  580. package/src/internal/upload/manager.test.ts +390 -0
  581. package/src/internal/upload/manager.ts +320 -0
  582. package/src/internal/upload/queue.ts +31 -0
  583. package/src/internal/upload/telemetry.test.ts +129 -0
  584. package/src/internal/upload/telemetry.ts +121 -0
  585. package/src/internal/utils.ts +9 -0
  586. package/src/internal/wait.test.ts +21 -0
  587. package/src/internal/wait.ts +26 -0
  588. package/src/protonDriveClient.ts +861 -0
  589. package/src/protonDrivePhotosClient.ts +56 -0
  590. package/src/telemetry.ts +346 -0
  591. package/src/tests/logger.ts +10 -0
  592. package/src/tests/telemetry.ts +9 -0
  593. package/src/transformers.ts +98 -0
  594. package/src/version.ts +4 -0
@@ -0,0 +1,176 @@
1
+ import { DriveAPIService, drivePaths } from "../apiService";
2
+ import { makeMemberUid } from "../uids";
3
+ import { EncryptedShare, EncryptedRootShare, EncryptedShareCrypto, ShareType } from "./interface";
4
+
5
+ type PostCreateVolumeRequest = Extract<drivePaths['/drive/volumes']['post']['requestBody'], { 'content': object }>['content']['application/json'];
6
+ type PostCreateVolumeResponse = drivePaths['/drive/volumes']['post']['responses']['200']['content']['application/json'];
7
+
8
+ type PostCreateShareRequest = Extract<drivePaths['/drive/volumes/{volumeID}/shares']['post']['requestBody'], { 'content': object }>['content']['application/json'];
9
+ type PostCreateShareResponse = drivePaths['/drive/volumes/{volumeID}/shares']['post']['responses']['200']['content']['application/json'];
10
+
11
+ type GetMyFilesResponse = drivePaths['/drive/v2/shares/my-files']['get']['responses']['200']['content']['application/json'];
12
+ type GetVolumeResponse = drivePaths['/drive/volumes/{volumeID}']['get']['responses']['200']['content']['application/json'];
13
+ type GetShareResponse = drivePaths['/drive/shares/{shareID}']['get']['responses']['200']['content']['application/json'];
14
+
15
+ /**
16
+ * Provides API communication for fetching shares and creating volumes.
17
+ *
18
+ * The service is responsible for transforming local objects to API payloads
19
+ * and vice versa. It should not contain any business logic.
20
+ */
21
+ export class SharesAPIService {
22
+ constructor(private apiService: DriveAPIService) {
23
+ this.apiService = apiService;
24
+ }
25
+
26
+ async getMyFiles(): Promise<EncryptedRootShare> {
27
+ const response = await this.apiService.get<GetMyFilesResponse>('drive/v2/shares/my-files');
28
+ return {
29
+ volumeId: response.Volume.VolumeID,
30
+ shareId: response.Share.ShareID,
31
+ rootNodeId: response.Link.Link.LinkID,
32
+ creatorEmail: response.Share.CreatorEmail,
33
+ encryptedCrypto: {
34
+ armoredKey: response.Share.Key,
35
+ armoredPassphrase: response.Share.Passphrase,
36
+ armoredPassphraseSignature: response.Share.PassphraseSignature,
37
+ },
38
+ addressId: response.Share.AddressID,
39
+ type: ShareType.Main,
40
+ };
41
+ }
42
+
43
+ async getVolume(volumeId: string): Promise<{ shareId: string }> {
44
+ const response = await this.apiService.get<GetVolumeResponse>(`drive/volumes/${volumeId}`);
45
+ return {
46
+ shareId: response.Volume.Share.ShareID,
47
+ }
48
+ }
49
+
50
+ async getShare(shareId: string): Promise<EncryptedShare> {
51
+ const response = await this.apiService.get<GetShareResponse>(`drive/shares/${shareId}`);
52
+ return convertSharePayload(response);
53
+ }
54
+
55
+ /**
56
+ * Returns root share with address key.
57
+ *
58
+ * This function provides access to root shares that provides access
59
+ * to node tree via address key. For this reason, caller must use this
60
+ * only when it is clear the shareId is root share.
61
+ *
62
+ * @throws Error when share is not root share.
63
+ */
64
+ async getRootShare(shareId: string): Promise<EncryptedRootShare> {
65
+ const response = await this.apiService.get<GetShareResponse>(`drive/shares/${shareId}`);
66
+
67
+ if (!response.AddressID) {
68
+ throw new Error('Loading share without direct access is not supported');
69
+ }
70
+
71
+ return {
72
+ ...convertSharePayload(response),
73
+ addressId: response.AddressID,
74
+ };
75
+ }
76
+
77
+ async createVolume(
78
+ share: {
79
+ addressId: string,
80
+ addressKeyId: string,
81
+ } & EncryptedShareCrypto,
82
+ node: {
83
+ encryptedName: string,
84
+ armoredKey: string,
85
+ armoredPassphrase: string,
86
+ armoredPassphraseSignature: string,
87
+ armoredHashKey: string,
88
+ },
89
+ ): Promise<{ volumeId: string, shareId: string, rootNodeId: string }> {
90
+ const response = await this.apiService.post<
91
+ // Volume & share names are deprecated.
92
+ Omit<PostCreateVolumeRequest, 'VolumeName' | 'ShareName'>,
93
+ PostCreateVolumeResponse
94
+ >('drive/volumes', {
95
+ AddressID: share.addressId,
96
+ AddressKeyID: share.addressKeyId,
97
+ ShareKey: share.armoredKey,
98
+ SharePassphrase: share.armoredPassphrase,
99
+ SharePassphraseSignature: share.armoredPassphraseSignature,
100
+
101
+ FolderName: node.encryptedName,
102
+ FolderKey: node.armoredKey,
103
+ FolderPassphrase: node.armoredPassphrase,
104
+ FolderPassphraseSignature: node.armoredPassphraseSignature,
105
+ FolderHashKey: node.armoredHashKey,
106
+ });
107
+ return {
108
+ volumeId: response.Volume.ID,
109
+ shareId: response.Volume.Share.ShareID,
110
+ rootNodeId: response.Volume.Share.LinkID,
111
+ }
112
+ }
113
+
114
+ async createShare(
115
+ volumeId: string,
116
+ share: {
117
+ addressId: string,
118
+ } & EncryptedShareCrypto,
119
+ node: {
120
+ nodeId: string,
121
+ encryptedName: string,
122
+ nameKeyPacket: string,
123
+ passphraseKeyPacket: string,
124
+ },
125
+ ): Promise<{ shareId: string }> {
126
+ const response = await this.apiService.post<
127
+ // Share name is deprecated.
128
+ Omit<PostCreateShareRequest, 'Name'>,
129
+ PostCreateShareResponse
130
+ >(`/drive/volumes/${volumeId}/shares`, {
131
+ AddressID: share.addressId,
132
+ ShareKey: share.armoredKey,
133
+ SharePassphrase: share.armoredPassphrase,
134
+ SharePassphraseSignature: share.armoredPassphraseSignature,
135
+ RootLinkID: node.nodeId,
136
+ NameKeyPacket: node.nameKeyPacket,
137
+ PassphraseKeyPacket: node.passphraseKeyPacket,
138
+ });
139
+
140
+ return {
141
+ shareId: response.Share.ID,
142
+ }
143
+ }
144
+ }
145
+
146
+ function convertSharePayload(response: GetShareResponse): EncryptedShare {
147
+ return {
148
+ volumeId: response.VolumeID,
149
+ shareId: response.ShareID,
150
+ rootNodeId: response.LinkID,
151
+ creatorEmail: response.Creator,
152
+ creationTime: response.CreateTime ? new Date(response.CreateTime*1000) : undefined,
153
+ encryptedCrypto: {
154
+ armoredKey: response.Key,
155
+ armoredPassphrase: response.Passphrase,
156
+ armoredPassphraseSignature: response.PassphraseSignature,
157
+ },
158
+ membership: response.Memberships?.[0] ? {
159
+ memberUid: makeMemberUid(response.ShareID, response.Memberships[0].MemberID),
160
+ } : undefined,
161
+ type: convertShareTypeNumberToEnum(response.Type),
162
+ };
163
+ }
164
+
165
+ function convertShareTypeNumberToEnum(type: 1 | 2 | 3 | 4): ShareType {
166
+ switch (type) {
167
+ case 1:
168
+ return ShareType.Main;
169
+ case 2:
170
+ return ShareType.Standard;
171
+ case 3:
172
+ return ShareType.Device;
173
+ case 4:
174
+ return ShareType.Photo;
175
+ }
176
+ }
@@ -0,0 +1,58 @@
1
+ import { MemoryCache } from "../../cache";
2
+ import { getMockLogger } from "../../tests/logger";
3
+ import { SharesCache } from "./cache";
4
+
5
+ describe('sharesCache', () => {
6
+ let memoryCache: MemoryCache<string>;
7
+ let cache: SharesCache;
8
+
9
+ beforeEach(async () => {
10
+ memoryCache = new MemoryCache();
11
+ await memoryCache.setEntity('volume-badObject', 'aaa');
12
+
13
+ cache = new SharesCache(getMockLogger(), memoryCache);
14
+ });
15
+
16
+ it('should store and retrieve volume', async () => {
17
+ const volumeId = 'volume1';
18
+ const volume = {
19
+ volumeId,
20
+ shareId: 'share1',
21
+ rootNodeId: 'node1',
22
+ creatorEmail: 'email',
23
+ addressId: 'address1',
24
+ };
25
+
26
+ await cache.setVolume(volume);
27
+ const result = await cache.getVolume(volumeId);
28
+
29
+ expect(result).toStrictEqual(volume);
30
+ });
31
+
32
+ it('should throw an error when retrieving a non-existing entity', async () => {
33
+ const volumeId = 'newVolumeId';
34
+
35
+ try {
36
+ await cache.getVolume(volumeId);
37
+ fail('Should have thrown an error');
38
+ } catch (error) {
39
+ expect(`${error}`).toBe('Error: Entity not found');
40
+ }
41
+ });
42
+
43
+ it('should throw an error when retrieving a bad keys and remove the key', async () => {
44
+ try {
45
+ await cache.getVolume('badObject');
46
+ fail('Should have thrown an error');
47
+ } catch (error) {
48
+ expect(`${error}`).toBe('Error: Failed to deserialize volume: Unexpected token \'a\', \"aaa\" is not valid JSON');
49
+ }
50
+
51
+ try {
52
+ await memoryCache.getEntity('volumes-badObject');
53
+ fail('Should have thrown an error');
54
+ } catch (error) {
55
+ expect(`${error}`).toBe('Error: Entity not found');
56
+ }
57
+ });
58
+ });
@@ -0,0 +1,64 @@
1
+ import { ProtonDriveEntitiesCache, Logger } from "../../interface";
2
+ import { getErrorMessage } from "../errors";
3
+ import { Volume } from "./interface";
4
+
5
+ /**
6
+ * Provides caching for shares and volume metadata.
7
+ *
8
+ * The cache is responsible for serialising and deserialising volume metadata.
9
+ */
10
+ export class SharesCache {
11
+ constructor(private logger: Logger, private driveCache: ProtonDriveEntitiesCache) {
12
+ this.logger = logger;
13
+ this.driveCache = driveCache;
14
+ }
15
+
16
+ async setVolume(volume: Volume): Promise<void> {
17
+ const key = getCacheUid(volume.volumeId);
18
+ const shareData = serializeVolume(volume);
19
+ await this.driveCache.setEntity(key, shareData);
20
+ }
21
+
22
+ async getVolume(volumeId: string): Promise<Volume> {
23
+ const key = getCacheUid(volumeId);
24
+ const volumeData = await this.driveCache.getEntity(key);
25
+
26
+ try {
27
+ return deserializeVolume(volumeData);
28
+ } catch (error: unknown) {
29
+ try {
30
+ await this.removeVolume(volumeId);
31
+ } catch (removingError: unknown) {
32
+ this.logger.error('Failed to remove invalid volume from cache', removingError);
33
+ }
34
+ throw new Error(`Failed to deserialize volume: ${getErrorMessage(error)}`);
35
+ }
36
+ }
37
+
38
+ async removeVolume(volumeId: string): Promise<void> {
39
+ await this.driveCache.removeEntities([getCacheUid(volumeId)]);
40
+ }
41
+ }
42
+
43
+ function getCacheUid(volumeId: string) {
44
+ return `volume-${volumeId}`;
45
+ }
46
+
47
+ function serializeVolume(volume: Volume) {
48
+ return JSON.stringify(volume);
49
+ }
50
+
51
+ function deserializeVolume(shareData: string): Volume {
52
+ const volume = JSON.parse(shareData);
53
+ if (
54
+ !volume || typeof volume !== 'object' ||
55
+ !volume.volumeId || typeof volume.volumeId !== 'string' ||
56
+ !volume.shareId || typeof volume.shareId !== 'string' ||
57
+ !volume.rootNodeId || typeof volume.rootNodeId !== 'string' ||
58
+ !volume.creatorEmail || typeof volume.creatorEmail !== 'string' ||
59
+ !volume.addressId || typeof volume.addressId !== 'string'
60
+ ) {
61
+ throw new Error('Invalid volume data');
62
+ }
63
+ return volume;
64
+ }
@@ -0,0 +1,70 @@
1
+ import { PrivateKey, SessionKey } from "../../crypto";
2
+ import { MemoryCache } from "../../cache";
3
+ import { CachedCryptoMaterial } from "../../interface";
4
+ import { SharesCryptoCache } from "./cryptoCache";
5
+
6
+ describe('sharesCryptoCache', () => {
7
+ let memoryCache: MemoryCache<CachedCryptoMaterial>;
8
+ let cache: SharesCryptoCache;
9
+
10
+ const generatePrivateKey = (name: string) => {
11
+ return name as unknown as PrivateKey
12
+ }
13
+
14
+ const generateSessionKey = (name: string) => {
15
+ return name as unknown as SessionKey
16
+ }
17
+
18
+ beforeEach(() => {
19
+ memoryCache = new MemoryCache();
20
+ cache = new SharesCryptoCache(memoryCache);
21
+ });
22
+
23
+ it('should store and retrieve keys', async () => {
24
+ const shareId = 'newShareId';
25
+ const keys = { key: generatePrivateKey('privateKey'), passphraseSessionKey: generateSessionKey('sessionKey') };
26
+
27
+ await cache.setShareKey(shareId, keys);
28
+ const result = await cache.getShareKey(shareId);
29
+
30
+ expect(result).toStrictEqual(keys);
31
+ });
32
+
33
+ it('should replace and retrieve new keys', async () => {
34
+ const shareId = 'newShareId';
35
+ const keys1 = { key: generatePrivateKey('privateKey1'), passphraseSessionKey: generateSessionKey('sessionKey1') };
36
+ const keys2 = { key: generatePrivateKey('privateKey2'), passphraseSessionKey: generateSessionKey('sessionKey2') };
37
+
38
+ await cache.setShareKey(shareId, keys1);
39
+ await cache.setShareKey(shareId, keys2);
40
+ const result = await cache.getShareKey(shareId);
41
+
42
+ expect(result).toStrictEqual(keys2);
43
+ });
44
+
45
+ it('should remove keys', async () => {
46
+ const shareId = 'newShareId';
47
+ const keys = { key: generatePrivateKey('privateKey'), passphraseSessionKey: generateSessionKey('sessionKey') };
48
+
49
+ await cache.setShareKey(shareId, keys);
50
+ await cache.removeShareKey([shareId]);
51
+
52
+ try {
53
+ await cache.getShareKey(shareId);
54
+ throw new Error('Should have thrown an error');
55
+ } catch (error) {
56
+ expect(`${error}`).toBe('Error: Entity not found');
57
+ }
58
+ });
59
+
60
+ it('should throw an error when retrieving a non-existing entity', async () => {
61
+ const shareId = 'newShareId';
62
+
63
+ try {
64
+ await cache.getShareKey(shareId);
65
+ throw new Error('Should have thrown an error');
66
+ } catch (error) {
67
+ expect(`${error}`).toBe('Error: Entity not found');
68
+ }
69
+ });
70
+ });
@@ -0,0 +1,35 @@
1
+ import { ProtonDriveCryptoCache } from "../../interface";
2
+ import { DecryptedShareKey } from "./interface";
3
+
4
+ /**
5
+ * Provides caching for share crypto material.
6
+ *
7
+ * The cache is responsible for serialising and deserialising share
8
+ * crypto material.
9
+ *
10
+ * The share crypto materials are cached so the updates to the root
11
+ * nodes can be decrypted without the need to fetch the share keys
12
+ * from the server again. Otherwise the rest of the tree requires
13
+ * only the root node, thus share cache is not needed.
14
+ */
15
+ export class SharesCryptoCache {
16
+ constructor(private driveCache: ProtonDriveCryptoCache) {
17
+ this.driveCache = driveCache;
18
+ }
19
+
20
+ async setShareKey(shareId: string, key: DecryptedShareKey): Promise<void> {
21
+ await this.driveCache.setEntity(getCacheUid(shareId), key);
22
+ }
23
+
24
+ async getShareKey(shareId: string): Promise<DecryptedShareKey> {
25
+ return this.driveCache.getEntity(getCacheUid(shareId));
26
+ }
27
+
28
+ async removeShareKey(shareIds: string[]): Promise<void> {
29
+ await this.driveCache.removeEntities(shareIds.map(getCacheUid));
30
+ }
31
+ }
32
+
33
+ function getCacheUid(shareId: string) {
34
+ return `shareKey-${shareId}`;
35
+ }
@@ -0,0 +1,137 @@
1
+ import { DriveCrypto, PrivateKey, SessionKey, VERIFICATION_STATUS } from "../../crypto";
2
+ import { ProtonDriveAccount, ProtonDriveTelemetry } from "../../interface";
3
+ import { getMockTelemetry } from "../../tests/telemetry";
4
+ import { EncryptedRootShare, ShareType } from "./interface";
5
+ import { SharesCryptoService } from "./cryptoService";
6
+
7
+ describe("SharesCryptoService", () => {
8
+ let telemetry: ProtonDriveTelemetry;
9
+ let driveCrypto: DriveCrypto;
10
+ let account: ProtonDriveAccount;
11
+ let cryptoService: SharesCryptoService;
12
+
13
+ beforeEach(() => {
14
+ telemetry = getMockTelemetry();
15
+ // @ts-expect-error No need to implement all methods for mocking
16
+ driveCrypto = {
17
+ decryptKey: jest.fn(async () => Promise.resolve({
18
+ passphrase: "pass",
19
+ key: "decryptedKey" as unknown as PrivateKey,
20
+ passphraseSessionKey: "sessionKey" as unknown as SessionKey,
21
+ verified: VERIFICATION_STATUS.SIGNED_AND_VALID,
22
+ })),
23
+ };
24
+ account = {
25
+ // @ts-expect-error No need to implement full response for mocking
26
+ getOwnAddress: jest.fn(async () => ({
27
+ keys: [{ key: "addressKey" as unknown as PrivateKey }],
28
+ })),
29
+ getPublicKeys: jest.fn(async () => []),
30
+ };
31
+ cryptoService = new SharesCryptoService(telemetry, driveCrypto, account);
32
+ });
33
+
34
+ it("should decrypt root share", async () => {
35
+ const result = await cryptoService.decryptRootShare(
36
+ {
37
+ shareId: "shareId",
38
+ addressId: "addressId",
39
+ creatorEmail: "signatureEmail",
40
+ encryptedCrypto: {
41
+ armoredKey: "armoredKey",
42
+ armoredPassphrase: "armoredPassphrase",
43
+ armoredPassphraseSignature: "armoredPassphraseSignature",
44
+ },
45
+ type: ShareType.Main,
46
+ } as EncryptedRootShare,
47
+ );
48
+
49
+ expect(result).toMatchObject({
50
+ share: {
51
+ shareId: "shareId",
52
+ author: { ok: true, value: "signatureEmail" },
53
+ },
54
+ key: {
55
+ key: "decryptedKey",
56
+ passphraseSessionKey: "sessionKey",
57
+ },
58
+ });
59
+
60
+ expect(account.getOwnAddress).toHaveBeenCalledWith("addressId");
61
+ expect(account.getPublicKeys).toHaveBeenCalledWith("signatureEmail");
62
+ expect(telemetry.logEvent).not.toHaveBeenCalled();
63
+ });
64
+
65
+ it("should decrypt root share with signiture verification error", async () => {
66
+ driveCrypto.decryptKey = jest.fn(async () => Promise.resolve({
67
+ passphrase: "pass",
68
+ key: "decryptedKey" as unknown as PrivateKey,
69
+ passphraseSessionKey: "sessionKey" as unknown as SessionKey,
70
+ verified: VERIFICATION_STATUS.NOT_SIGNED,
71
+ }));
72
+
73
+ const result = await cryptoService.decryptRootShare(
74
+ {
75
+ shareId: "shareId",
76
+ addressId: "addressId",
77
+ creatorEmail: "signatureEmail",
78
+ encryptedCrypto: {
79
+ armoredKey: "armoredKey",
80
+ armoredPassphrase: "armoredPassphrase",
81
+ armoredPassphraseSignature: "armoredPassphraseSignature",
82
+ },
83
+ type: ShareType.Main,
84
+ } as EncryptedRootShare,
85
+ );
86
+
87
+ expect(result).toMatchObject({
88
+ share: {
89
+ shareId: "shareId",
90
+ author: { ok: false, error: { claimedAuthor: "signatureEmail", error: "Missing signature" } },
91
+ },
92
+ key: {
93
+ key: "decryptedKey",
94
+ passphraseSessionKey: "sessionKey",
95
+ },
96
+ });
97
+
98
+ expect(account.getOwnAddress).toHaveBeenCalledWith("addressId");
99
+ expect(account.getPublicKeys).toHaveBeenCalledWith("signatureEmail");
100
+ expect(telemetry.logEvent).toHaveBeenCalledWith({
101
+ eventName: 'verificationError',
102
+ context: 'own_volume',
103
+ field: 'shareKey',
104
+ addressMatchingDefaultShare: undefined,
105
+ fromBefore2024: undefined,
106
+ });
107
+ });
108
+
109
+ it("should handle decrypt issue of root share", async () => {
110
+ const error = new Error("Decryption error");
111
+ driveCrypto.decryptKey = jest.fn(async () => Promise.reject(error));
112
+
113
+ const result = cryptoService.decryptRootShare(
114
+ {
115
+ shareId: "shareId",
116
+ addressId: "addressId",
117
+ creatorEmail: "signatureEmail",
118
+ encryptedCrypto: {
119
+ armoredKey: "armoredKey",
120
+ armoredPassphrase: "armoredPassphrase",
121
+ armoredPassphraseSignature: "armoredPassphraseSignature",
122
+ },
123
+ type: ShareType.Main,
124
+ } as EncryptedRootShare,
125
+ );
126
+
127
+ await expect(result).rejects.toThrow(error);
128
+
129
+ expect(telemetry.logEvent).toHaveBeenCalledWith({
130
+ eventName: 'decryptionError',
131
+ context: 'own_volume',
132
+ field: 'shareKey',
133
+ fromBefore2024: undefined,
134
+ error,
135
+ });
136
+ });
137
+ });
@@ -0,0 +1,143 @@
1
+ import { ProtonDriveAccount, resultOk, resultError, Result, UnverifiedAuthorError, ProtonDriveTelemetry, Logger, MetricContext } from "../../interface";
2
+ import { DriveCrypto, PrivateKey, VERIFICATION_STATUS } from "../../crypto";
3
+ import { getVerificationMessage } from "../errors";
4
+ import { EncryptedRootShare, DecryptedRootShare, EncryptedShareCrypto, DecryptedShareKey, ShareType } from "./interface";
5
+
6
+ /**
7
+ * Provides crypto operations for share keys.
8
+ *
9
+ * The share crypto service is responsible for encrypting and decrypting share
10
+ * keys. It should export high-level actions only, such as "decrypt share"
11
+ * instead of low-level operations like "decrypt share passphrase". Low-level
12
+ * operations should be kept private to the module.
13
+ *
14
+ * The service owns the logic to switch between old and new crypto model.
15
+ */
16
+ export class SharesCryptoService {
17
+ private logger: Logger;
18
+
19
+ private reportedDecryptionErrors = new Set<string>();
20
+ private reportedVerificationErrors = new Set<string>();
21
+
22
+ constructor(private telemetry: ProtonDriveTelemetry, private driveCrypto: DriveCrypto, private account: ProtonDriveAccount) {
23
+ this.telemetry = telemetry;
24
+ this.logger = telemetry.getLogger('shares-crypto');
25
+ this.driveCrypto = driveCrypto;
26
+ this.account = account;
27
+ }
28
+
29
+ async generateVolumeBootstrap(addressKey: PrivateKey): Promise<{
30
+ shareKey: { encrypted: EncryptedShareCrypto, decrypted: DecryptedShareKey },
31
+ rootNode: {
32
+ key: { encrypted: EncryptedShareCrypto, decrypted: DecryptedShareKey },
33
+ encryptedName: string,
34
+ armoredHashKey: string,
35
+ }
36
+ }> {
37
+ const shareKey = await this.driveCrypto.generateKey([addressKey], addressKey);
38
+ const rootNodeKey = await this.driveCrypto.generateKey([shareKey.decrypted.key], addressKey);
39
+ const { armoredNodeName } = await this.driveCrypto.encryptNodeName('root', undefined, shareKey.decrypted.key, addressKey);
40
+ const { armoredHashKey } = await this.driveCrypto.generateHashKey(rootNodeKey.decrypted.key);
41
+ return {
42
+ shareKey,
43
+ rootNode: {
44
+ key: rootNodeKey,
45
+ encryptedName: armoredNodeName,
46
+ armoredHashKey,
47
+ },
48
+ }
49
+ }
50
+
51
+ async decryptRootShare(share: EncryptedRootShare): Promise<{ share: DecryptedRootShare, key: DecryptedShareKey }> {
52
+ const { keys: addressKeys } = await this.account.getOwnAddress(share.addressId);
53
+ const addressPublicKeys = await this.account.getPublicKeys(share.creatorEmail);
54
+
55
+ let key, passphraseSessionKey, verified;
56
+ try {
57
+ const result = await this.driveCrypto.decryptKey(
58
+ share.encryptedCrypto.armoredKey,
59
+ share.encryptedCrypto.armoredPassphrase,
60
+ share.encryptedCrypto.armoredPassphraseSignature,
61
+ addressKeys.map(({ key }) => key),
62
+ addressPublicKeys,
63
+ )
64
+ key = result.key;
65
+ passphraseSessionKey = result.passphraseSessionKey;
66
+ verified = result.verified;
67
+ } catch (error: unknown) {
68
+ this.reportDecryptionError(share, error);
69
+ throw error;
70
+ }
71
+
72
+ const author: Result<string, UnverifiedAuthorError> = verified === VERIFICATION_STATUS.SIGNED_AND_VALID
73
+ ? resultOk(share.creatorEmail)
74
+ : resultError({
75
+ claimedAuthor: share.creatorEmail,
76
+ error: getVerificationMessage(verified),
77
+ });
78
+
79
+ if (!author.ok) {
80
+ await this.reportVerificationError(share);
81
+ }
82
+
83
+ return {
84
+ share: {
85
+ ...share,
86
+ author,
87
+ },
88
+ key: {
89
+ key,
90
+ passphraseSessionKey,
91
+ },
92
+ }
93
+ }
94
+
95
+ private reportDecryptionError(share: EncryptedRootShare, error?: unknown) {
96
+ if (this.reportedDecryptionErrors.has(share.shareId)) {
97
+ return;
98
+ }
99
+
100
+ const fromBefore2024 = share.creationTime ? share.creationTime < new Date('2024-01-01') : undefined;
101
+ this.logger.error(`Failed to decrypt share ${share.shareId} (from before 2024: ${fromBefore2024})`, error);
102
+
103
+ this.telemetry.logEvent({
104
+ eventName: 'decryptionError',
105
+ context: shareTypeToMetricContext(share.type),
106
+ field: 'shareKey',
107
+ fromBefore2024,
108
+ error,
109
+ });
110
+ this.reportedDecryptionErrors.add(share.shareId);
111
+ }
112
+
113
+ private async reportVerificationError(share: EncryptedRootShare) {
114
+ if (this.reportedVerificationErrors.has(share.shareId)) {
115
+ return;
116
+ }
117
+
118
+ const fromBefore2024 = share.creationTime ? share.creationTime < new Date('2024-01-01') : undefined;
119
+ this.logger.error(`Failed to verify share ${share.shareId} (from before 2024: ${fromBefore2024})`);
120
+
121
+ this.telemetry.logEvent({
122
+ eventName: 'verificationError',
123
+ context: shareTypeToMetricContext(share.type),
124
+ field: 'shareKey',
125
+ fromBefore2024,
126
+ });
127
+ this.reportedVerificationErrors.add(share.shareId);
128
+ }
129
+ }
130
+
131
+ function shareTypeToMetricContext(shareType: ShareType): MetricContext {
132
+ // SDK doesn't support public sharing yet, also public sharing
133
+ // doesn't use a share but shareURL, thus we can simplify and
134
+ // ignore this case for now.
135
+ switch (shareType) {
136
+ case ShareType.Main:
137
+ case ShareType.Device:
138
+ case ShareType.Photo:
139
+ return MetricContext.OwnVolume;
140
+ case ShareType.Standard:
141
+ return MetricContext.Shared;
142
+ }
143
+ }