@protontech/drive-sdk 0.6.2 → 0.7.1

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 (158) hide show
  1. package/dist/interface/index.d.ts +1 -0
  2. package/dist/interface/index.js.map +1 -1
  3. package/dist/interface/nodes.d.ts +14 -10
  4. package/dist/interface/nodes.js +5 -8
  5. package/dist/interface/nodes.js.map +1 -1
  6. package/dist/interface/photos.d.ts +62 -0
  7. package/dist/interface/photos.js +3 -0
  8. package/dist/interface/photos.js.map +1 -0
  9. package/dist/internal/apiService/apiService.d.ts +2 -2
  10. package/dist/internal/apiService/apiService.js.map +1 -1
  11. package/dist/internal/apiService/driveTypes.d.ts +1294 -517
  12. package/dist/internal/apiService/errors.js +4 -3
  13. package/dist/internal/apiService/errors.js.map +1 -1
  14. package/dist/internal/download/cryptoService.js +8 -6
  15. package/dist/internal/download/cryptoService.js.map +1 -1
  16. package/dist/internal/download/fileDownloader.d.ts +2 -1
  17. package/dist/internal/download/fileDownloader.js +6 -3
  18. package/dist/internal/download/fileDownloader.js.map +1 -1
  19. package/dist/internal/download/index.d.ts +1 -1
  20. package/dist/internal/download/index.js +3 -3
  21. package/dist/internal/download/index.js.map +1 -1
  22. package/dist/internal/errors.d.ts +1 -0
  23. package/dist/internal/errors.js +4 -0
  24. package/dist/internal/errors.js.map +1 -1
  25. package/dist/internal/nodes/apiService.d.ts +68 -16
  26. package/dist/internal/nodes/apiService.js +138 -85
  27. package/dist/internal/nodes/apiService.js.map +1 -1
  28. package/dist/internal/nodes/apiService.test.js +7 -5
  29. package/dist/internal/nodes/apiService.test.js.map +1 -1
  30. package/dist/internal/nodes/cache.d.ts +16 -8
  31. package/dist/internal/nodes/cache.js +19 -5
  32. package/dist/internal/nodes/cache.js.map +1 -1
  33. package/dist/internal/nodes/cache.test.js +1 -0
  34. package/dist/internal/nodes/cache.test.js.map +1 -1
  35. package/dist/internal/nodes/cryptoReporter.d.ts +3 -3
  36. package/dist/internal/nodes/cryptoReporter.js.map +1 -1
  37. package/dist/internal/nodes/cryptoService.d.ts +13 -22
  38. package/dist/internal/nodes/cryptoService.js +47 -16
  39. package/dist/internal/nodes/cryptoService.js.map +1 -1
  40. package/dist/internal/nodes/cryptoService.test.js +262 -17
  41. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  42. package/dist/internal/nodes/events.d.ts +2 -2
  43. package/dist/internal/nodes/events.js.map +1 -1
  44. package/dist/internal/nodes/index.test.js +1 -0
  45. package/dist/internal/nodes/index.test.js.map +1 -1
  46. package/dist/internal/nodes/interface.d.ts +14 -3
  47. package/dist/internal/nodes/nodesAccess.d.ts +36 -20
  48. package/dist/internal/nodes/nodesAccess.js +54 -29
  49. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  50. package/dist/internal/nodes/nodesManagement.d.ts +34 -14
  51. package/dist/internal/nodes/nodesManagement.js +44 -31
  52. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  53. package/dist/internal/nodes/nodesManagement.test.js +60 -14
  54. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  55. package/dist/internal/nodes/nodesRevisions.d.ts +2 -2
  56. package/dist/internal/nodes/nodesRevisions.js.map +1 -1
  57. package/dist/internal/photos/albums.d.ts +2 -2
  58. package/dist/internal/photos/albums.js.map +1 -1
  59. package/dist/internal/photos/index.d.ts +19 -3
  60. package/dist/internal/photos/index.js +38 -8
  61. package/dist/internal/photos/index.js.map +1 -1
  62. package/dist/internal/photos/interface.d.ts +18 -9
  63. package/dist/internal/photos/nodes.d.ts +57 -0
  64. package/dist/internal/photos/nodes.js +165 -0
  65. package/dist/internal/photos/nodes.js.map +1 -0
  66. package/dist/internal/photos/timeline.d.ts +2 -2
  67. package/dist/internal/photos/timeline.js.map +1 -1
  68. package/dist/internal/photos/timeline.test.js.map +1 -1
  69. package/dist/internal/photos/upload.d.ts +2 -2
  70. package/dist/internal/photos/upload.js.map +1 -1
  71. package/dist/internal/sharingPublic/index.d.ts +6 -6
  72. package/dist/internal/sharingPublic/index.js +8 -7
  73. package/dist/internal/sharingPublic/index.js.map +1 -1
  74. package/dist/internal/sharingPublic/nodes.d.ts +16 -3
  75. package/dist/internal/sharingPublic/nodes.js +34 -2
  76. package/dist/internal/sharingPublic/nodes.js.map +1 -1
  77. package/dist/internal/sharingPublic/unauthApiService.d.ts +17 -0
  78. package/dist/internal/sharingPublic/unauthApiService.js +31 -0
  79. package/dist/internal/sharingPublic/unauthApiService.js.map +1 -0
  80. package/dist/internal/sharingPublic/unauthApiService.test.d.ts +1 -0
  81. package/dist/internal/sharingPublic/unauthApiService.test.js +27 -0
  82. package/dist/internal/sharingPublic/unauthApiService.test.js.map +1 -0
  83. package/dist/internal/upload/apiService.d.ts +4 -3
  84. package/dist/internal/upload/apiService.js.map +1 -1
  85. package/dist/internal/upload/cryptoService.d.ts +8 -3
  86. package/dist/internal/upload/cryptoService.js +45 -9
  87. package/dist/internal/upload/cryptoService.js.map +1 -1
  88. package/dist/internal/upload/fileUploader.test.js +1 -1
  89. package/dist/internal/upload/fileUploader.test.js.map +1 -1
  90. package/dist/internal/upload/interface.d.ts +25 -13
  91. package/dist/internal/upload/manager.js +7 -4
  92. package/dist/internal/upload/manager.js.map +1 -1
  93. package/dist/internal/upload/manager.test.js +5 -4
  94. package/dist/internal/upload/manager.test.js.map +1 -1
  95. package/dist/internal/upload/streamUploader.js +9 -4
  96. package/dist/internal/upload/streamUploader.js.map +1 -1
  97. package/dist/internal/upload/streamUploader.test.js +8 -5
  98. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  99. package/dist/protonDriveClient.d.ts +11 -2
  100. package/dist/protonDriveClient.js +20 -4
  101. package/dist/protonDriveClient.js.map +1 -1
  102. package/dist/protonDrivePhotosClient.d.ts +8 -8
  103. package/dist/protonDrivePhotosClient.js +8 -9
  104. package/dist/protonDrivePhotosClient.js.map +1 -1
  105. package/dist/protonDrivePublicLinkClient.d.ts +9 -2
  106. package/dist/protonDrivePublicLinkClient.js +16 -5
  107. package/dist/protonDrivePublicLinkClient.js.map +1 -1
  108. package/dist/transformers.d.ts +7 -2
  109. package/dist/transformers.js +37 -0
  110. package/dist/transformers.js.map +1 -1
  111. package/package.json +1 -1
  112. package/src/interface/index.ts +1 -0
  113. package/src/interface/nodes.ts +14 -11
  114. package/src/interface/photos.ts +67 -0
  115. package/src/internal/apiService/apiService.ts +2 -2
  116. package/src/internal/apiService/driveTypes.ts +1294 -517
  117. package/src/internal/apiService/errors.ts +5 -4
  118. package/src/internal/download/cryptoService.ts +13 -6
  119. package/src/internal/download/fileDownloader.ts +4 -2
  120. package/src/internal/download/index.ts +3 -0
  121. package/src/internal/errors.ts +4 -0
  122. package/src/internal/nodes/apiService.test.ts +7 -5
  123. package/src/internal/nodes/apiService.ts +210 -124
  124. package/src/internal/nodes/cache.test.ts +1 -0
  125. package/src/internal/nodes/cache.ts +32 -13
  126. package/src/internal/nodes/cryptoReporter.ts +3 -3
  127. package/src/internal/nodes/cryptoService.test.ts +380 -18
  128. package/src/internal/nodes/cryptoService.ts +77 -36
  129. package/src/internal/nodes/events.ts +2 -2
  130. package/src/internal/nodes/index.test.ts +1 -0
  131. package/src/internal/nodes/interface.ts +17 -2
  132. package/src/internal/nodes/nodesAccess.ts +99 -54
  133. package/src/internal/nodes/nodesManagement.test.ts +69 -14
  134. package/src/internal/nodes/nodesManagement.ts +94 -48
  135. package/src/internal/nodes/nodesRevisions.ts +3 -3
  136. package/src/internal/photos/albums.ts +2 -2
  137. package/src/internal/photos/index.ts +45 -3
  138. package/src/internal/photos/interface.ts +21 -9
  139. package/src/internal/photos/nodes.ts +233 -0
  140. package/src/internal/photos/timeline.test.ts +2 -2
  141. package/src/internal/photos/timeline.ts +2 -2
  142. package/src/internal/photos/upload.ts +3 -3
  143. package/src/internal/sharingPublic/index.ts +7 -3
  144. package/src/internal/sharingPublic/nodes.ts +43 -2
  145. package/src/internal/sharingPublic/unauthApiService.test.ts +29 -0
  146. package/src/internal/sharingPublic/unauthApiService.ts +32 -0
  147. package/src/internal/upload/apiService.ts +4 -3
  148. package/src/internal/upload/cryptoService.ts +73 -12
  149. package/src/internal/upload/fileUploader.test.ts +1 -1
  150. package/src/internal/upload/interface.ts +24 -13
  151. package/src/internal/upload/manager.test.ts +5 -4
  152. package/src/internal/upload/manager.ts +7 -4
  153. package/src/internal/upload/streamUploader.test.ts +8 -5
  154. package/src/internal/upload/streamUploader.ts +10 -4
  155. package/src/protonDriveClient.ts +27 -5
  156. package/src/protonDrivePhotosClient.ts +23 -23
  157. package/src/protonDrivePublicLinkClient.ts +19 -3
  158. package/src/transformers.ts +49 -2
