Merge pull request #803 from ThibG/glitch-soc/merge-upstream
Merge upstream changes (v2.6.1)
This commit is contained in:
		
						commit
						a78ec63afa
					
				
							
								
								
									
										24
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -3,7 +3,13 @@ Changelog | |||||||
| 
 | 
 | ||||||
| All notable changes to this project will be documented in this file. | All notable changes to this project will be documented in this file. | ||||||
| 
 | 
 | ||||||
| ## [Unreleased] | ## [2.6.1] - 2018-10-30 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - Fix resolving resources by URL not working due to a regression in #9132 (#9171) | ||||||
|  | - Fix reducer error in web UI when a conversation has no last status (#9173) | ||||||
|  | 
 | ||||||
|  | ## [2.6.0] - 2018-10-30 | ||||||
| ### Added | ### Added | ||||||
| 
 | 
 | ||||||
| - Add link ownership verification (#8703) | - Add link ownership verification (#8703) | ||||||
| @ -46,7 +52,7 @@ All notable changes to this project will be documented in this file. | |||||||
| - Add CORS header to `/.well-known/*` routes (#9083) | - Add CORS header to `/.well-known/*` routes (#9083) | ||||||
| - Add `card` attribute to statuses returned from REST API (#9120) | - Add `card` attribute to statuses returned from REST API (#9120) | ||||||
| - Add in-stream link preview (#9120) | - Add in-stream link preview (#9120) | ||||||
| - Add support for ActivityPub `Page` objects (#9121)  | - Add support for ActivityPub `Page` objects (#9121) | ||||||
| 
 | 
 | ||||||
| ### Changed | ### Changed | ||||||
| 
 | 
 | ||||||
| @ -63,7 +69,7 @@ All notable changes to this project will be documented in this file. | |||||||
| - Change recommended Ruby version to 2.5.3 (#9003) | - Change recommended Ruby version to 2.5.3 (#9003) | ||||||
| - Change docker-compose default to persist volumes in current directory (#9055) | - Change docker-compose default to persist volumes in current directory (#9055) | ||||||
| - Change character counters on edit profile page to input length limit (#9100) | - Change character counters on edit profile page to input length limit (#9100) | ||||||
| - Change notification filtering to always let through messages from staff (#9152)  | - Change notification filtering to always let through messages from staff (#9152) | ||||||
| - Change "hide boosts from user" function also hiding notifications about boosts (#9147) | - Change "hide boosts from user" function also hiding notifications about boosts (#9147) | ||||||
| - Change CSS `detailed-status__wrapper` class actually wrap the detailed status (#8547) | - Change CSS `detailed-status__wrapper` class actually wrap the detailed status (#8547) | ||||||
| 
 | 
 | ||||||
| @ -97,15 +103,15 @@ All notable changes to this project will be documented in this file. | |||||||
| - Fix some hotkeys not working on detailed status view (#9006) | - Fix some hotkeys not working on detailed status view (#9006) | ||||||
| - Fix og:url on status pages (#9047) | - Fix og:url on status pages (#9047) | ||||||
| - Fix upload option buttons only being visible on hover (#9074) | - Fix upload option buttons only being visible on hover (#9074) | ||||||
| - Fix tootctl not returning exit code 1 on wrong arguments (#9094)  | - Fix tootctl not returning exit code 1 on wrong arguments (#9094) | ||||||
| - Fix preview cards for appearing for profiles mentioned in toot (#6934, #9158)  | - Fix preview cards for appearing for profiles mentioned in toot (#6934, #9158) | ||||||
| - Fix local accounts sometimes being duplicated as faux-remote (#9109) | - Fix local accounts sometimes being duplicated as faux-remote (#9109) | ||||||
| - Fix emoji search when the shortcode has multiple separators (#9124) | - Fix emoji search when the shortcode has multiple separators (#9124) | ||||||
| - Fix dropdowns sometimes being partially obscured by other elements (#9126)  | - Fix dropdowns sometimes being partially obscured by other elements (#9126) | ||||||
| - Fix cache not updating when reply/boost/favourite counters or media sensitivity update (#9119)  | - Fix cache not updating when reply/boost/favourite counters or media sensitivity update (#9119) | ||||||
| - Fix empty display name precedence over username in web UI (#9163)  | - Fix empty display name precedence over username in web UI (#9163) | ||||||
| - Fix td instead of th in sessions table header (#9162) | - Fix td instead of th in sessions table header (#9162) | ||||||
| - Fix handling of content types with profile (#9132)  | - Fix handling of content types with profile (#9132) | ||||||
| 
 | 
 | ||||||
| ## [2.5.2] - 2018-10-12 | ## [2.5.2] - 2018-10-12 | ||||||
| ### Security | ### Security | ||||||
|  | |||||||
| @ -90,9 +90,9 @@ | |||||||
|   "confirmations.mute.confirm": "Rescondre", |   "confirmations.mute.confirm": "Rescondre", | ||||||
|   "confirmations.mute.message": "Volètz vertadièrament rescondre {name} ?", |   "confirmations.mute.message": "Volètz vertadièrament rescondre {name} ?", | ||||||
|   "confirmations.redraft.confirm": "Escafar & tornar formular", |   "confirmations.redraft.confirm": "Escafar & tornar formular", | ||||||
|   "confirmations.redraft.message": "Volètz vertadièrament escafar aqueste estatut e lo reformular ? Tote sos partiments e favorits seràn perduts, e sas responsas seràn orfanèlas.", |   "confirmations.redraft.message": "Volètz vertadièrament escafar aqueste estatut e lo reformular ? Totes sos partiments e favorits seràn perduts, e sas responsas seràn orfanèlas.", | ||||||
|   "confirmations.reply.confirm": "Respondre", |   "confirmations.reply.confirm": "Respondre", | ||||||
|   "confirmations.reply.message": "Respondre remplaçarà lo messatge que sètz a escriure. Volètz vertadièrament contunhar ?", |   "confirmations.reply.message": "Respondre remplaçarà lo messatge que sètz a escriure. Volètz vertadièrament contunhar ?", | ||||||
|   "confirmations.unfollow.confirm": "Quitar de sègre", |   "confirmations.unfollow.confirm": "Quitar de sègre", | ||||||
|   "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?", |   "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?", | ||||||
|   "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.", |   "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.", | ||||||
| @ -115,8 +115,8 @@ | |||||||
|   "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !", |   "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !", | ||||||
|   "empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.", |   "empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.", | ||||||
|   "empty_column.domain_blocks": "I a pas encara cap de domeni amagat.", |   "empty_column.domain_blocks": "I a pas encara cap de domeni amagat.", | ||||||
|   "empty_column.favourited_statuses": "Avètz pas encara cap de tut favorit. Quanda n’auretz un, apareisserà  aquí.", |   "empty_column.favourited_statuses": "Avètz pas encara cap de tut favorit. Quand n’auretz un, apareisserà aquí.", | ||||||
|   "empty_column.favourites": "Degun a pas encara mes en favorit aqueste tut. Quanda qualqu’un o farà, apareisserà  aquí.", |   "empty_column.favourites": "Degun a pas encara mes en favorit aqueste tut. Quand qualqu’un o farà, apareisserà aquí.", | ||||||
|   "empty_column.follow_requests": "Avètz pas encara de demanda d’abonament. Quand n’auretz una apareisserà aquí.", |   "empty_column.follow_requests": "Avètz pas encara de demanda d’abonament. Quand n’auretz una apareisserà aquí.", | ||||||
|   "empty_column.hashtag": "I a pas encara de contengut ligat a aquesta etiqueta.", |   "empty_column.hashtag": "I a pas encara de contengut ligat a aquesta etiqueta.", | ||||||
|   "empty_column.home": "Vòstre flux d’acuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a d’autras personas.", |   "empty_column.home": "Vòstre flux d’acuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a d’autras personas.", | ||||||
| @ -129,7 +129,7 @@ | |||||||
|   "follow_request.authorize": "Acceptar", |   "follow_request.authorize": "Acceptar", | ||||||
|   "follow_request.reject": "Regetar", |   "follow_request.reject": "Regetar", | ||||||
|   "getting_started.developers": "Desvelopaires", |   "getting_started.developers": "Desvelopaires", | ||||||
|   "getting_started.documentation": "Documentation", |   "getting_started.documentation": "Documentacion", | ||||||
|   "getting_started.find_friends": "Trobar d’amics de Twitter", |   "getting_started.find_friends": "Trobar d’amics de Twitter", | ||||||
|   "getting_started.heading": "Per començar", |   "getting_started.heading": "Per començar", | ||||||
|   "getting_started.invite": "Convidar de monde", |   "getting_started.invite": "Convidar de monde", | ||||||
| @ -145,7 +145,7 @@ | |||||||
|   "keyboard_shortcuts.column": "centrar un estatut a una colomna", |   "keyboard_shortcuts.column": "centrar un estatut a una colomna", | ||||||
|   "keyboard_shortcuts.compose": "anar al camp tèxte", |   "keyboard_shortcuts.compose": "anar al camp tèxte", | ||||||
|   "keyboard_shortcuts.description": "Descripcion", |   "keyboard_shortcuts.description": "Descripcion", | ||||||
|   "keyboard_shortcuts.direct": "per dobrir la columna de messatges dirèctes", |   "keyboard_shortcuts.direct": "per dobrir la colomna de messatges dirèctes", | ||||||
|   "keyboard_shortcuts.down": "far davalar dins la lista", |   "keyboard_shortcuts.down": "far davalar dins la lista", | ||||||
|   "keyboard_shortcuts.enter": "dobrir los estatuts", |   "keyboard_shortcuts.enter": "dobrir los estatuts", | ||||||
|   "keyboard_shortcuts.favourite": "apondre als favorits", |   "keyboard_shortcuts.favourite": "apondre als favorits", | ||||||
| @ -159,7 +159,7 @@ | |||||||
|   "keyboard_shortcuts.mention": "mencionar l’autor", |   "keyboard_shortcuts.mention": "mencionar l’autor", | ||||||
|   "keyboard_shortcuts.muted": "per dobrir la lista dels utilizaires silenciats", |   "keyboard_shortcuts.muted": "per dobrir la lista dels utilizaires silenciats", | ||||||
|   "keyboard_shortcuts.my_profile": "per dobrir vòstre perfil", |   "keyboard_shortcuts.my_profile": "per dobrir vòstre perfil", | ||||||
|   "keyboard_shortcuts.notifications": "per dobrir la columna de notificacions", |   "keyboard_shortcuts.notifications": "per dobrir la colomna de notificacions", | ||||||
|   "keyboard_shortcuts.pinned": "per dobrir la lista dels tuts penjats", |   "keyboard_shortcuts.pinned": "per dobrir la lista dels tuts penjats", | ||||||
|   "keyboard_shortcuts.profile": "per dobrir lo perfil de l’autor", |   "keyboard_shortcuts.profile": "per dobrir lo perfil de l’autor", | ||||||
|   "keyboard_shortcuts.reply": "respondre", |   "keyboard_shortcuts.reply": "respondre", | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ const conversationToMap = item => ImmutableMap({ | |||||||
|   id: item.id, |   id: item.id, | ||||||
|   unread: item.unread, |   unread: item.unread, | ||||||
|   accounts: ImmutableList(item.accounts.map(a => a.id)), |   accounts: ImmutableList(item.accounts.map(a => a.id)), | ||||||
|   last_status: item.last_status.id, |   last_status: item.last_status ? item.last_status.id : null, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const updateConversation = (state, item) => state.update('items', list => { | const updateConversation = (state, item) => state.update('items', list => { | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ class FetchAtomService < BaseService | |||||||
| 
 | 
 | ||||||
|   def perform_request(&block) |   def perform_request(&block) | ||||||
|     accept = 'text/html' |     accept = 'text/html' | ||||||
|     accept = 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/atom+xml, ' + accept unless @unsupported_activity |     accept = 'application/activity+json, application/ld+json, application/atom+xml, ' + accept unless @unsupported_activity | ||||||
| 
 | 
 | ||||||
|     Request.new(:get, @url).add_headers('Accept' => accept).perform(&block) |     Request.new(:get, @url).add_headers('Accept' => accept).perform(&block) | ||||||
|   end |   end | ||||||
| @ -37,11 +37,9 @@ class FetchAtomService < BaseService | |||||||
|   def process_response(response, terminal = false) |   def process_response(response, terminal = false) | ||||||
|     return nil if response.code != 200 |     return nil if response.code != 200 | ||||||
| 
 | 
 | ||||||
|     response_type = response.headers['Content-type'] |     if response.mime_type == 'application/atom+xml' | ||||||
| 
 |  | ||||||
|     if response_type == 'application/atom+xml' |  | ||||||
|       [@url, { prefetched_body: response.body_with_limit }, :ostatus] |       [@url, { prefetched_body: response.body_with_limit }, :ostatus] | ||||||
|     elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(response_type) |     elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(response.mime_type) | ||||||
|       body = response.body_with_limit |       body = response.body_with_limit | ||||||
|       json = body_to_json(body) |       json = body_to_json(body) | ||||||
|       if supported_context?(json) && equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) && json['inbox'].present? |       if supported_context?(json) && equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) && json['inbox'].present? | ||||||
| @ -57,7 +55,7 @@ class FetchAtomService < BaseService | |||||||
| 
 | 
 | ||||||
|       if link_header&.find_link(%w(rel alternate)) |       if link_header&.find_link(%w(rel alternate)) | ||||||
|         process_link_headers(link_header) |         process_link_headers(link_header) | ||||||
|       elsif response_type == 'text/html' |       elsif response.mime_type == 'text/html' | ||||||
|         process_html(response) |         process_html(response) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  | |||||||
| @ -139,7 +139,7 @@ oc: | |||||||
|       resend_confirmation: |       resend_confirmation: | ||||||
|         already_confirmed: Aqueste utilizaire es ja confirmat |         already_confirmed: Aqueste utilizaire es ja confirmat | ||||||
|         send: Tornar mandar lo corrièl de confirmacion |         send: Tornar mandar lo corrièl de confirmacion | ||||||
|         success: Corrièl de confirmacion corrèctament mandat ! |         success: Corrièl de confirmacion corrèctament mandat ! | ||||||
|       reset: Reïnicializar |       reset: Reïnicializar | ||||||
|       reset_password: Reïnicializar lo senhal |       reset_password: Reïnicializar lo senhal | ||||||
|       resubscribe: Se tornar abonar |       resubscribe: Se tornar abonar | ||||||
| @ -438,11 +438,11 @@ oc: | |||||||
|       title: WebSub |       title: WebSub | ||||||
|       topic: Subjècte |       topic: Subjècte | ||||||
|     suspensions: |     suspensions: | ||||||
|       bad_acct_msg: La valor de confirmacion a pas coïncidit. Sètz a suspendre lo bon compte ? |       bad_acct_msg: La valor de confirmacion a pas coïncidit. Sètz a suspendre lo bon compte ? | ||||||
|       hint_html: 'Per confirmar la suspension del compte, picatz %{value} al camp çai-jos :' |       hint_html: 'Per confirmar la suspension del compte, picatz %{value} al camp çai-jos :' | ||||||
|       proceed: Tractat |       proceed: Tractat | ||||||
|       title: Suspension de %{acct} |       title: Suspension de %{acct} | ||||||
|       warning_html: 'Suspendre aqueste compte suprimirà <strong>irreversiblament</strong> las donadas del compte, aquò compren :' |       warning_html: 'Suspendre aqueste compte suprimirà <strong>irreversiblament</strong> las donadas del compte, aquò compren :' | ||||||
|     title: Administracion |     title: Administracion | ||||||
|   admin_mailer: |   admin_mailer: | ||||||
|     new_report: |     new_report: | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ oc: | |||||||
|       imports: |       imports: | ||||||
|         data: Fichièr CSV exportat d’una autra instància Mastodon |         data: Fichièr CSV exportat d’una autra instància Mastodon | ||||||
|       sessions: |       sessions: | ||||||
|         otp: 'Picatz lo còdi d’autentificacion en dos temps (Two factor code) de vòstra aplicacion mobil o utilizatz un de vòstres còdis de recuperacion :' |         otp: 'Picatz lo còdi d’autentificacion en dos temps (Two factor code) de vòstra aplicacion mobil o utilizatz un de vòstres còdis de recuperacion :' | ||||||
|       user: |       user: | ||||||
|         chosen_languages: Quand seleccionadas, solament los tuts dins las lengas triadas seràn mostrats dins vòstre flux d’actualitat |         chosen_languages: Quand seleccionadas, solament los tuts dins las lengas triadas seràn mostrats dins vòstre flux d’actualitat | ||||||
|     labels: |     labels: | ||||||
|  | |||||||
| @ -14,17 +14,15 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] | |||||||
|       sleep 1 |       sleep 1 | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     total        = estimate_rows(local_direct_statuses) + estimate_rows(notifications_about_direct_statuses) |     migrated  = 0 | ||||||
|     migrated     = 0 |     last_time = Time.zone.now | ||||||
|     started_time = Time.zone.now |  | ||||||
|     last_time    = Time.zone.now |  | ||||||
| 
 | 
 | ||||||
|     local_direct_statuses.includes(:account, mentions: :account).find_each do |status| |     local_direct_statuses.includes(:account, mentions: :account).find_each do |status| | ||||||
|       AccountConversation.add_status(status.account, status) |       AccountConversation.add_status(status.account, status) | ||||||
|       migrated += 1 |       migrated += 1 | ||||||
| 
 | 
 | ||||||
|       if Time.zone.now - last_time > 1 |       if Time.zone.now - last_time > 1 | ||||||
|         say_progress(migrated, total, started_time) |         say_progress(migrated) | ||||||
|         last_time = Time.zone.now |         last_time = Time.zone.now | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| @ -34,7 +32,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] | |||||||
|       migrated += 1 |       migrated += 1 | ||||||
| 
 | 
 | ||||||
|       if Time.zone.now - last_time > 1 |       if Time.zone.now - last_time > 1 | ||||||
|         say_progress(migrated, total, started_time) |         say_progress(migrated) | ||||||
|         last_time = Time.zone.now |         last_time = Time.zone.now | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| @ -45,24 +43,8 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] | |||||||
| 
 | 
 | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|   def estimate_rows(query) |   def say_progress(migrated) | ||||||
|     result = exec_query("EXPLAIN #{query.to_sql}").first |     say "Migrated #{migrated} rows", true | ||||||
|     result['QUERY PLAN'].scan(/ rows=([\d]+)/).first&.first&.to_i || 0 |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def say_progress(migrated, total, started_time) |  | ||||||
|     status = "Migrated #{migrated} rows" |  | ||||||
| 
 |  | ||||||
|     percentage = 100.0 * migrated / total |  | ||||||
|     status += " (~#{sprintf('%.2f', percentage)}%, " |  | ||||||
| 
 |  | ||||||
|     remaining_time = (100.0 - percentage) * (Time.zone.now - started_time) / percentage |  | ||||||
| 
 |  | ||||||
|     status += "#{(remaining_time / 60).to_i}:" |  | ||||||
|     status += sprintf('%02d', remaining_time.to_i % 60) |  | ||||||
|     status += ' remaining)' |  | ||||||
| 
 |  | ||||||
|     say status, true |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def local_direct_statuses |   def local_direct_statuses | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ module Mastodon | |||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def patch |     def patch | ||||||
|       0 |       1 | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def pre |     def pre | ||||||
| @ -21,7 +21,7 @@ module Mastodon | |||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def flags |     def flags | ||||||
|       'rc4' |       '' | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def to_a |     def to_a | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
|   "name": "mastodon", |   "name": "mastodon", | ||||||
|   "license": "AGPL-3.0-or-later", |   "license": "AGPL-3.0-or-later", | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": ">=8" |     "node": ">=8 <11" | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "postversion": "git push --tags", |     "postversion": "git push --tags", | ||||||
|  | |||||||
| @ -60,20 +60,13 @@ RSpec.describe FetchAtomService, type: :service do | |||||||
|         it { is_expected.to eq [url, { :prefetched_body => "" }, :ostatus] } |         it { is_expected.to eq [url, { :prefetched_body => "" }, :ostatus] } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'content_type is activity+json' do |       context 'content_type is json' do | ||||||
|         let(:content_type) { 'application/activity+json' } |         let(:content_type) { 'application/activity+json' } | ||||||
|         let(:body) { json } |         let(:body) { json } | ||||||
| 
 | 
 | ||||||
|         it { is_expected.to eq [1, { prefetched_body: body, id: true }, :activitypub] } |         it { is_expected.to eq [1, { prefetched_body: body, id: true }, :activitypub] } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'content_type is ld+json with profile' do |  | ||||||
|         let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' } |  | ||||||
|         let(:body) { json } |  | ||||||
| 
 |  | ||||||
|         it { is_expected.to eq [1, { prefetched_body: body, id: true }, :activitypub] } |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       before do |       before do | ||||||
|         WebMock.stub_request(:get, url).to_return(status: 200, body: body, headers: headers) |         WebMock.stub_request(:get, url).to_return(status: 200, body: body, headers: headers) | ||||||
|         WebMock.stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) |         WebMock.stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user