@oxyhq/core 8.1.0 → 9.0.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 (68) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/boot/coldBootV2.js +22 -332
  3. package/dist/cjs/crypto/keyManager.js +0 -95
  4. package/dist/cjs/index.js +6 -19
  5. package/dist/cjs/mixins/OxyServices.auth.js +4 -7
  6. package/dist/cjs/mixins/OxyServices.deviceBoot.js +19 -115
  7. package/dist/cjs/mixins/index.js +2 -3
  8. package/dist/cjs/session/SessionClient.js +29 -100
  9. package/dist/cjs/session/accountDialogController.js +0 -13
  10. package/dist/cjs/session/authStateStore.js +9 -89
  11. package/dist/cjs/session/createSessionClient.js +2 -9
  12. package/dist/cjs/session/refresh.js +46 -71
  13. package/dist/cjs/utils/registrableApex.js +2 -6
  14. package/dist/esm/.tsbuildinfo +1 -1
  15. package/dist/esm/boot/coldBootV2.js +23 -330
  16. package/dist/esm/crypto/keyManager.js +0 -95
  17. package/dist/esm/index.js +7 -11
  18. package/dist/esm/mixins/OxyServices.auth.js +4 -7
  19. package/dist/esm/mixins/OxyServices.deviceBoot.js +20 -116
  20. package/dist/esm/mixins/index.js +2 -3
  21. package/dist/esm/session/SessionClient.js +29 -100
  22. package/dist/esm/session/accountDialogController.js +0 -13
  23. package/dist/esm/session/authStateStore.js +8 -88
  24. package/dist/esm/session/createSessionClient.js +2 -9
  25. package/dist/esm/session/refresh.js +46 -71
  26. package/dist/esm/utils/registrableApex.js +2 -6
  27. package/dist/types/.tsbuildinfo +1 -1
  28. package/dist/types/HttpService.d.ts +3 -3
  29. package/dist/types/boot/coldBootV2.d.ts +28 -53
  30. package/dist/types/crypto/keyManager.d.ts +0 -21
  31. package/dist/types/index.d.ts +3 -5
  32. package/dist/types/mixins/OxyServices.auth.d.ts +4 -7
  33. package/dist/types/mixins/OxyServices.deviceBoot.d.ts +20 -60
  34. package/dist/types/session/SessionClient.d.ts +4 -38
  35. package/dist/types/session/accountDialogController.d.ts +1 -3
  36. package/dist/types/session/authStateStore.d.ts +32 -57
  37. package/dist/types/session/createSessionClient.d.ts +2 -9
  38. package/dist/types/session/refresh.d.ts +32 -28
  39. package/dist/types/utils/registrableApex.d.ts +2 -6
  40. package/package.json +2 -2
  41. package/src/HttpService.ts +3 -3
  42. package/src/boot/__tests__/coldBootV2.test.ts +140 -353
  43. package/src/boot/coldBootV2.ts +35 -391
  44. package/src/crypto/keyManager.ts +0 -101
  45. package/src/index.ts +7 -30
  46. package/src/mixins/OxyServices.auth.ts +5 -9
  47. package/src/mixins/OxyServices.deviceBoot.ts +19 -142
  48. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +9 -96
  49. package/src/mixins/__tests__/onTokensChanged.test.ts +0 -1
  50. package/src/mixins/__tests__/passwordSignIn.test.ts +33 -9
  51. package/src/mixins/index.ts +2 -3
  52. package/src/session/SessionClient.ts +29 -120
  53. package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +113 -0
  54. package/src/session/__tests__/SessionClient.socket.test.ts +8 -8
  55. package/src/session/__tests__/authStateStore.test.ts +29 -42
  56. package/src/session/__tests__/refresh.test.ts +66 -52
  57. package/src/session/accountDialogController.ts +4 -18
  58. package/src/session/authStateStore.ts +32 -126
  59. package/src/session/createSessionClient.ts +2 -9
  60. package/src/session/refresh.ts +60 -92
  61. package/src/utils/registrableApex.ts +2 -6
  62. package/dist/cjs/boot/deviceBootReturn.js +0 -167
  63. package/dist/esm/boot/deviceBootReturn.js +0 -161
  64. package/dist/types/boot/deviceBootReturn.d.ts +0 -83
  65. package/src/boot/__tests__/deviceBootReturn.test.ts +0 -190
  66. package/src/boot/deviceBootReturn.ts +0 -210
  67. package/src/crypto/__tests__/sharedDeviceToken.test.ts +0 -24
  68. package/src/session/__tests__/SessionClient.signedOut.test.ts +0 -224
