security settings: dynamic Set/Change labels, delete password shortcut
This commit is contained in:
+9
-4
@@ -1042,16 +1042,19 @@
|
||||
"views.Settings.Privacy.clipboard": "Read clipboard",
|
||||
"views.Settings.Privacy.clipboard.explainer": "If enabled, Zeus will read values copied to your clipboard and prompt you if they can be used in the app.",
|
||||
"views.Settings.Privacy.enableMempoolRates": "Enable Mempool.space fee suggestions",
|
||||
"views.Settings.SetPassword.title": "Set / Change Password",
|
||||
"views.Settings.SetPassword.title": "Set Password",
|
||||
"views.Settings.ChangePassword.title": "Change Password",
|
||||
"views.Settings.SetPassword.save": "Save",
|
||||
"views.Settings.SetPassword.noMatch": "Passwords do not match",
|
||||
"views.Settings.SetPassword.invalid": "Password and duress password cannot be the same",
|
||||
"views.Settings.SetPassword.empty": "Password can not be empty",
|
||||
"views.Settings.SetPassword.deletePassword": "Delete Password",
|
||||
"views.Settings.SetDuressPassword.title": "Set / Change Duress Password",
|
||||
"views.Settings.SetDuressPassword.title": "Set Duress Password",
|
||||
"views.Settings.ChangeDuressPassword.title": "Change Duress Password",
|
||||
"views.Settings.SetDuressPassword.deletePassword": "Delete Duress Password",
|
||||
"views.Settings.SetDuressPassword.duressPasswordExplanation": "Once set, you can enter your duress password on the login screen to delete all of your wallet configurations.",
|
||||
"views.Settings.SetPin.title": "Set / Change PIN",
|
||||
"views.Settings.SetPin.title": "Set PIN",
|
||||
"views.Settings.ChangePin.title": "Change PIN",
|
||||
"views.Settings.Security.BiometryRequiresPinOrPassword": "To enable biometric authentication, you need to set up a PIN or Password first as a backup method.",
|
||||
"views.Settings.Security.FaceID.title": "FaceID",
|
||||
"views.Settings.Security.TouchID.title": "TouchID",
|
||||
@@ -1062,9 +1065,11 @@
|
||||
"views.Settings.SetPin.noMatch": "PINs do not match. Please resubmit.",
|
||||
"views.Settings.SetPin.invalid": "PIN and Duress PIN cannot be equal.",
|
||||
"views.Settings.SetPin.createPin": "Create your PIN",
|
||||
"views.Settings.SetPin.newPin": "Enter your new PIN",
|
||||
"views.Settings.SetPin.confirmPin": "Confirm your PIN",
|
||||
"views.Settings.SetPin.scramblePin": "The order of numbers on the PIN Pad is randomized to prevent against attacks",
|
||||
"views.Settings.SetDuressPin.title": "Set / Change Duress PIN",
|
||||
"views.Settings.SetDuressPin.title": "Set Duress PIN",
|
||||
"views.Settings.ChangeDuressPin.title": "Change Duress PIN",
|
||||
"views.Settings.SetDuressPin.createDuressPin": "Create your Duress PIN",
|
||||
"views.Settings.SetDuressPin.duressPinExplanation": "Once set, you can enter your duress PIN on the PIN login screen to delete all of your wallet configurations.",
|
||||
"views.Settings.SetDuressPin.confirmDuressPin": "Confirm your Duress PIN",
|
||||
|
||||
+71
-4
@@ -36,6 +36,8 @@ interface LockscreenProps {
|
||||
modifySecurityScreen: string;
|
||||
deletePin: boolean;
|
||||
deleteDuressPin: boolean;
|
||||
deletePassword: boolean;
|
||||
deleteDuressPassword: boolean;
|
||||
pendingNavigation?: { screen: string; params?: any };
|
||||
shareIntentData?: { qrData?: string; base64Image?: string };
|
||||
}
|
||||
@@ -54,6 +56,8 @@ interface LockscreenState {
|
||||
modifySecurityScreen: string;
|
||||
deletePin: boolean;
|
||||
deleteDuressPin: boolean;
|
||||
deletePassword: boolean;
|
||||
deleteDuressPassword: boolean;
|
||||
authenticationAttempts: number;
|
||||
}
|
||||
|
||||
@@ -81,6 +85,8 @@ export default class Lockscreen extends React.Component<
|
||||
modifySecurityScreen: '',
|
||||
deletePin: false,
|
||||
deleteDuressPin: false,
|
||||
deletePassword: false,
|
||||
deleteDuressPassword: false,
|
||||
authenticationAttempts: 0
|
||||
};
|
||||
}
|
||||
@@ -126,6 +132,8 @@ export default class Lockscreen extends React.Component<
|
||||
modifySecurityScreen,
|
||||
deletePin,
|
||||
deleteDuressPin,
|
||||
deletePassword,
|
||||
deleteDuressPassword,
|
||||
pendingNavigation
|
||||
} = route.params ?? {};
|
||||
|
||||
@@ -138,7 +146,9 @@ export default class Lockscreen extends React.Component<
|
||||
SettingsStore.posStatus === 'active' &&
|
||||
!pendingNavigation &&
|
||||
!deletePin &&
|
||||
!deleteDuressPin
|
||||
!deleteDuressPin &&
|
||||
!deletePassword &&
|
||||
!deleteDuressPassword
|
||||
) {
|
||||
// If POS is enabled and active, proceed without authentication
|
||||
SettingsStore.setLoginStatus(true);
|
||||
@@ -152,6 +162,8 @@ export default class Lockscreen extends React.Component<
|
||||
isBiometryConfigured &&
|
||||
!deletePin &&
|
||||
!deleteDuressPin &&
|
||||
!deletePassword &&
|
||||
!deleteDuressPassword &&
|
||||
!modifySecurityScreen
|
||||
) {
|
||||
const isVerified = await verifyBiometry(
|
||||
@@ -191,6 +203,14 @@ export default class Lockscreen extends React.Component<
|
||||
this.setState({
|
||||
deleteDuressPin
|
||||
});
|
||||
} else if (deletePassword) {
|
||||
this.setState({
|
||||
deletePassword
|
||||
});
|
||||
} else if (deleteDuressPassword) {
|
||||
this.setState({
|
||||
deleteDuressPassword
|
||||
});
|
||||
}
|
||||
|
||||
if (settings && settings.passphrase) {
|
||||
@@ -244,7 +264,9 @@ export default class Lockscreen extends React.Component<
|
||||
duressPin,
|
||||
modifySecurityScreen,
|
||||
deletePin,
|
||||
deleteDuressPin
|
||||
deleteDuressPin,
|
||||
deletePassword,
|
||||
deleteDuressPassword
|
||||
} = this.state;
|
||||
const { updateSettings, getSettings, setPosStatus } = SettingsStore;
|
||||
|
||||
@@ -263,9 +285,15 @@ export default class Lockscreen extends React.Component<
|
||||
this.resetAuthenticationAttempts();
|
||||
navigation.popTo(modifySecurityScreen);
|
||||
return;
|
||||
} else if (deletePassword) {
|
||||
this.deletePassword();
|
||||
return;
|
||||
} else if (deletePin) {
|
||||
this.deletePin();
|
||||
return;
|
||||
} else if (deleteDuressPassword) {
|
||||
this.deleteDuressPassword();
|
||||
return;
|
||||
} else if (deleteDuressPin) {
|
||||
this.deleteDuressPin();
|
||||
return;
|
||||
@@ -361,6 +389,34 @@ export default class Lockscreen extends React.Component<
|
||||
});
|
||||
};
|
||||
|
||||
deletePassword = () => {
|
||||
const { SettingsStore, navigation } = this.props;
|
||||
const { updateSettings } = SettingsStore;
|
||||
|
||||
// duress passphrase is also deleted when passphrase is deleted
|
||||
// biometry is also disabled when passphrase is deleted
|
||||
updateSettings({
|
||||
passphrase: '',
|
||||
duressPassphrase: '',
|
||||
authenticationAttempts: 0,
|
||||
isBiometryEnabled: false
|
||||
}).then(() => {
|
||||
navigation.popTo('Security');
|
||||
});
|
||||
};
|
||||
|
||||
deleteDuressPassword = () => {
|
||||
const { SettingsStore, navigation } = this.props;
|
||||
const { updateSettings } = SettingsStore;
|
||||
|
||||
updateSettings({
|
||||
duressPassphrase: '',
|
||||
authenticationAttempts: 0
|
||||
}).then(() => {
|
||||
navigation.popTo('Security');
|
||||
});
|
||||
};
|
||||
|
||||
deletePin = () => {
|
||||
const { SettingsStore, navigation } = this.props;
|
||||
const { updateSettings } = SettingsStore;
|
||||
@@ -457,7 +513,9 @@ export default class Lockscreen extends React.Component<
|
||||
error,
|
||||
modifySecurityScreen,
|
||||
deletePin,
|
||||
deleteDuressPin
|
||||
deleteDuressPin,
|
||||
deletePassword,
|
||||
deleteDuressPassword
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
@@ -465,6 +523,8 @@ export default class Lockscreen extends React.Component<
|
||||
{(!!modifySecurityScreen ||
|
||||
deletePin ||
|
||||
deleteDuressPin ||
|
||||
deletePassword ||
|
||||
deleteDuressPassword ||
|
||||
pendingNavigation) && (
|
||||
<Header leftComponent="Back" navigation={navigation} />
|
||||
)}
|
||||
@@ -525,10 +585,17 @@ export default class Lockscreen extends React.Component<
|
||||
</View>
|
||||
<View style={styles.button}>
|
||||
<Button
|
||||
title={localeString('views.Lockscreen.login')}
|
||||
title={localeString(
|
||||
deletePassword
|
||||
? 'views.Settings.SetPassword.deletePassword'
|
||||
: deleteDuressPassword
|
||||
? 'views.Settings.SetDuressPassword.deletePassword'
|
||||
: 'views.Lockscreen.login'
|
||||
)}
|
||||
onPress={() => this.onAttemptLogIn()}
|
||||
containerStyle={{ width: 300 }}
|
||||
adaptiveWidth
|
||||
warning={deletePassword || deleteDuressPassword}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
+80
-39
@@ -33,33 +33,6 @@ interface SecurityState {
|
||||
isBiometryEnabled: boolean | undefined;
|
||||
}
|
||||
|
||||
const possibleSecurityItems = [
|
||||
{
|
||||
translateKey: 'views.Settings.SetPassword.title',
|
||||
screen: 'SetPassword'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.SetDuressPassword.title',
|
||||
screen: 'SetDuressPassword'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.SetPin.title',
|
||||
screen: 'SetPin'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.Security.deletePIN',
|
||||
action: 'DeletePin'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.SetDuressPin.title',
|
||||
screen: 'SetDuressPin'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.Security.deleteDuressPIN',
|
||||
action: 'DeleteDuressPin'
|
||||
}
|
||||
];
|
||||
|
||||
@inject('SettingsStore', 'ModalStore')
|
||||
@observer
|
||||
export default class Security extends React.Component<
|
||||
@@ -117,33 +90,75 @@ export default class Security extends React.Component<
|
||||
|
||||
// Three cases:
|
||||
// 1) If no passphrase or pin is set, allow user to set passphrase or pin
|
||||
// 2) If passphrase is set, allow user to set passphrase or duress passphrase
|
||||
// 3) If pin is set, allow user to set pin or duress pin
|
||||
// 2) If passphrase is set, allow user to change passphrase or set/change duress passphrase
|
||||
// 3) If pin is set, allow user to change pin, delete pin, set/change duress pin
|
||||
if (!settings.passphrase && !settings.pin) {
|
||||
this.setState({
|
||||
displaySecurityItems: [
|
||||
possibleSecurityItems[0],
|
||||
possibleSecurityItems[2]
|
||||
{
|
||||
translateKey: 'views.Settings.SetPassword.title',
|
||||
screen: 'SetPassword'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.SetPin.title',
|
||||
screen: 'SetPin'
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (settings.passphrase) {
|
||||
this.setState({
|
||||
displaySecurityItems: [
|
||||
possibleSecurityItems[0],
|
||||
possibleSecurityItems[1]
|
||||
{
|
||||
translateKey: 'views.Settings.ChangePassword.title',
|
||||
screen: 'SetPassword'
|
||||
},
|
||||
{
|
||||
translateKey:
|
||||
'views.Settings.SetPassword.deletePassword',
|
||||
action: 'DeletePassword'
|
||||
},
|
||||
{
|
||||
translateKey: settings.duressPassphrase
|
||||
? 'views.Settings.ChangeDuressPassword.title'
|
||||
: 'views.Settings.SetDuressPassword.title',
|
||||
screen: 'SetDuressPassword'
|
||||
},
|
||||
...(settings.duressPassphrase
|
||||
? [
|
||||
{
|
||||
translateKey:
|
||||
'views.Settings.SetDuressPassword.deletePassword',
|
||||
action: 'DeleteDuressPassword'
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]
|
||||
});
|
||||
} else if (settings.pin) {
|
||||
const minPinItems = [
|
||||
possibleSecurityItems[2],
|
||||
possibleSecurityItems[3],
|
||||
possibleSecurityItems[4]
|
||||
const items: Array<any> = [
|
||||
{
|
||||
translateKey: 'views.Settings.ChangePin.title',
|
||||
screen: 'SetPin'
|
||||
},
|
||||
{
|
||||
translateKey: 'views.Settings.Security.deletePIN',
|
||||
action: 'DeletePin'
|
||||
},
|
||||
{
|
||||
translateKey: settings.duressPin
|
||||
? 'views.Settings.ChangeDuressPin.title'
|
||||
: 'views.Settings.SetDuressPin.title',
|
||||
screen: 'SetDuressPin'
|
||||
}
|
||||
];
|
||||
if (settings.duressPin) {
|
||||
minPinItems.push(possibleSecurityItems[5]);
|
||||
items.push({
|
||||
translateKey: 'views.Settings.Security.deleteDuressPIN',
|
||||
action: 'DeleteDuressPin'
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
displaySecurityItems: minPinItems
|
||||
displaySecurityItems: items
|
||||
});
|
||||
}
|
||||
|
||||
@@ -235,6 +250,32 @@ export default class Security extends React.Component<
|
||||
navigation.navigate('Lockscreen', {
|
||||
deletePin: true
|
||||
});
|
||||
} else if (item.action === 'DeletePassword' && isBiometryEnabled) {
|
||||
ModalStore.toggleInfoModal({
|
||||
text: [
|
||||
localeString(
|
||||
'views.Settings.Security.biometricsWillBeDisabled'
|
||||
),
|
||||
localeString('general.continueQuestion')
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
title: localeString('general.ok'),
|
||||
callback: () =>
|
||||
navigation.navigate('Lockscreen', {
|
||||
deletePassword: true
|
||||
})
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (item.action === 'DeletePassword') {
|
||||
navigation.navigate('Lockscreen', {
|
||||
deletePassword: true
|
||||
});
|
||||
} else if (item.action === 'DeleteDuressPassword') {
|
||||
navigation.navigate('Lockscreen', {
|
||||
deleteDuressPassword: true
|
||||
});
|
||||
} else if (item.action === 'DeleteDuressPin') {
|
||||
navigation.navigate('Lockscreen', {
|
||||
deleteDuressPin: true
|
||||
|
||||
@@ -128,7 +128,9 @@ export default class SetDuressPassphrase extends React.Component<
|
||||
leftComponent="Back"
|
||||
centerComponent={{
|
||||
text: localeString(
|
||||
'views.Settings.SetDuressPassword.title'
|
||||
savedDuressPassphrase
|
||||
? 'views.Settings.ChangeDuressPassword.title'
|
||||
: 'views.Settings.SetDuressPassword.title'
|
||||
),
|
||||
style: {
|
||||
color: themeColor('text'),
|
||||
|
||||
@@ -144,7 +144,11 @@ export default class SetPassphrase extends React.Component<
|
||||
<Header
|
||||
leftComponent="Back"
|
||||
centerComponent={{
|
||||
text: localeString('views.Settings.SetPassword.title'),
|
||||
text: localeString(
|
||||
savedPassphrase
|
||||
? 'views.Settings.ChangePassword.title'
|
||||
: 'views.Settings.SetPassword.title'
|
||||
),
|
||||
style: {
|
||||
color: themeColor('text'),
|
||||
fontFamily: 'PPNeueMontreal-Book'
|
||||
|
||||
@@ -143,7 +143,9 @@ export default class SetPin extends React.Component<SetPinProps, SetPinState> {
|
||||
}}
|
||||
>
|
||||
{localeString(
|
||||
'views.Settings.SetPin.createPin'
|
||||
settings.pin
|
||||
? 'views.Settings.SetPin.newPin'
|
||||
: 'views.Settings.SetPin.createPin'
|
||||
)}
|
||||
</Text>
|
||||
{(settings.scramblePin ||
|
||||
|
||||
Reference in New Issue
Block a user