Add ability to use remote follow function on other sites
This commit is contained in:
		| @@ -324,3 +324,61 @@ | ||||
|   padding-bottom: 25px; | ||||
|   cursor: default; | ||||
| } | ||||
|  | ||||
| .account-card { | ||||
|   padding: 14px 10px; | ||||
|   background: #fff; | ||||
|   border-radius: 4px; | ||||
|   text-align: left; | ||||
|   box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); | ||||
|  | ||||
|   .detailed-status__display-name { | ||||
|     display: block; | ||||
|     overflow: hidden; | ||||
|     margin-bottom: 15px; | ||||
|  | ||||
|     & > div { | ||||
|       float: left; | ||||
|       margin-right: 10px; | ||||
|       width: 48px; | ||||
|       height: 48px; | ||||
|     } | ||||
|  | ||||
|     .avatar { | ||||
|       display: block; | ||||
|       border-radius: 4px; | ||||
|     } | ||||
|  | ||||
|     .display-name { | ||||
|       display: block; | ||||
|       max-width: 100%; | ||||
|       overflow: hidden; | ||||
|       white-space: nowrap; | ||||
|       text-overflow: ellipsis; | ||||
|       cursor: default; | ||||
|  | ||||
|       strong { | ||||
|         font-weight: 500; | ||||
|         color: #282c37; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         font-size: 14px; | ||||
|         color: #9baec8; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     &:hover { | ||||
|       .display-name { | ||||
|         strong { | ||||
|           text-decoration: none; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .account__header__content { | ||||
|     font-size: 14px; | ||||
|     color: #282c37; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -214,11 +214,13 @@ body { | ||||
| .footer { | ||||
|   text-align: center; | ||||
|   margin-top: 30px; | ||||
|   font-size: 12px; | ||||
|   color: darken(#d9e1e8, 25%); | ||||
|  | ||||
|   .domain { | ||||
|     font-size: 12px; | ||||
|     font-weight: 400; | ||||
|     font-family: 'Roboto Mono', monospace; | ||||
|     //font-size: 12px; | ||||
|     font-weight: 500; | ||||
|     //font-family: 'Roboto Mono', monospace; | ||||
|  | ||||
|     a { | ||||
|       color: inherit; | ||||
| @@ -227,13 +229,12 @@ body { | ||||
|   } | ||||
|  | ||||
|   .powered-by { | ||||
|     font-size: 12px; | ||||
|     font-weight: 400; | ||||
|     color: darken(#d9e1e8, 25%); | ||||
|  | ||||
|     a { | ||||
|       color: inherit; | ||||
|       text-decoration: underline; | ||||
|       font-weight: 500; | ||||
|  | ||||
|       &:hover { | ||||
|         text-decoration: none; | ||||
|   | ||||
| @@ -185,7 +185,7 @@ code { | ||||
|   } | ||||
| } | ||||
|  | ||||
| .oauth-prompt { | ||||
| .oauth-prompt, .follow-prompt { | ||||
|   margin-bottom: 30px; | ||||
|   text-align: center; | ||||
|   color: #9baec8; | ||||
|   | ||||
							
								
								
									
										24
									
								
								app/controllers/authorize_follow_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/controllers/authorize_follow_controller.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| class AuthorizeFollowController < ApplicationController | ||||
|   layout 'public' | ||||
|  | ||||
|   before_action :authenticate_user! | ||||
|  | ||||
|   def new | ||||
|     @account = FollowRemoteAccountService.new.call(params[:acct]) | ||||
|     render :error if @account.nil? | ||||
|   end | ||||
|  | ||||
|   def create | ||||
|     @account = FollowService.new.call(current_account, params[:acct]).try(:target_account) | ||||
|  | ||||
|     if @account.nil? | ||||
|       render :error | ||||
|     else | ||||
|       redirect_to web_url("accounts/#{@account.id}") | ||||
|     end | ||||
|   rescue ActiveRecord::RecordNotFound, Mastodon::NotPermitted | ||||
|     render :error | ||||
|   end | ||||
| end | ||||
							
								
								
									
										2
									
								
								app/helpers/authorize_follow_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/helpers/authorize_follow_helper.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| module AuthorizeFollowHelper | ||||
| end | ||||
| @@ -1,6 +1,6 @@ | ||||
| .account-grid-card | ||||
|   .account-grid-card__header | ||||
|     .avatar= image_tag account.avatar.url( :original) | ||||
|     .avatar= image_tag account.avatar.url(:original) | ||||
|     .name | ||||
|       = link_to TagManager.instance.url_for(account) do | ||||
|         %span.display_name= display_name(account) | ||||
|   | ||||
							
								
								
									
										3
									
								
								app/views/authorize_follow/error.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/views/authorize_follow/error.html.haml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| .form-container | ||||
|   .flash-message#error_explanation | ||||
|     = t('authorize_follow.error') | ||||
							
								
								
									
										21
									
								
								app/views/authorize_follow/new.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/views/authorize_follow/new.html.haml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| - content_for :page_title do | ||||
|   = t('authorize_follow.title', acct: @account.acct) | ||||
|  | ||||
| .form-container | ||||
|   .follow-prompt | ||||
|     %h2= t('authorize_follow.prompt_html', self: current_account.username) | ||||
|  | ||||
|     .account-card | ||||
|       .detailed-status__display-name | ||||
|         %div | ||||
|           = image_tag @account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar' | ||||
|  | ||||
|         %span.display-name | ||||
|           %strong= display_name(@account) | ||||
|           %span= "@#{@account.acct}" | ||||
|  | ||||
|       .account__header__content= Formatter.instance.simplified_format(@account) | ||||
|  | ||||
|   = form_tag authorize_follow_path, method: :post, class: 'simple_form' do | ||||
|     = hidden_field_tag :acct, @account.acct | ||||
|     = button_tag t('authorize_follow.follow'), type: :submit | ||||
| @@ -1,2 +1,3 @@ | ||||
| .flash-message#error_explanation | ||||
|   = @pre_auth.error_response.body[:error_description] | ||||
| .form-container | ||||
|   .flash-message#error_explanation | ||||
|     = @pre_auth.error_response.body[:error_description] | ||||
|   | ||||
| @@ -1,25 +1,26 @@ | ||||
| - content_for :page_title do | ||||
|   = t('doorkeeper.authorizations.new.title') | ||||
|  | ||||
| .oauth-prompt | ||||
|   %h2= t('doorkeeper.authorizations.new.prompt', client_name: @pre_auth.client.name) | ||||
| .form-container | ||||
|   .oauth-prompt | ||||
|     %h2= t('doorkeeper.authorizations.new.prompt', client_name: @pre_auth.client.name) | ||||
|  | ||||
|   %p | ||||
|     = t('doorkeeper.authorizations.new.able_to') | ||||
|     = @pre_auth.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.map { |s| "<strong>#{s}</strong>"}.to_sentence.html_safe | ||||
|     %p | ||||
|       = t('doorkeeper.authorizations.new.able_to') | ||||
|       = @pre_auth.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.map { |s| "<strong>#{s}</strong>"}.to_sentence.html_safe | ||||
|  | ||||
| = form_tag oauth_authorization_path, method: :post, class: 'simple_form' do | ||||
|   = hidden_field_tag :client_id, @pre_auth.client.uid | ||||
|   = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri | ||||
|   = hidden_field_tag :state, @pre_auth.state | ||||
|   = hidden_field_tag :response_type, @pre_auth.response_type | ||||
|   = hidden_field_tag :scope, @pre_auth.scope | ||||
|   = button_tag t('doorkeeper.authorizations.buttons.authorize'), type: :submit | ||||
|   = form_tag oauth_authorization_path, method: :post, class: 'simple_form' do | ||||
|     = hidden_field_tag :client_id, @pre_auth.client.uid | ||||
|     = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri | ||||
|     = hidden_field_tag :state, @pre_auth.state | ||||
|     = hidden_field_tag :response_type, @pre_auth.response_type | ||||
|     = hidden_field_tag :scope, @pre_auth.scope | ||||
|     = button_tag t('doorkeeper.authorizations.buttons.authorize'), type: :submit | ||||
|  | ||||
| = form_tag oauth_authorization_path, method: :delete, class: 'simple_form' do | ||||
|   = hidden_field_tag :client_id, @pre_auth.client.uid | ||||
|   = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri | ||||
|   = hidden_field_tag :state, @pre_auth.state | ||||
|   = hidden_field_tag :response_type, @pre_auth.response_type | ||||
|   = hidden_field_tag :scope, @pre_auth.scope | ||||
|   = button_tag t('doorkeeper.authorizations.buttons.deny'), type: :submit, class: 'negative' | ||||
|   = form_tag oauth_authorization_path, method: :delete, class: 'simple_form' do | ||||
|     = hidden_field_tag :client_id, @pre_auth.client.uid | ||||
|     = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri | ||||
|     = hidden_field_tag :state, @pre_auth.state | ||||
|     = hidden_field_tag :response_type, @pre_auth.response_type | ||||
|     = hidden_field_tag :scope, @pre_auth.scope | ||||
|     = button_tag t('doorkeeper.authorizations.buttons.deny'), type: :submit, class: 'negative' | ||||
|   | ||||
| @@ -1,2 +1,3 @@ | ||||
| .flash-message | ||||
|   %code= params[:code] | ||||
| .form-container | ||||
|   .flash-message | ||||
|     %code= params[:code] | ||||
|   | ||||
| @@ -11,6 +11,7 @@ node(:links) do | ||||
|     { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account) }, | ||||
|     { rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }, | ||||
|     { rel: 'salmon', href: api_salmon_url(@account.id) }, | ||||
|     { rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}" } | ||||
|     { rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}" }, | ||||
|     { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}" }, | ||||
|   ] | ||||
| end | ||||
|   | ||||
| @@ -6,5 +6,6 @@ Nokogiri::XML::Builder.new do |xml| | ||||
|     xml.Link(rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom')) | ||||
|     xml.Link(rel: 'salmon', href: api_salmon_url(@account.id)) | ||||
|     xml.Link(rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}") | ||||
|     xml.Link(rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}") | ||||
|   end | ||||
| end.to_xml | ||||
|   | ||||
| @@ -45,7 +45,7 @@ module Mastodon | ||||
|     config.browserify_rails.commandline_options = '--transform [ babelify --presets [ es2015 react ] ] --extension=".jsx"' | ||||
|  | ||||
|     config.to_prepare do | ||||
|       Doorkeeper::AuthorizationsController.layout 'auth' | ||||
|       Doorkeeper::AuthorizationsController.layout 'public' | ||||
|     end | ||||
|  | ||||
|     config.action_dispatch.default_headers = { | ||||
|   | ||||
| @@ -26,6 +26,11 @@ en: | ||||
|     resend_confirmation: Resend confirmation instructions | ||||
|     reset_password: Reset password | ||||
|     set_new_password: Set new password | ||||
|   authorize_follow: | ||||
|     error: Unfortunately, there was an error looking up the remote account | ||||
|     follow: Follow | ||||
|     prompt_html: 'You (<strong>%{self}</strong>) have requested to follow:' | ||||
|     title: Follow %{acct} | ||||
|   datetime: | ||||
|     distance_in_words: | ||||
|       about_x_hours: "%{count}h" | ||||
|   | ||||
| @@ -48,6 +48,10 @@ Rails.application.routes.draw do | ||||
|   resources :media, only: [:show] | ||||
|   resources :tags,  only: [:show] | ||||
|  | ||||
|   # Remote follow | ||||
|   get  :authorize_follow, to: 'authorize_follow#new' | ||||
|   post :authorize_follow, to: 'authorize_follow#create' | ||||
|  | ||||
|   namespace :admin do | ||||
|     resources :pubsubhubbub, only: [:index] | ||||
|     resources :domain_blocks, only: [:index, :create] | ||||
|   | ||||
							
								
								
									
										6
									
								
								spec/controllers/authorize_follow_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								spec/controllers/authorize_follow_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe AuthorizeFollowController, type: :controller do | ||||
|   describe 'GET #new' | ||||
|   describe 'POST #create' | ||||
| end | ||||
							
								
								
									
										5
									
								
								spec/helpers/authorize_follow_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/helpers/authorize_follow_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe AuthorizeFollowHelper, type: :helper do | ||||
|  | ||||
| end | ||||
		Reference in New Issue
	
	Block a user