@oxyhq/core 3.16.0 → 3.17.0

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.
Files changed (41) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/HttpService.js +8 -1
  3. package/dist/cjs/OxyServices.base.js +25 -0
  4. package/dist/esm/.tsbuildinfo +1 -1
  5. package/dist/esm/HttpService.js +8 -1
  6. package/dist/esm/OxyServices.base.js +25 -0
  7. package/dist/types/.tsbuildinfo +1 -1
  8. package/dist/types/OxyServices.base.d.ts +11 -0
  9. package/dist/types/index.d.ts +1 -0
  10. package/dist/types/mixins/OxyServices.analytics.d.ts +1 -0
  11. package/dist/types/mixins/OxyServices.appData.d.ts +1 -0
  12. package/dist/types/mixins/OxyServices.applications.d.ts +1 -0
  13. package/dist/types/mixins/OxyServices.assets.d.ts +1 -0
  14. package/dist/types/mixins/OxyServices.auth.d.ts +1 -0
  15. package/dist/types/mixins/OxyServices.civic.d.ts +1 -0
  16. package/dist/types/mixins/OxyServices.contacts.d.ts +1 -0
  17. package/dist/types/mixins/OxyServices.devices.d.ts +1 -0
  18. package/dist/types/mixins/OxyServices.features.d.ts +1 -0
  19. package/dist/types/mixins/OxyServices.fedcm.d.ts +1 -0
  20. package/dist/types/mixins/OxyServices.identity.d.ts +1 -0
  21. package/dist/types/mixins/OxyServices.language.d.ts +1 -0
  22. package/dist/types/mixins/OxyServices.links.d.ts +1 -0
  23. package/dist/types/mixins/OxyServices.location.d.ts +1 -0
  24. package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -0
  25. package/dist/types/mixins/OxyServices.nodes.d.ts +1 -0
  26. package/dist/types/mixins/OxyServices.payment.d.ts +1 -0
  27. package/dist/types/mixins/OxyServices.privacy.d.ts +1 -0
  28. package/dist/types/mixins/OxyServices.redirect.d.ts +1 -0
  29. package/dist/types/mixins/OxyServices.reputation.d.ts +1 -0
  30. package/dist/types/mixins/OxyServices.security.d.ts +1 -0
  31. package/dist/types/mixins/OxyServices.silent.d.ts +1 -0
  32. package/dist/types/mixins/OxyServices.sso.d.ts +1 -0
  33. package/dist/types/mixins/OxyServices.topics.d.ts +1 -0
  34. package/dist/types/mixins/OxyServices.user.d.ts +1 -0
  35. package/dist/types/mixins/OxyServices.utility.d.ts +1 -0
  36. package/dist/types/mixins/OxyServices.workspaces.d.ts +1 -0
  37. package/package.json +2 -2
  38. package/src/HttpService.ts +8 -1
  39. package/src/OxyServices.base.ts +25 -0
  40. package/src/__tests__/inSessionRefresh.test.ts +193 -0
  41. package/src/index.ts +4 -0
@@ -366,7 +366,14 @@ export class HttpService {
366
366
  if (response.status === 401 && !config._isAuthRetry) {
367
367
  const refreshed = await this.refreshAccessToken('response-401');
368
368
  if (refreshed) {
369
- return this.request({ ...config, _isAuthRetry: true, retry: false });
369
+ // `deduplicate: false` is REQUIRED on the retry (mirrors the 403
370
+ // CSRF retry below). This re-issue runs while the ORIGINAL request
371
+ // is still in-flight under its dedupe key; the refreshed token is
372
+ // for the SAME user, so the identity-scoped key is UNCHANGED — a
373
+ // deduplicated retry would resolve to the still-pending original
374
+ // and await itself (deadlock). Opting the retry out of dedupe makes
375
+ // it a fresh request.
376
+ return this.request({ ...config, _isAuthRetry: true, retry: false, deduplicate: false });
370
377
  }
371
378
  // Refresh failed or no token — clear tokens and stale CSRF
372
379
  this.tokenStore.clearTokens();
@@ -250,6 +250,31 @@ export class OxyServicesBase {
250
250
  getAccessToken() {
251
251
  return this.httpService.getAccessToken();
252
252
  }
253
+ /**
254
+ * Decode the current access token and return its `exp` claim in SECONDS since
255
+ * the Unix epoch (the raw JWT `exp` unit), or `null` when there is no token,
256
+ * the token is opaque/undecodable, or it carries no numeric `exp`.
257
+ *
258
+ * Exposed so `@oxyhq/services` can schedule a PROACTIVE in-session refresh a
259
+ * fixed lead before expiry without re-importing a JWT decoder (and without
260
+ * duplicating the `jwt-decode` dependency in the RN bundle). HttpService keeps
261
+ * the per-request preflight refresh; this powers the idle/background timer.
262
+ */
263
+ getAccessTokenExpiry() {
264
+ const token = this.httpService.getAccessToken();
265
+ if (!token) {
266
+ return null;
267
+ }
268
+ try {
269
+ const decoded = jwtDecode(token);
270
+ return typeof decoded.exp === 'number' ? decoded.exp : null;
271
+ }
272
+ catch {
273
+ // A malformed / non-JWT token has no usable expiry — fall back to the
274
+ // reactive 401 refresh path instead of a scheduled one.
275
+ return null;
276
+ }
277
+ }
253
278
  /**
254
279
  * Set the acting-as identity for managed accounts.
255
280
  *