Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.

Commit 11fae4d

Browse files
Merge pull request #1234 from lightninglabs/dev/reset-pin-mobile-custom-views
Dev/reset pin mobile custom views
2 parents f655361 + 2726911 commit 11fae4d

11 files changed

+476
-6
lines changed

src/action/auth-mobile.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ class AuthAction {
4343
this._nav.goPassword();
4444
}
4545

46+
/**
47+
* Initialize the reset pin flow by resetting input values
48+
* and then navigating to the view.
49+
* @return {undefined}
50+
*/
51+
initResetPin() {
52+
this._store.auth.resetPinCurrent = '';
53+
this._store.auth.resetPinNew = '';
54+
this._store.auth.resetPinVerify = '';
55+
this._nav.goResetPasswordCurrent();
56+
}
57+
58+
/**
59+
* Initialize the reset new pin flow by resetting new values
60+
* and then navigating to the new pin view.
61+
* @return {undefined}
62+
*/
63+
initResetPinNew() {
64+
this._store.auth.resetPinNew = '';
65+
this._store.auth.resetPinVerify = '';
66+
this._nav.goResetPasswordNew();
67+
}
68+
4669
/**
4770
* Append a digit input to the pin parameter.
4871
* @param {string} options.digit The digit to append to the pin
@@ -63,6 +86,12 @@ class AuthAction {
6386
this.checkNewPin();
6487
} else if (param === 'pin') {
6588
this.checkPin();
89+
} else if (param === 'resetPinCurrent') {
90+
this._nav.goResetPasswordNew();
91+
} else if (param === 'resetPinNew') {
92+
this._nav.goResetPasswordConfirm();
93+
} else if (param === 'resetPinVerify') {
94+
this.checkResetPin();
6695
}
6796
}
6897

@@ -77,6 +106,12 @@ class AuthAction {
77106
auth[param] = auth[param].slice(0, -1);
78107
} else if (param === 'pinVerify') {
79108
this.initSetPin();
109+
} else if (param === 'resetPinCurrent') {
110+
this._nav.goSettings();
111+
} else if (param === 'resetPinNew') {
112+
this.initResetPin();
113+
} else if (param === 'resetPinVerify') {
114+
this.initResetPinNew();
80115
}
81116
}
82117

@@ -113,6 +148,33 @@ class AuthAction {
113148
await this._unlockWallet();
114149
}
115150

151+
/**
152+
* Check that the pin that was chosen by the user doesn't match
153+
* their current pin, and that it was entered correctly twice.
154+
* If everything is ok, store the pin in the keystore and redirect
155+
* to home.
156+
* @return {undefined}
157+
*/
158+
async checkResetPin() {
159+
const { resetPinCurrent, resetPinNew, resetPinVerify } = this._store.auth;
160+
const storedPin = await this._getFromKeyStore(PIN);
161+
if (resetPinCurrent !== storedPin) {
162+
this._alert('Incorrect PIN', () => this.initResetPin());
163+
return;
164+
} else if (resetPinCurrent === resetPinNew) {
165+
this._alert('New PIN must not match old PIN', () => this.initResetPin());
166+
return;
167+
} else if (
168+
resetPinNew.length !== PIN_LENGTH ||
169+
resetPinNew !== resetPinVerify
170+
) {
171+
this._alert("PINs don't match", () => this.initResetPin());
172+
return;
173+
}
174+
await this._setToKeyStore(PIN, resetPinNew);
175+
this._nav.goResetPasswordSaved();
176+
}
177+
116178
//
117179
// TouchID & KeyStore Authentication
118180
//

src/action/nav-mobile.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ class NavAction {
7575
this._navigate('ResetPasswordCurrent');
7676
}
7777

78+
goResetPasswordNew() {
79+
this._navigate('ResetPasswordNew');
80+
}
81+
82+
goResetPasswordConfirm() {
83+
this._navigate('ResetPasswordConfirm');
84+
}
85+
86+
goResetPasswordSaved() {
87+
this._navigate('ResetPasswordSaved');
88+
}
89+
7890
goNewAddress() {
7991
this._navigate('NewAddress');
8092
}

