@oxyhq/core 6.0.0 → 7.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 (53) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/HttpService.js +1 -1
  3. package/dist/cjs/index.js +17 -11
  4. package/dist/cjs/mixins/OxyServices.accounts.js +7 -13
  5. package/dist/cjs/mixins/index.js +0 -5
  6. package/dist/cjs/server/index.js +2 -2
  7. package/dist/cjs/shared/utils/debugUtils.js +3 -3
  8. package/dist/cjs/utils/authWebUrl.js +10 -30
  9. package/dist/cjs/utils/coldBoot.js +10 -8
  10. package/dist/cjs/utils/{fapiAutoDetect.js → registrableApex.js} +8 -10
  11. package/dist/esm/.tsbuildinfo +1 -1
  12. package/dist/esm/HttpService.js +1 -1
  13. package/dist/esm/index.js +15 -8
  14. package/dist/esm/mixins/OxyServices.accounts.js +7 -13
  15. package/dist/esm/mixins/index.js +0 -5
  16. package/dist/esm/server/index.js +1 -1
  17. package/dist/esm/shared/utils/debugUtils.js +3 -3
  18. package/dist/esm/utils/authWebUrl.js +9 -29
  19. package/dist/esm/utils/coldBoot.js +10 -8
  20. package/dist/esm/utils/{fapiAutoDetect.js → registrableApex.js} +8 -10
  21. package/dist/types/.tsbuildinfo +1 -1
  22. package/dist/types/HttpService.d.ts +1 -1
  23. package/dist/types/index.d.ts +2 -3
  24. package/dist/types/mixins/OxyServices.accounts.d.ts +24 -27
  25. package/dist/types/mixins/index.d.ts +1 -2
  26. package/dist/types/models/session.d.ts +4 -5
  27. package/dist/types/server/index.d.ts +1 -1
  28. package/dist/types/session/SessionClient.d.ts +1 -1
  29. package/dist/types/shared/utils/debugUtils.d.ts +3 -3
  30. package/dist/types/utils/accountUtils.d.ts +2 -3
  31. package/dist/types/utils/authWebUrl.d.ts +9 -29
  32. package/dist/types/utils/coldBoot.d.ts +17 -14
  33. package/dist/types/utils/{fapiAutoDetect.d.ts → registrableApex.d.ts} +8 -10
  34. package/package.json +2 -2
  35. package/src/HttpService.ts +1 -1
  36. package/src/index.ts +12 -11
  37. package/src/mixins/OxyServices.accounts.ts +21 -26
  38. package/src/mixins/index.ts +0 -7
  39. package/src/models/session.ts +4 -5
  40. package/src/server/index.ts +1 -1
  41. package/src/session/SessionClient.ts +1 -1
  42. package/src/shared/utils/debugUtils.ts +3 -3
  43. package/src/utils/__tests__/authWebUrl.test.ts +5 -16
  44. package/src/utils/__tests__/{fapiAutoDetect.test.ts → registrableApex.test.ts} +1 -1
  45. package/src/utils/accountUtils.ts +2 -3
  46. package/src/utils/authWebUrl.ts +9 -30
  47. package/src/utils/coldBoot.ts +17 -14
  48. package/src/utils/{fapiAutoDetect.ts → registrableApex.ts} +8 -10
  49. package/dist/cjs/mixins/OxyServices.authorizedApps.js +0 -38
  50. package/dist/esm/mixins/OxyServices.authorizedApps.js +0 -35
  51. package/dist/types/mixins/OxyServices.authorizedApps.d.ts +0 -94
  52. package/src/mixins/OxyServices.authorizedApps.ts +0 -75
  53. package/src/mixins/__tests__/authorizedApps.test.ts +0 -63
