@oxy.so/services 8.2.0 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/index.js +2 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/BloomLocaleBridge.js +37 -0
- package/lib/commonjs/ui/components/BloomLocaleBridge.js.map +1 -0
- package/lib/commonjs/ui/components/OxyProvider.js +16 -7
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInRequestSurface.js +0 -1
- package/lib/commonjs/ui/components/OxySignInRequestSurface.js.map +1 -1
- package/lib/commonjs/ui/components/RequireOxyAuth.js +9 -1
- package/lib/commonjs/ui/components/RequireOxyAuth.js.map +1 -1
- package/lib/commonjs/ui/components/SurfaceScreen.js +4 -10
- package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js +0 -1
- package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/primitives.js +9 -11
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/requestSurfaces.js +13 -10
- package/lib/commonjs/ui/components/authChooser/requestSurfaces.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/styles.js +4 -1
- package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +2 -2
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js +5 -2
- package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js +13 -17
- package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js +9 -8
- package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyAuthenticatorPanel.js +38 -42
- package/lib/commonjs/ui/components/signIn/OxyAuthenticatorPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js +21 -6
- package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js +4 -2
- package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxyPasswordPanel.js +5 -16
- package/lib/commonjs/ui/components/signIn/OxyPasswordPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxySignInPanel.js +19 -20
- package/lib/commonjs/ui/components/signIn/OxySignInPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js +12 -8
- package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/ReauthStep.js +2 -7
- package/lib/commonjs/ui/components/signIn/ReauthStep.js.map +1 -1
- package/lib/commonjs/ui/components/signIn/accountFlowParts.js +64 -13
- package/lib/commonjs/ui/components/signIn/accountFlowParts.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +25 -4
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/accountQueryPersistence.js +157 -0
- package/lib/commonjs/ui/hooks/accountQueryPersistence.js.map +1 -0
- package/lib/commonjs/ui/hooks/queryClient.js +17 -9
- package/lib/commonjs/ui/hooks/queryClient.js.map +1 -1
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +2 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/buildId.js +25 -0
- package/lib/commonjs/ui/utils/buildId.js.map +1 -0
- package/lib/commonjs/ui/utils/clipboard.js +21 -0
- package/lib/commonjs/ui/utils/clipboard.js.map +1 -0
- package/lib/commonjs/ui/utils/clipboard.native.js +28 -0
- package/lib/commonjs/ui/utils/clipboard.native.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/BloomLocaleBridge.js +33 -0
- package/lib/module/ui/components/BloomLocaleBridge.js.map +1 -0
- package/lib/module/ui/components/OxyProvider.js +16 -7
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInRequestSurface.js +0 -1
- package/lib/module/ui/components/OxySignInRequestSurface.js.map +1 -1
- package/lib/module/ui/components/RequireOxyAuth.js +9 -1
- package/lib/module/ui/components/RequireOxyAuth.js.map +1 -1
- package/lib/module/ui/components/SurfaceScreen.js +5 -11
- package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/module/ui/components/authChooser/TroubleDisclosure.js +0 -1
- package/lib/module/ui/components/authChooser/TroubleDisclosure.js.map +1 -1
- package/lib/module/ui/components/authChooser/primitives.js +11 -12
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/module/ui/components/authChooser/requestSurfaces.js +15 -10
- package/lib/module/ui/components/authChooser/requestSurfaces.js.map +1 -1
- package/lib/module/ui/components/authChooser/styles.js +4 -1
- package/lib/module/ui/components/authChooser/styles.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentDetailsStep.js +3 -3
- package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/module/ui/components/signIn/InlineCommonsQr.js +6 -3
- package/lib/module/ui/components/signIn/InlineCommonsQr.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyAccountPicker.js +13 -17
- package/lib/module/ui/components/signIn/OxyAccountPicker.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyAuthScreen.js +10 -9
- package/lib/module/ui/components/signIn/OxyAuthScreen.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyAuthenticatorPanel.js +40 -44
- package/lib/module/ui/components/signIn/OxyAuthenticatorPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js +22 -7
- package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js +5 -3
- package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/OxyPasswordPanel.js +6 -17
- package/lib/module/ui/components/signIn/OxyPasswordPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/OxySignInPanel.js +20 -21
- package/lib/module/ui/components/signIn/OxySignInPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/OxySignUpPanel.js +13 -9
- package/lib/module/ui/components/signIn/OxySignUpPanel.js.map +1 -1
- package/lib/module/ui/components/signIn/ReauthStep.js +3 -8
- package/lib/module/ui/components/signIn/ReauthStep.js.map +1 -1
- package/lib/module/ui/components/signIn/accountFlowParts.js +60 -11
- package/lib/module/ui/components/signIn/accountFlowParts.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +27 -6
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/accountQueryPersistence.js +153 -0
- package/lib/module/ui/hooks/accountQueryPersistence.js.map +1 -0
- package/lib/module/ui/hooks/queryClient.js +18 -10
- package/lib/module/ui/hooks/queryClient.js.map +1 -1
- package/lib/module/ui/index.js +3 -0
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +3 -2
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/utils/buildId.js +21 -0
- package/lib/module/ui/utils/buildId.js.map +1 -0
- package/lib/module/ui/utils/clipboard.js +17 -0
- package/lib/module/ui/utils/clipboard.js.map +1 -0
- package/lib/module/ui/utils/clipboard.native.js +23 -0
- package/lib/module/ui/utils/clipboard.native.js.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/BloomLocaleBridge.d.ts +19 -0
- package/lib/typescript/commonjs/ui/components/BloomLocaleBridge.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxySignInRequestSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +4 -2
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts +4 -4
- package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts +1 -5
- package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyAuthenticatorPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxyPasswordPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxySignInPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/ReauthStep.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts +29 -2
- package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +9 -0
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/accountQueryPersistence.d.ts +54 -0
- package/lib/typescript/commonjs/ui/hooks/accountQueryPersistence.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hooks/queryClient.d.ts +8 -2
- package/lib/typescript/commonjs/ui/hooks/queryClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/icons/Ionicons.d.ts +1 -1
- package/lib/typescript/commonjs/ui/icons/MaterialCommunityIcons.d.ts +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +1 -0
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +9 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/buildId.d.ts +16 -0
- package/lib/typescript/commonjs/ui/utils/buildId.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/utils/clipboard.d.ts +11 -0
- package/lib/typescript/commonjs/ui/utils/clipboard.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/utils/clipboard.native.d.ts +18 -0
- package/lib/typescript/commonjs/ui/utils/clipboard.native.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/BloomLocaleBridge.d.ts +19 -0
- package/lib/typescript/module/ui/components/BloomLocaleBridge.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxySignInRequestSurface.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +4 -2
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts +4 -4
- package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/styles.d.ts +2 -1
- package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts +1 -5
- package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyAuthenticatorPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxyPasswordPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxySignInPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/ReauthStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts +29 -2
- package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +9 -0
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/accountQueryPersistence.d.ts +54 -0
- package/lib/typescript/module/ui/hooks/accountQueryPersistence.d.ts.map +1 -0
- package/lib/typescript/module/ui/hooks/queryClient.d.ts +8 -2
- package/lib/typescript/module/ui/hooks/queryClient.d.ts.map +1 -1
- package/lib/typescript/module/ui/icons/Ionicons.d.ts +1 -1
- package/lib/typescript/module/ui/icons/MaterialCommunityIcons.d.ts +1 -1
- package/lib/typescript/module/ui/index.d.ts +1 -0
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +9 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/buildId.d.ts +16 -0
- package/lib/typescript/module/ui/utils/buildId.d.ts.map +1 -0
- package/lib/typescript/module/ui/utils/clipboard.d.ts +11 -0
- package/lib/typescript/module/ui/utils/clipboard.d.ts.map +1 -0
- package/lib/typescript/module/ui/utils/clipboard.native.d.ts +18 -0
- package/lib/typescript/module/ui/utils/clipboard.native.d.ts.map +1 -0
- package/package.json +11 -6
- package/src/index.ts +2 -0
- package/src/ui/components/BloomLocaleBridge.tsx +23 -0
- package/src/ui/components/OxyProvider.tsx +18 -9
- package/src/ui/components/OxySignInRequestSurface.tsx +0 -1
- package/src/ui/components/RequireOxyAuth.tsx +7 -2
- package/src/ui/components/SurfaceScreen.tsx +3 -9
- package/src/ui/components/__tests__/BloomLocaleBridge.test.tsx +68 -0
- package/src/ui/components/authChooser/TroubleDisclosure.tsx +0 -1
- package/src/ui/components/authChooser/primitives.tsx +11 -9
- package/src/ui/components/authChooser/requestSurfaces.tsx +9 -8
- package/src/ui/components/authChooser/styles.ts +4 -1
- package/src/ui/components/payment/PaymentDetailsStep.tsx +5 -3
- package/src/ui/components/signIn/InlineCommonsQr.tsx +5 -2
- package/src/ui/components/signIn/OxyAccountPicker.tsx +14 -13
- package/src/ui/components/signIn/OxyAuthScreen.tsx +5 -8
- package/src/ui/components/signIn/OxyAuthenticatorPanel.tsx +33 -45
- package/src/ui/components/signIn/OxyDeleteAccountPanel.tsx +17 -3
- package/src/ui/components/signIn/OxyLinkCommonsPanel.tsx +3 -2
- package/src/ui/components/signIn/OxyPasswordPanel.tsx +6 -12
- package/src/ui/components/signIn/OxySignInPanel.tsx +18 -15
- package/src/ui/components/signIn/OxySignUpPanel.tsx +13 -5
- package/src/ui/components/signIn/ReauthStep.tsx +4 -7
- package/src/ui/components/signIn/accountFlowParts.tsx +61 -7
- package/src/ui/context/OxyContext.tsx +35 -5
- package/src/ui/context/oxyContextTypes.ts +9 -0
- package/src/ui/hooks/accountQueryPersistence.ts +201 -0
- package/src/ui/hooks/queryClient.ts +17 -8
- package/src/ui/index.ts +2 -0
- package/src/ui/screens/AppInfoScreen.tsx +2 -2
- package/src/ui/types/navigation.ts +9 -0
- package/src/ui/utils/buildId.ts +18 -0
- package/src/ui/utils/clipboard.native.ts +20 -0
- package/src/ui/utils/clipboard.ts +14 -0
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
import type React from 'react';
|
|
15
15
|
import { useState } from 'react';
|
|
16
|
-
import {
|
|
16
|
+
import { StyleSheet, View } from 'react-native';
|
|
17
17
|
import QRCode from 'react-native-qrcode-svg';
|
|
18
|
-
import {
|
|
18
|
+
import { CodeBlock } from '@oxy.so/bloom/code';
|
|
19
19
|
import { useTheme } from '@oxy.so/bloom/theme';
|
|
20
20
|
import { toast } from '@oxy.so/bloom/toast';
|
|
21
21
|
import { Text } from '@oxy.so/bloom/typography';
|
|
@@ -25,6 +25,7 @@ import { useOxy } from '../../context/OxyContext';
|
|
|
25
25
|
import { useSignInMethods } from '../../hooks/queries/useAuthMethods';
|
|
26
26
|
import { queryKeys } from '../../hooks/queries/queryKeys';
|
|
27
27
|
import { useI18n } from '../../hooks/useI18n';
|
|
28
|
+
import { copyText } from '../../utils/clipboard';
|
|
28
29
|
import { SubtleLink } from '../authChooser/primitives';
|
|
29
30
|
import { OxyAuthLoading, OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
|
|
30
31
|
import { ReauthStep } from './ReauthStep';
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
AccountFlowCodeField,
|
|
34
35
|
AccountFlowErrorLine,
|
|
35
36
|
AccountFlowNote,
|
|
37
|
+
AccountFlowProgress,
|
|
36
38
|
describeSignInError,
|
|
37
39
|
} from './accountFlowParts';
|
|
38
40
|
|
|
@@ -46,7 +48,8 @@ type Step =
|
|
|
46
48
|
| { name: 'enroll'; enrollment: TotpEnrollResponse }
|
|
47
49
|
| { name: 'regenerate' }
|
|
48
50
|
| { name: 'disable' }
|
|
49
|
-
|
|
51
|
+
/** `enrolling`: the last step of turning it on, rather than new codes for one that is on. */
|
|
52
|
+
| { name: 'codes'; codes: string[]; enrolling: boolean };
|
|
50
53
|
|
|
51
54
|
export interface OxyAuthenticatorPanelProps {
|
|
52
55
|
/** The person is done here (after saving backup codes, or turning it off). */
|
|
@@ -92,34 +95,36 @@ export const OxyAuthenticatorPanel: React.FC<OxyAuthenticatorPanelProps> = ({ on
|
|
|
92
95
|
};
|
|
93
96
|
|
|
94
97
|
const back = { label: t('common.cancel'), onPress: () => setStep({ name: 'status' }) };
|
|
98
|
+
// Turning it on is two steps: scan and confirm, then save the backup codes.
|
|
99
|
+
const enrolSteps = [t('signInSecurity.totp.title'), t('signInSecurity.totp.backupTitle')];
|
|
100
|
+
|
|
101
|
+
const copyCodes = async (codes: string) => {
|
|
102
|
+
try {
|
|
103
|
+
await copyText(codes);
|
|
104
|
+
} catch (reason) {
|
|
105
|
+
toast.error(t('appInfo.toasts.copyFailed'));
|
|
106
|
+
// Rethrown so the copy button keeps its copy glyph: nothing was copied.
|
|
107
|
+
throw reason;
|
|
108
|
+
}
|
|
109
|
+
toast.success(t('signInSecurity.totp.copied'));
|
|
110
|
+
};
|
|
95
111
|
|
|
96
112
|
switch (step.name) {
|
|
97
113
|
case 'codes':
|
|
98
114
|
return (
|
|
99
115
|
<OxyAuthScreen>
|
|
100
116
|
<OxyAuthScreenHeader title={t('signInSecurity.totp.backupTitle')} description={t('signInSecurity.totp.backupDescription')} />
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
fullWidth
|
|
113
|
-
onPress={() => {
|
|
114
|
-
Promise.resolve()
|
|
115
|
-
.then(() => Clipboard.setString(step.codes.join('\n')))
|
|
116
|
-
.then(() => toast.success(t('signInSecurity.totp.copied')))
|
|
117
|
-
.catch(() => undefined);
|
|
118
|
-
}}
|
|
119
|
-
testID="totp-copy-codes"
|
|
120
|
-
>
|
|
121
|
-
{t('signInSecurity.totp.copy')}
|
|
122
|
-
</Button>
|
|
117
|
+
{step.enrolling ? <AccountFlowProgress steps={enrolSteps} current={1} testID="totp-progress" /> : null}
|
|
118
|
+
{/* One code per line, with the block's own copy button (it shows a
|
|
119
|
+
check once the codes are on the clipboard). */}
|
|
120
|
+
<CodeBlock
|
|
121
|
+
code={step.codes.join('\n')}
|
|
122
|
+
filename={t('signInSecurity.totp.remaining', { count: step.codes.length })}
|
|
123
|
+
lineNumbers={false}
|
|
124
|
+
labels={{ copy: t('signInSecurity.totp.copy'), copied: t('signInSecurity.totp.copied') }}
|
|
125
|
+
onCopy={copyCodes}
|
|
126
|
+
testID="totp-backup-codes"
|
|
127
|
+
/>
|
|
123
128
|
<AccountFlowAction
|
|
124
129
|
label={t('signInSecurity.totp.savedThem')}
|
|
125
130
|
onPress={() => {
|
|
@@ -146,10 +151,11 @@ export const OxyAuthenticatorPanel: React.FC<OxyAuthenticatorPanelProps> = ({ on
|
|
|
146
151
|
const codes = await oxyServices.auth.totp.confirm(code.trim(), reauth);
|
|
147
152
|
refresh();
|
|
148
153
|
toast.success(t('signInSecurity.totp.enabled'));
|
|
149
|
-
setStep({ name: 'codes', codes });
|
|
154
|
+
setStep({ name: 'codes', codes, enrolling: true });
|
|
150
155
|
}}
|
|
151
156
|
secondary={back}
|
|
152
157
|
>
|
|
158
|
+
<AccountFlowProgress steps={enrolSteps} current={0} testID="totp-progress" />
|
|
153
159
|
<View style={styles.plateRow}>
|
|
154
160
|
<View style={[styles.plate, { borderColor: theme.colors.border }]} testID="totp-qr">
|
|
155
161
|
<QRCode value={enrollment.otpauthUri} size={QR_SIZE} backgroundColor={QR_PLATE_BG} color={QR_FOREGROUND} />
|
|
@@ -184,7 +190,7 @@ export const OxyAuthenticatorPanel: React.FC<OxyAuthenticatorPanelProps> = ({ on
|
|
|
184
190
|
onSubmit={async (reauth) => {
|
|
185
191
|
const codes = await oxyServices.auth.totp.regenerateBackupCodes(reauth);
|
|
186
192
|
refresh();
|
|
187
|
-
setStep({ name: 'codes', codes });
|
|
193
|
+
setStep({ name: 'codes', codes, enrolling: false });
|
|
188
194
|
}}
|
|
189
195
|
secondary={back}
|
|
190
196
|
/>
|
|
@@ -229,7 +235,6 @@ export const OxyAuthenticatorPanel: React.FC<OxyAuthenticatorPanelProps> = ({ on
|
|
|
229
235
|
/>
|
|
230
236
|
<SubtleLink
|
|
231
237
|
label={t('signInSecurity.totp.disable')}
|
|
232
|
-
theme={theme}
|
|
233
238
|
onPress={() => setStep({ name: 'disable' })}
|
|
234
239
|
testID="totp-disable"
|
|
235
240
|
/>
|
|
@@ -270,21 +275,4 @@ const styles = StyleSheet.create({
|
|
|
270
275
|
letterSpacing: 1,
|
|
271
276
|
textAlign: 'center',
|
|
272
277
|
},
|
|
273
|
-
codes: {
|
|
274
|
-
flexDirection: 'row',
|
|
275
|
-
flexWrap: 'wrap',
|
|
276
|
-
gap: 8,
|
|
277
|
-
padding: 16,
|
|
278
|
-
borderRadius: 16,
|
|
279
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
280
|
-
justifyContent: 'center',
|
|
281
|
-
},
|
|
282
|
-
code: {
|
|
283
|
-
width: '45%',
|
|
284
|
-
fontSize: 16,
|
|
285
|
-
lineHeight: 24,
|
|
286
|
-
fontWeight: '600',
|
|
287
|
-
letterSpacing: 1,
|
|
288
|
-
textAlign: 'center',
|
|
289
|
-
},
|
|
290
278
|
});
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
import type React from 'react';
|
|
14
14
|
import { useState } from 'react';
|
|
15
|
+
import { surfaces } from '@oxy.so/bloom/surfaces';
|
|
15
16
|
import { useOxy } from '../../context/OxyContext';
|
|
16
17
|
import { useSignInMethods } from '../../hooks/queries/useAuthMethods';
|
|
17
18
|
import { useI18n } from '../../hooks/useI18n';
|
|
18
19
|
import { OxyAuthLoading, OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
|
|
19
20
|
import { ReauthStep } from './ReauthStep';
|
|
20
|
-
import { AccountFlowField,
|
|
21
|
+
import { AccountFlowField, AccountFlowNotice } from './accountFlowParts';
|
|
21
22
|
|
|
22
23
|
export interface OxyDeleteAccountPanelProps {
|
|
23
24
|
/** The account is gone and this origin signed out of it. */
|
|
@@ -45,7 +46,8 @@ export const OxyDeleteAccountPanel: React.FC<OxyDeleteAccountPanelProps> = ({ on
|
|
|
45
46
|
if (keyed) {
|
|
46
47
|
return (
|
|
47
48
|
<OxyAuthScreen>
|
|
48
|
-
<OxyAuthScreenHeader title={t('deleteAccount.handoff.commonsTitle')}
|
|
49
|
+
<OxyAuthScreenHeader title={t('deleteAccount.handoff.commonsTitle')} />
|
|
50
|
+
<AccountFlowNotice testID="delete-account-keyed">{t('deleteAccount.keyless.keyed')}</AccountFlowNotice>
|
|
49
51
|
</OxyAuthScreen>
|
|
50
52
|
);
|
|
51
53
|
}
|
|
@@ -65,6 +67,16 @@ export const OxyDeleteAccountPanel: React.FC<OxyDeleteAccountPanelProps> = ({ on
|
|
|
65
67
|
validate={() => (confirmText.trim() === username ? null : t('deleteAccount.confirmLabel', { username }))}
|
|
66
68
|
onSubmit={async (proof) => {
|
|
67
69
|
if (!proof.emailCode) throw new Error(t('reauth.errors.invalid'));
|
|
70
|
+
// The last word before it is gone: the proof is ready, and nothing has
|
|
71
|
+
// been sent yet. Cancelling keeps the screen as it is, code and all.
|
|
72
|
+
const confirmed = await surfaces.confirm({
|
|
73
|
+
title: t('deleteAccount.title'),
|
|
74
|
+
description: t('deleteAccount.warning'),
|
|
75
|
+
confirmLabel: t('deleteAccount.confirm'),
|
|
76
|
+
cancelLabel: t('common.cancel'),
|
|
77
|
+
destructive: true,
|
|
78
|
+
});
|
|
79
|
+
if (!confirmed) return;
|
|
68
80
|
await oxyServices.users.deleteMe(confirmText.trim(), {
|
|
69
81
|
reauth: {
|
|
70
82
|
emailCode: proof.emailCode,
|
|
@@ -77,7 +89,9 @@ export const OxyDeleteAccountPanel: React.FC<OxyDeleteAccountPanelProps> = ({ on
|
|
|
77
89
|
}}
|
|
78
90
|
secondary={onCancel ? { label: t('common.cancel'), onPress: onCancel } : undefined}
|
|
79
91
|
>
|
|
80
|
-
<
|
|
92
|
+
<AccountFlowNotice type="warning" testID="delete-account-warning">
|
|
93
|
+
{t('deleteAccount.warning')}
|
|
94
|
+
</AccountFlowNotice>
|
|
81
95
|
<AccountFlowField
|
|
82
96
|
label={t('deleteAccount.confirmLabel', { username })}
|
|
83
97
|
value={confirmText}
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
import type React from 'react';
|
|
15
15
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
16
|
-
import {
|
|
16
|
+
import { StyleSheet, View } from 'react-native';
|
|
17
17
|
import QRCode from 'react-native-qrcode-svg';
|
|
18
18
|
import { Button } from '@oxy.so/bloom/button';
|
|
19
|
+
import { Loading } from '@oxy.so/bloom/loading';
|
|
19
20
|
import { useTheme } from '@oxy.so/bloom/theme';
|
|
20
21
|
import { Text } from '@oxy.so/bloom/typography';
|
|
21
22
|
import { deriveIdentityLinkCode } from '@oxy.so/core/crypto';
|
|
@@ -203,7 +204,7 @@ export const OxyLinkCommonsPanel: React.FC<OxyLinkCommonsPanelProps> = ({ onLink
|
|
|
203
204
|
<OxyAuthScreen>
|
|
204
205
|
<OxyAuthScreenHeader title={t('linkCommons.title')} description={t('linkCommons.subtitle')} />
|
|
205
206
|
<View style={styles.plateRow}>
|
|
206
|
-
<
|
|
207
|
+
<Loading variant="spinner" size="large" accessibilityLabel={t('common.status.loading')} />
|
|
207
208
|
</View>
|
|
208
209
|
</OxyAuthScreen>
|
|
209
210
|
);
|
|
@@ -7,11 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import type React from 'react';
|
|
9
9
|
import { useState } from 'react';
|
|
10
|
-
import { StyleSheet
|
|
10
|
+
import { StyleSheet } from 'react-native';
|
|
11
|
+
import { Field } from '@oxy.so/bloom/field';
|
|
11
12
|
import { Switch } from '@oxy.so/bloom/switch';
|
|
12
|
-
import { useTheme } from '@oxy.so/bloom/theme';
|
|
13
13
|
import { toast } from '@oxy.so/bloom/toast';
|
|
14
|
-
import { Text } from '@oxy.so/bloom/typography';
|
|
15
14
|
import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH } from '@oxy.so/contracts';
|
|
16
15
|
import { useQueryClient } from '@tanstack/react-query';
|
|
17
16
|
import { useOxy } from '../../context/OxyContext';
|
|
@@ -30,7 +29,6 @@ export interface OxyPasswordPanelProps {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export const OxyPasswordPanel: React.FC<OxyPasswordPanelProps> = ({ onDone, onCancel }) => {
|
|
33
|
-
const theme = useTheme();
|
|
34
32
|
const { t } = useI18n();
|
|
35
33
|
const { oxyServices, user } = useOxy();
|
|
36
34
|
const queryClient = useQueryClient();
|
|
@@ -94,10 +92,11 @@ export const OxyPasswordPanel: React.FC<OxyPasswordPanelProps> = ({ onDone, onCa
|
|
|
94
92
|
autoFocus={false}
|
|
95
93
|
testID="password-repeat"
|
|
96
94
|
/>
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
{/* The field names the switch ("Sign out everywhere else, switch, off")
|
|
96
|
+
and, on web, its label toggles it. One row: label, then the switch. */}
|
|
97
|
+
<Field label={t('signInSecurity.password.signOutOthers')} style={styles.row}>
|
|
99
98
|
<Switch value={signOutOthers} onValueChange={setSignOutOthers} testID="password-sign-out-others" />
|
|
100
|
-
</
|
|
99
|
+
</Field>
|
|
101
100
|
</ReauthStep>
|
|
102
101
|
);
|
|
103
102
|
};
|
|
@@ -109,9 +108,4 @@ const styles = StyleSheet.create({
|
|
|
109
108
|
justifyContent: 'space-between',
|
|
110
109
|
gap: 12,
|
|
111
110
|
},
|
|
112
|
-
label: {
|
|
113
|
-
flex: 1,
|
|
114
|
-
fontSize: 16,
|
|
115
|
-
lineHeight: 24,
|
|
116
|
-
},
|
|
117
111
|
});
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
AccountFlowAction,
|
|
61
61
|
AccountFlowCodeField,
|
|
62
62
|
AccountFlowField,
|
|
63
|
-
|
|
63
|
+
AccountFlowNotice,
|
|
64
64
|
BACKUP_CODE_LENGTH,
|
|
65
65
|
describeSignInError,
|
|
66
66
|
errorCode,
|
|
@@ -440,7 +440,14 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
440
440
|
);
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
|
|
443
|
+
// A 429 is not something the person typed wrong: it is a wait, counted down
|
|
444
|
+
// in a notice above the action it holds back, never the field's error.
|
|
445
|
+
const rateLimitNotice =
|
|
446
|
+
rateLimitSeconds > 0 ? (
|
|
447
|
+
<AccountFlowNotice type="warning" testID="signin-rate-limit">
|
|
448
|
+
{t('signin.errors.rateLimited', { seconds: rateLimitSeconds })}
|
|
449
|
+
</AccountFlowNotice>
|
|
450
|
+
) : null;
|
|
444
451
|
const clearError = () => {
|
|
445
452
|
if (error) setError(null);
|
|
446
453
|
};
|
|
@@ -464,7 +471,7 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
464
471
|
clearError();
|
|
465
472
|
}}
|
|
466
473
|
onComplete={submitCode}
|
|
467
|
-
error={
|
|
474
|
+
error={error}
|
|
468
475
|
disabled={blocked}
|
|
469
476
|
length={longCode ? EMAIL_SIGNIN_LONG_CODE_LENGTH : EMAIL_CODE_LENGTH}
|
|
470
477
|
type={longCode ? 'alphanumeric' : 'numeric'}
|
|
@@ -474,7 +481,6 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
474
481
|
/>
|
|
475
482
|
<SubtleLink
|
|
476
483
|
label={longCode ? t('signin.checkEmail.codeDigitsOnly') : t('signin.checkEmail.codeHasLetters')}
|
|
477
|
-
theme={theme}
|
|
478
484
|
onPress={() => {
|
|
479
485
|
setLongCode(!longCode);
|
|
480
486
|
setCode('');
|
|
@@ -483,7 +489,8 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
483
489
|
disabled={pending}
|
|
484
490
|
testID="signin-code-letters"
|
|
485
491
|
/>
|
|
486
|
-
{notice ? <
|
|
492
|
+
{notice ? <AccountFlowNotice testID="signin-notice">{notice}</AccountFlowNotice> : null}
|
|
493
|
+
{rateLimitNotice}
|
|
487
494
|
<AccountFlowAction
|
|
488
495
|
label={t('signin.actions.continue')}
|
|
489
496
|
onPress={() => submitCode(code)}
|
|
@@ -498,21 +505,18 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
498
505
|
? t('signin.checkEmail.resendIn', { seconds: resendSeconds })
|
|
499
506
|
: t('signin.checkEmail.resend')
|
|
500
507
|
}
|
|
501
|
-
theme={theme}
|
|
502
508
|
onPress={() => startEmail(request.identifier)}
|
|
503
509
|
disabled={blocked || resendSeconds > 0}
|
|
504
510
|
testID="signin-resend"
|
|
505
511
|
/>
|
|
506
512
|
<SubtleLink
|
|
507
513
|
label={t('signin.checkEmail.usePassword')}
|
|
508
|
-
theme={theme}
|
|
509
514
|
onPress={() => toPassword(request.identifier)}
|
|
510
515
|
disabled={pending}
|
|
511
516
|
testID="signin-use-password"
|
|
512
517
|
/>
|
|
513
518
|
<SubtleLink
|
|
514
519
|
label={t('signin.checkEmail.differentAccount')}
|
|
515
|
-
theme={theme}
|
|
516
520
|
onPress={backToIdentifier}
|
|
517
521
|
disabled={pending}
|
|
518
522
|
testID="signin-different-account"
|
|
@@ -535,12 +539,13 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
535
539
|
clearError();
|
|
536
540
|
}}
|
|
537
541
|
onSubmit={submitPassword}
|
|
538
|
-
error={
|
|
542
|
+
error={error}
|
|
539
543
|
disabled={blocked}
|
|
540
544
|
autoComplete="current-password"
|
|
541
545
|
secureTextEntry
|
|
542
546
|
testID="signin-password"
|
|
543
547
|
/>
|
|
548
|
+
{rateLimitNotice}
|
|
544
549
|
<AccountFlowAction
|
|
545
550
|
label={t('signin.actions.continue')}
|
|
546
551
|
onPress={submitPassword}
|
|
@@ -551,14 +556,12 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
551
556
|
<View style={styles.links}>
|
|
552
557
|
<SubtleLink
|
|
553
558
|
label={t('signin.password.forgot')}
|
|
554
|
-
theme={theme}
|
|
555
559
|
onPress={() => startEmail(request.identifier)}
|
|
556
560
|
disabled={blocked}
|
|
557
561
|
testID="signin-password-forgot"
|
|
558
562
|
/>
|
|
559
563
|
<SubtleLink
|
|
560
564
|
label={t('signin.checkEmail.differentAccount')}
|
|
561
|
-
theme={theme}
|
|
562
565
|
onPress={backToIdentifier}
|
|
563
566
|
disabled={pending}
|
|
564
567
|
testID="signin-different-account"
|
|
@@ -584,13 +587,14 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
584
587
|
clearError();
|
|
585
588
|
}}
|
|
586
589
|
onComplete={submitSecondFactor}
|
|
587
|
-
error={
|
|
590
|
+
error={error}
|
|
588
591
|
disabled={blocked}
|
|
589
592
|
length={useBackupCode ? BACKUP_CODE_LENGTH : TOTP_DIGITS}
|
|
590
593
|
type={useBackupCode ? 'alphanumeric' : 'numeric'}
|
|
591
594
|
groupEvery={useBackupCode ? BACKUP_CODE_LENGTH / 2 : undefined}
|
|
592
595
|
testID="signin-second-factor"
|
|
593
596
|
/>
|
|
597
|
+
{rateLimitNotice}
|
|
594
598
|
<AccountFlowAction
|
|
595
599
|
label={t('signin.actions.continue')}
|
|
596
600
|
onPress={() => submitSecondFactor(secondFactorCode)}
|
|
@@ -601,7 +605,6 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
601
605
|
<View style={styles.links}>
|
|
602
606
|
<SubtleLink
|
|
603
607
|
label={useBackupCode ? t('signin.secondFactor.useAuthenticator') : t('signin.secondFactor.useBackup')}
|
|
604
|
-
theme={theme}
|
|
605
608
|
onPress={() => {
|
|
606
609
|
setUseBackupCode(!useBackupCode);
|
|
607
610
|
setSecondFactorCode('');
|
|
@@ -612,7 +615,6 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
612
615
|
/>
|
|
613
616
|
<SubtleLink
|
|
614
617
|
label={t('signin.checkEmail.differentAccount')}
|
|
615
|
-
theme={theme}
|
|
616
618
|
onPress={backToIdentifier}
|
|
617
619
|
disabled={pending}
|
|
618
620
|
testID="signin-different-account"
|
|
@@ -675,7 +677,7 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
675
677
|
clearError();
|
|
676
678
|
}}
|
|
677
679
|
onSubmit={submitIdentifier}
|
|
678
|
-
error={
|
|
680
|
+
error={error}
|
|
679
681
|
disabled={blocked}
|
|
680
682
|
placeholder={t('signin.identifier.placeholder')}
|
|
681
683
|
autoComplete="username"
|
|
@@ -694,6 +696,7 @@ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
|
|
|
694
696
|
{t('signin.createAccount')}
|
|
695
697
|
</RNText>
|
|
696
698
|
</Text>
|
|
699
|
+
{rateLimitNotice}
|
|
697
700
|
<AccountFlowAction
|
|
698
701
|
label={t('signin.actions.continue')}
|
|
699
702
|
onPress={submitIdentifier}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import type React from 'react';
|
|
15
15
|
import { useEffect, useState } from 'react';
|
|
16
16
|
import { Linking, Platform } from 'react-native';
|
|
17
|
-
import { useTheme } from '@oxy.so/bloom/theme';
|
|
18
17
|
import { toast } from '@oxy.so/bloom/toast';
|
|
19
18
|
import { SIGN_IN_ERROR_CODES, emailAddressSchema, type EmailVerificationConfirmResponse } from '@oxy.so/contracts';
|
|
20
19
|
import { useOxy } from '../../context/OxyContext';
|
|
@@ -29,6 +28,7 @@ import {
|
|
|
29
28
|
AccountFlowAction,
|
|
30
29
|
AccountFlowField,
|
|
31
30
|
AccountFlowNote,
|
|
31
|
+
AccountFlowProgress,
|
|
32
32
|
EmailCodeStep,
|
|
33
33
|
describeSignInError,
|
|
34
34
|
errorCode,
|
|
@@ -61,7 +61,6 @@ interface SavedSignUpFlow {
|
|
|
61
61
|
const SIGN_UP_FLOW_KEY = 'signup';
|
|
62
62
|
|
|
63
63
|
export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSignIn, host = 'page' }) => {
|
|
64
|
-
const theme = useTheme();
|
|
65
64
|
const { t } = useI18n();
|
|
66
65
|
const { oxyServices, handleWebSession, accountDialogController } = useOxy();
|
|
67
66
|
const snapshot = useAccountDialogSnapshot(accountDialogController);
|
|
@@ -149,6 +148,12 @@ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSi
|
|
|
149
148
|
.catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
|
|
150
149
|
};
|
|
151
150
|
|
|
151
|
+
// username → email → code, drawn as one segmented bar under each header.
|
|
152
|
+
const progressSteps = [t('signup.username.label'), t('signup.email.label'), t('emailCode.title')];
|
|
153
|
+
const progress = (current: number) => (
|
|
154
|
+
<AccountFlowProgress steps={progressSteps} current={current} testID="signup-progress" />
|
|
155
|
+
);
|
|
156
|
+
|
|
152
157
|
switch (step.name) {
|
|
153
158
|
case 'code':
|
|
154
159
|
return (
|
|
@@ -158,12 +163,14 @@ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSi
|
|
|
158
163
|
onConfirmed={createAccount}
|
|
159
164
|
onResend={() => sendCode(email)}
|
|
160
165
|
back={{ label: t('emailCode.changeEmail'), onPress: () => setStep({ name: 'email' }) }}
|
|
166
|
+
progress={progress(2)}
|
|
161
167
|
/>
|
|
162
168
|
);
|
|
163
169
|
case 'email':
|
|
164
170
|
return (
|
|
165
171
|
<OxyAuthScreen>
|
|
166
172
|
<OxyAuthScreenHeader title={t('signup.email.title')} description={t('signup.email.subtitle')} />
|
|
173
|
+
{progress(1)}
|
|
167
174
|
<AccountFlowField
|
|
168
175
|
label={t('signup.email.label')}
|
|
169
176
|
value={email}
|
|
@@ -181,7 +188,7 @@ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSi
|
|
|
181
188
|
/>
|
|
182
189
|
<AccountFlowNote>{t('signup.laterNote')}</AccountFlowNote>
|
|
183
190
|
<AccountFlowAction label={t('signin.actions.continue')} onPress={submitEmail} pending={pending} testID="signup-email-continue" />
|
|
184
|
-
<SubtleLink label={t('signin.actions.back')}
|
|
191
|
+
<SubtleLink label={t('signin.actions.back')} onPress={() => setStep({ name: 'username' })} testID="signup-back" />
|
|
185
192
|
<OxyAuthTerms />
|
|
186
193
|
</OxyAuthScreen>
|
|
187
194
|
);
|
|
@@ -189,6 +196,7 @@ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSi
|
|
|
189
196
|
return (
|
|
190
197
|
<OxyAuthScreen>
|
|
191
198
|
<OxyAuthScreenHeader title={t('signup.title')} description={t('signup.subtitle')} />
|
|
199
|
+
{progress(0)}
|
|
192
200
|
<AccountFlowField
|
|
193
201
|
label={t('signup.username.label')}
|
|
194
202
|
value={username}
|
|
@@ -204,8 +212,8 @@ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignedIn, onSi
|
|
|
204
212
|
testID="signup-username"
|
|
205
213
|
/>
|
|
206
214
|
<AccountFlowAction label={t('signin.actions.continue')} onPress={submitUsername} pending={pending} testID="signup-username-continue" />
|
|
207
|
-
<SubtleLink label={t('signup.createInCommons')}
|
|
208
|
-
<SubtleLink label={t('signup.backToSignInLink')}
|
|
215
|
+
<SubtleLink label={t('signup.createInCommons')} onPress={createInCommons} testID="signup-commons-instead" />
|
|
216
|
+
<SubtleLink label={t('signup.backToSignInLink')} onPress={onSignIn} testID="back-to-sign-in" />
|
|
209
217
|
<OxyAuthTerms />
|
|
210
218
|
</OxyAuthScreen>
|
|
211
219
|
);
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
import type React from 'react';
|
|
10
10
|
import { useState } from 'react';
|
|
11
|
-
import { useTheme } from '@oxy.so/bloom/theme';
|
|
12
11
|
import { EMAIL_CODE_LENGTH, TOTP_DIGITS, type ReauthAction, type ReauthProof } from '@oxy.so/contracts';
|
|
13
12
|
import { useOxy } from '../../context/OxyContext';
|
|
14
13
|
import { useI18n } from '../../hooks/useI18n';
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
AccountFlowErrorLine,
|
|
21
20
|
AccountFlowField,
|
|
22
21
|
AccountFlowNote,
|
|
22
|
+
AccountFlowNotice,
|
|
23
23
|
BACKUP_CODE_LENGTH,
|
|
24
24
|
describeSignInError,
|
|
25
25
|
} from './accountFlowParts';
|
|
@@ -58,7 +58,6 @@ export const ReauthStep: React.FC<ReauthStepProps> = ({
|
|
|
58
58
|
secondary,
|
|
59
59
|
children,
|
|
60
60
|
}) => {
|
|
61
|
-
const theme = useTheme();
|
|
62
61
|
const { t } = useI18n();
|
|
63
62
|
const { oxyServices } = useOxy();
|
|
64
63
|
const [mode, setMode] = useState<'email' | 'password'>(allowPassword ? 'password' : 'email');
|
|
@@ -140,7 +139,7 @@ export const ReauthStep: React.FC<ReauthStepProps> = ({
|
|
|
140
139
|
/>
|
|
141
140
|
) : verificationId ? (
|
|
142
141
|
<>
|
|
143
|
-
<
|
|
142
|
+
<AccountFlowNotice testID="reauth-code-sent">{t('reauth.codeSent')}</AccountFlowNotice>
|
|
144
143
|
<AccountFlowCodeField
|
|
145
144
|
label={t('reauth.codeLabel')}
|
|
146
145
|
value={emailCode}
|
|
@@ -171,7 +170,6 @@ export const ReauthStep: React.FC<ReauthStepProps> = ({
|
|
|
171
170
|
/>
|
|
172
171
|
<SubtleLink
|
|
173
172
|
label={useBackupCode ? t('signin.secondFactor.useAuthenticator') : t('signin.secondFactor.useBackup')}
|
|
174
|
-
theme={theme}
|
|
175
173
|
onPress={() => {
|
|
176
174
|
setUseBackupCode(!useBackupCode);
|
|
177
175
|
setTotpCode('');
|
|
@@ -191,12 +189,11 @@ export const ReauthStep: React.FC<ReauthStepProps> = ({
|
|
|
191
189
|
testID={needsCode ? 'reauth-send-code' : 'reauth-submit'}
|
|
192
190
|
/>
|
|
193
191
|
{mode === 'email' && verificationId ? (
|
|
194
|
-
<SubtleLink label={t('emailCode.resend')}
|
|
192
|
+
<SubtleLink label={t('emailCode.resend')} onPress={sendCode} disabled={pending} testID="reauth-resend" />
|
|
195
193
|
) : null}
|
|
196
194
|
{allowPassword ? (
|
|
197
195
|
<SubtleLink
|
|
198
196
|
label={mode === 'password' ? t('reauth.useEmail') : t('reauth.usePassword')}
|
|
199
|
-
theme={theme}
|
|
200
197
|
onPress={() => {
|
|
201
198
|
setError(null);
|
|
202
199
|
setMode(mode === 'password' ? 'email' : 'password');
|
|
@@ -206,7 +203,7 @@ export const ReauthStep: React.FC<ReauthStepProps> = ({
|
|
|
206
203
|
/>
|
|
207
204
|
) : null}
|
|
208
205
|
{secondary ? (
|
|
209
|
-
<SubtleLink label={secondary.label}
|
|
206
|
+
<SubtleLink label={secondary.label} onPress={secondary.onPress} disabled={pending} testID="reauth-cancel" />
|
|
210
207
|
) : null}
|
|
211
208
|
</OxyAuthScreen>
|
|
212
209
|
);
|