mosquito-transport-js 0.3.2 → 0.3.4
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 +3 -3
- package/src/helpers/peripherals.js +20 -19
- package/src/helpers/utils.js +16 -3
- package/src/index.d.ts +32 -6
- package/src/index.js +57 -19
- package/src/products/auth/accessor.js +14 -10
- package/src/products/auth/index.js +21 -21
- package/src/products/database/index.js +37 -31
- package/src/products/http_callable/index.js +8 -7
- package/src/products/storage/index.js +1 -1
- package/src/polyfill.js +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mosquito-transport-js",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Javascript web sdk for mosquito-transport (https://github.com/deflexable/mosquito-transport)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"bson": "^6.8.0",
|
|
33
33
|
"buffer": "^6.0.3",
|
|
34
34
|
"crypto-js": "^4.2.0",
|
|
35
|
+
"entity-serializer": "^1.0.1",
|
|
35
36
|
"guard-object": "^1.1.3",
|
|
36
37
|
"limit-task": "1.0.0",
|
|
37
|
-
"json-buffer": "^3.0.1",
|
|
38
38
|
"lodash.clonedeep": "^4.5.0",
|
|
39
39
|
"lodash.get": "^4.4.2",
|
|
40
40
|
"lodash.set": "^4.3.2",
|
|
@@ -57,4 +57,4 @@
|
|
|
57
57
|
"engines": {
|
|
58
58
|
"node": ">=14"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
|
@@ -5,6 +5,7 @@ import Utf8Encoder from 'crypto-js/enc-utf8.js';
|
|
|
5
5
|
import naclPkg from 'tweetnacl-functional';
|
|
6
6
|
import getLodash from "lodash.get";
|
|
7
7
|
import e2e_worker from "./e2e_worker";
|
|
8
|
+
import { deserialize, serialize } from "entity-serializer";
|
|
8
9
|
|
|
9
10
|
const { encrypt, decrypt } = aes_pkg;
|
|
10
11
|
const { box, randomBytes } = naclPkg;
|
|
@@ -104,51 +105,51 @@ export const decryptString = (txt, password, iv) => {
|
|
|
104
105
|
};
|
|
105
106
|
|
|
106
107
|
export const serializeE2E = async (data, auth_token, serverPublicKey) => {
|
|
107
|
-
const inputData =
|
|
108
|
+
const inputData = serialize([data, auth_token]);
|
|
108
109
|
|
|
109
110
|
if (inputData.byteLength > 10240) {
|
|
110
111
|
// dispatch to background thread
|
|
111
|
-
const { data, pair, nonce } = e2e_worker.encrypt(inputData, serverPublicKey);
|
|
112
|
-
const pubBase64 = Buffer.from(pair.publicKey).toString('base64'),
|
|
113
|
-
nonceBase64 = Buffer.from(nonce).toString('base64');
|
|
112
|
+
const { data, pair, nonce } = await e2e_worker.encrypt(inputData, serverPublicKey);
|
|
114
113
|
|
|
115
114
|
return [
|
|
116
|
-
|
|
115
|
+
serialize([pair.publicKey, nonce, data]),
|
|
117
116
|
[pair.secretKey, pair.publicKey]
|
|
118
117
|
];
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
const pair = box.keyPair(),
|
|
122
|
-
nonce = randomBytes(box.nonceLength)
|
|
123
|
-
pubBase64 = Buffer.from(pair.publicKey).toString('base64'),
|
|
124
|
-
nonceBase64 = Buffer.from(nonce).toString('base64');
|
|
121
|
+
nonce = randomBytes(box.nonceLength);
|
|
125
122
|
|
|
126
123
|
return [
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
serialize([
|
|
125
|
+
pair.publicKey,
|
|
126
|
+
nonce,
|
|
127
|
+
Buffer.from(
|
|
128
|
+
box(
|
|
129
|
+
inputData,
|
|
130
|
+
nonce,
|
|
131
|
+
serverPublicKey,
|
|
132
|
+
pair.secretKey
|
|
133
|
+
)
|
|
133
134
|
)
|
|
134
|
-
)
|
|
135
|
+
]),
|
|
135
136
|
[pair.secretKey, pair.publicKey]
|
|
136
137
|
];
|
|
137
138
|
};
|
|
138
139
|
|
|
139
|
-
export const deserializeE2E = async (data
|
|
140
|
-
const [binaryNonce, binaryData] = data
|
|
140
|
+
export const deserializeE2E = async (data, serverPublicKey, clientPrivateKey) => {
|
|
141
|
+
const [binaryNonce, binaryData] = deserialize(data);
|
|
141
142
|
let baseArray;
|
|
142
143
|
|
|
143
144
|
if (binaryData.byteLength > 10240) {
|
|
144
145
|
// dispatch to background thread
|
|
145
|
-
baseArray = e2e_worker.decrypt(binaryData, binaryNonce, serverPublicKey, clientPrivateKey);
|
|
146
|
+
baseArray = await e2e_worker.decrypt(binaryData, binaryNonce, serverPublicKey, clientPrivateKey);
|
|
146
147
|
} else {
|
|
147
148
|
baseArray = box.open(binaryData, binaryNonce, serverPublicKey, clientPrivateKey);
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
if (!baseArray) throw 'Decrypting e2e message failed';
|
|
151
|
-
return
|
|
152
|
+
return deserialize(baseArray);
|
|
152
153
|
};
|
|
153
154
|
|
|
154
155
|
export const encodeBinary = (s) => Buffer.from(s, 'utf8').toString('base64');
|
package/src/helpers/utils.js
CHANGED
|
@@ -4,6 +4,7 @@ import { CacheStore, Scoped } from "./variables";
|
|
|
4
4
|
import { decryptString, encryptString, serializeE2E } from "./peripherals";
|
|
5
5
|
import { deserializeBSON, serializeToBase64 } from "../products/database/bson";
|
|
6
6
|
import { trySendPendingWrite } from "../products/database";
|
|
7
|
+
import { deserialize } from "entity-serializer";
|
|
7
8
|
|
|
8
9
|
export const updateCacheStore = (timer = 300) => {
|
|
9
10
|
try { window } catch (_) { return; }
|
|
@@ -116,7 +117,7 @@ export const getReachableServer = (projectUrl) => new Promise(resolve => {
|
|
|
116
117
|
}, true);
|
|
117
118
|
});
|
|
118
119
|
|
|
119
|
-
export const buildFetchInterface = async ({ body, accessKey, authToken, method, uglify, serverE2E_PublicKey }) => {
|
|
120
|
+
export const buildFetchInterface = async ({ body, accessKey, authToken, method, uglify, serverE2E_PublicKey, extraHeaders }) => {
|
|
120
121
|
if (!uglify) body = JSON.stringify({ ...body });
|
|
121
122
|
const [plate, keyPair] = uglify ? await serializeE2E(body, authToken, serverE2E_PublicKey) : [undefined, []];
|
|
122
123
|
|
|
@@ -124,10 +125,22 @@ export const buildFetchInterface = async ({ body, accessKey, authToken, method,
|
|
|
124
125
|
body: uglify ? plate : body,
|
|
125
126
|
cache: 'no-cache',
|
|
126
127
|
headers: {
|
|
127
|
-
'Content-type': uglify ? '
|
|
128
|
+
'Content-type': uglify ? 'request/buffer' : 'application/json',
|
|
128
129
|
'Authorization': accessKey,
|
|
129
|
-
...(
|
|
130
|
+
...(authToken && !uglify) ? { 'Mosquito-Token': authToken } : {},
|
|
131
|
+
...extraHeaders
|
|
130
132
|
},
|
|
131
133
|
method: method || 'POST'
|
|
132
134
|
}, keyPair];
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const buildFetchResult = async (fetchRef, ugly) => {
|
|
138
|
+
if (ugly) {
|
|
139
|
+
const [data, simpleError] = deserialize(await fetchRef.arrayBuffer());
|
|
140
|
+
if (simpleError) throw simpleError;
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
const json = await fetchRef.json();
|
|
144
|
+
if (json.simpleError) throw json;
|
|
145
|
+
return json;
|
|
133
146
|
};
|
package/src/index.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ interface MTConfig {
|
|
|
16
16
|
* this is the base64 public key for end-to-end encryption on the server
|
|
17
17
|
*/
|
|
18
18
|
serverE2E_PublicKey?: string;
|
|
19
|
+
/**
|
|
20
|
+
* extra headers that will be appended to all outgoing request in this instance
|
|
21
|
+
*/
|
|
22
|
+
extraHeaders?: {
|
|
23
|
+
[key: string]: string
|
|
24
|
+
};
|
|
19
25
|
/**
|
|
20
26
|
* true to deserialize BSON values to their Node.js closest equivalent types
|
|
21
27
|
*
|
|
@@ -54,6 +60,13 @@ export function FIND_GEO_JSON(coordinates: [latitude, longitude], offSetMeters:
|
|
|
54
60
|
|
|
55
61
|
export const AUTH_PROVIDER_ID: auth_provider_id;
|
|
56
62
|
|
|
63
|
+
/**
|
|
64
|
+
* useful for avoiding encrypting data and extra overhead
|
|
65
|
+
*/
|
|
66
|
+
export class DoNotEncrypt {
|
|
67
|
+
value: any;
|
|
68
|
+
}
|
|
69
|
+
|
|
57
70
|
interface auth_provider_id {
|
|
58
71
|
GOOGLE: 'google.com';
|
|
59
72
|
FACEBOOK: 'facebook.com';
|
|
@@ -436,14 +449,27 @@ interface TokenManager {
|
|
|
436
449
|
|
|
437
450
|
declare type Base64String = string;
|
|
438
451
|
|
|
439
|
-
interface
|
|
440
|
-
|
|
452
|
+
interface UploadOptions {
|
|
453
|
+
/**
|
|
454
|
+
* optionally create hash for this upload to save disk space
|
|
455
|
+
*/
|
|
441
456
|
createHash?: boolean;
|
|
457
|
+
/**
|
|
458
|
+
* wait for a reachable server before initiating the upload task
|
|
459
|
+
*/
|
|
460
|
+
awaitServer?: boolean;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
interface DownloadOptions {
|
|
464
|
+
/**
|
|
465
|
+
* wait for a reachable server before initiating the download task
|
|
466
|
+
*/
|
|
467
|
+
awaitServer?: boolean;
|
|
442
468
|
}
|
|
443
469
|
|
|
444
470
|
interface MTStorage {
|
|
445
|
-
downloadFile: (link: string, onComplete?: (error?: ErrorResponse, filepath?: string) => void, destination?: string, onProgress?: (stats: DownloadProgressStats) => void) => () => void;
|
|
446
|
-
uploadFile: (file: Base64String | Blob |
|
|
471
|
+
downloadFile: (link: string, onComplete?: (error?: ErrorResponse, filepath?: string) => void, destination?: string, onProgress?: (stats: DownloadProgressStats) => void, options?: DownloadOptions) => () => void;
|
|
472
|
+
uploadFile: (file: Base64String | Blob | File | Buffer, destination: string, onComplete?: (error?: ErrorResponse, downloadUrl?: string) => void, onProgress?: (stats: UploadProgressStats) => void, options?: UploadOptions) => () => void;
|
|
447
473
|
deleteFile: (path: string) => Promise<void>;
|
|
448
474
|
deleteFolder: (folder: string) => Promise<void>;
|
|
449
475
|
}
|
|
@@ -467,13 +493,13 @@ interface ErrorResponse {
|
|
|
467
493
|
}
|
|
468
494
|
|
|
469
495
|
/** @public */
|
|
470
|
-
|
|
496
|
+
declare type Sort = string | Exclude<SortDirection, {
|
|
471
497
|
$meta: string;
|
|
472
498
|
}> | string[] | {
|
|
473
499
|
[key: string]: SortDirection;
|
|
474
500
|
} | Map<string, SortDirection> | [string, SortDirection][] | [string, SortDirection];
|
|
475
501
|
|
|
476
502
|
/** @public */
|
|
477
|
-
|
|
503
|
+
declare type SortDirection = 1 | -1 | 'asc' | 'desc' | 'ascending' | 'descending' | {
|
|
478
504
|
$meta: string;
|
|
479
505
|
};
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import './polyfill';
|
|
2
1
|
import { deserializeE2E, listenReachableServer, serializeE2E } from "./helpers/peripherals";
|
|
3
2
|
import { releaseCacheStore, awaitStore } from "./helpers/utils";
|
|
4
3
|
import { CacheStore, Scoped } from "./helpers/variables";
|
|
@@ -12,7 +11,6 @@ import { mfetch } from "./products/http_callable";
|
|
|
12
11
|
import { io } from "socket.io-client";
|
|
13
12
|
import { AUTH_PROVIDER_ID, CACHE_PROTOCOL } from "./helpers/values";
|
|
14
13
|
import EngineApi from './helpers/engine_api';
|
|
15
|
-
import { parse, stringify } from 'json-buffer';
|
|
16
14
|
import { Validator } from 'guard-object';
|
|
17
15
|
import sendMessage from "./helpers/broadcaster";
|
|
18
16
|
import cloneDeep from "lodash.clonedeep";
|
|
@@ -46,7 +44,7 @@ export class MosquitoTransport {
|
|
|
46
44
|
maxRetries: config.maxRetries || 3,
|
|
47
45
|
uglify: config.enableE2E_Encryption
|
|
48
46
|
};
|
|
49
|
-
const { projectUrl } = this.config;
|
|
47
|
+
const { projectUrl, extraHeaders } = this.config;
|
|
50
48
|
|
|
51
49
|
this.config.secureUrl = projectUrl.startsWith('https');
|
|
52
50
|
this.config.baseUrl = projectUrl.split('://')[1];
|
|
@@ -67,6 +65,7 @@ export class MosquitoTransport {
|
|
|
67
65
|
|
|
68
66
|
const socket = io(`${this.config.wsPrefix}://${this.config.baseUrl}`, {
|
|
69
67
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
68
|
+
extraHeaders,
|
|
70
69
|
auth: {
|
|
71
70
|
_m_internal: true,
|
|
72
71
|
_from_base: true
|
|
@@ -154,7 +153,7 @@ export class MosquitoTransport {
|
|
|
154
153
|
|
|
155
154
|
getSocket = (configOpts) => {
|
|
156
155
|
const { disableAuth, authHandshake } = configOpts || {};
|
|
157
|
-
const { projectUrl, uglify, accessKey, serverE2E_PublicKey, wsPrefix } = this.config;
|
|
156
|
+
const { projectUrl, uglify, accessKey, serverE2E_PublicKey, wsPrefix, extraHeaders } = this.config;
|
|
158
157
|
|
|
159
158
|
const restrictedRoute = [
|
|
160
159
|
_listenCollection,
|
|
@@ -185,22 +184,23 @@ export class MosquitoTransport {
|
|
|
185
184
|
return;
|
|
186
185
|
}
|
|
187
186
|
|
|
188
|
-
const [args, emitable] = [...arguments];
|
|
187
|
+
const [[args, not_encrypted], emitable] = [...arguments];
|
|
189
188
|
let res;
|
|
190
189
|
|
|
191
190
|
if (uglify) {
|
|
192
|
-
res =
|
|
191
|
+
res = await deserializeE2E(args, serverE2E_PublicKey, clientPrivateKey);
|
|
193
192
|
} else res = args;
|
|
193
|
+
const sortedArgs = discloseSocketArguments([res, not_encrypted]);
|
|
194
194
|
|
|
195
|
-
callback?.(...
|
|
196
|
-
const args = [...arguments];
|
|
195
|
+
callback?.(...sortedArgs, ...typeof emitable === 'function' ? [async function () {
|
|
196
|
+
const [args, not_encrypted] = encloseSocketArguments([...arguments]);
|
|
197
197
|
let res;
|
|
198
198
|
|
|
199
199
|
if (uglify) {
|
|
200
|
-
res = (await serializeE2E(
|
|
200
|
+
res = (await serializeE2E(args, undefined, serverE2E_PublicKey))[0];
|
|
201
201
|
} else res = args;
|
|
202
202
|
|
|
203
|
-
emitable(res);
|
|
203
|
+
emitable([res, not_encrypted]);
|
|
204
204
|
}] : []);
|
|
205
205
|
};
|
|
206
206
|
|
|
@@ -229,28 +229,29 @@ export class MosquitoTransport {
|
|
|
229
229
|
|
|
230
230
|
const lastEmit = emittion.slice(-1)[0];
|
|
231
231
|
const hasEmitable = typeof lastEmit === 'function';
|
|
232
|
-
const mit = hasEmitable ? emittion.slice(0, -1) : emittion;
|
|
232
|
+
const [mit, not_encrypted] = encloseSocketArguments(hasEmitable ? emittion.slice(0, -1) : emittion);
|
|
233
233
|
|
|
234
|
-
const [reqBuilder, [privateKey]] = uglify ? await serializeE2E(
|
|
234
|
+
const [reqBuilder, [privateKey]] = uglify ? await serializeE2E(mit, undefined, serverE2E_PublicKey) : [undefined, []];
|
|
235
235
|
|
|
236
236
|
if (hasEmitable && promise)
|
|
237
237
|
throw 'emitWithAck cannot have function in it argument';
|
|
238
238
|
|
|
239
239
|
const result = await thisSocket[promise ? 'emitWithAck' : 'emit'](route,
|
|
240
|
-
uglify ? reqBuilder : mit,
|
|
240
|
+
[uglify ? reqBuilder : mit, not_encrypted],
|
|
241
241
|
...hasEmitable ? [async function () {
|
|
242
|
-
const [args] = [...arguments];
|
|
242
|
+
const [[args, not_encrypted]] = [...arguments];
|
|
243
243
|
let res;
|
|
244
244
|
|
|
245
245
|
if (uglify) {
|
|
246
|
-
res =
|
|
246
|
+
res = await deserializeE2E(args, serverE2E_PublicKey, privateKey);
|
|
247
247
|
} else res = args;
|
|
248
248
|
|
|
249
|
-
lastEmit(...res
|
|
249
|
+
lastEmit(...discloseSocketArguments([res, not_encrypted]));
|
|
250
250
|
}] : []
|
|
251
251
|
);
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
if (promise && result) {
|
|
253
|
+
resolve(discloseSocketArguments([uglify ? await deserializeE2E(result[0], serverE2E_PublicKey, privateKey) : result[0], result[1]])[0]);
|
|
254
|
+
} else resolve();
|
|
254
255
|
} catch (e) {
|
|
255
256
|
reject(e);
|
|
256
257
|
}
|
|
@@ -263,9 +264,10 @@ export class MosquitoTransport {
|
|
|
263
264
|
|
|
264
265
|
socket = io(`${wsPrefix}://${projectUrl.split('://')[1]}`, {
|
|
265
266
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
267
|
+
extraHeaders,
|
|
266
268
|
auth: uglify ? {
|
|
267
269
|
ugly: true,
|
|
268
|
-
e2e: reqBuilder
|
|
270
|
+
e2e: reqBuilder.toString('base64')
|
|
269
271
|
} : {
|
|
270
272
|
...mtoken ? { mtoken } : {},
|
|
271
273
|
a_extras: authHandshake,
|
|
@@ -359,6 +361,31 @@ export class MosquitoTransport {
|
|
|
359
361
|
}
|
|
360
362
|
};
|
|
361
363
|
|
|
364
|
+
class DoNotEncrypt {
|
|
365
|
+
constructor(value) {
|
|
366
|
+
this.value = value;
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const encloseSocketArguments = (args) => {
|
|
371
|
+
const [encrypted, unencrypted] = [{}, {}];
|
|
372
|
+
|
|
373
|
+
args.forEach((v, i) => {
|
|
374
|
+
if (v instanceof DoNotEncrypt) {
|
|
375
|
+
unencrypted[i] = v.value;
|
|
376
|
+
} else encrypted[i] = v;
|
|
377
|
+
});
|
|
378
|
+
return [encrypted, unencrypted];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const discloseSocketArguments = (args = []) => {
|
|
382
|
+
return args.map((obj, i) => Object.entries(obj).map(v => i ? [v[0], new DoNotEncrypt(v[1])] : v)).flat()
|
|
383
|
+
.sort((a, b) => (a[0] * 1) - (b[0] * 1)).map((v, i) => {
|
|
384
|
+
if (v[0] * 1 !== i) throw 'corrupted socket arguments';
|
|
385
|
+
return v[1];
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
362
389
|
const validateReleaseCacheProp = (prop) => {
|
|
363
390
|
const cacheList = [...Object.values(CACHE_PROTOCOL)];
|
|
364
391
|
|
|
@@ -426,6 +453,16 @@ const validator = {
|
|
|
426
453
|
serverE2E_PublicKey: (v) => {
|
|
427
454
|
if (typeof v !== 'string' || !v.trim())
|
|
428
455
|
throw `Invalid value supplied to serverETE_PublicKey, value must be a non-empty string`;
|
|
456
|
+
},
|
|
457
|
+
extraHeaders: v => {
|
|
458
|
+
if (!Validator.OBJECT(v)) throw '"extraHeaders" must be an object';
|
|
459
|
+
const reservedHeaders = ['mtoken', 'mosquito-token', 'init-content-type', 'content-type', 'authorization', 'uglified'];
|
|
460
|
+
|
|
461
|
+
Object.entries(v).forEach(([k, v]) => {
|
|
462
|
+
if (typeof v !== 'string') throw `expected a string at extraHeaders.${k} but got "${v}"`;
|
|
463
|
+
if (reservedHeaders.includes(v.toLowerCase()))
|
|
464
|
+
throw `extraHeaders must not include any reserved props which are: ${reservedHeaders}`;
|
|
465
|
+
});
|
|
429
466
|
}
|
|
430
467
|
};
|
|
431
468
|
|
|
@@ -445,6 +482,7 @@ const validateMTConfig = (config, that) => {
|
|
|
445
482
|
}
|
|
446
483
|
|
|
447
484
|
export {
|
|
485
|
+
DoNotEncrypt,
|
|
448
486
|
TIMESTAMP,
|
|
449
487
|
DOCUMENT_EXTRACTION,
|
|
450
488
|
FIND_GEO_JSON,
|
|
@@ -2,7 +2,7 @@ import { doSignOut } from ".";
|
|
|
2
2
|
import EngineApi from "../../helpers/engine_api";
|
|
3
3
|
import { AuthTokenListener, TokenRefreshListener } from "../../helpers/listeners";
|
|
4
4
|
import { decodeBinary, deserializeE2E, listenReachableServer } from "../../helpers/peripherals";
|
|
5
|
-
import { awaitStore, buildFetchInterface, getPrefferTime, updateCacheStore } from "../../helpers/utils";
|
|
5
|
+
import { awaitStore, buildFetchInterface, buildFetchResult, getPrefferTime, updateCacheStore } from "../../helpers/utils";
|
|
6
6
|
import { CacheStore, Scoped } from "../../helpers/variables";
|
|
7
7
|
import { simplifyError } from "simplify-error";
|
|
8
8
|
|
|
@@ -75,8 +75,8 @@ export const initTokenRefresher = async (config, forceRefresh) => {
|
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7, isForceRefresh) => new Promise(async (resolve, reject) => {
|
|
78
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
79
|
-
const lostProcess = simplifyError('process_lost', 'The token refresh process has been lost and
|
|
78
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
79
|
+
const lostProcess = simplifyError('process_lost', 'The token refresh process has been lost and replaced with another one');
|
|
80
80
|
|
|
81
81
|
try {
|
|
82
82
|
const { token, refreshToken: r_token } = CacheStore.AuthStore[projectUrl];
|
|
@@ -85,18 +85,22 @@ const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7
|
|
|
85
85
|
body: { token, r_token },
|
|
86
86
|
accessKey,
|
|
87
87
|
uglify,
|
|
88
|
-
serverE2E_PublicKey
|
|
88
|
+
serverE2E_PublicKey,
|
|
89
|
+
extraHeaders
|
|
89
90
|
});
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
let data;
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
try {
|
|
95
|
+
data = await buildFetchResult(await fetch(EngineApi._refreshAuthToken(projectUrl, uglify), reqBuilder), uglify);
|
|
96
|
+
} finally {
|
|
97
|
+
if (processRef !== Scoped.LastTokenRefreshRef[projectUrl]) {
|
|
98
|
+
reject(lostProcess.simpleError);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
96
101
|
}
|
|
97
|
-
if (r.simpleError) throw r;
|
|
98
102
|
|
|
99
|
-
const f = uglify ? await deserializeE2E(
|
|
103
|
+
const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
100
104
|
|
|
101
105
|
if (CacheStore.AuthStore[projectUrl]) {
|
|
102
106
|
CacheStore.AuthStore[projectUrl].token = f.result.token;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { io } from "socket.io-client";
|
|
2
2
|
import EngineApi from "../../helpers/engine_api";
|
|
3
3
|
import { TokenRefreshListener } from "../../helpers/listeners";
|
|
4
|
-
import { awaitReachableServer, awaitStore, buildFetchInterface, updateCacheStore } from "../../helpers/utils";
|
|
4
|
+
import { awaitReachableServer, awaitStore, buildFetchInterface, buildFetchResult, updateCacheStore } from "../../helpers/utils";
|
|
5
5
|
import { CacheStore, Scoped } from "../../helpers/variables";
|
|
6
6
|
import { awaitRefreshToken, initTokenRefresher, injectFreshToken, listenToken, parseToken, triggerAuthToken } from "./accessor";
|
|
7
7
|
import { deserializeE2E, encodeBinary, serializeE2E } from "../../helpers/peripherals";
|
|
@@ -66,7 +66,7 @@ export class MTAuth {
|
|
|
66
66
|
socket = io(`${wsPrefix}://${baseUrl}`, {
|
|
67
67
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
68
68
|
auth: uglify ? {
|
|
69
|
-
e2e: reqBuilder,
|
|
69
|
+
e2e: reqBuilder.toString('base64'),
|
|
70
70
|
_m_internal: true
|
|
71
71
|
} : { mtoken, _m_internal: true },
|
|
72
72
|
transports: ['websocket', 'polling', 'flashsocket']
|
|
@@ -167,7 +167,7 @@ export class MTAuth {
|
|
|
167
167
|
};
|
|
168
168
|
|
|
169
169
|
const doCustomSignin = (builder, email, password) => new Promise(async (resolve, reject) => {
|
|
170
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
170
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
171
171
|
|
|
172
172
|
try {
|
|
173
173
|
await awaitStore();
|
|
@@ -175,13 +175,13 @@ const doCustomSignin = (builder, email, password) => new Promise(async (resolve,
|
|
|
175
175
|
body: { data: `${encodeBinary(email)}.${encodeBinary(password)}` },
|
|
176
176
|
accessKey,
|
|
177
177
|
serverE2E_PublicKey,
|
|
178
|
-
uglify
|
|
178
|
+
uglify,
|
|
179
|
+
extraHeaders
|
|
179
180
|
});
|
|
180
181
|
|
|
181
|
-
const
|
|
182
|
-
if (f.simpleError) throw f;
|
|
182
|
+
const data = await buildFetchResult(await fetch(_customSignin(projectUrl, uglify), reqBuilder), uglify);
|
|
183
183
|
|
|
184
|
-
const r = uglify ? await deserializeE2E(
|
|
184
|
+
const r = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
185
185
|
|
|
186
186
|
resolve({
|
|
187
187
|
user: parseToken(r.result.token),
|
|
@@ -195,7 +195,7 @@ const doCustomSignin = (builder, email, password) => new Promise(async (resolve,
|
|
|
195
195
|
});
|
|
196
196
|
|
|
197
197
|
const doCustomSignup = (builder, email, password, name, metadata) => new Promise(async (resolve, reject) => {
|
|
198
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
198
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
199
199
|
|
|
200
200
|
try {
|
|
201
201
|
await awaitStore();
|
|
@@ -206,13 +206,13 @@ const doCustomSignup = (builder, email, password, name, metadata) => new Promise
|
|
|
206
206
|
},
|
|
207
207
|
accessKey,
|
|
208
208
|
serverE2E_PublicKey,
|
|
209
|
-
uglify
|
|
209
|
+
uglify,
|
|
210
|
+
extraHeaders
|
|
210
211
|
});
|
|
211
212
|
|
|
212
|
-
const
|
|
213
|
-
if (f.simpleError) throw f;
|
|
213
|
+
const data = await buildFetchResult(await fetch(_customSignup(projectUrl, uglify), reqBuilder), uglify);
|
|
214
214
|
|
|
215
|
-
const r = uglify ? await deserializeE2E(
|
|
215
|
+
const r = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
216
216
|
|
|
217
217
|
resolve({
|
|
218
218
|
user: parseToken(r.result.token),
|
|
@@ -239,7 +239,7 @@ export const clearCacheForSignout = (builder) => {
|
|
|
239
239
|
export const doSignOut = async (builder) => {
|
|
240
240
|
await awaitStore();
|
|
241
241
|
|
|
242
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder,
|
|
242
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder,
|
|
243
243
|
{ token, refreshToken: r_token } = CacheStore.AuthStore[projectUrl];
|
|
244
244
|
|
|
245
245
|
clearCacheForSignout(builder);
|
|
@@ -253,11 +253,11 @@ export const doSignOut = async (builder) => {
|
|
|
253
253
|
body: { token, r_token },
|
|
254
254
|
accessKey,
|
|
255
255
|
uglify,
|
|
256
|
-
serverE2E_PublicKey
|
|
256
|
+
serverE2E_PublicKey,
|
|
257
|
+
extraHeaders
|
|
257
258
|
});
|
|
258
259
|
|
|
259
|
-
|
|
260
|
-
if (r.simpleError) throw r;
|
|
260
|
+
await buildFetchResult(await fetch(_signOut(projectUrl, uglify), reqBuilder), uglify);
|
|
261
261
|
} catch (e) {
|
|
262
262
|
throw simplifyCaughtError(e).simpleError;
|
|
263
263
|
}
|
|
@@ -265,7 +265,7 @@ export const doSignOut = async (builder) => {
|
|
|
265
265
|
};
|
|
266
266
|
|
|
267
267
|
const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) => {
|
|
268
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
268
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
269
269
|
|
|
270
270
|
try {
|
|
271
271
|
await awaitStore();
|
|
@@ -273,13 +273,13 @@ const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) =
|
|
|
273
273
|
body: { token },
|
|
274
274
|
accessKey,
|
|
275
275
|
uglify,
|
|
276
|
-
serverE2E_PublicKey
|
|
276
|
+
serverE2E_PublicKey,
|
|
277
|
+
extraHeaders
|
|
277
278
|
});
|
|
278
279
|
|
|
279
|
-
const
|
|
280
|
-
if (r.simpleError) throw r;
|
|
280
|
+
const data = await buildFetchResult(await fetch(_googleSignin(projectUrl, uglify), reqBuilder), uglify);
|
|
281
281
|
|
|
282
|
-
const f = uglify ? await deserializeE2E(
|
|
282
|
+
const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
283
283
|
|
|
284
284
|
resolve({
|
|
285
285
|
user: parseToken(f.result.token),
|
|
@@ -2,7 +2,7 @@ import { io } from "socket.io-client";
|
|
|
2
2
|
import EngineApi from "../../helpers/engine_api";
|
|
3
3
|
import { DatabaseRecordsListener } from "../../helpers/listeners";
|
|
4
4
|
import { deserializeE2E, listenReachableServer, niceTry, serializeE2E } from "../../helpers/peripherals";
|
|
5
|
-
import { awaitStore, buildFetchInterface, getReachableServer } from "../../helpers/utils";
|
|
5
|
+
import { awaitStore, buildFetchInterface, buildFetchResult, getReachableServer } from "../../helpers/utils";
|
|
6
6
|
import { CacheStore, Scoped } from "../../helpers/variables";
|
|
7
7
|
import { addPendingWrites, generateRecordID, getRecord, insertRecord, listenQueryEntry, removePendingWrite, validateWriteValue } from "./accessor";
|
|
8
8
|
import { validateCollectionName, validateFilter, validateFindConfig, validateFindObject, validateListenFindConfig } from "./validator";
|
|
@@ -130,7 +130,7 @@ const {
|
|
|
130
130
|
} = EngineApi;
|
|
131
131
|
|
|
132
132
|
const listenDocument = (callback, onError, builder, config) => {
|
|
133
|
-
const { projectUrl, wsPrefix, serverE2E_PublicKey, baseUrl, dbUrl, dbName, accessKey, path, disableCache, command, uglify, castBSON } = builder;
|
|
133
|
+
const { projectUrl, wsPrefix, serverE2E_PublicKey, baseUrl, dbUrl, dbName, accessKey, path, disableCache, command, uglify, extraHeaders, castBSON } = builder;
|
|
134
134
|
const { find, findOne, sort, direction, limit } = command;
|
|
135
135
|
const { disableAuth } = config || {};
|
|
136
136
|
const shouldCache = !disableCache;
|
|
@@ -185,14 +185,14 @@ const listenDocument = (callback, onError, builder, config) => {
|
|
|
185
185
|
const mtoken = disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl];
|
|
186
186
|
const pureConfig = stripRequestConfig(config);
|
|
187
187
|
const authObj = {
|
|
188
|
-
commands: {
|
|
188
|
+
commands: stripUndefined({
|
|
189
189
|
config: pureConfig && serializeToBase64(pureConfig),
|
|
190
190
|
path,
|
|
191
191
|
find: serializeToBase64(findOne || find),
|
|
192
192
|
sort,
|
|
193
193
|
direction,
|
|
194
194
|
limit
|
|
195
|
-
},
|
|
195
|
+
}),
|
|
196
196
|
dbName,
|
|
197
197
|
dbUrl
|
|
198
198
|
};
|
|
@@ -201,7 +201,8 @@ const listenDocument = (callback, onError, builder, config) => {
|
|
|
201
201
|
|
|
202
202
|
socket = io(`${wsPrefix}://${baseUrl}`, {
|
|
203
203
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
204
|
-
|
|
204
|
+
extraHeaders,
|
|
205
|
+
auth: uglify ? { e2e: encPlate.toString('base64'), _m_internal: true } : {
|
|
205
206
|
accessKey,
|
|
206
207
|
_body: authObj,
|
|
207
208
|
...mtoken ? { mtoken } : {},
|
|
@@ -257,7 +258,7 @@ const listenDocument = (callback, onError, builder, config) => {
|
|
|
257
258
|
};
|
|
258
259
|
|
|
259
260
|
const initOnDisconnectionTask = (builder, value, type) => {
|
|
260
|
-
const { projectUrl, wsPrefix, baseUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, path, command, uglify } = builder;
|
|
261
|
+
const { projectUrl, wsPrefix, baseUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, path, extraHeaders, command, uglify } = builder;
|
|
261
262
|
const { find } = command || {};
|
|
262
263
|
const disableAuth = false;
|
|
263
264
|
|
|
@@ -277,20 +278,21 @@ const initOnDisconnectionTask = (builder, value, type) => {
|
|
|
277
278
|
|
|
278
279
|
const mtoken = disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl];
|
|
279
280
|
const authObj = {
|
|
280
|
-
commands: {
|
|
281
|
+
commands: stripUndefined({
|
|
281
282
|
path,
|
|
282
283
|
find: find && serializeToBase64(find),
|
|
283
284
|
value: value && serializeToBase64({ _: value }),
|
|
284
285
|
scope: type
|
|
285
|
-
},
|
|
286
|
+
}),
|
|
286
287
|
dbName,
|
|
287
288
|
dbUrl
|
|
288
289
|
};
|
|
289
290
|
|
|
290
291
|
socket = io(`${wsPrefix}://${baseUrl}`, {
|
|
291
292
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
293
|
+
extraHeaders,
|
|
292
294
|
auth: uglify ? {
|
|
293
|
-
e2e: (await serializeE2E({ accessKey, _body: authObj }, mtoken, serverE2E_PublicKey))[0],
|
|
295
|
+
e2e: (await serializeE2E({ accessKey, _body: authObj }, mtoken, serverE2E_PublicKey))[0].toString('base64'),
|
|
294
296
|
_m_internal: true
|
|
295
297
|
} : {
|
|
296
298
|
...mtoken ? { mtoken } : {},
|
|
@@ -337,7 +339,7 @@ const initOnDisconnectionTask = (builder, value, type) => {
|
|
|
337
339
|
};
|
|
338
340
|
|
|
339
341
|
const countCollection = async (builder, config) => {
|
|
340
|
-
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, uglify, path, disableCache, command = {} } = builder;
|
|
342
|
+
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, uglify, extraHeaders, path, disableCache, command = {} } = builder;
|
|
341
343
|
const { find } = command;
|
|
342
344
|
const { disableAuth } = config || {};
|
|
343
345
|
const accessId = await generateRecordID({ ...builder, countDoc: true }, config);
|
|
@@ -357,8 +359,8 @@ const countCollection = async (builder, config) => {
|
|
|
357
359
|
|
|
358
360
|
const finalize = (a, b) => {
|
|
359
361
|
if (Validator.NUMBER(a)) {
|
|
360
|
-
|
|
361
|
-
} else
|
|
362
|
+
resolve(a);
|
|
363
|
+
} else reject(b);
|
|
362
364
|
};
|
|
363
365
|
|
|
364
366
|
try {
|
|
@@ -374,13 +376,13 @@ const countCollection = async (builder, config) => {
|
|
|
374
376
|
accessKey,
|
|
375
377
|
...disableAuth ? {} : { authToken: Scoped.AuthJWTToken[projectUrl] },
|
|
376
378
|
serverE2E_PublicKey,
|
|
377
|
-
uglify
|
|
379
|
+
uglify,
|
|
380
|
+
extraHeaders
|
|
378
381
|
});
|
|
379
382
|
|
|
380
|
-
const
|
|
381
|
-
if (r.simpleError) throw r;
|
|
383
|
+
const data = await buildFetchResult(await fetch(_documentCount(projectUrl, uglify), reqBuilder), uglify);
|
|
382
384
|
|
|
383
|
-
const f = uglify ? await deserializeE2E(
|
|
385
|
+
const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
384
386
|
|
|
385
387
|
if (!disableCache)
|
|
386
388
|
setLodash(CacheStore.DatabaseCountResult, [projectUrl, dbUrl, dbName, accessId], f.result);
|
|
@@ -420,13 +422,17 @@ const stripRequestConfig = (config) => {
|
|
|
420
422
|
return requestConfig.length ? Object.fromEntries(requestConfig) : undefined;
|
|
421
423
|
};
|
|
422
424
|
|
|
425
|
+
const stripUndefined = o => Object.fromEntries(
|
|
426
|
+
Object.entries(o).filter(v => v[1] !== undefined)
|
|
427
|
+
);
|
|
428
|
+
|
|
423
429
|
const transformBSON = (d, castBSON) => {
|
|
424
430
|
if (castBSON) return d && deserializeBSON(serializeToBase64({ _: d }), true)._;
|
|
425
431
|
return cloneDeep(d);
|
|
426
432
|
};
|
|
427
433
|
|
|
428
434
|
const findObject = async (builder, config) => {
|
|
429
|
-
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, path, disableCache, uglify, command, castBSON } = builder;
|
|
435
|
+
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, path, disableCache, uglify, extraHeaders, command, castBSON } = builder;
|
|
430
436
|
const { find, findOne, sort, direction, limit, random } = command;
|
|
431
437
|
const { retrieval = RETRIEVAL.DEFAULT, episode = 0, disableAuth, disableMinimizer } = config || {};
|
|
432
438
|
const enableMinimizer = !disableMinimizer;
|
|
@@ -499,7 +505,7 @@ const findObject = async (builder, config) => {
|
|
|
499
505
|
|
|
500
506
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
501
507
|
body: {
|
|
502
|
-
commands: {
|
|
508
|
+
commands: stripUndefined({
|
|
503
509
|
config: pureConfig && serializeToBase64(pureConfig),
|
|
504
510
|
path,
|
|
505
511
|
find: serializeToBase64(findOne || find),
|
|
@@ -507,20 +513,20 @@ const findObject = async (builder, config) => {
|
|
|
507
513
|
direction,
|
|
508
514
|
limit,
|
|
509
515
|
random
|
|
510
|
-
},
|
|
516
|
+
}),
|
|
511
517
|
dbName,
|
|
512
518
|
dbUrl
|
|
513
519
|
},
|
|
514
520
|
accessKey,
|
|
515
521
|
authToken: disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl],
|
|
516
522
|
serverE2E_PublicKey,
|
|
517
|
-
uglify
|
|
523
|
+
uglify,
|
|
524
|
+
extraHeaders
|
|
518
525
|
});
|
|
519
526
|
|
|
520
|
-
const
|
|
521
|
-
if (r.simpleError) throw r;
|
|
527
|
+
const data = await buildFetchResult(await fetch((findOne ? _readDocument : _queryCollection)(projectUrl, uglify), reqBuilder), uglify);
|
|
522
528
|
|
|
523
|
-
const result = deserializeBSON((uglify ? await deserializeE2E(
|
|
529
|
+
const result = deserializeBSON((uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data).result)._;
|
|
524
530
|
|
|
525
531
|
if (shouldCache) insertRecord(builder, config, accessId, result);
|
|
526
532
|
finalize({ liveResult: result || null });
|
|
@@ -589,7 +595,7 @@ const commitData = async (builder, value, type, config) => {
|
|
|
589
595
|
)._;
|
|
590
596
|
}
|
|
591
597
|
|
|
592
|
-
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, path, find, disableCache, uglify } = builder;
|
|
598
|
+
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, accessKey, maxRetries = 7, path, find, disableCache, uglify, extraHeaders } = builder;
|
|
593
599
|
const { disableAuth, delivery = DELIVERY.DEFAULT, stepping } = config || {};
|
|
594
600
|
const writeId = `${Date.now() + ++Scoped.PendingIte}`;
|
|
595
601
|
const isBatchWrite = type === 'batchWrite';
|
|
@@ -636,29 +642,29 @@ const commitData = async (builder, value, type, config) => {
|
|
|
636
642
|
|
|
637
643
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
638
644
|
body: {
|
|
639
|
-
commands: {
|
|
645
|
+
commands: stripUndefined({
|
|
640
646
|
value: value && serializeToBase64({ _: value }),
|
|
641
647
|
...isBatchWrite ? { stepping } : {
|
|
642
648
|
path,
|
|
643
649
|
scope: type,
|
|
644
650
|
find: find && serializeToBase64(find)
|
|
645
651
|
}
|
|
646
|
-
},
|
|
652
|
+
}),
|
|
647
653
|
dbName,
|
|
648
654
|
dbUrl
|
|
649
655
|
},
|
|
650
656
|
accessKey,
|
|
651
657
|
serverE2E_PublicKey,
|
|
652
658
|
authToken: disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl],
|
|
653
|
-
uglify
|
|
659
|
+
uglify,
|
|
660
|
+
extraHeaders
|
|
654
661
|
});
|
|
655
662
|
|
|
656
|
-
const
|
|
657
|
-
if (r.simpleError) throw r;
|
|
663
|
+
const data = await buildFetchResult(await fetch((isBatchWrite ? _writeMapDocument : _writeDocument)(projectUrl, uglify), reqBuilder), uglify);
|
|
658
664
|
|
|
659
|
-
const f = uglify ? await deserializeE2E(
|
|
665
|
+
const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
660
666
|
|
|
661
|
-
finalize({ ...f }, undefined, { removeCache: true });
|
|
667
|
+
finalize({ ...f.statusData }, undefined, { removeCache: true });
|
|
662
668
|
} catch (e) {
|
|
663
669
|
if (e?.simpleError) {
|
|
664
670
|
console.error(`${type} error (${path}), ${e.simpleError?.message}`);
|
|
@@ -7,7 +7,7 @@ import { awaitRefreshToken } from "../auth/accessor";
|
|
|
7
7
|
import { simplifyCaughtError } from "simplify-error";
|
|
8
8
|
import { guardObject, Validator } from "guard-object";
|
|
9
9
|
import cloneDeep from "lodash.clonedeep";
|
|
10
|
-
import {
|
|
10
|
+
import { serialize } from "entity-serializer";
|
|
11
11
|
|
|
12
12
|
const buildFetchData = (data) => {
|
|
13
13
|
const { ok, type, status, statusText, redirected, url, headers, size, base64 } = data;
|
|
@@ -33,7 +33,7 @@ const buildFetchData = (data) => {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const mfetch = async (input = '', init, config) => {
|
|
36
|
-
const { projectUrl, serverE2E_PublicKey, method, maxRetries = 7, disableCache, accessKey, uglify } = config;
|
|
36
|
+
const { projectUrl, serverE2E_PublicKey, method, maxRetries = 7, disableCache, accessKey, uglify, extraHeaders } = config;
|
|
37
37
|
const { headers, body } = init || {};
|
|
38
38
|
|
|
39
39
|
if (method !== undefined)
|
|
@@ -74,15 +74,15 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
74
74
|
) throw `"body" must be any of string, buffer, object, File, Blob`;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const rawBody =
|
|
77
|
+
const rawBody = (body instanceof File || body instanceof Blob) ? Buffer.from(await body.arrayBuffer()) : body;
|
|
78
78
|
|
|
79
79
|
const reqId = await niceHash(
|
|
80
|
-
|
|
80
|
+
serialize([
|
|
81
81
|
rawHeader,
|
|
82
82
|
rawBody,
|
|
83
83
|
!!disableAuth,
|
|
84
84
|
input
|
|
85
|
-
])
|
|
85
|
+
]).toString('base64')
|
|
86
86
|
);
|
|
87
87
|
|
|
88
88
|
let retries = 0, hasFinalize;
|
|
@@ -153,11 +153,12 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
153
153
|
...uglified ? { body: reqBuilder } : {},
|
|
154
154
|
cache: 'no-cache',
|
|
155
155
|
headers: {
|
|
156
|
+
...extraHeaders,
|
|
156
157
|
...isBaseUrl ? {} : { 'content-type': 'application/json' },
|
|
157
158
|
...rawHeader,
|
|
158
159
|
...uglified ? {
|
|
159
160
|
uglified,
|
|
160
|
-
'content-type': '
|
|
161
|
+
'content-type': 'request/buffer',
|
|
161
162
|
...initType ? { 'init-content-type': initType } : {}
|
|
162
163
|
} : {},
|
|
163
164
|
...(disableAuth || !mtoken || uglified || isBaseUrl) ? {} : { mtoken },
|
|
@@ -170,7 +171,7 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
170
171
|
if (!isBaseUrl && simple) throw { simpleError: JSON.parse(simple) };
|
|
171
172
|
|
|
172
173
|
const base64 = uglified ?
|
|
173
|
-
Buffer.from(await deserializeE2E(await f.
|
|
174
|
+
Buffer.from(await deserializeE2E(await f.arrayBuffer(), serverE2E_PublicKey, privateKey)).toString('base64') :
|
|
174
175
|
Buffer.from(await f.arrayBuffer()).toString('base64');
|
|
175
176
|
|
|
176
177
|
const resObj = {
|
|
@@ -12,6 +12,7 @@ export class MTStorage {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
uploadFile = (file, destination, onComplete, onProgress, reqOptions) => {
|
|
15
|
+
const { awaitServer, createHash } = reqOptions || {};
|
|
15
16
|
let hasCancelled = false,
|
|
16
17
|
hasFinished = false,
|
|
17
18
|
xhr;
|
|
@@ -44,7 +45,6 @@ export class MTStorage {
|
|
|
44
45
|
|
|
45
46
|
const { projectUrl, accessKey, uglify } = this.builder;
|
|
46
47
|
xhr = new XMLHttpRequest();
|
|
47
|
-
const { awaitServer, createHash } = reqOptions || {};
|
|
48
48
|
|
|
49
49
|
if (awaitServer) await awaitReachableServer(projectUrl);
|
|
50
50
|
await awaitRefreshToken(projectUrl);
|
package/src/polyfill.js
DELETED