Merge branch 'master' into skylight

This commit is contained in:
Eugen Rochko 2017-04-08 22:27:03 +02:00
commit 2a4499bb23
10 changed files with 116 additions and 32 deletions

View file

@ -114,10 +114,6 @@
padding: 20px; padding: 20px;
} }
.screenshot-with-signup .mascot {
display: none;
}
.features-list { .features-list {
display: block; display: block;
} }
@ -158,6 +154,14 @@
color: $color5; color: $color5;
} }
} }
@media screen and (max-width: 500px) {
flex-direction: column;
.section {
text-align: left;
}
}
} }
.owner { .owner {
@ -281,6 +285,15 @@
} }
} }
} }
@media screen and (max-width: 625px) {
flex-direction: column;
.sidebar {
border: 1px solid lighten($color1, 10%);
width: auto;
}
}
} }
.features-list { .features-list {
@ -339,6 +352,16 @@
} }
} }
} }
@media screen and (max-width: 625px) {
.mascot {
display: none;
}
.simple_form, .closed-registrations-message {
flex: auto;
}
}
} }
.closed-registrations-message { .closed-registrations-message {

View file

@ -25,6 +25,10 @@ code {
margin-bottom: 15px; margin-bottom: 15px;
} }
strong {
font-weight: 500;
}
.label_input { .label_input {
display: flex; display: flex;
@ -224,7 +228,12 @@ code {
} }
} }
.qr-wrapper {
display: flex;
}
.qr-code { .qr-code {
flex: 0 0 auto;
background: #fff; background: #fff;
padding: 4px; padding: 4px;
margin-bottom: 20px; margin-bottom: 20px;
@ -236,3 +245,13 @@ code {
margin: 0; margin: 0;
} }
} }
.qr-alternative {
margin-left: 10px;
color: $color3;
samp {
display: block;
font-size: 14px;
}
}

View file

@ -5,19 +5,29 @@ class Settings::TwoFactorAuthsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
def show def show; end
return unless current_user.otp_required_for_login
@provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Rails.configuration.x.local_domain) def new
@qrcode = RQRCode::QRCode.new(@provision_url) redirect_to settings_two_factor_auth_path if current_user.otp_required_for_login
@confirmation = Form::TwoFactorConfirmation.new
current_user.otp_secret = User.generate_otp_secret(32)
current_user.save!
set_qr_code
end end
def enable def create
current_user.otp_required_for_login = true if current_user.validate_and_consume_otp!(confirmation_params[:code])
current_user.otp_secret = User.generate_otp_secret current_user.otp_required_for_login = true
current_user.save! current_user.save!
redirect_to settings_two_factor_auth_path redirect_to settings_two_factor_auth_path, notice: I18n.t('two_factor_auth.enabled_success')
else
@confirmation = Form::TwoFactorConfirmation.new
set_qr_code
flash.now[:alert] = I18n.t('two_factor_auth.wrong_code')
render action: :new
end
end end
def disable def disable
@ -26,4 +36,15 @@ class Settings::TwoFactorAuthsController < ApplicationController
redirect_to settings_two_factor_auth_path redirect_to settings_two_factor_auth_path
end end
private
def set_qr_code
@provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Rails.configuration.x.local_domain)
@qrcode = RQRCode::QRCode.new(@provision_url)
end
def confirmation_params
params.require(:form_two_factor_confirmation).permit(:code)
end
end end

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class Form::TwoFactorConfirmation
include ActiveModel::Model
attr_accessor :code
end

View file

@ -0,0 +1,17 @@
- content_for :page_title do
= t('settings.two_factor_auth')
= simple_form_for @confirmation, url: settings_two_factor_auth_path, method: :post do |f|
%p.hint= t('two_factor_auth.instructions_html')
.qr-wrapper
.qr-code= raw @qrcode.as_svg(padding: 0, module_size: 4)
.qr-alternative
%p.hint= t('two_factor_auth.manual_instructions')
%samp.qr-alternative__code= current_user.otp_secret.scan(/.{4}/).join(' ')
= f.input :code, hint: t('two_factor_auth.code_hint'), placeholder: t('simple_form.labels.defaults.otp_attempt')
.actions
= f.button :button, t('two_factor_auth.enable'), type: :submit

View file

@ -2,16 +2,9 @@
= t('settings.two_factor_auth') = t('settings.two_factor_auth')
.simple_form .simple_form
%p.hint= t('two_factor_auth.description_html')
- if current_user.otp_required_for_login - if current_user.otp_required_for_login
%p.hint= t('two_factor_auth.instructions_html')
.qr-code= raw @qrcode.as_svg(padding: 0, module_size: 5)
%p.hint= t('two_factor_auth.plaintext_secret_html', secret: current_user.otp_secret)
%p.hint= t('two_factor_auth.warning')
= link_to t('two_factor_auth.disable'), disable_settings_two_factor_auth_path, data: { method: 'POST' }, class: 'block-button' = link_to t('two_factor_auth.disable'), disable_settings_two_factor_auth_path, data: { method: 'POST' }, class: 'block-button'
- else - else
%p.hint= t('two_factor_auth.description_html') = link_to t('two_factor_auth.setup'), new_settings_two_factor_auth_path, class: 'block-button'
= link_to t('two_factor_auth.enable'), enable_settings_two_factor_auth_path, data: { method: 'POST' }, class: 'block-button'

