@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,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE Oxy sign-in screen. The account dialog every Oxy app opens and the
|
|
3
|
+
* auth.oxy.so page render this one component; only where it is mounted
|
|
4
|
+
* differs (`host`).
|
|
5
|
+
*
|
|
6
|
+
* picker a returning device: "Choose an account", then "Use another account"
|
|
7
|
+
* entry the header, the Commons way in, and the way in for someone with no
|
|
8
|
+
* account. On auth.oxy.so (`page`) also the username with its
|
|
9
|
+
* Continue — a username-first passkey sign-in, which takes a
|
|
10
|
+
* platform passkey AND a hardware security key with no resident
|
|
11
|
+
* credential (a U2F key such as a Titan) — and "or continue with" the
|
|
12
|
+
* discoverable passkey. From `md` that page is Bloom `AuthCard`'s
|
|
13
|
+
* split card, with the embedded QR over its photo carousel in the
|
|
14
|
+
* right column; below `md` it is "Continue with Oxy" at the top.
|
|
15
|
+
* In an app's dialog on the web, "Continue with Oxy" opens that page
|
|
16
|
+
* in a window over the app, like "Sign in with Google": the browser's
|
|
17
|
+
* session lives on auth.oxy.so, so every Oxy app shares it. On
|
|
18
|
+
* native it is "Continue with Oxy" ("Get Commons" without Commons).
|
|
19
|
+
*
|
|
20
|
+
* `signInMethods.ts` owns which blocks a platform gets.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type React from 'react';
|
|
24
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
25
|
+
import { Linking, Platform, Text as RNText, StyleSheet, View } from 'react-native';
|
|
26
|
+
import { View as CssView } from 'react-native-css/components';
|
|
27
|
+
import { AuthMediaCarousel } from '@oxy.so/bloom/auth-card';
|
|
28
|
+
import { Button } from '@oxy.so/bloom/button';
|
|
29
|
+
import { Divider } from '@oxy.so/bloom/divider';
|
|
30
|
+
import { RiKey2Line } from '@oxy.so/bloom/icons/RiKey2Line';
|
|
31
|
+
import { RiQrCodeLine } from '@oxy.so/bloom/icons/RiQrCodeLine';
|
|
32
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
33
|
+
import { TextField, TextFieldHint, TextFieldInput, TextFieldLabel } from '@oxy.so/bloom/text-field';
|
|
34
|
+
import { toast } from '@oxy.so/bloom/toast';
|
|
35
|
+
import { Text } from '@oxy.so/bloom/typography';
|
|
36
|
+
import type { SwitcherContextRow } from '@oxy.so/core';
|
|
37
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
38
|
+
import { useOxy } from '../../context/OxyContext';
|
|
39
|
+
import { useAccountDialogSnapshot } from '../../hooks/accountDialogSnapshot';
|
|
40
|
+
import { useDeviceSwitcher } from '../../hooks/useDeviceSwitcher';
|
|
41
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
42
|
+
import { getCommonsAcquisitionUrl } from '../../utils/commonsStoreLinks';
|
|
43
|
+
import { isWebBrowser } from '../../utils/isWebBrowser';
|
|
44
|
+
import { SubtleLink } from '../authChooser/primitives';
|
|
45
|
+
import { SIGN_IN_SLIDES } from './artwork';
|
|
46
|
+
import { InlineCommonsQr } from './InlineCommonsQr';
|
|
47
|
+
import { OxyAccountPicker } from './OxyAccountPicker';
|
|
48
|
+
import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthSplit, OxyAuthTerms } from './OxyAuthScreen';
|
|
49
|
+
import { RATE_LIMIT_SECONDS, describePasskeyError, isRateLimited } from './passkeyError';
|
|
50
|
+
import { resolveSignInMethods } from './signInMethods';
|
|
51
|
+
|
|
52
|
+
export interface OxySignInPanelProps {
|
|
53
|
+
/** This screen signed the origin in. */
|
|
54
|
+
onSignedIn: () => void;
|
|
55
|
+
/** "New to Oxy? Create one". */
|
|
56
|
+
onCreateAccount: () => void;
|
|
57
|
+
/** "Lost your passkey? Recover your account" — auth.oxy.so's page only. */
|
|
58
|
+
onRecover?: () => void;
|
|
59
|
+
/** A handle to pre-fill, skipping the picker (a re-authentication). */
|
|
60
|
+
loginHint?: string;
|
|
61
|
+
/** The app being continued to, when there is one. */
|
|
62
|
+
appName?: string | null;
|
|
63
|
+
/**
|
|
64
|
+
* `dialog` — inside the account dialog, which the controller closes itself
|
|
65
|
+
* once a request it runs signs in, and where a request shows in place.
|
|
66
|
+
* `page` — a page of its own (auth.oxy.so): a request opens the dialog to
|
|
67
|
+
* show it, and its completion is reported through `onSignedIn` too.
|
|
68
|
+
*/
|
|
69
|
+
host?: 'dialog' | 'page';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
73
|
+
onSignedIn,
|
|
74
|
+
onCreateAccount,
|
|
75
|
+
onRecover,
|
|
76
|
+
loginHint,
|
|
77
|
+
appName = null,
|
|
78
|
+
host = 'page',
|
|
79
|
+
}) => {
|
|
80
|
+
const theme = useTheme();
|
|
81
|
+
const { t } = useI18n();
|
|
82
|
+
const queryClient = useQueryClient();
|
|
83
|
+
const { accountDialogController: controller, openAccountDialog, signInWithPasskey, continueOnAuth } = useOxy();
|
|
84
|
+
const snapshot = useAccountDialogSnapshot(controller);
|
|
85
|
+
const { principals, activeContext } = useDeviceSwitcher();
|
|
86
|
+
|
|
87
|
+
const methods = resolveSignInMethods({
|
|
88
|
+
web: isWebBrowser(),
|
|
89
|
+
host,
|
|
90
|
+
commonsAvailability: snapshot.commonsAvailability,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const [showForm, setShowForm] = useState(Boolean(loginHint));
|
|
94
|
+
const [identifier, setIdentifier] = useState(loginHint ?? '');
|
|
95
|
+
const [pending, setPending] = useState(false);
|
|
96
|
+
const [error, setError] = useState<string | null>(null);
|
|
97
|
+
const [rateLimitSeconds, setRateLimitSeconds] = useState(0);
|
|
98
|
+
const blocked = pending || rateLimitSeconds > 0;
|
|
99
|
+
|
|
100
|
+
// The countdown after a 429: one tick a second until the person may retry.
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (rateLimitSeconds <= 0) return;
|
|
103
|
+
const timer = setTimeout(() => setRateLimitSeconds((seconds) => Math.max(0, seconds - 1)), 1000);
|
|
104
|
+
return () => clearTimeout(timer);
|
|
105
|
+
}, [rateLimitSeconds]);
|
|
106
|
+
|
|
107
|
+
// On a page, a request the controller runs (the embedded QR, or one shown in
|
|
108
|
+
// the dialog opened over it) finishes the page's sign-in too. Only one that
|
|
109
|
+
// STARTED here: a completion already on the controller is somebody else's.
|
|
110
|
+
const [mountedAttempt] = useState(snapshot.signIn.attempt);
|
|
111
|
+
const completedHere = snapshot.signIn.phase === 'completed' && snapshot.signIn.attempt !== mountedAttempt;
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (host === 'page' && completedHere) onSignedIn();
|
|
114
|
+
}, [host, completedHere, onSignedIn]);
|
|
115
|
+
|
|
116
|
+
/** Show the request a controller call just started — the dialog is where it lives. */
|
|
117
|
+
const showRequest = useCallback(() => {
|
|
118
|
+
if (host === 'page') openAccountDialog('qr');
|
|
119
|
+
}, [host, openAccountDialog]);
|
|
120
|
+
|
|
121
|
+
// These open a window or leave the page, so they run straight from the
|
|
122
|
+
// press, before any await.
|
|
123
|
+
const continueWithOxy = () => {
|
|
124
|
+
void controller?.signInWithOxy();
|
|
125
|
+
showRequest();
|
|
126
|
+
};
|
|
127
|
+
const signInOnOxy = () => {
|
|
128
|
+
void continueOnAuth('signin').then((result) => {
|
|
129
|
+
if (result.status === 'signed-in') onSignedIn();
|
|
130
|
+
else if (result.status === 'failed') toast.error(t('signin.errors.failed'));
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const useAnotherDevice = () => {
|
|
134
|
+
void controller?.showQr();
|
|
135
|
+
showRequest();
|
|
136
|
+
};
|
|
137
|
+
const getCommons = () => {
|
|
138
|
+
Promise.resolve()
|
|
139
|
+
.then(() => Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)))
|
|
140
|
+
.catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const runPasskey = async (username: string | undefined, failToast: string) => {
|
|
144
|
+
if (blocked) return;
|
|
145
|
+
setError(null);
|
|
146
|
+
setPending(true);
|
|
147
|
+
try {
|
|
148
|
+
await signInWithPasskey({ username });
|
|
149
|
+
onSignedIn();
|
|
150
|
+
} catch (err) {
|
|
151
|
+
if (isRateLimited(err)) {
|
|
152
|
+
setRateLimitSeconds(RATE_LIMIT_SECONDS);
|
|
153
|
+
} else {
|
|
154
|
+
const message = describePasskeyError(err, t);
|
|
155
|
+
setError(message);
|
|
156
|
+
toast.error(failToast, { description: message });
|
|
157
|
+
}
|
|
158
|
+
} finally {
|
|
159
|
+
setPending(false);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const submitUsername = () => {
|
|
163
|
+
const username = identifier.trim();
|
|
164
|
+
if (username) void runPasskey(username, t('signin.errors.failed'));
|
|
165
|
+
else setError(t('signin.username.required'));
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// A returning device starts at WHO. Not while adding an account from inside
|
|
169
|
+
// a signed-in app: the rows are the accounts it would add.
|
|
170
|
+
const pickerAllowed = host === 'dialog' ? !snapshot.hasSession : activeContext !== null;
|
|
171
|
+
const reauthenticate = (context: SwitcherContextRow) => {
|
|
172
|
+
setIdentifier(context.handle ?? '');
|
|
173
|
+
setShowForm(true);
|
|
174
|
+
};
|
|
175
|
+
const selectContext = async (context: SwitcherContextRow) => {
|
|
176
|
+
const outcome = await controller?.chooseContext(context.contextId).catch(() => 'failed' as const);
|
|
177
|
+
switch (outcome) {
|
|
178
|
+
case 'switched':
|
|
179
|
+
// Every account-scoped query now describes somebody else.
|
|
180
|
+
void queryClient.invalidateQueries();
|
|
181
|
+
onSignedIn();
|
|
182
|
+
return;
|
|
183
|
+
case 'current':
|
|
184
|
+
onSignedIn();
|
|
185
|
+
return;
|
|
186
|
+
case 'signing-in':
|
|
187
|
+
// The request for that account is running; it shows where requests do.
|
|
188
|
+
showRequest();
|
|
189
|
+
return;
|
|
190
|
+
case 'failed':
|
|
191
|
+
// The pair could not be activated as it stands: sign in as it explicitly.
|
|
192
|
+
if (methods.passkey && context.handle) reauthenticate(context);
|
|
193
|
+
else toast.error(t('accountSwitcher.toasts.activateFailed'));
|
|
194
|
+
return;
|
|
195
|
+
default:
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const showsPicker = pickerAllowed && !showForm && principals.length > 0;
|
|
201
|
+
// auth.oxy.so's page is the split card from `md`.
|
|
202
|
+
const splits = methods.commons === 'qr';
|
|
203
|
+
|
|
204
|
+
if (showsPicker) {
|
|
205
|
+
return (
|
|
206
|
+
<OxyAccountPicker
|
|
207
|
+
principals={principals}
|
|
208
|
+
appName={appName}
|
|
209
|
+
signedOut={!snapshot.hasSession}
|
|
210
|
+
pendingContextId={snapshot.activatingContextId}
|
|
211
|
+
isLoading={snapshot.activatingContextId !== null}
|
|
212
|
+
onSelectContext={(context) => void selectContext(context)}
|
|
213
|
+
onUseAnother={() => {
|
|
214
|
+
setIdentifier('');
|
|
215
|
+
setShowForm(true);
|
|
216
|
+
}}
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const shownError = rateLimitSeconds > 0 ? t('signin.errors.rateLimited', { seconds: rateLimitSeconds }) : error;
|
|
222
|
+
|
|
223
|
+
const adding = host === 'dialog' && snapshot.hasSession;
|
|
224
|
+
const title = adding ? t('signin.addAccountTitle') : t('signin.title');
|
|
225
|
+
const description = adding
|
|
226
|
+
? t('signin.addAccountSubtitle')
|
|
227
|
+
: appName
|
|
228
|
+
? t('signin.subtitleToApp', { app: appName })
|
|
229
|
+
: t('signin.subtitle');
|
|
230
|
+
const noAccount = (
|
|
231
|
+
<Text style={[styles.note, styles.noAccount, { color: theme.colors.textSecondary }]}>
|
|
232
|
+
{t('signin.noAccount')}{' '}
|
|
233
|
+
<RNText
|
|
234
|
+
accessibilityRole="link"
|
|
235
|
+
onPress={onCreateAccount}
|
|
236
|
+
style={[styles.noAccountLink, { color: theme.colors.text }]}
|
|
237
|
+
testID="create-account-link"
|
|
238
|
+
>
|
|
239
|
+
{t('signin.createAccount')}
|
|
240
|
+
</RNText>
|
|
241
|
+
</Text>
|
|
242
|
+
);
|
|
243
|
+
// One solid action per screen: the username's Continue when there is one.
|
|
244
|
+
const commonsAppearance = methods.passkey ? 'outline' : 'solid';
|
|
245
|
+
|
|
246
|
+
const continueWithOxyButton = (
|
|
247
|
+
<Button
|
|
248
|
+
appearance={commonsAppearance}
|
|
249
|
+
tone={commonsAppearance === 'solid' ? 'action' : 'neutral'}
|
|
250
|
+
size="lg"
|
|
251
|
+
fullWidth
|
|
252
|
+
onPress={methods.commons === 'window' ? signInOnOxy : continueWithOxy}
|
|
253
|
+
testID="continue-with-oxy"
|
|
254
|
+
>
|
|
255
|
+
{t('accountSwitcher.continueWithOxy')}
|
|
256
|
+
</Button>
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const form = (
|
|
260
|
+
<OxyAuthScreen className={splits ? 'md:max-w-none' : undefined}>
|
|
261
|
+
<OxyAuthScreenHeader title={title} description={description} />
|
|
262
|
+
|
|
263
|
+
{/* Below `md` this screen is the phone a QR would be scanned with. */}
|
|
264
|
+
{splits ? <CssView className="md:hidden">{continueWithOxyButton}</CssView> : null}
|
|
265
|
+
|
|
266
|
+
{methods.commons === 'continue' || methods.commons === 'window' ? continueWithOxyButton : null}
|
|
267
|
+
{methods.commons === 'get-commons' ? (
|
|
268
|
+
<View style={styles.stack}>
|
|
269
|
+
<Text style={[styles.note, { color: theme.colors.textSecondary }]}>{t('accountSwitcher.commonsNotInstalled')}</Text>
|
|
270
|
+
<Button appearance="solid" tone="action" size="lg" fullWidth onPress={getCommons} testID="get-commons-button">
|
|
271
|
+
{t('accountSwitcher.getCommons')}
|
|
272
|
+
</Button>
|
|
273
|
+
</View>
|
|
274
|
+
) : null}
|
|
275
|
+
|
|
276
|
+
{methods.passkey ? (
|
|
277
|
+
<View style={styles.stack}>
|
|
278
|
+
<View style={styles.field}>
|
|
279
|
+
<TextFieldLabel nativeID="username-label">{t('signin.username.label')}</TextFieldLabel>
|
|
280
|
+
<TextField invalid={shownError !== null} disabled={blocked} radius={999} style={styles.input}>
|
|
281
|
+
<TextFieldInput
|
|
282
|
+
testID="username"
|
|
283
|
+
label={t('signin.username.label')}
|
|
284
|
+
value={identifier}
|
|
285
|
+
onValueChange={(value) => {
|
|
286
|
+
setIdentifier(value);
|
|
287
|
+
if (error) setError(null);
|
|
288
|
+
}}
|
|
289
|
+
placeholder={t('signin.username.placeholder')}
|
|
290
|
+
autoComplete="username"
|
|
291
|
+
autoCapitalize="none"
|
|
292
|
+
autoCorrect={false}
|
|
293
|
+
autoFocus={Platform.OS === 'web'}
|
|
294
|
+
returnKeyType="go"
|
|
295
|
+
onSubmitEditing={submitUsername}
|
|
296
|
+
aria-required
|
|
297
|
+
/>
|
|
298
|
+
</TextField>
|
|
299
|
+
{shownError ? <TextFieldHint invalid>{shownError}</TextFieldHint> : null}
|
|
300
|
+
</View>
|
|
301
|
+
{noAccount}
|
|
302
|
+
<Button
|
|
303
|
+
appearance="solid"
|
|
304
|
+
tone="action"
|
|
305
|
+
size="lg"
|
|
306
|
+
fullWidth
|
|
307
|
+
loading={pending}
|
|
308
|
+
disabled={blocked}
|
|
309
|
+
onPress={submitUsername}
|
|
310
|
+
testID="username-continue"
|
|
311
|
+
>
|
|
312
|
+
{t('signin.actions.continue')}
|
|
313
|
+
</Button>
|
|
314
|
+
</View>
|
|
315
|
+
) : null}
|
|
316
|
+
|
|
317
|
+
{/* The alternatives to the screen's primary way in, always under it. The
|
|
318
|
+
window an app opens on the web is where they all are. */}
|
|
319
|
+
{methods.commons === 'window' ? null : <Divider>{t('signin.orContinueWith')}</Divider>}
|
|
320
|
+
|
|
321
|
+
{methods.passkey ? (
|
|
322
|
+
<Button
|
|
323
|
+
appearance="outline"
|
|
324
|
+
tone="neutral"
|
|
325
|
+
size="lg"
|
|
326
|
+
fullWidth
|
|
327
|
+
leadingIcon={RiKey2Line}
|
|
328
|
+
disabled={blocked}
|
|
329
|
+
onPress={() => void runPasskey(undefined, t('signin.errors.failed'))}
|
|
330
|
+
testID="passkey-sign-in"
|
|
331
|
+
>
|
|
332
|
+
{t('signin.methods.passkey')}
|
|
333
|
+
</Button>
|
|
334
|
+
) : methods.commons === 'window' ? null : (
|
|
335
|
+
<Button
|
|
336
|
+
appearance="outline"
|
|
337
|
+
tone="neutral"
|
|
338
|
+
size="lg"
|
|
339
|
+
fullWidth
|
|
340
|
+
leadingIcon={RiQrCodeLine}
|
|
341
|
+
onPress={useAnotherDevice}
|
|
342
|
+
testID="scan-qr"
|
|
343
|
+
>
|
|
344
|
+
{t('accountSwitcher.scanQr')}
|
|
345
|
+
</Button>
|
|
346
|
+
)}
|
|
347
|
+
|
|
348
|
+
{methods.passkey ? null : noAccount}
|
|
349
|
+
{onRecover ? (
|
|
350
|
+
<SubtleLink label={t('signin.recoverLink')} theme={theme} onPress={onRecover} testID="recover-link" />
|
|
351
|
+
) : null}
|
|
352
|
+
<OxyAuthTerms />
|
|
353
|
+
</OxyAuthScreen>
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
if (!splits) return form;
|
|
357
|
+
return (
|
|
358
|
+
<OxyAuthSplit
|
|
359
|
+
aside={
|
|
360
|
+
<>
|
|
361
|
+
<AuthMediaCarousel slides={SIGN_IN_SLIDES} style={StyleSheet.absoluteFill} />
|
|
362
|
+
<InlineCommonsQr controller={controller} />
|
|
363
|
+
</>
|
|
364
|
+
}
|
|
365
|
+
>
|
|
366
|
+
{form}
|
|
367
|
+
</OxyAuthSplit>
|
|
368
|
+
);
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const styles = StyleSheet.create({
|
|
372
|
+
stack: {
|
|
373
|
+
gap: 12,
|
|
374
|
+
},
|
|
375
|
+
field: {
|
|
376
|
+
gap: 6,
|
|
377
|
+
},
|
|
378
|
+
note: {
|
|
379
|
+
fontSize: 14,
|
|
380
|
+
lineHeight: 20,
|
|
381
|
+
textAlign: 'center',
|
|
382
|
+
},
|
|
383
|
+
noAccount: {
|
|
384
|
+
textAlign: 'left',
|
|
385
|
+
},
|
|
386
|
+
noAccountLink: {
|
|
387
|
+
textDecorationLine: 'underline',
|
|
388
|
+
},
|
|
389
|
+
input: {
|
|
390
|
+
height: 40,
|
|
391
|
+
},
|
|
392
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account creation in the account dialog.
|
|
3
|
+
*
|
|
4
|
+
* On the web the account is made on auth.oxy.so, in its window over the app
|
|
5
|
+
* (`onCreateOnWeb`), and this app is signed in as it. On native, Commons
|
|
6
|
+
* creates the identity: straight in when it is installed, "Get Commons"
|
|
7
|
+
* otherwise.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type React from 'react';
|
|
11
|
+
import { useCallback } from 'react';
|
|
12
|
+
import { Linking, Platform } from 'react-native';
|
|
13
|
+
import { Button } from '@oxy.so/bloom/button';
|
|
14
|
+
import { RiKey2Line } from '@oxy.so/bloom/icons/RiKey2Line';
|
|
15
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
16
|
+
import { toast } from '@oxy.so/bloom/toast';
|
|
17
|
+
import { useOxy } from '../../context/OxyContext';
|
|
18
|
+
import { useAccountDialogSnapshot } from '../../hooks/accountDialogSnapshot';
|
|
19
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
20
|
+
import { getCommonsAcquisitionUrl } from '../../utils/commonsStoreLinks';
|
|
21
|
+
import { isWebBrowser } from '../../utils/isWebBrowser';
|
|
22
|
+
import { SubtleLink } from '../authChooser/primitives';
|
|
23
|
+
import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthTerms } from './OxyAuthScreen';
|
|
24
|
+
|
|
25
|
+
/** Commons' own identity-creation deep link. */
|
|
26
|
+
const COMMONS_CREATE_IDENTITY_URL = 'oxycommons://create-identity';
|
|
27
|
+
|
|
28
|
+
export interface OxySignUpPanelProps {
|
|
29
|
+
/** "Already have an account? Sign in". */
|
|
30
|
+
onSignIn: () => void;
|
|
31
|
+
/** The web's one action: auth.oxy.so's sign-up, in its window. */
|
|
32
|
+
onCreateOnWeb: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignIn, onCreateOnWeb }) => {
|
|
36
|
+
const theme = useTheme();
|
|
37
|
+
const { t } = useI18n();
|
|
38
|
+
const { accountDialogController: controller } = useOxy();
|
|
39
|
+
const snapshot = useAccountDialogSnapshot(controller);
|
|
40
|
+
const web = isWebBrowser();
|
|
41
|
+
|
|
42
|
+
const openExternal = useCallback(
|
|
43
|
+
(url: string) => {
|
|
44
|
+
Promise.resolve()
|
|
45
|
+
.then(() => Linking.openURL(url))
|
|
46
|
+
.catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
|
|
47
|
+
},
|
|
48
|
+
[t],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const commonsInstalled = snapshot.commonsAvailability === 'available';
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<OxyAuthScreen>
|
|
55
|
+
<OxyAuthScreenHeader title={t('signup.title')} description={web ? t('signup.webSubtitle') : t('signup.subtitle')} />
|
|
56
|
+
{web ? (
|
|
57
|
+
<Button
|
|
58
|
+
appearance="solid"
|
|
59
|
+
tone="action"
|
|
60
|
+
size="lg"
|
|
61
|
+
fullWidth
|
|
62
|
+
leadingIcon={RiKey2Line}
|
|
63
|
+
onPress={onCreateOnWeb}
|
|
64
|
+
testID="signup-open-identity"
|
|
65
|
+
>
|
|
66
|
+
{t('signup.createAccount')}
|
|
67
|
+
</Button>
|
|
68
|
+
) : (
|
|
69
|
+
<Button
|
|
70
|
+
appearance="solid"
|
|
71
|
+
tone="action"
|
|
72
|
+
size="lg"
|
|
73
|
+
fullWidth
|
|
74
|
+
onPress={() =>
|
|
75
|
+
openExternal(commonsInstalled ? COMMONS_CREATE_IDENTITY_URL : getCommonsAcquisitionUrl(Platform.OS))
|
|
76
|
+
}
|
|
77
|
+
testID="signup-commons"
|
|
78
|
+
>
|
|
79
|
+
{commonsInstalled ? t('signup.createInCommons') : t('accountSwitcher.getCommons')}
|
|
80
|
+
</Button>
|
|
81
|
+
)}
|
|
82
|
+
<SubtleLink label={t('signup.backToSignInLink')} theme={theme} onPress={onSignIn} testID="back-to-sign-in" />
|
|
83
|
+
<OxyAuthTerms />
|
|
84
|
+
</OxyAuthScreen>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pieces auth.oxy.so's account pages share (ADR 0029 D3): creating a
|
|
3
|
+
* passkey account, recovering one, deleting one. Each is a page of the IdP
|
|
4
|
+
* built from the same sign-in shell as `OxySignInPanel`, so they read as one
|
|
5
|
+
* product; the passkey belongs to auth.oxy.so, so none of them runs anywhere
|
|
6
|
+
* else.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type React from 'react';
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { StyleSheet, View } from 'react-native';
|
|
12
|
+
import { Button } from '@oxy.so/bloom/button';
|
|
13
|
+
import { useTheme } from '@oxy.so/bloom/theme';
|
|
14
|
+
import { TextField, TextFieldHint, TextFieldInput, TextFieldLabel } from '@oxy.so/bloom/text-field';
|
|
15
|
+
import { Text } from '@oxy.so/bloom/typography';
|
|
16
|
+
import { EMAIL_CODE_LENGTH, EMAIL_VERIFICATION_ERROR_CODES, type EmailVerificationConfirmResponse } from '@oxy.so/contracts';
|
|
17
|
+
import { useOxy } from '../../context/OxyContext';
|
|
18
|
+
import { useI18n } from '../../hooks/useI18n';
|
|
19
|
+
import type { Translate } from '../authChooser/types';
|
|
20
|
+
import { SubtleLink } from '../authChooser/primitives';
|
|
21
|
+
import { OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
|
|
22
|
+
import { describePasskeyError, isRateLimited } from './passkeyError';
|
|
23
|
+
|
|
24
|
+
/** The API error code a thrown SDK error carries (`error.code`), if any. */
|
|
25
|
+
function errorCode(error: unknown): string | undefined {
|
|
26
|
+
const code = (error as { code?: unknown } | null)?.code;
|
|
27
|
+
return typeof code === 'string' ? code : undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A failure of an account page, in the person's language. */
|
|
31
|
+
export function describeAccountFlowError(error: unknown, t: Translate): string {
|
|
32
|
+
switch (errorCode(error)) {
|
|
33
|
+
case EMAIL_VERIFICATION_ERROR_CODES.codeInvalid:
|
|
34
|
+
return t('emailCode.errors.codeInvalid');
|
|
35
|
+
case EMAIL_VERIFICATION_ERROR_CODES.tooManyAttempts:
|
|
36
|
+
return t('emailCode.errors.tooManyAttempts');
|
|
37
|
+
case EMAIL_VERIFICATION_ERROR_CODES.ticketInvalid:
|
|
38
|
+
case EMAIL_VERIFICATION_ERROR_CODES.ticketRequired:
|
|
39
|
+
return t('emailCode.errors.expired');
|
|
40
|
+
case EMAIL_VERIFICATION_ERROR_CODES.unavailable:
|
|
41
|
+
return t('emailCode.errors.unavailable');
|
|
42
|
+
default:
|
|
43
|
+
if (isRateLimited(error)) return t('emailCode.errors.rateLimited');
|
|
44
|
+
return describePasskeyError(error, t);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Whether the confirmation this flow holds is gone and it must start again. */
|
|
49
|
+
export function isTicketExpired(error: unknown): boolean {
|
|
50
|
+
const code = errorCode(error);
|
|
51
|
+
return code === EMAIL_VERIFICATION_ERROR_CODES.ticketInvalid || code === EMAIL_VERIFICATION_ERROR_CODES.ticketRequired;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** One labelled input, the way the sign-in screen draws its username. */
|
|
55
|
+
export const AccountFlowField: React.FC<{
|
|
56
|
+
label: string;
|
|
57
|
+
value: string;
|
|
58
|
+
onChange: (value: string) => void;
|
|
59
|
+
onSubmit: () => void;
|
|
60
|
+
error: string | null;
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
autoComplete?: 'username' | 'email' | 'one-time-code' | 'off';
|
|
64
|
+
keyboardType?: 'default' | 'email-address' | 'number-pad';
|
|
65
|
+
maxLength?: number;
|
|
66
|
+
testID: string;
|
|
67
|
+
}> = ({ label, value, onChange, onSubmit, error, disabled, placeholder, autoComplete, keyboardType, maxLength, testID }) => (
|
|
68
|
+
<View style={styles.field}>
|
|
69
|
+
<TextFieldLabel>{label}</TextFieldLabel>
|
|
70
|
+
<TextField invalid={error !== null} disabled={disabled} radius={999} style={styles.input}>
|
|
71
|
+
<TextFieldInput
|
|
72
|
+
testID={testID}
|
|
73
|
+
label={label}
|
|
74
|
+
value={value}
|
|
75
|
+
onValueChange={onChange}
|
|
76
|
+
placeholder={placeholder}
|
|
77
|
+
autoComplete={autoComplete}
|
|
78
|
+
keyboardType={keyboardType}
|
|
79
|
+
maxLength={maxLength}
|
|
80
|
+
autoCapitalize="none"
|
|
81
|
+
autoCorrect={false}
|
|
82
|
+
autoFocus
|
|
83
|
+
returnKeyType="go"
|
|
84
|
+
onSubmitEditing={onSubmit}
|
|
85
|
+
aria-required
|
|
86
|
+
/>
|
|
87
|
+
</TextField>
|
|
88
|
+
{error ? <TextFieldHint invalid>{error}</TextFieldHint> : null}
|
|
89
|
+
</View>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
/** The screen's one primary action. */
|
|
93
|
+
export const AccountFlowAction: React.FC<{
|
|
94
|
+
label: string;
|
|
95
|
+
onPress: () => void;
|
|
96
|
+
pending: boolean;
|
|
97
|
+
disabled?: boolean;
|
|
98
|
+
testID: string;
|
|
99
|
+
}> = ({ label, onPress, pending, disabled, testID }) => (
|
|
100
|
+
<Button appearance="solid" tone="action" size="lg" fullWidth loading={pending} disabled={pending || disabled} onPress={onPress} testID={testID}>
|
|
101
|
+
{label}
|
|
102
|
+
</Button>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
/** A line of body copy under the header. */
|
|
106
|
+
export const AccountFlowNote: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
107
|
+
const theme = useTheme();
|
|
108
|
+
return <Text style={[styles.note, { color: theme.colors.textSecondary }]}>{children}</Text>;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** Why a step failed, where it happened. */
|
|
112
|
+
export const AccountFlowErrorLine: React.FC<{ message: string }> = ({ message }) => {
|
|
113
|
+
const theme = useTheme();
|
|
114
|
+
return (
|
|
115
|
+
<Text accessibilityRole="alert" style={[styles.note, { color: theme.colors.error }]}>
|
|
116
|
+
{message}
|
|
117
|
+
</Text>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export interface EmailCodeStepProps {
|
|
122
|
+
/** What was sent, and where (or, for a recovery, where it may have gone). */
|
|
123
|
+
description: string;
|
|
124
|
+
verificationId: string;
|
|
125
|
+
onConfirmed: (confirmed: EmailVerificationConfirmResponse) => void;
|
|
126
|
+
/** Send a new code; resolves once it is on its way. */
|
|
127
|
+
onResend: () => Promise<void>;
|
|
128
|
+
/** "Use another email" / "Back" — the step before. */
|
|
129
|
+
back: { label: string; onPress: () => void };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** "Check your email": the 6-digit code a verification sent. */
|
|
133
|
+
export const EmailCodeStep: React.FC<EmailCodeStepProps> = ({ description, verificationId, onConfirmed, onResend, back }) => {
|
|
134
|
+
const theme = useTheme();
|
|
135
|
+
const { t } = useI18n();
|
|
136
|
+
const { oxyServices } = useOxy();
|
|
137
|
+
const [code, setCode] = useState('');
|
|
138
|
+
const [pending, setPending] = useState(false);
|
|
139
|
+
const [error, setError] = useState<string | null>(null);
|
|
140
|
+
const [notice, setNotice] = useState<string | null>(null);
|
|
141
|
+
|
|
142
|
+
const confirm = () => {
|
|
143
|
+
const digits = code.replace(/\D/g, '');
|
|
144
|
+
if (digits.length !== EMAIL_CODE_LENGTH || pending) {
|
|
145
|
+
setError(t('emailCode.errors.codeInvalid'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
setError(null);
|
|
149
|
+
setPending(true);
|
|
150
|
+
oxyServices
|
|
151
|
+
.confirmEmailVerification(verificationId, digits)
|
|
152
|
+
.then(onConfirmed)
|
|
153
|
+
.catch((reason: unknown) => setError(describeAccountFlowError(reason, t)))
|
|
154
|
+
.finally(() => setPending(false));
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const resend = () => {
|
|
158
|
+
setError(null);
|
|
159
|
+
setNotice(null);
|
|
160
|
+
setCode('');
|
|
161
|
+
onResend()
|
|
162
|
+
.then(() => setNotice(t('emailCode.resent')))
|
|
163
|
+
.catch((reason: unknown) => setError(describeAccountFlowError(reason, t)));
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<OxyAuthScreen>
|
|
168
|
+
<OxyAuthScreenHeader title={t('emailCode.title')} description={description} />
|
|
169
|
+
<AccountFlowField
|
|
170
|
+
label={t('emailCode.label')}
|
|
171
|
+
value={code}
|
|
172
|
+
onChange={(value) => {
|
|
173
|
+
setCode(value);
|
|
174
|
+
if (error) setError(null);
|
|
175
|
+
}}
|
|
176
|
+
onSubmit={confirm}
|
|
177
|
+
error={error}
|
|
178
|
+
disabled={pending}
|
|
179
|
+
placeholder="000000"
|
|
180
|
+
autoComplete="one-time-code"
|
|
181
|
+
keyboardType="number-pad"
|
|
182
|
+
maxLength={EMAIL_CODE_LENGTH}
|
|
183
|
+
testID="email-code"
|
|
184
|
+
/>
|
|
185
|
+
{notice ? <Text style={[styles.note, { color: theme.colors.textSecondary }]}>{notice}</Text> : null}
|
|
186
|
+
<AccountFlowAction label={t('signin.actions.continue')} onPress={confirm} pending={pending} testID="email-code-continue" />
|
|
187
|
+
<SubtleLink label={t('emailCode.resend')} theme={theme} onPress={resend} disabled={pending} testID="email-code-resend" />
|
|
188
|
+
<SubtleLink label={back.label} theme={theme} onPress={back.onPress} disabled={pending} testID="email-code-back" />
|
|
189
|
+
</OxyAuthScreen>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const styles = StyleSheet.create({
|
|
194
|
+
field: {
|
|
195
|
+
gap: 6,
|
|
196
|
+
},
|
|
197
|
+
input: {
|
|
198
|
+
height: 40,
|
|
199
|
+
},
|
|
200
|
+
note: {
|
|
201
|
+
fontSize: 16,
|
|
202
|
+
lineHeight: 24,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The photos the sign-in split card's carousel turns through. Shipped with the
|
|
3
|
+
* SDK and imported like its icon fonts, so every host serves them from its own
|
|
4
|
+
* origin — nothing to allow in anyone's CSP.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AuthMediaSlide } from '@oxy.so/bloom/auth-card';
|
|
8
|
+
import slide1 from '../../../assets/signIn/slide-1.jpg';
|
|
9
|
+
import slide2 from '../../../assets/signIn/slide-2.jpg';
|
|
10
|
+
import slide3 from '../../../assets/signIn/slide-3.jpg';
|
|
11
|
+
import slide4 from '../../../assets/signIn/slide-4.jpg';
|
|
12
|
+
|
|
13
|
+
export const SIGN_IN_SLIDES: AuthMediaSlide[] = [slide1, slide2, slide3, slide4].map((source) => ({ source }));
|