feat: implement credentials information on Prefs -> Account pane (#632)

* feat: implement prefs -> credentials section UI (w/o backend integration)

* feat: implement credentials information on Prefs -> Account pane

- implement email changing UI (w/o backend integration)
- implement password changing UI and reuse existing change password logic
- replace 2FA dialog with shared one
- implement React hook for preventing window refresh

* fix: provide correct types

* refactor: reuse styles from stylekit, rename components and create enum for input types

* refactor: update default exports to named ones, correct texts

* chore: remove unnecessary depenedency

* chore: yarn.lock without unnecessary packages

* Revert "chore: yarn.lock without unnecessary packages"

This reverts commit 64aa75e8408b06884d6e7383180292a4a9a3e8ad.
This commit is contained in:
Vardan Hakobyan
2021-09-09 19:23:21 +04:00
committed by GitHub
parent 7b1499d75e
commit b0ed19d6a3
23 changed files with 551 additions and 108 deletions

View File

@@ -6,11 +6,11 @@ import { FunctionComponent } from 'preact';
import { downloadSecretKey } from './download-secret-key';
import { TwoFactorActivation } from './TwoFactorActivation';
import {
TwoFactorDialog,
TwoFactorDialogLabel,
TwoFactorDialogDescription,
TwoFactorDialogButtons,
} from './TwoFactorDialog';
ModalDialog,
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel
} from '@/components/shared/ModalDialog';
export const SaveSecretKey: FunctionComponent<{
activation: TwoFactorActivation;
@@ -32,15 +32,15 @@ export const SaveSecretKey: FunctionComponent<{
/>
);
return (
<TwoFactorDialog>
<TwoFactorDialogLabel
<ModalDialog>
<ModalDialogLabel
closeDialog={() => {
act.cancelActivation();
}}
>
Step 2 of 3 - Save secret key
</TwoFactorDialogLabel>
<TwoFactorDialogDescription>
</ModalDialogLabel>
<ModalDialogDescription>
<div className="flex-grow flex flex-col gap-2">
<div className="flex flex-row items-center gap-1">
<div className="text-sm">
@@ -70,8 +70,8 @@ export const SaveSecretKey: FunctionComponent<{
</a>
</div>
</div>
</TwoFactorDialogDescription>
<TwoFactorDialogButtons>
</ModalDialogDescription>
<ModalDialogButtons>
<Button
className="min-w-20"
type="normal"
@@ -84,7 +84,7 @@ export const SaveSecretKey: FunctionComponent<{
label="Next"
onClick={() => act.openVerification()}
/>
</TwoFactorDialogButtons>
</TwoFactorDialog>
</ModalDialogButtons>
</ModalDialog>
);
});

View File

@@ -3,17 +3,17 @@ import { observer } from 'mobx-react-lite';
import QRCode from 'qrcode.react';
import { DecoratedInput } from '../../../components/DecoratedInput';
import { IconButton } from '../../../components/IconButton';
import { DecoratedInput } from '@/components/DecoratedInput';
import { IconButton } from '@/components/IconButton';
import { Button } from '@/components/Button';
import { TwoFactorActivation } from './TwoFactorActivation';
import {
TwoFactorDialog,
TwoFactorDialogLabel,
TwoFactorDialogDescription,
TwoFactorDialogButtons,
} from './TwoFactorDialog';
import { AuthAppInfoTooltip } from './AuthAppInfoPopup';
import {
ModalDialog,
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel
} from '@/components/shared/ModalDialog';
export const ScanQRCode: FunctionComponent<{
activation: TwoFactorActivation;
@@ -27,15 +27,15 @@ export const ScanQRCode: FunctionComponent<{
/>
);
return (
<TwoFactorDialog>
<TwoFactorDialogLabel
<ModalDialog>
<ModalDialogLabel
closeDialog={() => {
act.cancelActivation();
}}
>
Step 1 of 3 - Scan QR code
</TwoFactorDialogLabel>
<TwoFactorDialogDescription>
</ModalDialogLabel>
<ModalDialogDescription>
<div className="flex flex-row gap-3 items-center">
<div className="w-25 h-25 flex items-center justify-center bg-info">
<QRCode value={act.qrCode} size={100} />
@@ -61,8 +61,8 @@ export const ScanQRCode: FunctionComponent<{
</div>
</div>
</div>
</TwoFactorDialogDescription>
<TwoFactorDialogButtons>
</ModalDialogDescription>
<ModalDialogButtons>
<Button
className="min-w-20"
type="normal"
@@ -75,7 +75,7 @@ export const ScanQRCode: FunctionComponent<{
label="Next"
onClick={() => act.openSaveSecretKey()}
/>
</TwoFactorDialogButtons>
</TwoFactorDialog>
</ModalDialogButtons>
</ModalDialog>
);
});

View File

@@ -1,64 +0,0 @@
import { ComponentChildren, FunctionComponent } from 'preact';
import { IconButton } from '../../../components/IconButton';
import {
AlertDialog,
AlertDialogDescription,
AlertDialogLabel,
} from '@reach/alert-dialog';
import { useRef } from 'preact/hooks';
/**
* TwoFactorDialog is AlertDialog styled for 2FA
* Can be generalized but more use cases are needed
*/
export const TwoFactorDialog: FunctionComponent<{
children: ComponentChildren;
}> = ({ children }) => {
const ldRef = useRef<HTMLButtonElement>();
return (
<AlertDialog leastDestructiveRef={ldRef}>
{/* sn-component is focusable by default, but doesn't stretch to child width
resulting in a badly focused dialog. Utility classes are not available
at the sn-component level, only below it. tabIndex -1 disables focus
and enables it on the child component */}
<div tabIndex={-1} className="sn-component">
<div
tabIndex={0}
className="w-160 bg-default rounded shadow-overlay focus:padded-ring-info"
>
{children}
</div>
</div>
</AlertDialog>
);
};
export const TwoFactorDialogLabel: FunctionComponent<{
closeDialog: () => void;
}> = ({ children, closeDialog }) => (
<AlertDialogLabel className="">
<div className="px-4 pt-4 pb-3 flex flex-row">
<div className="flex-grow color-black text-lg font-bold">{children}</div>
<IconButton
className="color-grey-1 h-5 w-5"
icon="close"
onClick={() => closeDialog()}
/>
</div>
<hr className="h-1px bg-border no-border m-0" />
</AlertDialogLabel>
);
export const TwoFactorDialogDescription: FunctionComponent = ({ children }) => (
<AlertDialogDescription className="px-4 py-4">
{children}
</AlertDialogDescription>
);
export const TwoFactorDialogButtons: FunctionComponent = ({ children }) => (
<>
<hr className="h-1px bg-border no-border m-0" />
<div className="px-4 py-4 flex flex-row justify-end gap-3">{children}</div>
</>
);

View File

@@ -4,11 +4,11 @@ import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { TwoFactorActivation } from './TwoFactorActivation';
import {
TwoFactorDialog,
TwoFactorDialogLabel,
TwoFactorDialogDescription,
TwoFactorDialogButtons,
} from './TwoFactorDialog';
ModalDialog,
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel
} from '@/components/shared/ModalDialog';
export const Verification: FunctionComponent<{
activation: TwoFactorActivation;
@@ -16,11 +16,11 @@ export const Verification: FunctionComponent<{
const borderInv =
act.verificationStatus === 'invalid' ? 'border-dark-red' : '';
return (
<TwoFactorDialog>
<TwoFactorDialogLabel closeDialog={act.cancelActivation}>
<ModalDialog>
<ModalDialogLabel closeDialog={act.cancelActivation}>
Step 3 of 3 - Verification
</TwoFactorDialogLabel>
<TwoFactorDialogDescription>
</ModalDialogLabel>
<ModalDialogDescription>
<div className="flex-grow flex flex-col gap-1">
<div className="flex flex-row items-center gap-2">
<div className="text-sm">
@@ -42,8 +42,8 @@ export const Verification: FunctionComponent<{
/>
</div>
</div>
</TwoFactorDialogDescription>
<TwoFactorDialogButtons>
</ModalDialogDescription>
<ModalDialogButtons>
{act.verificationStatus === 'invalid' && (
<div className="text-sm color-danger">
Incorrect credentials, please try again.
@@ -61,7 +61,7 @@ export const Verification: FunctionComponent<{
label="Next"
onClick={act.enable2FA}
/>
</TwoFactorDialogButtons>
</TwoFactorDialog>
</ModalDialogButtons>
</ModalDialog>
);
});