Skip to content

Commit 4247427

Browse files
committed
fix: verify-scan theme leak + fullscreen scanner; wipe sign history
- Scan-to-verify forced persisted dark mode: Scanner dispatches darkMode:true on mount and only Home's scanner paths restored it — the theme slice is redux-persisted, so a light-theme user who tapped 'Scan wallet to verify' was stuck in dark mode across restarts. VerificationCode now restores the theme on scan and on close, and mounts the scanner full-screen. - 'Delete SSP Key data' also clears the encrypted sign-history blob (keychain service sspkey_sign_history) — the wipe contract says all data.
1 parent a4f9056 commit 4247427

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/components/VerificationCode/VerificationCode.tsx

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import {
99
} from 'react-native';
1010
import { CircleCheck, Shield, TriangleAlert } from 'lucide-react-native';
1111
import { useTranslation } from 'react-i18next';
12+
import { useDispatch } from 'react-redux';
1213
import { useTheme } from '../../hooks';
14+
import { changeTheme } from '../../store/theme';
1315
import BlurOverlay from '../../BlurOverlay';
1416
import VerificationWords from '../VerificationWords/VerificationWords';
1517
import Scanner from '../Scanner/Scanner';
@@ -34,22 +36,51 @@ const VerificationCode = (props: {
3436
}) => {
3537
const { t } = useTranslation(['home', 'common']);
3638
const { Fonts, Gutters, Layout, Colors, Common } = useTheme();
39+
const dispatch = useDispatch();
3740
const [scanning, setScanning] = useState(false);
3841
const [result, setResult] = useState<'match' | 'mismatch' | null>(null);
3942

4043
const close = () => {
4144
props.actionStatus(false);
4245
};
4346

47+
// Scanner forces darkMode: true on mount and the theme slice is
48+
// redux-persisted — without this restore (the same one Home's scanner
49+
// paths do) a light-theme user would be stuck in dark mode for good.
50+
const restoreTheme = () => {
51+
dispatch(changeTheme({ theme: 'default', darkMode: null }));
52+
};
53+
4454
const onScanned = (scanned: string) => {
4555
setScanning(false);
56+
restoreTheme();
4657
// Recompute-free local check: compare the scanned wallet code against THIS
4758
// device's own words. Equal ⇒ the two devices derived the same keys.
4859
setResult(verificationMatches(props.words, scanned) ? 'match' : 'mismatch');
4960
};
5061

5162
if (scanning) {
52-
return <Scanner onRead={onScanned} onClose={() => setScanning(false)} />;
63+
// Full-screen Modal so the camera surface covers the viewport — rendered
64+
// inline it would only fill Home's inner scroll content view.
65+
return (
66+
<Modal
67+
animationType="fade"
68+
transparent={false}
69+
visible={true}
70+
onRequestClose={() => {
71+
setScanning(false);
72+
restoreTheme();
73+
}}
74+
>
75+
<Scanner
76+
onRead={onScanned}
77+
onClose={() => {
78+
setScanning(false);
79+
restoreTheme();
80+
}}
81+
/>
82+
</Modal>
83+
);
5384
}
5485

5586
const resultBanner =

src/screens/Welcome/Welcome.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useTheme } from '../../hooks';
55
import PoweredByFlux from '../../components/PoweredByFlux/PoweredByFlux';
66
import { PrimaryButton } from '../../components/ui';
77
import * as Keychain from 'react-native-keychain';
8+
import { clearSignHistory } from '../../lib/signHistory';
89

910
type Props = { navigation: any };
1011

@@ -20,6 +21,9 @@ function Welcome({ navigation }: Props) {
2021
await Keychain.resetGenericPassword({ service: 'sspkey_pw_hash' });
2122
await Keychain.resetGenericPassword({ service: 'fcm_key_token' });
2223
await Keychain.resetGenericPassword({ service: 'salt' });
24+
// the wipe contract says ALL data — the encrypted sign-history blob
25+
// (service sspkey_sign_history) must not linger on a "cleaned" device
26+
await clearSignHistory();
2327
} catch (error) {
2428
console.log(error);
2529
}

0 commit comments

Comments
 (0)