@@ -1020,7 +1020,7 @@ export class HttpService {
1020
1020
  * `clearCacheByPrefix` sweeps and `clearCacheEntry` base-key matching.
1021
1021
  * The `clearCacheEntry` callsites all pass fixed, dataless logical keys
1022
1022
  * (`GET:/users/<id>`, `GET:/session/user/<sessionId>`,
1023
- * `GET:/fedcm/me/authorized-apps`), so this readable suffix can never be
1023
+ * `GET:/auth/grants`), so this readable suffix can never be
1024
1024
  * ambiguous with a serialized request body.
1025
1025
  */
1026
1026
  HttpService.CACHE_IDENTITY_DELIM = ' id=';
package/dist/esm/index.js CHANGED
@@ -23,6 +23,9 @@ import './crypto/polyfill.js';
23
23
  // ---------------------------------------------------------------------------
24
24
  export { OxyServices, OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices.js';
25
25
  export { OXY_CLOUD_URL, oxyClient } from './OxyServices.js';
26
+ // ---------------------------------------------------------------------------
27
+ // Authentication
28
+ // ---------------------------------------------------------------------------
26
29
  export { ServiceCredentialMismatchError } from './mixins/OxyServices.auth.js';
27
30
  export { OxyAppDataIdentifierError } from './mixins/OxyServices.appData.js';
28
31
  // ---------------------------------------------------------------------------
@@ -117,14 +120,18 @@ export { buildAccountsArray, createQuickAccount, getAccountDisplayName, getAccou
117
120
  // Registrable-domain + central-IdP-apex helpers.
118
121
  //
119
122
  // The client SSO-bounce / silent-iframe / FedCM machinery was removed in the
120
- // device-first cutover. These three symbols survive because the api SSO surface
121
- // and the IdP (both lista B, gated on the ecosystem bump) still import them:
122
- // `registrableApex` (eTLD+1), `CENTRAL_IDP_APEX`, and the `SSO_CALLBACK_PATH`
123
- // constant. `@oxyhq/core/server` re-exports `registrableApex` + `SSO_CALLBACK_PATH`
124
- // for the api; the IdP imports all three from here.
125
- // ---------------------------------------------------------------------------
126
- export { registrableApex } from './utils/fapiAutoDetect.js';
127
- export { CENTRAL_AUTH_URL, CENTRAL_IDP_APEX } from './utils/authWebUrl.js';
123
+ // device-first cutover (wave 2, ecosystem-wide bump complete). `registrableApex`
124
+ // (eTLD+1) and `CENTRAL_IDP_APEX` are still genuinely used: `registrableApex`
125
+ // via the `@oxyhq/core/server` re-export consumed by
126
+ // `packages/api/src/utils/sameSite.ts` for same-site origin checks, and
127
+ // `CENTRAL_IDP_APEX` by `server/cors.ts`'s `createOxyCors` (auto-allows
128
+ // `*.oxy.so`). `SSO_CALLBACK_PATH` has no remaining importer outside this
129
+ // module as of wave 2 — kept exported for now rather than removed here (an
130
+ // export deletion is a logic change, out of scope for a comment sweep); flag
131
+ // for a follow-up dead-export cleanup pass.
132
+ // ---------------------------------------------------------------------------
133
+ export { registrableApex } from './utils/registrableApex.js';
134
+ export { CENTRAL_IDP_APEX } from './utils/authWebUrl.js';
128
135
  export { SSO_CALLBACK_PATH } from './utils/ssoBounce.js';
129
136
  export { runColdBoot } from './utils/coldBoot.js';
130
137
  // ---------------------------------------------------------------------------
@@ -49,24 +49,18 @@ export function OxyServicesAccountsMixin(Base) {
49
49
  * target, directly or inherited — else 403; 404 if missing/archived; 403 if
50
50
  * the target is a personal account), then mints a REAL session for the
51
51
  * target account and returns it in the canonical login / `claimSessionByToken`
52
- * shape (`{ sessionId, deviceId, expiresAt, accessToken, user, authuser }`).
52
+ * shape (`{ sessionId, deviceId, expiresAt, accessToken, user }`).
53
53
  *
54
54
  * Unlike the removed `X-Acting-As` delegation header, the returned session
55
55
  * IS the new identity: this plants `accessToken` as the active token —
56
56
  * exactly like `claimSessionByToken` / `verifyChallenge` — so every
57
57
  * subsequent request authenticates as the target account.
58
58
  *
59
- * Joining the device multi-account set (so the switch survives a reload and
60
- * propagates cross-domain via `/auth/refresh-all`) requires a SECOND call, to
61
- * `POST /auth/session`, made here after the token is planted. The switch route
62
- * lives at `/accounts/*`, OUTSIDE the `oxy_rt_<authuser>` cookie's `Path=/auth`
63
- * scope, so the server never sees the device's existing slots from it and
64
- * would clobber slot 0 (destroying the operator's own session). `/auth/session`
65
- * runs where those cookies ARE visible, so the server allocates a NEW slot that
66
- * coexists with the operator's and returns its `authuser`. This step is
67
- * web-only (native multi-account uses stored sessions, not cookies) and
68
- * best-effort — a failure leaves the in-session switch intact; the switched
69
- * account simply won't survive a reload until the cookie is next established.
59
+ * A single call is all that's needed: the server registers the switched
60
+ * session into the operator's `DeviceSession` set directly, inheriting the
61
+ * operator's central `deviceId` so the switch survives a reload and syncs
62
+ * cross-domain via the same device-first session model as a normal login —
63
+ * there is no separate client-side cookie/slot step to make it stick.
70
64
  *
71
65
  * After planting, the SDK's identity-scoped GET cache is fully cleared so
72
66
  * every cached read re-fetches as the new account. (The consuming
@@ -76,7 +70,7 @@ export function OxyServicesAccountsMixin(Base) {
76
70
  * same-user silent refreshes, so the sweep here is explicit.)
77
71
  *
78
72
  * @param accountId - The target account's Mongo `_id`.
79
- * @returns The minted session (planted) plus the device `authuser` slot.
73
+ * @returns The minted session, already planted as the active session.
80
74
  */
81
75
  async switchToAccount(accountId) {
82
76
  try {
@@ -6,7 +6,6 @@
6
6
  */
7
7
  import { OxyServicesBase } from '../OxyServices.base.js';
8
8
  import { OxyServicesAuthMixin } from './OxyServices.auth.js';
9
- import { OxyServicesAuthorizedAppsMixin } from './OxyServices.authorizedApps.js';
10
9
  import { OxyServicesUserMixin } from './OxyServices.user.js';
11
10
  import { OxyServicesIdentityMixin } from './OxyServices.identity.js';
12
11
  import { OxyServicesPrivacyMixin } from './OxyServices.privacy.js';
@@ -43,10 +42,6 @@ import { OxyServicesDeviceBootMixin } from './OxyServices.deviceBoot.js';
43
42
  const MIXIN_PIPELINE = [
44
43
  // Base authentication
45
44
  OxyServicesAuthMixin,
46
- // Legacy FedCM "Connected apps" management (list/revoke authorized RP grants).
47
- // The FedCM sign-in surface was removed in the device-first cutover; only
48
- // this management pair survives until the AppGrant migration.
49
- OxyServicesAuthorizedAppsMixin,
50
45
  // User management (requires auth)
51
46
  OxyServicesUserMixin,
52
47
  // Self-sovereign identity (DID, signed records, auth-method ↔ VM mapping)
@@ -26,7 +26,7 @@ export { verifySecret } from './verifySecret.js';
26
26
  // SOURCE OF TRUTH shared with the IdP worker and the client FAPI auto-detect.
27
27
  // Pure host handling (no browser deps), so it is safe on the server subpath and
28
28
  // lets `@oxyhq/api` derive `auth.<apex>` without duplicating PSL logic.
29
- export { registrableApex } from '../utils/fapiAutoDetect.js';
29
+ export { registrableApex } from '../utils/registrableApex.js';
30
30
  // The single RP callback path the IdP redirects back to. A pure wire-contract
31
31
  // constant (no browser deps at module top level), re-used server-side so the
32
32
  // `/sso/establish-token` `return_to` cannot drift from what `/sso/establish`
@@ -21,7 +21,7 @@ export const isDev = () => {
21
21
  };
22
22
  /**
23
23
  * Log a debug message (only in development)
24
- * @param prefix - Log prefix (e.g., '[FedCM]')
24
+ * @param prefix - Log prefix (e.g., '[ColdBoot]')
25
25
  * @param args - Arguments to log
26
26
  */
27
27
  export const debugLog = (prefix, ...args) => {
@@ -51,12 +51,12 @@ export const debugError = (prefix, ...args) => {
51
51
  };
52
52
  /**
53
53
  * Create a namespaced debug logger
54
- * @param namespace - Logger namespace (e.g., 'FedCM', 'SilentAuth')
54
+ * @param namespace - Logger namespace (e.g., 'ColdBoot', 'DeviceAuth')
55
55
  * @returns Object with log, warn, error methods
56
56
  *
57
57
  * @example
58
58
  * ```ts
59
- * const debug = createDebugLogger('FedCM');
59
+ * const debug = createDebugLogger('ColdBoot');
60
60
  * debug.log('Starting authentication');
61
61
  * debug.warn('Token expires soon');
62
62
  * debug.error('Authentication failed', error);
@@ -1,36 +1,16 @@
1
1
  /**
2
- * Central IdP (auth web) URL resolution for cross-domain SSO.
2
+ * Central IdP apex constant.
3
3
  *
4
- * The Oxy ecosystem runs a single, central Identity Provider at
5
- * `auth.oxy.so`. For TRUE central cross-domain SSO (Google/Meta/Clerk style),
6
- * FedCM and the opaque-code SSO bounce always target this one origin it owns
7
- * the host-only `fedcm_session` cookie and the central session store reachable
8
- * via `api.oxy.so`. Relying Parties (mention.earth, homiio.com, alia.onl, …)
9
- * delegate to it rather than standing up a per-apex IdP.
10
- *
11
- * This module is intentionally pure: it performs no DOM access, reads no
12
- * `window`/`location`, and has no side effects. It is the single source of
13
- * truth for the central IdP origin so call sites never hardcode the literal.
14
- *
15
- * LEGACY(old-sdk): the client resolver (`resolveCentralAuthUrl`) was removed in
16
- * the device-first cutover; `CENTRAL_IDP_APEX` / `CENTRAL_AUTH_URL` survive ONLY
17
- * because the lista-B IdP worker imports them to brand assertions. Deletable
18
- * once Homiio/Allo/Alia/Syra are bumped off the old SDK AND CloudWatch
19
- * `/oxy/ecs` shows the `/sso*` + `/fedcm/*` routes quiet — F-final sweep.
4
+ * The client SSO/FedCM resolvers (`resolveCentralAuthUrl`, `CENTRAL_AUTH_URL`)
5
+ * were removed in the device-first / legacy-final cutovers. The lone survivor is
6
+ * `CENTRAL_IDP_APEX`, kept because it has a LIVE consumer
7
+ * `@oxyhq/core/server`'s CORS helper (`server/cors.ts`'s `createOxyCors`)
8
+ * auto-allows `*.oxy.so` from it. That CORS use is permanent, so this stays
9
+ * past the SSO/FedCM teardown.
20
10
  */
21
11
  /**
22
12
  * The registrable apex (eTLD+1) of the Oxy ecosystem's central Identity
23
- * Provider. The central IdP is reachable at `auth.${CENTRAL_IDP_APEX}` and the
24
- * ID-token assertion issuer is always `https://auth.${CENTRAL_IDP_APEX}`
25
- * regardless of which per-apex `auth.<rp>` host served a given request.
26
- *
27
- * Kept as a standalone constant so the IdP worker and the SDK derive the same
28
- * literal from one source of truth (the worker imports it to brand assertions).
13
+ * Provider, reachable at `auth.${CENTRAL_IDP_APEX}`. Single source of truth so
14
+ * the CORS helper (and anything else that needs the central apex) never drifts.
29
15
  */
30
16
  export const CENTRAL_IDP_APEX = 'oxy.so';
31
- /**
32
- * The canonical central Identity Provider origin for the Oxy ecosystem.
33
- * No trailing slash. Derived from {@link CENTRAL_IDP_APEX} so the apex and the
34
- * full origin never drift apart. The IdP worker imports it to brand assertions.
35
- */
36
- export const CENTRAL_AUTH_URL = `https://auth.${CENTRAL_IDP_APEX}`;
@@ -3,19 +3,21 @@
3
3
  * authentication resolution.
4
4
  *
5
5
  * On a fresh page load / app launch the SDK may have several ways to recover an
6
- * existing session (silent FedCM, a persisted refresh token, a cross-domain
7
- * claim, a redirect SSO return, ...). They must be attempted in a deterministic
8
- * order*, and the FIRST one that yields a session wins — every later step is
9
- * skipped. This module encodes exactly that contract and nothing else.
6
+ * existing session (a persisted refresh-token family, a shared-keychain
7
+ * identity, a cross-domain boot-fragment return, ...). They must be attempted
8
+ * in a deterministic order, and the FIRST one that yields a session wins —
9
+ * every later step is skipped. This module encodes exactly that contract and
10
+ * nothing else.
10
11
  *
11
12
  * Design constraints (all enforced):
12
13
  * - PURE: no DOM, no `navigator`, no `window`, no React, no platform globals.
13
14
  * - NO module-level mutable state. Every call to {@link runColdBoot} is fully
14
15
  * self-contained, so it is safe under bundler re-evaluation (e.g. the Metro
15
- * web bundle, which is precisely why the FedCM silent-SSO guard had to live
16
- * in consumers rather than a core singleton).
17
- * - Architecture-agnostic: both candidate cross-domain SSO designs consume
18
- * this same primitive; it knows nothing about HOW a step resolves a session.
16
+ * web bundle the reason any run-once guard for a step must live in the
17
+ * calling consumer, never in a core module-level singleton).
18
+ * - Architecture-agnostic: it knows nothing about HOW a step resolves a
19
+ * session; `runSessionColdBoot` (`boot/coldBootV2.ts`) is the current
20
+ * device-first consumer.
19
21
  *
20
22
  * A step is skipped (without running) when its `enabled` predicate returns
21
23
  * false. Any thrown error — from either `enabled` or `run` — is reported via
@@ -1,17 +1,15 @@
1
1
  /**
2
2
  * Registrable-apex (eTLD+1) host kernel.
3
3
  *
4
- * The client FAPI auto-detection helper (`autoDetectAuthWebUrl`) was removed in
5
- * the device-first cutover the SDK no longer derives a per-apex `auth.<rp>`
6
- * IdP host. What survives is the pure registrable-domain kernel, still used by
7
- * the api SSO surface, `fedcm.service`, `deviceAuth` (same-apex trust checks),
8
- * and the IdP worker (all lista B / server-side). `@oxyhq/core/server`
9
- * re-exports it for the api.
4
+ * The client FAPI auto-detection helper was removed in the device-first cutover
5
+ * (which is why this file is now named for what it actually is, not the old
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
10
  *
11
- * LEGACY(old-sdk): `registrableApex` survives ONLY for the lista-B server/IdP
12
- * SSO surface. Deletable once Homiio/Allo/Alia/Syra are bumped off the old SDK
13
- * AND CloudWatch `/oxy/ecs` shows the `/sso*` + `/fedcm/*` routes quiet — the
14
- * F-final sweep should remove this file then.
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.
15
13
  */
16
14
  import { getDomain } from 'tldts';
17
15
  /**