@@ -1,7 +1,14 @@
1
1
  import { DriveCrypto, PrivateKey, SessionKey, VERIFICATION_STATUS } from '../../crypto';
2
2
  import { MemberRole, ProtonDriveAccount, ProtonDriveTelemetry, RevisionState } from '../../interface';
3
3
  import { getMockTelemetry } from '../../tests/telemetry';
4
- import { DecryptedNode, DecryptedNodeKeys, DecryptedUnparsedNode, EncryptedNode, SharesService } from './interface';
4
+ import {
5
+ DecryptedNode,
6
+ DecryptedNodeKeys,
7
+ DecryptedUnparsedNode,
8
+ EncryptedNode,
9
+ NodeSigningKeys,
10
+ SharesService,
11
+ } from './interface';
5
12
  import { NodesCryptoService } from './cryptoService';
6
13
  import { NodesCryptoReporter } from './cryptoReporter';
7
14
 
@@ -250,6 +257,48 @@ describe('nodesCryptoService', () => {
250
257
  });
251
258
  });
252
259
 
260
+ it('on older node name ignores NOT_SIGNED', async () => {
261
+ encryptedNode.creationTime = new Date('2020-12-31');
262
+ driveCrypto.decryptNodeName = jest.fn(async () =>
263
+ Promise.resolve({
264
+ name: 'name',
265
+ verified: VERIFICATION_STATUS.NOT_SIGNED,
266
+ verificationErrors: [new Error('missing signature')],
267
+ }),
268
+ );
269
+
270
+ const result = await cryptoService.decryptNode(encryptedNode, parentKey);
271
+ verifyResult(result, {
272
+ nameAuthor: {
273
+ ok: true,
274
+ value: 'nameSignatureEmail',
275
+ },
276
+ });
277
+ expect(telemetry.recordMetric).not.toHaveBeenCalled();
278
+ });
279
+
280
+ it('on newer node name does not ignore NOT_SIGNED', async () => {
281
+ encryptedNode.creationTime = new Date('2021-01-01');
282
+ driveCrypto.decryptNodeName = jest.fn(async () =>
283
+ Promise.resolve({
284
+ name: 'name',
285
+ verified: VERIFICATION_STATUS.NOT_SIGNED,
286
+ verificationErrors: [new Error('missing signature')],
287
+ }),
288
+ );
289
+
290
+ const result = await cryptoService.decryptNode(encryptedNode, parentKey);
291
+ verifyResult(result, {
292
+ nameAuthor: {
293
+ ok: false,
294
+ error: {
295
+ claimedAuthor: 'nameSignatureEmail',
296
+ error: 'Missing signature for name',
297
+ },
298
+ },
299
+ });
300
+ });
301
+
253
302
  it('on hash key', async () => {
254
303
  driveCrypto.decryptNodeHashKey = jest.fn(async () =>
255
304
  Promise.resolve({
@@ -275,6 +324,48 @@ describe('nodesCryptoService', () => {
275
324
  });
276
325
  });
277
326
 
327
+ it('on older node hash key ignores NOT_SIGNED', async () => {
328
+ encryptedNode.creationTime = new Date('2021-07-31');
329
+ driveCrypto.decryptNodeHashKey = jest.fn(async () =>
330
+ Promise.resolve({
331
+ hashKey: new Uint8Array(),
332
+ verified: VERIFICATION_STATUS.NOT_SIGNED,
333
+ verificationErrors: [new Error('missing signature')],
334
+ }),
335
+ );
336
+
337
+ const result = await cryptoService.decryptNode(encryptedNode, parentKey);
338
+ verifyResult(result, {
339
+ keyAuthor: {
340
+ ok: true,
341
+ value: 'signatureEmail',
342
+ },
343
+ });
344
+ expect(telemetry.recordMetric).not.toHaveBeenCalled();
345
+ });
346
+
347
+ it('on newer node hash key does not ignore NOT_SIGNED', async () => {
348
+ encryptedNode.creationTime = new Date('2021-08-01');
349
+ driveCrypto.decryptNodeHashKey = jest.fn(async () =>
350
+ Promise.resolve({
351
+ hashKey: new Uint8Array(),
352
+ verified: VERIFICATION_STATUS.NOT_SIGNED,
353
+ verificationErrors: [new Error('missing signature')],
354
+ }),
355
+ );
356
+
357
+ const result = await cryptoService.decryptNode(encryptedNode, parentKey);
358
+ verifyResult(result, {
359
+ keyAuthor: {
360
+ ok: false,
361
+ error: {
362
+ claimedAuthor: 'signatureEmail',
363
+ error: 'Missing signature for hash key',
364
+ },
365
+ },
366
+ });
367
+ });
368
+
278
369
  it('on node key and hash key reports error from node key', async () => {
279
370
  driveCrypto.decryptKey = jest.fn(async () =>
280
371
  Promise.resolve({
@@ -985,24 +1076,239 @@ describe('nodesCryptoService', () => {
985
1076
  });
986
1077
  });
987
1078
 
1079
+ describe('createFolder', () => {
1080
+ let parentKeys: any;
1081
+
1082
+ beforeEach(() => {
1083
+ parentKeys = {
1084
+ key: 'parentKey' as any,
1085
+ hashKey: new Uint8Array([1, 2, 3]),
1086
+ };
1087
+ driveCrypto.generateKey = jest.fn().mockResolvedValue({
1088
+ encrypted: {
1089
+ armoredKey: 'encryptedNodeKey',
1090
+ armoredPassphrase: 'encryptedPassphrase',
1091
+ armoredPassphraseSignature: 'passphraseSignature',
1092
+ },
1093
+ decrypted: {
1094
+ key: 'nodeKey' as any,
1095
+ passphrase: 'nodePassphrase',
1096
+ passphraseSessionKey: 'passphraseSessionKey' as any,
1097
+ },
1098
+ });
1099
+ driveCrypto.encryptNodeName = jest.fn().mockResolvedValue({
1100
+ armoredNodeName: 'encryptedNodeName',
1101
+ });
1102
+ driveCrypto.generateLookupHash = jest.fn().mockResolvedValue('lookupHash');
1103
+ driveCrypto.generateHashKey = jest.fn().mockResolvedValue({
1104
+ armoredHashKey: 'encryptedHashKey',
1105
+ hashKey: new Uint8Array([4, 5, 6]),
1106
+ });
1107
+ driveCrypto.encryptExtendedAttributes = jest.fn().mockResolvedValue({
1108
+ armoredExtendedAttributes: 'encryptedAttributes',
1109
+ });
1110
+ });
1111
+
1112
+ it('should encrypt new folder with account key', async () => {
1113
+ const signingKeys: NodeSigningKeys = {
1114
+ type: 'userAddress',
1115
+ email: 'test@example.com',
1116
+ addressId: 'addressId',
1117
+ key: 'addressKey' as any,
1118
+ };
1119
+
1120
+ const result = await cryptoService.createFolder(
1121
+ parentKeys,
1122
+ signingKeys,
1123
+ 'New Folder',
1124
+ '{"modificationTime": 1234567890}',
1125
+ );
1126
+
1127
+ expect(result).toEqual({
1128
+ encryptedCrypto: {
1129
+ encryptedName: 'encryptedNodeName',
1130
+ hash: 'lookupHash',
1131
+ armoredKey: 'encryptedNodeKey',
1132
+ armoredNodePassphrase: 'encryptedPassphrase',
1133
+ armoredNodePassphraseSignature: 'passphraseSignature',
1134
+ folder: {
1135
+ armoredExtendedAttributes: 'encryptedAttributes',
1136
+ armoredHashKey: 'encryptedHashKey',
1137
+ },
1138
+ signatureEmail: 'test@example.com',
1139
+ nameSignatureEmail: 'test@example.com',
1140
+ },
1141
+ keys: {
1142
+ passphrase: 'nodePassphrase',
1143
+ key: 'nodeKey',
1144
+ passphraseSessionKey: 'passphraseSessionKey',
1145
+ hashKey: new Uint8Array([4, 5, 6]),
1146
+ },
1147
+ });
1148
+
1149
+ expect(driveCrypto.generateKey).toHaveBeenCalledWith([parentKeys.key], signingKeys.key);
1150
+ expect(driveCrypto.encryptNodeName).toHaveBeenCalledWith(
1151
+ 'New Folder',
1152
+ undefined,
1153
+ parentKeys.key,
1154
+ signingKeys.key,
1155
+ );
1156
+ expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('New Folder', parentKeys.hashKey);
1157
+ expect(driveCrypto.generateHashKey).toHaveBeenCalledWith('nodeKey');
1158
+ expect(driveCrypto.encryptExtendedAttributes).toHaveBeenCalledWith(
1159
+ '{"modificationTime": 1234567890}',
1160
+ 'nodeKey',
1161
+ signingKeys.key,
1162
+ );
1163
+ });
1164
+
1165
+ it('should encrypt new folder with node key', async () => {
1166
+ const signingKeys: NodeSigningKeys = {
1167
+ type: 'nodeKey',
1168
+ nodeKey: 'nodeSigningKey' as any,
1169
+ parentNodeKey: 'parentNodeKey' as any,
1170
+ };
1171
+
1172
+ const result = await cryptoService.createFolder(
1173
+ parentKeys,
1174
+ signingKeys,
1175
+ 'New Folder',
1176
+ '{"modificationTime": 1234567890}',
1177
+ );
1178
+
1179
+ expect(result).toEqual({
1180
+ encryptedCrypto: {
1181
+ encryptedName: 'encryptedNodeName',
1182
+ hash: 'lookupHash',
1183
+ armoredKey: 'encryptedNodeKey',
1184
+ armoredNodePassphrase: 'encryptedPassphrase',
1185
+ armoredNodePassphraseSignature: 'passphraseSignature',
1186
+ folder: {
1187
+ armoredExtendedAttributes: 'encryptedAttributes',
1188
+ armoredHashKey: 'encryptedHashKey',
1189
+ },
1190
+ signatureEmail: null,
1191
+ nameSignatureEmail: null,
1192
+ },
1193
+ keys: {
1194
+ passphrase: 'nodePassphrase',
1195
+ key: 'nodeKey',
1196
+ passphraseSessionKey: 'passphraseSessionKey',
1197
+ hashKey: new Uint8Array([4, 5, 6]),
1198
+ },
1199
+ });
1200
+
1201
+ expect(driveCrypto.generateKey).toHaveBeenCalledWith([parentKeys.key], signingKeys.parentNodeKey);
1202
+ expect(driveCrypto.encryptNodeName).toHaveBeenCalledWith(
1203
+ 'New Folder',
1204
+ undefined,
1205
+ parentKeys.key,
1206
+ signingKeys.parentNodeKey,
1207
+ );
1208
+ expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('New Folder', parentKeys.hashKey);
1209
+ expect(driveCrypto.generateHashKey).toHaveBeenCalledWith('nodeKey');
1210
+ expect(driveCrypto.encryptExtendedAttributes).toHaveBeenCalledWith(
1211
+ '{"modificationTime": 1234567890}',
1212
+ 'nodeKey',
1213
+ signingKeys.nodeKey,
1214
+ );
1215
+ });
1216
+ });
1217
+
1218
+ describe('encryptNewName', () => {
1219
+ let parentKeys: any;
1220
+ let nodeNameSessionKey: SessionKey;
1221
+
1222
+ beforeEach(() => {
1223
+ parentKeys = {
1224
+ key: 'parentKey' as any,
1225
+ hashKey: new Uint8Array([1, 2, 3]),
1226
+ };
1227
+ nodeNameSessionKey = 'nameSessionKey' as any;
1228
+ driveCrypto.encryptNodeName = jest.fn().mockResolvedValue({
1229
+ armoredNodeName: 'encryptedNewNodeName',
1230
+ });
1231
+ driveCrypto.generateLookupHash = jest.fn().mockResolvedValue('newHash');
1232
+ });
1233
+
1234
+ it('should encrypt new name with account key', async () => {
1235
+ const signingKeys: NodeSigningKeys = {
1236
+ type: 'userAddress',
1237
+ email: 'test@example.com',
1238
+ addressId: 'addressId',
1239
+ key: 'addressKey' as any,
1240
+ };
1241
+
1242
+ const result = await cryptoService.encryptNewName(
1243
+ parentKeys,
1244
+ nodeNameSessionKey,
1245
+ signingKeys,
1246
+ 'Renamed File.txt',
1247
+ );
1248
+
1249
+ expect(result).toEqual({
1250
+ signatureEmail: 'test@example.com',
1251
+ armoredNodeName: 'encryptedNewNodeName',
1252
+ hash: 'newHash',
1253
+ });
1254
+
1255
+ expect(driveCrypto.encryptNodeName).toHaveBeenCalledWith(
1256
+ 'Renamed File.txt',
1257
+ nodeNameSessionKey,
1258
+ parentKeys.key,
1259
+ signingKeys.key,
1260
+ );
1261
+ expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('Renamed File.txt', parentKeys.hashKey);
1262
+ });
1263
+
1264
+ it('should encrypt new name with node key', async () => {
1265
+ const signingKeys: NodeSigningKeys = {
1266
+ type: 'nodeKey',
1267
+ nodeKey: 'nodeSigningKey' as any,
1268
+ parentNodeKey: 'parentNodeKey' as any,
1269
+ };
1270
+
1271
+ const result = await cryptoService.encryptNewName(
1272
+ parentKeys,
1273
+ nodeNameSessionKey,
1274
+ signingKeys,
1275
+ 'Renamed File.txt',
1276
+ );
1277
+
1278
+ expect(result).toEqual({
1279
+ signatureEmail: null,
1280
+ armoredNodeName: 'encryptedNewNodeName',
1281
+ hash: 'newHash',
1282
+ });
1283
+
1284
+ expect(driveCrypto.encryptNodeName).toHaveBeenCalledWith(
1285
+ 'Renamed File.txt',
1286
+ nodeNameSessionKey,
1287
+ parentKeys.key,
1288
+ signingKeys.parentNodeKey,
1289
+ );
1290
+ expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('Renamed File.txt', parentKeys.hashKey);
1291
+ });
1292
+ });
1293
+
988
1294
  describe('encryptNodeWithNewParent', () => {
989
- it('should encrypt node data for move operation', async () => {
990
- const node = {
1295
+ let node: DecryptedNode;
1296
+ let keys: any;
1297
+ let parentKeys: any;
1298
+
1299
+ beforeEach(() => {
1300
+ node = {
991
1301
  name: { ok: true, value: 'testFile.txt' },
992
1302
  } as DecryptedNode;
993
- const keys = {
1303
+ keys = {
994
1304
  passphrase: 'nodePassphrase',
995
1305
  passphraseSessionKey: 'nodePassphraseSessionKey',
996
1306
  nameSessionKey: 'nameSessionKey' as any,
997
1307
  };
998
- const parentKeys = {
1308
+ parentKeys = {
999
1309
  key: 'newParentKey' as any,
1000
1310
  hashKey: new Uint8Array([1, 2, 3]),
1001
1311
  };
1002
- const address = {
1003
- email: 'test@example.com',
1004
- addressKey: 'addressKey' as any,
1005
- };
1006
1312
  driveCrypto.encryptNodeName = jest.fn().mockResolvedValue({
1007
1313
  armoredNodeName: 'encryptedNodeName',
1008
1314
  });
@@ -1011,8 +1317,22 @@ describe('nodesCryptoService', () => {
1011
1317
  armoredPassphrase: 'encryptedPassphrase',
1012
1318
  armoredPassphraseSignature: 'passphraseSignature',
1013
1319
  });
1320
+ });
1321
+
1322
+ it('should encrypt node data for move operation with account key (logged in context)', async () => {
1323
+ const signingKeys: NodeSigningKeys = {
1324
+ type: 'userAddress',
1325
+ email: 'test@example.com',
1326
+ addressId: 'addressId',
1327
+ key: 'addressKey' as any,
1328
+ };
1014
1329
 
1015
- const result = await cryptoService.encryptNodeWithNewParent(node, keys as any, parentKeys, address);
1330
+ const result = await cryptoService.encryptNodeWithNewParent(
1331
+ node.name,
1332
+ keys as any,
1333
+ parentKeys,
1334
+ signingKeys,
1335
+ );
1016
1336
 
1017
1337
  expect(result).toEqual({
1018
1338
  encryptedName: 'encryptedNodeName',
@@ -1027,14 +1347,52 @@ describe('nodesCryptoService', () => {
1027
1347
  'testFile.txt',
1028
1348
  keys.nameSessionKey,
1029
1349
  parentKeys.key,
1030
- address.addressKey,
1350
+ signingKeys.key,
1351
+ );
1352
+ expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('testFile.txt', parentKeys.hashKey);
1353
+ expect(driveCrypto.encryptPassphrase).toHaveBeenCalledWith(
1354
+ keys.passphrase,
1355
+ keys.passphraseSessionKey,
1356
+ [parentKeys.key],
1357
+ signingKeys.key,
1358
+ );
1359
+ });
1360
+
1361
+ it('should encrypt node data for move operation with node key (anonymous context)', async () => {
1362
+ const signingKeys: NodeSigningKeys = {
1363
+ type: 'nodeKey',
1364
+ nodeKey: 'addressKey' as any,
1365
+ parentNodeKey: 'parentNodeKey' as any,
1366
+ };
1367
+
1368
+ const result = await cryptoService.encryptNodeWithNewParent(
1369
+ node.name,
1370
+ keys as any,
1371
+ parentKeys,
1372
+ signingKeys,
1373
+ );
1374
+
1375
+ expect(result).toEqual({
1376
+ encryptedName: 'encryptedNodeName',
1377
+ hash: 'newHash',
1378
+ armoredNodePassphrase: 'encryptedPassphrase',
1379
+ armoredNodePassphraseSignature: 'passphraseSignature',
1380
+ signatureEmail: null,
1381
+ nameSignatureEmail: null,
1382
+ });
1383
+
1384
+ expect(driveCrypto.encryptNodeName).toHaveBeenCalledWith(
1385
+ 'testFile.txt',
1386
+ keys.nameSessionKey,
1387
+ parentKeys.key,
1388
+ signingKeys.nodeKey,
1031
1389
  );
1032
1390
  expect(driveCrypto.generateLookupHash).toHaveBeenCalledWith('testFile.txt', parentKeys.hashKey);
1033
1391
  expect(driveCrypto.encryptPassphrase).toHaveBeenCalledWith(
1034
1392
  keys.passphrase,
1035
1393
  keys.passphraseSessionKey,
1036
1394
  [parentKeys.key],
1037
- address.addressKey,
1395
+ signingKeys.nodeKey,
1038
1396
  );
1039
1397
  });
1040
1398
 
@@ -1051,13 +1409,15 @@ describe('nodesCryptoService', () => {
1051
1409
  key: 'newParentKey' as any,
1052
1410
  hashKey: undefined,
1053
1411
  } as any;
1054
- const address = {
1412
+ const signingKeys: NodeSigningKeys = {
1413
+ type: 'userAddress',
1055
1414
  email: 'test@example.com',
1056
- addressKey: 'addressKey' as any,
1415
+ addressId: 'addressId',
1416
+ key: 'addressKey' as any,
1057
1417
  };
1058
1418
 
1059
1419
  await expect(
1060
- cryptoService.encryptNodeWithNewParent(node, keys as any, parentKeys, address),
1420
+ cryptoService.encryptNodeWithNewParent(node.name, keys as any, parentKeys, signingKeys),
1061
1421
  ).rejects.toThrow('Moving item to a non-folder is not allowed');
1062
1422
  });
1063
1423
 
@@ -1074,13 +1434,15 @@ describe('nodesCryptoService', () => {
1074
1434
  key: 'newParentKey' as any,
1075
1435
  hashKey: new Uint8Array([1, 2, 3]),
1076
1436
  };
1077
- const address = {
1437
+ const signingKeys: NodeSigningKeys = {
1438
+ type: 'userAddress',
1078
1439
  email: 'test@example.com',
1079
- addressKey: 'addressKey' as any,
1440
+ addressId: 'addressId',
1441
+ key: 'addressKey' as any,
1080
1442
  };
1081
1443
 
1082
1444
  await expect(
1083
- cryptoService.encryptNodeWithNewParent(node, keys as any, parentKeys, address),
1445
+ cryptoService.encryptNodeWithNewParent(node, keys as any, parentKeys, signingKeys),
1084
1446
  ).rejects.toThrow('Cannot move item without a valid name, please rename the item first');
1085
1447
  });
1086
1448
  });