src/store.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ export class Store {
4343
pin: '',
4444
newPin: '',
4545
pinVerify: '',
46+
resetPinCurrent: '',
47+
resetPinNew: '',
48+
resetPinVerify: '',
4649
},
4750
wallet: {
4851
password: '',

src/view/main-mobile.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import RestoreSeedView from './restore-seed-mobile';
2020
import NewAddressView from './new-address-mobile';
2121

2222
import PinView from './pin-mobile';
23+
import ResetPinCurrentView from './reset-pin-current-mobile';
24+
import ResetPinNewView from './reset-pin-new-mobile';
25+
import ResetPinConfirmView from './reset-pin-confirm-mobile';
26+
import ResetPinSavedView from './reset-pin-saved-mobile';
2327
import LoaderSyncingView from './loader-syncing-mobile';
2428
import WaitView from './wait-mobile';
2529
import HomeView from './home';
@@ -93,6 +97,18 @@ const NewAddress = () => (
9397

9498
const Password = () => <PinView store={store} auth={auth} />;
9599

100+
const ResetPasswordCurrent = () => (
101+
<ResetPinCurrentView store={store} auth={auth} nav={nav} />
102+
);
103+
104+
const ResetPasswordNew = () => <ResetPinNewView store={store} auth={auth} />;
105+
106+
const ResetPasswordConfirm = () => (
107+
<ResetPinConfirmView store={store} auth={auth} />
108+
);
109+
110+
const ResetPasswordSaved = () => <ResetPinSavedView nav={nav} />;
111+
96112
const LoaderSyncing = () => <LoaderSyncingView store={store} />;
97113

98114
const Wait = () => <WaitView />;
@@ -110,7 +126,7 @@ const Home = () => (
110126
);
111127

112128
const Settings = () => (
113-
<SettingView store={store} nav={nav} wallet={wallet} autopilot={autopilot} />
129+
<SettingView store={store} nav={nav} auth={auth} autopilot={autopilot} />
114130
);
115131

116132
const SettingsUnit = () => (
@@ -247,6 +263,10 @@ const SettingStack = createStackNavigator(
247263
Settings,
248264
SettingsUnit,
249265
SettingsFiat,
266+
ResetPasswordCurrent,
267+
ResetPasswordNew,
268+
ResetPasswordConfirm,
269+
ResetPasswordSaved,
250270
CLI,
251271
Notifications,
252272
},

src/view/reset-pin-confirm-mobile.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import { StyleSheet } from 'react-native';
3+
import { observer } from 'mobx-react';
4+
import PropTypes from 'prop-types';
5+
import Background from '../component/background';
6+
import { Header, Title } from '../component/header';
7+
import { Button, BackButton } from '../component/button';
8+
import MainContent from '../component/main-content';
9+
import { CopyOnboardText, Text } from '../component/text';
10+
import { FormStretcher } from '../component/form';
11+
import { PinBubbles, PinKeyboard } from '../component/pin-entry';
12+
import { color } from '../component/style';
13+
14+
//
15+
// Reset Pin: Confirm New View (Mobile)
16+
//
17+
18+
const styles = StyleSheet.create({
19+
content: {
20+
paddingLeft: 20,
21+
paddingRight: 20,
22+
},
23+
title: {
24+
marginTop: 50,
25+
},
26+
text: {
27+
marginTop: 10,
28+
textAlign: 'center',
29+
maxWidth: 250,
30+
},
31+
});
32+
33+
const ResetPinConfirmView = ({ store, auth }) => (
34+
<Background color={color.blackDark}>
35+
<Header separator>
36+
<BackButton onPress={() => auth.initResetPinNew()} />
37+
<Title title="Change PIN" />
38+
<Button disabled onPress={() => {}} />
39+
</Header>
40+
<MainContent style={styles.content}>
41+
<CopyOnboardText style={styles.title}>Re-type PIN</CopyOnboardText>
42+
<Text style={styles.text}>
43+
{"Type your PIN again to make sure it's the correct one."}
44+
</Text>
45+
<FormStretcher>
46+
<PinBubbles pin={store.auth.resetPinVerify} />
47+
</FormStretcher>
48+
<PinKeyboard
49+
onInput={digit => auth.pushPinDigit({ digit, param: 'resetPinVerify' })}
50+
onBackspace={() => auth.popPinDigit({ param: 'resetPinVerify' })}
51+
/>
52+
</MainContent>
53+
</Background>
54+
);
55+
56+
ResetPinConfirmView.propTypes = {
57+
store: PropTypes.object.isRequired,
58+
auth: PropTypes.object.isRequired,
59+
};
60+
61+
export default observer(ResetPinConfirmView);

src/view/reset-pin-current-mobile.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { StyleSheet } from 'react-native';
3+
import { observer } from 'mobx-react';
4+
import PropTypes from 'prop-types';
5+
import Background from '../component/background';
6+
import { Header, Title } from '../component/header';
7+
import { Button, BackButton } from '../component/button';
8+
import MainContent from '../component/main-content';
9+
import { CopyOnboardText, Text } from '../component/text';
10+
import { FormStretcher } from '../component/form';
11+
import { PinBubbles, PinKeyboard } from '../component/pin-entry';
12+
import { color } from '../component/style';
13+
14+
//
15+
// Reset Pin: Current Pin View (Mobile)
16+
//
17+
18+
const styles = StyleSheet.create({
19+
content: {
20+
paddingLeft: 20,
21+
paddingRight: 20,
22+
},
23+
title: {
24+
marginTop: 50,
25+
},
26+
text: {
27+
marginTop: 10,
28+
textAlign: 'center',
29+
maxWidth: 250,
30+
},
31+
});
32+
33+
const ResetPinCurrentView = ({ store, nav, auth }) => (
34+
<Background color={color.blackDark}>
35+
<Header separator>
36+
<BackButton onPress={() => nav.goSettings()} />
37+
<Title title="Change PIN" />
38+
<Button disabled onPress={() => {}} />
39+
</Header>
40+
<MainContent style={styles.content}>
41+
<CopyOnboardText style={styles.title}>Current PIN</CopyOnboardText>
42+
<Text style={styles.text}>{'First type your current PIN below.'}</Text>
43+
<FormStretcher>
44+
<PinBubbles pin={store.auth.resetPinCurrent} />
45+
</FormStretcher>
46+
<PinKeyboard
47+
onInput={digit =>
48+
auth.pushPinDigit({ digit, param: 'resetPinCurrent' })
49+
}
50+
onBackspace={() => auth.popPinDigit({ param: 'resetPinCurrent' })}
51+
/>
52+
</MainContent>
53+
</Background>
54+
);
55+
56+
ResetPinCurrentView.propTypes = {
57+
store: PropTypes.object.isRequired,
58+
auth: PropTypes.object.isRequired,
59+
nav: PropTypes.object.isRequired,
60+
};
61+
62+
export default observer(ResetPinCurrentView);

src/view/reset-pin-new-mobile.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import { StyleSheet } from 'react-native';
3+
import { observer } from 'mobx-react';
4+
import PropTypes from 'prop-types';
5+
import Background from '../component/background';
6+
import { Header, Title } from '../component/header';
7+
import { Button, BackButton } from '../component/button';
8+
import MainContent from '../component/main-content';
9+
import { CopyOnboardText, Text } from '../component/text';
10+
import { FormStretcher } from '../component/form';
11+
import { PinBubbles, PinKeyboard } from '../component/pin-entry';
12+
import { color } from '../component/style';
13+
14+
//
15+
// Reset Pin: New Pin View (Mobile)
16+
//
17+
18+
const styles = StyleSheet.create({
19+
content: {
20+
paddingLeft: 20,
21+
paddingRight: 20,
22+
},
23+
title: {
24+
marginTop: 50,
25+
},
26+
text: {
27+
marginTop: 10,
28+
textAlign: 'center',
29+
maxWidth: 250,
30+
},
31+
});
32+
33+
const ResetPinNewView = ({ store, auth }) => (
34+
<Background color={color.blackDark}>
35+
<Header separator>
36+
<BackButton onPress={() => auth.initResetPin()} />
37+
<Title title="Change PIN" />
38+
<Button disabled onPress={() => {}} />
39+
</Header>
40+
<MainContent style={styles.content}>
41+
<CopyOnboardText style={styles.title}>New PIN</CopyOnboardText>
42+
<Text style={styles.text}>
43+
{'Type the new PIN you would like to use below.'}
44+
</Text>
45+
<FormStretcher>
46+
<PinBubbles pin={store.auth.resetPinNew} />
47+
</FormStretcher>
48+
<PinKeyboard
49+
onInput={digit => auth.pushPinDigit({ digit, param: 'resetPinNew' })}
50+
onBackspace={() => auth.popPinDigit({ param: 'resetPinNew' })}
51+
/>
52+
</MainContent>
53+
</Background>
54+
);
55+
56+
ResetPinNewView.propTypes = {
57+
store: PropTypes.object.isRequired,
58+
auth: PropTypes.object.isRequired,
59+
};
60+
61+
export default observer(ResetPinNewView);

0 commit comments

Comments
 (0)