mosquito-transport-js 0.3.3 → 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 +2 -2
- package/src/helpers/utils.js +3 -2
- package/src/index.d.ts +32 -6
- package/src/index.js +53 -14
- package/src/products/auth/accessor.js +14 -10
- package/src/products/auth/index.js +14 -11
- package/src/products/database/index.js +29 -20
- package/src/products/http_callable/index.js +2 -1
- 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,7 +32,7 @@
|
|
|
32
32
|
"bson": "^6.8.0",
|
|
33
33
|
"buffer": "^6.0.3",
|
|
34
34
|
"crypto-js": "^4.2.0",
|
|
35
|
-
"entity-serializer": "^1.0.
|
|
35
|
+
"entity-serializer": "^1.0.1",
|
|
36
36
|
"guard-object": "^1.1.3",
|
|
37
37
|
"limit-task": "1.0.0",
|
|
38
38
|
"lodash.clonedeep": "^4.5.0",
|
package/src/helpers/utils.js
CHANGED
|
@@ -117,7 +117,7 @@ export const getReachableServer = (projectUrl) => new Promise(resolve => {
|
|
|
117
117
|
}, true);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
-
export const buildFetchInterface = async ({ body, accessKey, authToken, method, uglify, serverE2E_PublicKey }) => {
|
|
120
|
+
export const buildFetchInterface = async ({ body, accessKey, authToken, method, uglify, serverE2E_PublicKey, extraHeaders }) => {
|
|
121
121
|
if (!uglify) body = JSON.stringify({ ...body });
|
|
122
122
|
const [plate, keyPair] = uglify ? await serializeE2E(body, authToken, serverE2E_PublicKey) : [undefined, []];
|
|
123
123
|
|
|
@@ -127,7 +127,8 @@ export const buildFetchInterface = async ({ body, accessKey, authToken, method,
|
|
|
127
127
|
headers: {
|
|
128
128
|
'Content-type': uglify ? 'request/buffer' : 'application/json',
|
|
129
129
|
'Authorization': accessKey,
|
|
130
|
-
...(
|
|
130
|
+
...(authToken && !uglify) ? { 'Mosquito-Token': authToken } : {},
|
|
131
|
+
...extraHeaders
|
|
131
132
|
},
|
|
132
133
|
method: method || 'POST'
|
|
133
134
|
}, keyPair];
|
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";
|
|
@@ -45,7 +44,7 @@ export class MosquitoTransport {
|
|
|
45
44
|
maxRetries: config.maxRetries || 3,
|
|
46
45
|
uglify: config.enableE2E_Encryption
|
|
47
46
|
};
|
|
48
|
-
const { projectUrl } = this.config;
|
|
47
|
+
const { projectUrl, extraHeaders } = this.config;
|
|
49
48
|
|
|
50
49
|
this.config.secureUrl = projectUrl.startsWith('https');
|
|
51
50
|
this.config.baseUrl = projectUrl.split('://')[1];
|
|
@@ -66,6 +65,7 @@ export class MosquitoTransport {
|
|
|
66
65
|
|
|
67
66
|
const socket = io(`${this.config.wsPrefix}://${this.config.baseUrl}`, {
|
|
68
67
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
68
|
+
extraHeaders,
|
|
69
69
|
auth: {
|
|
70
70
|
_m_internal: true,
|
|
71
71
|
_from_base: true
|
|
@@ -153,7 +153,7 @@ export class MosquitoTransport {
|
|
|
153
153
|
|
|
154
154
|
getSocket = (configOpts) => {
|
|
155
155
|
const { disableAuth, authHandshake } = configOpts || {};
|
|
156
|
-
const { projectUrl, uglify, accessKey, serverE2E_PublicKey, wsPrefix } = this.config;
|
|
156
|
+
const { projectUrl, uglify, accessKey, serverE2E_PublicKey, wsPrefix, extraHeaders } = this.config;
|
|
157
157
|
|
|
158
158
|
const restrictedRoute = [
|
|
159
159
|
_listenCollection,
|
|
@@ -184,22 +184,23 @@ export class MosquitoTransport {
|
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
const [args, emitable] = [...arguments];
|
|
187
|
+
const [[args, not_encrypted], emitable] = [...arguments];
|
|
188
188
|
let res;
|
|
189
189
|
|
|
190
190
|
if (uglify) {
|
|
191
191
|
res = await deserializeE2E(args, serverE2E_PublicKey, clientPrivateKey);
|
|
192
192
|
} else res = args;
|
|
193
|
+
const sortedArgs = discloseSocketArguments([res, not_encrypted]);
|
|
193
194
|
|
|
194
|
-
callback?.(...
|
|
195
|
-
const args = [...arguments];
|
|
195
|
+
callback?.(...sortedArgs, ...typeof emitable === 'function' ? [async function () {
|
|
196
|
+
const [args, not_encrypted] = encloseSocketArguments([...arguments]);
|
|
196
197
|
let res;
|
|
197
198
|
|
|
198
199
|
if (uglify) {
|
|
199
200
|
res = (await serializeE2E(args, undefined, serverE2E_PublicKey))[0];
|
|
200
201
|
} else res = args;
|
|
201
202
|
|
|
202
|
-
emitable(res);
|
|
203
|
+
emitable([res, not_encrypted]);
|
|
203
204
|
}] : []);
|
|
204
205
|
};
|
|
205
206
|
|
|
@@ -228,7 +229,7 @@ export class MosquitoTransport {
|
|
|
228
229
|
|
|
229
230
|
const lastEmit = emittion.slice(-1)[0];
|
|
230
231
|
const hasEmitable = typeof lastEmit === 'function';
|
|
231
|
-
const mit = hasEmitable ? emittion.slice(0, -1) : emittion;
|
|
232
|
+
const [mit, not_encrypted] = encloseSocketArguments(hasEmitable ? emittion.slice(0, -1) : emittion);
|
|
232
233
|
|
|
233
234
|
const [reqBuilder, [privateKey]] = uglify ? await serializeE2E(mit, undefined, serverE2E_PublicKey) : [undefined, []];
|
|
234
235
|
|
|
@@ -236,20 +237,21 @@ export class MosquitoTransport {
|
|
|
236
237
|
throw 'emitWithAck cannot have function in it argument';
|
|
237
238
|
|
|
238
239
|
const result = await thisSocket[promise ? 'emitWithAck' : 'emit'](route,
|
|
239
|
-
uglify ? reqBuilder : mit,
|
|
240
|
+
[uglify ? reqBuilder : mit, not_encrypted],
|
|
240
241
|
...hasEmitable ? [async function () {
|
|
241
|
-
const [args] = [...arguments];
|
|
242
|
+
const [[args, not_encrypted]] = [...arguments];
|
|
242
243
|
let res;
|
|
243
244
|
|
|
244
245
|
if (uglify) {
|
|
245
246
|
res = await deserializeE2E(args, serverE2E_PublicKey, privateKey);
|
|
246
247
|
} else res = args;
|
|
247
248
|
|
|
248
|
-
lastEmit(...res
|
|
249
|
+
lastEmit(...discloseSocketArguments([res, not_encrypted]));
|
|
249
250
|
}] : []
|
|
250
251
|
);
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
if (promise && result) {
|
|
253
|
+
resolve(discloseSocketArguments([uglify ? await deserializeE2E(result[0], serverE2E_PublicKey, privateKey) : result[0], result[1]])[0]);
|
|
254
|
+
} else resolve();
|
|
253
255
|
} catch (e) {
|
|
254
256
|
reject(e);
|
|
255
257
|
}
|
|
@@ -262,9 +264,10 @@ export class MosquitoTransport {
|
|
|
262
264
|
|
|
263
265
|
socket = io(`${wsPrefix}://${projectUrl.split('://')[1]}`, {
|
|
264
266
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
267
|
+
extraHeaders,
|
|
265
268
|
auth: uglify ? {
|
|
266
269
|
ugly: true,
|
|
267
|
-
e2e: reqBuilder
|
|
270
|
+
e2e: reqBuilder.toString('base64')
|
|
268
271
|
} : {
|
|
269
272
|
...mtoken ? { mtoken } : {},
|
|
270
273
|
a_extras: authHandshake,
|
|
@@ -358,6 +361,31 @@ export class MosquitoTransport {
|
|
|
358
361
|
}
|
|
359
362
|
};
|
|
360
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
|
+
|
|
361
389
|
const validateReleaseCacheProp = (prop) => {
|
|
362
390
|
const cacheList = [...Object.values(CACHE_PROTOCOL)];
|
|
363
391
|
|
|
@@ -425,6 +453,16 @@ const validator = {
|
|
|
425
453
|
serverE2E_PublicKey: (v) => {
|
|
426
454
|
if (typeof v !== 'string' || !v.trim())
|
|
427
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
|
+
});
|
|
428
466
|
}
|
|
429
467
|
};
|
|
430
468
|
|
|
@@ -444,6 +482,7 @@ const validateMTConfig = (config, that) => {
|
|
|
444
482
|
}
|
|
445
483
|
|
|
446
484
|
export {
|
|
485
|
+
DoNotEncrypt,
|
|
447
486
|
TIMESTAMP,
|
|
448
487
|
DOCUMENT_EXTRACTION,
|
|
449
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;
|
|
@@ -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,7 +175,8 @@ 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
182
|
const data = await buildFetchResult(await fetch(_customSignin(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -194,7 +195,7 @@ const doCustomSignin = (builder, email, password) => new Promise(async (resolve,
|
|
|
194
195
|
});
|
|
195
196
|
|
|
196
197
|
const doCustomSignup = (builder, email, password, name, metadata) => new Promise(async (resolve, reject) => {
|
|
197
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
198
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
198
199
|
|
|
199
200
|
try {
|
|
200
201
|
await awaitStore();
|
|
@@ -205,7 +206,8 @@ const doCustomSignup = (builder, email, password, name, metadata) => new Promise
|
|
|
205
206
|
},
|
|
206
207
|
accessKey,
|
|
207
208
|
serverE2E_PublicKey,
|
|
208
|
-
uglify
|
|
209
|
+
uglify,
|
|
210
|
+
extraHeaders
|
|
209
211
|
});
|
|
210
212
|
|
|
211
213
|
const data = await buildFetchResult(await fetch(_customSignup(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -237,7 +239,7 @@ export const clearCacheForSignout = (builder) => {
|
|
|
237
239
|
export const doSignOut = async (builder) => {
|
|
238
240
|
await awaitStore();
|
|
239
241
|
|
|
240
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder,
|
|
242
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder,
|
|
241
243
|
{ token, refreshToken: r_token } = CacheStore.AuthStore[projectUrl];
|
|
242
244
|
|
|
243
245
|
clearCacheForSignout(builder);
|
|
@@ -251,11 +253,11 @@ export const doSignOut = async (builder) => {
|
|
|
251
253
|
body: { token, r_token },
|
|
252
254
|
accessKey,
|
|
253
255
|
uglify,
|
|
254
|
-
serverE2E_PublicKey
|
|
256
|
+
serverE2E_PublicKey,
|
|
257
|
+
extraHeaders
|
|
255
258
|
});
|
|
256
259
|
|
|
257
|
-
|
|
258
|
-
if (r.simpleError) throw r;
|
|
260
|
+
await buildFetchResult(await fetch(_signOut(projectUrl, uglify), reqBuilder), uglify);
|
|
259
261
|
} catch (e) {
|
|
260
262
|
throw simplifyCaughtError(e).simpleError;
|
|
261
263
|
}
|
|
@@ -263,7 +265,7 @@ export const doSignOut = async (builder) => {
|
|
|
263
265
|
};
|
|
264
266
|
|
|
265
267
|
const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) => {
|
|
266
|
-
const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
|
|
268
|
+
const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
|
|
267
269
|
|
|
268
270
|
try {
|
|
269
271
|
await awaitStore();
|
|
@@ -271,7 +273,8 @@ const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) =
|
|
|
271
273
|
body: { token },
|
|
272
274
|
accessKey,
|
|
273
275
|
uglify,
|
|
274
|
-
serverE2E_PublicKey
|
|
276
|
+
serverE2E_PublicKey,
|
|
277
|
+
extraHeaders
|
|
275
278
|
});
|
|
276
279
|
|
|
277
280
|
const data = await buildFetchResult(await fetch(_googleSignin(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -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,7 +376,8 @@ 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
383
|
const data = await buildFetchResult(await fetch(_documentCount(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -419,13 +422,17 @@ const stripRequestConfig = (config) => {
|
|
|
419
422
|
return requestConfig.length ? Object.fromEntries(requestConfig) : undefined;
|
|
420
423
|
};
|
|
421
424
|
|
|
425
|
+
const stripUndefined = o => Object.fromEntries(
|
|
426
|
+
Object.entries(o).filter(v => v[1] !== undefined)
|
|
427
|
+
);
|
|
428
|
+
|
|
422
429
|
const transformBSON = (d, castBSON) => {
|
|
423
430
|
if (castBSON) return d && deserializeBSON(serializeToBase64({ _: d }), true)._;
|
|
424
431
|
return cloneDeep(d);
|
|
425
432
|
};
|
|
426
433
|
|
|
427
434
|
const findObject = async (builder, config) => {
|
|
428
|
-
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;
|
|
429
436
|
const { find, findOne, sort, direction, limit, random } = command;
|
|
430
437
|
const { retrieval = RETRIEVAL.DEFAULT, episode = 0, disableAuth, disableMinimizer } = config || {};
|
|
431
438
|
const enableMinimizer = !disableMinimizer;
|
|
@@ -498,7 +505,7 @@ const findObject = async (builder, config) => {
|
|
|
498
505
|
|
|
499
506
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
500
507
|
body: {
|
|
501
|
-
commands: {
|
|
508
|
+
commands: stripUndefined({
|
|
502
509
|
config: pureConfig && serializeToBase64(pureConfig),
|
|
503
510
|
path,
|
|
504
511
|
find: serializeToBase64(findOne || find),
|
|
@@ -506,14 +513,15 @@ const findObject = async (builder, config) => {
|
|
|
506
513
|
direction,
|
|
507
514
|
limit,
|
|
508
515
|
random
|
|
509
|
-
},
|
|
516
|
+
}),
|
|
510
517
|
dbName,
|
|
511
518
|
dbUrl
|
|
512
519
|
},
|
|
513
520
|
accessKey,
|
|
514
521
|
authToken: disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl],
|
|
515
522
|
serverE2E_PublicKey,
|
|
516
|
-
uglify
|
|
523
|
+
uglify,
|
|
524
|
+
extraHeaders
|
|
517
525
|
});
|
|
518
526
|
|
|
519
527
|
const data = await buildFetchResult(await fetch((findOne ? _readDocument : _queryCollection)(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -587,7 +595,7 @@ const commitData = async (builder, value, type, config) => {
|
|
|
587
595
|
)._;
|
|
588
596
|
}
|
|
589
597
|
|
|
590
|
-
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;
|
|
591
599
|
const { disableAuth, delivery = DELIVERY.DEFAULT, stepping } = config || {};
|
|
592
600
|
const writeId = `${Date.now() + ++Scoped.PendingIte}`;
|
|
593
601
|
const isBatchWrite = type === 'batchWrite';
|
|
@@ -634,21 +642,22 @@ const commitData = async (builder, value, type, config) => {
|
|
|
634
642
|
|
|
635
643
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
636
644
|
body: {
|
|
637
|
-
commands: {
|
|
645
|
+
commands: stripUndefined({
|
|
638
646
|
value: value && serializeToBase64({ _: value }),
|
|
639
647
|
...isBatchWrite ? { stepping } : {
|
|
640
648
|
path,
|
|
641
649
|
scope: type,
|
|
642
650
|
find: find && serializeToBase64(find)
|
|
643
651
|
}
|
|
644
|
-
},
|
|
652
|
+
}),
|
|
645
653
|
dbName,
|
|
646
654
|
dbUrl
|
|
647
655
|
},
|
|
648
656
|
accessKey,
|
|
649
657
|
serverE2E_PublicKey,
|
|
650
658
|
authToken: disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl],
|
|
651
|
-
uglify
|
|
659
|
+
uglify,
|
|
660
|
+
extraHeaders
|
|
652
661
|
});
|
|
653
662
|
|
|
654
663
|
const data = await buildFetchResult(await fetch((isBatchWrite ? _writeMapDocument : _writeDocument)(projectUrl, uglify), reqBuilder), uglify);
|
|
@@ -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)
|
|
@@ -153,6 +153,7 @@ 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 ? {
|
|
@@ -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