@oxyhq/services 19.1.2 → 19.1.3
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/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +53 -50
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/commitSessionFlow.js +91 -0
- package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -0
- package/lib/commonjs/ui/hooks/useOxyEvent.js +28 -0
- package/lib/commonjs/ui/hooks/useOxyEvent.js.map +1 -0
- package/lib/commonjs/ui/screens/FileManagementScreen.js +3 -9
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/session/createSessionClient.js +12 -8
- package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
- package/lib/commonjs/ui/session/tokenTransport.js +22 -32
- package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +54 -51
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/commitSessionFlow.js +87 -0
- package/lib/module/ui/context/commitSessionFlow.js.map +1 -0
- package/lib/module/ui/hooks/useOxyEvent.js +25 -0
- package/lib/module/ui/hooks/useOxyEvent.js.map +1 -0
- package/lib/module/ui/screens/FileManagementScreen.js +3 -9
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/session/createSessionClient.js +12 -8
- package/lib/module/ui/session/createSessionClient.js.map +1 -1
- package/lib/module/ui/session/tokenTransport.js +23 -33
- package/lib/module/ui/session/tokenTransport.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +39 -0
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +3 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useOxyEvent.d.ts +8 -0
- package/lib/typescript/commonjs/ui/hooks/useOxyEvent.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +12 -8
- package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +11 -9
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +39 -0
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -0
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +3 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useOxyEvent.d.ts +8 -0
- package/lib/typescript/module/ui/hooks/useOxyEvent.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/createSessionClient.d.ts +12 -8
- package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/tokenTransport.d.ts +11 -9
- package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/index.ts +1 -0
- package/src/ui/context/OxyContext.tsx +51 -49
- package/src/ui/context/__tests__/commitSessionFlow.test.ts +192 -0
- package/src/ui/context/commitSessionFlow.ts +115 -0
- package/src/ui/context/oxyContextTypes.ts +3 -1
- package/src/ui/hooks/useOxyEvent.ts +22 -0
- package/src/ui/screens/FileManagementScreen.tsx +3 -9
- package/src/ui/session/__tests__/createSessionClient.test.ts +5 -5
- package/src/ui/session/__tests__/tokenTransport.test.ts +43 -60
- package/src/ui/session/createSessionClient.ts +13 -10
- package/src/ui/session/tokenTransport.ts +22 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxyContextTypes.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/oxyContextTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"oxyContextTypes.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/oxyContextTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscribe to a named server-pushed Socket.IO event (e.g. `civic:attested`)
|
|
3
|
+
* for the lifetime of the component. Payloads arrive as `unknown` — callers
|
|
4
|
+
* validate shape. Handler identity may change between renders; the latest one
|
|
5
|
+
* is always invoked.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOxyEvent(event: string, handler: (payload: unknown) => void): void;
|
|
8
|
+
//# sourceMappingURL=useOxyEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOxyEvent.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useOxyEvent.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAWpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAgBjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAgFzE,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAgBjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAgFzE,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAk1D7D,CAAC;AAIF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SessionClient, createSessionClientHost, type
|
|
1
|
+
import { SessionClient, createSessionClientHost, type OxyServices, type SessionStateOrigin } from '@oxyhq/core';
|
|
2
2
|
/**
|
|
3
3
|
* Wire a `SessionClient` for `@oxyhq/services`.
|
|
4
4
|
*
|
|
@@ -11,18 +11,22 @@ import { SessionClient, createSessionClientHost, type AuthStateStore, type OxySe
|
|
|
11
11
|
* core's lazy dynamic import of a bare specifier — bundler-fragile in
|
|
12
12
|
* Metro/Expo-web against the published core dist.
|
|
13
13
|
* - the device-first {@link createTokenTransport}, which mints a fallback token
|
|
14
|
-
*
|
|
14
|
+
* through the ONE shared `httpService.refreshAccessToken` single-flight (it
|
|
15
|
+
* reads the persisted `deviceId` + `deviceSecret` via the installed handler,
|
|
16
|
+
* so it takes no `store` of its own).
|
|
15
17
|
*
|
|
16
|
-
* `onUnauthenticated` fires when an applied device state has zero accounts
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* `onUnauthenticated` fires when an applied device state has zero accounts. It
|
|
19
|
+
* receives the {@link SessionStateOrigin} so the provider can gate the
|
|
20
|
+
* destructive credential wipe: a `request`-origin verdict (a REST sign-out /
|
|
21
|
+
* revocation) clears the persisted store; a `push`-origin verdict (a possibly
|
|
22
|
+
* transient socket broadcast) clears only the local UI session and KEEPS the
|
|
23
|
+
* durable device credential. The host is returned alongside the client so the
|
|
24
|
+
* caller can call `host.setCurrentAccountId(...)` as the active account changes.
|
|
21
25
|
*
|
|
22
26
|
* The realtime socket uses bearer when authenticated, or deviceId+deviceSecret
|
|
23
27
|
* when signed out (after the one-shot join redirect).
|
|
24
28
|
*/
|
|
25
|
-
export declare function createSessionClient(oxyServices: OxyServices,
|
|
29
|
+
export declare function createSessionClient(oxyServices: OxyServices, onUnauthenticated?: (origin: SessionStateOrigin) => void): {
|
|
26
30
|
client: SessionClient;
|
|
27
31
|
host: ReturnType<typeof createSessionClientHost>;
|
|
28
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSessionClient.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/createSessionClient.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,KAAK,
|
|
1
|
+
{"version":3,"file":"createSessionClient.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/createSessionClient.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAGrB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,GACvD;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;CAClD,CAKA"}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type OxyServices, type TokenTransport } from '@oxyhq/core';
|
|
2
2
|
/**
|
|
3
3
|
* Platform `TokenTransport` for `SessionClient` (device-first model).
|
|
4
4
|
*
|
|
5
5
|
* `ensureActiveToken` is the fallback the client uses when a `session_state`
|
|
6
6
|
* push arrived WITHOUT an embedded `activeToken` and the app currently holds no
|
|
7
|
-
* bearer. It mints one through the ONE unified
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* bearer. It mints one through the ONE unified single-flight the scheduler, the
|
|
8
|
+
* request-time preflight, and the 401 retry all use —
|
|
9
|
+
* `oxyServices.httpService.refreshAccessToken(...)` — which runs the installed
|
|
10
|
+
* refresh handler (present the persisted zero-cookie `deviceId` + `deviceSecret`
|
|
11
|
+
* at `POST /session/device/token`). Routing through the SAME entry point means
|
|
12
|
+
* this lane can never double-rotate the device secret against the others: it has
|
|
13
|
+
* NO private single-flight of its own.
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* handler).
|
|
15
|
+
* A failure is logged and swallowed: this method must never throw out (it runs
|
|
16
|
+
* inside the socket state handler).
|
|
15
17
|
*/
|
|
16
|
-
export declare function createTokenTransport(oxyServices: OxyServices
|
|
18
|
+
export declare function createTokenTransport(oxyServices: OxyServices): TokenTransport;
|
|
17
19
|
//# sourceMappingURL=tokenTransport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenTransport.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/tokenTransport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"tokenTransport.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/tokenTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,WAAW,GAAG,cAAc,CA0B7E"}
|
|
@@ -48,6 +48,7 @@ export { queryKeys, invalidateAccountQueries, invalidateUserQueries, invalidateS
|
|
|
48
48
|
export { useMutationStatus } from './ui/hooks/useMutationStatus.js';
|
|
49
49
|
export type { MutationStatus } from './ui/hooks/useMutationStatus.js';
|
|
50
50
|
export { useOnlineStatus } from './ui/hooks/useOnlineStatus.js';
|
|
51
|
+
export { useOxyEvent } from './ui/hooks/useOxyEvent.js';
|
|
51
52
|
export { handleAuthError, isInvalidSessionError, isTimeoutOrNetworkError, extractErrorMessage, } from './ui/utils/errorHandlers.js';
|
|
52
53
|
export type { HandleAuthErrorOptions } from './ui/utils/errorHandlers.js';
|
|
53
54
|
export { useFileFiltering } from './ui/hooks/useFileFiltering.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAYH,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gCAA6B,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAAyB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,4BAAyB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAoB,CAAC;AAC7C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAoB,CAAC;AAKhF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,+BAA4B,CAAC;AAKpE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA0B,CAAC;AAC3D,OAAO,EACH,aAAa,EACb,SAAS,IAAI,cAAc,EAC3B,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,2BAAwB,CAAC;AAKhC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,yBAAsB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAA+B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,yBAAsB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAAuB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,0BAAuB,CAAC;AAKjF,OAAO,EACH,cAAc,EACd,eAAe,EACf,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,yCAAsC,CAAC;AAC9C,OAAO,EACH,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,sBAAsB,GACzB,MAAM,0CAAuC,CAAC;AAC/C,OAAO,EACH,mBAAmB,EACnB,yBAAyB,EACzB,2BAA2B,GAC9B,MAAM,0CAAuC,CAAC;AAC/C,OAAO,EACH,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,yBAAyB,GAC5B,MAAM,yCAAsC,CAAC;AAG9C,YAAY,EACR,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,0BAA0B,GAC7B,MAAM,oCAAiC,CAAC;AAKzC,OAAO,EACH,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,GAChB,MAAM,6CAA0C,CAAC;AAClD,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,eAAe,GAClB,MAAM,8CAA2C,CAAC;AACnD,OAAO,EACH,qBAAqB,EACrB,qBAAqB,GACxB,MAAM,yCAAsC,CAAC;AAC9C,YAAY,EACR,qBAAqB,EACrB,qBAAqB,GACxB,MAAM,yCAAsC,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAmC,CAAC;AAQjE,OAAO,EACH,SAAS,EACT,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,GACjC,MAAM,iCAA8B,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAA8B,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,iCAA8B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyContext.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/OxyContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OxyContext.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/OxyContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA0D/B,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,uBAAuB,EAE7B,MAAM,sBAAmB,CAAC;AAK3B,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,sBAAmB,CAAC;AAIxG,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA63BzD,CAAC;AAEF,eAAO,MAAM,kBAAkB,mCAAc,CAAC;AAgE9C,eAAO,MAAM,MAAM,QAAO,eAMzB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { User } from '@oxyhq/core';
|
|
2
|
+
export interface CommitDeviceSetAndResolveDeps {
|
|
3
|
+
/**
|
|
4
|
+
* Whether this commit is a deliberate sign-in on THIS device (activates the
|
|
5
|
+
* account and BLOCKS on the device-set reconcile before resolving) vs. a
|
|
6
|
+
* cold-boot restore (resolves auth from the profile fetch FIRST, then
|
|
7
|
+
* reconciles the device set in the background).
|
|
8
|
+
*/
|
|
9
|
+
activate: boolean;
|
|
10
|
+
/** The committing account id (only used by `registerAndActivate`). */
|
|
11
|
+
userId?: string;
|
|
12
|
+
/** Minimal user carried by the commit input; used if the profile fetch fails. */
|
|
13
|
+
fallbackUser: User | null;
|
|
14
|
+
/** Deliberate sign-in: register + activate the account in the device set. */
|
|
15
|
+
registerAndActivate: (userId?: string) => Promise<void>;
|
|
16
|
+
/** Cold boot: ensure membership only; the server's `activeAccountId` wins. */
|
|
17
|
+
addCurrentAccount: () => Promise<void>;
|
|
18
|
+
/** Start the device-scoped socket. */
|
|
19
|
+
startSocket: () => Promise<void>;
|
|
20
|
+
/** Project the server-authoritative device state onto local sessions. */
|
|
21
|
+
syncFromClient: () => Promise<void>;
|
|
22
|
+
/** Hydrate the full profile (the commit input carries only minimal data). */
|
|
23
|
+
getCurrentUser: () => Promise<User | null>;
|
|
24
|
+
loginSuccess: (user: User) => void;
|
|
25
|
+
onAuthStateChange?: (user: User | null) => void;
|
|
26
|
+
markAuthResolved: () => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Device-set registration + full-user hydration + auth-resolution gate flip.
|
|
30
|
+
*
|
|
31
|
+
* On a deliberate sign-in (`activate: true`) the device-set reconcile is awaited
|
|
32
|
+
* BEFORE hydrating and resolving — unchanged legacy ordering. On a cold boot
|
|
33
|
+
* (`activate: false`) auth resolves from the profile fetch FIRST so the app can
|
|
34
|
+
* paint an authenticated shell without waiting on device-set registration, the
|
|
35
|
+
* socket connect, and the authoritative sessions projection — those reconcile in
|
|
36
|
+
* a DETACHED background task a moment later.
|
|
37
|
+
*/
|
|
38
|
+
export declare function commitDeviceSetAndResolve(deps: CommitDeviceSetAndResolveDeps): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=commitSessionFlow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commitSessionFlow.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/commitSessionFlow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAKxC,MAAM,WAAW,6BAA6B;IAC5C;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,6EAA6E;IAC7E,mBAAmB,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,8EAA8E;IAC9E,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,sCAAsC;IACtC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,yEAAyE;IACzE,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,6EAA6E;IAC7E,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC3C,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,IAAI,CAAC,CAsEf"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import type { OxyServices, User, SessionLoginResponse, AccountNode, CreateAccountInput, ClientSession, AccountDialogController, AccountDialogView, ApiError } from '@oxyhq/core';
|
|
2
|
+
import type { OxyServices, User, SessionLoginResponse, AccountNode, CreateAccountInput, ClientSession, AccountDialogController, AccountDialogView, ApiError, SessionClient } from '@oxyhq/core';
|
|
3
3
|
import type { SecurityAlert } from '@oxyhq/contracts';
|
|
4
4
|
import type { UseFollowHook } from '../hooks/useFollow.types.js';
|
|
5
5
|
import type { useLanguageManagement } from '../hooks/useLanguageManagement.js';
|
|
@@ -68,6 +68,8 @@ export interface OxyContextState {
|
|
|
68
68
|
storageKeyPrefix: string;
|
|
69
69
|
clientId: string | null;
|
|
70
70
|
oxyServices: OxyServices;
|
|
71
|
+
/** Server-authoritative device session client. `null` before an `OxyProvider` is mounted. */
|
|
72
|
+
sessionClient: SessionClient | null;
|
|
71
73
|
useFollow?: UseFollowHook;
|
|
72
74
|
showBottomSheet?: (screenOrConfig: RouteName | {
|
|
73
75
|
screen: RouteName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxyContextTypes.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/oxyContextTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"oxyContextTypes.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/oxyContextTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscribe to a named server-pushed Socket.IO event (e.g. `civic:attested`)
|
|
3
|
+
* for the lifetime of the component. Payloads arrive as `unknown` — callers
|
|
4
|
+
* validate shape. Handler identity may change between renders; the latest one
|
|
5
|
+
* is always invoked.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOxyEvent(event: string, handler: (payload: unknown) => void): void;
|
|
8
|
+
//# sourceMappingURL=useOxyEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOxyEvent.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useOxyEvent.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAWpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAgBjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAAyB,CAAC;AAgFzE,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAgBjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAAyB,CAAC;AAgFzE,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAk1D7D,CAAC;AAIF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SessionClient, createSessionClientHost, type
|
|
1
|
+
import { SessionClient, createSessionClientHost, type OxyServices, type SessionStateOrigin } from '@oxyhq/core';
|
|
2
2
|
/**
|
|
3
3
|
* Wire a `SessionClient` for `@oxyhq/services`.
|
|
4
4
|
*
|
|
@@ -11,18 +11,22 @@ import { SessionClient, createSessionClientHost, type AuthStateStore, type OxySe
|
|
|
11
11
|
* core's lazy dynamic import of a bare specifier — bundler-fragile in
|
|
12
12
|
* Metro/Expo-web against the published core dist.
|
|
13
13
|
* - the device-first {@link createTokenTransport}, which mints a fallback token
|
|
14
|
-
*
|
|
14
|
+
* through the ONE shared `httpService.refreshAccessToken` single-flight (it
|
|
15
|
+
* reads the persisted `deviceId` + `deviceSecret` via the installed handler,
|
|
16
|
+
* so it takes no `store` of its own).
|
|
15
17
|
*
|
|
16
|
-
* `onUnauthenticated` fires when an applied device state has zero accounts
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* `onUnauthenticated` fires when an applied device state has zero accounts. It
|
|
19
|
+
* receives the {@link SessionStateOrigin} so the provider can gate the
|
|
20
|
+
* destructive credential wipe: a `request`-origin verdict (a REST sign-out /
|
|
21
|
+
* revocation) clears the persisted store; a `push`-origin verdict (a possibly
|
|
22
|
+
* transient socket broadcast) clears only the local UI session and KEEPS the
|
|
23
|
+
* durable device credential. The host is returned alongside the client so the
|
|
24
|
+
* caller can call `host.setCurrentAccountId(...)` as the active account changes.
|
|
21
25
|
*
|
|
22
26
|
* The realtime socket uses bearer when authenticated, or deviceId+deviceSecret
|
|
23
27
|
* when signed out (after the one-shot join redirect).
|
|
24
28
|
*/
|
|
25
|
-
export declare function createSessionClient(oxyServices: OxyServices,
|
|
29
|
+
export declare function createSessionClient(oxyServices: OxyServices, onUnauthenticated?: (origin: SessionStateOrigin) => void): {
|
|
26
30
|
client: SessionClient;
|
|
27
31
|
host: ReturnType<typeof createSessionClientHost>;
|
|
28
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSessionClient.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/createSessionClient.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,KAAK,
|
|
1
|
+
{"version":3,"file":"createSessionClient.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/createSessionClient.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAGrB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,GACvD;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;CAClD,CAKA"}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type OxyServices, type TokenTransport } from '@oxyhq/core';
|
|
2
2
|
/**
|
|
3
3
|
* Platform `TokenTransport` for `SessionClient` (device-first model).
|
|
4
4
|
*
|
|
5
5
|
* `ensureActiveToken` is the fallback the client uses when a `session_state`
|
|
6
6
|
* push arrived WITHOUT an embedded `activeToken` and the app currently holds no
|
|
7
|
-
* bearer. It mints one through the ONE unified
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* bearer. It mints one through the ONE unified single-flight the scheduler, the
|
|
8
|
+
* request-time preflight, and the 401 retry all use —
|
|
9
|
+
* `oxyServices.httpService.refreshAccessToken(...)` — which runs the installed
|
|
10
|
+
* refresh handler (present the persisted zero-cookie `deviceId` + `deviceSecret`
|
|
11
|
+
* at `POST /session/device/token`). Routing through the SAME entry point means
|
|
12
|
+
* this lane can never double-rotate the device secret against the others: it has
|
|
13
|
+
* NO private single-flight of its own.
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* handler).
|
|
15
|
+
* A failure is logged and swallowed: this method must never throw out (it runs
|
|
16
|
+
* inside the socket state handler).
|
|
15
17
|
*/
|
|
16
|
-
export declare function createTokenTransport(oxyServices: OxyServices
|
|
18
|
+
export declare function createTokenTransport(oxyServices: OxyServices): TokenTransport;
|
|
17
19
|
//# sourceMappingURL=tokenTransport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenTransport.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/tokenTransport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"tokenTransport.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/tokenTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,WAAW,GAAG,cAAc,CA0B7E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "19.1.
|
|
3
|
+
"version": "19.1.3",
|
|
4
4
|
"description": "OxyHQ Expo/React Native SDK — UI components, screens, and native features",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -118,11 +118,11 @@
|
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"@oxyhq/contracts": "0.13.
|
|
121
|
+
"@oxyhq/contracts": "0.13.2",
|
|
122
122
|
"color": "^4.2.3"
|
|
123
123
|
},
|
|
124
124
|
"devDependencies": {
|
|
125
|
-
"@oxyhq/core": "9.2.
|
|
125
|
+
"@oxyhq/core": "9.2.3",
|
|
126
126
|
"nativewind": "5.0.0-preview.3",
|
|
127
127
|
"react-native-css": "^3.0.0",
|
|
128
128
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
@@ -147,16 +147,16 @@
|
|
|
147
147
|
"@types/color": "^4.2.1",
|
|
148
148
|
"@types/jest": "^29.5.14",
|
|
149
149
|
"@types/node": "^20.19.9",
|
|
150
|
-
"expo-file-system": "~
|
|
151
|
-
"expo-font": "~
|
|
152
|
-
"expo-haptics": "~
|
|
153
|
-
"expo-image": "~
|
|
154
|
-
"expo-linear-gradient": "~
|
|
150
|
+
"expo-file-system": "~57.0.0",
|
|
151
|
+
"expo-font": "~57.0.0",
|
|
152
|
+
"expo-haptics": "~57.0.0",
|
|
153
|
+
"expo-image": "~57.0.0",
|
|
154
|
+
"expo-linear-gradient": "~57.0.0",
|
|
155
155
|
"husky": "^4.3.8",
|
|
156
156
|
"jest": "~29.7.0",
|
|
157
157
|
"lint-staged": "^15.2.4",
|
|
158
158
|
"react-native-builder-bob": "^0.43.0",
|
|
159
|
-
"react-native-gesture-handler": "~2.
|
|
159
|
+
"react-native-gesture-handler": "~2.32.0",
|
|
160
160
|
"react-native-reanimated": "4.5.0",
|
|
161
161
|
"react-native-safe-area-context": "~5.8.0",
|
|
162
162
|
"react-native-svg": "15.15.5",
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"peerDependencies": {
|
|
167
167
|
"@expo/vector-icons": "^15.0.3",
|
|
168
168
|
"@oxyhq/bloom": ">=0.16.0",
|
|
169
|
-
"@oxyhq/core": "^9.2.
|
|
169
|
+
"@oxyhq/core": "^9.2.3",
|
|
170
170
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
171
171
|
"@react-native-community/netinfo": "^11.4.1",
|
|
172
172
|
"@tanstack/query-async-storage-persister": "^5.101",
|
|
@@ -176,16 +176,16 @@
|
|
|
176
176
|
"@types/react": "*",
|
|
177
177
|
"@types/react-native": "*",
|
|
178
178
|
"expo": ">=56.0.0",
|
|
179
|
-
"expo-document-picker": "
|
|
180
|
-
"expo-file-system": "
|
|
179
|
+
"expo-document-picker": ">=56.0.0",
|
|
180
|
+
"expo-file-system": ">=56.0.0",
|
|
181
181
|
"expo-font": ">=13.0.0",
|
|
182
|
-
"expo-haptics": "
|
|
182
|
+
"expo-haptics": ">=56.0.0",
|
|
183
183
|
"expo-image": ">=2.0.0",
|
|
184
|
-
"expo-image-manipulator": "
|
|
185
|
-
"expo-linear-gradient": "
|
|
184
|
+
"expo-image-manipulator": ">=56.0.0",
|
|
185
|
+
"expo-linear-gradient": ">=56.0.0",
|
|
186
186
|
"react": ">=18.0.0",
|
|
187
187
|
"react-native": ">=0.85.0",
|
|
188
|
-
"react-native-gesture-handler": "~2.
|
|
188
|
+
"react-native-gesture-handler": "~2.32.0",
|
|
189
189
|
"react-native-keyboard-controller": ">=1.21.0",
|
|
190
190
|
"react-native-qrcode-svg": "^6.3.0",
|
|
191
191
|
"react-native-reanimated": ">=4.3.0",
|
package/src/index.ts
CHANGED
|
@@ -172,6 +172,7 @@ export {
|
|
|
172
172
|
export { useMutationStatus } from './ui/hooks/useMutationStatus';
|
|
173
173
|
export type { MutationStatus } from './ui/hooks/useMutationStatus';
|
|
174
174
|
export { useOnlineStatus } from './ui/hooks/useOnlineStatus';
|
|
175
|
+
export { useOxyEvent } from './ui/hooks/useOxyEvent';
|
|
175
176
|
|
|
176
177
|
// ---------------------------------------------------------------------------
|
|
177
178
|
// Error handlers
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
installAuthRefreshHandler,
|
|
24
24
|
startTokenRefreshScheduler,
|
|
25
25
|
createAccountDialogController,
|
|
26
|
-
refreshPersistedSession,
|
|
27
26
|
logger as loggerUtil,
|
|
28
27
|
syncHubAfterSignIn,
|
|
29
28
|
} from '@oxyhq/core';
|
|
@@ -64,6 +63,7 @@ import {
|
|
|
64
63
|
type CommitInput,
|
|
65
64
|
} from './oxyContextTypes';
|
|
66
65
|
import { DEFAULT_SESSION_VALIDITY_MS, loadUseFollowHook } from './oxyContextHelpers';
|
|
66
|
+
import { commitDeviceSetAndResolve } from './commitSessionFlow';
|
|
67
67
|
import { useOxyAccountGraph } from './useOxyAccountGraph';
|
|
68
68
|
|
|
69
69
|
export type { OxyContextState, PasswordSignInResult, OxyContextProviderProps } from './oxyContextTypes';
|
|
@@ -281,9 +281,16 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
281
281
|
if (!sessionClientPairRef.current) {
|
|
282
282
|
sessionClientPairRef.current = createSessionClient(
|
|
283
283
|
oxyServices,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
(origin) => {
|
|
285
|
+
// Erase the DURABLE device credential only on a `request`-origin verdict
|
|
286
|
+
// (a REST sign-out / revocation). A `push`-origin empty state is a socket
|
|
287
|
+
// broadcast that may be a transient reconnect artifact — clearing the
|
|
288
|
+
// credential on it would strand the user signed out with no way back, so
|
|
289
|
+
// we clear only the local UI session and keep the credential (a dead one
|
|
290
|
+
// re-mints to `no_active_session` and resolves signed-out on next boot).
|
|
291
|
+
if (origin === 'request') {
|
|
292
|
+
clearPersistedAuthSafe(authStore, logger);
|
|
293
|
+
}
|
|
287
294
|
void clearSessionStateRef.current().catch((clearError) => {
|
|
288
295
|
logger('Failed to clear local state on remote sign-out', clearError);
|
|
289
296
|
});
|
|
@@ -301,8 +308,12 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
301
308
|
return;
|
|
302
309
|
}
|
|
303
310
|
if (state.accounts.length === 0) {
|
|
311
|
+
// Clear the LOCAL UI session on any applied empty state, but NEVER the
|
|
312
|
+
// durable device credential here: `syncFromClient` runs for socket-pushed
|
|
313
|
+
// (possibly transient) states too, and wiping the credential on one would
|
|
314
|
+
// strand the user signed out. The credential wipe is gated on a
|
|
315
|
+
// `request`-origin verdict in `onUnauthenticated` above.
|
|
304
316
|
sessionClientHost.setCurrentAccountId(null);
|
|
305
|
-
clearPersistedAuthSafe(authStore, logger);
|
|
306
317
|
await clearSessionState();
|
|
307
318
|
return;
|
|
308
319
|
}
|
|
@@ -333,7 +344,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
333
344
|
oxyServices,
|
|
334
345
|
sessionClient,
|
|
335
346
|
sessionClientHost,
|
|
336
|
-
authStore,
|
|
337
347
|
updateSessions,
|
|
338
348
|
setActiveSessionId,
|
|
339
349
|
loginSuccess,
|
|
@@ -526,47 +536,27 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
526
536
|
setActiveSessionId(input.sessionId);
|
|
527
537
|
}
|
|
528
538
|
|
|
529
|
-
// Register into the device set
|
|
530
|
-
//
|
|
531
|
-
// the
|
|
532
|
-
//
|
|
533
|
-
//
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
// Hydrate the full user (the commit input carries only minimal data). Fall
|
|
551
|
-
// back to the minimal shape if the profile fetch fails.
|
|
552
|
-
let fullUser: User | null = null;
|
|
553
|
-
try {
|
|
554
|
-
fullUser = await oxyServices.getCurrentUser();
|
|
555
|
-
} catch (profileError) {
|
|
556
|
-
if (__DEV__) {
|
|
557
|
-
loggerUtil.debug(
|
|
558
|
-
'Failed to fetch full user on commit; using minimal fallback',
|
|
559
|
-
{ component: 'OxyContext', method: 'commitSession' },
|
|
560
|
-
profileError as unknown,
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
fullUser = (input.user as unknown as User) ?? null;
|
|
564
|
-
}
|
|
565
|
-
if (fullUser) {
|
|
566
|
-
loginSuccess(fullUser);
|
|
567
|
-
onAuthStateChangeRef.current?.(fullUser);
|
|
568
|
-
}
|
|
569
|
-
markAuthResolvedRef.current();
|
|
539
|
+
// Register into the device set, hydrate the full user, and flip the
|
|
540
|
+
// auth-resolution gate. A deliberate sign-in ACTIVATES the account and
|
|
541
|
+
// BLOCKS on the reconcile (register + socket + sessions projection) before
|
|
542
|
+
// resolving — unchanged ordering. The cold boot resolves auth from the
|
|
543
|
+
// profile fetch FIRST and reconciles the device set in the background, so
|
|
544
|
+
// first paint is not held behind those extra round-trips. Reconcile is
|
|
545
|
+
// best-effort — a failure never fails the sign-in (cold boot re-registers
|
|
546
|
+
// on the next load).
|
|
547
|
+
await commitDeviceSetAndResolve({
|
|
548
|
+
activate: options.activate,
|
|
549
|
+
userId: input.userId,
|
|
550
|
+
fallbackUser: (input.user as unknown as User) ?? null,
|
|
551
|
+
registerAndActivate: (userId) => sessionClient.registerAndActivate(userId),
|
|
552
|
+
addCurrentAccount: () => sessionClient.addCurrentAccount(),
|
|
553
|
+
startSocket: () => sessionClient.start(),
|
|
554
|
+
syncFromClient,
|
|
555
|
+
getCurrentUser: () => oxyServices.getCurrentUser(),
|
|
556
|
+
loginSuccess,
|
|
557
|
+
onAuthStateChange: onAuthStateChangeRef.current,
|
|
558
|
+
markAuthResolved: markAuthResolvedRef.current,
|
|
559
|
+
});
|
|
570
560
|
|
|
571
561
|
if (options.activate && options.hubSync && hubSync && isWebBrowser()) {
|
|
572
562
|
try {
|
|
@@ -636,6 +626,12 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
636
626
|
}
|
|
637
627
|
void Linking.openURL(url);
|
|
638
628
|
},
|
|
629
|
+
// Native-only probe so the controller can detect an installed Commons and
|
|
630
|
+
// deep-link straight into its approve screen (keeping the QR/polling live
|
|
631
|
+
// as fallback). `undefined` on web mirrors the `openUrl` split — the
|
|
632
|
+
// controller short-circuits, so `redirectToAuthorize` never runs for the
|
|
633
|
+
// `oxycommons://` payload.
|
|
634
|
+
canOpenApp: isWebBrowser() ? undefined : (url) => Linking.canOpenURL(url),
|
|
639
635
|
});
|
|
640
636
|
}
|
|
641
637
|
const accountDialogController = accountDialogControllerRef.current;
|
|
@@ -782,7 +778,10 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
782
778
|
if (document.visibilityState !== 'visible') return;
|
|
783
779
|
const reconcile = async (): Promise<void> => {
|
|
784
780
|
if (!oxyServices.getAccessToken() && sessionClientHost.getDeviceCredential()) {
|
|
785
|
-
|
|
781
|
+
// Route through the ONE shared single-flight the scheduler/preflight/401
|
|
782
|
+
// use — never a private mint lane — so a tab-focus reconcile can't
|
|
783
|
+
// double-rotate the device secret against them.
|
|
784
|
+
await oxyServices.httpService.refreshAccessToken('preflight');
|
|
786
785
|
}
|
|
787
786
|
if (!oxyServices.getAccessToken() && !sessionClientHost.getDeviceCredential()) {
|
|
788
787
|
return;
|
|
@@ -794,7 +793,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
794
793
|
};
|
|
795
794
|
document.addEventListener('visibilitychange', onVisibility);
|
|
796
795
|
return () => document.removeEventListener('visibilitychange', onVisibility);
|
|
797
|
-
}, [oxyServices, sessionClient, sessionClientHost,
|
|
796
|
+
}, [oxyServices, sessionClient, sessionClientHost, syncFromClient]);
|
|
798
797
|
|
|
799
798
|
// Exposed `refreshSessions`: re-bootstrap the server-authoritative device
|
|
800
799
|
// state and reproject — the manual counterpart to the realtime socket.
|
|
@@ -898,6 +897,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
898
897
|
storageKeyPrefix,
|
|
899
898
|
clientId,
|
|
900
899
|
oxyServices,
|
|
900
|
+
sessionClient,
|
|
901
901
|
useFollow: useFollowHook,
|
|
902
902
|
showBottomSheet: showBottomSheetForContext,
|
|
903
903
|
openAvatarPicker,
|
|
@@ -947,6 +947,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
947
947
|
storageKeyPrefix,
|
|
948
948
|
clientId,
|
|
949
949
|
oxyServices,
|
|
950
|
+
sessionClient,
|
|
950
951
|
useFollowHook,
|
|
951
952
|
showBottomSheetForContext,
|
|
952
953
|
openAvatarPicker,
|
|
@@ -1016,6 +1017,7 @@ const LOADING_STATE: OxyContextState = {
|
|
|
1016
1017
|
storageKeyPrefix: 'oxy_session',
|
|
1017
1018
|
clientId: null,
|
|
1018
1019
|
oxyServices: LOADING_STATE_OXY_SERVICES,
|
|
1020
|
+
sessionClient: null,
|
|
1019
1021
|
openAvatarPicker: () => {},
|
|
1020
1022
|
accountDialogController: null,
|
|
1021
1023
|
isAccountDialogOpen: false,
|