@protontech/drive-sdk 0.1.1 → 0.2.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 (193) hide show
  1. package/dist/crypto/driveCrypto.d.ts +11 -0
  2. package/dist/crypto/driveCrypto.js +20 -7
  3. package/dist/crypto/driveCrypto.js.map +1 -1
  4. package/dist/crypto/interface.d.ts +10 -1
  5. package/dist/crypto/openPGPCrypto.d.ts +18 -2
  6. package/dist/crypto/openPGPCrypto.js +25 -6
  7. package/dist/crypto/openPGPCrypto.js.map +1 -1
  8. package/dist/diagnostic/telemetry.d.ts +1 -1
  9. package/dist/diagnostic/telemetry.js +1 -1
  10. package/dist/diagnostic/telemetry.js.map +1 -1
  11. package/dist/interface/download.d.ts +46 -0
  12. package/dist/interface/index.d.ts +2 -2
  13. package/dist/interface/index.js.map +1 -1
  14. package/dist/interface/nodes.d.ts +26 -1
  15. package/dist/interface/nodes.js.map +1 -1
  16. package/dist/interface/telemetry.d.ts +5 -2
  17. package/dist/interface/telemetry.js.map +1 -1
  18. package/dist/internal/apiService/apiService.js +1 -1
  19. package/dist/internal/apiService/apiService.js.map +1 -1
  20. package/dist/internal/apiService/driveTypes.d.ts +78 -165
  21. package/dist/internal/apiService/index.d.ts +1 -1
  22. package/dist/internal/apiService/index.js +2 -2
  23. package/dist/internal/apiService/index.js.map +1 -1
  24. package/dist/internal/apiService/transformers.d.ts +1 -1
  25. package/dist/internal/apiService/transformers.js +2 -2
  26. package/dist/internal/apiService/transformers.js.map +1 -1
  27. package/dist/internal/download/blockIndex.d.ts +11 -0
  28. package/dist/internal/download/blockIndex.js +35 -0
  29. package/dist/internal/download/blockIndex.js.map +1 -0
  30. package/dist/internal/download/blockIndex.test.d.ts +1 -0
  31. package/dist/internal/download/blockIndex.test.js +147 -0
  32. package/dist/internal/download/blockIndex.test.js.map +1 -0
  33. package/dist/internal/download/fileDownloader.d.ts +6 -2
  34. package/dist/internal/download/fileDownloader.js +83 -6
  35. package/dist/internal/download/fileDownloader.js.map +1 -1
  36. package/dist/internal/download/fileDownloader.test.js +69 -4
  37. package/dist/internal/download/fileDownloader.test.js.map +1 -1
  38. package/dist/internal/download/interface.d.ts +4 -4
  39. package/dist/internal/download/seekableStream.d.ts +80 -0
  40. package/dist/internal/download/seekableStream.js +163 -0
  41. package/dist/internal/download/seekableStream.js.map +1 -0
  42. package/dist/internal/download/seekableStream.test.d.ts +1 -0
  43. package/dist/internal/download/seekableStream.test.js +149 -0
  44. package/dist/internal/download/seekableStream.test.js.map +1 -0
  45. package/dist/internal/download/telemetry.js +1 -1
  46. package/dist/internal/download/telemetry.js.map +1 -1
  47. package/dist/internal/download/telemetry.test.js +7 -7
  48. package/dist/internal/download/telemetry.test.js.map +1 -1
  49. package/dist/internal/errors.d.ts +1 -1
  50. package/dist/internal/errors.js +7 -1
  51. package/dist/internal/errors.js.map +1 -1
  52. package/dist/internal/errors.test.js +44 -10
  53. package/dist/internal/errors.test.js.map +1 -1
  54. package/dist/internal/events/eventManager.d.ts +1 -0
  55. package/dist/internal/events/eventManager.js +9 -0
  56. package/dist/internal/events/eventManager.js.map +1 -1
  57. package/dist/internal/events/eventManager.test.js +53 -38
  58. package/dist/internal/events/eventManager.test.js.map +1 -1
  59. package/dist/internal/events/index.d.ts +4 -3
  60. package/dist/internal/events/index.js +38 -32
  61. package/dist/internal/events/index.js.map +1 -1
  62. package/dist/internal/nodes/apiService.js +16 -3
  63. package/dist/internal/nodes/apiService.js.map +1 -1
  64. package/dist/internal/nodes/apiService.test.js +43 -7
  65. package/dist/internal/nodes/apiService.test.js.map +1 -1
  66. package/dist/internal/nodes/cache.js +9 -2
  67. package/dist/internal/nodes/cache.js.map +1 -1
  68. package/dist/internal/nodes/cache.test.js +6 -1
  69. package/dist/internal/nodes/cache.test.js.map +1 -1
  70. package/dist/internal/nodes/cryptoService.d.ts +4 -1
  71. package/dist/internal/nodes/cryptoService.js +66 -16
  72. package/dist/internal/nodes/cryptoService.js.map +1 -1
  73. package/dist/internal/nodes/cryptoService.test.js +129 -46
  74. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  75. package/dist/internal/nodes/events.js +7 -7
  76. package/dist/internal/nodes/events.js.map +1 -1
  77. package/dist/internal/nodes/extendedAttributes.d.ts +2 -1
  78. package/dist/internal/nodes/extendedAttributes.js +27 -1
  79. package/dist/internal/nodes/extendedAttributes.js.map +1 -1
  80. package/dist/internal/nodes/extendedAttributes.test.js +59 -6
  81. package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
  82. package/dist/internal/nodes/index.test.js +1 -1
  83. package/dist/internal/nodes/index.test.js.map +1 -1
  84. package/dist/internal/nodes/interface.d.ts +18 -2
  85. package/dist/internal/nodes/nodesAccess.js +11 -1
  86. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  87. package/dist/internal/nodes/nodesManagement.js +1 -1
  88. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  89. package/dist/internal/nodes/nodesRevisions.d.ts +4 -3
  90. package/dist/internal/nodes/nodesRevisions.js +2 -2
  91. package/dist/internal/nodes/nodesRevisions.js.map +1 -1
  92. package/dist/internal/shares/cryptoService.js +7 -4
  93. package/dist/internal/shares/cryptoService.js.map +1 -1
  94. package/dist/internal/shares/cryptoService.test.js +5 -3
  95. package/dist/internal/shares/cryptoService.test.js.map +1 -1
  96. package/dist/internal/sharing/apiService.js +5 -5
  97. package/dist/internal/sharing/apiService.js.map +1 -1
  98. package/dist/internal/sharing/cache.d.ts +1 -0
  99. package/dist/internal/sharing/cache.js +9 -0
  100. package/dist/internal/sharing/cache.js.map +1 -1
  101. package/dist/internal/sharing/cryptoService.js +8 -5
  102. package/dist/internal/sharing/cryptoService.js.map +1 -1
  103. package/dist/internal/sharing/cryptoService.test.js +7 -4
  104. package/dist/internal/sharing/cryptoService.test.js.map +1 -1
  105. package/dist/internal/sharing/events.d.ts +1 -0
  106. package/dist/internal/sharing/events.js +28 -18
  107. package/dist/internal/sharing/events.js.map +1 -1
  108. package/dist/internal/sharing/events.test.js +98 -84
  109. package/dist/internal/sharing/events.test.js.map +1 -1
  110. package/dist/internal/upload/interface.d.ts +1 -0
  111. package/dist/internal/upload/manager.d.ts +1 -1
  112. package/dist/internal/upload/manager.js +8 -4
  113. package/dist/internal/upload/manager.js.map +1 -1
  114. package/dist/internal/upload/manager.test.js +7 -10
  115. package/dist/internal/upload/manager.test.js.map +1 -1
  116. package/dist/internal/upload/streamUploader.js +1 -1
  117. package/dist/internal/upload/streamUploader.js.map +1 -1
  118. package/dist/internal/upload/streamUploader.test.js +1 -1
  119. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  120. package/dist/internal/upload/telemetry.js +2 -2
  121. package/dist/internal/upload/telemetry.js.map +1 -1
  122. package/dist/internal/upload/telemetry.test.js +7 -7
  123. package/dist/internal/upload/telemetry.test.js.map +1 -1
  124. package/dist/protonDriveClient.js +2 -2
  125. package/dist/protonDriveClient.js.map +1 -1
  126. package/dist/telemetry.d.ts +2 -2
  127. package/dist/telemetry.js +2 -2
  128. package/dist/telemetry.js.map +1 -1
  129. package/dist/tests/telemetry.js +1 -1
  130. package/dist/tests/telemetry.js.map +1 -1
  131. package/dist/transformers.d.ts +1 -1
  132. package/dist/transformers.js +3 -1
  133. package/dist/transformers.js.map +1 -1
  134. package/package.json +1 -1
  135. package/src/crypto/driveCrypto.ts +70 -25
  136. package/src/crypto/interface.ts +15 -0
  137. package/src/crypto/openPGPCrypto.ts +37 -5
  138. package/src/diagnostic/telemetry.ts +1 -1
  139. package/src/interface/download.ts +46 -0
  140. package/src/interface/index.ts +2 -1
  141. package/src/interface/nodes.ts +28 -1
  142. package/src/interface/telemetry.ts +6 -1
  143. package/src/internal/apiService/apiService.ts +1 -1
  144. package/src/internal/apiService/driveTypes.ts +78 -165
  145. package/src/internal/apiService/index.ts +1 -1
  146. package/src/internal/apiService/transformers.ts +1 -1
  147. package/src/internal/download/blockIndex.test.ts +158 -0
  148. package/src/internal/download/blockIndex.ts +36 -0
  149. package/src/internal/download/fileDownloader.test.ts +100 -7
  150. package/src/internal/download/fileDownloader.ts +109 -9
  151. package/src/internal/download/interface.ts +4 -4
  152. package/src/internal/download/seekableStream.test.ts +187 -0
  153. package/src/internal/download/seekableStream.ts +182 -0
  154. package/src/internal/download/telemetry.test.ts +7 -7
  155. package/src/internal/download/telemetry.ts +1 -1
  156. package/src/internal/errors.test.ts +45 -11
  157. package/src/internal/errors.ts +8 -0
  158. package/src/internal/events/eventManager.test.ts +61 -40
  159. package/src/internal/events/eventManager.ts +10 -0
  160. package/src/internal/events/index.ts +53 -35
  161. package/src/internal/nodes/apiService.test.ts +59 -15
  162. package/src/internal/nodes/apiService.ts +21 -4
  163. package/src/internal/nodes/cache.test.ts +6 -1
  164. package/src/internal/nodes/cache.ts +9 -2
  165. package/src/internal/nodes/cryptoService.test.ts +139 -47
  166. package/src/internal/nodes/cryptoService.ts +94 -9
  167. package/src/internal/nodes/events.ts +6 -7
  168. package/src/internal/nodes/extendedAttributes.test.ts +60 -7
  169. package/src/internal/nodes/extendedAttributes.ts +37 -1
  170. package/src/internal/nodes/index.test.ts +1 -1
  171. package/src/internal/nodes/interface.ts +19 -2
  172. package/src/internal/nodes/nodesAccess.ts +15 -1
  173. package/src/internal/nodes/nodesManagement.ts +1 -1
  174. package/src/internal/nodes/nodesRevisions.ts +14 -5
  175. package/src/internal/shares/cryptoService.test.ts +5 -3
  176. package/src/internal/shares/cryptoService.ts +7 -4
  177. package/src/internal/sharing/apiService.ts +6 -6
  178. package/src/internal/sharing/cache.ts +9 -0
  179. package/src/internal/sharing/cryptoService.test.ts +7 -4
  180. package/src/internal/sharing/cryptoService.ts +8 -5
  181. package/src/internal/sharing/events.test.ts +104 -89
  182. package/src/internal/sharing/events.ts +33 -18
  183. package/src/internal/upload/interface.ts +1 -0
  184. package/src/internal/upload/manager.test.ts +7 -10
  185. package/src/internal/upload/manager.ts +7 -4
  186. package/src/internal/upload/streamUploader.test.ts +1 -1
  187. package/src/internal/upload/streamUploader.ts +1 -1
  188. package/src/internal/upload/telemetry.test.ts +7 -7
  189. package/src/internal/upload/telemetry.ts +2 -2
  190. package/src/protonDriveClient.ts +2 -2
  191. package/src/telemetry.ts +2 -2
  192. package/src/tests/telemetry.ts +1 -1
  193. package/src/transformers.ts +6 -2
@@ -21,7 +21,7 @@ const CORE_POLLING_INTERVAL = 30;
21
21
  */
22
22
  export class DriveEventsService {
23
23
  private apiService: EventsAPIService;
24
- private coreEvents?: EventManager<DriveEvent>;
24
+ private coreEventManager?: EventManager<DriveEvent>;
25
25
  private volumeEventManagers: { [volumeId: string]: EventManager<DriveEvent> };
26
26
  private logger: Logger;
27
27
 
@@ -38,20 +38,16 @@ export class DriveEventsService {
38
38
  this.volumeEventManagers = {};
39
39
  }
40
40
 
41
- /**
42
- * Subscribe to drive events. The treeEventScopeId can be obtained from a node.
43
- */
44
- async subscribeToTreeEvents(treeEventScopeId: string, callback: DriveListener): Promise<EventSubscription> {
45
- const volumeId = treeEventScopeId;
46
- this.logger.debug(`Creating volume event manager for volume ${volumeId}`);
47
- let manager = this.volumeEventManagers[volumeId];
48
- let started = true;
41
+ // FIXME: Allow to pass own core events manager from the public interface.
42
+ async subscribeToCoreEvents(callback: DriveListener): Promise<EventSubscription> {
43
+ let manager = this.coreEventManager;
44
+ const started = !!manager;
45
+
49
46
  if (manager === undefined) {
50
- manager = await this.createVolumeEventManager(volumeId);
51
- this.volumeEventManagers[volumeId] = manager;
52
- started = false;
53
- this.sendNumberOfVolumeSubscriptionsToTelemetry();
47
+ manager = await this.createCoreEventManager();
48
+ this.coreEventManager = manager;
54
49
  }
50
+
55
51
  const eventSubscription = manager.addListener(callback);
56
52
  if (!started) {
57
53
  await manager.start();
@@ -59,53 +55,75 @@ export class DriveEventsService {
59
55
  return eventSubscription;
60
56
  }
61
57
 
62
- // FIXME: Allow to pass own core events manager from the public interface.
63
- async subscribeToCoreEvents(callback: DriveListener): Promise<EventSubscription> {
64
- if (this.latestEventIdProvider === null || this.latestEventIdProvider === undefined) {
58
+ private async createCoreEventManager() {
59
+ if (!this.latestEventIdProvider) {
65
60
  throw new Error(
66
61
  'Cannot subscribe to events without passing a latestEventIdProvider in ProtonDriveClient initialization',
67
62
  );
68
63
  }
69
- if (this.coreEvents === undefined) {
70
- const coreEventManager = new CoreEventManager(this.logger, this.apiService);
71
- const latestEventId = this.latestEventIdProvider.getLatestEventId('core') ?? null;
72
- this.coreEvents = new EventManager(coreEventManager, CORE_POLLING_INTERVAL, latestEventId);
73
- for (const listener of this.cacheEventListeners) {
74
- this.coreEvents.addListener(listener);
75
- }
64
+
65
+ const coreEventManager = new CoreEventManager(this.logger, this.apiService);
66
+ const latestEventId = this.latestEventIdProvider.getLatestEventId('core') ?? null;
67
+ const eventManager = new EventManager(coreEventManager, CORE_POLLING_INTERVAL, latestEventId);
68
+
69
+ for (const listener of this.cacheEventListeners) {
70
+ eventManager.addListener(listener);
76
71
  }
77
- const eventSubscription = this.coreEvents.addListener(callback);
78
- await this.coreEvents.start();
79
- return eventSubscription;
72
+
73
+ return eventManager;
80
74
  }
81
75
 
82
- private sendNumberOfVolumeSubscriptionsToTelemetry() {
83
- this.telemetry.logEvent({
84
- eventName: 'volumeEventsSubscriptionsChanged',
85
- numberOfVolumeSubscriptions: Object.keys(this.volumeEventManagers).length,
86
- });
76
+ /**
77
+ * Subscribe to drive events. The treeEventScopeId can be obtained from a node.
78
+ */
79
+ async subscribeToTreeEvents(treeEventScopeId: string, callback: DriveListener): Promise<EventSubscription> {
80
+ const volumeId = treeEventScopeId;
81
+ let manager = this.volumeEventManagers[volumeId];
82
+ const started = !!manager;
83
+
84
+ if (manager === undefined) {
85
+ manager = await this.createVolumeEventManager(volumeId);
86
+ this.volumeEventManagers[volumeId] = manager;
87
+ }
88
+
89
+ const eventSubscription = manager.addListener(callback);
90
+ if (!started) {
91
+ await manager.start();
92
+ this.sendNumberOfVolumeSubscriptionsToTelemetry();
93
+ }
94
+ return eventSubscription;
87
95
  }
88
96
 
89
97
  private async createVolumeEventManager(volumeId: string): Promise<EventManager<DriveEvent>> {
90
- if (this.latestEventIdProvider === null || this.latestEventIdProvider === undefined) {
98
+ if (!this.latestEventIdProvider) {
91
99
  throw new Error(
92
100
  'Cannot subscribe to events without passing a latestEventIdProvider in ProtonDriveClient initialization',
93
101
  );
94
102
  }
103
+
104
+ this.logger.debug(`Creating volume event manager for volume ${volumeId}`);
105
+ const volumeEventManager = new VolumeEventManager(this.logger, this.apiService, volumeId);
106
+
95
107
  const isOwnVolume = await this.shareManagement.isOwnVolume(volumeId);
96
108
  const pollingInterval = this.getDefaultVolumePollingInterval(isOwnVolume);
97
- const volumeEventManager = new VolumeEventManager(this.logger, this.apiService, volumeId);
98
109
  const latestEventId = this.latestEventIdProvider.getLatestEventId(volumeId);
99
110
  const eventManager = new EventManager<DriveEvent>(volumeEventManager, pollingInterval, latestEventId);
111
+
100
112
  for (const listener of this.cacheEventListeners) {
101
113
  eventManager.addListener(listener);
102
114
  }
103
- await eventManager.start();
104
- this.volumeEventManagers[volumeId] = eventManager;
115
+
105
116
  return eventManager;
106
117
  }
107
118
 
108
119
  private getDefaultVolumePollingInterval(isOwnVolume: boolean): number {
109
120
  return isOwnVolume ? OWN_VOLUME_POLLING_INTERVAL : OTHER_VOLUME_POLLING_INTERVAL;
110
121
  }
122
+
123
+ private sendNumberOfVolumeSubscriptionsToTelemetry() {
124
+ this.telemetry.recordMetric({
125
+ eventName: 'volumeEventsSubscriptionsChanged',
126
+ numberOfVolumeSubscriptions: Object.keys(this.volumeEventManagers).length,
127
+ });
128
+ }
111
129
  }
@@ -76,7 +76,7 @@ function generateAPINode() {
76
76
  };
77
77
  }
78
78
 
79
- function generateFileNode(overrides = {}) {
79
+ function generateFileNode(overrides = {}, encryptedCryptoOverrides = {}) {
80
80
  const node = generateNode();
81
81
  return {
82
82
  ...node,
@@ -98,12 +98,13 @@ function generateFileNode(overrides = {}) {
98
98
  armoredExtendedAttributes: '{file}',
99
99
  thumbnails: [],
100
100
  },
101
+ ...encryptedCryptoOverrides,
101
102
  },
102
103
  ...overrides,
103
104
  };
104
105
  }
105
106
 
106
- function generateFolderNode(overrides = {}) {
107
+ function generateFolderNode(overrides = {}, encryptedCryptoOverrides = {}) {
107
108
  const node = generateNode();
108
109
  return {
109
110
  ...node,
@@ -114,6 +115,7 @@ function generateFolderNode(overrides = {}) {
114
115
  armoredHashKey: 'nodeHashKey',
115
116
  armoredExtendedAttributes: '{folder}',
116
117
  },
118
+ ...encryptedCryptoOverrides,
117
119
  },
118
120
  ...overrides,
119
121
  };
@@ -140,7 +142,8 @@ function generateNode() {
140
142
 
141
143
  shareId: undefined,
142
144
  isShared: false,
143
- directMemberRole: MemberRole.Admin,
145
+ directRole: MemberRole.Admin,
146
+ membership: undefined,
144
147
 
145
148
  encryptedCrypto: {
146
149
  armoredKey: 'nodeKey',
@@ -148,6 +151,7 @@ function generateNode() {
148
151
  armoredNodePassphraseSignature: 'nodePassSig',
149
152
  nameSignatureEmail: 'nameSigEmail',
150
153
  signatureEmail: 'sigEmail',
154
+ membership: undefined,
151
155
  },
152
156
  };
153
157
  }
@@ -211,14 +215,34 @@ describe('nodeAPIService', () => {
211
215
  },
212
216
  Membership: {
213
217
  Permissions: 22,
218
+ InviteTime: 1234567890,
219
+ InviterEmail: 'inviterEmail',
220
+ MemberSharePassphraseKeyPacket: 'memberSharePassphraseKeyPacket',
221
+ InviterSharePassphraseKeyPacketSignature: 'inviterSharePassphraseKeyPacketSignature',
222
+ InviteeSharePassphraseSessionKeySignature: 'inviteeSharePassphraseSessionKeySignature',
223
+ },
224
+ },
225
+ ),
226
+ generateFolderNode(
227
+ {
228
+ isShared: true,
229
+ shareId: 'shareId',
230
+ directRole: MemberRole.Admin,
231
+ membership: {
232
+ role: MemberRole.Admin,
233
+ inviteTime: new Date(1234567890000),
234
+ },
235
+ },
236
+ {
237
+ membership: {
238
+ inviterEmail: 'inviterEmail',
239
+ base64MemberSharePassphraseKeyPacket: 'memberSharePassphraseKeyPacket',
240
+ armoredInviterSharePassphraseKeyPacketSignature: 'inviterSharePassphraseKeyPacketSignature',
241
+ armoredInviteeSharePassphraseSessionKeySignature:
242
+ 'inviteeSharePassphraseSessionKeySignature',
214
243
  },
215
244
  },
216
245
  ),
217
- generateFolderNode({
218
- isShared: true,
219
- shareId: 'shareId',
220
- directMemberRole: MemberRole.Admin,
221
- }),
222
246
  );
223
247
  });
224
248
 
@@ -232,14 +256,34 @@ describe('nodeAPIService', () => {
232
256
  },
233
257
  Membership: {
234
258
  Permissions: 42,
259
+ InviteTime: 1234567890,
260
+ InviterEmail: 'inviterEmail',
261
+ MemberSharePassphraseKeyPacket: 'memberSharePassphraseKeyPacket',
262
+ InviterSharePassphraseKeyPacketSignature: 'inviterSharePassphraseKeyPacketSignature',
263
+ InviteeSharePassphraseSessionKeySignature: 'inviteeSharePassphraseSessionKeySignature',
264
+ },
265
+ },
266
+ ),
267
+ generateFolderNode(
268
+ {
269
+ isShared: true,
270
+ shareId: 'shareId',
271
+ directRole: MemberRole.Viewer,
272
+ membership: {
273
+ role: MemberRole.Viewer,
274
+ inviteTime: new Date(1234567890000),
275
+ },
276
+ },
277
+ {
278
+ membership: {
279
+ inviterEmail: 'inviterEmail',
280
+ base64MemberSharePassphraseKeyPacket: 'memberSharePassphraseKeyPacket',
281
+ armoredInviterSharePassphraseKeyPacketSignature: 'inviterSharePassphraseKeyPacketSignature',
282
+ armoredInviteeSharePassphraseSessionKeySignature:
283
+ 'inviteeSharePassphraseSessionKeySignature',
235
284
  },
236
285
  },
237
286
  ),
238
- generateFolderNode({
239
- isShared: true,
240
- shareId: 'shareId',
241
- directMemberRole: MemberRole.Viewer,
242
- }),
243
287
  'myVolumeId',
244
288
  );
245
289
  });
@@ -308,12 +352,12 @@ describe('nodeAPIService', () => {
308
352
  generateFolderNode({
309
353
  uid: 'volumeId1~nodeId1',
310
354
  parentUid: 'volumeId1~parentNodeId1',
311
- directMemberRole: MemberRole.Admin,
355
+ directRole: MemberRole.Admin,
312
356
  }),
313
357
  generateFolderNode({
314
358
  uid: 'volumeId2~nodeId2',
315
359
  parentUid: 'volumeId2~parentNodeId2',
316
- directMemberRole: MemberRole.Inherited,
360
+ directRole: MemberRole.Inherited,
317
361
  }),
318
362
  ]);
319
363
  });
@@ -8,7 +8,7 @@ import {
8
8
  drivePaths,
9
9
  isCodeOk,
10
10
  nodeTypeNumberToNodeType,
11
- permissionsToDirectMemberRole,
11
+ permissionsToMemberRole,
12
12
  } from '../apiService';
13
13
  import { asyncIteratorRace } from '../asyncIteratorRace';
14
14
  import { batch } from '../batch';
@@ -471,6 +471,8 @@ function linkToEncryptedNode(
471
471
  link: PostLoadLinksMetadataResponse['Links'][0],
472
472
  isAdmin: boolean,
473
473
  ): EncryptedNode {
474
+ const membershipRole = permissionsToMemberRole(logger, link.Membership?.Permissions);
475
+
474
476
  const baseNodeMetadata = {
475
477
  // Internal metadata
476
478
  hash: link.Link.NameHash || undefined,
@@ -486,16 +488,31 @@ function linkToEncryptedNode(
486
488
  // Sharing node metadata
487
489
  shareId: link.Sharing?.ShareID || undefined,
488
490
  isShared: !!link.Sharing,
489
- directMemberRole: isAdmin
490
- ? MemberRole.Admin
491
- : permissionsToDirectMemberRole(logger, link.Membership?.Permissions),
491
+ directRole: isAdmin ? MemberRole.Admin : membershipRole,
492
+ membership: link.Membership
493
+ ? {
494
+ role: membershipRole,
495
+ inviteTime: new Date(link.Membership.InviteTime * 1000),
496
+ }
497
+ : undefined,
492
498
  };
499
+
493
500
  const baseCryptoNodeMetadata = {
494
501
  signatureEmail: link.Link.SignatureEmail || undefined,
495
502
  nameSignatureEmail: link.Link.NameSignatureEmail || undefined,
496
503
  armoredKey: link.Link.NodeKey,
497
504
  armoredNodePassphrase: link.Link.NodePassphrase,
498
505
  armoredNodePassphraseSignature: link.Link.NodePassphraseSignature,
506
+ membership: link.Membership
507
+ ? {
508
+ inviterEmail: link.Membership.InviterEmail,
509
+ base64MemberSharePassphraseKeyPacket: link.Membership.MemberSharePassphraseKeyPacket,
510
+ armoredInviterSharePassphraseKeyPacketSignature:
511
+ link.Membership.InviterSharePassphraseKeyPacketSignature,
512
+ armoredInviteeSharePassphraseSessionKeySignature:
513
+ link.Membership.InviteeSharePassphraseSessionKeySignature,
514
+ }
515
+ : undefined,
499
516
  };
500
517
 
501
518
  if (link.Link.Type === 1 && link.Folder) {
@@ -12,7 +12,12 @@ function generateNode(
12
12
  return {
13
13
  uid: `${params.volumeId || 'volumeId'}~:${uid}`,
14
14
  parentUid: `${params.volumeId || 'volumeId'}~:${parentUid}`,
15
- directMemberRole: MemberRole.Admin,
15
+ directRole: MemberRole.Admin,
16
+ membership: {
17
+ role: MemberRole.Admin,
18
+ inviteTime: new Date(),
19
+ sharedBy: resultOk('test@example.com'),
20
+ },
16
21
  type: NodeType.File,
17
22
  mediaType: 'text',
18
23
  isShared: false,
@@ -252,8 +252,9 @@ function deserialiseNode(nodeData: string): DecryptedNode {
252
252
  typeof node !== 'object' ||
253
253
  !node.uid ||
254
254
  typeof node.uid !== 'string' ||
255
- !node.directMemberRole ||
256
- typeof node.directMemberRole !== 'string' ||
255
+ !node.directRole ||
256
+ typeof node.directRole !== 'string' ||
257
+ (typeof node.membership !== 'object' && node.membership !== undefined) ||
257
258
  !node.type ||
258
259
  typeof node.type !== 'string' ||
259
260
  (typeof node.mediaType !== 'string' && node.mediaType !== undefined) ||
@@ -271,6 +272,12 @@ function deserialiseNode(nodeData: string): DecryptedNode {
271
272
  creationTime: new Date(node.creationTime),
272
273
  trashTime: node.trashTime ? new Date(node.trashTime) : undefined,
273
274
  activeRevision: node.activeRevision ? deserialiseRevision(node.activeRevision) : undefined,
275
+ membership: node.membership
276
+ ? {
277
+ ...node.membership,
278
+ inviteTime: new Date(node.membership.inviteTime),
279
+ }
280
+ : undefined,
274
281
  folder: node.folder
275
282
  ? {
276
283
  ...node.folder,