Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: #1180 PIN when idle on Android #1191

Merged
merged 1 commit into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/components/AuthCheck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,26 @@ const AuthCheck = ({
const requirePin = route?.params?.requirePin ?? false;
onSuccess = route?.params?.onSuccess ?? onSuccess;

return (
<Animated.View style={StyleSheet.absoluteFillObject} exiting={FadeOut}>
{requireBiometrics && !requirePin ? (
if (requireBiometrics && !requirePin) {
return (
<Animated.View style={StyleSheet.absoluteFillObject} exiting={FadeOut}>
<GlowingBackground topLeft="brand">
<Biometrics
onSuccess={(): void => onSuccess?.()}
onFailure={(): void => setRequireBiometrics(false)}
/>
</GlowingBackground>
) : (
<PinPad
showBackNavigation={showBackNavigation}
showLogoOnPIN={showLogoOnPIN}
onSuccess={(): void => onSuccess?.()}
/>
)}
</Animated.View>
);
}

return (
<Animated.View style={StyleSheet.absoluteFillObject} exiting={FadeOut}>
<PinPad
showBackNavigation={showBackNavigation}
showLogoOnPIN={showLogoOnPIN}
onSuccess={(): void => onSuccess?.()}
/>
</Animated.View>
);
};
Expand Down
4 changes: 3 additions & 1 deletion src/components/InactivityTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ const InactivityTracker = ({
});
}, [resetInactivityTimeout]);

const panProps = pinOnIdle ? panResponder.panHandlers : {};

return (
<View style={styles.root} {...panResponder.panHandlers}>
<View style={styles.root} {...panProps}>
{children}
</View>
);
Expand Down
21 changes: 5 additions & 16 deletions src/navigation/root/RootNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import { NavigationContainer } from '../../styles/components';
import { processInputData } from '../../utils/scanner';
import { checkClipboardData } from '../../utils/clipboard';
import { useRenderCount } from '../../hooks/helpers';
import { getStore } from '../../store/helpers';
import { updateUi } from '../../store/actions/ui';
import { resetSendTransaction } from '../../store/actions/wallet';
import { isAuthenticatedSelector } from '../../store/reselect/ui';
import { pinOnIdleSelector, pinSelector } from '../../store/reselect/settings';
import AuthCheck from '../../components/AuthCheck';
import Dialog from '../../components/Dialog';
import WalletNavigator from '../wallet/WalletNavigator';
Expand Down Expand Up @@ -99,8 +99,6 @@ const RootNavigator = (): ReactElement => {
const appState = useRef(AppState.currentState);
const [showDialog, setShowDialog] = useState(false);
const [shouldCheckClipboard, setShouldCheckClipboard] = useState(false);
const pin = useSelector(pinSelector);
const pinOnIdle = useSelector(pinOnIdleSelector);
const isAuthenticated = useSelector(isAuthenticatedSelector);
const renderCount = useRenderCount();

Expand Down Expand Up @@ -169,28 +167,19 @@ const RootNavigator = (): ReactElement => {
const appStateSubscription = AppState.addEventListener(
'change',
(nextAppState): void => {
// get state fresh from store everytime
const uiStore = getStore().ui;

// on App to foreground
if (appState.current.match(/background/) && nextAppState === 'active') {
// prevent redirecting while on AuthCheck
if (isAuthenticated) {
if (uiStore.isAuthenticated) {
checkClipboard().then();
} else {
setShouldCheckClipboard(true);
}
}

// on App to background
if (
appState.current.match(/active|inactive/) &&
nextAppState === 'background'
) {
// lock the app on background if pinOnIdle is enabled
if (pin && pinOnIdle) {
updateUi({ isAuthenticated: false });
setShouldCheckClipboard(true);
}
}

appState.current = nextAppState;
},
);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/i18n/locales/en/lightning.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"setting_up_step4": "Opening Connection",
"result_header": "Connecting",
"result_text": "Lightning connection initiated. You will be able to use instant payments in ±10 minutes.",
"timeout_header": "Timed Out",
"timeout_header": "Please keep Bitkit open.",
"timeout_text": "Bitkit will keep trying to open your Lightning connection in the background. Please keep the app open.",
"awesome": "Awesome!",
"transfer_funds": "Transfer Funds",
Expand Down
2 changes: 1 addition & 1 deletion src/utils/i18n/locales/en/other.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@
"high_text2_beta": "Please consider moving some of your funds. We recommend using only small amounts while Bitkit is in beta.",
"high_button_more": "Learn More",
"caution_header": "Caution:\n<yellow>Beta Risk.</yellow>",
"caution_text": "Beta software may put your money at risk. We recommend using only small amounts (like $10) while Bitkit is in beta."
"caution_text": "Beta software may put your money at risk. We recommend using only small amounts while Bitkit is in beta."
}
44 changes: 12 additions & 32 deletions src/utils/settings/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { resetKeychainValue, setKeychainValue } from '../keychain';
import { getSettingsStore } from '../../store/helpers';
import { removeTodo } from '../../store/actions/todos';
import { updateSettings } from '../../store/actions/settings';
import { PIN_ATTEMPTS } from '../../components/PinPad';
Expand All @@ -17,10 +16,11 @@ export const addPin = async (newPin: string): Promise<void> => {
* Edit PIN keychain data and update settings state
*/
export const editPin = async (newPin: string): Promise<void> => {
updateSettings({ pin: true });

await Promise.all([
setKeychainValue({ key: 'pin', value: newPin }),
setKeychainValue({ key: 'pinAttemptsRemaining', value: PIN_ATTEMPTS }),
updateSettings({ pin: true }),
]);
};

Expand All @@ -29,38 +29,18 @@ export const editPin = async (newPin: string): Promise<void> => {
* Wipes PIN data from device memory.
*/
export const removePin = async (): Promise<void> => {
removeTodo('pin');
// reset to defaults
updateSettings({
pin: false,
pinOnLaunch: true,
pinOnIdle: false,
pinForPayments: false,
biometrics: false,
});

await Promise.all([
// reset to defaults
updateSettings({
pin: false,
pinOnLaunch: true,
pinForPayments: false,
biometrics: false,
}),
setKeychainValue({ key: 'pinAttemptsRemaining', value: PIN_ATTEMPTS }),
resetKeychainValue({ key: 'pin' }),
removeTodo('pin'),
]);
};

/**
* Returns if the user's various methods of authentication are enabled or disabled.
*/
export const hasEnabledAuthentication = (): {
pin: boolean;
pinOnLaunch: boolean;
pinForPayments: boolean;
biometrics: boolean;
} => {
try {
const { pin, pinOnLaunch, pinForPayments, biometrics } = getSettingsStore();
return { pin, pinOnLaunch, pinForPayments, biometrics };
} catch {
return {
pin: false,
pinOnLaunch: false,
pinForPayments: false,
biometrics: false,
};
}
};
Loading