@opexa/portal-sdk 0.59.128 → 0.59.129

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/dist/index.cjs CHANGED
@@ -4882,6 +4882,15 @@ var ERROR_MAP = {
4882
4882
  };
4883
4883
 
4884
4884
  // src/services/auth.service.ts
4885
+ function getCompatibleSignal(signal) {
4886
+ if (!signal) return void 0;
4887
+ try {
4888
+ new Request("about:blank", { signal });
4889
+ return signal;
4890
+ } catch {
4891
+ return void 0;
4892
+ }
4893
+ }
4885
4894
  var AuthService = class {
4886
4895
  url;
4887
4896
  graphqlClient;
@@ -5049,7 +5058,7 @@ var AuthService = class {
5049
5058
  }
5050
5059
  throw new Error("Invalid input 'type'");
5051
5060
  }
5052
- async refreshSession(refreshToken, version = 1) {
5061
+ async refreshSession(refreshToken, version = 1, signal) {
5053
5062
  const headers = new Headers(this.headers);
5054
5063
  if (version !== 4 || refreshToken) {
5055
5064
  headers.append("Authorization", `Bearer ${refreshToken}`);
@@ -5068,6 +5077,7 @@ var AuthService = class {
5068
5077
  {
5069
5078
  method: "POST",
5070
5079
  headers,
5080
+ signal: getCompatibleSignal(signal),
5071
5081
  ...version === 4 && { credentials: "include" }
5072
5082
  }
5073
5083
  );
@@ -5136,13 +5146,14 @@ var AuthService = class {
5136
5146
  return { ok: false, error: statusCodeToOperationError(500) };
5137
5147
  }
5138
5148
  }
5139
- async verifySession(accessToken) {
5149
+ async verifySession(accessToken, signal) {
5140
5150
  const headers = new Headers(this.headers);
5141
5151
  headers.append("Authorization", `Bearer ${accessToken}`);
5142
5152
  try {
5143
5153
  const res = await fetch(`${this.url}/session`, {
5144
5154
  method: "GET",
5145
- headers
5155
+ headers,
5156
+ signal: getCompatibleSignal(signal)
5146
5157
  });
5147
5158
  return res.ok;
5148
5159
  } catch {
@@ -7737,6 +7748,36 @@ function createRefreshTokenStore(logger, sessionPrefix) {
7737
7748
  return new PreferencesRefreshTokenStore(key, logger);
7738
7749
  }
7739
7750
 
7751
+ // src/sdk/session-lifecycle.ts
7752
+ var SessionLifecycle = class {
7753
+ controller = new AbortController();
7754
+ get signal() {
7755
+ return this.controller.signal;
7756
+ }
7757
+ renew() {
7758
+ this.controller.abort();
7759
+ this.controller = new AbortController();
7760
+ return this.controller.signal;
7761
+ }
7762
+ logout() {
7763
+ this.renew();
7764
+ }
7765
+ };
7766
+ var CredentialMutationLock = class {
7767
+ tail = Promise.resolve();
7768
+ wait() {
7769
+ return this.tail;
7770
+ }
7771
+ run(operation) {
7772
+ const result = this.tail.then(operation, operation);
7773
+ this.tail = result.then(
7774
+ () => void 0,
7775
+ () => void 0
7776
+ );
7777
+ return result;
7778
+ }
7779
+ };
7780
+
7740
7781
  // src/sdk/session-manager.ts
7741
7782
  var SessionManager = class {
7742
7783
  logger;
@@ -7745,6 +7786,8 @@ var SessionManager = class {
7745
7786
  authService;
7746
7787
  walletService;
7747
7788
  _refreshing = false;
7789
+ lifecycle = new SessionLifecycle();
7790
+ mutations = new CredentialMutationLock();
7748
7791
  /*
7749
7792
  * v4 access tokens live in memory only, so an XSS-readable storage layer
7750
7793
  * never holds a live one. Re-minted from the HttpOnly cookie, or from
@@ -7774,38 +7817,44 @@ var SessionManager = class {
7774
7817
  set refreshing(value) {
7775
7818
  this._refreshing = value;
7776
7819
  }
7777
- async persist(data, version) {
7778
- const now = /* @__PURE__ */ new Date();
7779
- if (version === 4) {
7780
- if (!data.session || !data.accessToken) {
7781
- this.logger.error(
7782
- "Malformed session response: expected 'session' and 'accessToken'."
7820
+ async persist(data, version, signal) {
7821
+ return this.mutations.run(async () => {
7822
+ if (signal.aborted) return true;
7823
+ const now = /* @__PURE__ */ new Date();
7824
+ this.refreshing = false;
7825
+ this.v4RefreshPromise = null;
7826
+ if (version === 4) {
7827
+ if (!data.session || !data.accessToken) {
7828
+ this.logger.error(
7829
+ "Malformed session response: expected 'session' and 'accessToken'."
7830
+ );
7831
+ return false;
7832
+ }
7833
+ this.v4AccessToken = data.accessToken;
7834
+ this.v4AccessTokenExpiresAt = addMinutes(now, 4).getTime();
7835
+ this.invalidReason = null;
7836
+ if (data.refreshToken) {
7837
+ await this.refreshTokenStore.set(data.refreshToken);
7838
+ }
7839
+ if (signal.aborted) return true;
7840
+ localStorage.setItem(
7841
+ this.storageKey,
7842
+ JSON.stringify({ version, session: data.session })
7783
7843
  );
7784
- return false;
7844
+ return true;
7785
7845
  }
7786
- this.v4AccessToken = data.accessToken;
7787
- this.v4AccessTokenExpiresAt = addMinutes(now, 4).getTime();
7788
7846
  this.invalidReason = null;
7789
- if (data.refreshToken) {
7790
- await this.refreshTokenStore.set(data.refreshToken);
7791
- }
7792
7847
  localStorage.setItem(
7793
7848
  this.storageKey,
7794
- JSON.stringify({ version, session: data.session })
7849
+ JSON.stringify({
7850
+ version,
7851
+ ...data,
7852
+ accessTokenExpiresAt: addMinutes(now, 8).getTime(),
7853
+ refreshTokenExpiresAt: subMinutes(addDays(now, 1), 2).getTime()
7854
+ })
7795
7855
  );
7796
7856
  return true;
7797
- }
7798
- this.invalidReason = null;
7799
- localStorage.setItem(
7800
- this.storageKey,
7801
- JSON.stringify({
7802
- version,
7803
- ...data,
7804
- accessTokenExpiresAt: addMinutes(now, 8).getTime(),
7805
- refreshTokenExpiresAt: subMinutes(addDays(now, 1), 2).getTime()
7806
- })
7807
- );
7808
- return true;
7857
+ });
7809
7858
  }
7810
7859
  malformedResponseError() {
7811
7860
  return {
@@ -7817,6 +7866,10 @@ var SessionManager = class {
7817
7866
  };
7818
7867
  }
7819
7868
  async create(input, version = 1) {
7869
+ const waitingSignal = this.lifecycle.signal;
7870
+ await this.mutations.wait();
7871
+ if (waitingSignal.aborted) return { ok: true, data: null };
7872
+ const signal = this.lifecycle.renew();
7820
7873
  if (this.isServer) {
7821
7874
  this.logger.warn("'localStorage' is not available on the server.");
7822
7875
  return {
@@ -7852,7 +7905,7 @@ var SessionManager = class {
7852
7905
  maxAttempt: 5
7853
7906
  })();
7854
7907
  if (!r1.ok) return r1;
7855
- if (!await this.persist(r1.data, version))
7908
+ if (!await this.persist(r1.data, version, signal))
7856
7909
  return this.malformedResponseError();
7857
7910
  return {
7858
7911
  ok: true,
@@ -7862,7 +7915,7 @@ var SessionManager = class {
7862
7915
  if (input.type === "MOBILE_NUMBER") {
7863
7916
  const res2 = await this.authService.createSession(input, version);
7864
7917
  if (res2.ok) {
7865
- if (!await this.persist(res2.data, version))
7918
+ if (!await this.persist(res2.data, version, signal))
7866
7919
  return this.malformedResponseError();
7867
7920
  return {
7868
7921
  ok: true,
@@ -7881,7 +7934,7 @@ var SessionManager = class {
7881
7934
  version
7882
7935
  );
7883
7936
  if (res2.ok) {
7884
- if (!await this.persist(res2.data, version))
7937
+ if (!await this.persist(res2.data, version, signal))
7885
7938
  return this.malformedResponseError();
7886
7939
  return {
7887
7940
  ok: true,
@@ -7894,7 +7947,7 @@ var SessionManager = class {
7894
7947
  localStorage.setItem(this.platformStorageKey, "CABINET");
7895
7948
  const res2 = await this.authService.createSession(input, version);
7896
7949
  if (res2.ok) {
7897
- if (!await this.persist(res2.data, version))
7950
+ if (!await this.persist(res2.data, version, signal))
7898
7951
  return this.malformedResponseError();
7899
7952
  return {
7900
7953
  ok: true,
@@ -7913,7 +7966,7 @@ var SessionManager = class {
7913
7966
  }
7914
7967
  };
7915
7968
  }
7916
- if (!await this.persist(res.data, version))
7969
+ if (!await this.persist(res.data, version, signal))
7917
7970
  return this.malformedResponseError();
7918
7971
  return {
7919
7972
  ok: true,
@@ -7921,11 +7974,15 @@ var SessionManager = class {
7921
7974
  };
7922
7975
  }
7923
7976
  async createFromAuthenticator(input) {
7977
+ const waitingSignal = this.lifecycle.signal;
7978
+ await this.mutations.wait();
7979
+ if (waitingSignal.aborted) return { ok: true };
7980
+ const signal = this.lifecycle.renew();
7924
7981
  const res = await this.authService.authenticate(input);
7925
7982
  if (res.ok) {
7926
7983
  if (this.isServer) {
7927
7984
  this.logger.warn("'localStorage' is not available on the server.");
7928
- } else if (!await this.persist(res.data, 1)) {
7985
+ } else if (!await this.persist(res.data, 1, signal)) {
7929
7986
  return this.malformedResponseError();
7930
7987
  }
7931
7988
  return { ok: true };
@@ -7934,6 +7991,7 @@ var SessionManager = class {
7934
7991
  }
7935
7992
  }
7936
7993
  async get() {
7994
+ const signal = this.lifecycle.signal;
7937
7995
  if (this.isServer) {
7938
7996
  this.logger.warn("'localStorage' is not available on the server.");
7939
7997
  return {
@@ -7943,6 +8001,7 @@ var SessionManager = class {
7943
8001
  }
7944
8002
  if (this.refreshing) {
7945
8003
  await sleep(1e3);
8004
+ if (signal.aborted) return { ok: true, data: null };
7946
8005
  return await this.get();
7947
8006
  }
7948
8007
  const val = localStorage.getItem(this.storageKey);
@@ -7977,8 +8036,10 @@ var SessionManager = class {
7977
8036
  this.refreshing = true;
7978
8037
  const res = await this.authService.refreshSession(
7979
8038
  obj.refreshToken,
7980
- obj.version ?? 1
8039
+ obj.version ?? 1,
8040
+ signal
7981
8041
  );
8042
+ if (signal.aborted) return { ok: true, data: null };
7982
8043
  this.refreshing = false;
7983
8044
  if (!res.ok) {
7984
8045
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
@@ -8011,6 +8072,8 @@ var SessionManager = class {
8011
8072
  data: obj
8012
8073
  };
8013
8074
  } catch {
8075
+ if (signal.aborted) return { ok: true, data: null };
8076
+ this.refreshing = false;
8014
8077
  return {
8015
8078
  ok: false,
8016
8079
  error: {
@@ -8035,6 +8098,7 @@ var SessionManager = class {
8035
8098
  return await this.refreshV4(session);
8036
8099
  }
8037
8100
  async refresh() {
8101
+ const signal = this.lifecycle.signal;
8038
8102
  if (this.isServer) {
8039
8103
  this.logger.warn("'localStorage' is not available on the server.");
8040
8104
  return {
@@ -8060,8 +8124,10 @@ var SessionManager = class {
8060
8124
  this.refreshing = true;
8061
8125
  const res = await this.authService.refreshSession(
8062
8126
  obj.refreshToken,
8063
- obj.version ?? 1
8127
+ obj.version ?? 1,
8128
+ signal
8064
8129
  );
8130
+ if (signal.aborted) return { ok: true, data: null };
8065
8131
  this.refreshing = false;
8066
8132
  if (!res.ok) {
8067
8133
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
@@ -8094,6 +8160,8 @@ var SessionManager = class {
8094
8160
  data: obj
8095
8161
  };
8096
8162
  } catch {
8163
+ if (signal.aborted) return { ok: true, data: null };
8164
+ this.refreshing = false;
8097
8165
  return {
8098
8166
  ok: false,
8099
8167
  error: {
@@ -8105,18 +8173,20 @@ var SessionManager = class {
8105
8173
  }
8106
8174
  async refreshV4(session) {
8107
8175
  if (this.v4RefreshPromise) return await this.v4RefreshPromise;
8108
- this.v4RefreshPromise = this.requestV4Refresh(session);
8176
+ const promise = this.requestV4Refresh(session, this.lifecycle.signal);
8177
+ this.v4RefreshPromise = promise;
8109
8178
  try {
8110
- return await this.v4RefreshPromise;
8179
+ return await promise;
8111
8180
  } finally {
8112
- this.v4RefreshPromise = null;
8181
+ if (this.v4RefreshPromise === promise) this.v4RefreshPromise = null;
8113
8182
  }
8114
8183
  }
8115
- async requestV4Refresh(session) {
8184
+ async requestV4Refresh(session, signal) {
8116
8185
  this.logger.info("Refreshing session...");
8117
8186
  let refreshToken;
8118
8187
  if (isIOSPlatform()) {
8119
8188
  refreshToken = await this.refreshTokenStore.get() ?? void 0;
8189
+ if (signal.aborted) return { ok: true, data: null };
8120
8190
  if (!refreshToken) {
8121
8191
  this.logger.warn("No stored refresh token. Session expired.");
8122
8192
  this.v4AccessToken = null;
@@ -8133,7 +8203,8 @@ var SessionManager = class {
8133
8203
  }
8134
8204
  }
8135
8205
  this.refreshing = true;
8136
- const res = await this.authService.refreshSession(refreshToken, 4);
8206
+ const res = await this.authService.refreshSession(refreshToken, 4, signal);
8207
+ if (signal.aborted) return { ok: true, data: null };
8137
8208
  if (!res.ok) {
8138
8209
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
8139
8210
  const terminal = res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError" || res.error.name === "SessionExpiredError";
@@ -8145,6 +8216,7 @@ var SessionManager = class {
8145
8216
  }
8146
8217
  this.refreshing = false;
8147
8218
  if (terminal) await this.refreshTokenStore.remove();
8219
+ if (signal.aborted) return { ok: true, data: null };
8148
8220
  return {
8149
8221
  ok: false,
8150
8222
  error: res.error
@@ -8154,8 +8226,13 @@ var SessionManager = class {
8154
8226
  this.logger.success("Session refreshed!");
8155
8227
  this.invalidReason = null;
8156
8228
  if (res.data.refreshToken) {
8157
- await this.refreshTokenStore.set(res.data.refreshToken);
8229
+ await this.mutations.run(async () => {
8230
+ if (!signal.aborted && res.data.refreshToken) {
8231
+ await this.refreshTokenStore.set(res.data.refreshToken);
8232
+ }
8233
+ });
8158
8234
  }
8235
+ if (signal.aborted) return { ok: true, data: null };
8159
8236
  const now = /* @__PURE__ */ new Date();
8160
8237
  this.v4AccessToken = res.data.accessToken;
8161
8238
  this.v4AccessTokenExpiresAt = addMinutes(now, 4).getTime();
@@ -8173,26 +8250,53 @@ var SessionManager = class {
8173
8250
  this.logger.warn("'localStorage' is not available on the server.");
8174
8251
  return;
8175
8252
  }
8176
- let version = 1;
8253
+ let version = this.v4AccessToken ? 4 : 1;
8254
+ let accessToken = this.v4AccessToken ?? void 0;
8255
+ let accessTokenExpiresAt = this.v4AccessTokenExpiresAt;
8256
+ let refreshToken;
8177
8257
  const val = localStorage.getItem(this.storageKey);
8178
8258
  if (val) {
8179
8259
  try {
8180
8260
  const stored = JSON.parse(val);
8181
8261
  version = stored.version ?? 1;
8262
+ accessToken = stored.version === 4 ? this.v4AccessToken ?? void 0 : stored.accessToken;
8263
+ accessTokenExpiresAt = stored.version === 4 ? this.v4AccessTokenExpiresAt : stored.accessTokenExpiresAt;
8264
+ if (stored.version !== 4) refreshToken = stored.refreshToken;
8182
8265
  } catch {
8183
8266
  }
8184
8267
  }
8185
- const res = await this.get();
8186
- if (res.data?.accessToken) {
8187
- await this.authService.destroySession(res.data.accessToken, version);
8188
- }
8268
+ this.lifecycle.logout();
8269
+ this.refreshing = false;
8270
+ this.v4RefreshPromise = null;
8189
8271
  this.v4AccessToken = null;
8190
8272
  this.v4AccessTokenExpiresAt = null;
8191
8273
  this.invalidReason = null;
8192
- await this.refreshTokenStore.remove();
8193
8274
  localStorage.removeItem(this.storageKey);
8275
+ await this.mutations.run(async () => {
8276
+ try {
8277
+ if (val && (!accessToken || !accessTokenExpiresAt || Date.now() > accessTokenExpiresAt)) {
8278
+ if (version === 4 && isIOSPlatform()) {
8279
+ refreshToken = await this.refreshTokenStore.get() ?? void 0;
8280
+ }
8281
+ if (refreshToken || version === 4 && !isIOSPlatform()) {
8282
+ accessToken = void 0;
8283
+ const res = await this.authService.refreshSession(
8284
+ refreshToken,
8285
+ version
8286
+ );
8287
+ if (res.ok) accessToken = res.data.accessToken;
8288
+ }
8289
+ }
8290
+ if (accessToken) {
8291
+ await this.authService.destroySession(accessToken, version);
8292
+ }
8293
+ } finally {
8294
+ if (version === 4) await this.refreshTokenStore.remove();
8295
+ }
8296
+ });
8194
8297
  }
8195
8298
  async verify() {
8299
+ const signal = this.lifecycle.signal;
8196
8300
  if (this.isServer) {
8197
8301
  this.logger.warn("'localStorage' is not available on the server.");
8198
8302
  return { valid: true };
@@ -8205,7 +8309,8 @@ var SessionManager = class {
8205
8309
  try {
8206
8310
  const stored = JSON.parse(val);
8207
8311
  if (stored.version === 4) {
8208
- const res = await this.verifyV4(stored.session);
8312
+ const res = await this.verifyV4(stored.session, signal);
8313
+ if (signal.aborted) return { valid: true };
8209
8314
  if (!res.valid) localStorage.removeItem(this.storageKey);
8210
8315
  return res;
8211
8316
  }
@@ -8213,32 +8318,37 @@ var SessionManager = class {
8213
8318
  }
8214
8319
  }
8215
8320
  const s = await this.get();
8321
+ if (signal.aborted) return { valid: true };
8216
8322
  if (s.error?.name === "InvalidTokenError" || s.error?.name === "SessionExpiredError" || s.error?.name === "AccountBlacklistedError") {
8217
8323
  this.invalidReason = "INVALID_SESSION";
8218
8324
  return { valid: false, reason: "INVALID_SESSION" };
8219
8325
  }
8220
8326
  if (!s.data) return { valid: true };
8221
- const v = await this.authService.verifySession(s.data.accessToken);
8327
+ const v = await this.authService.verifySession(s.data.accessToken, signal);
8328
+ if (signal.aborted) return { valid: true };
8222
8329
  if (!v) {
8223
8330
  this.invalidReason = "INVALID_SESSION";
8224
8331
  localStorage.removeItem(this.storageKey);
8225
8332
  }
8226
8333
  return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
8227
8334
  }
8228
- async verifyV4(session) {
8335
+ async verifyV4(session, signal) {
8229
8336
  if (!this.v4AccessToken || !this.v4AccessTokenExpiresAt || isAfter(/* @__PURE__ */ new Date(), new Date(this.v4AccessTokenExpiresAt))) {
8230
8337
  const res = await this.refreshV4(session);
8338
+ if (signal.aborted) return { valid: true };
8231
8339
  if (res.ok) return { valid: true };
8232
8340
  if (!this.invalidReason) return { valid: true };
8233
8341
  return { valid: false, reason: this.invalidReason };
8234
8342
  }
8235
- const v = await this.authService.verifySession(this.v4AccessToken);
8343
+ const v = await this.authService.verifySession(this.v4AccessToken, signal);
8344
+ if (signal.aborted) return { valid: true };
8236
8345
  if (!v) {
8237
8346
  localStorage.removeItem(this.storageKey);
8238
8347
  this.v4AccessToken = null;
8239
8348
  this.v4AccessTokenExpiresAt = null;
8240
8349
  this.invalidReason = "INVALID_SESSION";
8241
8350
  await this.refreshTokenStore.remove();
8351
+ if (signal.aborted) return { valid: true };
8242
8352
  }
8243
8353
  return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
8244
8354
  }
@@ -8267,6 +8377,8 @@ var SessionManagerCookie = class {
8267
8377
  authService;
8268
8378
  walletService;
8269
8379
  _refreshing = false;
8380
+ lifecycle = new SessionLifecycle();
8381
+ mutations = new CredentialMutationLock();
8270
8382
  /*
8271
8383
  * v4 access tokens live in memory only, so an XSS-readable storage layer
8272
8384
  * never holds a live one. Re-minted from the HttpOnly cookie, or from
@@ -8289,34 +8401,44 @@ var SessionManagerCookie = class {
8289
8401
  set refreshing(value) {
8290
8402
  this._refreshing = value;
8291
8403
  }
8292
- async persist(data, version) {
8293
- const now = /* @__PURE__ */ new Date();
8294
- this.invalidReason = null;
8295
- if (version === 4) {
8296
- this.v4AccessToken = data.accessToken ?? null;
8297
- this.v4AccessTokenExpiresAt = addMinutes(now, 5).getTime();
8298
- if (data.refreshToken) {
8299
- await this.refreshTokenStore.set(data.refreshToken);
8404
+ async persist(data, version, signal) {
8405
+ return this.mutations.run(async () => {
8406
+ if (signal.aborted) return;
8407
+ const now = /* @__PURE__ */ new Date();
8408
+ this.refreshing = false;
8409
+ this.v4RefreshPromise = null;
8410
+ this.invalidReason = null;
8411
+ if (version === 4) {
8412
+ this.v4AccessToken = data.accessToken ?? null;
8413
+ this.v4AccessTokenExpiresAt = addMinutes(now, 5).getTime();
8414
+ if (data.refreshToken) {
8415
+ await this.refreshTokenStore.set(data.refreshToken);
8416
+ }
8417
+ if (signal.aborted) return;
8418
+ cookies__default.default.set(
8419
+ this.storageKey,
8420
+ JSON.stringify({ version, session: data.session }),
8421
+ { expires: subMinutes(addDays(now, 15), 2) }
8422
+ );
8423
+ return;
8300
8424
  }
8301
8425
  cookies__default.default.set(
8302
8426
  this.storageKey,
8303
- JSON.stringify({ version, session: data.session }),
8304
- { expires: subMinutes(addDays(now, 15), 2) }
8427
+ JSON.stringify({
8428
+ version,
8429
+ ...data,
8430
+ accessTokenExpiresAt: addMinutes(now, 8).getTime(),
8431
+ refreshTokenExpiresAt: subMinutes(addDays(now, 30), 2).getTime()
8432
+ }),
8433
+ { expires: subMinutes(addDays(now, 30), 2) }
8305
8434
  );
8306
- return;
8307
- }
8308
- cookies__default.default.set(
8309
- this.storageKey,
8310
- JSON.stringify({
8311
- version,
8312
- ...data,
8313
- accessTokenExpiresAt: addMinutes(now, 8).getTime(),
8314
- refreshTokenExpiresAt: subMinutes(addDays(now, 30), 2).getTime()
8315
- }),
8316
- { expires: subMinutes(addDays(now, 30), 2) }
8317
- );
8435
+ });
8318
8436
  }
8319
8437
  async create(input, version = 1) {
8438
+ const waitingSignal = this.lifecycle.signal;
8439
+ await this.mutations.wait();
8440
+ if (waitingSignal.aborted) return { ok: true, data: null };
8441
+ const signal = this.lifecycle.renew();
8320
8442
  if (input.type === "MAYA") {
8321
8443
  localStorage.setItem(this.platformStorageKey, "MAYA");
8322
8444
  const f0 = () => this.walletService.mayaSession({ id: input.sessionId });
@@ -8342,7 +8464,7 @@ var SessionManagerCookie = class {
8342
8464
  maxAttempt: 5
8343
8465
  })();
8344
8466
  if (!r1.ok) return r1;
8345
- await this.persist(r1.data, version);
8467
+ await this.persist(r1.data, version, signal);
8346
8468
  return {
8347
8469
  ok: true,
8348
8470
  data: null
@@ -8351,7 +8473,7 @@ var SessionManagerCookie = class {
8351
8473
  if (input.type === "MOBILE_NUMBER") {
8352
8474
  const res2 = await this.authService.createSession(input, version);
8353
8475
  if (res2.ok) {
8354
- await this.persist(res2.data, version);
8476
+ await this.persist(res2.data, version, signal);
8355
8477
  return {
8356
8478
  ok: true,
8357
8479
  data: null
@@ -8368,7 +8490,7 @@ var SessionManagerCookie = class {
8368
8490
  version
8369
8491
  );
8370
8492
  if (res2.ok) {
8371
- await this.persist(res2.data, version);
8493
+ await this.persist(res2.data, version, signal);
8372
8494
  return {
8373
8495
  ok: true,
8374
8496
  data: null
@@ -8380,7 +8502,7 @@ var SessionManagerCookie = class {
8380
8502
  localStorage.setItem(this.platformStorageKey, "CABINET");
8381
8503
  const res2 = await this.authService.createSession(input, version);
8382
8504
  if (res2.ok) {
8383
- await this.persist(res2.data, version);
8505
+ await this.persist(res2.data, version, signal);
8384
8506
  return {
8385
8507
  ok: true,
8386
8508
  data: null
@@ -8398,19 +8520,23 @@ var SessionManagerCookie = class {
8398
8520
  }
8399
8521
  };
8400
8522
  }
8401
- await this.persist(res.data, version);
8523
+ await this.persist(res.data, version, signal);
8402
8524
  return {
8403
8525
  ok: true,
8404
8526
  data: null
8405
8527
  };
8406
8528
  }
8407
8529
  async createFromAuthenticator(input) {
8530
+ const waitingSignal = this.lifecycle.signal;
8531
+ await this.mutations.wait();
8532
+ if (waitingSignal.aborted) return { ok: true };
8533
+ const signal = this.lifecycle.renew();
8408
8534
  const res = await this.authService.authenticate(input);
8409
8535
  if (res.ok) {
8410
8536
  if (this.isServer) {
8411
8537
  this.logger.warn("'client cookies' is not available on the server.");
8412
8538
  } else {
8413
- await this.persist(res.data, 1);
8539
+ await this.persist(res.data, 1, signal);
8414
8540
  }
8415
8541
  return { ok: true };
8416
8542
  } else {
@@ -8418,6 +8544,7 @@ var SessionManagerCookie = class {
8418
8544
  }
8419
8545
  }
8420
8546
  async get() {
8547
+ const signal = this.lifecycle.signal;
8421
8548
  if (this.isServer) {
8422
8549
  this.logger.warn("'client cookies' is not available on the server.");
8423
8550
  return {
@@ -8427,6 +8554,7 @@ var SessionManagerCookie = class {
8427
8554
  }
8428
8555
  if (this.refreshing) {
8429
8556
  await sleep(1e3);
8557
+ if (signal.aborted) return { ok: true, data: null };
8430
8558
  return await this.get();
8431
8559
  }
8432
8560
  const val = cookies__default.default.get(this.storageKey);
@@ -8461,8 +8589,10 @@ var SessionManagerCookie = class {
8461
8589
  this.refreshing = true;
8462
8590
  const res = await this.authService.refreshSession(
8463
8591
  obj.refreshToken,
8464
- obj.version ?? 1
8592
+ obj.version ?? 1,
8593
+ signal
8465
8594
  );
8595
+ if (signal.aborted) return { ok: true, data: null };
8466
8596
  this.refreshing = false;
8467
8597
  if (!res.ok) {
8468
8598
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
@@ -8498,6 +8628,8 @@ var SessionManagerCookie = class {
8498
8628
  data: obj
8499
8629
  };
8500
8630
  } catch {
8631
+ if (signal.aborted) return { ok: true, data: null };
8632
+ this.refreshing = false;
8501
8633
  return {
8502
8634
  ok: false,
8503
8635
  error: {
@@ -8522,6 +8654,7 @@ var SessionManagerCookie = class {
8522
8654
  return await this.refreshV4(session);
8523
8655
  }
8524
8656
  async refresh() {
8657
+ const signal = this.lifecycle.signal;
8525
8658
  if (this.isServer) {
8526
8659
  this.logger.warn("'client cookies' is not available on the server.");
8527
8660
  return {
@@ -8547,8 +8680,10 @@ var SessionManagerCookie = class {
8547
8680
  this.refreshing = true;
8548
8681
  const res = await this.authService.refreshSession(
8549
8682
  obj.refreshToken,
8550
- obj.version ?? 1
8683
+ obj.version ?? 1,
8684
+ signal
8551
8685
  );
8686
+ if (signal.aborted) return { ok: true, data: null };
8552
8687
  this.refreshing = false;
8553
8688
  if (!res.ok) {
8554
8689
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
@@ -8583,6 +8718,8 @@ var SessionManagerCookie = class {
8583
8718
  data: obj
8584
8719
  };
8585
8720
  } catch {
8721
+ if (signal.aborted) return { ok: true, data: null };
8722
+ this.refreshing = false;
8586
8723
  return {
8587
8724
  ok: false,
8588
8725
  error: {
@@ -8594,18 +8731,20 @@ var SessionManagerCookie = class {
8594
8731
  }
8595
8732
  async refreshV4(session) {
8596
8733
  if (this.v4RefreshPromise) return await this.v4RefreshPromise;
8597
- this.v4RefreshPromise = this.requestV4Refresh(session);
8734
+ const promise = this.requestV4Refresh(session, this.lifecycle.signal);
8735
+ this.v4RefreshPromise = promise;
8598
8736
  try {
8599
- return await this.v4RefreshPromise;
8737
+ return await promise;
8600
8738
  } finally {
8601
- this.v4RefreshPromise = null;
8739
+ if (this.v4RefreshPromise === promise) this.v4RefreshPromise = null;
8602
8740
  }
8603
8741
  }
8604
- async requestV4Refresh(session) {
8742
+ async requestV4Refresh(session, signal) {
8605
8743
  this.logger.info("Refreshing session...");
8606
8744
  let refreshToken;
8607
8745
  if (isIOSPlatform()) {
8608
8746
  refreshToken = await this.refreshTokenStore.get() ?? void 0;
8747
+ if (signal.aborted) return { ok: true, data: null };
8609
8748
  if (!refreshToken) {
8610
8749
  this.logger.warn("No stored refresh token. Session expired.");
8611
8750
  this.v4AccessToken = null;
@@ -8622,7 +8761,8 @@ var SessionManagerCookie = class {
8622
8761
  }
8623
8762
  }
8624
8763
  this.refreshing = true;
8625
- const res = await this.authService.refreshSession(refreshToken, 4);
8764
+ const res = await this.authService.refreshSession(refreshToken, 4, signal);
8765
+ if (signal.aborted) return { ok: true, data: null };
8626
8766
  if (!res.ok) {
8627
8767
  this.logger.error(`Failed to refresh session: ${res.error.message}`);
8628
8768
  const terminal = res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError" || res.error.name === "SessionExpiredError";
@@ -8634,6 +8774,7 @@ var SessionManagerCookie = class {
8634
8774
  }
8635
8775
  this.refreshing = false;
8636
8776
  if (terminal) await this.refreshTokenStore.remove();
8777
+ if (signal.aborted) return { ok: true, data: null };
8637
8778
  return {
8638
8779
  ok: false,
8639
8780
  error: res.error
@@ -8643,8 +8784,13 @@ var SessionManagerCookie = class {
8643
8784
  this.logger.success("Session refreshed!");
8644
8785
  this.invalidReason = null;
8645
8786
  if (res.data.refreshToken) {
8646
- await this.refreshTokenStore.set(res.data.refreshToken);
8787
+ await this.mutations.run(async () => {
8788
+ if (!signal.aborted && res.data.refreshToken) {
8789
+ await this.refreshTokenStore.set(res.data.refreshToken);
8790
+ }
8791
+ });
8647
8792
  }
8793
+ if (signal.aborted) return { ok: true, data: null };
8648
8794
  const now = /* @__PURE__ */ new Date();
8649
8795
  this.v4AccessToken = res.data.accessToken;
8650
8796
  this.v4AccessTokenExpiresAt = addMinutes(now, 5).getTime();
@@ -8662,26 +8808,53 @@ var SessionManagerCookie = class {
8662
8808
  this.logger.warn("'client cookies' is not available on the server.");
8663
8809
  return;
8664
8810
  }
8665
- let version = 1;
8811
+ let version = this.v4AccessToken ? 4 : 1;
8812
+ let accessToken = this.v4AccessToken ?? void 0;
8813
+ let accessTokenExpiresAt = this.v4AccessTokenExpiresAt;
8814
+ let refreshToken;
8666
8815
  const val = cookies__default.default.get(this.storageKey);
8667
8816
  if (val) {
8668
8817
  try {
8669
8818
  const stored = JSON.parse(val);
8670
8819
  version = stored.version ?? 1;
8820
+ accessToken = stored.version === 4 ? this.v4AccessToken ?? void 0 : stored.accessToken;
8821
+ accessTokenExpiresAt = stored.version === 4 ? this.v4AccessTokenExpiresAt : stored.accessTokenExpiresAt;
8822
+ if (stored.version !== 4) refreshToken = stored.refreshToken;
8671
8823
  } catch {
8672
8824
  }
8673
8825
  }
8674
- const res = await this.get();
8675
- if (res.data?.accessToken) {
8676
- await this.authService.destroySession(res.data.accessToken, version);
8677
- }
8826
+ this.lifecycle.logout();
8827
+ this.refreshing = false;
8828
+ this.v4RefreshPromise = null;
8678
8829
  this.v4AccessToken = null;
8679
8830
  this.v4AccessTokenExpiresAt = null;
8680
8831
  this.invalidReason = null;
8681
- await this.refreshTokenStore.remove();
8682
8832
  cookies__default.default.remove(this.storageKey);
8833
+ await this.mutations.run(async () => {
8834
+ try {
8835
+ if (val && (!accessToken || !accessTokenExpiresAt || Date.now() > accessTokenExpiresAt)) {
8836
+ if (version === 4 && isIOSPlatform()) {
8837
+ refreshToken = await this.refreshTokenStore.get() ?? void 0;
8838
+ }
8839
+ if (refreshToken || version === 4 && !isIOSPlatform()) {
8840
+ accessToken = void 0;
8841
+ const res = await this.authService.refreshSession(
8842
+ refreshToken,
8843
+ version
8844
+ );
8845
+ if (res.ok) accessToken = res.data.accessToken;
8846
+ }
8847
+ }
8848
+ if (accessToken) {
8849
+ await this.authService.destroySession(accessToken, version);
8850
+ }
8851
+ } finally {
8852
+ if (version === 4) await this.refreshTokenStore.remove();
8853
+ }
8854
+ });
8683
8855
  }
8684
8856
  async verify() {
8857
+ const signal = this.lifecycle.signal;
8685
8858
  if (this.isServer) {
8686
8859
  this.logger.warn("'client cookies' is not available on the server.");
8687
8860
  return { valid: true };
@@ -8694,7 +8867,8 @@ var SessionManagerCookie = class {
8694
8867
  try {
8695
8868
  const stored = JSON.parse(val);
8696
8869
  if (stored.version === 4) {
8697
- const res = await this.verifyV4(stored.session);
8870
+ const res = await this.verifyV4(stored.session, signal);
8871
+ if (signal.aborted) return { valid: true };
8698
8872
  if (!res.valid) cookies__default.default.remove(this.storageKey);
8699
8873
  return res;
8700
8874
  }
@@ -8702,32 +8876,37 @@ var SessionManagerCookie = class {
8702
8876
  }
8703
8877
  }
8704
8878
  const s = await this.get();
8879
+ if (signal.aborted) return { valid: true };
8705
8880
  if (s.error?.name === "InvalidTokenError" || s.error?.name === "SessionExpiredError" || s.error?.name === "AccountBlacklistedError") {
8706
8881
  this.invalidReason = "INVALID_SESSION";
8707
8882
  return { valid: false, reason: "INVALID_SESSION" };
8708
8883
  }
8709
8884
  if (!s.data) return { valid: true };
8710
- const v = await this.authService.verifySession(s.data.accessToken);
8885
+ const v = await this.authService.verifySession(s.data.accessToken, signal);
8886
+ if (signal.aborted) return { valid: true };
8711
8887
  if (!v) {
8712
8888
  this.invalidReason = "INVALID_SESSION";
8713
8889
  cookies__default.default.remove(this.storageKey);
8714
8890
  }
8715
8891
  return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
8716
8892
  }
8717
- async verifyV4(session) {
8893
+ async verifyV4(session, signal) {
8718
8894
  if (!this.v4AccessToken || !this.v4AccessTokenExpiresAt || isAfter(/* @__PURE__ */ new Date(), new Date(this.v4AccessTokenExpiresAt))) {
8719
8895
  const res = await this.refreshV4(session);
8896
+ if (signal.aborted) return { valid: true };
8720
8897
  if (res.ok) return { valid: true };
8721
8898
  if (!this.invalidReason) return { valid: true };
8722
8899
  return { valid: false, reason: this.invalidReason };
8723
8900
  }
8724
- const v = await this.authService.verifySession(this.v4AccessToken);
8901
+ const v = await this.authService.verifySession(this.v4AccessToken, signal);
8902
+ if (signal.aborted) return { valid: true };
8725
8903
  if (!v) {
8726
8904
  cookies__default.default.remove(this.storageKey);
8727
8905
  this.v4AccessToken = null;
8728
8906
  this.v4AccessTokenExpiresAt = null;
8729
8907
  this.invalidReason = "INVALID_SESSION";
8730
8908
  await this.refreshTokenStore.remove();
8909
+ if (signal.aborted) return { valid: true };
8731
8910
  }
8732
8911
  return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
8733
8912
  }