@@ -1,21 +1,22 @@
1
1
  /**
2
- * Unified token refresh — THE single refresh implementation for web + native.
2
+ * Unified token refresh — THE single access-token re-mint for web + native.
3
3
  *
4
- * ONE persisted-refresh-token rotation shared by every consumer (it replaced
5
- * the pre-device-first per-platform duplicates):
4
+ * The access token is short-lived; there is no refresh token. To keep a session
5
+ * alive past the access token's TTL the client re-mints via the zero-cookie
6
+ * device transport:
6
7
  *
7
- * - `refreshPersistedSession` — arm 1 rotates the stored refresh-token family
8
- * (`POST /auth/refresh-token`), planting + persisting the rotated pair; arm 2
9
- * (native only) re-mints via the shared-keychain identity when there is no
10
- * live refresh token. It is used BOTH reactively (wrapped as the
11
- * `AuthRefreshHandler` installed on `HttpService`) AND proactively (the
12
- * cold-boot `stored-tokens` step calls it directly).
8
+ * - `refreshPersistedSession` — arm 1 mints a fresh access token from the
9
+ * persisted `deviceId` + `deviceSecret` (`POST /session/device/token`),
10
+ * planting + persisting the rotated secret; arm 2 (native only) re-mints via
11
+ * the shared-keychain identity when there is no usable secret. It is used BOTH
12
+ * reactively (wrapped as the `AuthRefreshHandler` installed on `HttpService`)
13
+ * AND proactively (the scheduler below calls it).
13
14
  * - `createAuthRefreshHandler` / `installAuthRefreshHandler` wire arm 1+2 into
14
15
  * `HttpService.setAuthRefreshHandler`, keeping that layer's single-flight
15
16
  * dedup + cooldown (this module does NOT reimplement them).
16
17
  * - `startTokenRefreshScheduler` — a proactive scheduler decoupled from any
17
- * React type: refreshes ~60s before `exp`,
18
- * re-arms on token change + web tab-focus, `.unref?.()`s its timer in Node.
18
+ * React type: re-mints ~60s before `exp`, re-arms on token change + web
19
+ * tab-focus, `.unref?.()`s its timer in Node.
19
20
  *
20
21
  * Framework-free; no module-level mutable state.
21
22
  */
@@ -24,33 +25,36 @@ import type { AuthRefreshHandler } from '../HttpService';
24
25
  import type { AuthStateStore } from './authStateStore';
25
26
  /**
26
27
  * Lead time (ms) before access-token expiry at which the proactive scheduler
27
- * refreshes. Mirrors `HttpService`'s per-request `TOKEN_REFRESH_LEAD_SECONDS`
28
- * (60s) so the scheduled refresh and the request-time preflight refresh use
29
- * the same window — the scheduler just fires it during idle/background.
28
+ * re-mints. Mirrors `HttpService`'s per-request `TOKEN_REFRESH_LEAD_SECONDS`
29
+ * (60s) so the scheduled re-mint and the request-time preflight use the same
30
+ * window — the scheduler just fires it during idle/background.
30
31
  */
31
32
  export declare const TOKEN_REFRESH_LEAD_MS = 60000;
32
33
  export interface RefreshDeps {
33
34
  oxy: OxyServices;
34
35
  store: AuthStateStore;
35
36
  /**
36
- * Whether to fall back to the native shared-keychain re-mint (arm 2) when
37
- * there is no live refresh token / arm 1 is revoked. Defaults to `isNative()`
38
- * — web has no shared keychain. Exposed for tests.
37
+ * Whether to fall back to the native shared-keychain re-mint (arm 2) when the
38
+ * persisted secret is absent / rejected. Defaults to `isNative()` — web has no
39
+ * shared keychain. Exposed for tests.
39
40
  */
40
41
  allowSharedKeyFallback?: boolean;
41
42
  }
42
43
  /**
43
- * Rotate the persisted session and return the fresh access token, or `null`
44
+ * Re-mint the persisted session and return the fresh access token, or `null`
44
45
  * when no arm could produce one.
45
46
  *
46
- * Arm 1 (`POST /auth/refresh-token`): if the store holds a refresh token, rotate
47
- * it — on success plant + persist the rotated pair; on a REVOKED error clear the
48
- * store; on a transient error leave the store and return `null`.
47
+ * Arm 1 (`POST /session/device/token`): if the store holds a `deviceId` +
48
+ * `deviceSecret`, mint — on success plant + persist the rotated secret. A 401
49
+ * means the secret is diverged (`invalid_device_secret`) or the device has no
50
+ * live session (`no_active_session`): drop the secret so the mint lane stops (or
51
+ * clear the store on web, where there is no fallback). A transient error leaves
52
+ * the store and returns `null`.
49
53
  *
50
- * Arm 2 (native shared-keychain): when there is no refresh token or arm 1 was
51
- * revoked, re-mint via `signInWithSharedIdentity` (which plants tokens). The
52
- * shared keychain — not the per-origin store — is the durable native credential,
53
- * so this arm does not write the store.
54
+ * Arm 2 (native shared-keychain): when the secret is absent or was just rejected,
55
+ * re-mint via `signInWithSharedIdentity` (which plants tokens). The shared
56
+ * keychain — not the per-origin store — is the durable native credential, so this
57
+ * arm does not write the store.
54
58
  */
