diff options
Diffstat (limited to 'app/controllers')
31 files changed, 331 insertions, 71 deletions
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index 7b0438127..5d5db937c 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -4,9 +4,7 @@ class AboutController < ApplicationController before_action :set_pack layout 'public' - before_action :require_open_federation!, only: [:show, :more, :blocks] - before_action :check_blocklist_enabled, only: [:blocks] - before_action :authenticate_user!, only: [:blocks], if: :blocklist_account_required? + before_action :require_open_federation!, only: [:show, :more] before_action :set_body_classes, only: :show before_action :set_instance_presenter before_action :set_expires_in, only: [:show, :more, :terms] @@ -17,15 +15,20 @@ class AboutController < ApplicationController def more flash.now[:notice] = I18n.t('about.instance_actor_flash') if params[:instance_actor] + + toc_generator = TOCGenerator.new(@instance_presenter.site_extended_description) + + @contents = toc_generator.html + @table_of_contents = toc_generator.toc + @blocks = DomainBlock.with_user_facing_limitations.by_severity if display_blocks? end def terms; end - def blocks - @show_rationale = Setting.show_domain_blocks_rationale == 'all' - @show_rationale |= Setting.show_domain_blocks_rationale == 'users' && !current_user.nil? && current_user.functional? - @blocks = DomainBlock.with_user_facing_limitations.order('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), reject_media, domain').to_a - end + helper_method :display_blocks? + helper_method :display_blocks_rationale? + helper_method :public_fetch_mode? + helper_method :new_user private @@ -33,28 +36,14 @@ class AboutController < ApplicationController not_found if whitelist_mode? end - def check_blocklist_enabled - not_found if Setting.show_domain_blocks == 'disabled' - end - - def blocklist_account_required? - Setting.show_domain_blocks == 'users' + def display_blocks? + Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?) end - def block_severity_text(block) - if block.severity == 'suspend' - I18n.t('domain_blocks.suspension') - else - limitations = [] - limitations << I18n.t('domain_blocks.media_block') if block.reject_media? - limitations << I18n.t('domain_blocks.silence') if block.severity == 'silence' - limitations.join(', ') - end + def display_blocks_rationale? + Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?) end - helper_method :block_severity_text - helper_method :public_fetch_mode? - def new_user User.new.tap do |user| user.build_account @@ -62,8 +51,6 @@ class AboutController < ApplicationController end end - helper_method :new_user - def set_pack use_pack 'public' end diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 817e5e832..1c36813d0 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -10,6 +10,7 @@ class AccountsController < ApplicationController before_action :set_body_classes skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def show respond_to do |format| diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb index 989fee385..910fefb1c 100644 --- a/app/controllers/activitypub/collections_controller.rb +++ b/app/controllers/activitypub/collections_controller.rb @@ -33,9 +33,9 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController def scope_for_collection case params[:id] when 'featured' - @account.statuses.permitted_for(@account, signed_request_account).tap do |scope| - scope.merge!(@account.pinned_statuses) - end + return Status.none if @account.blocking?(signed_request_account) + + @account.pinned_statuses else raise ActiveRecord::RecordNotFound end diff --git a/app/controllers/admin/relays_controller.rb b/app/controllers/admin/relays_controller.rb index 1b02d3c36..6fbb6e063 100644 --- a/app/controllers/admin/relays_controller.rb +++ b/app/controllers/admin/relays_controller.rb @@ -3,6 +3,7 @@ module Admin class RelaysController < BaseController before_action :set_relay, except: [:index, :new, :create] + before_action :require_signatures_enabled!, only: [:new, :create, :enable] def index authorize :relay, :update? @@ -11,7 +12,7 @@ module Admin def new authorize :relay, :update? - @relay = Relay.new(inbox_url: Relay::PRESET_RELAY) + @relay = Relay.new end def create @@ -54,5 +55,9 @@ module Admin def resource_params params.require(:relay).permit(:inbox_url) end + + def require_signatures_enabled! + redirect_to admin_relays_path, alert: I18n.t('admin.relays.signatures_not_enabled') if authorized_fetch_mode? + end end end diff --git a/app/controllers/admin/two_factor_authentications_controller.rb b/app/controllers/admin/two_factor_authentications_controller.rb index 2577a4b17..0652c3a7a 100644 --- a/app/controllers/admin/two_factor_authentications_controller.rb +++ b/app/controllers/admin/two_factor_authentications_controller.rb @@ -8,6 +8,7 @@ module Admin authorize @user, :disable_2fa? @user.disable_two_factor! log_action :disable_2fa, @user + UserMailer.two_factor_disabled(@user).deliver_later! redirect_to admin_accounts_path end diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb index 0787cd636..333db9618 100644 --- a/app/controllers/api/v1/accounts/statuses_controller.rb +++ b/app/controllers/api/v1/accounts/statuses_controller.rb @@ -57,6 +57,8 @@ class Api::V1::Accounts::StatusesController < Api::BaseController end def pinned_scope + return Status.none if @account.blocking?(current_account) + @account.pinned_statuses end diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index b306e8e8c..c12e1c12e 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -33,7 +33,7 @@ class Api::V1::AccountsController < Api::BaseController def follow FollowService.new.call(current_user.account, @account, reblogs: truthy_param?(:reblogs)) - options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } } + options = @account.locked? || current_user.account.silenced? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } } render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options) end diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb index 7fdc030e5..76decdb25 100644 --- a/app/controllers/api/v2/search_controller.rb +++ b/app/controllers/api/v2/search_controller.rb @@ -22,7 +22,7 @@ class Api::V2::SearchController < Api::BaseController params[:q], current_account, limit_param(RESULTS_LIMIT), - search_params.merge(resolve: truthy_param?(:resolve)) + search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed)) ) end diff --git a/app/controllers/auth/challenges_controller.rb b/app/controllers/auth/challenges_controller.rb new file mode 100644 index 000000000..060944240 --- /dev/null +++ b/app/controllers/auth/challenges_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Auth::ChallengesController < ApplicationController + include ChallengableConcern + + layout 'auth' + + before_action :authenticate_user! + + skip_before_action :require_functional! + + def create + if challenge_passed? + session[:challenge_passed_at] = Time.now.utc + redirect_to challenge_params[:return_to] + else + @challenge = Form::Challenge.new(return_to: challenge_params[:return_to]) + flash.now[:alert] = I18n.t('challenge.invalid_password') + render_challenge + end + end +end diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index c2b38883b..efde02ac2 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -9,6 +9,7 @@ class Auth::SessionsController < Devise::SessionsController skip_before_action :require_functional! prepend_before_action :set_pack + prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] before_action :set_instance_presenter, only: [:new] before_action :set_body_classes @@ -22,34 +23,32 @@ class Auth::SessionsController < Devise::SessionsController end def create - self.resource = begin - if user_params[:email].blank? && session[:otp_user_id].present? - User.find(session[:otp_user_id]) - else - warden.authenticate!(auth_options) - end - end - - if resource.otp_required_for_login? - if user_params[:otp_attempt].present? && session[:otp_user_id].present? - authenticate_with_two_factor_via_otp(resource) - else - prompt_for_two_factor(resource) - end - else - authenticate_and_respond(resource) + super do |resource| + remember_me(resource) + flash.delete(:notice) end end def destroy tmp_stored_location = stored_location_for(:user) super + session.delete(:challenge_passed_at) flash.delete(:notice) store_location_for(:user, tmp_stored_location) if continue_after? end protected + def find_user + if session[:otp_user_id] + User.find(session[:otp_user_id]) + else + user = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication + user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication + user ||= User.find_for_authentication(email: user_params[:email]) + end + end + def user_params params.require(:user).permit(:email, :password, :otp_attempt) end @@ -72,6 +71,10 @@ class Auth::SessionsController < Devise::SessionsController super end + def two_factor_enabled? + find_user&.otp_required_for_login? + end + def valid_otp_attempt?(user) user.validate_and_consume_otp!(user_params[:otp_attempt]) || user.invalidate_otp_backup_code!(user_params[:otp_attempt]) @@ -79,10 +82,24 @@ class Auth::SessionsController < Devise::SessionsController false end + def authenticate_with_two_factor + user = self.resource = find_user + + if user_params[:otp_attempt].present? && session[:otp_user_id] + authenticate_with_two_factor_via_otp(user) + elsif user.present? && (user.encrypted_password.blank? || user.valid_password?(user_params[:password])) + # If encrypted_password is blank, we got the user from LDAP or PAM, + # so credentials are already valid + + prompt_for_two_factor(user) + end + end + def authenticate_with_two_factor_via_otp(user) if valid_otp_attempt?(user) session.delete(:otp_user_id) - authenticate_and_respond(user) + remember_me(user) + sign_in(user) else flash.now[:alert] = I18n.t('users.invalid_otp_token') prompt_for_two_factor(user) @@ -91,16 +108,10 @@ class Auth::SessionsController < Devise::SessionsController def prompt_for_two_factor(user) session[:otp_user_id] = user.id + @body_classes = 'lighter' render :two_factor end - def authenticate_and_respond(user) - sign_in(user) - remember_me(user) - - respond_with user, location: after_sign_in_path_for(user) - end - private def set_pack @@ -117,11 +128,9 @@ class Auth::SessionsController < Devise::SessionsController def home_paths(resource) paths = [about_path] - if single_user_mode? && resource.is_a?(User) paths << short_account_path(username: resource.account) end - paths end diff --git a/app/controllers/concerns/challengable_concern.rb b/app/controllers/concerns/challengable_concern.rb new file mode 100644 index 000000000..b29d90b3c --- /dev/null +++ b/app/controllers/concerns/challengable_concern.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# This concern is inspired by "sudo mode" on GitHub. It +# is a way to re-authenticate a user before allowing them +# to see or perform an action. +# +# Add `before_action :require_challenge!` to actions you +# want to protect. +# +# The user will be shown a page to enter the challenge (which +# is either the password, or just the username when no +# password exists). Upon passing, there is a grace period +# during which no challenge will be asked from the user. +# +# Accessing challenge-protected resources during the grace +# period will refresh the grace period. +module ChallengableConcern + extend ActiveSupport::Concern + + CHALLENGE_TIMEOUT = 1.hour.freeze + + def require_challenge! + return if skip_challenge? + + if challenge_passed_recently? + session[:challenge_passed_at] = Time.now.utc + return + end + + @challenge = Form::Challenge.new(return_to: request.url) + + if params.key?(:form_challenge) + if challenge_passed? + session[:challenge_passed_at] = Time.now.utc + return + else + flash.now[:alert] = I18n.t('challenge.invalid_password') + render_challenge + end + else + render_challenge + end + end + + def render_challenge + @body_classes = 'lighter' + render template: 'auth/challenges/new', layout: 'auth' + end + + def challenge_passed? + current_user.valid_password?(challenge_params[:current_password]) + end + + def skip_challenge? + current_user.encrypted_password.blank? + end + + def challenge_passed_recently? + session[:challenge_passed_at].present? && session[:challenge_passed_at] >= CHALLENGE_TIMEOUT.ago + end + + def challenge_params + params.require(:form_challenge).permit(:current_password, :return_to) + end +end diff --git a/app/controllers/concerns/export_controller_concern.rb b/app/controllers/concerns/export_controller_concern.rb index e20b71a30..bfe990c82 100644 --- a/app/controllers/concerns/export_controller_concern.rb +++ b/app/controllers/concerns/export_controller_concern.rb @@ -5,7 +5,10 @@ module ExportControllerConcern included do before_action :authenticate_user! + before_action :require_not_suspended! before_action :load_export + + skip_before_action :require_functional! end private @@ -27,4 +30,8 @@ module ExportControllerConcern def export_filename "#{controller_name}.csv" end + + def require_not_suspended! + forbidden if current_account.suspended? + end end diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb index e3f67bd14..0a667a6a6 100644 --- a/app/controllers/custom_css_controller.rb +++ b/app/controllers/custom_css_controller.rb @@ -2,6 +2,7 @@ class CustomCssController < ApplicationController skip_before_action :store_current_location + skip_before_action :require_functional! before_action :set_cache_headers diff --git a/app/controllers/directories_controller.rb b/app/controllers/directories_controller.rb index bbfdde8af..adf2bd014 100644 --- a/app/controllers/directories_controller.rb +++ b/app/controllers/directories_controller.rb @@ -10,6 +10,8 @@ class DirectoriesController < ApplicationController before_action :set_accounts before_action :set_pack + skip_before_action :require_functional! + def index render :index end diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index 4641a8bb9..df46f5f72 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -8,6 +8,7 @@ class FollowerAccountsController < ApplicationController before_action :set_cache_headers skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def index respond_to do |format| diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 6e80554fb..8cab67ff5 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -8,6 +8,7 @@ class FollowingAccountsController < ApplicationController before_action :set_cache_headers skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def index respond_to do |format| diff --git a/app/controllers/manifests_controller.rb b/app/controllers/manifests_controller.rb index 491cde745..960510f60 100644 --- a/app/controllers/manifests_controller.rb +++ b/app/controllers/manifests_controller.rb @@ -2,6 +2,7 @@ class ManifestsController < ApplicationController skip_before_action :store_current_location + skip_before_action :require_functional! def show expires_in 3.minutes, public: true diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb index 1f693de32..05cf09c28 100644 --- a/app/controllers/media_controller.rb +++ b/app/controllers/media_controller.rb @@ -4,6 +4,7 @@ class MediaController < ApplicationController include Authorization skip_before_action :store_current_location + skip_before_action :require_functional! before_action :authenticate_user!, if: :whitelist_mode? before_action :set_media_attachment diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb index 47544f21c..014b89de1 100644 --- a/app/controllers/media_proxy_controller.rb +++ b/app/controllers/media_proxy_controller.rb @@ -4,6 +4,7 @@ class MediaProxyController < ApplicationController include RoutingHelper skip_before_action :store_current_location + skip_before_action :require_functional! before_action :authenticate_user!, if: :whitelist_mode? diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb index 65dfa35db..93a0a7476 100644 --- a/app/controllers/remote_follow_controller.rb +++ b/app/controllers/remote_follow_controller.rb @@ -8,6 +8,8 @@ class RemoteFollowController < ApplicationController before_action :set_pack before_action :set_body_classes + skip_before_action :require_functional! + def new @remote_follow = RemoteFollow.new(session_params) end diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index 6b797b10f..e058d0ed5 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -11,6 +11,8 @@ class RemoteInteractionController < ApplicationController before_action :set_body_classes before_action :set_pack + skip_before_action :require_functional! + def new @remote_follow = RemoteFollow.new(session_params) end diff --git a/app/controllers/settings/aliases_controller.rb b/app/controllers/settings/aliases_controller.rb new file mode 100644 index 000000000..b7c9a409d --- /dev/null +++ b/app/controllers/settings/aliases_controller.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +class Settings::AliasesController < Settings::BaseController + layout 'admin' + + before_action :authenticate_user! + before_action :set_aliases, except: :destroy + before_action :set_alias, only: :destroy + + def index + @alias = current_account.aliases.build + end + + def create + @alias = current_account.aliases.build(resource_params) + + if @alias.save + ActivityPub::UpdateDistributionWorker.perform_async(current_account.id) + redirect_to settings_aliases_path, notice: I18n.t('aliases.created_msg') + else + render :index + end + end + + def destroy + @alias.destroy! + redirect_to settings_aliases_path, notice: I18n.t('aliases.deleted_msg') + end + + private + + def resource_params + params.require(:account_alias).permit(:acct) + end + + def set_alias + @alias = current_account.aliases.find(params[:id]) + end + + def set_aliases + @aliases = current_account.aliases.order(id: :desc).reject(&:new_record?) + end +end diff --git a/app/controllers/settings/exports_controller.rb b/app/controllers/settings/exports_controller.rb index 3012fbf77..0e93d07a9 100644 --- a/app/controllers/settings/exports_controller.rb +++ b/app/controllers/settings/exports_controller.rb @@ -6,6 +6,9 @@ class Settings::ExportsController < Settings::BaseController layout 'admin' before_action :authenticate_user! + before_action :require_not_suspended! + + skip_before_action :require_functional! def show @export = Export.new(current_account) @@ -34,4 +37,8 @@ class Settings::ExportsController < Settings::BaseController def lock_options { redis: Redis.current, key: "backup:#{current_user.id}" } end + + def require_not_suspended! + forbidden if current_account.suspended? + end end diff --git a/app/controllers/settings/migration/redirects_controller.rb b/app/controllers/settings/migration/redirects_controller.rb new file mode 100644 index 000000000..6e5b72ffb --- /dev/null +++ b/app/controllers/settings/migration/redirects_controller.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class Settings::Migration::RedirectsController < Settings::BaseController + layout 'admin' + + before_action :authenticate_user! + before_action :require_not_suspended! + + skip_before_action :require_functional! + + def new + @redirect = Form::Redirect.new + end + + def create + @redirect = Form::Redirect.new(resource_params.merge(account: current_account)) + + if @redirect.valid_with_challenge?(current_user) + current_account.update!(moved_to_account: @redirect.target_account) + ActivityPub::UpdateDistributionWorker.perform_async(current_account.id) + redirect_to settings_migration_path, notice: I18n.t('migrations.moved_msg', acct: current_account.moved_to_account.acct) + else + render :new + end + end + + def destroy + if current_account.moved_to_account_id.present? + current_account.update!(moved_to_account: nil) + ActivityPub::UpdateDistributionWorker.perform_async(current_account.id) + end + + redirect_to settings_migration_path, notice: I18n.t('migrations.cancelled_msg') + end + + private + + def resource_params + params.require(:form_redirect).permit(:acct, :current_password, :current_username) + end + + def require_not_suspended! + forbidden if current_account.suspended? + end +end diff --git a/app/controllers/settings/migrations_controller.rb b/app/controllers/settings/migrations_controller.rb index 59eb48779..68304bb51 100644 --- a/app/controllers/settings/migrations_controller.rb +++ b/app/controllers/settings/migrations_controller.rb @@ -4,31 +4,48 @@ class Settings::MigrationsController < Settings::BaseController layout 'admin' before_action :authenticate_user! + before_action :require_not_suspended! + before_action :set_migrations + before_action :set_cooldown + + skip_before_action :require_functional! def show - @migration = Form::Migration.new(account: current_account.moved_to_account) + @migration = current_account.migrations.build end - def update - @migration = Form::Migration.new(resource_params) + def create + @migration = current_account.migrations.build(resource_params) - if @migration.valid? && migration_account_changed? - current_account.update!(moved_to_account: @migration.account) - ActivityPub::UpdateDistributionWorker.perform_async(current_account.id) - redirect_to settings_migration_path, notice: I18n.t('migrations.updated_msg') + if @migration.save_with_challenge(current_user) + MoveService.new.call(@migration) + redirect_to settings_migration_path, notice: I18n.t('migrations.moved_msg', acct: current_account.moved_to_account.acct) else render :show end end + helper_method :on_cooldown? + private def resource_params - params.require(:migration).permit(:acct) + params.require(:account_migration).permit(:acct, :current_password, :current_username) + end + + def set_migrations + @migrations = current_account.migrations.includes(:target_account).order(id: :desc).reject(&:new_record?) + end + + def set_cooldown + @cooldown = current_account.migrations.within_cooldown.first + end + + def on_cooldown? + @cooldown.present? end - def migration_account_changed? - current_account.moved_to_account_id != @migration.account&.id && - current_account.id != @migration.account&.id + def require_not_suspended! + forbidden if current_account.suspended? end end diff --git a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb index 46c90bf74..ef4df3339 100644 --- a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb +++ b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb @@ -3,9 +3,12 @@ module Settings module TwoFactorAuthentication class ConfirmationsController < BaseController + include ChallengableConcern + layout 'admin' before_action :authenticate_user! + before_action :require_challenge! before_action :ensure_otp_secret skip_before_action :require_functional! @@ -22,6 +25,8 @@ module Settings @recovery_codes = current_user.generate_otp_backup_codes! current_user.save! + UserMailer.two_factor_enabled(current_user).deliver_later! + render 'settings/two_factor_authentication/recovery_codes/index' else flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code') diff --git a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb index 09a759860..0c4f5bff7 100644 --- a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb +++ b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb @@ -3,16 +3,22 @@ module Settings module TwoFactorAuthentication class RecoveryCodesController < BaseController + include ChallengableConcern + layout 'admin' before_action :authenticate_user! + before_action :require_challenge!, on: :create skip_before_action :require_functional! def create @recovery_codes = current_user.generate_otp_backup_codes! current_user.save! + + UserMailer.two_factor_recovery_codes_changed(current_user).deliver_later! flash.now[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated') + render :index end end diff --git a/app/controllers/settings/two_factor_authentications_controller.rb b/app/controllers/settings/two_factor_authentications_controller.rb index c93b17577..9118a7933 100644 --- a/app/controllers/settings/two_factor_authentications_controller.rb +++ b/app/controllers/settings/two_factor_authentications_controller.rb @@ -2,10 +2,13 @@ module Settings class TwoFactorAuthenticationsController < BaseController + include ChallengableConcern + layout 'admin' before_action :authenticate_user! before_action :verify_otp_required, only: [:create] + before_action :require_challenge!, only: [:create] skip_before_action :require_functional! @@ -23,6 +26,7 @@ module Settings if acceptable_code? current_user.otp_required_for_login = false current_user.save! + UserMailer.two_factor_disabled(current_user).deliver_later! redirect_to settings_two_factor_authentication_path else flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code') diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 83c412d5c..1b00d38c9 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -19,6 +19,7 @@ class StatusesController < ApplicationController before_action :set_autoplay, only: :embed skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional!, only: [:show, :embed] content_security_policy only: :embed do |p| p.frame_ancestors(false) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index c447a3a2b..ef61c980f 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -13,6 +13,8 @@ class TagsController < ApplicationController before_action :set_body_classes before_action :set_instance_presenter + skip_before_action :require_functional! + def show respond_to do |format| format.html do diff --git a/app/controllers/well_known/nodeinfo_controller.rb b/app/controllers/well_known/nodeinfo_controller.rb new file mode 100644 index 000000000..11a699ebc --- /dev/null +++ b/app/controllers/well_known/nodeinfo_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module WellKnown + class NodeInfoController < ActionController::Base + include CacheConcern + + before_action { response.headers['Vary'] = 'Accept' } + + def index + expires_in 3.days, public: true + render_with_cache json: {}, serializer: NodeInfo::DiscoverySerializer, adapter: NodeInfo::Adapter, expires_in: 3.days, root: 'nodeinfo' + end + + def show + expires_in 30.minutes, public: true + render_with_cache json: {}, serializer: NodeInfo::Serializer, adapter: NodeInfo::Adapter, expires_in: 30.minutes, root: 'nodeinfo' + end + end +end |