From 30ce6e395c5094c3989288619a99f539bb61f05d Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 14 Jul 2021 05:35:49 +0200 Subject: [PATCH 1/4] Fix user email address being banned on self-deletion (#16503) * Add tests * Fix user email address being banned on self-deletion Fixes #16498 --- app/controllers/settings/deletes_controller.rb | 2 +- app/models/account.rb | 4 ++-- spec/controllers/settings/deletes_controller_spec.rb | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/settings/deletes_controller.rb b/app/controllers/settings/deletes_controller.rb index 7b8f8d2078..e0dd5edcb1 100644 --- a/app/controllers/settings/deletes_controller.rb +++ b/app/controllers/settings/deletes_controller.rb @@ -42,7 +42,7 @@ class Settings::DeletesController < Settings::BaseController end def destroy_account! - current_account.suspend!(origin: :local) + current_account.suspend!(origin: :local, block_email: false) AccountDeletionWorker.perform_async(current_user.account_id) sign_out end diff --git a/app/models/account.rb b/app/models/account.rb index 8be36bf5b8..a6d8d15374 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -232,11 +232,11 @@ class Account < ApplicationRecord suspended? && deletion_request.present? end - def suspend!(date: Time.now.utc, origin: :local) + def suspend!(date: Time.now.utc, origin: :local, block_email: true) transaction do create_deletion_request! update!(suspended_at: date, suspension_origin: origin) - create_canonical_email_block! + create_canonical_email_block! if block_email end end diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index 8d5c4774fd..92ab401c96 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -59,6 +59,10 @@ describe Settings::DeletesController do expect(user.account.reload).to be_suspended end + it 'does not create an email block' do + expect(CanonicalEmailBlock.block?(user.email)).to be false + end + context 'when suspended' do let(:user) { Fabricate(:user, account_attributes: { username: 'alice', suspended_at: Time.now.utc }) } From 3dcf3f2a3a059191668c4edf395e4ad0b19209c5 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 14 Jul 2021 05:36:23 +0200 Subject: [PATCH 2/4] Fix minor code quality issues (#16502) --- app/javascript/mastodon/features/ui/components/video_modal.js | 2 +- app/javascript/mastodon/reducers/modal.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js index 7e8e1329d7..f3ee89dfd9 100644 --- a/app/javascript/mastodon/features/ui/components/video_modal.js +++ b/app/javascript/mastodon/features/ui/components/video_modal.js @@ -21,7 +21,7 @@ export default class VideoModal extends ImmutablePureComponent { }; componentDidMount () { - const { media, onChangeBackgroundColor, onClose } = this.props; + const { media, onChangeBackgroundColor } = this.props; const backgroundColor = getAverageFromBlurhash(media.get('blurhash')); diff --git a/app/javascript/mastodon/reducers/modal.js b/app/javascript/mastodon/reducers/modal.js index ea81b43323..c43446f6d5 100644 --- a/app/javascript/mastodon/reducers/modal.js +++ b/app/javascript/mastodon/reducers/modal.js @@ -5,11 +5,11 @@ import { Stack as ImmutableStack, Map as ImmutableMap } from 'immutable'; export default function modal(state = ImmutableStack(), action) { switch(action.type) { case MODAL_OPEN: - return state.unshift(ImmutableMap({ modalType: action.modalType, modalProps: action.modalProps })); + return state.unshift(ImmutableMap({ modalType: action.modalType, modalProps: action.modalProps })); case MODAL_CLOSE: return (action.modalType === undefined || action.modalType === state.getIn([0, 'modalType'])) ? state.shift() : state; case TIMELINE_DELETE: - return state.filterNot((modal) => modal.get('modalProps').statusId === action.id); + return state.filterNot((modal) => modal.get('modalProps').statusId === action.id); default: return state; } From 211d5c3c300b5a54b60c7b0142158144f9b0d392 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 15 Jul 2021 15:56:58 +0200 Subject: [PATCH 3/4] Fix inefficiencies in auto-linking code (#16506) The auto-linking code basically rewrote the whole string escaping non-ascii characters in an inefficient way, and building a full character offset map between the unescaped and escaped texts before sending the contents to TwitterText's extractor. Instead of doing that, this commit changes the TwitterText regexps to include valid IRI characters in addition to valid URI characters. --- app/lib/formatter.rb | 31 +--------------------------- config/initializers/twitter_regex.rb | 4 ++++ 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index fd65375262..1610f36892 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -214,39 +214,10 @@ class Formatter result.flatten.join end - UNICODE_ESCAPE_BLACKLIST_RE = /\p{Z}|\p{P}/ - def utf8_friendly_extractor(text, options = {}) - old_to_new_index = [0] - - escaped = text.chars.map do |c| - output = begin - if c.ord.to_s(16).length > 2 && !UNICODE_ESCAPE_BLACKLIST_RE.match?(c) - CGI.escape(c) - else - c - end - end - - old_to_new_index << old_to_new_index.last + output.length - - output - end.join - # Note: I couldn't obtain list_slug with @user/list-name format # for mention so this requires additional check - special = Extractor.extract_urls_with_indices(escaped, options).map do |extract| - new_indices = [ - old_to_new_index.find_index(extract[:indices].first), - old_to_new_index.find_index(extract[:indices].last), - ] - - next extract.merge( - indices: new_indices, - url: text[new_indices.first..new_indices.last - 1] - ) - end - + special = Extractor.extract_urls_with_indices(text, options) standard = Extractor.extract_entities_with_indices(text, options) extra = Extractor.extract_extra_uris_with_indices(text, options) diff --git a/config/initializers/twitter_regex.rb b/config/initializers/twitter_regex.rb index 3ff2aa9e5d..84c09ff35c 100644 --- a/config/initializers/twitter_regex.rb +++ b/config/initializers/twitter_regex.rb @@ -24,6 +24,10 @@ module Twitter::TwitterText ) \) /iox + REGEXEN[:valid_iri_ucschar] = /[\u{A0}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}]/iou + REGEXEN[:valid_iri_iprivate] = /[\u{E000}-\u{F8FF}\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}]/iou + REGEXEN[:valid_url_query_chars] = /(?:#{REGEXEN[:valid_iri_ucschar]})|(?:#{REGEXEN[:valid_iri_iprivate]})|[a-z0-9!?\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|@]/iou + REGEXEN[:valid_url_query_ending_chars] = /(?:#{REGEXEN[:valid_iri_ucschar]})|(?:#{REGEXEN[:valid_iri_iprivate]})|[a-z0-9_&=#\/\-]/iou REGEXEN[:valid_url_path] = /(?: (?: #{REGEXEN[:valid_general_url_path_chars]}* From e54a65013d200cc8407dc4d3cf6631846062f813 Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 17 Jul 2021 17:06:52 +0200 Subject: [PATCH 4/4] Fix replying from modal (#16516) Fixes #16515 Not using a router object somehow made `this.history` lag behind the real browser history whenever pushing a new history item in `replyCompose`. Not using the context-provided router in this case was an oversight made when porting glitch-soc changes in #16499. --- app/javascript/mastodon/components/modal_root.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/javascript/mastodon/components/modal_root.js b/app/javascript/mastodon/components/modal_root.js index 8c9409d014..755c46fd6b 100644 --- a/app/javascript/mastodon/components/modal_root.js +++ b/app/javascript/mastodon/components/modal_root.js @@ -6,6 +6,10 @@ import { multiply } from 'color-blend'; export default class ModalRoot extends React.PureComponent { + static contextTypes = { + router: PropTypes.object, + }; + static propTypes = { children: PropTypes.node, onClose: PropTypes.func.isRequired,