Add forgot pin flow

This commit is contained in:
Bojan Mojsilovic 2024-03-18 14:49:28 +01:00
parent 29461e4e96
commit f07932707d
3 changed files with 86 additions and 5 deletions

View File

@ -14,6 +14,8 @@ import ButtonPrimary from '../Buttons/ButtonPrimary';
import TextInput from '../TextInput/TextInput'; import TextInput from '../TextInput/TextInput';
import { decryptWithPin, setCurrentPin } from '../../lib/PrimalNostr'; import { decryptWithPin, setCurrentPin } from '../../lib/PrimalNostr';
import { logError } from '../../lib/logger'; import { logError } from '../../lib/logger';
import ButtonSecondary from '../Buttons/ButtonSecondary';
import { useAccountContext } from '../../contexts/AccountContext';
const EnterPinModal: Component<{ const EnterPinModal: Component<{
id?: string, id?: string,
@ -21,10 +23,12 @@ const EnterPinModal: Component<{
valueToDecrypt?: string, valueToDecrypt?: string,
onSuccess?: (decryptedValue: string) => void, onSuccess?: (decryptedValue: string) => void,
onAbort?: () => void, onAbort?: () => void,
onForgot?: () => void,
}> = (props) => { }> = (props) => {
const intl = useIntl(); const intl = useIntl();
const toast = useToastContext(); const toast = useToastContext();
const account = useAccountContext();
let pinInput: HTMLInputElement | undefined; let pinInput: HTMLInputElement | undefined;
@ -107,6 +111,12 @@ const EnterPinModal: Component<{
> >
{intl.formatMessage(tActions.login)} {intl.formatMessage(tActions.login)}
</ButtonPrimary> </ButtonPrimary>
<ButtonSecondary
onClick={props.onForgot}
>
{intl.formatMessage(tActions.forgotPin)}
</ButtonSecondary>
</div> </div>
</div> </div>
</Modal> </Modal>

View File

@ -39,7 +39,7 @@ import LoginModal from "../components/LoginModal/LoginModal";
import { logError, logInfo, logWarning } from "../lib/logger"; import { logError, logInfo, logWarning } from "../lib/logger";
import { useToastContext } from "../components/Toaster/Toaster"; import { useToastContext } from "../components/Toaster/Toaster";
import { useIntl } from "@cookbook/solid-intl"; import { useIntl } from "@cookbook/solid-intl";
import { account as tAccount } from "../translations"; import { account as tAccount, followWarning, forgotPin } from "../translations";
import { getMembershipStatus } from "../lib/membership"; import { getMembershipStatus } from "../lib/membership";
import ConfirmModal from "../components/ConfirmModal/ConfirmModal"; import ConfirmModal from "../components/ConfirmModal/ConfirmModal";
@ -69,6 +69,7 @@ export type AccountContextStore = {
allowlistSince: number, allowlistSince: number,
sec: string | undefined, sec: string | undefined,
showPin: string, showPin: string,
showForgot: boolean,
showGettingStarted: boolean, showGettingStarted: boolean,
showLogin: boolean, showLogin: boolean,
emojiHistory: EmojiOption[], emojiHistory: EmojiOption[],
@ -128,6 +129,7 @@ const initialData = {
allowlistSince: 0, allowlistSince: 0,
sec: undefined, sec: undefined,
showPin: '', showPin: '',
showForgot: false,
showGettingStarted: false, showGettingStarted: false,
showLogin: false, showLogin: false,
emojiHistory: [], emojiHistory: [],
@ -1525,6 +1527,10 @@ const [store, updateStore] = createStore<AccountContextStore>({
updateStore('showPin', () => ''); updateStore('showPin', () => '');
}} }}
onAbort={() => updateStore('showPin', () => '')} onAbort={() => updateStore('showPin', () => '')}
onForgot={() => {
updateStore('showPin', () => '');
updateStore('showForgot', () => true);
}}
/> />
<CreateAccountModal <CreateAccountModal
open={store.showGettingStarted} open={store.showGettingStarted}
@ -1540,10 +1546,10 @@ const [store, updateStore] = createStore<AccountContextStore>({
/> />
<ConfirmModal <ConfirmModal
open={followData.openDialog} open={followData.openDialog}
title="This action may result in an error" title={intl.formatMessage(followWarning.title)}
description={'If you continue, you will end up following just one nostr account. Are you sure you want to continue?'} description={intl.formatMessage(followWarning.description)}
confirmLabel="Yes, continue" confirmLabel={intl.formatMessage(followWarning.confirm)}
abortLablel="Abort" abortLablel={intl.formatMessage(followWarning.abort)}
onConfirm={async () => { onConfirm={async () => {
if (store.publicKey) { if (store.publicKey) {
const data = unwrap(followData) const data = unwrap(followData)
@ -1567,6 +1573,20 @@ const [store, updateStore] = createStore<AccountContextStore>({
})); }));
}} }}
/> />
<ConfirmModal
open={store.showForgot}
title={intl.formatMessage(forgotPin.title)}
description={intl.formatMessage(forgotPin.description)}
confirmLabel={intl.formatMessage(forgotPin.confirm)}
abortLablel={intl.formatMessage(forgotPin.abort)}
onConfirm={async () => {
logout();
updateStore('showForgot', () => false);
}}
onAbort={() => {
updateStore('showForgot', () => false);
}}
/>
</AccountContext.Provider> </AccountContext.Provider>
); );
} }

View File

@ -182,6 +182,11 @@ export const actions = {
defaultMessage: 'Get Started', defaultMessage: 'Get Started',
description: 'Get Started action, button label', description: 'Get Started action, button label',
}, },
forgotPin: {
id: 'actions.forgotPin',
defaultMessage: 'I forgot my PIN',
description: 'Forgot PIN action, button label',
},
cancel: { cancel: {
id: 'actions.cancel', id: 'actions.cancel',
defaultMessage: 'Cancel', defaultMessage: 'Cancel',
@ -2020,3 +2025,49 @@ export const landing = {
description: 'Landing page browser option', description: 'Landing page browser option',
}, },
}; };
export const forgotPin = {
title: {
id: 'forgotPin.title',
defaultMessage: 'This action will erase you key',
description: 'Forgot pin modal title',
},
description: {
id: 'forgotPin.description',
defaultMessage: 'You will still be able to browse Nostr through Primal but you will not be able to take any actions (post notes, likes,...) until you re-login with your private key. Are you sure you wish to continue?',
description: 'Explanation of what happens when pin is erased',
},
confirm: {
id: 'forgotPin.confirm',
defaultMessage: 'Yes, continue',
description: 'Confirm forgot pin action',
},
abort: {
id: 'forgotPin.abort',
defaultMessage: 'Cancel',
description: 'Abort forgot pin action',
},
};
export const followWarning = {
title: {
id: 'followWarning.title',
defaultMessage: 'This action may result in an error',
description: 'Follow error modal title',
},
description: {
id: 'followWarning.description',
defaultMessage: 'If you continue, you will end up following just one nostr account. Are you sure you want to continue?',
description: 'Explanation of what happens when follow erro occurs',
},
confirm: {
id: 'followWarning.confirm',
defaultMessage: 'Yes, continue',
description: 'Confirm forgot pin action',
},
abort: {
id: 'followWarning.abort',
defaultMessage: 'Abort',
description: 'Abort forgot pin action',
},
};