@oxyhq/services 27.1.3 → 29.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/LICENSE +202 -661
- package/NOTICE +16 -0
- package/README.md +67 -2
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt +178 -0
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionProvider.kt +99 -0
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionStore.kt +115 -0
- package/expo-module.config.json +1 -0
- package/lib/commonjs/index.js +78 -16
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/boot/runProviderColdBoot.js +7 -0
- package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/commonjs/ui/client.js +12 -7
- package/lib/commonjs/ui/client.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +10 -27
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +132 -44
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +4 -2
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/SurfaceScreen.js +31 -3
- package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +209 -84
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +25 -7
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/primitives.js +35 -22
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/signInProgress.js +5 -0
- package/lib/commonjs/ui/components/authChooser/signInProgress.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/types.js +11 -0
- package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +257 -306
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +27 -37
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/oxyContextHelpers.js +0 -29
- package/lib/commonjs/ui/context/oxyContextHelpers.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +6 -17
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +42 -0
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -0
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +0 -19
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +57 -0
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -0
- package/lib/commonjs/ui/hooks/useI18n.js +22 -3
- package/lib/commonjs/ui/hooks/useI18n.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +46 -153
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/index.js +12 -7
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +85 -73
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/navigation/surfaces.js +8 -7
- package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
- package/lib/commonjs/ui/runtime/createOxyRuntime.js +433 -0
- package/lib/commonjs/ui/runtime/createOxyRuntime.js.map +1 -0
- package/lib/commonjs/ui/runtime/index.js +63 -0
- package/lib/commonjs/ui/runtime/index.js.map +1 -0
- package/lib/commonjs/ui/runtime/runtimeContext.js +83 -0
- package/lib/commonjs/ui/runtime/runtimeContext.js.map +1 -0
- package/lib/commonjs/ui/runtime/types.js +6 -0
- package/lib/commonjs/ui/runtime/types.js.map +1 -0
- package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js +57 -0
- package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountMembersScreen.js +3 -4
- package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/CreateAccountScreen.js +3 -12
- package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +6 -5
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +4 -4
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js +4 -2
- package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/server.js +1 -2
- package/lib/commonjs/ui/server.js.map +1 -1
- package/lib/commonjs/ui/session/authStore.js +45 -9
- package/lib/commonjs/ui/session/authStore.js.map +1 -1
- package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js +306 -0
- package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +154 -55
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/stores/followTargetStore.js +27 -0
- package/lib/commonjs/ui/stores/followTargetStore.js.map +1 -1
- package/lib/commonjs/ui/utils/avatarUtils.js +2 -36
- package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
- package/lib/module/index.js +20 -9
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/boot/runProviderColdBoot.js +7 -0
- package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/module/ui/client.js +1 -2
- package/lib/module/ui/client.js.map +1 -1
- package/lib/module/ui/components/OxyAccountDialogScreen.js +10 -27
- package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +134 -44
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +5 -3
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/SurfaceScreen.js +33 -5
- package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/module/ui/components/authChooser/AccountsMenuView.js +210 -85
- package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/module/ui/components/authChooser/SignInEntryView.js +25 -7
- package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -1
- package/lib/module/ui/components/authChooser/primitives.js +35 -22
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/module/ui/components/authChooser/signInProgress.js +5 -0
- package/lib/module/ui/components/authChooser/signInProgress.js.map +1 -1
- package/lib/module/ui/components/authChooser/types.js +11 -0
- package/lib/module/ui/components/authChooser/types.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +251 -303
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +27 -37
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/oxyContextHelpers.js +0 -28
- package/lib/module/ui/context/oxyContextHelpers.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +6 -17
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/accountDialogSnapshot.js +38 -0
- package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -0
- package/lib/module/ui/hooks/mutations/useAccountMutations.js +0 -19
- package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/module/ui/hooks/useDeviceSwitcher.js +53 -0
- package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -0
- package/lib/module/ui/hooks/useI18n.js +24 -4
- package/lib/module/ui/hooks/useI18n.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +47 -155
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/index.js +1 -2
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +84 -72
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/navigation/surfaces.js +6 -6
- package/lib/module/ui/navigation/surfaces.js.map +1 -1
- package/lib/module/ui/runtime/createOxyRuntime.js +430 -0
- package/lib/module/ui/runtime/createOxyRuntime.js.map +1 -0
- package/lib/module/ui/runtime/index.js +15 -0
- package/lib/module/ui/runtime/index.js.map +1 -0
- package/lib/module/ui/runtime/runtimeContext.js +75 -0
- package/lib/module/ui/runtime/runtimeContext.js.map +1 -0
- package/lib/module/ui/runtime/types.js +4 -0
- package/lib/module/ui/runtime/types.js.map +1 -0
- package/lib/module/ui/runtime/useRuntimeSnapshot.js +52 -0
- package/lib/module/ui/runtime/useRuntimeSnapshot.js.map +1 -0
- package/lib/module/ui/screens/AccountMembersScreen.js +4 -5
- package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
- package/lib/module/ui/screens/CreateAccountScreen.js +4 -13
- package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js +6 -5
- package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +5 -5
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustRulesScreen.js +4 -2
- package/lib/module/ui/screens/trust/TrustRulesScreen.js.map +1 -1
- package/lib/module/ui/server.js +0 -1
- package/lib/module/ui/server.js.map +1 -1
- package/lib/module/ui/session/authStore.js +46 -11
- package/lib/module/ui/session/authStore.js.map +1 -1
- package/lib/module/ui/session/sharedDeviceCredentialStore.js +302 -0
- package/lib/module/ui/session/sharedDeviceCredentialStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +154 -55
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/stores/followTargetStore.js +25 -0
- package/lib/module/ui/stores/followTargetStore.js.map +1 -1
- package/lib/module/ui/utils/avatarUtils.js +2 -35
- package/lib/module/ui/utils/avatarUtils.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +6 -4
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/client.d.ts +1 -2
- package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +3 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +18 -6
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +33 -1
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +35 -4
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +8 -12
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts +0 -2
- package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +9 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -3
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +15 -0
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts +49 -0
- package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts +13 -0
- package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +23 -18
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +1 -2
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts +15 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts +144 -0
- package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/index.d.ts +16 -0
- package/lib/typescript/commonjs/ui/runtime/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts +43 -0
- package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/types.d.ts +89 -0
- package/lib/typescript/commonjs/ui/runtime/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
- package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/AccountMembersScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/server.d.ts +0 -1
- package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/authStore.d.ts +60 -9
- package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
- package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/stores/authStore.d.ts +49 -5
- package/lib/typescript/commonjs/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/stores/followTargetStore.d.ts +8 -1
- package/lib/typescript/commonjs/ui/stores/followTargetStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +26 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts +2 -10
- package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +6 -4
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +1 -2
- package/lib/typescript/module/ui/client.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +3 -1
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +18 -6
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/types.d.ts +33 -1
- package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts +35 -4
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +8 -12
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts +0 -2
- package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +9 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -3
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +15 -0
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts +49 -0
- package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
- package/lib/typescript/module/ui/hooks/useI18n.d.ts +13 -0
- package/lib/typescript/module/ui/hooks/useI18n.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +23 -18
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +1 -2
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts +15 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
- package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts +144 -0
- package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/index.d.ts +16 -0
- package/lib/typescript/module/ui/runtime/index.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/runtimeContext.d.ts +43 -0
- package/lib/typescript/module/ui/runtime/runtimeContext.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/types.d.ts +89 -0
- package/lib/typescript/module/ui/runtime/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
- package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/server.d.ts +0 -1
- package/lib/typescript/module/ui/server.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/authStore.d.ts +60 -9
- package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
- package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
- package/lib/typescript/module/ui/stores/authStore.d.ts +49 -5
- package/lib/typescript/module/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/stores/followTargetStore.d.ts +8 -1
- package/lib/typescript/module/ui/stores/followTargetStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +26 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/avatarUtils.d.ts +2 -10
- package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
- package/package.json +8 -8
- package/plugins/withSharedDeviceSessionProvider.js +102 -0
- package/plugins/withSharedDeviceSessionReader.js +57 -0
- package/src/__tests__/esmSourcePurity.test.ts +61 -0
- package/src/index.ts +36 -9
- package/src/ui/boot/runProviderColdBoot.ts +7 -0
- package/src/ui/client.ts +1 -2
- package/src/ui/components/OxyAccountDialogScreen.tsx +10 -29
- package/src/ui/components/OxyAuthChooser.tsx +149 -50
- package/src/ui/components/OxyProvider.tsx +7 -5
- package/src/ui/components/SurfaceScreen.tsx +28 -4
- package/src/ui/components/__tests__/followTargetButton.test.ts +39 -0
- package/src/ui/components/authChooser/AccountsMenuView.tsx +246 -96
- package/src/ui/components/authChooser/SignInEntryView.tsx +31 -8
- package/src/ui/components/authChooser/primitives.tsx +37 -23
- package/src/ui/components/authChooser/signInProgress.ts +4 -0
- package/src/ui/components/authChooser/types.ts +34 -1
- package/src/ui/context/OxyContext.tsx +269 -324
- package/src/ui/context/hooks/useAuthOperations.ts +32 -35
- package/src/ui/context/oxyContextHelpers.ts +0 -30
- package/src/ui/context/oxyContextTypes.ts +9 -1
- package/src/ui/context/useOxyAccountGraph.ts +5 -19
- package/src/ui/hooks/accountDialogSnapshot.ts +37 -0
- package/src/ui/hooks/mutations/useAccountMutations.ts +0 -19
- package/src/ui/hooks/queries/__tests__/userCache.test.ts +12 -1
- package/src/ui/hooks/useDeviceSwitcher.ts +110 -0
- package/src/ui/hooks/useI18n.ts +23 -3
- package/src/ui/hooks/useSessionManagement.ts +62 -211
- package/src/ui/index.ts +1 -2
- package/src/ui/navigation/routes.ts +85 -75
- package/src/ui/navigation/surfaces.ts +6 -9
- package/src/ui/runtime/createOxyRuntime.ts +623 -0
- package/src/ui/runtime/index.ts +34 -0
- package/src/ui/runtime/runtimeContext.tsx +111 -0
- package/src/ui/runtime/types.ts +110 -0
- package/src/ui/runtime/useRuntimeSnapshot.ts +52 -0
- package/src/ui/screens/AccountMembersScreen.tsx +6 -5
- package/src/ui/screens/CreateAccountScreen.tsx +3 -16
- package/src/ui/screens/trust/TrustCenterScreen.tsx +7 -7
- package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +4 -5
- package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
- package/src/ui/screens/trust/TrustRulesScreen.tsx +3 -2
- package/src/ui/server.ts +0 -1
- package/src/ui/session/__tests__/authStore.test.ts +90 -0
- package/src/ui/session/__tests__/sharedDeviceCredentialStore.test.ts +289 -0
- package/src/ui/session/authStore.ts +78 -9
- package/src/ui/session/sharedDeviceCredentialStore.ts +318 -0
- package/src/ui/stores/authStore.ts +171 -43
- package/src/ui/stores/followTargetStore.ts +24 -1
- package/src/ui/types/navigation.ts +26 -0
- package/src/ui/utils/avatarUtils.ts +2 -37
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +0 -64
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +0 -1
- package/lib/commonjs/ui/screens/trust/trustTier.js +0 -23
- package/lib/commonjs/ui/screens/trust/trustTier.js.map +0 -1
- package/lib/commonjs/ui/stores/accountStore.js +0 -221
- package/lib/commonjs/ui/stores/accountStore.js.map +0 -1
- package/lib/module/ui/hooks/useSwitchableAccounts.js +0 -60
- package/lib/module/ui/hooks/useSwitchableAccounts.js.map +0 -1
- package/lib/module/ui/screens/trust/trustTier.js +0 -19
- package/lib/module/ui/screens/trust/trustTier.js.map +0 -1
- package/lib/module/ui/stores/accountStore.js +0 -213
- package/lib/module/ui/stores/accountStore.js.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +0 -23
- package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +0 -9
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/stores/accountStore.d.ts +0 -27
- package/lib/typescript/commonjs/ui/stores/accountStore.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +0 -23
- package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +0 -9
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +0 -1
- package/lib/typescript/module/ui/stores/accountStore.d.ts +0 -27
- package/lib/typescript/module/ui/stores/accountStore.d.ts.map +0 -1
- package/src/ui/hooks/useSwitchableAccounts.ts +0 -75
- package/src/ui/screens/trust/trustTier.ts +0 -20
- package/src/ui/stores/accountStore.ts +0 -264
|
@@ -123,5 +123,31 @@ export interface OxyProviderProps {
|
|
|
123
123
|
* @default false
|
|
124
124
|
*/
|
|
125
125
|
backgroundSession?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Whether this origin/app may persist the durable device credential
|
|
128
|
+
* (`deviceId` + `deviceSecret`) at all.
|
|
129
|
+
*
|
|
130
|
+
* `'persistent'` (the default, and every app's behaviour) stores it — web
|
|
131
|
+
* localStorage per origin, SecureStore per app on native — so the SDK can
|
|
132
|
+
* re-mint an access token on the next cold boot.
|
|
133
|
+
*
|
|
134
|
+
* `'ephemeral'` stores NOTHING durable: the session lives in memory for the
|
|
135
|
+
* lifetime of the page and is gone on reload. It exists for ONE caller,
|
|
136
|
+
* `auth.oxy.so` with the browser hub enabled (issue #937 Phase 5, ADR 0003),
|
|
137
|
+
* where the durable credential for the browser profile is the server-side
|
|
138
|
+
* DeviceSession behind the `__Host-oxy-device` handle. Two durable
|
|
139
|
+
* credentials for one origin is the dual authority that phase exists to
|
|
140
|
+
* remove — revoking the hub while a localStorage secret still mints would
|
|
141
|
+
* make a sign-out look like it worked — so the way to let the hub be
|
|
142
|
+
* authoritative is to stop persisting the other one, not to consult it
|
|
143
|
+
* second.
|
|
144
|
+
*
|
|
145
|
+
* Do NOT reach for this to make an app "more private". A relying-party
|
|
146
|
+
* origin set to `'ephemeral'` simply signs the user out on every reload,
|
|
147
|
+
* because nothing else on that origin remembers the device.
|
|
148
|
+
*
|
|
149
|
+
* @default 'persistent'
|
|
150
|
+
*/
|
|
151
|
+
deviceCredentialStorage?: 'persistent' | 'ephemeral';
|
|
126
152
|
}
|
|
127
153
|
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,uBAAuB,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACxD"}
|
|
@@ -2,16 +2,8 @@ import type { OxyServices, User } from '@oxyhq/core';
|
|
|
2
2
|
import type { UserProfileUpdate } from '@oxyhq/contracts';
|
|
3
3
|
import type { QueryClient } from '@tanstack/react-query';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @param sessionId - The session ID for the account to update
|
|
8
|
-
* @param avatarFileId - The new avatar file ID
|
|
9
|
-
* @param oxyServices - OxyServices instance to generate download URL
|
|
10
|
-
*/
|
|
11
|
-
export declare function refreshAvatarInStore(sessionId: string, avatarFileId: string, oxyServices: OxyServices): void;
|
|
12
|
-
/**
|
|
13
|
-
* Updates user profile with avatar and handles all side effects (query invalidation, accountStore update).
|
|
14
|
-
* This function can be used from within OxyContext provider without requiring useOxy hook.
|
|
5
|
+
* Updates user profile with avatar and handles all side effects (cache writes,
|
|
6
|
+
* query invalidation). Usable from inside the provider without `useOxy`.
|
|
15
7
|
*
|
|
16
8
|
* @param updates - Profile updates including avatar
|
|
17
9
|
* @param oxyServices - OxyServices instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatarUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/avatarUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"avatarUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/avatarUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "29.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",
|
|
7
7
|
"types": "lib/typescript/commonjs/index.d.ts",
|
|
8
8
|
"react-native": "src/index.ts",
|
|
9
9
|
"source": "src/index.ts",
|
|
10
|
-
"sideEffects": false,
|
|
11
10
|
"publishConfig": {
|
|
12
11
|
"access": "public"
|
|
13
12
|
},
|
|
@@ -77,6 +76,7 @@
|
|
|
77
76
|
"./package.json": "./package.json"
|
|
78
77
|
},
|
|
79
78
|
"files": [
|
|
79
|
+
"NOTICE",
|
|
80
80
|
"src",
|
|
81
81
|
"lib",
|
|
82
82
|
"assets",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"directory": "packages/services"
|
|
104
104
|
},
|
|
105
105
|
"author": "OxyHQ",
|
|
106
|
-
"license": "
|
|
106
|
+
"license": "Apache-2.0",
|
|
107
107
|
"engines": {
|
|
108
108
|
"node": ">=18.0.0"
|
|
109
109
|
},
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
}
|
|
139
139
|
},
|
|
140
140
|
"dependencies": {
|
|
141
|
-
"@oxyhq/contracts": "0.
|
|
141
|
+
"@oxyhq/contracts": "0.26.0",
|
|
142
142
|
"@simplewebauthn/browser": "^13.3.0",
|
|
143
143
|
"color": "^4.2.3"
|
|
144
144
|
},
|
|
@@ -147,10 +147,10 @@
|
|
|
147
147
|
"@commitlint/cli": "^21.2.1",
|
|
148
148
|
"@commitlint/config-conventional": "^21.2.0",
|
|
149
149
|
"@expo/vector-icons": "^15.0.3",
|
|
150
|
-
"@oxyhq/core": "
|
|
150
|
+
"@oxyhq/core": "21.0.0",
|
|
151
151
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
152
152
|
"@react-native-community/netinfo": "^11.4.1",
|
|
153
|
-
"@react-native/babel-preset": "^0.86.
|
|
153
|
+
"@react-native/babel-preset": "^0.86.2",
|
|
154
154
|
"@release-it/conventional-changelog": "^10.0.6",
|
|
155
155
|
"@tanstack/query-async-storage-persister": "^5.101",
|
|
156
156
|
"@tanstack/query-sync-storage-persister": "^5.101",
|
|
@@ -183,14 +183,14 @@
|
|
|
183
183
|
"react-native-svg": "15.15.5",
|
|
184
184
|
"release-it": "^19.0.6",
|
|
185
185
|
"socket.io-client": "^4.8.1",
|
|
186
|
-
"ts-jest": "^29.4.
|
|
186
|
+
"ts-jest": "^29.4.12",
|
|
187
187
|
"typescript": "^5.9.2",
|
|
188
188
|
"zustand": "^5.0.14"
|
|
189
189
|
},
|
|
190
190
|
"peerDependencies": {
|
|
191
191
|
"@expo/vector-icons": "^15.0.3",
|
|
192
192
|
"@oxyhq/bloom": ">=0.59.0",
|
|
193
|
-
"@oxyhq/core": "^
|
|
193
|
+
"@oxyhq/core": "^21.0.0",
|
|
194
194
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
195
195
|
"@react-native-community/netinfo": ">=11.4.1",
|
|
196
196
|
"@tanstack/query-async-storage-persister": "^5.101",
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config plugin: withSharedDeviceSessionProvider (UID-member hub apps).
|
|
3
|
+
*
|
|
4
|
+
* The shared DeviceSession credential is how several official Oxy apps end up on
|
|
5
|
+
* ONE `DeviceSession` — and therefore one globally active account context —
|
|
6
|
+
* WITHOUT any of them reading Commons's private identity key. This plugin wires
|
|
7
|
+
* the Android side of `@oxyhq/services`:
|
|
8
|
+
*
|
|
9
|
+
* - Defines a `signature`-level permission
|
|
10
|
+
* `so.oxy.shared.permission.READ_DEVICE_SESSION`. `signature` means only apps
|
|
11
|
+
* signed with the SAME certificate (the shared Oxy release keystore) can hold
|
|
12
|
+
* it — the trust boundary is the signing key, not the deprecated `sharedUserId`.
|
|
13
|
+
* - Requests that same permission so this app can also read cross-authority.
|
|
14
|
+
* - Declares `OxyDeviceSessionProvider` at authority
|
|
15
|
+
* `${applicationId}.devicesession` (AGP substitutes `${applicationId}` at
|
|
16
|
+
* build), guarded by that permission. The provider is READ-only across the
|
|
17
|
+
* process boundary: a sibling may join the device session, never overwrite it.
|
|
18
|
+
* - Adds `<queries>` entries so Android 11+ package-visibility filtering never
|
|
19
|
+
* hides the sibling providers from the resolver.
|
|
20
|
+
*
|
|
21
|
+
* WHICH APPS USE THIS PLUGIN: exactly the apps listed in `PROVIDER_AUTHORITIES`
|
|
22
|
+
* below, which must be apps inside the `so.oxy.shared` UID. UID members share one
|
|
23
|
+
* data directory, so they all serve the SAME file and the sweep in
|
|
24
|
+
* `OxyDeviceSessionModule` is deterministic whichever one answers. An app that is
|
|
25
|
+
* same-signature but outside that UID must use `withSharedDeviceSessionReader`
|
|
26
|
+
* instead — hosting from there would publish a second, independent copy of "the
|
|
27
|
+
* shared credential" and make the winner depend on list order.
|
|
28
|
+
*
|
|
29
|
+
* Keep this list identical to `PROVIDER_AUTHORITIES` in
|
|
30
|
+
* `android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt`.
|
|
31
|
+
*
|
|
32
|
+
* This is deliberately a SEPARATE permission and a SEPARATE provider from
|
|
33
|
+
* `withSharedIdentityProvider`. Two secrets with different blast radii: the
|
|
34
|
+
* identity key is self-custody and irreplaceable, the device credential is
|
|
35
|
+
* server-revocable and re-publishable. An app that only needs a session gets only
|
|
36
|
+
* the second one.
|
|
37
|
+
*/
|
|
38
|
+
const { withAndroidManifest } = require('@expo/config-plugins');
|
|
39
|
+
|
|
40
|
+
const READ_DEVICE_SESSION_PERMISSION = 'so.oxy.shared.permission.READ_DEVICE_SESSION';
|
|
41
|
+
const PROVIDER_CLASS = 'so.oxy.devicesession.OxyDeviceSessionProvider';
|
|
42
|
+
const PROVIDER_AUTHORITIES = [
|
|
43
|
+
'so.oxy.accounts.devicesession',
|
|
44
|
+
'so.oxy.accounts.dev.devicesession',
|
|
45
|
+
'so.oxy.commons.devicesession',
|
|
46
|
+
'so.oxy.commons.dev.devicesession',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
module.exports = function withSharedDeviceSessionProvider(config) {
|
|
50
|
+
return withAndroidManifest(config, (modConfig) => {
|
|
51
|
+
const manifest = modConfig.modResults.manifest;
|
|
52
|
+
|
|
53
|
+
// 1. Define the signature-level permission.
|
|
54
|
+
manifest['permission'] = manifest['permission'] ?? [];
|
|
55
|
+
if (!manifest['permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
|
|
56
|
+
manifest['permission'].push({
|
|
57
|
+
$: {
|
|
58
|
+
'android:name': READ_DEVICE_SESSION_PERMISSION,
|
|
59
|
+
'android:protectionLevel': 'signature',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 2. Request it (a hub app reads its siblings too — prod ⇆ dev variant).
|
|
65
|
+
manifest['uses-permission'] = manifest['uses-permission'] ?? [];
|
|
66
|
+
if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
|
|
67
|
+
manifest['uses-permission'].push({ $: { 'android:name': READ_DEVICE_SESSION_PERMISSION } });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 3. Make the sibling provider authorities visible under package filtering.
|
|
71
|
+
manifest['queries'] = manifest['queries'] ?? [];
|
|
72
|
+
if (manifest['queries'].length === 0) {
|
|
73
|
+
manifest['queries'].push({});
|
|
74
|
+
}
|
|
75
|
+
const queries = manifest['queries'][0];
|
|
76
|
+
queries.provider = queries.provider ?? [];
|
|
77
|
+
for (const authority of PROVIDER_AUTHORITIES) {
|
|
78
|
+
if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
|
|
79
|
+
queries.provider.push({ $: { 'android:authorities': authority } });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 4. Host the provider.
|
|
84
|
+
const app = manifest.application?.[0];
|
|
85
|
+
if (!app) {
|
|
86
|
+
throw new Error('withSharedDeviceSessionProvider: AndroidManifest has no <application>');
|
|
87
|
+
}
|
|
88
|
+
app.provider = app.provider ?? [];
|
|
89
|
+
if (!app.provider.some((p) => p.$['android:name'] === PROVIDER_CLASS)) {
|
|
90
|
+
app.provider.push({
|
|
91
|
+
$: {
|
|
92
|
+
'android:name': PROVIDER_CLASS,
|
|
93
|
+
'android:authorities': '${applicationId}.devicesession',
|
|
94
|
+
'android:exported': 'true',
|
|
95
|
+
'android:permission': READ_DEVICE_SESSION_PERMISSION,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return modConfig;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config plugin: withSharedDeviceSessionReader (every other official Oxy app).
|
|
3
|
+
*
|
|
4
|
+
* A reader app JOINS the device's existing session — it adopts the shared
|
|
5
|
+
* `deviceId` + `deviceSecret` a hub app published, so it lands signed in with no
|
|
6
|
+
* QR and, crucially, without ever asking for Commons's private identity key.
|
|
7
|
+
* This plugin wires the minimal Android side of `@oxyhq/services`:
|
|
8
|
+
*
|
|
9
|
+
* - Requests the `signature`-level permission
|
|
10
|
+
* `so.oxy.shared.permission.READ_DEVICE_SESSION` (defined by the hub apps).
|
|
11
|
+
* Because it is `signature`, it is granted only when this app is signed with
|
|
12
|
+
* the SAME certificate as the hub — that is the entire trust boundary, and it
|
|
13
|
+
* is what makes an incorrectly-signed app unable to read the slot.
|
|
14
|
+
* - Adds `<queries>` entries for the hub authorities so package-visibility
|
|
15
|
+
* filtering (Android 11+) never hides them from `ContentResolver.call`.
|
|
16
|
+
*
|
|
17
|
+
* The provider itself is declared only by the hub apps
|
|
18
|
+
* (`withSharedDeviceSessionProvider`) — see the note there about why hosting is
|
|
19
|
+
* restricted to apps inside the `so.oxy.shared` UID.
|
|
20
|
+
*
|
|
21
|
+
* Keep this list identical to `PROVIDER_AUTHORITIES` in
|
|
22
|
+
* `android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt`.
|
|
23
|
+
*/
|
|
24
|
+
const { withAndroidManifest } = require('@expo/config-plugins');
|
|
25
|
+
|
|
26
|
+
const READ_DEVICE_SESSION_PERMISSION = 'so.oxy.shared.permission.READ_DEVICE_SESSION';
|
|
27
|
+
const PROVIDER_AUTHORITIES = [
|
|
28
|
+
'so.oxy.accounts.devicesession',
|
|
29
|
+
'so.oxy.accounts.dev.devicesession',
|
|
30
|
+
'so.oxy.commons.devicesession',
|
|
31
|
+
'so.oxy.commons.dev.devicesession',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
module.exports = function withSharedDeviceSessionReader(config) {
|
|
35
|
+
return withAndroidManifest(config, (modConfig) => {
|
|
36
|
+
const manifest = modConfig.modResults.manifest;
|
|
37
|
+
|
|
38
|
+
manifest['uses-permission'] = manifest['uses-permission'] ?? [];
|
|
39
|
+
if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
|
|
40
|
+
manifest['uses-permission'].push({ $: { 'android:name': READ_DEVICE_SESSION_PERMISSION } });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
manifest['queries'] = manifest['queries'] ?? [];
|
|
44
|
+
if (manifest['queries'].length === 0) {
|
|
45
|
+
manifest['queries'].push({});
|
|
46
|
+
}
|
|
47
|
+
const queries = manifest['queries'][0];
|
|
48
|
+
queries.provider = queries.provider ?? [];
|
|
49
|
+
for (const authority of PROVIDER_AUTHORITIES) {
|
|
50
|
+
if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
|
|
51
|
+
queries.provider.push({ $: { 'android:authorities': authority } });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return modConfig;
|
|
56
|
+
});
|
|
57
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@oxyhq/services` ships an ESM build, and ESM has no `require`.
|
|
3
|
+
*
|
|
4
|
+
* This is not a style rule: a surviving `require()` puts web bundlers into
|
|
5
|
+
* CommonJS interop, which hands consumers `undefined` bindings with no build
|
|
6
|
+
* error and no warning. It blanked auth.oxy.so/authorize once — see the note on
|
|
7
|
+
* `screenComponents` in `../ui/navigation/routes` for the mechanism, and
|
|
8
|
+
* `README.md` for the incident.
|
|
9
|
+
*
|
|
10
|
+
* Deferring is still legitimate: a thunk over a static import defers a READ,
|
|
11
|
+
* `import()` defers a LOAD. Neither needs `require()`.
|
|
12
|
+
*/
|
|
13
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
14
|
+
import { join, relative } from 'node:path';
|
|
15
|
+
|
|
16
|
+
const SRC_ROOT = join(__dirname, '..');
|
|
17
|
+
|
|
18
|
+
/** Source extensions that end up in the published ESM build. */
|
|
19
|
+
const SOURCE_EXTENSIONS = ['.ts', '.tsx'];
|
|
20
|
+
|
|
21
|
+
/** Tests are compiled to CommonJS by ts-jest and never ship, so they are exempt. */
|
|
22
|
+
const EXEMPT_SEGMENTS = ['__tests__'];
|
|
23
|
+
|
|
24
|
+
function collectSourceFiles(dir: string): string[] {
|
|
25
|
+
const found: string[] = [];
|
|
26
|
+
for (const entry of readdirSync(dir)) {
|
|
27
|
+
const path = join(dir, entry);
|
|
28
|
+
if (statSync(path).isDirectory()) {
|
|
29
|
+
if (EXEMPT_SEGMENTS.includes(entry)) continue;
|
|
30
|
+
found.push(...collectSourceFiles(path));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (SOURCE_EXTENSIONS.some((ext) => path.endsWith(ext)) && !path.endsWith('.d.ts')) {
|
|
34
|
+
found.push(path);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return found;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Drop comments and string/template literals so prose about `require()` — such
|
|
42
|
+
* as the notes explaining this very rule — is not mistaken for a call.
|
|
43
|
+
*/
|
|
44
|
+
function stripCommentsAndStrings(code: string): string {
|
|
45
|
+
return code
|
|
46
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
47
|
+
.replace(/(^|[^:])\/\/.*$/gm, '$1')
|
|
48
|
+
.replace(/'(?:[^'\\\n]|\\.)*'/g, "''")
|
|
49
|
+
.replace(/"(?:[^"\\\n]|\\.)*"/g, '""')
|
|
50
|
+
.replace(/`(?:[^`\\]|\\.)*`/g, '``');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe('ESM source purity', () => {
|
|
54
|
+
it('never calls require() anywhere in the shipped source', () => {
|
|
55
|
+
const offenders = collectSourceFiles(SRC_ROOT)
|
|
56
|
+
.filter((file) => /\brequire\s*\(/.test(stripCommentsAndStrings(readFileSync(file, 'utf8'))))
|
|
57
|
+
.map((file) => relative(SRC_ROOT, file));
|
|
58
|
+
|
|
59
|
+
expect(offenders).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -33,6 +33,29 @@ setPlatformOS(Platform.OS as PlatformOS);
|
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
export { default as OxyProvider } from './ui/components/OxyProvider';
|
|
35
35
|
export { useOxy } from './ui/context/OxyContext';
|
|
36
|
+
// `useOxy()` THROWS when no provider is mounted. `useOptionalOxy()` returns
|
|
37
|
+
// `null` instead, for the rare component that renders on both sides of the
|
|
38
|
+
// provider boundary; there is no fabricated forever-loading runtime.
|
|
39
|
+
export { useOptionalOxy, OxyProviderMissingError } from './ui/context/OxyContext';
|
|
40
|
+
|
|
41
|
+
// The runtime surface (ADR 0004). These subscribe to the ONE runtime with a
|
|
42
|
+
// selector, so — unlike `useOxy()`, whose value is rebuilt by any of its fifty
|
|
43
|
+
// members moving — a locale change or a dialog opening does not re-render them.
|
|
44
|
+
export {
|
|
45
|
+
useOxyRuntime,
|
|
46
|
+
useOxySnapshot,
|
|
47
|
+
useActiveAccount,
|
|
48
|
+
useDeviceDirectory,
|
|
49
|
+
OxyRuntimeMissingError,
|
|
50
|
+
} from './ui/runtime';
|
|
51
|
+
export type {
|
|
52
|
+
ActiveAccount,
|
|
53
|
+
OxyRuntime,
|
|
54
|
+
OxyRuntimeError,
|
|
55
|
+
OxyRuntimeSnapshot,
|
|
56
|
+
OxyRuntimeStatus,
|
|
57
|
+
OxyTokenStatus,
|
|
58
|
+
} from './ui/runtime';
|
|
36
59
|
export type { OxyContextState } from './ui/context/OxyContext';
|
|
37
60
|
export { useAuth } from './ui/hooks/useAuth';
|
|
38
61
|
export type { AuthState, AuthActions, UseAuthReturn } from './ui/hooks/useAuth';
|
|
@@ -45,7 +68,6 @@ export { IdentityBoundSessionError } from './ui/session/identityBinding';
|
|
|
45
68
|
// Zustand stores
|
|
46
69
|
// ---------------------------------------------------------------------------
|
|
47
70
|
export { useAuthStore } from './ui/stores/authStore';
|
|
48
|
-
export { useAccountStore } from './ui/stores/accountStore';
|
|
49
71
|
export {
|
|
50
72
|
useAssetStore,
|
|
51
73
|
useAssets as useAssetsStore,
|
|
@@ -306,6 +328,11 @@ export {
|
|
|
306
328
|
// guide most likely to be reached for did not resolve.
|
|
307
329
|
isFollowedGlobally,
|
|
308
330
|
withApplicationMode,
|
|
331
|
+
// Whether a cached status is safe to act on without a round trip — list rows
|
|
332
|
+
// often carry globalState without relationshipId.
|
|
333
|
+
isCompleteFollowStatus,
|
|
334
|
+
followRecordToStatus,
|
|
335
|
+
followRecordsToStatusMap,
|
|
309
336
|
} from './ui/stores/followTargetStore';
|
|
310
337
|
export { default as OxyPayButton } from './ui/components/OxyPayButton';
|
|
311
338
|
export { LogoIcon } from './ui/components/logo/LogoIcon';
|
|
@@ -338,14 +365,14 @@ export { OxySignInRequestSurface } from './ui/components/OxySignInRequestSurface
|
|
|
338
365
|
export type { OxySignInRequestSurfaceProps } from './ui/components/OxySignInRequestSurface';
|
|
339
366
|
export type { OxySignInSurfaceAction } from './ui/components/authChooser/types';
|
|
340
367
|
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
//
|
|
345
|
-
//
|
|
346
|
-
//
|
|
347
|
-
export {
|
|
348
|
-
export type {
|
|
368
|
+
// The device switcher — the server's own directory (ADR 0002) of who is signed
|
|
369
|
+
// in here and what each of them may act as, grouped by PERSON, with the two
|
|
370
|
+
// removals an account id cannot name. Backed by the shared
|
|
371
|
+
// `AccountDialogController` in `@oxyhq/core`; selecting a row activates a
|
|
372
|
+
// `contextId`. `DevicePrincipalGroup` and `DeviceContext` live in `@oxyhq/core`
|
|
373
|
+
// — import them from there.
|
|
374
|
+
export { useDeviceSwitcher } from './ui/hooks/useDeviceSwitcher';
|
|
375
|
+
export type { UseDeviceSwitcherResult } from './ui/hooks/useDeviceSwitcher';
|
|
349
376
|
|
|
350
377
|
// Unified "Manage your Oxy Account" screen (the caller's own personal account)
|
|
351
378
|
export { default as ProfileScreen } from './ui/screens/ProfileScreen';
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from '@oxyhq/core';
|
|
9
9
|
import type { SessionClient } from '@oxyhq/core';
|
|
10
10
|
import { loadPersistedDeviceCredential } from '../utils/deviceCredential';
|
|
11
|
+
import { createPlatformSharedDeviceCredentialStore } from '../session/sharedDeviceCredentialStore';
|
|
11
12
|
import { tryCompleteOAuthReturn } from '../utils/oauthReturn';
|
|
12
13
|
import { isWebBrowser } from '../utils/isWebBrowser';
|
|
13
14
|
import { isNetConnectivityExplicitlyOffline } from '../utils/netConnectivity';
|
|
@@ -161,6 +162,12 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
|
|
|
161
162
|
platform: { isWeb: isWebBrowser(), isNative: !isWebBrowser() },
|
|
162
163
|
sessionMode,
|
|
163
164
|
identity,
|
|
165
|
+
// The device-wide shared credential slot, enabling the `shared-device-adopt`
|
|
166
|
+
// lane: a newly installed official app joins this device's existing session
|
|
167
|
+
// instead of falling back to signing a challenge with the Commons identity
|
|
168
|
+
// key. `null` on web, where each origin is its own device by design; the
|
|
169
|
+
// core lane is also skipped outright in `sessionMode: 'identity'`.
|
|
170
|
+
sharedDeviceCredential: createPlatformSharedDeviceCredentialStore() ?? undefined,
|
|
164
171
|
overallDeadlineMs: COLD_BOOT_OVERALL_DEADLINE_MS,
|
|
165
172
|
isOffline: () => offline,
|
|
166
173
|
onStepDeadline: (stepId) => {
|
package/src/ui/client.ts
CHANGED
|
@@ -19,7 +19,7 @@ export { default as FollowButton } from './components/FollowButton';
|
|
|
19
19
|
export { default as OxyPayButton } from './components/OxyPayButton';
|
|
20
20
|
|
|
21
21
|
// Context
|
|
22
|
-
export { useOxy } from './context/OxyContext';
|
|
22
|
+
export { useOxy, useOptionalOxy, OxyProviderMissingError } from './context/OxyContext';
|
|
23
23
|
|
|
24
24
|
// Hooks
|
|
25
25
|
export { useAuth } from './hooks/useAuth';
|
|
@@ -34,7 +34,6 @@ export { default as ManageAccountScreen } from './screens/ManageAccountScreen';
|
|
|
34
34
|
|
|
35
35
|
// Stores
|
|
36
36
|
export { useAuthStore } from './stores/authStore';
|
|
37
|
-
export { useAccountStore } from './stores/accountStore';
|
|
38
37
|
|
|
39
38
|
// Error handler utilities
|
|
40
39
|
export {
|
|
@@ -31,6 +31,7 @@ import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
|
|
|
31
31
|
import type { BaseScreenProps } from '../types/navigation';
|
|
32
32
|
import LogoText from './logo/LogoText';
|
|
33
33
|
import OxyAuthChooser from './OxyAuthChooser';
|
|
34
|
+
import { EMPTY_ACCOUNT_DIALOG_SNAPSHOT } from '../hooks/accountDialogSnapshot';
|
|
34
35
|
|
|
35
36
|
type Translate = ReturnType<typeof useI18n>['t'];
|
|
36
37
|
|
|
@@ -61,20 +62,22 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
|
|
|
61
62
|
|
|
62
63
|
// A lightweight, header-only binding to the same controller `OxyAuthChooser`
|
|
63
64
|
// binds independently — cheap, and the established pattern here (
|
|
64
|
-
// `
|
|
65
|
+
// `useDeviceSwitcher` also binds to this controller on its own).
|
|
65
66
|
const subscribe = useCallback(
|
|
66
67
|
(listener: () => void) => (controller ? controller.subscribe(listener) : () => undefined),
|
|
67
68
|
[controller],
|
|
68
69
|
);
|
|
69
70
|
const getSnapshot = useCallback(
|
|
70
|
-
() => (controller ? controller.getSnapshot() :
|
|
71
|
+
() => (controller ? controller.getSnapshot() : EMPTY_ACCOUNT_DIALOG_SNAPSHOT),
|
|
71
72
|
[controller],
|
|
72
73
|
);
|
|
73
74
|
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
74
75
|
|
|
75
76
|
const { view } = snapshot;
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
// "Add another account" only makes sense as a back destination when there IS
|
|
78
|
+
// another — i.e. somebody is already signed in on this device.
|
|
79
|
+
const hasSignedInAccounts = (snapshot.directory?.principals.length ?? 0) > 0;
|
|
80
|
+
const showBack = view === 'qr' || view === 'signup' || (view === 'add' && hasSignedInAccounts);
|
|
78
81
|
const goToAccounts = useCallback(() => {
|
|
79
82
|
if (!controller) return;
|
|
80
83
|
const { view: currentView, signIn } = controller.getSnapshot();
|
|
@@ -100,7 +103,7 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
|
|
|
100
103
|
// by the bar. Every OTHER view keeps the SHARED Dialog nav header the rest of
|
|
101
104
|
// the SDK uses — a large in-content title/subtitle that collapses into the bar
|
|
102
105
|
// on scroll — because their copy is informative.
|
|
103
|
-
const copy = view === 'accounts' ? null : headerCopy(view,
|
|
106
|
+
const copy = view === 'accounts' ? null : headerCopy(view, hasSignedInAccounts, t);
|
|
104
107
|
|
|
105
108
|
useSurfaceHeader({
|
|
106
109
|
titleContent: copy ? undefined : NAV_LOGO,
|
|
@@ -126,7 +129,7 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
|
|
|
126
129
|
|
|
127
130
|
function headerCopy(
|
|
128
131
|
view: Exclude<AccountDialogSnapshot['view'], 'accounts'>,
|
|
129
|
-
|
|
132
|
+
hasSignedInAccounts: boolean,
|
|
130
133
|
t: Translate,
|
|
131
134
|
): { title: string; subtitle: string | null } {
|
|
132
135
|
switch (view) {
|
|
@@ -147,7 +150,7 @@ function headerCopy(
|
|
|
147
150
|
subtitle: t('signup.subtitle') || 'One identity for the whole ecosystem.',
|
|
148
151
|
};
|
|
149
152
|
default:
|
|
150
|
-
return
|
|
153
|
+
return hasSignedInAccounts
|
|
151
154
|
? {
|
|
152
155
|
title: t('signin.addAccountTitle') || 'Add another account',
|
|
153
156
|
subtitle: t('signin.addAccountSubtitle') || 'Sign in with another account.',
|
|
@@ -159,28 +162,6 @@ function headerCopy(
|
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
164
|
|
|
162
|
-
const EMPTY_SNAPSHOT: AccountDialogSnapshot = {
|
|
163
|
-
view: 'accounts',
|
|
164
|
-
accounts: [],
|
|
165
|
-
activeAccountId: null,
|
|
166
|
-
loading: false,
|
|
167
|
-
error: null,
|
|
168
|
-
switchingAccountId: null,
|
|
169
|
-
signIn: {
|
|
170
|
-
phase: 'idle',
|
|
171
|
-
authorizeCode: null,
|
|
172
|
-
qrPayload: null,
|
|
173
|
-
expiresAt: null,
|
|
174
|
-
error: null,
|
|
175
|
-
route: null,
|
|
176
|
-
routeFailed: false,
|
|
177
|
-
pushSentAt: null,
|
|
178
|
-
openedAt: null,
|
|
179
|
-
progress: 'idle',
|
|
180
|
-
},
|
|
181
|
-
commonsAvailability: 'unknown',
|
|
182
|
-
};
|
|
183
|
-
|
|
184
165
|
/**
|
|
185
166
|
* The screen gutter. In the Dialog's nav-header mode the surface adds NO content
|
|
186
167
|
* padding of its own — the large title and each screen own theirs — so this must
|