From 4ce5dfc92a6410b7225cff51e550515233e4bda2 Mon Sep 17 00:00:00 2001 From: Dominik Kwiatek Date: Sun, 18 Oct 2020 19:48:12 +0200 Subject: [PATCH] Fix detaching, improve UI for attaching 2FA --- app/assets/stylesheets/application.scss | 1 + .../stylesheets/components/_totp-setup.scss | 35 +++++++++++++++++++ app/controllers/user_controller.rb | 11 ++++-- app/views/settings/_security.haml | 35 ++++++++++++++----- ...01001172537_add_otp_secret_key_to_users.rb | 2 +- 5 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 app/assets/stylesheets/components/_totp-setup.scss diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 768706ef..5b033152 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -91,6 +91,7 @@ "components/profile", "components/question", "components/smiles", +"components/totp-setup", "components/userbox"; /** diff --git a/app/assets/stylesheets/components/_totp-setup.scss b/app/assets/stylesheets/components/_totp-setup.scss new file mode 100644 index 00000000..633c91ec --- /dev/null +++ b/app/assets/stylesheets/components/_totp-setup.scss @@ -0,0 +1,35 @@ +.totp-setup { + display: flex; + + &__card { + background: var(--primary); + padding: 10px; + border-radius: 5px; + width: 256px; + } + + &__qr { + background: white; + border-radius: 5px; + } + + &__text { + background: #000; + color: #fff; + margin: 10px 0 0 0; + padding: 5px; + border-radius: 5px; + + code { + color: var(--warning); + } + } + + &__right { + margin-left: 20px; + } + + &__code-field { + font-family: "Monaco", "Inconsolata", "Cascadia Code", "Consolas", monospace; + } +} \ No newline at end of file diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 7f9ce77a..8f513995 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -185,18 +185,23 @@ class UserController < ApplicationController def update_2fa req_params = params.require(:user).permit(:otp_secret_key, :otp_validation) + current_user.otp_secret_key = req_params[:otp_secret_key] + current_user.otp_module = :enabled if current_user.authenticate_otp(req_params[:otp_validation]) - flash[:success] = 'yay' + flash[:success] = 'Two factor authentication has been enabled for your account.' current_user.save! else - flash[:error] = current_user.otp_code + flash[:error] = 'The code you entered was invalid.' end redirect_to edit_user_security_path end def destroy_2fa - + current_user.otp_module = :disabled + current_user.save! + flash[:success] = 'Two factor authentication has been disabled for your account.' + redirect_to edit_user_security_path end end diff --git a/app/views/settings/_security.haml b/app/views/settings/_security.haml index e2d7046b..764d4a82 100644 --- a/app/views/settings/_security.haml +++ b/app/views/settings/_security.haml @@ -1,15 +1,32 @@ .card .card-body %h2= t('views.settings.security.2fa.title') - - if current_user.otp_secret_key.nil? - = bootstrap_form_for(current_user, url: { action: :update_2fa, method: :post }) do |f| - %a{:href => "https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis"} Aegis Authenticator for Android - %a{:href => "https://apps.apple.com/gb/app/strongbox-authenticator/id1023839880"} Strongbox Authenticator for iOS - = RQRCode::QRCode.new(current_user.provisioning_uri("Retrospring:#{current_user.screen_name}", issuer: "Retrospring")).as_svg.html_safe - %pre= current_user.otp_secret_key - = f.text_field :otp_validation - = f.hidden_field :otp_secret_key, value: current_user.otp_secret_key - = f.submit t('views.actions.save'), class: 'btn btn-primary' + - if current_user.otp_module_disabled? + .totp-setup + .totp-setup__left + .totp-setup__card + .totp-setup__qr + = RQRCode::QRCode.new(current_user.provisioning_uri("Retrospring:#{current_user.screen_name}", issuer: "Retrospring")).as_svg({:offset => 4, :module_size => 4, :color => '000;fill:var(--primary)'}).html_safe + %p.totp-setup__text + If you cannot scan the QR code, use the following key instead: + %code= current_user.otp_secret_key.scan(/.{4}/).flatten.join(' ') + .totp-setup__right + = bootstrap_form_for(current_user, url: { action: :update_2fa, method: :post }) do |f| + %p + If you do not have an authenticator app already installed on your device, we suggest one of the following: + %ul.list-unstyled.pl-3 + %li + %a{:href => "https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis"} + %i.fa.fa-android + Aegis Authenticator for Android + %li + %a{:href => "https://apps.apple.com/gb/app/strongbox-authenticator/id1023839880"} + %i.fa.fa-apple + Strongbox Authenticator for iOS + %p Once you have downloaded an authenticator app, add your Retrospring account by scanning the QR code displayed on the left. + = f.text_field :otp_validation, class: 'totp-setup__code-field', label: 'Enter the code displayed in the app here:' + = f.hidden_field :otp_secret_key, value: current_user.otp_secret_key + = f.submit t('views.actions.save'), class: 'btn btn-primary' - else %p= t('views.settings.security.2fa.enabled_hint') = link_to t('views.actions.remove'), destroy_user_2fa_path, :class => 'btn btn-primary', :method => 'delete' \ No newline at end of file diff --git a/db/migrate/20201001172537_add_otp_secret_key_to_users.rb b/db/migrate/20201001172537_add_otp_secret_key_to_users.rb index 5b7ea48d..4e736ab8 100644 --- a/db/migrate/20201001172537_add_otp_secret_key_to_users.rb +++ b/db/migrate/20201001172537_add_otp_secret_key_to_users.rb @@ -1,7 +1,7 @@ class AddOtpSecretKeyToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :otp_secret_key, :string - add_column :users, :otp_module, :integer + add_column :users, :otp_module, :integer, default: 0, null: false User.find_each do |user| user.update_attribute(:otp_secret_key, User.otp_random_secret)