react-native-mosquito-transport 0.0.19 → 0.0.21

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.
@@ -1,10 +1,12 @@
1
- import setLargeTimeout from "set-large-timeout";
2
- import { doSignOut } from ".";
3
- import EngineApi from "../../helpers/EngineApi";
1
+ import cloneDeep from "lodash.clonedeep";
2
+ import { doSignOut, revokeAuthIntance } from ".";
3
+ import EngineApi from "../../helpers/engine_api";
4
4
  import { AuthTokenListener, TokenRefreshListener } from "../../helpers/listeners";
5
5
  import { decodeBinary, deserializeE2E, listenReachableServer } from "../../helpers/peripherals";
6
- import { awaitStore, buildFetchInterface, simplifyError, updateCacheStore } from "../../helpers/utils";
6
+ import { awaitStore, buildFetchInterface, buildFetchResult, getPrefferTime, updateCacheStore } from "../../helpers/utils";
7
7
  import { CacheStore, Scoped } from "../../helpers/variables";
8
+ import { simplifyError } from "simplify-error";
9
+ import { Validator } from "guard-object";
8
10
 
9
11
  export const listenToken = (callback, projectUrl) =>
10
12
  AuthTokenListener.listenTo(projectUrl, (t, n) => {
@@ -18,18 +20,44 @@ export const injectFreshToken = async (config, { token, refreshToken }) => {
18
20
  await awaitStore();
19
21
  CacheStore.AuthStore[projectUrl] = { token, refreshToken };
20
22
  Scoped.AuthJWTToken[projectUrl] = token;
21
- updateCacheStore();
23
+ if (projectUrl in CacheStore.EmulatedAuth)
24
+ delete CacheStore.EmulatedAuth[projectUrl];
22
25
 
26
+ updateCacheStore(0);
27
+
28
+ triggerAuthToken(projectUrl);
29
+ initTokenRefresher(config);
30
+ };
31
+
32
+ export const injectEmulatedAuth = async (config, emulatedURL) => {
33
+ if (!Scoped.IsStoreReady) await awaitStore();
34
+ if (typeof emulatedURL !== 'string' || (!Validator.HTTPS(emulatedURL) && !Validator.HTTP(emulatedURL)))
35
+ throw `Expected "projectUrl" to be valid https or http link but got "${emulatedURL}"`;
36
+
37
+ const { projectUrl } = config;
38
+ const { token } = CacheStore.AuthStore[emulatedURL] || {};
39
+ const depended = Object.entries(CacheStore.EmulatedAuth).find(([_, v]) => projectUrl === v);
40
+
41
+ if (emulatedURL === projectUrl) throw `auth instance for ${emulatedURL} cannot emulate itself`;
42
+ if (depended) throw `Chain Emulation Error: this auth instance (${projectUrl}) cannot be emulated as other auth instance (${depended[0]}) is already emulating it`;
43
+ const thisAuthStore = cloneDeep(CacheStore.AuthStore[projectUrl]);
44
+ revokeAuthIntance(config, thisAuthStore);
45
+
46
+ CacheStore.AuthStore[projectUrl] = cloneDeep(CacheStore.AuthStore[emulatedURL]);
47
+ Scoped.AuthJWTToken[projectUrl] = token;
48
+ CacheStore.EmulatedAuth[projectUrl] = emulatedURL;
49
+
50
+ updateCacheStore(0);
23
51
  triggerAuthToken(projectUrl);
24
52
  initTokenRefresher(config);
25
- }
53
+ };
26
54
 
27
55
  export const parseToken = (token) => JSON.parse(decodeBinary(token.split('.')[1]));
28
56
 
29
57
  export const triggerAuthToken = async (projectUrl, isInit) => {
30
58
  await awaitStore();
31
59
  AuthTokenListener.dispatch(projectUrl, CacheStore.AuthStore[projectUrl]?.token || null, isInit);
32
- }
60
+ };
33
61
 
