react-native-mosquito-transport 0.0.46 → 0.0.48
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/TODO +8 -0
- package/ios/Mosquitodb.swift +2 -2
- package/package.json +3 -3
- package/src/helpers/peripherals.js +2 -2
- package/src/helpers/utils.js +7 -7
- package/src/index.d.ts +61 -25
- package/src/index.js +7 -4
- package/src/products/auth/accessor.js +9 -9
- package/src/products/auth/index.js +13 -14
- package/src/products/http_callable/index.js +6 -5
- package/src/products/storage/index.js +59 -40
package/TODO
CHANGED
|
@@ -25,3 +25,11 @@
|
|
|
25
25
|
- transform undefined to void instead of null
|
|
26
26
|
- add metadata to provider auth login
|
|
27
27
|
<!-- - error: "refreshToken retry limit exceeded" <--- no need -->
|
|
28
|
+
|
|
29
|
+
- _areYouOk() should timeout max 5000
|
|
30
|
+
- .json() should be parse nicely
|
|
31
|
+
- when server is offline and suddenly comes online, fetchHttp throw some error
|
|
32
|
+
- string to Buffer may be in utf16
|
|
33
|
+
|
|
34
|
+
# changes made
|
|
35
|
+
storage uploadFile method and others
|
package/ios/Mosquitodb.swift
CHANGED
|
@@ -95,7 +95,7 @@ class MosquitodbUploadTask: NSObject, URLSessionDataDelegate {
|
|
|
95
95
|
var request = URLRequest(url: URL(string: url)!)
|
|
96
96
|
request.httpMethod = "POST"
|
|
97
97
|
|
|
98
|
-
if let extraHeaders = options["extraHeaders"] as? [
|
|
98
|
+
if let extraHeaders = options["extraHeaders"] as? [String: String] {
|
|
99
99
|
for (key, value) in extraHeaders {
|
|
100
100
|
request.setValue(value, forHTTPHeaderField: key)
|
|
101
101
|
}
|
|
@@ -191,7 +191,7 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
|
|
|
191
191
|
var request = URLRequest(url: URL(string: url)!)
|
|
192
192
|
request.httpMethod = "POST"
|
|
193
193
|
|
|
194
|
-
if let extraHeaders = options["extraHeaders"] as? [
|
|
194
|
+
if let extraHeaders = options["extraHeaders"] as? [String: String] {
|
|
195
195
|
for (key, value) in extraHeaders {
|
|
196
196
|
request.setValue(value, forHTTPHeaderField: key)
|
|
197
197
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mosquito-transport",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@turf/turf": "^7.2.0",
|
|
31
31
|
"buffer": "^6.0.3",
|
|
32
|
-
"entity-serializer": "^1.0.
|
|
32
|
+
"entity-serializer": "^1.0.4",
|
|
33
33
|
"guard-object": "^1.1.4",
|
|
34
34
|
"poke-object": "^1.0.1",
|
|
35
35
|
"simplify-error": "^1.0.1",
|
|
36
36
|
"socket.io-client": "^4.8.1",
|
|
37
|
-
"subscription-listener": "^1.1.
|
|
37
|
+
"subscription-listener": "^1.1.3",
|
|
38
38
|
"tweetnacl": "^1.0.3"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -10,10 +10,10 @@ const { box, randomBytes } = naclPkg;
|
|
|
10
10
|
|
|
11
11
|
export const listenReachableServer = (callback, projectUrl) => {
|
|
12
12
|
let lastValue;
|
|
13
|
-
return ServerReachableListener.
|
|
13
|
+
return ServerReachableListener.listenToPersist(projectUrl, t => {
|
|
14
14
|
if (typeof t === 'boolean' && t !== lastValue) callback?.(t);
|
|
15
15
|
lastValue = t;
|
|
16
|
-
}
|
|
16
|
+
});
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export const prefixStoragePath = (path, prefix = 'file:///') => {
|
package/src/helpers/utils.js
CHANGED
|
@@ -134,7 +134,7 @@ export const releaseCacheStore = async (builder) => {
|
|
|
134
134
|
Scoped.AuthJWTToken[key] = value?.token;
|
|
135
135
|
});
|
|
136
136
|
Scoped.IsStoreReady = true;
|
|
137
|
-
StoreReadyListener.
|
|
137
|
+
StoreReadyListener.dispatchPersist('_', 'ready');
|
|
138
138
|
setTimeout(() => {
|
|
139
139
|
if (tobePurged.length) updateCacheStore(tobePurged);
|
|
140
140
|
}, 0);
|
|
@@ -147,12 +147,12 @@ export const awaitStore = () => new Promise(resolve => {
|
|
|
147
147
|
resolve();
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
const l = StoreReadyListener.
|
|
150
|
+
const l = StoreReadyListener.listenToPersist('_', t => {
|
|
151
151
|
if (t === 'ready') {
|
|
152
152
|
resolve();
|
|
153
153
|
l();
|
|
154
154
|
}
|
|
155
|
-
}
|
|
155
|
+
});
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
export const awaitReachableServer = (projectUrl) => new Promise(resolve => {
|
|
@@ -160,12 +160,12 @@ export const awaitReachableServer = (projectUrl) => new Promise(resolve => {
|
|
|
160
160
|
resolve();
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
|
-
const l = ServerReachableListener.
|
|
163
|
+
const l = ServerReachableListener.listenToPersist(projectUrl, t => {
|
|
164
164
|
if (t) {
|
|
165
165
|
resolve();
|
|
166
166
|
l();
|
|
167
167
|
}
|
|
168
|
-
}
|
|
168
|
+
});
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
export const getReachableServer = (projectUrl) => new Promise(resolve => {
|
|
@@ -173,12 +173,12 @@ export const getReachableServer = (projectUrl) => new Promise(resolve => {
|
|
|
173
173
|
resolve(Scoped.IS_CONNECTED[projectUrl]);
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
|
-
const l = ServerReachableListener.
|
|
176
|
+
const l = ServerReachableListener.listenToPersist(projectUrl, t => {
|
|
177
177
|
if (typeof t === 'boolean') {
|
|
178
178
|
resolve(t);
|
|
179
179
|
l();
|
|
180
180
|
}
|
|
181
|
-
}
|
|
181
|
+
});
|
|
182
182
|
});
|
|
183
183
|
|
|
184
184
|
export const buildFetchInterface = async ({ body, authToken, method, uglify, serverE2E_PublicKey, extraHeaders }) => {
|
package/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BSON } from "./vendor/bson";
|
|
2
2
|
|
|
3
|
-
interface RNMTConfig {
|
|
3
|
+
export interface RNMTConfig {
|
|
4
4
|
dbName?: string;
|
|
5
5
|
dbUrl?: string;
|
|
6
6
|
projectUrl: string;
|
|
@@ -38,7 +38,7 @@ interface RNMTConfig {
|
|
|
38
38
|
castBSON?: boolean;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
interface GetDatabase {
|
|
41
|
+
export interface GetDatabase {
|
|
42
42
|
collection: (path: string) => RNMTCollection;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -98,7 +98,7 @@ type auth_provider_id_values = auth_provider_id['GOOGLE'] |
|
|
|
98
98
|
interface ReleaseCacheOption_IO {
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
interface ReleaseCacheOption {
|
|
101
|
+
export interface ReleaseCacheOption {
|
|
102
102
|
/**
|
|
103
103
|
* fs is used as the default caching mechanism
|
|
104
104
|
*
|
|
@@ -137,7 +137,7 @@ interface ReleaseCacheOption {
|
|
|
137
137
|
promoteCache?: boolean;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
interface RNMTSocket {
|
|
140
|
+
export interface RNMTSocket {
|
|
141
141
|
timeout: (timeout?: number) => ({
|
|
142
142
|
emitWithAck: (...args: any) => Promise<any>;
|
|
143
143
|
});
|
|
@@ -167,13 +167,18 @@ interface CountConfig {
|
|
|
167
167
|
disableAuth?: boolean;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
interface FetchHttpResponse extends Response {
|
|
170
|
+
export interface FetchHttpResponse extends Response {
|
|
171
171
|
/**
|
|
172
172
|
* true if this response was from local cache
|
|
173
173
|
*/
|
|
174
174
|
fromCache?: boolean | undefined;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
interface CustomSocketOption extends OveridenProjectUrl {
|
|
178
|
+
disableAuth?: boolean;
|
|
179
|
+
authHandshake?: Object;
|
|
180
|
+
}
|
|
181
|
+
|
|
177
182
|
export default class RNMT {
|
|
178
183
|
constructor(config: RNMTConfig);
|
|
179
184
|
static initializeCache(option?: ReleaseCacheOption): void;
|
|
@@ -183,12 +188,12 @@ export default class RNMT {
|
|
|
183
188
|
storage(): RNMTStorage;
|
|
184
189
|
fetchHttp(endpoint: string, init?: RequestInit, config?: FetchHttpConfig): Promise<FetchHttpResponse>;
|
|
185
190
|
listenReachableServer(callback: (reachable: boolean) => void): () => void;
|
|
186
|
-
getSocket(options
|
|
191
|
+
getSocket(options?: CustomSocketOption): RNMTSocket;
|
|
187
192
|
onConnect: () => CollectionIO;
|
|
188
193
|
batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): Promise<DocumentWriteResult[] | undefined>;
|
|
189
194
|
}
|
|
190
195
|
|
|
191
|
-
interface RNMTCollection {
|
|
196
|
+
export interface RNMTCollection {
|
|
192
197
|
find: (find?: DocumentFind) => ({
|
|
193
198
|
get: (config?: GetConfig) => Promise<DocumentResult[]>;
|
|
194
199
|
listen: (callback: (snapshot?: DocumentResult[]) => void, onError?: (error?: DocumentError) => void, config?: GetConfig) => void;
|
|
@@ -258,7 +263,7 @@ interface RNMTCollection {
|
|
|
258
263
|
deleteMany: (find?: DocumentFind, config?: WriteConfig) => Promise<DocumentWriteResult>;
|
|
259
264
|
}
|
|
260
265
|
|
|
261
|
-
interface CollectionTaskIO<T> {
|
|
266
|
+
export interface CollectionTaskIO<T> {
|
|
262
267
|
batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): T;
|
|
263
268
|
}
|
|
264
269
|
|
|
@@ -270,7 +275,7 @@ interface OnConnectChain extends StartStop {
|
|
|
270
275
|
onDisconnect: () => CollectionTaskIO<StartStop>;
|
|
271
276
|
}
|
|
272
277
|
|
|
273
|
-
interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
|
|
278
|
+
export interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
|
|
274
279
|
onDisconnect: () => CollectionTaskIO<StartStop>;
|
|
275
280
|
}
|
|
276
281
|
|
|
@@ -282,7 +287,7 @@ interface DocumentError extends ErrorResponse {
|
|
|
282
287
|
|
|
283
288
|
}
|
|
284
289
|
|
|
285
|
-
interface FetchHttpConfig {
|
|
290
|
+
export interface FetchHttpConfig {
|
|
286
291
|
retrieval?: GetConfig['retrieval'];
|
|
287
292
|
/**
|
|
288
293
|
* disable sending authentication token along with this request
|
|
@@ -429,11 +434,16 @@ interface DocumentWriteValue {
|
|
|
429
434
|
|
|
430
435
|
}
|
|
431
436
|
|
|
432
|
-
interface RNMTAuth {
|
|
437
|
+
export interface RNMTAuth {
|
|
433
438
|
customSignin: (email: string, password: string) => Promise<SigninResult>;
|
|
434
439
|
customSignup: (email: string, password: string, name?: string, metadata?: Object) => Promise<SignupResult>;
|
|
435
|
-
|
|
436
|
-
|
|
440
|
+
/**
|
|
441
|
+
*
|
|
442
|
+
* @param token can be an `id_token` or `authorization code` returned from Google Identity Services
|
|
443
|
+
* @param metadata
|
|
444
|
+
*/
|
|
445
|
+
googleSignin: (token: string, metadata?: any | undefined) => Promise<SignupResult>;
|
|
446
|
+
appleSignin: (id_token: string, metadata?: any | undefined) => Promise<SignupResult>;
|
|
437
447
|
facebookSignin: () => Promise<SignupResult>;
|
|
438
448
|
twitterSignin: () => Promise<SignupResult>;
|
|
439
449
|
githubSignin: () => Promise<SignupResult>;
|
|
@@ -460,7 +470,7 @@ export interface SignupResult extends SigninResult {
|
|
|
460
470
|
isNewUser: boolean;
|
|
461
471
|
}
|
|
462
472
|
|
|
463
|
-
interface AuthData {
|
|
473
|
+
export interface AuthData {
|
|
464
474
|
email?: string;
|
|
465
475
|
metadata: Object;
|
|
466
476
|
signupMethod: auth_provider_id_values;
|
|
@@ -468,7 +478,8 @@ interface AuthData {
|
|
|
468
478
|
joinedOn: number;
|
|
469
479
|
uid: string;
|
|
470
480
|
claims: Object;
|
|
471
|
-
|
|
481
|
+
authVerified: boolean;
|
|
482
|
+
passwordVerified?: boolean | undefined;
|
|
472
483
|
tokenID: string;
|
|
473
484
|
disabled: boolean;
|
|
474
485
|
entityOf: string;
|
|
@@ -482,7 +493,7 @@ interface AuthData {
|
|
|
482
493
|
sub: string;
|
|
483
494
|
}
|
|
484
495
|
|
|
485
|
-
interface RefreshTokenData {
|
|
496
|
+
export interface RefreshTokenData {
|
|
486
497
|
uid: string;
|
|
487
498
|
tokenID: string;
|
|
488
499
|
isRefreshToken: true;
|
|
@@ -492,24 +503,37 @@ interface RefreshTokenData {
|
|
|
492
503
|
sub: string;
|
|
493
504
|
}
|
|
494
505
|
|
|
495
|
-
interface TokenEventData extends AuthData {
|
|
506
|
+
export interface TokenEventData extends AuthData {
|
|
496
507
|
tokenManager: TokenManager;
|
|
497
508
|
}
|
|
498
509
|
|
|
499
|
-
interface TokenManager {
|
|
510
|
+
export interface TokenManager {
|
|
500
511
|
refreshToken: string;
|
|
501
512
|
accessToken: string;
|
|
502
513
|
}
|
|
503
514
|
|
|
504
|
-
interface
|
|
515
|
+
interface OveridenProjectUrl {
|
|
516
|
+
/**
|
|
517
|
+
* The server instance to send requests to. This overrides the parent `projectUrl`, but still relies on the parent `projectUrl` for authentication token resolution and verify server reachability.
|
|
518
|
+
*/
|
|
519
|
+
projectUrl?: string;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
interface UploadOptions extends OveridenProjectUrl {
|
|
505
523
|
/**
|
|
506
524
|
* optionally create hash for this upload to save disk space
|
|
507
525
|
*/
|
|
508
526
|
createHash?: boolean;
|
|
527
|
+
|
|
509
528
|
/**
|
|
510
529
|
* wait for a reachable server before initiating the upload task
|
|
511
530
|
*/
|
|
512
531
|
awaitServer?: boolean;
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* monitor upload progress stats
|
|
535
|
+
*/
|
|
536
|
+
onProgress?: (stats: UploadProgressStats) => void;
|
|
513
537
|
}
|
|
514
538
|
|
|
515
539
|
interface DownloadOptions {
|
|
@@ -517,16 +541,28 @@ interface DownloadOptions {
|
|
|
517
541
|
* wait for a reachable server before initiating the download task
|
|
518
542
|
*/
|
|
519
543
|
awaitServer?: boolean;
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* monitor download progress stats
|
|
547
|
+
*/
|
|
548
|
+
onProgress?: (stats: DownloadProgressStats) => void;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
interface StorageTask extends Promise<string> {
|
|
552
|
+
/**
|
|
553
|
+
* abort the running task process
|
|
554
|
+
*/
|
|
555
|
+
abort: () => void;
|
|
520
556
|
}
|
|
521
557
|
|
|
522
|
-
interface RNMTStorage {
|
|
523
|
-
downloadFile: (link: string,
|
|
524
|
-
uploadFile: (
|
|
525
|
-
deleteFile: (path: string) => Promise<void>;
|
|
526
|
-
deleteFolder: (folder: string) => Promise<void>;
|
|
558
|
+
export interface RNMTStorage {
|
|
559
|
+
downloadFile: (link: string, filepath?: string | undefined, options?: DownloadOptions | undefined) => StorageTask;
|
|
560
|
+
uploadFile: (filepath: string, destination: string, options?: UploadOptions | undefined) => StorageTask;
|
|
561
|
+
deleteFile: (path: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
|
|
562
|
+
deleteFolder: (folder: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
|
|
527
563
|
}
|
|
528
564
|
|
|
529
|
-
interface DownloadProgressStats {
|
|
565
|
+
export interface DownloadProgressStats {
|
|
530
566
|
receivedBtyes: number;
|
|
531
567
|
expectedBytes: number;
|
|
532
568
|
isPaused: boolean;
|
package/src/index.js
CHANGED
|
@@ -79,7 +79,7 @@ class RNMT {
|
|
|
79
79
|
isConnected = true;
|
|
80
80
|
Scoped.IS_CONNECTED[projectUrl] = true;
|
|
81
81
|
if (recentToken) updateMountedToken();
|
|
82
|
-
ServerReachableListener.
|
|
82
|
+
ServerReachableListener.dispatchPersist(projectUrl, true);
|
|
83
83
|
awaitStore().then(() => {
|
|
84
84
|
if (isConnected) trySendPendingWrite(projectUrl);
|
|
85
85
|
});
|
|
@@ -88,7 +88,7 @@ class RNMT {
|
|
|
88
88
|
++connectionIte;
|
|
89
89
|
isConnected = false;
|
|
90
90
|
Scoped.IS_CONNECTED[projectUrl] = false;
|
|
91
|
-
ServerReachableListener.
|
|
91
|
+
ServerReachableListener.dispatchPersist(projectUrl, false);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
const manualCheckConnection = () => {
|
|
@@ -165,7 +165,7 @@ class RNMT {
|
|
|
165
165
|
listenReachableServer = (callback) => listenReachableServer(callback, this.config.projectUrl);
|
|
166
166
|
|
|
167
167
|
getSocket = (configOpts) => {
|
|
168
|
-
const { disableAuth, authHandshake } = configOpts || {};
|
|
168
|
+
const { disableAuth, authHandshake, projectUrl: overidenUrl } = configOpts || {};
|
|
169
169
|
const { projectUrl, uglify, serverE2E_PublicKey, wsPrefix, extraHeaders } = this.config;
|
|
170
170
|
|
|
171
171
|
const restrictedRoute = [
|
|
@@ -278,7 +278,10 @@ class RNMT {
|
|
|
278
278
|
const mtoken = disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl];
|
|
279
279
|
const [reqBuilder, [privateKey]] = uglify ? await serializeE2E({ a_extras: authHandshake }, mtoken, serverE2E_PublicKey) : [null, []];
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
const getWsPrefix = url => url.startsWith('https') ? 'wss' : 'ws';
|
|
282
|
+
const wsUrl = overidenUrl ? `${getWsPrefix(overidenUrl)}://${overidenUrl.split('://')[1]}` : `${wsPrefix}://${projectUrl.split('://')[1]}`;
|
|
283
|
+
|
|
284
|
+
socket = io(wsUrl, {
|
|
282
285
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
283
286
|
extraHeaders,
|
|
284
287
|
auth: uglify ? {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { doSignOut, revokeAuthIntance } from ".";
|
|
1
|
+
import { doSignOut, revokeAuthIntance } from "./index.js";
|
|
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";
|
|
@@ -9,10 +9,10 @@ import { Validator } from "guard-object";
|
|
|
9
9
|
import { basicClone } from "../../helpers/basic_clone";
|
|
10
10
|
|
|
11
11
|
export const listenToken = (callback, projectUrl) =>
|
|
12
|
-
AuthTokenListener.
|
|
12
|
+
AuthTokenListener.listenToPersist(projectUrl, (t, n) => {
|
|
13
13
|
if (t === undefined) return;
|
|
14
14
|
callback?.(t || null, n);
|
|
15
|
-
}
|
|
15
|
+
});
|
|
16
16
|
|
|
17
17
|
export const injectFreshToken = async (config, { token, refreshToken }) => {
|
|
18
18
|
const { projectUrl } = config;
|
|
@@ -56,19 +56,19 @@ export const parseToken = (token) => JSON.parse(decodeBinary(token.split('.')[1]
|
|
|
56
56
|
|
|
57
57
|
export const triggerAuthToken = async (projectUrl, isInit) => {
|
|
58
58
|
await awaitStore();
|
|
59
|
-
AuthTokenListener.
|
|
59
|
+
AuthTokenListener.dispatchPersist(projectUrl, CacheStore.AuthStore[projectUrl]?.token || null, isInit);
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
export const awaitRefreshToken = (projectUrl) => new Promise(resolve => {
|
|
63
|
-
const l = TokenRefreshListener.
|
|
63
|
+
const l = TokenRefreshListener.listenToPersist(projectUrl, v => {
|
|
64
64
|
if (v === 'ready') {
|
|
65
65
|
l();
|
|
66
66
|
resolve();
|
|
67
67
|
}
|
|
68
|
-
}
|
|
68
|
+
});
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
export const listenTokenReady = (callback, projectUrl) => TokenRefreshListener.
|
|
71
|
+
export const listenTokenReady = (callback, projectUrl) => TokenRefreshListener.listenToPersist(projectUrl, callback);
|
|
72
72
|
|
|
73
73
|
export const initTokenRefresher = async (config, forceRefresh) => {
|
|
74
74
|
const { projectUrl, maxRetries } = config;
|
|
@@ -81,9 +81,9 @@ export const initTokenRefresher = async (config, forceRefresh) => {
|
|
|
81
81
|
if (emulatedURL) return;
|
|
82
82
|
|
|
83
83
|
const notifyAuthReady = (value) => {
|
|
84
|
-
TokenRefreshListener.
|
|
84
|
+
TokenRefreshListener.dispatchPersist(projectUrl, value);
|
|
85
85
|
getEmulatedLinks(projectUrl).forEach(v => {
|
|
86
|
-
TokenRefreshListener.
|
|
86
|
+
TokenRefreshListener.dispatchPersist(v, value);
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
_customSignin,
|
|
15
15
|
_customSignup,
|
|
16
16
|
_googleSignin,
|
|
17
|
+
_appleSignin,
|
|
17
18
|
_areYouOk
|
|
18
19
|
} = EngineApi;
|
|
19
20
|
|
|
@@ -28,9 +29,7 @@ export default class MTAuth {
|
|
|
28
29
|
|
|
29
30
|
googleSignin = (token, metadata) => doGoogleSignin(this.builder, token, metadata);
|
|
30
31
|
|
|
31
|
-
appleSignin()
|
|
32
|
-
throw 'unsupported method call';
|
|
33
|
-
}
|
|
32
|
+
appleSignin = (token, metadata) => doAppleSignin(this.builder, token, metadata);
|
|
34
33
|
|
|
35
34
|
facebookSignin() {
|
|
36
35
|
throw 'unsupported method call';
|
|
@@ -240,7 +239,7 @@ const purgeCache = (url, isMain) => {
|
|
|
240
239
|
].forEach(e => {
|
|
241
240
|
if (e && CacheStore[e]?.[url]) delete CacheStore[e][url];
|
|
242
241
|
});
|
|
243
|
-
TokenRefreshListener.
|
|
242
|
+
TokenRefreshListener.dispatchPersist(url);
|
|
244
243
|
triggerAuthToken(url);
|
|
245
244
|
};
|
|
246
245
|
|
|
@@ -255,11 +254,13 @@ const clearCacheForSignout = (builder, disposeEmulated) => {
|
|
|
255
254
|
export const doSignOut = async (builder) => {
|
|
256
255
|
if (!Scoped.IsStoreReady) await awaitStore();
|
|
257
256
|
const emulatedURL = CacheStore.EmulatedAuth[builder.projectUrl];
|
|
257
|
+
const thisAuthStore = emulatedURL ? undefined : basicClone(CacheStore.AuthStore[builder.projectUrl]);
|
|
258
258
|
|
|
259
259
|
clearCacheForSignout(builder, !emulatedURL);
|
|
260
260
|
updateCacheStore(['AuthStore', 'EmulatedAuth']);
|
|
261
261
|
if (emulatedURL) return;
|
|
262
|
-
|
|
262
|
+
|
|
263
|
+
await revokeAuthIntance(builder, thisAuthStore);
|
|
263
264
|
};
|
|
264
265
|
|
|
265
266
|
export const revokeAuthIntance = async (builder, authStore) => {
|
|
@@ -289,8 +290,7 @@ export const purgePendingToken = async (nodeId) => {
|
|
|
289
290
|
isConnected = (await (await fetch(_areYouOk(projectUrl), { credentials: 'omit' })).json()).status === 'yes';
|
|
290
291
|
} catch (_) { }
|
|
291
292
|
|
|
292
|
-
if (!isConnected)
|
|
293
|
-
await awaitReachableServer(projectUrl);
|
|
293
|
+
if (!isConnected) await awaitReachableServer(projectUrl);
|
|
294
294
|
|
|
295
295
|
const [reqBuilder] = await buildFetchInterface({
|
|
296
296
|
body: { token, r_token },
|
|
@@ -308,7 +308,10 @@ export const purgePendingToken = async (nodeId) => {
|
|
|
308
308
|
}
|
|
309
309
|
};
|
|
310
310
|
|
|
311
|
-
const doGoogleSignin = (builder, token, metadata) =>
|
|
311
|
+
const doGoogleSignin = (builder, token, metadata) => doProviderSignin(builder, token, metadata, _googleSignin);
|
|
312
|
+
const doAppleSignin = (builder, token, metadata) => doProviderSignin(builder, token, metadata, _appleSignin);
|
|
313
|
+
|
|
314
|
+
const doProviderSignin = (builder, token, metadata, endpointer) => new Promise(async (resolve, reject) => {
|
|
312
315
|
const { projectUrl, serverE2E_PublicKey, uglify, extraHeaders } = builder;
|
|
313
316
|
|
|
314
317
|
try {
|
|
@@ -322,7 +325,7 @@ const doGoogleSignin = (builder, token, metadata) => new Promise(async (resolve,
|
|
|
322
325
|
extraHeaders
|
|
323
326
|
});
|
|
324
327
|
|
|
325
|
-
const data = await buildFetchResult(await fetch(
|
|
328
|
+
const data = await buildFetchResult(await fetch(endpointer(projectUrl, uglify), reqBuilder), uglify);
|
|
326
329
|
|
|
327
330
|
const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
328
331
|
|
|
@@ -337,8 +340,4 @@ const doGoogleSignin = (builder, token, metadata) => new Promise(async (resolve,
|
|
|
337
340
|
} catch (e) {
|
|
338
341
|
reject(simplifyCaughtError(e).simpleError);
|
|
339
342
|
}
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
const doAppleSignin = async () => {
|
|
343
|
-
|
|
344
|
-
}
|
|
343
|
+
});
|
|
@@ -3,7 +3,7 @@ import { deserializeE2E, listenReachableServer, niceHash, normalizeRoute, serial
|
|
|
3
3
|
import { awaitStore, getReachableServer } from "../../helpers/utils";
|
|
4
4
|
import { RETRIEVAL } from "../../helpers/values";
|
|
5
5
|
import { Scoped } from "../../helpers/variables";
|
|
6
|
-
import { awaitRefreshToken } from "../auth/accessor";
|
|
6
|
+
import { awaitRefreshToken, parseToken } from "../auth/accessor";
|
|
7
7
|
import { simplifyCaughtError } from "simplify-error";
|
|
8
8
|
import { guardObject, Validator } from "guard-object";
|
|
9
9
|
import { serialize } from "entity-serializer";
|
|
@@ -71,17 +71,18 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
71
71
|
) throw `"body" must be any of string, buffer, object`;
|
|
72
72
|
}
|
|
73
73
|
await awaitStore();
|
|
74
|
+
const thisToken = disableAuth ? '' : (Scoped.AuthJWTToken[projectUrl] || '');
|
|
74
75
|
|
|
75
76
|
const reqId = await niceHash(
|
|
76
77
|
serialize([
|
|
77
78
|
rawHeader,
|
|
78
79
|
body,
|
|
79
|
-
!!disableAuth,
|
|
80
|
+
// !!disableAuth,
|
|
80
81
|
input,
|
|
81
|
-
|
|
82
|
+
thisToken && await parseToken(thisToken).uid
|
|
82
83
|
]).toString('base64')
|
|
83
84
|
);
|
|
84
|
-
const processReqId = `${reqId}_${disableCache}_${retrieval}`;
|
|
85
|
+
const processReqId = `${reqId}_${thisToken}_${disableCache}_${retrieval}`;
|
|
85
86
|
|
|
86
87
|
let retries = 0, hasFinalize;
|
|
87
88
|
|
|
@@ -143,7 +144,7 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
143
144
|
const [reqBuilder, [privateKey]] = uglified ? await serializeE2E(body, mtoken, serverE2E_PublicKey) : [null, []];
|
|
144
145
|
|
|
145
146
|
const f = await fetch(isLink ? input : `${projectUrl}/${normalizeRoute(input)}`, {
|
|
146
|
-
...(
|
|
147
|
+
...(hasBody || uglified) ? { method: 'POST' } : {},
|
|
147
148
|
credentials: 'omit',
|
|
148
149
|
...init,
|
|
149
150
|
...uglified ? { body: reqBuilder } : encodeBody ? { body: serialize(body) } : {},
|
|
@@ -5,6 +5,7 @@ import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from
|
|
|
5
5
|
import { awaitReachableServer, buildFetchInterface, buildFetchResult } from "../../helpers/utils";
|
|
6
6
|
import { awaitRefreshToken } from "../auth/accessor";
|
|
7
7
|
import { simplifyError } from "simplify-error";
|
|
8
|
+
import { Validator } from "guard-object";
|
|
8
9
|
|
|
9
10
|
const LINKING_ERROR =
|
|
10
11
|
`The package 'react-native-mosquito-transport' doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -19,6 +20,7 @@ const RNMTModule = NativeModules.Mosquitodb || (
|
|
|
19
20
|
},
|
|
20
21
|
})
|
|
21
22
|
);
|
|
23
|
+
|
|
22
24
|
const emitter = Platform.OS === 'android' ?
|
|
23
25
|
DeviceEventEmitter : new NativeEventEmitter(RNMTModule);
|
|
24
26
|
|
|
@@ -27,26 +29,43 @@ export class MTStorage {
|
|
|
27
29
|
this.builder = { ...config };
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
downloadFile(link = '',
|
|
31
|
-
const { awaitServer } = options || {};
|
|
32
|
+
downloadFile = (link = '', destination, options) => {
|
|
33
|
+
const { awaitServer, onProgress } = options || {};
|
|
32
34
|
let hasFinished, isPaused, hasCancelled;
|
|
33
35
|
|
|
34
36
|
const { projectUrl, extraHeaders } = this.builder;
|
|
37
|
+
let onComplete;
|
|
38
|
+
|
|
39
|
+
const promise = new Promise((resolve, reject) => {
|
|
40
|
+
onComplete = (err, path) => {
|
|
41
|
+
if (hasFinished) return;
|
|
42
|
+
hasFinished = true;
|
|
43
|
+
if (path) {
|
|
44
|
+
resolve(path);
|
|
45
|
+
} else reject(err);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
promise.abort = () => {
|
|
50
|
+
if (hasFinished || hasCancelled) return;
|
|
51
|
+
RNMTModule.cancelDownload(processID);
|
|
52
|
+
hasCancelled = true;
|
|
53
|
+
onComplete?.({ error: 'download_aborted', message: 'The download process was aborted' });
|
|
54
|
+
}
|
|
35
55
|
|
|
36
56
|
if (destination && (typeof destination !== 'string' || !destination.trim())) {
|
|
37
57
|
onComplete?.({ error: 'destination_invalid', message: 'destination must be a non-empty string' });
|
|
38
|
-
return
|
|
58
|
+
return promise;
|
|
39
59
|
}
|
|
40
60
|
if (destination) destination = prefixStoragePath(destination?.trim());
|
|
41
61
|
|
|
42
|
-
if (typeof link !== 'string' || !link.trim()
|
|
62
|
+
if (typeof link !== 'string' || !Validator.LINK(link = link.trim())) {
|
|
43
63
|
onComplete?.({
|
|
44
64
|
error: 'invalid_link',
|
|
45
|
-
message: `
|
|
65
|
+
message: `downloadFile first argument has an invalid value, expected a valid link string but got '${link}' instead`
|
|
46
66
|
});
|
|
47
|
-
return
|
|
67
|
+
return promise;
|
|
48
68
|
}
|
|
49
|
-
link = link.trim();
|
|
50
69
|
|
|
51
70
|
const processID = `${++Scoped.StorageProcessID}`;
|
|
52
71
|
const init = async () => {
|
|
@@ -86,7 +105,6 @@ export class MTStorage {
|
|
|
86
105
|
onComplete?.(path ? undefined : (result?.simpleError || { error, message: errorDes }), path);
|
|
87
106
|
resultListener.remove();
|
|
88
107
|
progressListener.remove();
|
|
89
|
-
hasFinished = true;
|
|
90
108
|
});
|
|
91
109
|
|
|
92
110
|
RNMTModule.downloadFile({
|
|
@@ -103,30 +121,36 @@ export class MTStorage {
|
|
|
103
121
|
}
|
|
104
122
|
|
|
105
123
|
init();
|
|
106
|
-
|
|
107
|
-
return () => {
|
|
108
|
-
if (hasFinished || hasCancelled) return;
|
|
109
|
-
RNMTModule.cancelDownload(processID);
|
|
110
|
-
hasCancelled = true;
|
|
111
|
-
setTimeout(() => {
|
|
112
|
-
onComplete?.({ error: 'download_aborted', message: 'The download process was aborted' });
|
|
113
|
-
}, 1);
|
|
114
|
-
}
|
|
124
|
+
return promise;
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
uploadFile(file = '', destination = '',
|
|
118
|
-
const { createHash, awaitServer } = options || {};
|
|
127
|
+
uploadFile = (file = '', destination = '', options) => {
|
|
128
|
+
const { createHash, awaitServer, onProgress } = options || {};
|
|
119
129
|
let hasFinished, hasCancelled;
|
|
130
|
+
let thisComplete;
|
|
120
131
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
const promise = new Promise((resolve, reject) => {
|
|
133
|
+
thisComplete = (err, url) => {
|
|
134
|
+
if (hasFinished) return;
|
|
135
|
+
hasFinished = true;
|
|
136
|
+
if (url) {
|
|
137
|
+
resolve(url);
|
|
138
|
+
} else reject(err);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
promise.abort = () => {
|
|
143
|
+
if (hasFinished || hasCancelled) return;
|
|
144
|
+
hasCancelled = true;
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
thisComplete?.({ error: 'upload_aborted', message: 'The upload process was aborted' });
|
|
147
|
+
}, 0);
|
|
148
|
+
RNMTModule.cancelUpload(processID);
|
|
149
|
+
};
|
|
126
150
|
|
|
127
151
|
if (typeof file !== 'string' || !file.trim()) {
|
|
128
152
|
thisComplete?.({ error: 'file_path_invalid', message: 'file must be a non-empty string in uploadFile()' });
|
|
129
|
-
return
|
|
153
|
+
return promise;
|
|
130
154
|
}
|
|
131
155
|
destination = destination?.trim?.();
|
|
132
156
|
|
|
@@ -134,7 +158,7 @@ export class MTStorage {
|
|
|
134
158
|
validateDestination(destination);
|
|
135
159
|
} catch (error) {
|
|
136
160
|
thisComplete?.({ error: 'destination_invalid', message: error });
|
|
137
|
-
return
|
|
161
|
+
return promise;
|
|
138
162
|
}
|
|
139
163
|
|
|
140
164
|
const isAsset = file.startsWith('ph://') || file.startsWith('content://');
|
|
@@ -142,6 +166,7 @@ export class MTStorage {
|
|
|
142
166
|
|
|
143
167
|
const { projectUrl, uglify, extraHeaders } = this.builder;
|
|
144
168
|
const processID = `${++Scoped.StorageProcessID}`;
|
|
169
|
+
const thisProjectUrl = options?.projectUrl || projectUrl;
|
|
145
170
|
|
|
146
171
|
const init = async () => {
|
|
147
172
|
if (awaitServer) await awaitReachableServer(projectUrl);
|
|
@@ -167,7 +192,7 @@ export class MTStorage {
|
|
|
167
192
|
const authToken = Scoped.AuthJWTToken[projectUrl];
|
|
168
193
|
|
|
169
194
|
RNMTModule.uploadFile({
|
|
170
|
-
url: EngineApi._uploadFile(
|
|
195
|
+
url: EngineApi._uploadFile(thisProjectUrl, uglify),
|
|
171
196
|
file: isAsset ? file : file.substring('file://'.length),
|
|
172
197
|
...authToken ? { authToken } : {},
|
|
173
198
|
createHash: createHash ? 'yes' : 'no',
|
|
@@ -178,24 +203,16 @@ export class MTStorage {
|
|
|
178
203
|
}
|
|
179
204
|
|
|
180
205
|
init();
|
|
181
|
-
|
|
182
|
-
return () => {
|
|
183
|
-
if (hasFinished || hasCancelled) return;
|
|
184
|
-
hasCancelled = true;
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
thisComplete?.({ error: 'upload_aborted', message: 'The upload process was aborted' });
|
|
187
|
-
}, 0);
|
|
188
|
-
RNMTModule.cancelUpload(processID);
|
|
189
|
-
}
|
|
206
|
+
return promise;
|
|
190
207
|
}
|
|
191
208
|
|
|
192
|
-
deleteFile = (path) => deleteContent(this.builder, path);
|
|
193
|
-
deleteFolder = (path) => deleteContent(this.builder, path, true);
|
|
209
|
+
deleteFile = (path, options) => deleteContent(this.builder, path, options);
|
|
210
|
+
deleteFolder = (path, options) => deleteContent(this.builder, path, options, true);
|
|
194
211
|
}
|
|
195
212
|
|
|
196
213
|
const { _deleteFile, _deleteFolder } = EngineApi;
|
|
197
214
|
|
|
198
|
-
const deleteContent = async (builder, path, isFolder) => {
|
|
215
|
+
const deleteContent = async (builder, path, options, isFolder) => {
|
|
199
216
|
const { projectUrl, uglify, extraHeaders, serverE2E_PublicKey } = builder;
|
|
200
217
|
|
|
201
218
|
try {
|
|
@@ -207,8 +224,10 @@ const deleteContent = async (builder, path, isFolder) => {
|
|
|
207
224
|
serverE2E_PublicKey,
|
|
208
225
|
uglify
|
|
209
226
|
});
|
|
227
|
+
const thisProjectUrl = options?.projectUrl || projectUrl;
|
|
210
228
|
|
|
211
|
-
const
|
|
229
|
+
const res = await fetch((isFolder ? _deleteFolder : _deleteFile)(thisProjectUrl, uglify), reqBuilder);
|
|
230
|
+
const data = await buildFetchResult(res, uglify);
|
|
212
231
|
const result = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
213
232
|
|
|
214
233
|
if (result.status !== 'success') throw 'operation not successful';
|