Multi-Factor Auth with OTP

This commit is contained in:
marykatefain 2020-08-07 20:17:13 +00:00 committed by Alex Gleason
parent 19e3dc9ed3
commit 68f765da28
23 changed files with 154 additions and 10 deletions

Binary file not shown.

BIN
app/soapbox/actions/mfa.js Normal file

Binary file not shown.

Binary file not shown.

View file

@ -3,11 +3,8 @@
exports[`<LoginForm /> renders correctly 1`] = ` exports[`<LoginForm /> renders correctly 1`] = `
<form <form
className="simple_form new_user" className="simple_form new_user"
onSubmit={[Function]}
> >
<fieldset <fieldset>
disabled={false}
>
<div <div
className="fields-group" className="fields-group"
> >

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<LoginPage /> renders correctly 1`] = ` exports[`<LoginPage /> renders correctly on load 1`] = `
<form <form
className="simple_form new_user" className="simple_form new_user"
onSubmit={[Function]} onSubmit={[Function]}
@ -59,4 +59,4 @@ exports[`<LoginPage /> renders correctly 1`] = `
</form> </form>
`; `;
exports[`<LoginPage /> renders correctly 2`] = `null`; exports[`<LoginPage /> renders correctly on load 2`] = `null`;

Binary file not shown.

Binary file not shown.

View file

@ -34,6 +34,7 @@ $small-breakpoint: 960px;
flex-wrap: nowrap; flex-wrap: nowrap;
padding: 14px 0; padding: 14px 0;
box-sizing: border-box; box-sizing: border-box;
position: relative;
@media screen and (max-width: 1024px) { @media screen and (max-width: 1024px) {
padding: 14px 20px; padding: 14px 20px;
@ -1712,7 +1713,40 @@ $small-breakpoint: 960px;
.header, .header,
.container { .container {
position: relative; position: relative;
z-index: 1; }
.otp-form-overlay__container {
z-index: 9998;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba($base-overlay-background, 0.7);
.otp-form-overlay__form {
@include standard-panel-shadow;
border-radius: 10px;
z-index: 9999;
margin: 0 auto;
max-width: 800px;
position: relative;
padding: 20px;
background-color: var(--background-color);
display: flex;
flex-direction: column;
.simple_form {
padding: 30px 50px 50px;
}
.otp-form-overlay__close {
align-self: flex-end;
}
}
} }
} }
@ -1725,3 +1759,10 @@ $small-breakpoint: 960px;
bottom: 0; bottom: 0;
right: 0; right: 0;
} }
h1.otp-login {
font-size: 16px;
line-height: 24px;
font-weight: 800;
padding: 10px 0;
}

View file

@ -72,3 +72,4 @@
@import 'components/video-player'; @import 'components/video-player';
@import 'components/audio-player'; @import 'components/audio-player';
@import 'components/profile_hover_card'; @import 'components/profile_hover_card';
@import 'components/mfa_form';

View file

