@oxy.so/services 4.0.7 → 6.1.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/README.md +2 -2
- package/lib/commonjs/assets/assets/signIn/slide-1.jpg +0 -0
- package/lib/commonjs/assets/assets/signIn/slide-1.jpg.d.ts +3 -0
- package/lib/commonjs/assets/assets/signIn/slide-2.jpg +0 -0
- package/lib/commonjs/assets/assets/signIn/slide-2.jpg.d.ts +3 -0
- package/lib/commonjs/assets/assets/signIn/slide-3.jpg +0 -0
- package/lib/commonjs/assets/assets/signIn/slide-3.jpg.d.ts +3 -0
- package/lib/commonjs/assets/assets/signIn/slide-4.jpg +0 -0
- package/lib/commonjs/assets/assets/signIn/slide-4.jpg.d.ts +3 -0
- package/lib/commonjs/assets/signIn/slide-1.jpg +0 -0
- package/lib/commonjs/assets/signIn/slide-2.jpg +0 -0
- package/lib/commonjs/assets/signIn/slide-3.jpg +0 -0
- package/lib/commonjs/assets/signIn/slide-4.jpg +0 -0
- package/lib/commonjs/index.js +77 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +11 -58
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +36 -45
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +0 -2
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +30 -16
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/primitives.js +7 -52
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js +1 -7
- package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/styles.js +0 -31
- package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/types.js +2 -2
- package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
- package/lib/commonjs/ui/components/oauthNavigation.js +1 -1
- package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js +161 -0
- package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js +111 -0
- package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js +160 -0
- package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyCreateAccountPanel.js +236 -0
- package/lib/commonjs/ui/components/signIn/OxyCreateAccountPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js +114 -0
- package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js +275 -0
- package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxyRecoverAccountPanel.js +170 -0
- package/lib/commonjs/ui/components/signIn/OxyRecoverAccountPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxySignInPanel.js +371 -0
- package/lib/commonjs/ui/components/signIn/OxySignInPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js +78 -0
- package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/accountFlowParts.js +244 -0
- package/lib/commonjs/ui/components/signIn/accountFlowParts.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/artwork.js +21 -0
- package/lib/commonjs/ui/components/signIn/artwork.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/passkeyError.js +46 -0
- package/lib/commonjs/ui/components/signIn/passkeyError.js.map +1 -0
- package/lib/commonjs/ui/components/signIn/signInMethods.js +46 -0
- package/lib/commonjs/ui/components/signIn/signInMethods.js.map +1 -0
- package/lib/commonjs/ui/context/OxyContext.js +16 -16
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/commitSessionFlow.js +0 -43
- package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/commonjs/ui/context/passkeyFlow.js +22 -0
- package/lib/commonjs/ui/context/passkeyFlow.js.map +1 -1
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +15 -1
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -1
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +1 -3
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -1
- package/lib/commonjs/ui/oauth/browserAuthTransport.js +11 -4
- package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -1
- package/lib/commonjs/ui/oauth/oauthHandshake.js +3 -0
- package/lib/commonjs/ui/oauth/oauthHandshake.js.map +1 -1
- package/lib/commonjs/ui/oauth/oauthPopup.js +2 -3
- package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +0 -23
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileScreen.js +0 -8
- package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +3 -4
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/session/authStore.js +0 -21
- package/lib/commonjs/ui/session/authStore.js.map +1 -1
- package/lib/commonjs/ui/utils/accountDeletionHandoff.js +2 -2
- package/lib/commonjs/ui/utils/accountDeletionHandoff.js.map +1 -1
- package/lib/module/assets/assets/signIn/slide-1.jpg +0 -0
- package/lib/module/assets/assets/signIn/slide-1.jpg.d.ts +3 -0
- package/lib/module/assets/assets/signIn/slide-2.jpg +0 -0
- package/lib/module/assets/assets/signIn/slide-2.jpg.d.ts +3 -0
- package/lib/module/assets/assets/signIn/slide-3.jpg +0 -0
- package/lib/module/assets/assets/signIn/slide-3.jpg.d.ts +3 -0
- package/lib/module/assets/assets/signIn/slide-4.jpg +0 -0
- package/lib/module/assets/assets/signIn/slide-4.jpg.d.ts +3 -0
- package/lib/module/assets/signIn/slide-1.jpg +0 -0
- package/lib/module/assets/signIn/slide-2.jpg +0 -0
- package/lib/module/assets/signIn/slide-3.jpg +0 -0
- package/lib/module/assets/signIn/slide-4.jpg +0 -0
- package/lib/module/index.js +14 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/OxyAccountDialogScreen.js +14 -59
- package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +37 -46
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +0 -2
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/ProfileButton.js.map +1 -1
- package/lib/module/ui/components/authChooser/AccountsMenuView.js +22 -10
- package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/module/ui/components/authChooser/primitives.js +1 -44
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/module/ui/components/authChooser/signInFailureMessage.js +1 -7
- package/lib/module/ui/components/authChooser/signInFailureMessage.js.map +1 -1
- package/lib/module/ui/components/authChooser/styles.js +0 -31
- package/lib/module/ui/components/authChooser/styles.js.map +1 -1
- package/lib/module/ui/components/authChooser/types.js +2 -2
- package/lib/module/ui/components/authChooser/types.js.map +1 -1
- package/lib/module/ui/components/oauthNavigation.js +1 -1
- package/lib/module/ui/components/signIn/InlineCommonsQr.js +157 -0
- package/lib/module/ui/components/signIn/InlineCommonsQr.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyAccountPicker.js +106 -0
- package/lib/module/ui/components/signIn/OxyAccountPicker.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyAuthScreen.js +151 -0
- package/lib/module/ui/components/signIn/OxyAuthScreen.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyCreateAccountPanel.js +231 -0
- package/lib/module/ui/components/signIn/OxyCreateAccountPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js +109 -0
- package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js +270 -0
- package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/OxyRecoverAccountPanel.js +165 -0
- package/lib/module/ui/components/signIn/OxyRecoverAccountPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/OxySignInPanel.js +366 -0
- package/lib/module/ui/components/signIn/OxySignInPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/OxySignUpPanel.js +75 -0
- package/lib/module/ui/components/signIn/OxySignUpPanel.js.map +1 -0
- package/lib/module/ui/components/signIn/accountFlowParts.js +235 -0
- package/lib/module/ui/components/signIn/accountFlowParts.js.map +1 -0
- package/lib/module/ui/components/signIn/artwork.js +16 -0
- package/lib/module/ui/components/signIn/artwork.js.map +1 -0
- package/lib/module/ui/components/signIn/passkeyError.js +40 -0
- package/lib/module/ui/components/signIn/passkeyError.js.map +1 -0
- package/lib/module/ui/components/signIn/signInMethods.js +42 -0
- package/lib/module/ui/components/signIn/signInMethods.js.map +1 -0
- package/lib/module/ui/context/OxyContext.js +17 -17
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/commitSessionFlow.js +0 -42
- package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/module/ui/context/passkeyFlow.js +21 -0
- package/lib/module/ui/context/passkeyFlow.js.map +1 -1
- package/lib/module/ui/hooks/accountDialogSnapshot.js +14 -1
- package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -1
- package/lib/module/ui/hooks/useDeviceSwitcher.js +3 -5
- package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -1
- package/lib/module/ui/oauth/browserAuthTransport.js +11 -4
- package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -1
- package/lib/module/ui/oauth/oauthHandshake.js +3 -0
- package/lib/module/ui/oauth/oauthHandshake.js.map +1 -1
- package/lib/module/ui/oauth/oauthPopup.js +2 -3
- package/lib/module/ui/oauth/oauthPopup.js.map +1 -1
- package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -24
- package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileScreen.js +0 -8
- package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +4 -5
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/session/authStore.js +1 -22
- package/lib/module/ui/session/authStore.js.map +1 -1
- package/lib/module/ui/utils/accountDeletionHandoff.js +3 -3
- package/lib/module/ui/utils/accountDeletionHandoff.js.map +1 -1
- package/lib/typescript/assets/signIn/slide-1.jpg.d.ts +3 -0
- package/lib/typescript/assets/signIn/slide-2.jpg.d.ts +3 -0
- package/lib/typescript/assets/signIn/slide-3.jpg.d.ts +3 -0
- package/lib/typescript/assets/signIn/slide-4.jpg.d.ts +3 -0
- package/lib/typescript/commonjs/index.d.ts +16 -2
- package/lib/typescript/commonjs/index.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 +5 -12
- 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/ProfileButton.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +0 -19
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts +1 -5
- package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts +0 -31
- package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +2 -7
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/oauthNavigation.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/InlineCommonsQr.d.ts +20 -0
- package/lib/typescript/commonjs/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyAccountPicker.d.ts +34 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts +43 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyCreateAccountPanel.d.ts +24 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyCreateAccountPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyDeleteAccountPanel.d.ts +16 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyLinkCommonsPanel.d.ts +21 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyRecoverAccountPanel.d.ts +20 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxyRecoverAccountPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxySignInPanel.d.ts +43 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxySignInPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxySignUpPanel.d.ts +17 -0
- package/lib/typescript/commonjs/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts +60 -0
- package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/artwork.d.ts +8 -0
- package/lib/typescript/commonjs/ui/components/signIn/artwork.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/passkeyError.d.ts +16 -0
- package/lib/typescript/commonjs/ui/components/signIn/passkeyError.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/signIn/signInMethods.d.ts +39 -0
- package/lib/typescript/commonjs/ui/components/signIn/signInMethods.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +0 -40
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +15 -10
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts +16 -1
- package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +7 -1
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts +9 -0
- package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts +3 -0
- package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +2 -3
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/authStore.d.ts +0 -30
- package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +0 -26
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +16 -2
- package/lib/typescript/module/index.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 +5 -12
- 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/ProfileButton.d.ts +1 -1
- package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +0 -19
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts +1 -5
- package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/styles.d.ts +0 -31
- package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/types.d.ts +2 -7
- package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/oauthNavigation.d.ts +1 -1
- package/lib/typescript/module/ui/components/signIn/InlineCommonsQr.d.ts +20 -0
- package/lib/typescript/module/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyAccountPicker.d.ts +34 -0
- package/lib/typescript/module/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts +43 -0
- package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyCreateAccountPanel.d.ts +24 -0
- package/lib/typescript/module/ui/components/signIn/OxyCreateAccountPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyDeleteAccountPanel.d.ts +16 -0
- package/lib/typescript/module/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyLinkCommonsPanel.d.ts +21 -0
- package/lib/typescript/module/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxyRecoverAccountPanel.d.ts +20 -0
- package/lib/typescript/module/ui/components/signIn/OxyRecoverAccountPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxySignInPanel.d.ts +43 -0
- package/lib/typescript/module/ui/components/signIn/OxySignInPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/OxySignUpPanel.d.ts +17 -0
- package/lib/typescript/module/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts +60 -0
- package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/artwork.d.ts +8 -0
- package/lib/typescript/module/ui/components/signIn/artwork.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/passkeyError.d.ts +16 -0
- package/lib/typescript/module/ui/components/signIn/passkeyError.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/signIn/signInMethods.d.ts +39 -0
- package/lib/typescript/module/ui/components/signIn/signInMethods.d.ts.map +1 -0
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +0 -40
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +15 -10
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/passkeyFlow.d.ts +16 -1
- package/lib/typescript/module/ui/context/passkeyFlow.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +7 -1
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts +9 -0
- package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts +3 -0
- package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +2 -3
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/authStore.d.ts +0 -30
- package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +0 -26
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/package.json +4 -7
- package/src/assets/signIn/slide-1.jpg +0 -0
- package/src/assets/signIn/slide-1.jpg.d.ts +3 -0
- package/src/assets/signIn/slide-2.jpg +0 -0
- package/src/assets/signIn/slide-2.jpg.d.ts +3 -0
- package/src/assets/signIn/slide-3.jpg +0 -0
- package/src/assets/signIn/slide-3.jpg.d.ts +3 -0
- package/src/assets/signIn/slide-4.jpg +0 -0
- package/src/assets/signIn/slide-4.jpg.d.ts +3 -0
- package/src/index.ts +27 -7
- package/src/ui/components/OxyAccountDialogScreen.tsx +11 -72
- package/src/ui/components/OxyAuthChooser.tsx +37 -54
- package/src/ui/components/OxyProvider.tsx +0 -2
- package/src/ui/components/ProfileButton.tsx +1 -4
- package/src/ui/components/authChooser/AccountsMenuView.tsx +28 -8
- package/src/ui/components/authChooser/primitives.tsx +1 -39
- package/src/ui/components/authChooser/signInFailureMessage.ts +1 -7
- package/src/ui/components/authChooser/styles.ts +0 -31
- package/src/ui/components/authChooser/types.ts +2 -7
- package/src/ui/components/oauthNavigation.ts +1 -1
- package/src/ui/components/signIn/InlineCommonsQr.tsx +135 -0
- package/src/ui/components/signIn/OxyAccountPicker.tsx +129 -0
- package/src/ui/components/signIn/OxyAuthScreen.tsx +123 -0
- package/src/ui/components/signIn/OxyCreateAccountPanel.tsx +207 -0
- package/src/ui/components/signIn/OxyDeleteAccountPanel.tsx +106 -0
- package/src/ui/components/signIn/OxyLinkCommonsPanel.tsx +222 -0
- package/src/ui/components/signIn/OxyRecoverAccountPanel.tsx +154 -0
- package/src/ui/components/signIn/OxySignInPanel.tsx +392 -0
- package/src/ui/components/signIn/OxySignUpPanel.tsx +86 -0
- package/src/ui/components/signIn/accountFlowParts.tsx +204 -0
- package/src/ui/components/signIn/artwork.ts +13 -0
- package/src/ui/components/signIn/passkeyError.ts +44 -0
- package/src/ui/components/signIn/signInMethods.ts +51 -0
- package/src/ui/context/OxyContext.tsx +23 -19
- package/src/ui/context/__tests__/commitSessionFlow.test.ts +0 -89
- package/src/ui/context/__tests__/passkeyFlow.test.ts +59 -1
- package/src/ui/context/commitSessionFlow.ts +0 -61
- package/src/ui/context/oxyContextTypes.ts +16 -10
- package/src/ui/context/passkeyFlow.ts +28 -0
- package/src/ui/hooks/accountDialogSnapshot.ts +20 -1
- package/src/ui/hooks/useDeviceSwitcher.ts +3 -11
- package/src/ui/oauth/__tests__/browserAuthTransport.test.ts +21 -0
- package/src/ui/oauth/browserAuthTransport.ts +14 -4
- package/src/ui/oauth/oauthHandshake.ts +4 -1
- package/src/ui/oauth/oauthPopup.ts +2 -3
- package/src/ui/screens/EditProfileFieldScreen.tsx +1 -27
- package/src/ui/screens/EditProfileScreen.tsx +0 -6
- package/src/ui/screens/ManageAccountScreen.tsx +4 -5
- package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +1 -1
- package/src/ui/session/authStore.ts +0 -37
- package/src/ui/types/navigation.ts +0 -26
- package/src/ui/utils/accountDeletionHandoff.ts +3 -3
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +0 -132
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +0 -1
- package/lib/commonjs/ui/components/authChooser/SignUpView.js +0 -77
- package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +0 -1
- package/lib/commonjs/ui/components/passkeyHubPopup.js +0 -33
- package/lib/commonjs/ui/components/passkeyHubPopup.js.map +0 -1
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +0 -48
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +0 -1
- package/lib/module/ui/components/authChooser/SignInEntryView.js +0 -127
- package/lib/module/ui/components/authChooser/SignInEntryView.js.map +0 -1
- package/lib/module/ui/components/authChooser/SignUpView.js +0 -73
- package/lib/module/ui/components/authChooser/SignUpView.js.map +0 -1
- package/lib/module/ui/components/passkeyHubPopup.js +0 -29
- package/lib/module/ui/components/passkeyHubPopup.js.map +0 -1
- package/lib/module/ui/oauth/legacyRedirectLanes.js +0 -44
- package/lib/module/ui/oauth/legacyRedirectLanes.js.map +0 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +0 -39
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +0 -31
- package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/passkeyHubPopup.d.ts +0 -23
- package/lib/typescript/commonjs/ui/components/passkeyHubPopup.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +0 -40
- package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +0 -39
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +0 -31
- package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/passkeyHubPopup.d.ts +0 -23
- package/lib/typescript/module/ui/components/passkeyHubPopup.d.ts.map +0 -1
- package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +0 -40
- package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
- package/src/ui/components/authChooser/SignInEntryView.tsx +0 -157
- package/src/ui/components/authChooser/SignUpView.tsx +0 -76
- package/src/ui/components/passkeyHubPopup.ts +0 -28
- package/src/ui/oauth/legacyRedirectLanes.ts +0 -43
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sign-in entry's embedded QR, over the split card's photo carousel: scan
|
|
3
|
+
* it with Commons on a phone and this screen is signed in.
|
|
4
|
+
*
|
|
5
|
+
* It owns one QR-only request (`controller.startInlineQr()`): started the
|
|
6
|
+
* first time the block is actually laid out on screen — never while its column
|
|
7
|
+
* is hidden below `md` — renewed when it expires, and withdrawn when the block
|
|
8
|
+
* goes away while it is still approvable. It never pushes to a phone or opens Commons —
|
|
9
|
+
* the person did not ask for either by opening the screen. Any other sign-in
|
|
10
|
+
* they choose supersedes it like any new attempt.
|
|
11
|
+
*
|
|
12
|
+
* Anti-phishing: the plate encodes `signIn.qrPayload` and renders nothing
|
|
13
|
+
* derived from it; the approver resolves the app server-side.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type React from 'react';
|
|
17
|
+
import { useEffect, useState } from 'react';
|
|
18
|
+
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
|
19
|
+
import QRCode from 'react-native-qrcode-svg';
|
|
20
|
+
import { Button } from '@oxy.so/bloom/button';
|
|
21
|
+
import { RiCheckboxCircleLine } from '@oxy.so/bloom/icons/RiCheckboxCircleLine';
|
|
22
|
+
import { RiRefreshLine } from '@oxy.so/bloom/icons/RiRefreshLine';
|
|
23
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
24
|
+
import { Text } from '@oxy.so/bloom/typography';
|
|
25
|
+
import type { AccountDialogController } from '@oxy.so/core';
|
|
26
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
27
|
+
import { useAccountDialogSnapshot } from '../../hooks/accountDialogSnapshot';
|
|
28
|
+
|
|
29
|
+
/** High-contrast, un-themed on purpose: scan reliability. */
|
|
30
|
+
const QR_PLATE_BG = '#FFFFFF';
|
|
31
|
+
const QR_FOREGROUND = '#000000';
|
|
32
|
+
const QR_SIZE = 112;
|
|
33
|
+
const PLATE_PADDING = 8;
|
|
34
|
+
const PLATE_SIZE = QR_SIZE + PLATE_PADDING * 2;
|
|
35
|
+
|
|
36
|
+
export const InlineCommonsQr: React.FC<{ controller: AccountDialogController | null }> = ({ controller }) => {
|
|
37
|
+
const theme = useTheme();
|
|
38
|
+
const { t } = useI18n();
|
|
39
|
+
const { signIn } = useAccountDialogSnapshot(controller);
|
|
40
|
+
const live = signIn.inline && (signIn.phase === 'starting' || signIn.phase === 'waiting');
|
|
41
|
+
const expired = signIn.inline && signIn.phase === 'error' && signIn.failure === 'expired';
|
|
42
|
+
|
|
43
|
+
// Laid out with a size only where its column shows (`display: none` below
|
|
44
|
+
// `md` lays out empty), so that is when a request is worth having.
|
|
45
|
+
const [shown, setShown] = useState(false);
|
|
46
|
+
|
|
47
|
+
// One request for as long as the block is on screen. Withdrawn on the way
|
|
48
|
+
// out only while it is still ours and still approvable: an attempt the
|
|
49
|
+
// person started meanwhile (a passkey window, "Continue with Oxy") is theirs.
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!controller || !shown) return;
|
|
52
|
+
const { signIn: current } = controller.getSnapshot();
|
|
53
|
+
if (!(current.inline && (current.phase === 'starting' || current.phase === 'waiting'))) {
|
|
54
|
+
void controller.startInlineQr();
|
|
55
|
+
}
|
|
56
|
+
return () => {
|
|
57
|
+
const { signIn: last } = controller.getSnapshot();
|
|
58
|
+
if (last.inline && (last.phase === 'starting' || last.phase === 'waiting')) controller.cancelSignIn();
|
|
59
|
+
};
|
|
60
|
+
}, [controller, shown]);
|
|
61
|
+
|
|
62
|
+
// A code only lives a few minutes; an expired one is replaced, not reported.
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (controller && expired) void controller.startInlineQr();
|
|
65
|
+
}, [controller, expired]);
|
|
66
|
+
|
|
67
|
+
let plate: React.ReactNode;
|
|
68
|
+
if (signIn.inline && signIn.progress === 'identity-confirmed') {
|
|
69
|
+
plate = <RiCheckboxCircleLine size="3xl" fill={theme.colors.success} />;
|
|
70
|
+
} else if (live && signIn.qrPayload && signIn.progress !== 'confirming-identity') {
|
|
71
|
+
plate = <QRCode value={signIn.qrPayload} size={QR_SIZE} backgroundColor={QR_PLATE_BG} color={QR_FOREGROUND} />;
|
|
72
|
+
} else if (live || expired || (signIn.inline && signIn.phase === 'completed')) {
|
|
73
|
+
plate = <ActivityIndicator size="large" color={QR_FOREGROUND} />;
|
|
74
|
+
} else {
|
|
75
|
+
// Failed for a reason renewing will not fix by itself, or superseded and
|
|
76
|
+
// then withdrawn: one press for a new code.
|
|
77
|
+
plate = (
|
|
78
|
+
<Button
|
|
79
|
+
appearance="plain"
|
|
80
|
+
tone="neutral"
|
|
81
|
+
size="sm"
|
|
82
|
+
iconOnly
|
|
83
|
+
leadingIcon={RiRefreshLine}
|
|
84
|
+
accessibilityLabel={t('signin.qr.renew')}
|
|
85
|
+
onPress={() => void controller?.startInlineQr()}
|
|
86
|
+
testID="inline-qr-renew"
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<View
|
|
93
|
+
style={styles.block}
|
|
94
|
+
testID="inline-commons-qr"
|
|
95
|
+
onLayout={(event) => {
|
|
96
|
+
if (event.nativeEvent.layout.width > 0) setShown(true);
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
<View style={[styles.plate, { borderColor: theme.colors.border }]}>{plate}</View>
|
|
100
|
+
<Text style={[styles.caption, styles.captionOnMedia]}>
|
|
101
|
+
{t('signin.qr.caption')}
|
|
102
|
+
</Text>
|
|
103
|
+
</View>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const styles = StyleSheet.create({
|
|
108
|
+
block: {
|
|
109
|
+
width: PLATE_SIZE,
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
gap: 6,
|
|
112
|
+
},
|
|
113
|
+
plate: {
|
|
114
|
+
width: PLATE_SIZE,
|
|
115
|
+
height: PLATE_SIZE,
|
|
116
|
+
padding: PLATE_PADDING,
|
|
117
|
+
borderRadius: 12,
|
|
118
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
119
|
+
backgroundColor: QR_PLATE_BG,
|
|
120
|
+
alignItems: 'center',
|
|
121
|
+
justifyContent: 'center',
|
|
122
|
+
},
|
|
123
|
+
caption: {
|
|
124
|
+
fontSize: 12,
|
|
125
|
+
lineHeight: 16,
|
|
126
|
+
textAlign: 'center',
|
|
127
|
+
},
|
|
128
|
+
captionOnMedia: {
|
|
129
|
+
color: '#FFFFFF',
|
|
130
|
+
fontWeight: '500',
|
|
131
|
+
textShadowColor: 'rgba(0, 0, 0, 0.6)',
|
|
132
|
+
textShadowOffset: { width: 0, height: 1 },
|
|
133
|
+
textShadowRadius: 4,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Choose an account" — every `principal acting as account` pair on this
|
|
3
|
+
* device, then "Use another account".
|
|
4
|
+
*
|
|
5
|
+
* The front screen of sign-in on a returning device, in the account dialog and
|
|
6
|
+
* on every auth.oxy.so page that asks WHO (sign-in, OAuth authorize, device
|
|
7
|
+
* approval, MCP linking). Presentational: the host decides what choosing a row
|
|
8
|
+
* means — a switch, a "Continue as" sign-in, or activating the pair before an
|
|
9
|
+
* OAuth consent — and passes the pair back, never an account id, which cannot
|
|
10
|
+
* say whose route was chosen.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type React from 'react';
|
|
14
|
+
import { Pressable, StyleSheet, View } from 'react-native';
|
|
15
|
+
import { RiArrowRightSLine } from '@oxy.so/bloom/icons/RiArrowRightSLine';
|
|
16
|
+
import { RiUserAddLine } from '@oxy.so/bloom/icons/RiUserAddLine';
|
|
17
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
18
|
+
import { Text } from '@oxy.so/bloom/typography';
|
|
19
|
+
import { showsPrincipalHeaders, type SwitcherContextRow, type SwitcherPrincipalRow } from '@oxy.so/core';
|
|
20
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
21
|
+
import { AccountRow } from '../authChooser/primitives';
|
|
22
|
+
import { authChooserStyles } from '../authChooser/styles';
|
|
23
|
+
import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthTerms } from './OxyAuthScreen';
|
|
24
|
+
|
|
25
|
+
export interface OxyAccountPickerProps {
|
|
26
|
+
/** The device's people, each with the accounts they may act as (`useDeviceSwitcher`). */
|
|
27
|
+
principals: SwitcherPrincipalRow[];
|
|
28
|
+
/** The app being continued to, when there is one. */
|
|
29
|
+
appName?: string | null;
|
|
30
|
+
onSelectContext: (context: SwitcherContextRow) => void;
|
|
31
|
+
/** "Use another account" — the host reveals its sign-in. */
|
|
32
|
+
onUseAnother: () => void;
|
|
33
|
+
/** The pair being activated, whose row shows it is busy. */
|
|
34
|
+
pendingContextId?: string | null;
|
|
35
|
+
/** Disables every row while a choice is in flight. */
|
|
36
|
+
isLoading?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* This origin holds no session. A row then reads "Continue as @handle" and
|
|
39
|
+
* never as the current account: the device can list an identity as active
|
|
40
|
+
* while nobody is signed in HERE.
|
|
41
|
+
*/
|
|
42
|
+
signedOut?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const OxyAccountPicker: React.FC<OxyAccountPickerProps> = ({
|
|
46
|
+
principals,
|
|
47
|
+
appName,
|
|
48
|
+
onSelectContext,
|
|
49
|
+
onUseAnother,
|
|
50
|
+
pendingContextId = null,
|
|
51
|
+
isLoading = false,
|
|
52
|
+
signedOut = false,
|
|
53
|
+
}) => {
|
|
54
|
+
const theme = useTheme();
|
|
55
|
+
const { t } = useI18n();
|
|
56
|
+
// Whose route a row is only needs naming once someone holds more than one
|
|
57
|
+
// account here — the same rule the account menu's group headers follow.
|
|
58
|
+
const namesTheOperator = showsPrincipalHeaders(principals);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<OxyAuthScreen>
|
|
62
|
+
<OxyAuthScreenHeader
|
|
63
|
+
title={t('signin.chooser.title')}
|
|
64
|
+
description={appName ? t('signin.chooser.subtitleToApp', { app: appName }) : t('signin.chooser.subtitle')}
|
|
65
|
+
/>
|
|
66
|
+
<View style={authChooserStyles.rows}>
|
|
67
|
+
{principals.flatMap((principal) =>
|
|
68
|
+
principal.contexts.map((context) => (
|
|
69
|
+
<AccountRow
|
|
70
|
+
key={context.contextId}
|
|
71
|
+
context={context}
|
|
72
|
+
operatedBy={
|
|
73
|
+
namesTheOperator && context.isDelegated
|
|
74
|
+
? t('accountSwitcher.context.operatedBy', { name: principal.displayName })
|
|
75
|
+
: null
|
|
76
|
+
}
|
|
77
|
+
continueAsLabel={
|
|
78
|
+
signedOut
|
|
79
|
+
? t('signin.chooser.continueAs', {
|
|
80
|
+
name: context.handle ? `@${context.handle}` : context.displayName,
|
|
81
|
+
})
|
|
82
|
+
: null
|
|
83
|
+
}
|
|
84
|
+
theme={theme}
|
|
85
|
+
activating={pendingContextId === context.contextId}
|
|
86
|
+
disabled={isLoading}
|
|
87
|
+
onPress={() => onSelectContext(context)}
|
|
88
|
+
/>
|
|
89
|
+
)),
|
|
90
|
+
)}
|
|
91
|
+
<Pressable
|
|
92
|
+
onPress={onUseAnother}
|
|
93
|
+
disabled={isLoading}
|
|
94
|
+
accessibilityRole="button"
|
|
95
|
+
accessibilityLabel={t('signin.chooser.useAnother')}
|
|
96
|
+
style={[
|
|
97
|
+
authChooserStyles.accountRow,
|
|
98
|
+
{ borderColor: theme.colors.border, backgroundColor: theme.colors.card },
|
|
99
|
+
isLoading ? authChooserStyles.rowDisabled : null,
|
|
100
|
+
]}
|
|
101
|
+
testID="use-another-account"
|
|
102
|
+
>
|
|
103
|
+
<View style={[styles.addGlyph, { backgroundColor: theme.colors.backgroundSecondary }]}>
|
|
104
|
+
<RiUserAddLine size="md" fill={theme.colors.textSecondary} />
|
|
105
|
+
</View>
|
|
106
|
+
<Text style={[authChooserStyles.rowName, styles.addLabel, { color: theme.colors.text }]}>
|
|
107
|
+
{t('signin.chooser.useAnother')}
|
|
108
|
+
</Text>
|
|
109
|
+
<RiArrowRightSLine size="md" fill={theme.colors.textSecondary} />
|
|
110
|
+
</Pressable>
|
|
111
|
+
</View>
|
|
112
|
+
<OxyAuthTerms />
|
|
113
|
+
</OxyAuthScreen>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const styles = StyleSheet.create({
|
|
118
|
+
// Matches `AccountRow`'s 40px avatar plus its 2px ring and 1px gap.
|
|
119
|
+
addGlyph: {
|
|
120
|
+
width: 46,
|
|
121
|
+
height: 46,
|
|
122
|
+
borderRadius: 23,
|
|
123
|
+
alignItems: 'center',
|
|
124
|
+
justifyContent: 'center',
|
|
125
|
+
},
|
|
126
|
+
addLabel: {
|
|
127
|
+
flex: 1,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shell every Oxy sign-in screen shares — the in-app account dialog and
|
|
3
|
+
* every page of the auth.oxy.so IdP render these, so the two cannot drift:
|
|
4
|
+
*
|
|
5
|
+
* header the Oxy mark (56), then the title (48/800, tight) and a 18px
|
|
6
|
+
* description, 8 apart
|
|
7
|
+
* screen blocks 24 apart, at most 448 wide
|
|
8
|
+
* split from `md`, Bloom `AuthCard`'s split base — max 880, radius 24,
|
|
9
|
+
* 1px border, two equal columns, the right one on the secondary
|
|
10
|
+
* surface; below `md` the right column is dropped, not stacked
|
|
11
|
+
* loading an indeterminate spinner holding the screen's height
|
|
12
|
+
* terms one centred caption linking the Terms of Service and Privacy Policy
|
|
13
|
+
*
|
|
14
|
+
* Layout is NativeWind `className` (breakpoints included). Type stays on
|
|
15
|
+
* Bloom `Text`'s own ramp through `style` — a `className` there drops its
|
|
16
|
+
* default family — and colours come from the Bloom theme.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type React from 'react';
|
|
20
|
+
import { ActivityIndicator, Linking, Text as RNText } from 'react-native';
|
|
21
|
+
import { View } from 'react-native-css/components';
|
|
22
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
23
|
+
import { Text } from '@oxy.so/bloom/typography';
|
|
24
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
25
|
+
import { LogoIcon } from '../logo/LogoIcon';
|
|
26
|
+
|
|
27
|
+
const LOGO_HEIGHT = 56;
|
|
28
|
+
const TERMS_URL = 'https://oxy.so/company/transparency/policies/terms-of-service';
|
|
29
|
+
const PRIVACY_URL = 'https://oxy.so/company/transparency/policies/privacy';
|
|
30
|
+
|
|
31
|
+
const TITLE = { fontSize: 48, lineHeight: 48, fontWeight: '800', letterSpacing: -1.2 } as const;
|
|
32
|
+
const DESCRIPTION = { fontSize: 18, lineHeight: 28 } as const;
|
|
33
|
+
const TERMS = { fontSize: 14, lineHeight: 20, textAlign: 'center', paddingHorizontal: 24 } as const;
|
|
34
|
+
|
|
35
|
+
export interface OxyAuthScreenHeaderProps {
|
|
36
|
+
title: string;
|
|
37
|
+
description?: React.ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The Oxy mark over the screen's title and description. */
|
|
41
|
+
export const OxyAuthScreenHeader: React.FC<OxyAuthScreenHeaderProps> = ({ title, description }) => {
|
|
42
|
+
const theme = useTheme();
|
|
43
|
+
return (
|
|
44
|
+
<View className="gap-6">
|
|
45
|
+
<LogoIcon height={LOGO_HEIGHT} />
|
|
46
|
+
<View className="max-w-[90%] gap-2">
|
|
47
|
+
<Text accessibilityRole="header" style={[TITLE, { color: theme.colors.text }]}>
|
|
48
|
+
{title}
|
|
49
|
+
</Text>
|
|
50
|
+
{description != null && description !== '' ? (
|
|
51
|
+
typeof description === 'string' ? (
|
|
52
|
+
<Text style={[DESCRIPTION, { color: theme.colors.textSecondary }]}>
|
|
53
|
+
{description}
|
|
54
|
+
</Text>
|
|
55
|
+
) : (
|
|
56
|
+
description
|
|
57
|
+
)
|
|
58
|
+
) : null}
|
|
59
|
+
</View>
|
|
60
|
+
</View>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** A sign-in screen's column: its blocks 24 apart. `className` extends it (the split's form column). */
|
|
65
|
+
export const OxyAuthScreen: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className }) => (
|
|
66
|
+
<View className={`w-full max-w-[448px] self-center gap-6 ${className ?? ''}`}>{children}</View>
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
/** The split card: `children` on the left and, from `md`, `aside` on the right. */
|
|
70
|
+
export const OxyAuthSplit: React.FC<{ children: React.ReactNode; aside: React.ReactNode }> = ({ children, aside }) => {
|
|
71
|
+
const theme = useTheme();
|
|
72
|
+
return (
|
|
73
|
+
<View
|
|
74
|
+
className="w-full self-center md:max-w-[880px] md:flex-row md:rounded-3xl md:border md:border-border md:bg-card md:overflow-hidden"
|
|
75
|
+
>
|
|
76
|
+
{/* Padding on an inner box: a padded flex item cannot shrink its base
|
|
77
|
+
size below its padding, which breaks the two equal tracks. */}
|
|
78
|
+
<View className="md:flex-1 md:basis-0 md:min-w-0">
|
|
79
|
+
<View className="md:p-8">{children}</View>
|
|
80
|
+
</View>
|
|
81
|
+
<View
|
|
82
|
+
className="hidden md:flex md:flex-1 md:basis-0 md:min-w-0 items-center justify-center overflow-hidden p-8"
|
|
83
|
+
style={{ backgroundColor: theme.colors.backgroundSecondary }}
|
|
84
|
+
>
|
|
85
|
+
{aside}
|
|
86
|
+
</View>
|
|
87
|
+
</View>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The screen while there is nothing to show yet. React Native's own indicator:
|
|
93
|
+
* `@oxy.so/bloom/loading` can tree-shake to `undefined` in a rolldown-vite
|
|
94
|
+
* production bundle when co-imported with `@oxy.so/bloom/button`.
|
|
95
|
+
*/
|
|
96
|
+
export const OxyAuthLoading: React.FC = () => {
|
|
97
|
+
const theme = useTheme();
|
|
98
|
+
return (
|
|
99
|
+
<View className="min-h-[300px] items-center justify-center">
|
|
100
|
+
<ActivityIndicator size="large" color={theme.colors.primary} />
|
|
101
|
+
</View>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/** "By continuing, you agree to our Terms of Service and Privacy Policy." */
|
|
106
|
+
export const OxyAuthTerms: React.FC = () => {
|
|
107
|
+
const theme = useTheme();
|
|
108
|
+
const { t } = useI18n();
|
|
109
|
+
const link = { color: theme.colors.text, textDecorationLine: 'underline' as const };
|
|
110
|
+
return (
|
|
111
|
+
<Text style={[TERMS, { color: theme.colors.textSecondary }]}>
|
|
112
|
+
{t('signin.terms.before')}{' '}
|
|
113
|
+
<RNText accessibilityRole="link" style={link} onPress={() => void Linking.openURL(TERMS_URL)}>
|
|
114
|
+
{t('signin.terms.termsLink')}
|
|
115
|
+
</RNText>{' '}
|
|
116
|
+
{t('signin.terms.and')}{' '}
|
|
117
|
+
<RNText accessibilityRole="link" style={link} onPress={() => void Linking.openURL(PRIVACY_URL)}>
|
|
118
|
+
{t('signin.terms.privacyLink')}
|
|
119
|
+
</RNText>
|
|
120
|
+
.
|
|
121
|
+
</Text>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creating an Oxy account on the web (ADR 0029 D3), auth.oxy.so's `/signup`:
|
|
3
|
+
*
|
|
4
|
+
* username → recovery email → the code sent to it → passkey → signed in
|
|
5
|
+
*
|
|
6
|
+
* A web account is a username, a passkey and a recovery email — no password, no
|
|
7
|
+
* phrase, no key. The email is confirmed before the account exists, and is
|
|
8
|
+
* used only to get back in (`OxyRecoverAccountPanel`). Commons stays the way to
|
|
9
|
+
* hold your own key: the first step says so, and linking Commons later makes
|
|
10
|
+
* the account self-custodied and deletes the email.
|
|
11
|
+
*
|
|
12
|
+
* Only on auth.oxy.so: the passkey belongs to that origin (RP ID `oxy.so`,
|
|
13
|
+
* asserted only there), and an app's dialog opens this page in a window
|
|
14
|
+
* (`OxySignUpPanel`'s `onCreateOnWeb`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type React from 'react';
|
|
18
|
+
import { useState } from 'react';
|
|
19
|
+
import { Linking, Platform } from 'react-native';
|
|
20
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
21
|
+
import { toast } from '@oxy.so/bloom/toast';
|
|
22
|
+
import { DeviceManager } from '@oxy.so/core';
|
|
23
|
+
import { emailAddressSchema } from '@oxy.so/contracts';
|
|
24
|
+
import { useOxy } from '../../context/OxyContext';
|
|
25
|
+
import { runPasskeyRegisterSignIn } from '../../context/passkeyFlow';
|
|
26
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
27
|
+
import { getCommonsAcquisitionUrl } from '../../utils/commonsStoreLinks';
|
|
28
|
+
import { isPasskeySupported, runRegistrationCeremony } from '../../../webauthn/passkeyClient';
|
|
29
|
+
import { SubtleLink } from '../authChooser/primitives';
|
|
30
|
+
import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthTerms } from './OxyAuthScreen';
|
|
31
|
+
import {
|
|
32
|
+
AccountFlowAction,
|
|
33
|
+
AccountFlowErrorLine,
|
|
34
|
+
AccountFlowField,
|
|
35
|
+
EmailCodeStep,
|
|
36
|
+
describeAccountFlowError,
|
|
37
|
+
isTicketExpired,
|
|
38
|
+
} from './accountFlowParts';
|
|
39
|
+
|
|
40
|
+
type Step =
|
|
41
|
+
| { name: 'username' }
|
|
42
|
+
| { name: 'email' }
|
|
43
|
+
| { name: 'code'; verificationId: string }
|
|
44
|
+
| { name: 'passkey'; emailTicket: string };
|
|
45
|
+
|
|
46
|
+
export interface OxyCreateAccountPanelProps {
|
|
47
|
+
/** The account exists and this origin is signed in as it. */
|
|
48
|
+
onSignedIn: () => void;
|
|
49
|
+
/** "Already have an account? Sign in". */
|
|
50
|
+
onSignIn: () => void;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const OxyCreateAccountPanel: React.FC<OxyCreateAccountPanelProps> = ({ onSignedIn, onSignIn }) => {
|
|
54
|
+
const theme = useTheme();
|
|
55
|
+
const { t } = useI18n();
|
|
56
|
+
const { oxyServices, handleWebSession } = useOxy();
|
|
57
|
+
const [step, setStep] = useState<Step>({ name: 'username' });
|
|
58
|
+
const [username, setUsername] = useState('');
|
|
59
|
+
const [email, setEmail] = useState('');
|
|
60
|
+
const [pending, setPending] = useState(false);
|
|
61
|
+
const [error, setError] = useState<string | null>(null);
|
|
62
|
+
|
|
63
|
+
const run = (work: () => Promise<void>) => {
|
|
64
|
+
if (pending) return;
|
|
65
|
+
setError(null);
|
|
66
|
+
setPending(true);
|
|
67
|
+
work()
|
|
68
|
+
.catch((reason: unknown) => {
|
|
69
|
+
if (isTicketExpired(reason)) setStep({ name: 'email' });
|
|
70
|
+
setError(describeAccountFlowError(reason, t));
|
|
71
|
+
})
|
|
72
|
+
.finally(() => setPending(false));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const submitUsername = () => {
|
|
76
|
+
const handle = username.trim();
|
|
77
|
+
if (!handle) {
|
|
78
|
+
setError(t('signup.username.required'));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
run(async () => {
|
|
82
|
+
const { available } = await oxyServices.checkUsernameAvailability(handle);
|
|
83
|
+
if (!available) throw new Error(t('signup.username.taken'));
|
|
84
|
+
setStep({ name: 'email' });
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const sendCode = async (address: string) => {
|
|
89
|
+
const { verificationId } = await oxyServices.startEmailVerification({ purpose: 'signup', email: address });
|
|
90
|
+
setStep({ name: 'code', verificationId });
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const submitEmail = () => {
|
|
94
|
+
const parsed = emailAddressSchema.safeParse(email);
|
|
95
|
+
if (!parsed.success) {
|
|
96
|
+
setError(t('signup.email.invalid'));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
setEmail(parsed.data);
|
|
100
|
+
run(() => sendCode(parsed.data));
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// The ceremony opens the browser's passkey prompt, so it starts from the press.
|
|
104
|
+
const createPasskey = (emailTicket: string) =>
|
|
105
|
+
run(() =>
|
|
106
|
+
runPasskeyRegisterSignIn({
|
|
107
|
+
isSupported: isPasskeySupported,
|
|
108
|
+
getRegisterOptions: () => oxyServices.webauthnRegisterOptions({ username: username.trim() }),
|
|
109
|
+
runCeremony: runRegistrationCeremony,
|
|
110
|
+
registerVerify: (response) =>
|
|
111
|
+
oxyServices.webauthnRegisterVerify(response, {
|
|
112
|
+
username: username.trim(),
|
|
113
|
+
email,
|
|
114
|
+
emailTicket,
|
|
115
|
+
deviceFingerprint: JSON.stringify(DeviceManager.getDeviceFingerprint()),
|
|
116
|
+
}),
|
|
117
|
+
commit: async (session) => {
|
|
118
|
+
await handleWebSession(session);
|
|
119
|
+
onSignedIn();
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const getCommons = () => {
|
|
125
|
+
Promise.resolve()
|
|
126
|
+
.then(() => Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)))
|
|
127
|
+
.catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
switch (step.name) {
|
|
131
|
+
case 'code':
|
|
132
|
+
return (
|
|
133
|
+
<EmailCodeStep
|
|
134
|
+
description={t('emailCode.sentTo', { email })}
|
|
135
|
+
verificationId={step.verificationId}
|
|
136
|
+
onConfirmed={({ ticket }) => {
|
|
137
|
+
setError(null);
|
|
138
|
+
setStep({ name: 'passkey', emailTicket: ticket });
|
|
139
|
+
}}
|
|
140
|
+
onResend={() => sendCode(email)}
|
|
141
|
+
back={{ label: t('emailCode.changeEmail'), onPress: () => setStep({ name: 'email' }) }}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
case 'passkey':
|
|
145
|
+
return (
|
|
146
|
+
<OxyAuthScreen>
|
|
147
|
+
<OxyAuthScreenHeader title={t('signup.passkey.title')} description={t('signup.passkey.subtitle')} />
|
|
148
|
+
{error ? <AccountFlowErrorLine message={error} /> : null}
|
|
149
|
+
<AccountFlowAction
|
|
150
|
+
label={t('signup.passkey.action')}
|
|
151
|
+
onPress={() => createPasskey(step.emailTicket)}
|
|
152
|
+
pending={pending}
|
|
153
|
+
testID="signup-create-passkey"
|
|
154
|
+
/>
|
|
155
|
+
<OxyAuthTerms />
|
|
156
|
+
</OxyAuthScreen>
|
|
157
|
+
);
|
|
158
|
+
case 'email':
|
|
159
|
+
return (
|
|
160
|
+
<OxyAuthScreen>
|
|
161
|
+
<OxyAuthScreenHeader title={t('signup.email.title')} description={t('signup.email.subtitle')} />
|
|
162
|
+
<AccountFlowField
|
|
163
|
+
label={t('signup.email.label')}
|
|
164
|
+
value={email}
|
|
165
|
+
onChange={(value) => {
|
|
166
|
+
setEmail(value);
|
|
167
|
+
if (error) setError(null);
|
|
168
|
+
}}
|
|
169
|
+
onSubmit={submitEmail}
|
|
170
|
+
error={error}
|
|
171
|
+
disabled={pending}
|
|
172
|
+
placeholder={t('signup.email.placeholder')}
|
|
173
|
+
autoComplete="email"
|
|
174
|
+
keyboardType="email-address"
|
|
175
|
+
testID="signup-email"
|
|
176
|
+
/>
|
|
177
|
+
<AccountFlowAction label={t('signin.actions.continue')} onPress={submitEmail} pending={pending} testID="signup-email-continue" />
|
|
178
|
+
<SubtleLink label={t('signin.actions.back')} theme={theme} onPress={() => setStep({ name: 'username' })} testID="signup-back" />
|
|
179
|
+
<OxyAuthTerms />
|
|
180
|
+
</OxyAuthScreen>
|
|
181
|
+
);
|
|
182
|
+
default:
|
|
183
|
+
return (
|
|
184
|
+
<OxyAuthScreen>
|
|
185
|
+
<OxyAuthScreenHeader title={t('signup.title')} description={t('signup.webSubtitle')} />
|
|
186
|
+
<AccountFlowField
|
|
187
|
+
label={t('signup.username.label')}
|
|
188
|
+
value={username}
|
|
189
|
+
onChange={(value) => {
|
|
190
|
+
setUsername(value);
|
|
191
|
+
if (error) setError(null);
|
|
192
|
+
}}
|
|
193
|
+
onSubmit={submitUsername}
|
|
194
|
+
error={error}
|
|
195
|
+
disabled={pending}
|
|
196
|
+
placeholder={t('signup.username.placeholder')}
|
|
197
|
+
autoComplete="username"
|
|
198
|
+
testID="signup-username"
|
|
199
|
+
/>
|
|
200
|
+
<AccountFlowAction label={t('signin.actions.continue')} onPress={submitUsername} pending={pending} testID="signup-username-continue" />
|
|
201
|
+
<SubtleLink label={t('signup.commonsInstead')} theme={theme} onPress={getCommons} testID="signup-commons-instead" />
|
|
202
|
+
<SubtleLink label={t('signup.backToSignInLink')} theme={theme} onPress={onSignIn} testID="back-to-sign-in" />
|
|
203
|
+
<OxyAuthTerms />
|
|
204
|
+
</OxyAuthScreen>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
};
|