From 113b040f25a5eda7814f539d10b2ec078d9725d5 Mon Sep 17 00:00:00 2001 From: Avris Date: Sat, 18 Dec 2021 18:54:36 +0000 Subject: [PATCH] #291 [auth][mfa] MFA --- components/Account.vue | 3 + components/Login.vue | 2 +- components/MfaConnection.vue | 104 ++++++++++++++++++++++++++ components/MfaValidation.vue | 106 +++++++++++++++++++++++++++ locale/_base/translations.suml | 17 +++++ locale/de/translations.suml | 18 +++++ locale/en/translations.suml | 17 +++++ locale/es/translations.suml | 18 +++++ locale/fr/translations.suml | 18 +++++ locale/gl/translations.suml | 18 +++++ locale/ja/translations.suml | 18 +++++ locale/nl/translations.suml | 18 +++++ locale/no/translations.suml | 18 +++++ locale/pl/translations.suml | 17 +++++ locale/pt/translations.suml | 18 +++++ locale/ru/translations.suml | 18 +++++ locale/yi/translations.suml | 18 +++++ locale/zh/translations.suml | 18 +++++ package.json | 2 + routes/user.vue | 7 ++ server/index.js | 2 + server/routes/mfa.js | 129 +++++++++++++++++++++++++++++++++ server/routes/user.js | 80 +++++++++++++------- store/index.js | 9 +++ yarn.lock | 85 +++++++++++++++++++++- 25 files changed, 750 insertions(+), 28 deletions(-) create mode 100644 components/MfaConnection.vue create mode 100644 components/MfaValidation.vue create mode 100644 server/routes/mfa.js diff --git a/components/Account.vue b/components/Account.vue index cb41d1f1..ed69bfad 100644 --- a/components/Account.vue +++ b/components/Account.vue @@ -139,6 +139,9 @@ +
  • + +
  • diff --git a/components/Login.vue b/components/Login.vue index 992ba3b7..c09f2f08 100644 --- a/components/Login.vue +++ b/components/Login.vue @@ -2,7 +2,7 @@
    -
    +

    diff --git a/components/MfaConnection.vue b/components/MfaConnection.vue new file mode 100644 index 00000000..c53c1965 --- /dev/null +++ b/components/MfaConnection.vue @@ -0,0 +1,104 @@ + + + diff --git a/components/MfaValidation.vue b/components/MfaValidation.vue new file mode 100644 index 00000000..a36619d1 --- /dev/null +++ b/components/MfaValidation.vue @@ -0,0 +1,106 @@ + + + diff --git a/locale/_base/translations.suml b/locale/_base/translations.suml index 7a6e4587..c9a8a276 100644 --- a/locale/_base/translations.suml +++ b/locale/_base/translations.suml @@ -514,6 +514,23 @@ user: refresh: 'Refresh' disconnect: 'Disconnect' disconnectConfirm: 'Are you sure you want to remove this connection? (You can always log in using email %email%)' + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Description' diff --git a/locale/de/translations.suml b/locale/de/translations.suml index 1e0e2728..c3573cd6 100644 --- a/locale/de/translations.suml +++ b/locale/de/translations.suml @@ -412,6 +412,24 @@ user: refresh: 'Aktualisieren' disconnect: 'Verbindung trennen' disconnectConfirm: 'Bist du sicher, dass du die Verbindung trennen möchtest? (Du kannst dich jederzeit mit der E-Mail %email% anmelden)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Beschreibung' diff --git a/locale/en/translations.suml b/locale/en/translations.suml index ede1fcf4..2f2c9c35 100644 --- a/locale/en/translations.suml +++ b/locale/en/translations.suml @@ -515,6 +515,23 @@ user: refresh: 'Refresh' disconnect: 'Disconnect' disconnectConfirm: 'Are you sure you want to remove this connection? (You can always log in using email %email%)' + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Description' diff --git a/locale/es/translations.suml b/locale/es/translations.suml index 532558d7..d73ad26f 100644 --- a/locale/es/translations.suml +++ b/locale/es/translations.suml @@ -425,6 +425,24 @@ user: refresh: 'Actualizar' disconnect: 'Desconectar' disconnectConfirm: '¿Confirmas que quieres eliminar esta conexión? (Siempre puedes iniciar sesión usando el correo electrónico %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Descripción' diff --git a/locale/fr/translations.suml b/locale/fr/translations.suml index b47bc63b..798ec5bc 100644 --- a/locale/fr/translations.suml +++ b/locale/fr/translations.suml @@ -418,6 +418,24 @@ user: refresh: 'Rafraîchir' disconnect: 'Déconnecter' disconnectConfirm: 'Êtes-vous sûr·e de vouloir retirer cette connexion ? (Vous pouvez toujours vous connecter en utilisant l’adresse mail %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Description' diff --git a/locale/gl/translations.suml b/locale/gl/translations.suml index be79e8d9..e4c53774 100644 --- a/locale/gl/translations.suml +++ b/locale/gl/translations.suml @@ -424,6 +424,24 @@ user: refresh: 'Atualizar' disconnect: 'Desconectar' disconnectConfirm: 'Confirma que quer excluir esta conexão? (Sempre pode iniciar sessão usando seu endereço %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Descrição' diff --git a/locale/ja/translations.suml b/locale/ja/translations.suml index 8a453426..c0f3cb45 100644 --- a/locale/ja/translations.suml +++ b/locale/ja/translations.suml @@ -428,6 +428,24 @@ user: refresh: '更新' disconnect: '切断' disconnectConfirm: 'この接続を削除してもよろしいですか?まだメールアドレスでログインできます。(%email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: '記述' diff --git a/locale/nl/translations.suml b/locale/nl/translations.suml index 88d31a9a..e3bb072d 100644 --- a/locale/nl/translations.suml +++ b/locale/nl/translations.suml @@ -417,6 +417,24 @@ user: refresh: 'Vernieuw' disconnect: 'Ontkoppel' disconnectConfirm: 'Weet je zeker dat je deze koppeling wil verwijderen? (Je kunt altijd inloggen met de email %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Omschrijving' diff --git a/locale/no/translations.suml b/locale/no/translations.suml index a51eaa19..85a495a6 100644 --- a/locale/no/translations.suml +++ b/locale/no/translations.suml @@ -420,6 +420,24 @@ user: refresh: 'Last inn på nytt' disconnect: 'Koble fra' disconnectConfirm: 'Er du sikker på at du vil kobla fra? (Du kan alltid logge inn via email %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Beskrivelse' diff --git a/locale/pl/translations.suml b/locale/pl/translations.suml index 1b3a7654..d2eec7bf 100644 --- a/locale/pl/translations.suml +++ b/locale/pl/translations.suml @@ -1212,6 +1212,23 @@ user: refresh: 'Odśwież' disconnect: 'Rozłącz' disconnectConfirm: 'Czy na pewno chcesz usunąć to połączenie? (Zawsze możesz logować się przez maila %email%)' + mfa: + header: 'Uwierzytelnianie wieloskładnikowe (MFA)' + init: > + Zeskanuj poniższy kod QR (lub wklej kod tekstowy pod spodem) do swojej apki TOTP (np. {https://authy.com/=Authy}), + a następnie wpisz wstępny token, jaki zostanie wygenerowany. + recovery: + header: 'Kod odzyskiwania' + save: > + Zapisz poniższe kody odzyskiwania w bezpiecznym miejscu. + Będziesz mogłx ich użyć, aby obejść MFA na wypadek utraty urządzenia uwierzytelniającego. + saved: 'OK, zapisane!' + enter: 'Wpisz kod odzyskiwania' + cancel: 'Anuluj logowanie' + enabled: 'Włączone' + enable: 'Włącz MFA' + disable: 'Wyłącz MFA' + disableConfirm: 'Czy na pewno chcesz wyłączyć MFA?' profile: description: 'Opis' diff --git a/locale/pt/translations.suml b/locale/pt/translations.suml index fd842797..554b5ec3 100644 --- a/locale/pt/translations.suml +++ b/locale/pt/translations.suml @@ -420,6 +420,24 @@ user: refresh: 'Atualizar' disconnect: 'Desconectar' disconnectConfirm: 'Confirma que quer excluir esta conexão? (Sempre pode iniciar sessão usando seu endereço %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Descrição' diff --git a/locale/ru/translations.suml b/locale/ru/translations.suml index 5b6fa2f8..c7b1edbc 100644 --- a/locale/ru/translations.suml +++ b/locale/ru/translations.suml @@ -453,6 +453,24 @@ user: refresh: 'Обновить' disconnect: 'Отсоединить' disconnectConfirm: 'Вы уверены, что хотите отсоединить привязанную социальную сеть? (Вы всегда можете войти в аккаунт, используя почту %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'Описание' diff --git a/locale/yi/translations.suml b/locale/yi/translations.suml index 4b1c681a..93758ff7 100644 --- a/locale/yi/translations.suml +++ b/locale/yi/translations.suml @@ -420,6 +420,24 @@ user: refresh: 'Refresh' disconnect: 'Disconnect' disconnectConfirm: 'Are you sure you want to remove this connection? (You can always log in using email %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: 'באַשרײַבונג' diff --git a/locale/zh/translations.suml b/locale/zh/translations.suml index f77e24cf..41413d31 100644 --- a/locale/zh/translations.suml +++ b/locale/zh/translations.suml @@ -405,6 +405,24 @@ user: refresh: '祓飾' disconnect: '掉線' disconnectConfirm: '確定要刪除此連接嗎? (您始終可以使用電子郵件登錄 %email%)' + # TODO + mfa: + header: 'Multi-factor authentication' + init: > + Scan this QR code (or enter the text code below) in your TOTP authenticator app (eg. {https://authy.com/=Authy}) + and then enter the initial token that gets generated. + recovery: + header: 'Recovery code' + save: > + Save the following recovery codes in a safe place. + You'll be able to use them to bypass MFA in case you ever lose your authentication device. + saved: 'OK, I''ve saved them!' + enter: 'Enter recovery code' + cancel: 'Cancel login' + enabled: 'Enabled' + enable: 'Enable MFA' + disable: 'Disable MFA' + disableConfirm: 'Are you sure you want to disable MFA?' profile: description: '傳記' diff --git a/package.json b/package.json index 0afb9c74..803997ba 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,10 @@ "node-fetch": "^2.6.1", "nuxt": "^2.15.2", "pageres": "^6.2.3", + "qrcode": "^1.5.0", "rtlcss": "^3.1.2", "sha1": "^1.1.1", + "speakeasy": "^2.0.0", "sql-template-strings": "^2.2.2", "sqlite": "^4.0.12", "sqlite3": "^5.0.0", diff --git a/routes/user.vue b/routes/user.vue index ff978a20..deecfe97 100644 --- a/routes/user.vue +++ b/routes/user.vue @@ -6,14 +6,21 @@ +