@ -102,7 +102,7 @@ button {
&:focus, &:focus,
&:hover { &:hover {
border-color: var(--brand-color); border-color: var(--brand-color);
color: var(--primary-text-color); color: var(--background-color);
} }
&:disabled { &:disabled {

View file

@ -0,0 +1,81 @@
.security-settings-panel {
margin: 20px;
h1.security-settings-panel__setup-otp {
font-size: 20px;
line-height: 1.25;
color: var(--primary-text-color);
font-weight: 600;
}
h2.security-settings-panel__setup-otp {
display: block;
font-size: 16px;
line-height: 1.5;
color: var(--primary-text-color--faint);
font-weight: 400;
}
div {
display: block;
margin: 10px 0;
}
.security-warning {
color: var(--primary-text-color);
padding: 15px 20px;
font-size: 14px;
background-color: var(--warning-color--faint);
margin: 5px 20px;
border-radius: 8px;
margin: 20px auto;
}
.backup_codes {
margin: 20px;
font-weight: bold;
padding: 15px 20px;
font-size: 14px;
background-color: var(--brand-color--faint);
border-radius: 8px;
margin: 20px;
text-align: center;
position: relative;
min-height: 125px;
.backup_code {
margin: 5px auto;
}
.loading-indicator {
position: absolute;
}
}
.security-settings-panel__setup-otp__buttons {
margin: 20px;
display: flex;
justify-content: space-between;
.button {
min-width: 182px;
}
}
div.confirm-key {
display: block;
font-size: 16px;
line-height: 1.5;
color: var(--primary-text-color--faint);
font-weight: 400;
margin: 0 0 20px 20px;
}
}
form.otp-auth {
.error-box {
width: 100%;
text-align: center;
color: $error-red;
}
}

View file

@ -255,9 +255,9 @@
display: block; display: block;
margin-right: 30px; margin-right: 30px;
border: 0; border: 0;
height: 50px; height: 40px;
overflow: hidden; overflow: hidden;
padding: 10px 0; padding: 13px 0 0;
box-sizing: border-box; box-sizing: border-box;
filter: brightness(0%) grayscale(100%) invert(100%); filter: brightness(0%) grayscale(100%) invert(100%);
& span {display: none !important;} & span {display: none !important;}

View file

@ -30,12 +30,14 @@ body {
--accent-color: hsl(var(--accent-color_hsl)); --accent-color: hsl(var(--accent-color_hsl));
--primary-text-color: hsl(var(--primary-text-color_hsl)); --primary-text-color: hsl(var(--primary-text-color_hsl));
--background-color: hsl(var(--background-color_hsl)); --background-color: hsl(var(--background-color_hsl));
--warning-color: hsla(var(--warning-color_hsl));
// Meta-variables // Meta-variables
--brand-color_hsl: var(--brand-color_h), var(--brand-color_s), var(--brand-color_l); --brand-color_hsl: var(--brand-color_h), var(--brand-color_s), var(--brand-color_l);
--accent-color_hsl: var(--accent-color_h), var(--accent-color_s), var(--accent-color_l); --accent-color_hsl: var(--accent-color_h), var(--accent-color_s), var(--accent-color_l);
--primary-text-color_hsl: var(--primary-text-color_h), var(--primary-text-color_s), var(--primary-text-color_l); --primary-text-color_hsl: var(--primary-text-color_h), var(--primary-text-color_s), var(--primary-text-color_l);
--background-color_hsl: var(--background-color_h), var(--background-color_s), var(--background-color_l); --background-color_hsl: var(--background-color_h), var(--background-color_s), var(--background-color_l);
--warning-color_hsl: var(--warning-color_h), var(--warning-color_s), var(--warning-color_l);
--accent-color_h: calc(var(--brand-color_h) - 15); --accent-color_h: calc(var(--brand-color_h) - 15);
--accent-color_s: 86%; --accent-color_s: 86%;
--accent-color_l: 44%; --accent-color_l: 44%;
@ -51,6 +53,7 @@ body {
calc(var(--accent-color_l) + 3%) calc(var(--accent-color_l) + 3%)
); );
--primary-text-color--faint: hsla(var(--primary-text-color_hsl), 0.6); --primary-text-color--faint: hsla(var(--primary-text-color_hsl), 0.6);
--warning-color--faint: hsla(var(--warning-color_hsl), 0.5);
} }
body.theme-mode-light { body.theme-mode-light {
@ -69,6 +72,9 @@ body.theme-mode-light {
--background-color_h: 0; --background-color_h: 0;
--background-color_s: 0%; --background-color_s: 0%;
--background-color_l: 94.9%; --background-color_l: 94.9%;
--warning-color_h: 0;
--warning-color_s: 100%;
--warning-color_l: 66%;
// Modifiers // Modifiers
--brand-color--hicontrast: hsl( --brand-color--hicontrast: hsl(
@ -94,6 +100,9 @@ body.theme-mode-dark {
--background-color_h: 0; --background-color_h: 0;
--background-color_s: 0%; --background-color_s: 0%;
--background-color_l: 20%; --background-color_l: 20%;
--warning-color_h: 0;
--warning-color_s: 100%;
--warning-color_l: 66%;
// Modifiers // Modifiers
--brand-color--hicontrast: hsl( --brand-color--hicontrast: hsl(

View file

@ -100,6 +100,7 @@
"postcss-object-fit-images": "^1.1.2", "postcss-object-fit-images": "^1.1.2",
"prop-types": "^15.5.10", "prop-types": "^15.5.10",
"punycode": "^2.1.0", "punycode": "^2.1.0",
"qrcode.react": "^1.0.0",
"rails-ujs": "^5.2.3", "rails-ujs": "^5.2.3",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",

View file

@ -9320,6 +9320,20 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
qr.js@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
qrcode.react@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.0.tgz#7e8889db3b769e555e8eb463d4c6de221c36d5de"
integrity sha512-jBXleohRTwvGBe1ngV+62QvEZ/9IZqQivdwzo9pJM4LQMoCM2VnvNBnKdjvGnKyDZ/l0nCDgsPod19RzlPvm/Q==
dependencies:
loose-envify "^1.4.0"
prop-types "^15.6.0"
qr.js "0.0.0"
qs@6.7.0: qs@6.7.0:
version "6.7.0" version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"