55
59
  export declare function refreshPersistedSession(deps: RefreshDeps): Promise<string | null>;
56
60
  /**
@@ -71,7 +75,7 @@ export interface TokenRefreshSchedulerHandle {
71
75
  dispose(): void;
72
76
  }
73
77
  /**
74
- * Start the proactive refresh scheduler against `oxy`.
78
+ * Start the proactive re-mint scheduler against `oxy`.
75
79
  *
76
80
  * Schedules a single timer to fire {@link TOKEN_REFRESH_LEAD_MS} before the
77
81
  * current access token's `exp`, calling
@@ -79,11 +83,11 @@ export interface TokenRefreshSchedulerHandle {
79
83
  * handler; deduped + cooldown-guarded). After every attempt it reschedules
80
84
  * from the possibly-rotated token. It also reschedules whenever the token
81
85
  * changes (a sign-out that clears the token cancels the timer) and, on web
82
- * tab-focus, refreshes immediately if already inside the lead window (a
86
+ * tab-focus, re-mints immediately if already inside the lead window (a
83
87
  * long-hidden tab throttles timers, so the token can be expired on return).
84
88
  *
85
89
  * No-ops cleanly when there is no token or an opaque/no-`exp` token — the
86
- * reactive 401 path stays the only refresh trigger in that case. The timer is
90
+ * reactive 401 path stays the only re-mint trigger in that case. The timer is
87
91
  * `.unref?.()`-ed so it never keeps a Node/Jest event loop alive.
88
92
  */
89
93
  export declare function startTokenRefreshScheduler(oxy: OxyServices): TokenRefreshSchedulerHandle;
@@ -4,12 +4,8 @@
4
4
  * The client FAPI auto-detection helper was removed in the device-first cutover
5
5
  * (which is why this file is now named for what it actually is, not the old
6
6
  * `fapiAutoDetect`). What survives is the pure registrable-domain kernel, still
7
- * used server-side by the api's device-first same-apex trust checks
8
- * (`deviceAuth.ts`'s `POST /auth/device/web-session`, via `sameSite.ts`'s
9
- * `isSameSiteTrustedRequest`) and the `@oxyhq/core/server` CORS/re-export layer.
10
- *
11
- * `registrableApex` is NOT legacy — the device-first same-apex check is a live
12
- * consumer, so this kernel stays regardless of the SSO/FedCM removal.
7
+ * used by the `@oxyhq/core/server` CORS layer (the `*.oxy.so` same-apex trust
8
+ * check) and its re-export surface.
13
9
  */
14
10
  /**
15
11
  * Compute the bare registrable apex (eTLD+1) of a hostname using the Public
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/core",
3
- "version": "8.1.0",
3
+ "version": "9.0.0",
4
4
  "description": "OxyHQ SDK Foundation — API client, authentication, cryptographic identity, and shared utilities",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -94,7 +94,7 @@
94
94
  }
95
95
  },
96
96
  "dependencies": {
97
- "@oxyhq/contracts": "^0.12.0",
97
+ "@oxyhq/contracts": "^0.13.0",
98
98
  "@oxyhq/protocol": "^0.1.2",
99
99
  "bip39": "^3.1.0",
100
100
  "buffer": "^6.0.3",
@@ -74,13 +74,13 @@ export interface RequestOptions {
74
74
  * Skip BOTH the bearer auth header (and its near-expiry preflight refresh)
75
75
  * AND the 401-driven auto-refresh/retry for this request.
76
76
  *
77
- * Required for the body-authenticated refresh endpoint (`POST
78
- * /auth/refresh-token`): it does not need a bearer, and — critically — it is
77
+ * Required for the body-authenticated device-secret mint (`POST
78
+ * /session/device/token`): it does not need a bearer, and — critically — it is
79
79
  * itself invoked from inside the registered `AuthRefreshHandler`. If it went
80
80
  * through the normal preflight, `getAuthHeader` would call
81
81
  * `refreshAccessToken` while the handler-owning `tokenRefreshPromise` is
82
82
  * still in flight and await ITSELF (deadlock). Skipping auth makes the
83
- * refresh call fully independent of the current (near-expired) bearer.
83
+ * mint call fully independent of the current (near-expired) bearer.
84
84
  */
85
85
  skipAuth?: boolean;
86
86
  }