Add confirmation when redirecting logged-out requests to permalink (#27792)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
7a1f087659
commit
b19ae521b7
9 changed files with 165 additions and 29 deletions
|
@ -21,10 +21,19 @@ module WebAppControllerConcern
|
||||||
def redirect_unauthenticated_to_permalinks!
|
def redirect_unauthenticated_to_permalinks!
|
||||||
return if user_signed_in? && current_account.moved_to_account_id.nil?
|
return if user_signed_in? && current_account.moved_to_account_id.nil?
|
||||||
|
|
||||||
redirect_path = PermalinkRedirector.new(request.path).redirect_path
|
permalink_redirector = PermalinkRedirector.new(request.path)
|
||||||
return if redirect_path.blank?
|
return if permalink_redirector.redirect_path.blank?
|
||||||
|
|
||||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
||||||
redirect_to(redirect_path)
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
redirect_to(permalink_redirector.redirect_confirmation_path, allow_other_host: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
format.json do
|
||||||
|
redirect_to(permalink_redirector.redirect_uri, allow_other_host: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
10
app/controllers/redirect/accounts_controller.rb
Normal file
10
app/controllers/redirect/accounts_controller.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Redirect::AccountsController < ApplicationController
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_resource
|
||||||
|
@resource = Account.find(params[:id])
|
||||||
|
not_found if @resource.local?
|
||||||
|
end
|
||||||
|
end
|
24
app/controllers/redirect/base_controller.rb
Normal file
24
app/controllers/redirect/base_controller.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Redirect::BaseController < ApplicationController
|
||||||
|
vary_by 'Accept-Language'
|
||||||
|
|
||||||
|
before_action :set_resource
|
||||||
|
before_action :set_app_body_class
|
||||||
|
|
||||||
|
def show
|
||||||
|
@redirect_path = ActivityPub::TagManager.instance.url_for(@resource)
|
||||||
|
|
||||||
|
render 'redirects/show', layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_app_body_class
|
||||||
|
@body_classes = 'app-body'
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_resource
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
10
app/controllers/redirect/statuses_controller.rb
Normal file
10
app/controllers/redirect/statuses_controller.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Redirect::StatusesController < Redirect::BaseController
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_resource
|
||||||
|
@resource = Status.find(params[:id])
|
||||||
|
not_found if @resource.local? || !@resource.distributable?
|
||||||
|
end
|
||||||
|
end
|
|
@ -104,3 +104,59 @@
|
||||||
margin-inline-start: 10px;
|
margin-inline-start: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redirect {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__message {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,17 +5,46 @@ class PermalinkRedirector
|
||||||
|
|
||||||
def initialize(path)
|
def initialize(path)
|
||||||
@path = path
|
@path = path
|
||||||
|
@object = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def object
|
||||||
|
@object ||= begin
|
||||||
|
if at_username_status_request? || statuses_status_request?
|
||||||
|
status = Status.find_by(id: second_segment)
|
||||||
|
status if status&.distributable? && !status&.local?
|
||||||
|
elsif at_username_request?
|
||||||
|
username, domain = first_segment.delete_prefix('@').split('@')
|
||||||
|
domain = nil if TagManager.instance.local_domain?(domain)
|
||||||
|
account = Account.find_remote(username, domain)
|
||||||
|
account unless account&.local?
|
||||||
|
elsif accounts_request? && record_integer_id_request?
|
||||||
|
account = Account.find_by(id: second_segment)
|
||||||
|
account unless account&.local?
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def redirect_path
|
def redirect_path
|
||||||
if at_username_status_request? || statuses_status_request?
|
return ActivityPub::TagManager.instance.url_for(object) if object.present?
|
||||||
find_status_url_by_id(second_segment)
|
|
||||||
elsif at_username_request?
|
@path.delete_prefix('/deck') if @path.start_with?('/deck')
|
||||||
find_account_url_by_name(first_segment)
|
end
|
||||||
elsif accounts_request? && record_integer_id_request?
|
|
||||||
find_account_url_by_id(second_segment)
|
def redirect_uri
|
||||||
elsif @path.start_with?('/deck')
|
return ActivityPub::TagManager.instance.uri_for(object) if object.present?
|
||||||
@path.delete_prefix('/deck')
|
|
||||||
|
@path.delete_prefix('/deck') if @path.start_with?('/deck')
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirect_confirmation_path
|
||||||
|
case object.class.name
|
||||||
|
when 'Account'
|
||||||
|
redirect_account_path(object.id)
|
||||||
|
when 'Status'
|
||||||
|
redirect_status_path(object.id)
|
||||||
|
else
|
||||||
|
@path.delete_prefix('/deck') if @path.start_with?('/deck')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -56,22 +85,4 @@ class PermalinkRedirector
|
||||||
def path_segments
|
def path_segments
|
||||||
@path_segments ||= @path.delete_prefix('/deck').delete_prefix('/').split('/')
|
@path_segments ||= @path.delete_prefix('/deck').delete_prefix('/').split('/')
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_status_url_by_id(id)
|
|
||||||
status = Status.find_by(id: id)
|
|
||||||
ActivityPub::TagManager.instance.url_for(status) if status&.distributable? && !status.account.local?
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_account_url_by_id(id)
|
|
||||||
account = Account.find_by(id: id)
|
|
||||||
ActivityPub::TagManager.instance.url_for(account) if account.present? && !account.local?
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_account_url_by_name(name)
|
|
||||||
username, domain = name.gsub(/\A@/, '').split('@')
|
|
||||||
domain = nil if TagManager.instance.local_domain?(domain)
|
|
||||||
account = Account.find_remote(username, domain)
|
|
||||||
|
|
||||||
ActivityPub::TagManager.instance.url_for(account) if account.present? && !account.local?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
8
app/views/redirects/show.html.haml
Normal file
8
app/views/redirects/show.html.haml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.redirect
|
||||||
|
.redirect__logo
|
||||||
|
= link_to render_logo, root_path
|
||||||
|
|
||||||
|
.redirect__message
|
||||||
|
%h1= t('redirects.title', instance: site_hostname)
|
||||||
|
%p= t('redirects.prompt')
|
||||||
|
%p= link_to @redirect_path, @redirect_path, rel: 'noreferrer noopener'
|
|
@ -1547,6 +1547,9 @@ en:
|
||||||
errors:
|
errors:
|
||||||
limit_reached: Limit of different reactions reached
|
limit_reached: Limit of different reactions reached
|
||||||
unrecognized_emoji: is not a recognized emoji
|
unrecognized_emoji: is not a recognized emoji
|
||||||
|
redirects:
|
||||||
|
prompt: If you trust this link, click it to continue.
|
||||||
|
title: You are leaving %{instance}.
|
||||||
relationships:
|
relationships:
|
||||||
activity: Account activity
|
activity: Account activity
|
||||||
confirm_follow_selected_followers: Are you sure you want to follow selected followers?
|
confirm_follow_selected_followers: Are you sure you want to follow selected followers?
|
||||||
|
|
|
@ -162,6 +162,11 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
namespace :redirect do
|
||||||
|
resources :accounts, only: :show
|
||||||
|
resources :statuses, only: :show
|
||||||
|
end
|
||||||
|
|
||||||
resources :media, only: [:show] do
|
resources :media, only: [:show] do
|
||||||
get :player
|
get :player
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue