@protontech/drive-sdk 0.12.1 → 0.13.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.
- package/dist/crypto/driveCrypto.d.ts +1 -0
- package/dist/crypto/driveCrypto.js +1 -0
- package/dist/crypto/driveCrypto.js.map +1 -1
- package/dist/interface/featureFlags.d.ts +2 -1
- package/dist/interface/featureFlags.js +1 -0
- package/dist/interface/featureFlags.js.map +1 -1
- package/dist/interface/httpClient.d.ts +1 -0
- package/dist/interface/nodes.d.ts +7 -0
- package/dist/interface/nodes.js.map +1 -1
- package/dist/internal/apiService/apiService.d.ts +1 -0
- package/dist/internal/apiService/apiService.js +16 -7
- package/dist/internal/apiService/apiService.js.map +1 -1
- package/dist/internal/apiService/apiService.test.js +24 -0
- package/dist/internal/apiService/apiService.test.js.map +1 -1
- package/dist/internal/apiService/driveTypes.d.ts +110 -101
- package/dist/internal/nodes/apiService.d.ts +4 -0
- package/dist/internal/nodes/apiService.js +4 -0
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +8 -0
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/cryptoService.js +3 -0
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.d.ts +5 -5
- package/dist/internal/nodes/extendedAttributes.js +5 -14
- package/dist/internal/nodes/extendedAttributes.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.test.js +16 -22
- package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
- package/dist/internal/nodes/interface.d.ts +5 -0
- package/dist/internal/nodes/nodesManagement.d.ts +3 -3
- package/dist/internal/nodes/nodesManagement.js +7 -5
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/photos/albumsManager.js +1 -0
- package/dist/internal/photos/albumsManager.js.map +1 -1
- package/dist/internal/photos/nodes.d.ts +1 -1
- package/dist/internal/photos/nodes.js +2 -2
- package/dist/internal/photos/nodes.js.map +1 -1
- package/dist/internal/photos/upload.d.ts +5 -5
- package/dist/internal/photos/upload.js +8 -2
- package/dist/internal/photos/upload.js.map +1 -1
- package/dist/internal/sharingPublic/nodes.d.ts +1 -0
- package/dist/internal/upload/apiService.d.ts +45 -1
- package/dist/internal/upload/apiService.js +69 -1
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/blockVerifier.d.ts +4 -1
- package/dist/internal/upload/blockVerifier.js +5 -0
- package/dist/internal/upload/blockVerifier.js.map +1 -1
- package/dist/internal/upload/cryptoService.d.ts +2 -2
- package/dist/internal/upload/cryptoService.js +1 -3
- package/dist/internal/upload/cryptoService.js.map +1 -1
- package/dist/internal/upload/fileUploader.d.ts +4 -3
- package/dist/internal/upload/fileUploader.js +17 -7
- package/dist/internal/upload/fileUploader.js.map +1 -1
- package/dist/internal/upload/index.d.ts +3 -3
- package/dist/internal/upload/index.js +17 -1
- package/dist/internal/upload/index.js.map +1 -1
- package/dist/internal/upload/index.test.d.ts +1 -0
- package/dist/internal/upload/index.test.js +71 -0
- package/dist/internal/upload/index.test.js.map +1 -0
- package/dist/internal/upload/interface.d.ts +2 -0
- package/dist/internal/upload/manager.d.ts +41 -2
- package/dist/internal/upload/manager.js +123 -42
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +267 -0
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/smallFileUploader.d.ts +83 -0
- package/dist/internal/upload/smallFileUploader.js +197 -0
- package/dist/internal/upload/smallFileUploader.js.map +1 -0
- package/dist/internal/upload/smallFileUploader.test.d.ts +1 -0
- package/dist/internal/upload/smallFileUploader.test.js +358 -0
- package/dist/internal/upload/smallFileUploader.test.js.map +1 -0
- package/dist/internal/upload/streamReader.d.ts +4 -0
- package/dist/internal/upload/streamReader.js +37 -0
- package/dist/internal/upload/streamReader.js.map +1 -0
- package/dist/internal/upload/streamReader.test.d.ts +1 -0
- package/dist/internal/upload/streamReader.test.js +90 -0
- package/dist/internal/upload/streamReader.test.js.map +1 -0
- package/dist/internal/upload/streamUploader.d.ts +6 -0
- package/dist/internal/upload/streamUploader.js +3 -3
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/telemetry.d.ts +3 -2
- package/dist/internal/upload/telemetry.js +3 -0
- package/dist/internal/upload/telemetry.js.map +1 -1
- package/dist/protonDrivePhotosClient.d.ts +1 -1
- package/dist/protonDrivePublicLinkClient.js +3 -1
- package/dist/protonDrivePublicLinkClient.js.map +1 -1
- package/dist/transformers.d.ts +1 -1
- package/dist/transformers.js +1 -0
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/crypto/driveCrypto.ts +2 -0
- package/src/interface/featureFlags.ts +1 -0
- package/src/interface/httpClient.ts +1 -0
- package/src/interface/nodes.ts +7 -0
- package/src/internal/apiService/apiService.test.ts +30 -0
- package/src/internal/apiService/apiService.ts +23 -7
- package/src/internal/apiService/driveTypes.ts +110 -101
- package/src/internal/nodes/apiService.test.ts +9 -0
- package/src/internal/nodes/apiService.ts +4 -0
- package/src/internal/nodes/cryptoService.ts +11 -1
- package/src/internal/nodes/extendedAttributes.test.ts +25 -25
- package/src/internal/nodes/extendedAttributes.ts +10 -19
- package/src/internal/nodes/interface.ts +5 -0
- package/src/internal/nodes/nodesManagement.ts +8 -6
- package/src/internal/photos/albumsManager.ts +1 -0
- package/src/internal/photos/nodes.ts +2 -2
- package/src/internal/photos/upload.ts +23 -10
- package/src/internal/upload/apiService.ts +167 -2
- package/src/internal/upload/blockVerifier.ts +12 -0
- package/src/internal/upload/cryptoService.ts +10 -10
- package/src/internal/upload/fileUploader.ts +20 -7
- package/src/internal/upload/index.test.ts +99 -0
- package/src/internal/upload/index.ts +45 -4
- package/src/internal/upload/interface.ts +2 -0
- package/src/internal/upload/manager.test.ts +367 -1
- package/src/internal/upload/manager.ts +226 -76
- package/src/internal/upload/smallFileUploader.test.ts +491 -0
- package/src/internal/upload/smallFileUploader.ts +353 -0
- package/src/internal/upload/streamReader.test.ts +109 -0
- package/src/internal/upload/streamReader.ts +38 -0
- package/src/internal/upload/streamUploader.ts +1 -1
- package/src/internal/upload/telemetry.ts +5 -1
- package/src/protonDrivePhotosClient.ts +1 -1
- package/src/protonDrivePublicLinkClient.ts +2 -0
- package/src/transformers.ts +2 -0
|
@@ -1392,7 +1392,7 @@ export interface paths {
|
|
|
1392
1392
|
put?: never;
|
|
1393
1393
|
/**
|
|
1394
1394
|
* Request block upload
|
|
1395
|
-
* @description Request upload
|
|
1395
|
+
* @description Request upload URLs for a set of blocks/thumbnails of a given draft revision.
|
|
1396
1396
|
*/
|
|
1397
1397
|
post: operations["post_drive-blocks"];
|
|
1398
1398
|
delete?: never;
|
|
@@ -1410,10 +1410,7 @@ export interface paths {
|
|
|
1410
1410
|
};
|
|
1411
1411
|
get?: never;
|
|
1412
1412
|
put?: never;
|
|
1413
|
-
/**
|
|
1414
|
-
* Upload small file
|
|
1415
|
-
* @description This does not support anonymous uploads (yet)
|
|
1416
|
-
*/
|
|
1413
|
+
/** Upload small file */
|
|
1417
1414
|
post: operations["post_drive-v2-volumes-{volumeID}-files-small"];
|
|
1418
1415
|
delete?: never;
|
|
1419
1416
|
options?: never;
|
|
@@ -1430,10 +1427,7 @@ export interface paths {
|
|
|
1430
1427
|
};
|
|
1431
1428
|
get?: never;
|
|
1432
1429
|
put?: never;
|
|
1433
|
-
/**
|
|
1434
|
-
* Upload small revision
|
|
1435
|
-
* @description This does not support anonymous uploads (yet)
|
|
1436
|
-
*/
|
|
1430
|
+
/** Upload small revision */
|
|
1437
1431
|
post: operations["post_drive-v2-volumes-{volumeID}-files-{linkID}-revisions-small"];
|
|
1438
1432
|
delete?: never;
|
|
1439
1433
|
options?: never;
|
|
@@ -2148,7 +2142,10 @@ export interface paths {
|
|
|
2148
2142
|
path?: never;
|
|
2149
2143
|
cookie?: never;
|
|
2150
2144
|
};
|
|
2151
|
-
/**
|
|
2145
|
+
/**
|
|
2146
|
+
* List URLs on share
|
|
2147
|
+
* @description There can only be one or zero share URLs on a given share.
|
|
2148
|
+
*/
|
|
2152
2149
|
get: operations["get_drive-shares-{shareID}-urls"];
|
|
2153
2150
|
put?: never;
|
|
2154
2151
|
/** Share by URL */
|
|
@@ -2465,6 +2462,46 @@ export interface paths {
|
|
|
2465
2462
|
patch?: never;
|
|
2466
2463
|
trace?: never;
|
|
2467
2464
|
};
|
|
2465
|
+
"/drive/unauth/v2/volumes/{volumeID}/files/small": {
|
|
2466
|
+
parameters: {
|
|
2467
|
+
query?: never;
|
|
2468
|
+
header?: never;
|
|
2469
|
+
path?: never;
|
|
2470
|
+
cookie?: never;
|
|
2471
|
+
};
|
|
2472
|
+
get?: never;
|
|
2473
|
+
put?: never;
|
|
2474
|
+
/**
|
|
2475
|
+
* Upload small file
|
|
2476
|
+
* @description See /drive/v2/volumes/{volumeID}/files/small for full documentation
|
|
2477
|
+
*/
|
|
2478
|
+
post: operations["post_drive-unauth-v2-volumes-{volumeID}-files-small"];
|
|
2479
|
+
delete?: never;
|
|
2480
|
+
options?: never;
|
|
2481
|
+
head?: never;
|
|
2482
|
+
patch?: never;
|
|
2483
|
+
trace?: never;
|
|
2484
|
+
};
|
|
2485
|
+
"/drive/unauth/v2/volumes/{volumeID}/files/{linkID}/revisions/small": {
|
|
2486
|
+
parameters: {
|
|
2487
|
+
query?: never;
|
|
2488
|
+
header?: never;
|
|
2489
|
+
path?: never;
|
|
2490
|
+
cookie?: never;
|
|
2491
|
+
};
|
|
2492
|
+
get?: never;
|
|
2493
|
+
put?: never;
|
|
2494
|
+
/**
|
|
2495
|
+
* Upload small revision
|
|
2496
|
+
* @description See /drive/v2/volumes/{volumeID}/files/{linkID}/revisions/small for full documentation
|
|
2497
|
+
*/
|
|
2498
|
+
post: operations["post_drive-unauth-v2-volumes-{volumeID}-files-{linkID}-revisions-small"];
|
|
2499
|
+
delete?: never;
|
|
2500
|
+
options?: never;
|
|
2501
|
+
head?: never;
|
|
2502
|
+
patch?: never;
|
|
2503
|
+
trace?: never;
|
|
2504
|
+
};
|
|
2468
2505
|
"/drive/unauth/v2/volumes/{volumeID}/links/{linkID}/revisions/{revisionID}/verification": {
|
|
2469
2506
|
parameters: {
|
|
2470
2507
|
query?: never;
|
|
@@ -4540,6 +4577,15 @@ export interface components {
|
|
|
4540
4577
|
* @enum {integer}
|
|
4541
4578
|
*/
|
|
4542
4579
|
LinkState2: 0 | 1 | 2;
|
|
4580
|
+
OwnedByDto: {
|
|
4581
|
+
/**
|
|
4582
|
+
* Format: email
|
|
4583
|
+
* @description OwnerUser email for regular and photo volumes, null otherwise
|
|
4584
|
+
*/
|
|
4585
|
+
Email?: string | null;
|
|
4586
|
+
/** @description OwnerOrganization name for org. volumes, null otherwise */
|
|
4587
|
+
Organization?: string | null;
|
|
4588
|
+
};
|
|
4543
4589
|
LinkDto: {
|
|
4544
4590
|
LinkID: components["schemas"]["Id"];
|
|
4545
4591
|
Type: components["schemas"]["NodeType2"];
|
|
@@ -4557,6 +4603,7 @@ export interface components {
|
|
|
4557
4603
|
SignatureEmail?: string | null;
|
|
4558
4604
|
/** Format: email */
|
|
4559
4605
|
NameSignatureEmail?: string | null;
|
|
4606
|
+
OwnedBy: components["schemas"]["OwnedByDto"];
|
|
4560
4607
|
/** @default null */
|
|
4561
4608
|
DirectPermissions: number | null;
|
|
4562
4609
|
};
|
|
@@ -5236,6 +5283,8 @@ export interface components {
|
|
|
5236
5283
|
State: components["schemas"]["HealthCheckState"];
|
|
5237
5284
|
};
|
|
5238
5285
|
AbuseReportDto: {
|
|
5286
|
+
/** @description Passphrase for reported Link's Node key, unencrypted, as a string, escaped for JSON. */
|
|
5287
|
+
ResourcePassphrase: string;
|
|
5239
5288
|
/**
|
|
5240
5289
|
* @description Reported ShareURL, complete including fragment
|
|
5241
5290
|
* @example https://drive.proton.me/urls/1F9BKXYDMA#yF7d7bn01GMM
|
|
@@ -5243,8 +5292,6 @@ export interface components {
|
|
|
5243
5292
|
ShareURL: string;
|
|
5244
5293
|
/** @enum {string} */
|
|
5245
5294
|
AbuseCategory: "spam" | "copyright" | "child-abuse" | "stolen-data" | "malware" | "other";
|
|
5246
|
-
/** @description Passphrase for reported Link's Node key, unencrypted, as a string, escaped for JSON. */
|
|
5247
|
-
ResourcePassphrase: string;
|
|
5248
5295
|
/**
|
|
5249
5296
|
* @description Full password, including custom part, as string, escaped for JSON
|
|
5250
5297
|
* @default
|
|
@@ -5984,11 +6031,10 @@ export interface components {
|
|
|
5984
6031
|
ShareURLs: components["schemas"]["ShareURLResponseDto"][];
|
|
5985
6032
|
/**
|
|
5986
6033
|
* @deprecated
|
|
5987
|
-
* @description
|
|
6034
|
+
* @description Unused and deprecated. Always empty.
|
|
6035
|
+
* @default []
|
|
5988
6036
|
*/
|
|
5989
|
-
Links:
|
|
5990
|
-
[key: string]: components["schemas"]["ExtendedLinkTransformer"];
|
|
5991
|
-
};
|
|
6037
|
+
Links: Record<string, never>;
|
|
5992
6038
|
/**
|
|
5993
6039
|
* ProtonResponseCode
|
|
5994
6040
|
* @example 1000
|
|
@@ -7275,23 +7321,6 @@ export interface operations {
|
|
|
7275
7321
|
};
|
|
7276
7322
|
};
|
|
7277
7323
|
};
|
|
7278
|
-
/** @description Failed dependency */
|
|
7279
|
-
424: {
|
|
7280
|
-
headers: {
|
|
7281
|
-
[name: string]: unknown;
|
|
7282
|
-
};
|
|
7283
|
-
content: {
|
|
7284
|
-
"application/json": {
|
|
7285
|
-
/**
|
|
7286
|
-
* @description Potential codes:
|
|
7287
|
-
* - 2032
|
|
7288
|
-
*
|
|
7289
|
-
* @enum {integer}
|
|
7290
|
-
*/
|
|
7291
|
-
Code: 2032;
|
|
7292
|
-
};
|
|
7293
|
-
};
|
|
7294
|
-
};
|
|
7295
7324
|
};
|
|
7296
7325
|
};
|
|
7297
7326
|
"post_drive-photos-volumes": {
|
|
@@ -7333,23 +7362,6 @@ export interface operations {
|
|
|
7333
7362
|
};
|
|
7334
7363
|
};
|
|
7335
7364
|
};
|
|
7336
|
-
/** @description Failed dependency */
|
|
7337
|
-
424: {
|
|
7338
|
-
headers: {
|
|
7339
|
-
[name: string]: unknown;
|
|
7340
|
-
};
|
|
7341
|
-
content: {
|
|
7342
|
-
"application/json": {
|
|
7343
|
-
/**
|
|
7344
|
-
* @description Potential codes:
|
|
7345
|
-
* - 2032
|
|
7346
|
-
*
|
|
7347
|
-
* @enum {integer}
|
|
7348
|
-
*/
|
|
7349
|
-
Code: 2032;
|
|
7350
|
-
};
|
|
7351
|
-
};
|
|
7352
|
-
};
|
|
7353
7365
|
};
|
|
7354
7366
|
};
|
|
7355
7367
|
"put_drive-photos-volumes-{volumeID}-albums-{linkID}": {
|
|
@@ -7393,26 +7405,6 @@ export interface operations {
|
|
|
7393
7405
|
};
|
|
7394
7406
|
};
|
|
7395
7407
|
};
|
|
7396
|
-
/** @description Failed dependency */
|
|
7397
|
-
424: {
|
|
7398
|
-
headers: {
|
|
7399
|
-
[name: string]: unknown;
|
|
7400
|
-
};
|
|
7401
|
-
content: {
|
|
7402
|
-
"application/json": {
|
|
7403
|
-
/**
|
|
7404
|
-
* @description Potential codes:
|
|
7405
|
-
* - 2501: File or folder not found
|
|
7406
|
-
* - 2001: Invalid PGP message
|
|
7407
|
-
* - 200501: Operation failed: Please retry
|
|
7408
|
-
* - 2032
|
|
7409
|
-
*
|
|
7410
|
-
* @enum {integer}
|
|
7411
|
-
*/
|
|
7412
|
-
Code: 2032;
|
|
7413
|
-
};
|
|
7414
|
-
};
|
|
7415
|
-
};
|
|
7416
7408
|
};
|
|
7417
7409
|
};
|
|
7418
7410
|
"delete_drive-photos-volumes-{volumeID}-albums-{linkID}": {
|
|
@@ -10832,23 +10824,6 @@ export interface operations {
|
|
|
10832
10824
|
};
|
|
10833
10825
|
};
|
|
10834
10826
|
};
|
|
10835
|
-
/** @description Failed dependency */
|
|
10836
|
-
424: {
|
|
10837
|
-
headers: {
|
|
10838
|
-
[name: string]: unknown;
|
|
10839
|
-
};
|
|
10840
|
-
content: {
|
|
10841
|
-
"application/json": {
|
|
10842
|
-
/**
|
|
10843
|
-
* @description Potential codes:
|
|
10844
|
-
* - 2032
|
|
10845
|
-
*
|
|
10846
|
-
* @enum {integer}
|
|
10847
|
-
*/
|
|
10848
|
-
Code: 2032;
|
|
10849
|
-
};
|
|
10850
|
-
};
|
|
10851
|
-
};
|
|
10852
10827
|
};
|
|
10853
10828
|
};
|
|
10854
10829
|
"post_drive-urls-{token}-auth": {
|
|
@@ -11570,20 +11545,7 @@ export interface operations {
|
|
|
11570
11545
|
};
|
|
11571
11546
|
"get_drive-shares-{shareID}-urls": {
|
|
11572
11547
|
parameters: {
|
|
11573
|
-
query?:
|
|
11574
|
-
/**
|
|
11575
|
-
* @deprecated
|
|
11576
|
-
* @description By default, only shareURL pointing to the share are returned. With Recursive=1, list all shareURLs in the subtree reachable from the Share. 1 (true) or 0 (false).
|
|
11577
|
-
*/
|
|
11578
|
-
Recursive?: 0 | 1;
|
|
11579
|
-
/**
|
|
11580
|
-
* @deprecated
|
|
11581
|
-
* @description Fetch Thumbnail URLs
|
|
11582
|
-
*/
|
|
11583
|
-
Thumbnails?: 0 | 1;
|
|
11584
|
-
PageSize?: components["schemas"]["OffsetPagination"]["PageSize"] & unknown;
|
|
11585
|
-
Page?: components["schemas"]["OffsetPagination"]["Page"] & unknown;
|
|
11586
|
-
};
|
|
11548
|
+
query?: never;
|
|
11587
11549
|
header?: never;
|
|
11588
11550
|
path: {
|
|
11589
11551
|
shareID: string;
|
|
@@ -12120,6 +12082,53 @@ export interface operations {
|
|
|
12120
12082
|
};
|
|
12121
12083
|
};
|
|
12122
12084
|
};
|
|
12085
|
+
"post_drive-unauth-v2-volumes-{volumeID}-files-small": {
|
|
12086
|
+
parameters: {
|
|
12087
|
+
query?: never;
|
|
12088
|
+
header?: never;
|
|
12089
|
+
path: {
|
|
12090
|
+
volumeID: string;
|
|
12091
|
+
};
|
|
12092
|
+
cookie?: never;
|
|
12093
|
+
};
|
|
12094
|
+
requestBody?: never;
|
|
12095
|
+
responses: {
|
|
12096
|
+
/** @description Success */
|
|
12097
|
+
200: {
|
|
12098
|
+
headers: {
|
|
12099
|
+
"x-pm-code": 1000;
|
|
12100
|
+
[name: string]: unknown;
|
|
12101
|
+
};
|
|
12102
|
+
content: {
|
|
12103
|
+
"application/json": components["schemas"]["SmallUploadResponseDto"];
|
|
12104
|
+
};
|
|
12105
|
+
};
|
|
12106
|
+
};
|
|
12107
|
+
};
|
|
12108
|
+
"post_drive-unauth-v2-volumes-{volumeID}-files-{linkID}-revisions-small": {
|
|
12109
|
+
parameters: {
|
|
12110
|
+
query?: never;
|
|
12111
|
+
header?: never;
|
|
12112
|
+
path: {
|
|
12113
|
+
volumeID: string;
|
|
12114
|
+
linkID: components["schemas"]["Id"];
|
|
12115
|
+
};
|
|
12116
|
+
cookie?: never;
|
|
12117
|
+
};
|
|
12118
|
+
requestBody?: never;
|
|
12119
|
+
responses: {
|
|
12120
|
+
/** @description Success */
|
|
12121
|
+
200: {
|
|
12122
|
+
headers: {
|
|
12123
|
+
"x-pm-code": 1000;
|
|
12124
|
+
[name: string]: unknown;
|
|
12125
|
+
};
|
|
12126
|
+
content: {
|
|
12127
|
+
"application/json": components["schemas"]["SmallUploadResponseDto"];
|
|
12128
|
+
};
|
|
12129
|
+
};
|
|
12130
|
+
};
|
|
12131
|
+
};
|
|
12123
12132
|
"get_drive-unauth-v2-volumes-{volumeID}-links-{linkID}-revisions-{revisionID}-verification": {
|
|
12124
12133
|
parameters: {
|
|
12125
12134
|
query?: never;
|
|
@@ -74,6 +74,11 @@ function generateAPINode() {
|
|
|
74
74
|
NodeKey: 'nodeKey',
|
|
75
75
|
NodePassphrase: 'nodePass',
|
|
76
76
|
NodePassphraseSignature: 'nodePassSig',
|
|
77
|
+
|
|
78
|
+
OwnedBy: {
|
|
79
|
+
Email: 'ownerByEmail',
|
|
80
|
+
Organization: null,
|
|
81
|
+
},
|
|
77
82
|
},
|
|
78
83
|
SharingSummary: null,
|
|
79
84
|
};
|
|
@@ -149,6 +154,10 @@ function generateNode() {
|
|
|
149
154
|
isSharedPublicly: false,
|
|
150
155
|
directRole: MemberRole.Admin,
|
|
151
156
|
membership: undefined,
|
|
157
|
+
ownedBy: {
|
|
158
|
+
email: 'ownerByEmail',
|
|
159
|
+
organization: undefined,
|
|
160
|
+
},
|
|
152
161
|
|
|
153
162
|
encryptedCrypto: {
|
|
154
163
|
armoredKey: 'nodeKey',
|
|
@@ -780,6 +780,10 @@ export function linkToEncryptedNodeBaseMetadata(
|
|
|
780
780
|
inviteTime: new Date(link.Membership.InviteTime * 1000),
|
|
781
781
|
}
|
|
782
782
|
: undefined,
|
|
783
|
+
ownedBy: {
|
|
784
|
+
email: link.Link.OwnedBy?.Email || undefined,
|
|
785
|
+
organization: link.Link.OwnedBy?.Organization || undefined,
|
|
786
|
+
},
|
|
783
787
|
};
|
|
784
788
|
|
|
785
789
|
const baseCryptoNodeMetadata = {
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { c } from 'ttag';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
base64StringToUint8Array,
|
|
5
|
+
DriveCrypto,
|
|
6
|
+
PrivateKey,
|
|
7
|
+
PublicKey,
|
|
8
|
+
SessionKey,
|
|
9
|
+
VERIFICATION_STATUS,
|
|
10
|
+
} from '../../crypto';
|
|
4
11
|
import {
|
|
5
12
|
resultOk,
|
|
6
13
|
resultError,
|
|
@@ -201,7 +208,9 @@ export class NodesCryptoService {
|
|
|
201
208
|
let activeRevision: Result<DecryptedUnparsedRevision, Error> | undefined;
|
|
202
209
|
let contentKeyPacketSessionKey;
|
|
203
210
|
let contentKeyPacketAuthor;
|
|
211
|
+
let contentKeyPacket: Uint8Array<ArrayBuffer> | undefined;
|
|
204
212
|
if ('file' in node.encryptedCrypto) {
|
|
213
|
+
contentKeyPacket = base64StringToUint8Array(node.encryptedCrypto.file.base64ContentKeyPacket);
|
|
205
214
|
const [activeRevisionPromise, contentKeyPacketSessionKeyPromise] = [
|
|
206
215
|
this.decryptRevision(node.uid, node.encryptedCrypto.activeRevision, key),
|
|
207
216
|
this.decryptContentKeyPacket(node, node.encryptedCrypto, key, keyVerificationKeys),
|
|
@@ -284,6 +293,7 @@ export class NodesCryptoService {
|
|
|
284
293
|
passphrase,
|
|
285
294
|
key,
|
|
286
295
|
passphraseSessionKey,
|
|
296
|
+
contentKeyPacket,
|
|
287
297
|
contentKeyPacketSessionKey,
|
|
288
298
|
hashKey,
|
|
289
299
|
},
|
|
@@ -51,19 +51,15 @@ describe('extended attrbiutes', () => {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
describe('should generate file attributes without additional metadata', () => {
|
|
54
|
-
const testCases: [
|
|
55
|
-
[{}, undefined],
|
|
54
|
+
const testCases: [any, string | undefined][] = [
|
|
56
55
|
[
|
|
57
|
-
{
|
|
58
|
-
'{"Common":{"
|
|
56
|
+
{ size: 0, blockSizes: [], digests: { sha1: 'abcdef' } },
|
|
57
|
+
'{"Common":{"Size":0,"BlockSizes":[],"Digests":{"SHA1":"abcdef"}}}',
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
{ size: 1234, blockSizes: [1200, 34], digests: { sha1: 'gedcba' } },
|
|
61
|
+
'{"Common":{"Size":1234,"BlockSizes":[1200,34],"Digests":{"SHA1":"gedcba"}}}',
|
|
59
62
|
],
|
|
60
|
-
[{ size: undefined }, undefined],
|
|
61
|
-
[{ size: 0 }, '{"Common":{"Size":0}}'],
|
|
62
|
-
[{ size: 1234 }, '{"Common":{"Size":1234}}'],
|
|
63
|
-
[{ blockSizes: [] }, undefined],
|
|
64
|
-
[{ blockSizes: [4, 4, 4, 2] }, '{"Common":{"BlockSizes":[4,4,4,2]}}'],
|
|
65
|
-
[{ digests: {} }, undefined],
|
|
66
|
-
[{ digests: { sha1: 'abcdef' } }, '{"Common":{"Digests":{"SHA1":"abcdef"}}}'],
|
|
67
63
|
[
|
|
68
64
|
{
|
|
69
65
|
modificationTime: new Date(1234567890000),
|
|
@@ -75,7 +71,7 @@ describe('extended attrbiutes', () => {
|
|
|
75
71
|
],
|
|
76
72
|
];
|
|
77
73
|
testCases.forEach(([input, expectedAttributes]) => {
|
|
78
|
-
it(`should generate ${input}`, () => {
|
|
74
|
+
it(`should generate ${JSON.stringify(input)}`, () => {
|
|
79
75
|
const output = generateFileExtendedAttributes(input);
|
|
80
76
|
expect(output).toBe(expectedAttributes);
|
|
81
77
|
});
|
|
@@ -83,24 +79,28 @@ describe('extended attrbiutes', () => {
|
|
|
83
79
|
});
|
|
84
80
|
|
|
85
81
|
describe('should generate file attributes with additional metadata', () => {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
const input = {
|
|
83
|
+
size: 1234,
|
|
84
|
+
blockSizes: [1200, 34],
|
|
85
|
+
digests: { sha1: 'abcdef' },
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
it(`should generate ${JSON.stringify(input)}`, () => {
|
|
89
|
+
const output = generateFileExtendedAttributes(input, { Media: { Width: 100, Height: 100 } });
|
|
90
|
+
expect(output).toBe(
|
|
91
|
+
'{"Common":{"Size":1234,"BlockSizes":[1200,34],"Digests":{"SHA1":"abcdef"}},"Media":{"Width":100,"Height":100}}',
|
|
92
|
+
);
|
|
96
93
|
});
|
|
97
94
|
});
|
|
98
95
|
|
|
99
96
|
describe('should throw an error if additional metadata contains common attributes', () => {
|
|
100
97
|
it('should throw an error', () => {
|
|
101
|
-
expect(() =>
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
expect(() =>
|
|
99
|
+
generateFileExtendedAttributes(
|
|
100
|
+
{ size: 123, blockSizes: [], digests: { sha1: 'abcdef' } },
|
|
101
|
+
{ Common: { Hello: 'World' } },
|
|
102
|
+
),
|
|
103
|
+
).toThrow('Common attributes are not allowed in additional metadata');
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
|
|
@@ -86,14 +86,14 @@ export function parseFolderExtendedAttributes(logger: Logger, extendedAttributes
|
|
|
86
86
|
export function generateFileExtendedAttributes(
|
|
87
87
|
common: {
|
|
88
88
|
modificationTime?: Date;
|
|
89
|
-
size
|
|
90
|
-
blockSizes
|
|
91
|
-
digests
|
|
92
|
-
sha1
|
|
89
|
+
size: number;
|
|
90
|
+
blockSizes: number[];
|
|
91
|
+
digests: {
|
|
92
|
+
sha1: string;
|
|
93
93
|
};
|
|
94
94
|
},
|
|
95
95
|
additionalMetadata?: object,
|
|
96
|
-
): string
|
|
96
|
+
): string {
|
|
97
97
|
if (additionalMetadata && 'Common' in additionalMetadata) {
|
|
98
98
|
throw new Error('Common attributes are not allowed in additional metadata');
|
|
99
99
|
}
|
|
@@ -102,20 +102,11 @@ export function generateFileExtendedAttributes(
|
|
|
102
102
|
if (common.modificationTime) {
|
|
103
103
|
commonAttributes.ModificationTime = dateToIsoString(common.modificationTime);
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
if (common.digests?.sha1) {
|
|
112
|
-
commonAttributes.Digests = {
|
|
113
|
-
SHA1: common.digests.sha1,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
if (!Object.keys(commonAttributes).length && !additionalMetadata) {
|
|
117
|
-
return undefined;
|
|
118
|
-
}
|
|
105
|
+
commonAttributes.Size = common.size;
|
|
106
|
+
commonAttributes.BlockSizes = common.blockSizes;
|
|
107
|
+
commonAttributes.Digests = {
|
|
108
|
+
SHA1: common.digests.sha1,
|
|
109
|
+
};
|
|
119
110
|
return JSON.stringify({
|
|
120
111
|
...(Object.keys(commonAttributes).length ? { Common: commonAttributes } : {}),
|
|
121
112
|
...(additionalMetadata ? { ...additionalMetadata } : {}),
|
|
@@ -47,6 +47,10 @@ interface BaseNode {
|
|
|
47
47
|
inviteTime: Date;
|
|
48
48
|
// TODO: acceptedBy: Author;
|
|
49
49
|
};
|
|
50
|
+
ownedBy: {
|
|
51
|
+
email?: string;
|
|
52
|
+
organization?: string;
|
|
53
|
+
};
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
/**
|
|
@@ -156,6 +160,7 @@ export interface DecryptedNodeKeys {
|
|
|
156
160
|
passphrase: string;
|
|
157
161
|
key: PrivateKey;
|
|
158
162
|
passphraseSessionKey: SessionKey;
|
|
163
|
+
contentKeyPacket?: Uint8Array<ArrayBuffer>;
|
|
159
164
|
contentKeyPacketSessionKey?: SessionKey;
|
|
160
165
|
hashKey?: Uint8Array<ArrayBuffer>;
|
|
161
166
|
}
|
|
@@ -312,6 +312,7 @@ export abstract class NodesManagementBase<
|
|
|
312
312
|
async createFolder(parentNodeUid: string, folderName: string, modificationTime?: Date): Promise<TDecryptedNode> {
|
|
313
313
|
validateNodeName(folderName);
|
|
314
314
|
|
|
315
|
+
const parentNode = await this.nodesAccess.getNode(parentNodeUid);
|
|
315
316
|
const parentKeys = await this.nodesAccess.getNodeKeys(parentNodeUid);
|
|
316
317
|
if (!parentKeys.hashKey) {
|
|
317
318
|
throw new ValidationError(c('Error').t`Creating folders in non-folders is not allowed`);
|
|
@@ -338,14 +339,14 @@ export abstract class NodesManagementBase<
|
|
|
338
339
|
});
|
|
339
340
|
|
|
340
341
|
await this.nodesAccess.notifyChildCreated(parentNodeUid);
|
|
341
|
-
const node = this.generateNodeFolder(
|
|
342
|
+
const node = this.generateNodeFolder(parentNode, nodeUid, folderName, encryptedCrypto);
|
|
342
343
|
await this.cryptoCache.setNodeKeys(nodeUid, keys);
|
|
343
344
|
return node;
|
|
344
345
|
}
|
|
345
346
|
|
|
346
347
|
protected abstract generateNodeFolder(
|
|
348
|
+
parentNode: TDecryptedNode,
|
|
347
349
|
nodeUid: string,
|
|
348
|
-
parentUid: string,
|
|
349
350
|
name: string,
|
|
350
351
|
encryptedCrypto: {
|
|
351
352
|
hash: string;
|
|
@@ -355,8 +356,8 @@ export abstract class NodesManagementBase<
|
|
|
355
356
|
): TDecryptedNode;
|
|
356
357
|
|
|
357
358
|
protected generateNodeFolderBase(
|
|
359
|
+
parentNode: TDecryptedNode,
|
|
358
360
|
nodeUid: string,
|
|
359
|
-
parentNodeUid: string,
|
|
360
361
|
name: string,
|
|
361
362
|
encryptedCrypto: {
|
|
362
363
|
hash: string;
|
|
@@ -371,7 +372,7 @@ export abstract class NodesManagementBase<
|
|
|
371
372
|
|
|
372
373
|
// Basic node metadata
|
|
373
374
|
uid: nodeUid,
|
|
374
|
-
parentUid:
|
|
375
|
+
parentUid: parentNode.uid,
|
|
375
376
|
type: NodeType.Folder,
|
|
376
377
|
mediaType: FOLDER_MEDIA_TYPE,
|
|
377
378
|
creationTime: new Date(),
|
|
@@ -381,6 +382,7 @@ export abstract class NodesManagementBase<
|
|
|
381
382
|
isShared: false,
|
|
382
383
|
isSharedPublicly: false,
|
|
383
384
|
directRole: MemberRole.Inherited,
|
|
385
|
+
ownedBy: parentNode.ownedBy,
|
|
384
386
|
|
|
385
387
|
// Decrypted metadata
|
|
386
388
|
isStale: false,
|
|
@@ -432,8 +434,8 @@ export abstract class NodesManagementBase<
|
|
|
432
434
|
|
|
433
435
|
export class NodesManagement extends NodesManagementBase {
|
|
434
436
|
protected generateNodeFolder(
|
|
437
|
+
parentNode: DecryptedNode,
|
|
435
438
|
nodeUid: string,
|
|
436
|
-
parentNodeUid: string,
|
|
437
439
|
name: string,
|
|
438
440
|
encryptedCrypto: {
|
|
439
441
|
hash: string;
|
|
@@ -441,6 +443,6 @@ export class NodesManagement extends NodesManagementBase {
|
|
|
441
443
|
signatureEmail: string | null;
|
|
442
444
|
},
|
|
443
445
|
): DecryptedNode {
|
|
444
|
-
return this.generateNodeFolderBase(
|
|
446
|
+
return this.generateNodeFolderBase(parentNode, nodeUid, name, encryptedCrypto);
|
|
445
447
|
}
|
|
446
448
|
}
|
|
@@ -252,8 +252,8 @@ export class PhotosNodesManagement extends NodesManagementBase<
|
|
|
252
252
|
PhotosNodesCryptoService
|
|
253
253
|
> {
|
|
254
254
|
protected generateNodeFolder(
|
|
255
|
+
parentNode: DecryptedPhotoNode,
|
|
255
256
|
nodeUid: string,
|
|
256
|
-
parentNodeUid: string,
|
|
257
257
|
name: string,
|
|
258
258
|
encryptedCrypto: {
|
|
259
259
|
hash: string;
|
|
@@ -261,6 +261,6 @@ export class PhotosNodesManagement extends NodesManagementBase<
|
|
|
261
261
|
signatureEmail: string | null;
|
|
262
262
|
},
|
|
263
263
|
): DecryptedPhotoNode {
|
|
264
|
-
return this.generateNodeFolderBase(
|
|
264
|
+
return this.generateNodeFolderBase(parentNode, nodeUid, name, encryptedCrypto);
|
|
265
265
|
}
|
|
266
266
|
}
|