curtain-web-api 1.0.40 → 1.0.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "curtain-web-api",
3
- "version": "1.0.40",
3
+ "version": "1.0.41",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -1,6 +1,12 @@
1
1
  import {User} from "./curtain-user";
2
2
  import axios, {AxiosHeaders} from "axios";
3
- import {arrayBufferToBase64String, CurtainEncryption, encryptDataRSA} from "./curtain-encryption";
3
+ import {
4
+ arrayBufferToBase64String, base64ToArrayBuffer,
5
+ CurtainEncryption,
6
+ encryptAESData, encryptAESKey,
7
+ encryptDataRSA, exportAESKey,
8
+ generateAESKey
9
+ } from "./curtain-encryption";
4
10
 
5
11
  const base: string = "https://celsus.muttsu.xyz/"
6
12
 
@@ -222,9 +228,18 @@ export class CurtainWebAPI {
222
228
  }
223
229
 
224
230
  if (encryption.encrypted && encryption.e2e && encryption.publicKey !== undefined) {
225
- const response = await encryptDataRSA(data, encryption.publicKey)
226
- const base64String = arrayBufferToBase64String(response)
227
- form.append("file", new Blob([base64String], {type: 'text/json'}), "curtain-settings.json")
231
+ const aesKey = await generateAESKey()
232
+ const encryptedData = await encryptAESData(aesKey, data)
233
+ const encryptedKey = await encryptAESKey(encryption.publicKey, await exportAESKey(aesKey))
234
+ const encryptedIV = await encryptAESKey(encryption.publicKey, base64ToArrayBuffer(encryptedData.iv))
235
+ const payload = {
236
+ encryptedData: encryptedData.encrypted,
237
+ encryptedKey: arrayBufferToBase64String(encryptedKey),
238
+ encryptedIV: arrayBufferToBase64String(encryptedIV)
239
+ }
240
+ form.append("encryptedKey", payload.encryptedKey)
241
+ form.append("encryptedIV", payload.encryptedIV)
242
+ form.append("file", new Blob([payload.encryptedData], {type: 'text/json'}), "curtain-settings.json")
228
243
  } else {
229
244
  form.append("file", new Blob([data], {type: 'text/json'}), "curtain-settings.json")
230
245
  }
@@ -236,8 +251,10 @@ export class CurtainWebAPI {
236
251
  headers["Content-Type"] = "multipart/form-data";
237
252
  if (onUploadProgress !== undefined) {
238
253
  return await this.axiosInstance.post(this.baseURL + "curtain/", form, {headers: headers, responseType:"json", onUploadProgress: onUploadProgress})
254
+ } else {
255
+ return await this.axiosInstance.post(this.baseURL + "curtain/", form, {headers: headers, responseType:"json"})
239
256
  }
240
- return await this.axiosInstance.post(this.baseURL + "curtain/", form, {headers: headers, responseType:"json"})
257
+
241
258
  }
242
259
 
243
260
  postSettings(id: string, token: string, onDownloadProgress: any = undefined) {
@@ -467,5 +484,19 @@ export class CurtainWebAPI {
467
484
  headers["Content-Type"] = "application/json";
468
485
  return this.axiosInstance.get(this.baseURL + `stats/summary/${lastNDays}/`, {responseType:"json", headers})
469
486
  }
487
+
488
+ postEncryptionFactors(encryptedAESKey: string, encryptedIV: string, linkId: string) {
489
+ let headers = new AxiosHeaders();
490
+ headers["Accept"] = "application/json";
491
+ headers["Content-Type"] = "application/json";
492
+ return this.axiosInstance.post(this.baseURL + "curtain/" + linkId + "/set_encryption_factors/", {encryption_key: encryptedAESKey, encryption_iv: encryptedIV}, {headers: headers, responseType: "json"}).then((response) => {return response;});
493
+ }
494
+
495
+ getEncryptionFactors(linkId: string) {
496
+ let headers = new AxiosHeaders();
497
+ headers["Accept"] = "application/json";
498
+ headers["Content-Type"] = "application/json";
499
+ return this.axiosInstance.get(this.baseURL + "curtain/" + linkId + "/get_encryption_factors/", {headers: headers, responseType: "json"}).then((response) => {return response;});
500
+ }
470
501
  }