View file

@ -94,6 +94,10 @@ en:
following: Following list following: Following list
upload: Upload upload: Upload
landing_strip_html: <strong>%{name}</strong> is a user on <strong>%{domain}</strong>. You can follow them or interact with them if you have an account anywhere in the fediverse. If you don't, you can <a href="%{sign_up_path}">sign up here</a>. landing_strip_html: <strong>%{name}</strong> is a user on <strong>%{domain}</strong>. You can follow them or interact with them if you have an account anywhere in the fediverse. If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
media_attachments:
validations:
images_and_video: Cannot attach a video to a status that already contains images
too_many: Cannot attach more than 4 files
notification_mailer: notification_mailer:
digest: digest:
body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:' body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:'
@ -152,18 +156,18 @@ en:
formats: formats:
default: "%b %d, %Y, %H:%M" default: "%b %d, %Y, %H:%M"
two_factor_auth: two_factor_auth:
code_hint: Enter the code generated by your authenticator app to confirm
description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter. description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter.
disable: Disable disable: Disable
enable: Enable enable: Enable
instructions_html: "<strong>Scan this QR code into Google Authenticator or a similiar app on your phone</strong>. From now on, that app will generate tokens that you will have to enter when logging in." enabled_success: Two-factor authentication successfully enabled
plaintext_secret_html: 'Plain-text secret: <samp>%{secret}</samp>' instructions_html: "<strong>Scan this QR code into Google Authenticator or a similiar TOTP app on your phone</strong>. From now on, that app will generate tokens that you will have to enter when logging in."
manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:'
setup: Set up
warning: If you cannot configure an authenticator app right now, you should click "disable" or you won't be able to login. warning: If you cannot configure an authenticator app right now, you should click "disable" or you won't be able to login.
wrong_code: The entered code was invalid! Are server time and device time correct?
users: users:
invalid_email: The e-mail address is invalid invalid_email: The e-mail address is invalid
invalid_otp_token: Invalid two-factor code invalid_otp_token: Invalid two-factor code
will_paginate: will_paginate:
page_gap: "&hellip;" page_gap: "&hellip;"
media_attachments:
validations:
too_many: Cannot attach more than 4 files
images_and_video: Cannot attach a video to a status that already contains images

View file

@ -8,7 +8,7 @@ SimpleNavigation::Configuration.run do |navigation|
settings.item :profile, safe_join([fa_icon('user fw'), t('settings.edit_profile')]), settings_profile_url settings.item :profile, safe_join([fa_icon('user fw'), t('settings.edit_profile')]), settings_profile_url
settings.item :preferences, safe_join([fa_icon('sliders fw'), t('settings.preferences')]), settings_preferences_url settings.item :preferences, safe_join([fa_icon('sliders fw'), t('settings.preferences')]), settings_preferences_url
settings.item :password, safe_join([fa_icon('cog fw'), t('auth.change_password')]), edit_user_registration_url settings.item :password, safe_join([fa_icon('cog fw'), t('auth.change_password')]), edit_user_registration_url
settings.item :two_factor_auth, safe_join([fa_icon('mobile fw'), t('settings.two_factor_auth')]), settings_two_factor_auth_url settings.item :two_factor_auth, safe_join([fa_icon('mobile fw'), t('settings.two_factor_auth')]), settings_two_factor_auth_url, highlights_on: %r{/settings/two_factor_auth}
settings.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_url settings.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_url
settings.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url settings.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url
settings.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_url settings.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_url

View file

@ -60,9 +60,8 @@ Rails.application.routes.draw do
end end
end end
resource :two_factor_auth, only: [:show] do resource :two_factor_auth, only: [:show, :new, :create] do
member do member do
post :enable
post :disable post :disable
end end
end end

View file

@ -76,6 +76,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz)
| [mastodon.fun](https://mastodon.fun/)|Mastodon for everyone ! |Yes|Yes| | [mastodon.fun](https://mastodon.fun/)|Mastodon for everyone ! |Yes|Yes|
| [oulipo.social](https://oulipo.social/)|An Oulipo Mastodon in which that fifth symbol in Latin script is taboo|Yes|No| | [oulipo.social](https://oulipo.social/)|An Oulipo Mastodon in which that fifth symbol in Latin script is taboo|Yes|No|
| [indigo.zone](https://indigo.zone)|Open Registrations, General Purpose|Yes|No| | [indigo.zone](https://indigo.zone)|Open Registrations, General Purpose|Yes|No|
| [mst3k.interlinked.me](https://mst3k.interlinked.me)|Open registrations, general purpose|Yes|Yes|
We are no longer maintaining this list as instances are popping up too quickly for using GitHub to be a tenable system for tracking them. Please standby while we work on another solution We are no longer maintaining this list as instances are popping up too quickly for using GitHub to be a tenable system for tracking them. Please standby while we work on another solution