Multi-Factor Auth with OTP
This commit is contained in:
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
BIN
app/soapbox/actions/mfa.js
Normal file
Binary file not shown.
Binary file not shown.
|
@ -3,11 +3,8 @@
|
|||
exports[`<LoginForm /> renders correctly 1`] = `
|
||||
<form
|
||||
className="simple_form new_user"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<fieldset
|
||||
disabled={false}
|
||||
>
|
||||
<fieldset>
|
||||
<div
|
||||
className="fields-group"
|
||||
>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<LoginPage /> renders correctly 1`] = `
|
||||
exports[`<LoginPage /> renders correctly on load 1`] = `
|
||||
<form
|
||||
className="simple_form new_user"
|
||||
onSubmit={[Function]}
|
||||
|
@ -59,4 +59,4 @@ exports[`<LoginPage /> renders correctly 1`] = `
|
|||
</form>
|
||||
`;
|
||||
|
||||
exports[`<LoginPage /> renders correctly 2`] = `null`;
|
||||
exports[`<LoginPage /> renders correctly on load 2`] = `null`;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/soapbox/features/auth_login/components/otp_auth_form.js
Normal file
BIN
app/soapbox/features/auth_login/components/otp_auth_form.js
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/soapbox/features/security/mfa_form.js
Normal file
BIN
app/soapbox/features/security/mfa_form.js
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -34,6 +34,7 @@ $small-breakpoint: 960px;
|
|||
flex-wrap: nowrap;
|
||||
padding: 14px 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: 14px 20px;
|
||||
|
@ -1712,7 +1713,40 @@ $small-breakpoint: 960px;
|
|||
.header,
|
||||
.container {
|
||||
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;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
h1.otp-login {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 800;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
|
|
@ -72,3 +72,4 @@
|
|||
@import 'components/video-player';
|
||||
@import 'components/audio-player';
|
||||
@import 'components/profile_hover_card';
|
||||
@import 'components/mfa_form';
|
||||
|
|
|
@ -102,7 +102,7 @@ button {
|
|||
&:focus,
|
||||
&:hover {
|
||||
border-color: var(--brand-color);
|
||||
color: var(--primary-text-color);
|
||||
color: var(--background-color);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
|
|
81
app/styles/components/mfa_form.scss
Normal file
81
app/styles/components/mfa_form.scss
Normal 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;
|
||||
}
|
||||
}
|
|
@ -255,9 +255,9 @@
|
|||
display: block;
|
||||
margin-right: 30px;
|
||||
border: 0;
|
||||
height: 50px;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
padding: 13px 0 0;
|
||||
box-sizing: border-box;
|
||||
filter: brightness(0%) grayscale(100%) invert(100%);
|
||||
& span {display: none !important;}
|
||||
|
|
|
@ -30,12 +30,14 @@ body {
|
|||
--accent-color: hsl(var(--accent-color_hsl));
|
||||
--primary-text-color: hsl(var(--primary-text-color_hsl));
|
||||
--background-color: hsl(var(--background-color_hsl));
|
||||
--warning-color: hsla(var(--warning-color_hsl));
|
||||
|
||||
// Meta-variables
|
||||
--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);
|
||||
--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);
|
||||
--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_s: 86%;
|
||||
--accent-color_l: 44%;
|
||||
|
@ -51,6 +53,7 @@ body {
|
|||
calc(var(--accent-color_l) + 3%)
|
||||
);
|
||||
--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 {
|
||||
|
@ -69,6 +72,9 @@ body.theme-mode-light {
|
|||
--background-color_h: 0;
|
||||
--background-color_s: 0%;
|
||||
--background-color_l: 94.9%;
|
||||
--warning-color_h: 0;
|
||||
--warning-color_s: 100%;
|
||||
--warning-color_l: 66%;
|
||||
|
||||
// Modifiers
|
||||
--brand-color--hicontrast: hsl(
|
||||
|
@ -94,6 +100,9 @@ body.theme-mode-dark {
|
|||
--background-color_h: 0;
|
||||
--background-color_s: 0%;
|
||||
--background-color_l: 20%;
|
||||
--warning-color_h: 0;
|
||||
--warning-color_s: 100%;
|
||||
--warning-color_l: 66%;
|
||||
|
||||
// Modifiers
|
||||
--brand-color--hicontrast: hsl(
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"postcss-object-fit-images": "^1.1.2",
|
||||
"prop-types": "^15.5.10",
|
||||
"punycode": "^2.1.0",
|
||||
"qrcode.react": "^1.0.0",
|
||||
"rails-ujs": "^5.2.3",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -9320,6 +9320,20 @@ q@^1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
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:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
|
|
Loading…
Reference in a new issue