471
502
 
@@ -103,4 +103,68 @@ export function pemToArrayBuffer(pem: string) {
103
103
  b64Final = b64Final.replace('-----END PUBLIC KEY-----', '');
104
104
 
105
105
  return base64ToArrayBuffer(b64Final);
106
- }
106
+ }
107
+
108
+ // a function to generate to encrypt an aes key arraybuffer with a public key
109
+ export async function encryptAESKey(publicKey: CryptoKey, aesKey: ArrayBuffer) {
110
+ return await crypto.subtle.encrypt({name: "RSA-OAEP"}, publicKey, aesKey)
111
+ }
112
+
113
+ // a function to generate an aes key in GCM mode with a length of 256 bits
114
+ export async function generateAESKey() {
115
+ return await crypto.subtle.generateKey(
116
+ {
117
+ name: "AES-GCM",
118
+ length: 256,
119
+ },
120
+ true,
121
+ ["encrypt", "decrypt"],
122
+ )
123
+ }
124
+
125
+ // a function to encrypt a string with an aes key
126
+ export async function encryptAESData(aesKey: CryptoKey, data: string) {
127
+ const iv = crypto.getRandomValues(new Uint8Array(12))
128
+ const enc = new TextEncoder()
129
+ const encoded = enc.encode(data)
130
+ const encrypted = await crypto.subtle.encrypt({name: "AES-GCM", iv: iv}, aesKey, encoded)
131
+ return {encrypted: arrayBufferToBase64String(encrypted), iv: arrayBufferToBase64String(iv)}
132
+ }
133
+
134
+ // a function to decrypt a string with an aes key
135
+ export async function decryptAESData(aesKey: CryptoKey, data: string, iv: string) {
136
+ const dec = new TextDecoder()
137
+ const decrypted = await crypto.subtle.decrypt({name: "AES-GCM", iv: base64ToArrayBuffer(iv)}, aesKey, base64ToArrayBuffer(data))
138
+ return dec.decode(decrypted)
139
+ }
140
+
141
+ // a function to decrypt an aes key with a private key
142
+ export async function decryptAESKey(privateKey: CryptoKey, encryptedKey: ArrayBuffer) {
143
+ return await crypto.subtle.decrypt({name: "RSA-OAEP"}, privateKey, encryptedKey)
144
+ }
145
+
146
+ // a function to export an aes key to a string
147
+ export async function exportAESKey(key: CryptoKey) {
148
+ return await crypto.subtle.exportKey("raw", key)
149
+ }
150
+ // a function to import an aes key from a string
151
+ export async function importAESKey(key: ArrayBuffer) {
152
+ return await crypto.subtle.importKey("raw", key, "AES-GCM", true, ["encrypt", "decrypt"])
153
+ }
154
+
155
+ // a function to encrypt aes key with a public key and also use the aes key to encrypt a large string then return the encrypted aes key and the encrypted string
156
+ export async function encryptDataAES(data: string, publicKey: CryptoKey) {
157
+ const aesKey = await generateAESKey()
158
+ const encryptedKey = await encryptAESKey(publicKey, await exportAESKey(aesKey))
159
+ const encryptedData = await encryptAESData(aesKey, data)
160
+ return {encryptedKey: arrayBufferToBase64String(encryptedKey), encryptedData: encryptedData}
161
+ }
162
+
163
+ // a function to decrypt an aes key with a private key and use the aes key to decrypt a large string
164
+ export async function decryptDataAES(encryptedKey: ArrayBuffer, encryptedData: string, iv: string, privateKey: CryptoKey) {
165
+ const aesKey = await decryptAESKey(privateKey, encryptedKey)
166
+ //import aes key
167
+ return await decryptAESData(await importAESKey(aesKey), encryptedData, iv)
168
+ }
169
+
170
+