@oxyhq/services 10.4.0 → 11.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.
- package/lib/commonjs/ui/components/AnotherDeviceQR.js +121 -0
- package/lib/commonjs/ui/components/AnotherDeviceQR.js.map +1 -0
- package/lib/commonjs/ui/components/SignInModal.js +145 -356
- package/lib/commonjs/ui/components/SignInModal.js.map +1 -1
- package/lib/commonjs/ui/hooks/useOxyAuthSession.js +458 -0
- package/lib/commonjs/ui/hooks/useOxyAuthSession.js.map +1 -0
- package/lib/commonjs/ui/screens/OxyAuthScreen.js +62 -460
- package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/module/ui/components/AnotherDeviceQR.js +116 -0
- package/lib/module/ui/components/AnotherDeviceQR.js.map +1 -0
- package/lib/module/ui/components/SignInModal.js +149 -358
- package/lib/module/ui/components/SignInModal.js.map +1 -1
- package/lib/module/ui/hooks/useOxyAuthSession.js +452 -0
- package/lib/module/ui/hooks/useOxyAuthSession.js.map +1 -0
- package/lib/module/ui/screens/OxyAuthScreen.js +62 -460
- package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts +24 -0
- package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/SignInModal.d.ts +10 -5
- package/lib/typescript/commonjs/ui/components/SignInModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts +83 -0
- package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts +12 -8
- package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts +24 -0
- package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/SignInModal.d.ts +10 -5
- package/lib/typescript/module/ui/components/SignInModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts +83 -0
- package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +12 -8
- package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +1 -1
- package/package.json +21 -33
- package/src/ui/components/AnotherDeviceQR.tsx +111 -0
- package/src/ui/components/SignInModal.tsx +142 -381
- package/src/ui/hooks/useOxyAuthSession.ts +556 -0
- package/src/ui/screens/OxyAuthScreen.tsx +61 -506
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnotherDeviceQR — the collapsed "Sign in on another device" disclosure shared
|
|
3
|
+
* by both sign-in containers (`SignInModal` on web, `OxyAuthScreen` on native).
|
|
4
|
+
*
|
|
5
|
+
* The QR code is always DEMOTED below the platform-primary "Continue with Oxy"
|
|
6
|
+
* action: you cannot scan your own screen, so the QR is only useful for handing
|
|
7
|
+
* sign-in to a SECOND device (scan with the Oxy Accounts app there). It lives
|
|
8
|
+
* inside a tap-to-expand disclosure so it never competes with the primary CTA.
|
|
9
|
+
*
|
|
10
|
+
* The QR plate stays white intentionally — high contrast is required for
|
|
11
|
+
* reliable scanning regardless of the app theme.
|
|
12
|
+
*/
|
|
13
|
+
import type React from 'react';
|
|
14
|
+
export interface AnotherDeviceQRProps {
|
|
15
|
+
/** The QR payload (`oxyauth://<token>`). Empty string renders nothing. */
|
|
16
|
+
qrData: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Collapsed disclosure that reveals a high-contrast QR for signing in on a
|
|
20
|
+
* second device with the Oxy Accounts app.
|
|
21
|
+
*/
|
|
22
|
+
declare const AnotherDeviceQR: React.FC<AnotherDeviceQRProps>;
|
|
23
|
+
export default AnotherDeviceQR;
|
|
24
|
+
//# sourceMappingURL=AnotherDeviceQR.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnotherDeviceQR.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/AnotherDeviceQR.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD;;;GAGG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA0CnD,CAAC;AAqCF,eAAe,eAAe,CAAC"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SignInModal -
|
|
2
|
+
* SignInModal - Web-first centered sign-in modal (Continue with Oxy)
|
|
3
3
|
*
|
|
4
|
-
* A semi-transparent full-screen modal
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* A semi-transparent full-screen modal whose primary action is the one-tap
|
|
5
|
+
* "Continue with Oxy" approval flow. The QR code is demoted to a collapsed
|
|
6
|
+
* "Sign in on another device" disclosure (you can't scan your own screen).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* ALL of the auth-session machinery (session-token creation, QR data, socket +
|
|
9
|
+
* polling, waiting/error/retry state, the open-auth handler, deep-link return,
|
|
10
|
+
* and cleanup) lives in the shared `useOxyAuthSession` hook, which the native
|
|
11
|
+
* `OxyAuthScreen` also consumes — neither container re-implements the transport.
|
|
12
|
+
*
|
|
13
|
+
* Animates with a fade + scale effect.
|
|
9
14
|
*/
|
|
10
15
|
import type React from 'react';
|
|
11
16
|
export declare const showSignInModal: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignInModal.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/SignInModal.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SignInModal.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/SignInModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuB/B,eAAO,MAAM,eAAe,YAI3B,CAAC;AAEF,eAAO,MAAM,eAAe,YAI3B,CAAC;AAEF,eAAO,MAAM,oBAAoB,eAAqB,CAAC;AAEvD,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB,GAAI,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAGxF,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EA8BxB,CAAC;AAgPF,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAccountMutations.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/mutations/useAccountMutations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,IAAI,EACJ,eAAe,EAChB,MAAM,aAAa,CAAC;AAerB;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;aAsOY,CAAC;YAClC,CAAL;;aAEK,CAAN;YAAkC,CAAC;;;;;;;;;;;;;;;;;;;UAoBzB,CAAV;mBAEM,CAAD;aAGc,CAAC;aAEH,CAAC;;;UACc,CAAC;mBAC7B,CAAN;aAAmC,CAAC;aACX,CAAC;;;;;;;;;EAzKzB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe;SAMQ,MAAM;WAAS,MAAM;WAAS,MAAM;WAAS,MAAM;;;EA4EtF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,UAAU,8BAA8B;IACtC,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC;;;;OAIG;IACH,WAAW,EAAE,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB;sBAoFf,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useAccountMutations.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/mutations/useAccountMutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useOxyAuthSession — the single shared engine for the cross-app device-flow
|
|
3
|
+
* sign-in ("Sign in with Oxy") used by BOTH containers:
|
|
4
|
+
*
|
|
5
|
+
* - `SignInModal` (web centered modal)
|
|
6
|
+
* - `OxyAuthScreen` (native bottom sheet)
|
|
7
|
+
*
|
|
8
|
+
* Before this hook existed, those two files each re-implemented ~90% of the
|
|
9
|
+
* same auth-session machinery (session-token creation, QR data, socket.io
|
|
10
|
+
* `/auth-session` subscription, the HTTP polling fallback, waiting/error/retry
|
|
11
|
+
* state, the open-auth handler, and cleanup) — and they had drifted (notably a
|
|
12
|
+
* weaker `Math.random()` session token on native vs the crypto-secure one on
|
|
13
|
+
* web). This hook owns ALL of it ONCE, with a clean typed surface, so the
|
|
14
|
+
* containers only own their layout. The transport is functionally identical to
|
|
15
|
+
* the previous implementations — this is a structural de-duplication, not a
|
|
16
|
+
* behavior change.
|
|
17
|
+
*
|
|
18
|
+
* The native-only deep-link return path (`Linking` redirect handling) lives
|
|
19
|
+
* HERE, gated to native via `Platform.OS`, so the web container never carries
|
|
20
|
+
* native-only code while the two paths still cannot drift.
|
|
21
|
+
*/
|
|
22
|
+
import type { OxyServices, User } from '@oxyhq/core';
|
|
23
|
+
/**
|
|
24
|
+
* Default destination for the "Create an Oxy account" / "Get Oxy Accounts"
|
|
25
|
+
* link, shared by both containers. Reused as-is from the original native
|
|
26
|
+
* `OxyAuthScreen` so no new route is invented.
|
|
27
|
+
*/
|
|
28
|
+
export declare const OXY_ACCOUNTS_WEB_URL = "https://accounts.oxy.so";
|
|
29
|
+
/** Default central Oxy auth web origin used when no override can be resolved. */
|
|
30
|
+
export declare const OXY_AUTH_WEB_URL = "https://auth.oxy.so";
|
|
31
|
+
/** Auth session expiration (5 minutes). */
|
|
32
|
+
export declare const AUTH_SESSION_EXPIRY_MS: number;
|
|
33
|
+
/** Polling interval (fallback if the socket fails) in milliseconds. */
|
|
34
|
+
export declare const POLLING_INTERVAL_MS = 3000;
|
|
35
|
+
/** The active device-flow session this client created and is waiting on. */
|
|
36
|
+
export interface AuthSession {
|
|
37
|
+
/** The secret high-entropy token that IS the device-flow credential. */
|
|
38
|
+
sessionToken: string;
|
|
39
|
+
/** Epoch ms after which the server rejects this session. */
|
|
40
|
+
expiresAt: number;
|
|
41
|
+
}
|
|
42
|
+
export interface UseOxyAuthSessionOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Called after a fully completed sign-in (bearer claimed, session hydrated).
|
|
45
|
+
* The web modal closes itself here; the native screen forwards the user to
|
|
46
|
+
* its `onAuthenticated` prop. The hook itself stays presentation-agnostic.
|
|
47
|
+
*/
|
|
48
|
+
onSignedIn?: (user: User) => void;
|
|
49
|
+
}
|
|
50
|
+
export interface UseOxyAuthSessionResult {
|
|
51
|
+
/** The active device-flow session, or `null` before/while it is created. */
|
|
52
|
+
authSession: AuthSession | null;
|
|
53
|
+
/** The QR payload string (`oxyauth://<token>`), or `''` when no session. */
|
|
54
|
+
qrData: string;
|
|
55
|
+
/** `true` while the session is being created (initial spinner). */
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
/** A user-facing error message, or `null`. Drives the retry UI. */
|
|
58
|
+
error: string | null;
|
|
59
|
+
/** `true` once a session exists and we are awaiting authorization. */
|
|
60
|
+
isWaiting: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Open the central Oxy auth approval surface for THIS device-flow session.
|
|
63
|
+
* On web this opens a centered approval popup; on native it opens the system
|
|
64
|
+
* browser (carrying a `redirect_uri` so the deep-link return path can fire).
|
|
65
|
+
* This is the action behind the platform-primary "Continue with Oxy" button.
|
|
66
|
+
*/
|
|
67
|
+
openAuthApproval: () => Promise<void>;
|
|
68
|
+
/** Tear down the current session and create a fresh one (the retry action). */
|
|
69
|
+
retry: () => void;
|
|
70
|
+
/** Disconnect the socket and stop polling. Idempotent. */
|
|
71
|
+
cleanup: () => void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Owns the full device-flow auth-session lifecycle for one mounted sign-in
|
|
75
|
+
* surface. Both `SignInModal` and `OxyAuthScreen` consume this; neither
|
|
76
|
+
* re-implements the socket / polling / deep-link transport.
|
|
77
|
+
*
|
|
78
|
+
* Subscriptions (socket connect/disconnect, the poll interval, the native
|
|
79
|
+
* deep-link listener, and unmount cleanup) are the legitimate `useEffect` use
|
|
80
|
+
* WITH cleanup. No effect here computes derived UI state.
|
|
81
|
+
*/
|
|
82
|
+
export declare function useOxyAuthSession(oxyServices: OxyServices, clientId: string | null, switchSession: ((sessionId: string) => Promise<User>) | undefined, options?: UseOxyAuthSessionOptions): UseOxyAuthSessionResult;
|
|
83
|
+
//# sourceMappingURL=useOxyAuthSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOxyAuthSession.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useOxyAuthSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMrD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAEtD,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,4EAA4E;IAC5E,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAoFD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,aAAa,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,EACjE,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CA0WzB"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OxyAuthScreen - Sign in with Oxy
|
|
2
|
+
* OxyAuthScreen - Sign in with Oxy (native bottom-sheet container)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Used by OTHER apps in the Oxy ecosystem to authenticate users. The primary
|
|
5
|
+
* action is the one-tap "Continue with Oxy" approval flow (opens the Oxy Auth
|
|
6
|
+
* web flow with a deep-link `redirect_uri` so the app→app return path can
|
|
7
|
+
* complete the sign-in). The QR code is demoted to a collapsed "Sign in on
|
|
8
|
+
* another device" disclosure — you can't scan your own screen.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* ALL of the auth-session machinery (session-token creation, QR data, socket +
|
|
11
|
+
* polling, the native deep-link return path, waiting/error/retry state, the
|
|
12
|
+
* open-auth handler, and cleanup) lives in the shared `useOxyAuthSession` hook,
|
|
13
|
+
* which the web `SignInModal` also consumes — neither container re-implements
|
|
14
|
+
* the transport. The Oxy Accounts app is where users manage their cryptographic
|
|
15
|
+
* identity; this screen should NOT be used within the Accounts app itself.
|
|
12
16
|
*/
|
|
13
17
|
import type React from 'react';
|
|
14
18
|
import type { BaseScreenProps } from '../types/navigation';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyAuthScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/OxyAuthScreen.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"OxyAuthScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/OxyAuthScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAyF5C,CAAC;AA8EF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnotherDeviceQR — the collapsed "Sign in on another device" disclosure shared
|
|
3
|
+
* by both sign-in containers (`SignInModal` on web, `OxyAuthScreen` on native).
|
|
4
|
+
*
|
|
5
|
+
* The QR code is always DEMOTED below the platform-primary "Continue with Oxy"
|
|
6
|
+
* action: you cannot scan your own screen, so the QR is only useful for handing
|
|
7
|
+
* sign-in to a SECOND device (scan with the Oxy Accounts app there). It lives
|
|
8
|
+
* inside a tap-to-expand disclosure so it never competes with the primary CTA.
|
|
9
|
+
*
|
|
10
|
+
* The QR plate stays white intentionally — high contrast is required for
|
|
11
|
+
* reliable scanning regardless of the app theme.
|
|
12
|
+
*/
|
|
13
|
+
import type React from 'react';
|
|
14
|
+
export interface AnotherDeviceQRProps {
|
|
15
|
+
/** The QR payload (`oxyauth://<token>`). Empty string renders nothing. */
|
|
16
|
+
qrData: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Collapsed disclosure that reveals a high-contrast QR for signing in on a
|
|
20
|
+
* second device with the Oxy Accounts app.
|
|
21
|
+
*/
|
|
22
|
+
declare const AnotherDeviceQR: React.FC<AnotherDeviceQRProps>;
|
|
23
|
+
export default AnotherDeviceQR;
|
|
24
|
+
//# sourceMappingURL=AnotherDeviceQR.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnotherDeviceQR.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/AnotherDeviceQR.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD;;;GAGG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA0CnD,CAAC;AAqCF,eAAe,eAAe,CAAC"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SignInModal -
|
|
2
|
+
* SignInModal - Web-first centered sign-in modal (Continue with Oxy)
|
|
3
3
|
*
|
|
4
|
-
* A semi-transparent full-screen modal
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* A semi-transparent full-screen modal whose primary action is the one-tap
|
|
5
|
+
* "Continue with Oxy" approval flow. The QR code is demoted to a collapsed
|
|
6
|
+
* "Sign in on another device" disclosure (you can't scan your own screen).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* ALL of the auth-session machinery (session-token creation, QR data, socket +
|
|
9
|
+
* polling, waiting/error/retry state, the open-auth handler, deep-link return,
|
|
10
|
+
* and cleanup) lives in the shared `useOxyAuthSession` hook, which the native
|
|
11
|
+
* `OxyAuthScreen` also consumes — neither container re-implements the transport.
|
|
12
|
+
*
|
|
13
|
+
* Animates with a fade + scale effect.
|
|
9
14
|
*/
|
|
10
15
|
import type React from 'react';
|
|
11
16
|
export declare const showSignInModal: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignInModal.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/SignInModal.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SignInModal.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/SignInModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuB/B,eAAO,MAAM,eAAe,YAI3B,CAAC;AAEF,eAAO,MAAM,eAAe,YAI3B,CAAC;AAEF,eAAO,MAAM,oBAAoB,eAAqB,CAAC;AAEvD,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB,GAAI,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAGxF,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EA8BxB,CAAC;AAgPF,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAccountMutations.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/mutations/useAccountMutations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,IAAI,EACJ,eAAe,EAChB,MAAM,aAAa,CAAC;AAerB;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;aAsOY,CAAC;YAClC,CAAL;;aAEK,CAAN;YAAkC,CAAC;;;;;;;;;;;;;;;;;;;UAoBzB,CAAV;mBAEM,CAAD;aAGc,CAAC;aAEH,CAAC;;;UACc,CAAC;mBAC7B,CAAN;aAAmC,CAAC;aACX,CAAC;;;;;;;;;EAzKzB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe;SAMQ,MAAM;WAAS,MAAM;WAAS,MAAM;WAAS,MAAM;;;EA4EtF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,UAAU,8BAA8B;IACtC,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC;;;;OAIG;IACH,WAAW,EAAE,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB;sBAoFf,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;sBARnD,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;2BAQpB,OAAO,CAAC,eAAe,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useAccountMutations.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/mutations/useAccountMutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useOxyAuthSession — the single shared engine for the cross-app device-flow
|
|
3
|
+
* sign-in ("Sign in with Oxy") used by BOTH containers:
|
|
4
|
+
*
|
|
5
|
+
* - `SignInModal` (web centered modal)
|
|
6
|
+
* - `OxyAuthScreen` (native bottom sheet)
|
|
7
|
+
*
|
|
8
|
+
* Before this hook existed, those two files each re-implemented ~90% of the
|
|
9
|
+
* same auth-session machinery (session-token creation, QR data, socket.io
|
|
10
|
+
* `/auth-session` subscription, the HTTP polling fallback, waiting/error/retry
|
|
11
|
+
* state, the open-auth handler, and cleanup) — and they had drifted (notably a
|
|
12
|
+
* weaker `Math.random()` session token on native vs the crypto-secure one on
|
|
13
|
+
* web). This hook owns ALL of it ONCE, with a clean typed surface, so the
|
|
14
|
+
* containers only own their layout. The transport is functionally identical to
|
|
15
|
+
* the previous implementations — this is a structural de-duplication, not a
|
|
16
|
+
* behavior change.
|
|
17
|
+
*
|
|
18
|
+
* The native-only deep-link return path (`Linking` redirect handling) lives
|
|
19
|
+
* HERE, gated to native via `Platform.OS`, so the web container never carries
|
|
20
|
+
* native-only code while the two paths still cannot drift.
|
|
21
|
+
*/
|
|
22
|
+
import type { OxyServices, User } from '@oxyhq/core';
|
|
23
|
+
/**
|
|
24
|
+
* Default destination for the "Create an Oxy account" / "Get Oxy Accounts"
|
|
25
|
+
* link, shared by both containers. Reused as-is from the original native
|
|
26
|
+
* `OxyAuthScreen` so no new route is invented.
|
|
27
|
+
*/
|
|
28
|
+
export declare const OXY_ACCOUNTS_WEB_URL = "https://accounts.oxy.so";
|
|
29
|
+
/** Default central Oxy auth web origin used when no override can be resolved. */
|
|
30
|
+
export declare const OXY_AUTH_WEB_URL = "https://auth.oxy.so";
|
|
31
|
+
/** Auth session expiration (5 minutes). */
|
|
32
|
+
export declare const AUTH_SESSION_EXPIRY_MS: number;
|
|
33
|
+
/** Polling interval (fallback if the socket fails) in milliseconds. */
|
|
34
|
+
export declare const POLLING_INTERVAL_MS = 3000;
|
|
35
|
+
/** The active device-flow session this client created and is waiting on. */
|
|
36
|
+
export interface AuthSession {
|
|
37
|
+
/** The secret high-entropy token that IS the device-flow credential. */
|
|
38
|
+
sessionToken: string;
|
|
39
|
+
/** Epoch ms after which the server rejects this session. */
|
|
40
|
+
expiresAt: number;
|
|
41
|
+
}
|
|
42
|
+
export interface UseOxyAuthSessionOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Called after a fully completed sign-in (bearer claimed, session hydrated).
|
|
45
|
+
* The web modal closes itself here; the native screen forwards the user to
|
|
46
|
+
* its `onAuthenticated` prop. The hook itself stays presentation-agnostic.
|
|
47
|
+
*/
|
|
48
|
+
onSignedIn?: (user: User) => void;
|
|
49
|
+
}
|
|
50
|
+
export interface UseOxyAuthSessionResult {
|
|
51
|
+
/** The active device-flow session, or `null` before/while it is created. */
|
|
52
|
+
authSession: AuthSession | null;
|
|
53
|
+
/** The QR payload string (`oxyauth://<token>`), or `''` when no session. */
|
|
54
|
+
qrData: string;
|
|
55
|
+
/** `true` while the session is being created (initial spinner). */
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
/** A user-facing error message, or `null`. Drives the retry UI. */
|
|
58
|
+
error: string | null;
|
|
59
|
+
/** `true` once a session exists and we are awaiting authorization. */
|
|
60
|
+
isWaiting: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Open the central Oxy auth approval surface for THIS device-flow session.
|
|
63
|
+
* On web this opens a centered approval popup; on native it opens the system
|
|
64
|
+
* browser (carrying a `redirect_uri` so the deep-link return path can fire).
|
|
65
|
+
* This is the action behind the platform-primary "Continue with Oxy" button.
|
|
66
|
+
*/
|
|
67
|
+
openAuthApproval: () => Promise<void>;
|
|
68
|
+
/** Tear down the current session and create a fresh one (the retry action). */
|
|
69
|
+
retry: () => void;
|
|
70
|
+
/** Disconnect the socket and stop polling. Idempotent. */
|
|
71
|
+
cleanup: () => void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Owns the full device-flow auth-session lifecycle for one mounted sign-in
|
|
75
|
+
* surface. Both `SignInModal` and `OxyAuthScreen` consume this; neither
|
|
76
|
+
* re-implements the socket / polling / deep-link transport.
|
|
77
|
+
*
|
|
78
|
+
* Subscriptions (socket connect/disconnect, the poll interval, the native
|
|
79
|
+
* deep-link listener, and unmount cleanup) are the legitimate `useEffect` use
|
|
80
|
+
* WITH cleanup. No effect here computes derived UI state.
|
|
81
|
+
*/
|
|
82
|
+
export declare function useOxyAuthSession(oxyServices: OxyServices, clientId: string | null, switchSession: ((sessionId: string) => Promise<User>) | undefined, options?: UseOxyAuthSessionOptions): UseOxyAuthSessionResult;
|
|
83
|
+
//# sourceMappingURL=useOxyAuthSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOxyAuthSession.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useOxyAuthSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMrD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAEtD,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,4EAA4E;IAC5E,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAoFD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,aAAa,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,EACjE,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CA0WzB"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OxyAuthScreen - Sign in with Oxy
|
|
2
|
+
* OxyAuthScreen - Sign in with Oxy (native bottom-sheet container)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Used by OTHER apps in the Oxy ecosystem to authenticate users. The primary
|
|
5
|
+
* action is the one-tap "Continue with Oxy" approval flow (opens the Oxy Auth
|
|
6
|
+
* web flow with a deep-link `redirect_uri` so the app→app return path can
|
|
7
|
+
* complete the sign-in). The QR code is demoted to a collapsed "Sign in on
|
|
8
|
+
* another device" disclosure — you can't scan your own screen.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* ALL of the auth-session machinery (session-token creation, QR data, socket +
|
|
11
|
+
* polling, the native deep-link return path, waiting/error/retry state, the
|
|
12
|
+
* open-auth handler, and cleanup) lives in the shared `useOxyAuthSession` hook,
|
|
13
|
+
* which the web `SignInModal` also consumes — neither container re-implements
|
|
14
|
+
* the transport. The Oxy Accounts app is where users manage their cryptographic
|
|
15
|
+
* identity; this screen should NOT be used within the Accounts app itself.
|
|
12
16
|
*/
|
|
13
17
|
import type React from 'react';
|
|
14
18
|
import type { BaseScreenProps } from '../types/navigation';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyAuthScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/OxyAuthScreen.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"OxyAuthScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/OxyAuthScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAyF5C,CAAC;AA8EF,eAAe,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
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",
|
|
@@ -106,29 +106,19 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"dependencies": {
|
|
109
|
-
"@
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
"@oxyhq/contracts": "^0.2.0"
|
|
110
|
+
},
|
|
111
|
+
"devDependencies": {
|
|
112
|
+
"nativewind": "5.0.0-preview.3",
|
|
113
|
+
"react-native-css": "^3.0.0",
|
|
114
|
+
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
112
115
|
"@types/react": "*",
|
|
113
116
|
"copyfiles": "^2.4.1",
|
|
114
|
-
"expo-blur": "~56.0.3",
|
|
115
|
-
"expo-checkbox": "~56.0.1",
|
|
116
|
-
"expo-crypto": "~56.0.3",
|
|
117
|
-
"expo-print": "~56.0.3",
|
|
118
|
-
"expo-secure-store": "~56.0.4",
|
|
119
|
-
"lottie-react-native": "^7.3.4",
|
|
120
117
|
"react-native-keyboard-controller": "1.21.6",
|
|
121
118
|
"react-native-qrcode-svg": "^6.3.0",
|
|
122
|
-
"react-native-url-polyfill": "^2.0.0",
|
|
123
119
|
"socket.io-client": "^4.8.1",
|
|
124
|
-
"sonner": "^2.0.4",
|
|
125
|
-
"sonner-native": "^0.20.0",
|
|
126
120
|
"typescript": "^5.9.2",
|
|
127
|
-
"zustand": "^5.0.9"
|
|
128
|
-
},
|
|
129
|
-
"devDependencies": {
|
|
130
|
-
"nativewind": "5.0.0-preview.3",
|
|
131
|
-
"react-native-css": "^3.0.0",
|
|
121
|
+
"zustand": "^5.0.9",
|
|
132
122
|
"@biomejs/biome": "^1.9.4",
|
|
133
123
|
"@commitlint/cli": "^17.6.5",
|
|
134
124
|
"@commitlint/config-conventional": "^17.6.5",
|
|
@@ -160,8 +150,9 @@
|
|
|
160
150
|
},
|
|
161
151
|
"peerDependencies": {
|
|
162
152
|
"@expo/vector-icons": "^15.0.3",
|
|
163
|
-
"@oxyhq/bloom": ">=0.
|
|
164
|
-
"@oxyhq/core": "^3.
|
|
153
|
+
"@oxyhq/bloom": ">=0.16.0",
|
|
154
|
+
"@oxyhq/core": "^3.8.0",
|
|
155
|
+
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
165
156
|
"@react-native-community/netinfo": "^11.4.1",
|
|
166
157
|
"@tanstack/query-async-storage-persister": "^5.100",
|
|
167
158
|
"@tanstack/query-sync-storage-persister": "^5.100",
|
|
@@ -172,17 +163,21 @@
|
|
|
172
163
|
"expo": ">=56.0.0",
|
|
173
164
|
"expo-document-picker": "~56.0.4",
|
|
174
165
|
"expo-file-system": "~56.0.7",
|
|
175
|
-
"expo-font": "
|
|
176
|
-
"expo-image": "
|
|
166
|
+
"expo-font": ">=13.0.0",
|
|
167
|
+
"expo-image": ">=2.0.0",
|
|
177
168
|
"expo-image-manipulator": "~56.0.3",
|
|
178
169
|
"expo-linear-gradient": "~56.0.4",
|
|
179
170
|
"react": ">=18.0.0",
|
|
180
171
|
"react-native": ">=0.85.0",
|
|
181
172
|
"react-native-gesture-handler": "~2.31.2",
|
|
173
|
+
"react-native-keyboard-controller": ">=1.21.0",
|
|
174
|
+
"react-native-qrcode-svg": "^6.3.0",
|
|
182
175
|
"react-native-reanimated": ">=4.3.0",
|
|
183
176
|
"react-native-safe-area-context": "~5.7.0",
|
|
184
177
|
"react-native-svg": ">=15.15.0",
|
|
185
|
-
"
|
|
178
|
+
"socket.io-client": "^4.8.0",
|
|
179
|
+
"zustand": "^5.0.0",
|
|
180
|
+
"nativewind": ">=5.0.0"
|
|
186
181
|
},
|
|
187
182
|
"peerDependenciesMeta": {
|
|
188
183
|
"nativewind": {
|
|
@@ -197,16 +192,13 @@
|
|
|
197
192
|
"@types/react": {
|
|
198
193
|
"optional": true
|
|
199
194
|
},
|
|
200
|
-
"react-native-
|
|
201
|
-
"optional": true
|
|
202
|
-
},
|
|
203
|
-
"expo": {
|
|
195
|
+
"react-native-keyboard-controller": {
|
|
204
196
|
"optional": true
|
|
205
197
|
},
|
|
206
|
-
"
|
|
198
|
+
"react-native-qrcode-svg": {
|
|
207
199
|
"optional": true
|
|
208
200
|
},
|
|
209
|
-
"expo
|
|
201
|
+
"expo": {
|
|
210
202
|
"optional": true
|
|
211
203
|
},
|
|
212
204
|
"expo-linear-gradient": {
|
|
@@ -240,9 +232,5 @@
|
|
|
240
232
|
],
|
|
241
233
|
"typescript"
|
|
242
234
|
]
|
|
243
|
-
},
|
|
244
|
-
"overrides": {
|
|
245
|
-
"react-native-gesture-handler": "~2.31.2",
|
|
246
|
-
"react-native-reanimated": "4.3.1"
|
|
247
235
|
}
|
|
248
236
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnotherDeviceQR — the collapsed "Sign in on another device" disclosure shared
|
|
3
|
+
* by both sign-in containers (`SignInModal` on web, `OxyAuthScreen` on native).
|
|
4
|
+
*
|
|
5
|
+
* The QR code is always DEMOTED below the platform-primary "Continue with Oxy"
|
|
6
|
+
* action: you cannot scan your own screen, so the QR is only useful for handing
|
|
7
|
+
* sign-in to a SECOND device (scan with the Oxy Accounts app there). It lives
|
|
8
|
+
* inside a tap-to-expand disclosure so it never competes with the primary CTA.
|
|
9
|
+
*
|
|
10
|
+
* The QR plate stays white intentionally — high contrast is required for
|
|
11
|
+
* reliable scanning regardless of the app theme.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type React from 'react';
|
|
15
|
+
import { useState, useCallback } from 'react';
|
|
16
|
+
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
|
17
|
+
import QRCode from 'react-native-qrcode-svg';
|
|
18
|
+
import { useTheme } from '@oxyhq/bloom/theme';
|
|
19
|
+
|
|
20
|
+
export interface AnotherDeviceQRProps {
|
|
21
|
+
/** The QR payload (`oxyauth://<token>`). Empty string renders nothing. */
|
|
22
|
+
qrData: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Size, in px, of the rendered QR symbol. */
|
|
26
|
+
const QR_SIZE = 200;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Collapsed disclosure that reveals a high-contrast QR for signing in on a
|
|
30
|
+
* second device with the Oxy Accounts app.
|
|
31
|
+
*/
|
|
32
|
+
const AnotherDeviceQR: React.FC<AnotherDeviceQRProps> = ({ qrData }) => {
|
|
33
|
+
const { colors } = useTheme();
|
|
34
|
+
const [expanded, setExpanded] = useState(false);
|
|
35
|
+
|
|
36
|
+
const toggle = useCallback(() => {
|
|
37
|
+
setExpanded((prev) => !prev);
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
if (!qrData) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View style={styles.container}>
|
|
46
|
+
<TouchableOpacity
|
|
47
|
+
style={styles.toggle}
|
|
48
|
+
onPress={toggle}
|
|
49
|
+
accessibilityRole="button"
|
|
50
|
+
accessibilityState={{ expanded }}
|
|
51
|
+
accessibilityHint="Reveals a QR code to sign in using the Oxy Accounts app on another device"
|
|
52
|
+
>
|
|
53
|
+
<Text style={styles.toggleText} className="text-muted-foreground">
|
|
54
|
+
Sign in on another device
|
|
55
|
+
</Text>
|
|
56
|
+
<Text style={styles.chevron} className="text-muted-foreground">
|
|
57
|
+
{expanded ? '✕' : '›'}
|
|
58
|
+
</Text>
|
|
59
|
+
</TouchableOpacity>
|
|
60
|
+
|
|
61
|
+
{expanded && (
|
|
62
|
+
<View style={styles.body}>
|
|
63
|
+
{/* The QR plate is intentionally white for scan reliability. */}
|
|
64
|
+
<View style={[styles.qrPlate, { backgroundColor: '#FFFFFF' }]}>
|
|
65
|
+
<QRCode value={qrData} size={QR_SIZE} backgroundColor="#FFFFFF" color="#000000" />
|
|
66
|
+
</View>
|
|
67
|
+
<Text style={[styles.hint, { color: colors.textSecondary }]}>
|
|
68
|
+
Scan with the Oxy Accounts app
|
|
69
|
+
</Text>
|
|
70
|
+
</View>
|
|
71
|
+
)}
|
|
72
|
+
</View>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const styles = StyleSheet.create({
|
|
77
|
+
container: {
|
|
78
|
+
width: '100%',
|
|
79
|
+
alignItems: 'center',
|
|
80
|
+
},
|
|
81
|
+
toggle: {
|
|
82
|
+
flexDirection: 'row',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
justifyContent: 'center',
|
|
85
|
+
paddingVertical: 12,
|
|
86
|
+
paddingHorizontal: 8,
|
|
87
|
+
},
|
|
88
|
+
toggleText: {
|
|
89
|
+
fontSize: 14,
|
|
90
|
+
fontWeight: '600',
|
|
91
|
+
},
|
|
92
|
+
chevron: {
|
|
93
|
+
fontSize: 16,
|
|
94
|
+
marginLeft: 8,
|
|
95
|
+
},
|
|
96
|
+
body: {
|
|
97
|
+
alignItems: 'center',
|
|
98
|
+
marginTop: 8,
|
|
99
|
+
},
|
|
100
|
+
qrPlate: {
|
|
101
|
+
padding: 16,
|
|
102
|
+
borderRadius: 16,
|
|
103
|
+
},
|
|
104
|
+
hint: {
|
|
105
|
+
marginTop: 12,
|
|
106
|
+
fontSize: 12,
|
|
107
|
+
textAlign: 'center',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export default AnotherDeviceQR;
|