curtain-web-api 1.0.62 → 1.0.64
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/build/classes/curtain-api.d.ts +64 -2
- package/build/classes/curtain-api.js +342 -226
- package/build/classes/curtain-encryption.js +92 -166
- package/build/classes/curtain-user.js +4 -11
- package/build/index.d.ts +2 -2
- package/build/index.js +6 -36
- package/build/utilities.js +13 -53
- package/package.json +9 -1
- package/src/classes/curtain-api.ts +264 -4
- package/src/index.ts +17 -1
- package/tsconfig.json +4 -3
|
@@ -30,6 +30,60 @@ export const reviver = (key: any, value: any) => {
|
|
|
30
30
|
return value;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export interface SiteProperties {
|
|
34
|
+
non_user_post: boolean;
|
|
35
|
+
allow_user_set_permanent: boolean;
|
|
36
|
+
expiry_duration_options: number[];
|
|
37
|
+
default_expiry_duration_months: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CurtainChunkedUploadStatus {
|
|
41
|
+
id: string;
|
|
42
|
+
filename?: string;
|
|
43
|
+
offset: number;
|
|
44
|
+
created_at: string;
|
|
45
|
+
status: number;
|
|
46
|
+
completed_at?: string;
|
|
47
|
+
original_filename?: string;
|
|
48
|
+
mime_type?: string;
|
|
49
|
+
file_size?: number;
|
|
50
|
+
upload_session_id?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CurtainChunkedUploadRequest {
|
|
54
|
+
file: File | Blob;
|
|
55
|
+
filename?: string;
|
|
56
|
+
upload_session_id?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
curtain_type?: string;
|
|
59
|
+
permanent?: boolean;
|
|
60
|
+
encrypted?: boolean;
|
|
61
|
+
expiry_duration?: number;
|
|
62
|
+
enable?: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface CurtainChunkedUploadResponse {
|
|
66
|
+
id: string;
|
|
67
|
+
filename: string;
|
|
68
|
+
offset: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CurtainChunkedUploadCompletionRequest {
|
|
72
|
+
md5?: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
curtain_type?: string;
|
|
75
|
+
permanent?: boolean;
|
|
76
|
+
encrypted?: boolean;
|
|
77
|
+
expiry_duration?: number;
|
|
78
|
+
enable?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface CurtainChunkedUploadCompletionResponse {
|
|
82
|
+
curtain?: any;
|
|
83
|
+
message?: string;
|
|
84
|
+
error?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
33
87
|
export class CurtainWebAPI {
|
|
34
88
|
loginURL: string = "";
|
|
35
89
|
logoutURL: string = "";
|
|
@@ -211,7 +265,7 @@ export class CurtainWebAPI {
|
|
|
211
265
|
async putSettings(settings: any, enable: boolean = true, description: string = "", sessionType: string = "TP", encryption: CurtainEncryption = {
|
|
212
266
|
encrypted: false,
|
|
213
267
|
e2e: false,
|
|
214
|
-
}, permanent: boolean = false, onUploadProgress: any = undefined) {
|
|
268
|
+
}, permanent: boolean = false, expiry_duration?: number, onUploadProgress: any = undefined) {
|
|
215
269
|
let form: FormData = new FormData();
|
|
216
270
|
let data = JSON.stringify(settings, replacer)
|
|
217
271
|
if (enable) {
|
|
@@ -234,6 +288,9 @@ export class CurtainWebAPI {
|
|
|
234
288
|
} else {
|
|
235
289
|
form.append("permanent", "False")
|
|
236
290
|
}
|
|
291
|
+
if (expiry_duration !== undefined) {
|
|
292
|
+
form.append("expiry_duration", expiry_duration.toString())
|
|
293
|
+
}
|
|
237
294
|
if (encryption.encrypted && encryption.e2e && encryption.publicKey !== undefined) {
|
|
238
295
|
const aesKey = await generateAESKey()
|
|
239
296
|
console.log("Encrypting data")
|
|
@@ -350,6 +407,10 @@ export class CurtainWebAPI {
|
|
|
350
407
|
}
|
|
351
408
|
}
|
|
352
409
|
|
|
410
|
+
if ("expiry_duration" in sessionData) {
|
|
411
|
+
form.append("expiry_duration", sessionData["expiry_duration"].toString())
|
|
412
|
+
}
|
|
413
|
+
|
|
353
414
|
if (encryption.encrypted) {
|
|
354
415
|
form.append("encrypted", "True")
|
|
355
416
|
} else {
|
|
@@ -422,9 +483,7 @@ export class CurtainWebAPI {
|
|
|
422
483
|
getSiteProperties() {
|
|
423
484
|
let headers = new AxiosHeaders();
|
|
424
485
|
headers["Accept"] = "application/json";
|
|
425
|
-
return this.axiosInstance.get(this.baseURL + "site-properties/", {headers: headers, responseType:"json"})
|
|
426
|
-
return response;
|
|
427
|
-
});
|
|
486
|
+
return this.axiosInstance.get<SiteProperties>(this.baseURL + "site-properties/", {headers: headers, responseType:"json"});
|
|
428
487
|
}
|
|
429
488
|
|
|
430
489
|
saveDataFilterList(name: string, data: string, category: string = "") {
|
|
@@ -694,5 +753,206 @@ export class CurtainWebAPI {
|
|
|
694
753
|
headers["Accept"] = "application/json";
|
|
695
754
|
return this.axiosInstance.get(this.baseURL + "datacite/file/" + datacite_id + "/", {headers: headers, responseType: "blob"});
|
|
696
755
|
}
|
|
756
|
+
|
|
757
|
+
uploadCurtainChunk(
|
|
758
|
+
request: CurtainChunkedUploadRequest,
|
|
759
|
+
uploadId?: string,
|
|
760
|
+
offset?: number,
|
|
761
|
+
totalSize?: number
|
|
762
|
+
) {
|
|
763
|
+
const formData = new FormData();
|
|
764
|
+
formData.append('file', request.file);
|
|
765
|
+
|
|
766
|
+
if (request.filename) {
|
|
767
|
+
formData.append('filename', request.filename);
|
|
768
|
+
}
|
|
769
|
+
if (request.upload_session_id) {
|
|
770
|
+
formData.append('upload_session_id', request.upload_session_id);
|
|
771
|
+
}
|
|
772
|
+
if (request.description) {
|
|
773
|
+
formData.append('description', request.description);
|
|
774
|
+
}
|
|
775
|
+
if (request.curtain_type) {
|
|
776
|
+
formData.append('curtain_type', request.curtain_type);
|
|
777
|
+
}
|
|
778
|
+
if (request.permanent !== undefined) {
|
|
779
|
+
formData.append('permanent', request.permanent.toString());
|
|
780
|
+
}
|
|
781
|
+
if (request.encrypted !== undefined) {
|
|
782
|
+
formData.append('encrypted', request.encrypted.toString());
|
|
783
|
+
}
|
|
784
|
+
if (request.expiry_duration !== undefined) {
|
|
785
|
+
formData.append('expiry_duration', request.expiry_duration.toString());
|
|
786
|
+
}
|
|
787
|
+
if (request.enable !== undefined) {
|
|
788
|
+
formData.append('enable', request.enable.toString());
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
const url = uploadId
|
|
792
|
+
? `${this.baseURL}curtain-chunked-upload/${uploadId}/`
|
|
793
|
+
: `${this.baseURL}curtain-chunked-upload/`;
|
|
794
|
+
|
|
795
|
+
const headers = new AxiosHeaders();
|
|
796
|
+
headers["Accept"] = "application/json";
|
|
797
|
+
|
|
798
|
+
const isChunkedUpload = offset !== undefined && totalSize !== undefined;
|
|
799
|
+
|
|
800
|
+
if (isChunkedUpload && offset !== undefined && totalSize !== undefined) {
|
|
801
|
+
const chunkEnd = offset + (request.file as Blob).size - 1;
|
|
802
|
+
headers["Content-Range"] = `bytes ${offset}-${chunkEnd}/${totalSize}`;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
if (isChunkedUpload || uploadId) {
|
|
806
|
+
return this.axiosInstance.put<CurtainChunkedUploadResponse>(url, formData, {headers: headers});
|
|
807
|
+
} else {
|
|
808
|
+
return this.axiosInstance.post<CurtainChunkedUploadResponse>(url, formData, {headers: headers});
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
getCurtainUploadStatus(uploadId: string) {
|
|
813
|
+
let headers = new AxiosHeaders();
|
|
814
|
+
headers["Accept"] = "application/json";
|
|
815
|
+
return this.axiosInstance.get<CurtainChunkedUploadStatus>(`${this.baseURL}curtain-chunked-upload/${uploadId}/`, {headers: headers});
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
completeCurtainUpload(uploadId: string, request?: CurtainChunkedUploadCompletionRequest) {
|
|
819
|
+
const formData = new FormData();
|
|
820
|
+
|
|
821
|
+
if (request?.md5) {
|
|
822
|
+
formData.append('md5', request.md5);
|
|
823
|
+
}
|
|
824
|
+
if (request?.description) {
|
|
825
|
+
formData.append('description', request.description);
|
|
826
|
+
}
|
|
827
|
+
if (request?.curtain_type) {
|
|
828
|
+
formData.append('curtain_type', request.curtain_type);
|
|
829
|
+
}
|
|
830
|
+
if (request?.permanent !== undefined) {
|
|
831
|
+
formData.append('permanent', request.permanent.toString());
|
|
832
|
+
}
|
|
833
|
+
if (request?.encrypted !== undefined) {
|
|
834
|
+
formData.append('encrypted', request.encrypted.toString());
|
|
835
|
+
}
|
|
836
|
+
if (request?.expiry_duration !== undefined) {
|
|
837
|
+
formData.append('expiry_duration', request.expiry_duration.toString());
|
|
838
|
+
}
|
|
839
|
+
if (request?.enable !== undefined) {
|
|
840
|
+
formData.append('enable', request.enable.toString());
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
let headers = new AxiosHeaders();
|
|
844
|
+
headers["Accept"] = "application/json";
|
|
845
|
+
return this.axiosInstance.put<CurtainChunkedUploadCompletionResponse>(`${this.baseURL}curtain-chunked-upload/${uploadId}/`, formData, {headers: headers});
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
cancelCurtainUpload(uploadId: string) {
|
|
849
|
+
let headers = new AxiosHeaders();
|
|
850
|
+
headers["Accept"] = "application/json";
|
|
851
|
+
return this.axiosInstance.delete<void>(`${this.baseURL}curtain-chunked-upload/${uploadId}/`, {headers: headers});
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
async uploadCurtainFileInChunks(
|
|
855
|
+
file: File,
|
|
856
|
+
chunkSize: number = 1024 * 1024,
|
|
857
|
+
options?: {
|
|
858
|
+
description?: string;
|
|
859
|
+
curtain_type?: string;
|
|
860
|
+
permanent?: boolean;
|
|
861
|
+
encrypted?: boolean;
|
|
862
|
+
expiry_duration?: number;
|
|
863
|
+
enable?: boolean;
|
|
864
|
+
upload_session_id?: string;
|
|
865
|
+
onProgress?: (progress: number) => void;
|
|
866
|
+
}
|
|
867
|
+
): Promise<CurtainChunkedUploadCompletionResponse> {
|
|
868
|
+
return new Promise(async (resolve, reject) => {
|
|
869
|
+
let uploadId: string | undefined;
|
|
870
|
+
let offset = 0;
|
|
871
|
+
const totalSize = file.size;
|
|
872
|
+
|
|
873
|
+
if (totalSize <= chunkSize) {
|
|
874
|
+
try {
|
|
875
|
+
const response = await this.uploadCurtainChunk({
|
|
876
|
+
file: file,
|
|
877
|
+
filename: file.name,
|
|
878
|
+
upload_session_id: options?.upload_session_id,
|
|
879
|
+
description: options?.description,
|
|
880
|
+
curtain_type: options?.curtain_type,
|
|
881
|
+
permanent: options?.permanent,
|
|
882
|
+
encrypted: options?.encrypted,
|
|
883
|
+
expiry_duration: options?.expiry_duration,
|
|
884
|
+
enable: options?.enable
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
const completionResponse = await this.completeCurtainUpload(response.data.id, {
|
|
888
|
+
description: options?.description,
|
|
889
|
+
curtain_type: options?.curtain_type,
|
|
890
|
+
permanent: options?.permanent,
|
|
891
|
+
encrypted: options?.encrypted,
|
|
892
|
+
expiry_duration: options?.expiry_duration,
|
|
893
|
+
enable: options?.enable
|
|
894
|
+
});
|
|
895
|
+
resolve(completionResponse.data);
|
|
896
|
+
} catch (error) {
|
|
897
|
+
reject(error);
|
|
898
|
+
}
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
const uploadNextChunk = async () => {
|
|
903
|
+
if (offset >= totalSize) {
|
|
904
|
+
if (uploadId) {
|
|
905
|
+
try {
|
|
906
|
+
const completionResponse = await this.completeCurtainUpload(uploadId, {
|
|
907
|
+
description: options?.description,
|
|
908
|
+
curtain_type: options?.curtain_type,
|
|
909
|
+
permanent: options?.permanent,
|
|
910
|
+
encrypted: options?.encrypted,
|
|
911
|
+
expiry_duration: options?.expiry_duration,
|
|
912
|
+
enable: options?.enable
|
|
913
|
+
});
|
|
914
|
+
resolve(completionResponse.data);
|
|
915
|
+
} catch (error) {
|
|
916
|
+
reject(error);
|
|
917
|
+
}
|
|
918
|
+
} else {
|
|
919
|
+
reject(new Error('Upload failed: No upload ID'));
|
|
920
|
+
}
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const end = Math.min(offset + chunkSize, totalSize);
|
|
925
|
+
const chunk = file.slice(offset, end);
|
|
926
|
+
|
|
927
|
+
try {
|
|
928
|
+
const response = await this.uploadCurtainChunk({
|
|
929
|
+
file: chunk,
|
|
930
|
+
filename: file.name,
|
|
931
|
+
upload_session_id: options?.upload_session_id,
|
|
932
|
+
description: options?.description,
|
|
933
|
+
curtain_type: options?.curtain_type,
|
|
934
|
+
permanent: options?.permanent,
|
|
935
|
+
encrypted: options?.encrypted,
|
|
936
|
+
expiry_duration: options?.expiry_duration,
|
|
937
|
+
enable: options?.enable
|
|
938
|
+
}, uploadId, offset, totalSize);
|
|
939
|
+
|
|
940
|
+
uploadId = response.data.id;
|
|
941
|
+
offset = response.data.offset;
|
|
942
|
+
|
|
943
|
+
const progress = (offset / totalSize) * 100;
|
|
944
|
+
if (options?.onProgress) {
|
|
945
|
+
options.onProgress(progress);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
uploadNextChunk();
|
|
949
|
+
} catch (error) {
|
|
950
|
+
reject(error);
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
uploadNextChunk();
|
|
955
|
+
});
|
|
956
|
+
}
|
|
697
957
|
}
|
|
698
958
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CurtainWebAPI,
|
|
3
|
+
replacer,
|
|
4
|
+
reviver,
|
|
5
|
+
SiteProperties,
|
|
6
|
+
CurtainChunkedUploadStatus,
|
|
7
|
+
CurtainChunkedUploadRequest,
|
|
8
|
+
CurtainChunkedUploadResponse,
|
|
9
|
+
CurtainChunkedUploadCompletionRequest,
|
|
10
|
+
CurtainChunkedUploadCompletionResponse
|
|
11
|
+
} from "./classes/curtain-api";
|
|
2
12
|
import {User} from "./classes/curtain-user";
|
|
3
13
|
import {getProteomicsData, getPrideData, getEBIAlpha, getInteractomeAtlas, getStringDBInteractions} from "./utilities";
|
|
4
14
|
import {importKey, importPrivateKey, exportPrivateKey, exportKeyString, exportPublicKey, importPublicKey, CurtainEncryption, generateKeyPair, encryptDataRSA, decryptDataRSA, loadFromLocalStorage, saveToLocalStorage, pemToArrayBuffer, base64ToArrayBuffer, arrayBufferToBase64String, removeLines} from "./classes/curtain-encryption";
|
|
@@ -13,6 +23,12 @@ export {
|
|
|
13
23
|
getStringDBInteractions,
|
|
14
24
|
replacer,
|
|
15
25
|
reviver,
|
|
26
|
+
SiteProperties,
|
|
27
|
+
CurtainChunkedUploadStatus,
|
|
28
|
+
CurtainChunkedUploadRequest,
|
|
29
|
+
CurtainChunkedUploadResponse,
|
|
30
|
+
CurtainChunkedUploadCompletionRequest,
|
|
31
|
+
CurtainChunkedUploadCompletionResponse,
|
|
16
32
|
importKey,
|
|
17
33
|
importPrivateKey,
|
|
18
34
|
exportPrivateKey,
|
package/tsconfig.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
4
|
-
"lib": ["
|
|
5
|
-
"module": "
|
|
3
|
+
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
4
|
+
"lib": ["ES2020", "DOM"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
5
|
+
"module": "ES2020", /* Specify what module code is generated. */
|
|
6
|
+
"moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
6
7
|
"rootDir": "src", /* Specify the root folder within your source files. */
|
|
7
8
|
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
8
9
|
"outDir": "build", /* Specify an output folder for all emitted files. */
|