feat: two factor authentication segment in preferences with mocked state (#600)

This commit is contained in:
Gorjan Petrovski
2021-07-21 12:17:50 +02:00
committed by GitHub
parent bffd9ec54d
commit d9c5fd5129
32 changed files with 618 additions and 247 deletions

View File

@@ -0,0 +1,101 @@
import { FunctionComponent } from 'preact';
import {} from '../components';
import {
Title,
Subtitle,
Text,
Button,
PreferencesGroup,
PreferencesPane,
PreferencesSegment,
} from '../components';
export const HelpAndFeedback: FunctionComponent = () => (
<PreferencesPane>
<PreferencesGroup>
<PreferencesSegment>
<Title>Frequently asked questions</Title>
<div className="h-2 w-full" />
<Subtitle>Who can read my private notes?</Subtitle>
<Text>
Quite simply: no one but you. Not us, not your ISP, not a hacker, and
not a government agency. As long as you keep your password safe, and
your password is reasonably strong, then you are the only person in
the world with the ability to decrypt your notes. For more on how we
handle your privacy and security, check out our easy to read{' '}
<a target="_blank" href="https://standardnotes.com/privacy">
Privacy Manifesto.
</a>
</Text>
</PreferencesSegment>
<PreferencesSegment>
<Subtitle>Can I collaborate with others on a note?</Subtitle>
<Text>
Because of our encrypted architecture, Standard Notes does not
currently provide a real-time collaboration solution. Multiple users
can share the same account however, but editing at the same time may
result in sync conflicts, which may result in the duplication of
notes.
</Text>
</PreferencesSegment>
<PreferencesSegment>
<Subtitle>Can I use Standard Notes totally offline?</Subtitle>
<Text>
Standard Notes can be used totally offline without an account, and
without an internet connection. You can find{' '}
<a
target="_blank"
href="https://standardnotes.com/help/59/can-i-use-standard-notes-totally-offline"
>
more details here.
</a>
</Text>
</PreferencesSegment>
<PreferencesSegment>
<Subtitle>Cant find your question here?</Subtitle>
<Button label="Open FAQ" link="https://standardnotes.com/help" />
</PreferencesSegment>
</PreferencesGroup>
<PreferencesGroup>
<PreferencesSegment>
<Title>Community forum</Title>
<Text>
If you have an issue, found a bug or want to suggest a feature, you
can browse or post to the forum. Its recommended for non-account
related issues. Please read our{' '}
<a target="_blank" href="https://standardnotes.com/longevity/">
Longevity statement
</a>{' '}
before advocating for a feature request.
</Text>
<Button
label="Go to the forum"
link="https://forum.standardnotes.org/"
/>
</PreferencesSegment>
</PreferencesGroup>
<PreferencesGroup>
<PreferencesSegment>
<Title>Slack group</Title>
<Text>
Want to meet other passionate note-takers and privacy enthusiasts?
Want to share your feedback with us? Join the Standard Notes Slack
group for discussions on security, themes, editors and more.
</Text>
<Button
link="https://standardnotes.com/slack"
label="Join our Slack group"
/>
</PreferencesSegment>
</PreferencesGroup>
<PreferencesGroup>
<PreferencesSegment>
<Title>Account related issue?</Title>
<Text>
Send an email to help@standardnotes.org and well sort it out.
</Text>
<Button link="mailto: help@standardnotes.org" label="Email us" />
</PreferencesSegment>
</PreferencesGroup>
</PreferencesPane>
);

View File

@@ -0,0 +1,13 @@
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { PreferencesPane } from '../components';
import { Preferences } from '../models';
import { TwoFactorAuthComponent } from './TwoFactorAuth';
export const Security: FunctionComponent<{ prefs: Preferences }> = observer(
({ prefs }) => (
<PreferencesPane>
<TwoFactorAuthComponent tfAuth={prefs.twoFactorAuth} />
</PreferencesPane>
)
);

View File

@@ -0,0 +1,110 @@
import { FunctionComponent } from 'preact';
import {
Title,
Text,
PreferencesGroup,
PreferencesSegment,
} from '../components';
import { Switch } from '../../components/Switch';
import { observer } from 'mobx-react-lite';
import { DecoratedInput } from '../../components/DecoratedInput';
import { IconButton } from '../../components/IconButton';
import { TwoFactorAuth } from '../models';
// Temporary implementation until integration
function downloadSecretKey(text: string) {
const link = document.createElement('a');
const blob = new Blob([text], {
type: 'text/plain;charset=utf-8',
});
link.href = window.URL.createObjectURL(blob);
link.setAttribute('download', 'secret_key.txt');
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(link.href);
}
export const TwoFactorAuthComponent: FunctionComponent<{
tfAuth: TwoFactorAuth;
}> = observer(({ tfAuth }) => {
return (
<PreferencesGroup>
<PreferencesSegment>
<div className="flex flex-row items-center">
<div className="flex-grow flex flex-col">
<Title>Two-factor authentication</Title>
<Text>
An extra layer of security when logging in to your account.
</Text>
</div>
<Switch
checked={tfAuth.twoFactorStatus === 'enabled'}
onChange={() => tfAuth.toggle2FA()}
/>
</div>
</PreferencesSegment>
<PreferencesSegment>
{tfAuth.twoFactorStatus === 'enabled' &&
tfAuth.twoFactorData != null ? (
<TwoFactorEnabled tfAuth={tfAuth} />
) : (
<TwoFactorDisabled />
)}
</PreferencesSegment>
</PreferencesGroup>
);
});
const TwoFactorEnabled: FunctionComponent<{ tfAuth: TwoFactorAuth }> = observer(
({ tfAuth }) => {
const state = tfAuth.twoFactorData!;
const download = (
<IconButton
icon="download"
onClick={() => {
downloadSecretKey(state.secretKey);
}}
/>
);
const copy = (
<IconButton
icon="copy"
onClick={() => {
navigator?.clipboard?.writeText(state.secretKey);
}}
/>
);
const spinner = <div class="sk-spinner info w-8 h-3.5" />;
return (
<div className="flex flex-row gap-4">
<div className="flex-grow flex flex-col">
<Text>Secret Key</Text>
<DecoratedInput
disabled={true}
right={[copy, download]}
text={state.secretKey}
/>
</div>
<div className="w-30 flex flex-col">
<Text>Authentication Code</Text>
<DecoratedInput
disabled={true}
text={state.authCode}
right={[spinner]}
/>
</div>
</div>
);
}
);
const TwoFactorDisabled: FunctionComponent = () => (
<Text>
Enabling two-factor authentication will sign you out of all other sessions.{' '}
<a
target="_blank"
href="https://standardnotes.com/help/21/where-should-i-store-my-two-factor-authentication-secret-key"
>
Learn more
</a>
</Text>
);

View File

@@ -0,0 +1,2 @@
export * from './HelpFeedback';
export * from './Security';