34
62
  export const awaitRefreshToken = (projectUrl) => new Promise(resolve => {
35
63
  const l = TokenRefreshListener.listenTo(projectUrl, v => {
@@ -44,63 +72,96 @@ export const listenTokenReady = (callback, projectUrl) => TokenRefreshListener.l
44
72
 
45
73
  export const initTokenRefresher = async (config, forceRefresh) => {
46
74
  const { projectUrl, maxRetries } = config;
47
- await awaitStore();
48
- const { token } = CacheStore.AuthStore[projectUrl] || {},
49
- tokenInfo = token ? parseToken(token) : undefined;
50
-
51
- Scoped.TokenRefreshTimer[projectUrl]?.();
75
+ if (!Scoped.IsStoreReady) await awaitStore();
76
+ const { token } = CacheStore.AuthStore[projectUrl] || {};
77
+ const emulatedURL = CacheStore.EmulatedAuth[projectUrl];
78
+ const tokenInfo = token && parseToken(token);
79
+
80
+ clearInterval(Scoped.TokenRefreshTimer[projectUrl]);
81
+ if (emulatedURL) return;
82
+
83
+ const notifyAuthReady = (value) => {
84
+ TokenRefreshListener.dispatch(projectUrl, value);
85
+ getEmulatedLinks(projectUrl).forEach(v => {
86
+ TokenRefreshListener.dispatch(v, value);
87
+ });
88
+ }
52
89
 
53
90
  if (token) {
54
- const hasExpire = Date.now() >= (tokenInfo.exp * 1000) - 60000,
55
- rizz = () => refreshToken(config, ++Scoped.LastTokenRefreshRef[projectUrl], maxRetries, maxRetries, forceRefresh);
91
+ const expireOn = (tokenInfo.exp * 1000) - 60000;
92
+ const hasExpire = getPrefferTime() >= expireOn;
93
+ const rizz = () => refreshToken(config, ++Scoped.LastTokenRefreshRef[projectUrl], maxRetries, maxRetries, forceRefresh);
56
94
 
57
95
  if (hasExpire || forceRefresh) {
58
- TokenRefreshListener.dispatch(projectUrl);
96
+ notifyAuthReady();
59
97
  return rizz();
60
98
  } else {
61
- TokenRefreshListener.dispatch(projectUrl, 'ready');
62
- Scoped.TokenRefreshTimer[projectUrl] = setLargeTimeout(() => {
63
- TokenRefreshListener.dispatch(projectUrl);
99
+ notifyAuthReady('ready');
100
+ Scoped.TokenRefreshTimer[projectUrl] = setInterval(() => {
101
+ const countdown = expireOn - getPrefferTime();
102
+ if (countdown > 3000) return;
103
+ clearInterval(Scoped.TokenRefreshTimer[projectUrl]);
104
+ notifyAuthReady();
64
105
  rizz();
65
- }, ((tokenInfo.exp * 1000) - 60000) - Date.now());
106
+ }, 3000);
107
+ }
108
+ } else {
109
+ notifyAuthReady('ready');
110
+ if (forceRefresh) {
111
+ return simplifyError('no_token_yet', 'No token is available to initiate a refresh').simpleError;
66
112
  }
67
- } else if (forceRefresh) {
68
- TokenRefreshListener.dispatch(projectUrl, 'ready');
69
- return simplifyError('no_token_yet', 'No token is available to initiate a refresh').simpleError
70
113
  }
71
- }
114
+ };
115
+
116
+ export const getEmulatedLinks = (projectUrl) => Object.entries(CacheStore.EmulatedAuth)
117
+ .filter(([_, v]) => v === projectUrl)
118
+ .map(v => v[0]);
72
119
 
73
120
  const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7, isForceRefresh) => new Promise(async (resolve, reject) => {
74
- const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
75
- const lostProcess = simplifyError('process_lost', 'The token refresh process has been lost and replace with another one');
121
+ const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
122
+ const lostProcess = simplifyError('process_lost', 'The token refresh process has been lost and replaced with another one');
76
123
 
77
124
  try {
78
125
  const { token, refreshToken: r_token } = CacheStore.AuthStore[projectUrl];
79
126
 
80
- const [reqBuilder, [privateKey]] = buildFetchInterface({
127
+ const [reqBuilder, [privateKey]] = await buildFetchInterface({
81
128
  body: { token, r_token },
82
129
  accessKey,
83
130
  uglify,
84
- serverE2E_PublicKey
131
+ serverE2E_PublicKey,
132
+ extraHeaders
85
133
  });
86
134
 
87
- const r = await (await fetch(EngineApi._refreshAuthToken(projectUrl, uglify), reqBuilder)).json();
135
+ let data;
88
136
 
89
- if (processRef !== Scoped.LastTokenRefreshRef[projectUrl]) {
90
- reject(lostProcess.simpleError);
91
- return;
137
+ try {
138
+ data = await buildFetchResult(await fetch(EngineApi._refreshAuthToken(projectUrl, uglify), reqBuilder), uglify);
139
+ } finally {
140
+ if (processRef !== Scoped.LastTokenRefreshRef[projectUrl]) {
141
+ reject(lostProcess.simpleError);
142
+ return;
143
+ }
92
144
  }
93
- if (r.simpleError) throw r;
94
145
 
95
- const f = uglify ? deserializeE2E(r.e2e, serverE2E_PublicKey, privateKey) : r;
146
+ const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
96
147
 
97
148
  if (CacheStore.AuthStore[projectUrl]) {
98
149
  CacheStore.AuthStore[projectUrl].token = f.result.token;
99
150
  Scoped.AuthJWTToken[projectUrl] = f.result.token;
100
151
 
101
152
  resolve(f.result.token);
102
- triggerAuthToken(projectUrl, !Scoped.InitiatedForcedToken[projectUrl] && isForceRefresh);
153
+ const isInit = !Scoped.InitiatedForcedToken[projectUrl] && isForceRefresh;
154
+
155
+ triggerAuthToken(projectUrl, isInit);
103
156
  if (isForceRefresh) Scoped.InitiatedForcedToken[projectUrl] = true;
157
+
158
+ getEmulatedLinks(projectUrl).forEach(v => {
159
+ CacheStore.AuthStore[v] = cloneDeep(CacheStore.AuthStore[projectUrl]);
160
+ Scoped.AuthJWTToken[v] = f.result.token;
161
+
162
+ triggerAuthToken(v, isInit);
163
+ if (isForceRefresh) Scoped.InitiatedForcedToken[v] = true;
164
+ });
104
165
  updateCacheStore();
105
166
  initTokenRefresher(builder);
106
167
  } else reject(lostProcess.simpleError);
@@ -115,7 +176,7 @@ const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7
115
176
  lostProcess.simpleError :
116
177
  simplifyError('retry_limit_reached', 'The retry limit has been reach and execution prematurely stopped').simpleError
117
178
  );
118
- console.error(`refreshToken retry exceeded, waiting for 2min before starting another retry`);
179
+ console.error(`refreshToken retry limit exceeded`);
119
180
  } else {
120
181
  const l = listenReachableServer(c => {
121
182
  if (processRef !== Scoped.LastTokenRefreshRef[projectUrl]) {
@@ -123,7 +184,7 @@ const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7
123
184
  l();
124
185
  } else if (c) {
125
186
  l();
126
- refreshToken(builder, processRef, remainRetries - 1, initialRetries).then(resolve, reject);
187
+ refreshToken(builder, processRef, remainRetries - 1, initialRetries, isForceRefresh).then(resolve, reject);
127
188
  }
128
189
  }, projectUrl);
129
190
  }
@@ -1,20 +1,23 @@
1
1
  import { io } from "socket.io-client";
2
- import EngineApi from "../../helpers/EngineApi";
2
+ import EngineApi from "../../helpers/engine_api";
3
3
  import { TokenRefreshListener } from "../../helpers/listeners";
4
- import { awaitReachableServer, awaitStore, buildFetchInterface, simplifyError, updateCacheStore } from "../../helpers/utils";
5
- import { CacheConstant, CacheStore, Scoped } from "../../helpers/variables";
6
- import { awaitRefreshToken, initTokenRefresher, injectFreshToken, listenToken, parseToken, triggerAuthToken } from "./accessor";
7
- import { deserializeE2E, encodeBinary, serializeE2E, simplifyCaughtError } from "../../helpers/peripherals";
4
+ import { awaitReachableServer, awaitStore, buildFetchInterface, buildFetchResult, updateCacheStore } from "../../helpers/utils";
5
+ import { CacheStore, Scoped } from "../../helpers/variables";
6
+ import { awaitRefreshToken, getEmulatedLinks, initTokenRefresher, injectEmulatedAuth, injectFreshToken, listenToken, parseToken, triggerAuthToken } from "./accessor";
7
+ import { deserializeE2E, encodeBinary, serializeE2E } from "../../helpers/peripherals";
8
+ import { simplifyCaughtError, simplifyError } from "simplify-error";
9
+ import cloneDeep from "lodash.clonedeep";
8
10
 
9
11
  const {
10
12
  _listenUserVerification,
11
13
  _signOut,
12
14
  _customSignin,
13
15
  _customSignup,
14
- _googleSignin
16
+ _googleSignin,
17
+ _areYouOk
15
18
  } = EngineApi;
16
19
 
17
- export class MTAuth {
20
+ export default class MTAuth {
18
21
  constructor(config) {
19
22
  this.builder = { ...config };
20
23
  }
@@ -26,25 +29,29 @@ export class MTAuth {
26
29
  googleSignin = (token) => doGoogleSignin(this.builder, token);
27
30
 
28
31
  appleSignin() {
29
-
32
+ throw 'unsupported method call';
30
33
  }
31
34
 
32
35
  facebookSignin() {
33
-
36
+ throw 'unsupported method call';
34
37
  }
35
38
 
36
39
  twitterSignin() {
37
-
40
+ throw 'unsupported method call';
38
41
  }
39
42
 
40
43
  githubSignin() {
41
-
44
+ throw 'unsupported method call';
42
45
  }
43
46
 
44
47
  listenVerifiedStatus(callback, onError) {
45
48
  const { projectUrl, serverE2E_PublicKey, uglify, baseUrl, wsPrefix } = this.builder;
46
49
 
47
- let socket, wasDisconnected, lastToken = Scoped.AuthJWTToken[projectUrl] || null, lastInitRef = 0;
50
+ let socket,
51
+ wasDisconnected,
52
+ hasCancelled,
53
+ lastToken = Scoped.AuthJWTToken[projectUrl] || null,
54
+ lastInitRef = 0;
48
55
 
49
56
  const init = async () => {
50
57
  const processID = ++lastInitRef;
@@ -56,23 +63,23 @@ export class MTAuth {
56
63
  }
57
64
  if (processID !== lastInitRef) return;
58
65
  const mtoken = Scoped.AuthJWTToken[projectUrl],
59
- [reqBuilder, [privateKey]] = uglify ? serializeE2E({ mtoken }, undefined, serverE2E_PublicKey) : [null, []];
66
+ [reqBuilder, [privateKey]] = uglify ? await serializeE2E({ mtoken }, undefined, serverE2E_PublicKey) : [null, []];
60
67
 
61
68
  socket = io(`${wsPrefix}://${baseUrl}`, {
69
+ transports: ['websocket', 'polling', 'flashsocket'],
62
70
  auth: uglify ? {
63
- e2e: reqBuilder,
71
+ e2e: reqBuilder.toString('base64'),
64
72
  _m_internal: true
65
73
  } : { mtoken, _m_internal: true }
66
74
  });
67
75
 
68
76
  socket.emit(_listenUserVerification(uglify));
69
77
 
70
- socket.on("onVerificationChanged", ([err, verified]) => {
71
- const fatal = err ? simplifyCaughtError(err).simpleError : undefined;
72
- if (fatal) {
73
- onError?.(fatal);
78
+ socket.on("onVerificationChanged", async ([err, verified]) => {
79
+ if (err) {
80
+ onError?.(simplifyCaughtError(err).simpleError);
74
81
  } else {
75
- callback?.(uglify ? deserializeE2E(verified, serverE2E_PublicKey, privateKey) : verified);
82
+ callback?.(uglify ? await deserializeE2E(verified, serverE2E_PublicKey, privateKey) : verified);
76
83
  }
77
84
  });
78
85
 
@@ -97,6 +104,8 @@ export class MTAuth {
97
104
  }, projectUrl);
98
105
 
99
106
  return () => {
107
+ if (hasCancelled) return;
108
+ hasCancelled = true;
100
109
  socket?.close?.();
101
110
  tokenListener?.();
102
111
  }
@@ -108,7 +117,13 @@ export class MTAuth {
108
117
  await awaitStore();
109
118
  return CacheStore.AuthStore[this.builder.projectUrl]?.refreshToken;
110
119
  }
111
-
120
+
121
+ getRefreshTokenData = async () => {
122
+ await awaitStore();
123
+ const { refreshToken } = CacheStore.AuthStore[this.builder.projectUrl] || {};
124
+ return refreshToken && parseToken(refreshToken);
125
+ }
126
+
112
127
  parseToken = (token) => parseToken(token);
113
128
 
114
129
  getAuthToken = () => new Promise(resolve => {
@@ -126,19 +141,23 @@ export class MTAuth {
126
141
 
127
142
  return listenToken((t, initToken) => {
128
143
  const { refreshToken } = CacheStore.AuthStore[this.builder.projectUrl] || {};
144
+ const parseData = t && parseToken(t);
145
+ const tokenEntity = parseData?.entityOf || null;
129
146
 
130
147
  if (
131
- (!!t || null) !== lastTrig ||
148
+ tokenEntity !== lastTrig ||
132
149
  initToken
133
- ) callback(t ? {
134
- ...parseToken(t),
135
- tokenManager: {
136
- refreshToken,
137
- accessToken: t
138
- }
139
- } : null);
150
+ ) {
151
+ callback(t ? {
152
+ ...parseData,
153
+ tokenManager: {
154
+ refreshToken,
155
+ accessToken: t
156
+ }
157
+ } : null);
158
+ }
140
159
 
141
- lastTrig = !!t || null;
160
+ lastTrig = tokenEntity;
142
161
  }, this.builder.projectUrl);
143
162
  }
144
163
 
@@ -152,24 +171,30 @@ export class MTAuth {
152
171
  signOut = () => doSignOut(this.builder);
153
172
 
154
173
  forceRefreshToken = () => initTokenRefresher(this.builder, true);
155
- }
174
+
175
+ emulate = async (projectUrl) => {
176
+ await injectEmulatedAuth(this.builder, projectUrl);
177
+ }
178
+ };
156
179
 
157
180
  const doCustomSignin = (builder, email, password) => new Promise(async (resolve, reject) => {
158
- const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
181
+ const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
159
182
 
160
183
  try {
161
184
  await awaitStore();
162
- const [reqBuilder, [privateKey]] = buildFetchInterface({
163
- body: { _: `${encodeBinary(email)}.${encodeBinary(password)}` },
185
+ const thisAuthStore = cloneDeep(CacheStore.AuthStore[projectUrl]);
186
+
187
+ const [reqBuilder, [privateKey]] = await buildFetchInterface({
188
+ body: { data: `${encodeBinary(email)}.${encodeBinary(password)}` },
164
189
  accessKey,
165
190
  serverE2E_PublicKey,
166
- uglify
191
+ uglify,
192
+ extraHeaders
167
193
  });
168
194
 
169
- const f = await (await fetch(_customSignin(projectUrl, uglify), reqBuilder)).json();
170
- if (f.simpleError) throw f;
195
+ const data = await buildFetchResult(await fetch(_customSignin(projectUrl, uglify), reqBuilder), uglify);
171
196
 
172
- const r = uglify ? deserializeE2E(f.e2e, serverE2E_PublicKey, privateKey) : f;
197
+ const r = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
173
198
 
174
199
  resolve({
175
200
  user: parseToken(r.result.token),
@@ -177,30 +202,33 @@ const doCustomSignin = (builder, email, password) => new Promise(async (resolve,
177
202
  refreshToken: r.result.refreshToken
178
203
  });
179
204
  await injectFreshToken(builder, r.result);
205
+ revokeAuthIntance(builder, thisAuthStore);
180
206
  } catch (e) {
181
207
  reject(simplifyCaughtError(e).simpleError);
182
208
  }
183
209
  });
184
210
 
185
211
  const doCustomSignup = (builder, email, password, name, metadata) => new Promise(async (resolve, reject) => {
186
- const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
212
+ const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
187
213
 
188
214
  try {
189
215
  await awaitStore();
190
- const [reqBuilder, [privateKey]] = buildFetchInterface({
216
+ const thisAuthStore = cloneDeep(CacheStore.AuthStore[projectUrl]);
217
+
218
+ const [reqBuilder, [privateKey]] = await buildFetchInterface({
191
219
  body: {
192
- _: `${encodeBinary(email)}.${encodeBinary(password)}.${(encodeBinary(name || '').trim())}`,
220
+ data: `${encodeBinary(email)}.${encodeBinary(password)}.${(encodeBinary((name || '').trim()))}`,
193
221
  metadata,
194
222
  },
195
223
  accessKey,
196
224
  serverE2E_PublicKey,
197
- uglify
225
+ uglify,
226
+ extraHeaders
198
227
  });
199
228
 
200
- const f = await (await fetch(_customSignup(projectUrl, uglify), reqBuilder)).json();
201
- if (f.simpleError) throw f;
229
+ const data = await buildFetchResult(await fetch(_customSignup(projectUrl, uglify), reqBuilder), uglify);
202
230
 
203
- const r = uglify ? deserializeE2E(f.e2e, serverE2E_PublicKey, privateKey) : f;
231
+ const r = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
204
232
 
205
233
  resolve({
206
234
  user: parseToken(r.result.token),
@@ -208,63 +236,109 @@ const doCustomSignup = (builder, email, password, name, metadata) => new Promise
208
236
  refreshToken: r.result.refreshToken
209
237
  });
210
238
  await injectFreshToken(builder, r.result);
239
+ revokeAuthIntance(builder, thisAuthStore);
211
240
  } catch (e) {
212
241
  reject(simplifyCaughtError(e).simpleError);
213
242
  }
214
243
  });
215
244
 
216
- export const doSignOut = async (builder) => {
217
- await awaitStore();
245
+ const purgeCache = (url, isMain) => {
246
+ if (url in Scoped.AuthJWTToken) delete Scoped.AuthJWTToken[url];
247
+ Object.keys(CacheStore).forEach(e => {
248
+ if (
249
+ e !== 'PendingAuthPurge' &&
250
+ (!['EmulatedAuth'].includes(e) || isMain)
251
+ ) {
252
+ if (CacheStore[e][url]) delete CacheStore[e][url];
253
+ }
254
+ });
255
+ TokenRefreshListener.dispatch(url);
256
+ triggerAuthToken(url);
257
+ };
218
258
 
219
- const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder,
220
- { token, refreshToken: r_token } = CacheStore.AuthStore[projectUrl];
259
+ const clearCacheForSignout = (builder, disposeEmulated) => {
260
+ const { projectUrl } = builder;
221
261
 
222
- TokenRefreshListener.dispatch(projectUrl);
223
- if (CacheStore.AuthStore[projectUrl]) delete CacheStore.AuthStore[projectUrl];
224
- if (token) delete Scoped.AuthJWTToken[projectUrl];
225
- Object.keys(CacheConstant).forEach(e => {
226
- CacheStore[e] = CacheConstant[e];
227
- });
228
- triggerAuthToken(projectUrl);
229
- updateCacheStore();
262
+ purgeCache(projectUrl, true);
263
+ if (disposeEmulated) getEmulatedLinks(projectUrl).forEach(e => purgeCache(e));
230
264
  initTokenRefresher(builder);
265
+ };
231
266
 
232
- if (token) {
233
- TokenRefreshListener.dispatch(projectUrl, 'ready');
267
+ export const doSignOut = async (builder) => {
268
+ if (!Scoped.IsStoreReady) await awaitStore();
269
+ const emulatedURL = CacheStore.EmulatedAuth[builder.projectUrl];
270
+
271
+ clearCacheForSignout(builder, !emulatedURL);
272
+ updateCacheStore(0);
273
+ if (emulatedURL) return;
274
+ await revokeAuthIntance(builder);
275
+ };
276
+
277
+ export const revokeAuthIntance = async (builder, authStore) => {
278
+ const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
279
+ const { token, refreshToken: r_token } = { ...authStore };
280
+
281
+ if (!r_token || CacheStore.EmulatedAuth[projectUrl]) return;
282
+ const nodeId = `${Math.random()}`;
283
+
284
+ CacheStore.PendingAuthPurge[nodeId] = {
285
+ auth: { token, refreshToken: r_token },
286
+ data: { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders }
287
+ };
288
+ await purgePendingToken(nodeId);
289
+ };
290
+
291
+ export const purgePendingToken = async (nodeId) => {
292
+ const {
293
+ auth: { token, refreshToken: r_token },
294
+ data: { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders }
295
+ } = CacheStore.PendingAuthPurge[nodeId];
296
+
297
+ if (!token) return;
298
+ try {
299
+ let isConnected;
234
300
  try {
301
+ isConnected = (await (await fetch(_areYouOk(projectUrl))).json(), { cache: 'no-cache' }).status === 'yes';
302
+ } catch (_) { }
303
+
304
+ if (!isConnected)
235
305
  await awaitReachableServer(projectUrl);
236
306
 
237
- const [reqBuilder] = buildFetchInterface({
238
- body: { token, r_token },
239
- accessKey,
240
- uglify,
241
- serverE2E_PublicKey
242
- });
307
+ const [reqBuilder] = await buildFetchInterface({
308
+ body: { token, r_token },
309
+ accessKey,
310
+ uglify,
311
+ serverE2E_PublicKey,
312
+ extraHeaders
313
+ });
243
314
 
244
- const r = await (await fetch(_signOut(projectUrl, uglify), reqBuilder)).json();
245
- if (r.simpleError) throw r;
246
- } catch (e) {
247
- throw simplifyCaughtError(e).simpleError;
248
- }
315
+ await buildFetchResult(await fetch(_signOut(projectUrl, uglify), reqBuilder), uglify);
316
+ } catch (e) {
317
+ throw simplifyCaughtError(e).simpleError;
318
+ } finally {
319
+ delete CacheStore.PendingAuthPurge[nodeId];
320
+ updateCacheStore(0);
249
321
  }
250
- }
322
+ };
251
323
 
252
324
  const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) => {
253
- const { projectUrl, serverE2E_PublicKey, accessKey, uglify } = builder;
325
+ const { projectUrl, serverE2E_PublicKey, accessKey, uglify, extraHeaders } = builder;
254
326
 
255
327
  try {
256
328
  await awaitStore();
257
- const [reqBuilder, [privateKey]] = buildFetchInterface({
329
+ const thisAuthStore = cloneDeep(CacheStore.AuthStore[projectUrl]);
330
+
331
+ const [reqBuilder, [privateKey]] = await buildFetchInterface({
258
332
  body: { token },
259
333
  accessKey,
260
334
  uglify,
261
- serverE2E_PublicKey
335
+ serverE2E_PublicKey,
336
+ extraHeaders
262
337
  });
263
338
 
264
- const r = await (await fetch(_googleSignin(projectUrl, uglify), reqBuilder)).json();
265
- if (r.simpleError) throw r;
339
+ const data = await buildFetchResult(await fetch(_googleSignin(projectUrl, uglify), reqBuilder), uglify);
266
340
 
267
- const f = uglify ? deserializeE2E(r.e2e, serverE2E_PublicKey, privateKey) : r;
341
+ const f = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
268
342
 
269
343
  resolve({
270
344
  user: parseToken(f.result.token),
@@ -273,6 +347,7 @@ const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) =
273
347
  isNewUser: f.result.isNewUser
274
348
  });
275
349
  await injectFreshToken(builder, f.result);
350
+ revokeAuthIntance(builder, thisAuthStore);
276
351
  } catch (e) {
277
352
  reject(simplifyCaughtError(e).simpleError);
278
353
  }
@@ -280,10 +355,4 @@ const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) =
280
355
 
281
356
  const doAppleSignin = async () => {
282
357
 
283
- }
284
-
285
- const validateEmailAndPassword = () => { }
286
-
287
- const getAuthState = async (projectUrl) => {
288
-
289
358
  }