From d36b45ad436fbbb027bfe6af1093107c0bfed61f Mon Sep 17 00:00:00 2001 From: rinpatch Date: Tue, 16 Nov 2021 19:49:01 +0300 Subject: [PATCH 1/2] entity_normalizer: Escape name when parsing user In January 2020 Pleroma backend stopped escaping HTML in display names and passed that responsibility on frontends, compliant with Mastodon's version of Mastodon API [1]. Pleroma-FE was subsequently modified to escape the display name [2], however only in the "name_html" field. This was fine however, since that's what the code rendering display names used. However, 2 months ago an MR [3] refactoring the way the frontend does emoji and mention rendering was merged. One of the things it did was moving away from doing emoji rendering in the entity normalizer and use the unescaped 'user.name' in the rendering code, resulting in HTML injection being possible again. This patch escapes 'user.name' as well, as far as I can tell there is no actual use for an unescaped display name in frontend code, especially when it comes from MastoAPI, where it is not supposed to be HTML. [1]: https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1052 [2]: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/2167 [3]: https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1392 --- src/components/settings_modal/tabs/profile_tab.js | 2 +- src/services/entity_normalizer/entity_normalizer.service.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index 9709424c..64079fcd 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -24,7 +24,7 @@ library.add( const ProfileTab = { data () { return { - newName: this.$store.state.users.currentUser.name, + newName: this.$store.state.users.currentUser.name_unescaped, newBio: unescape(this.$store.state.users.currentUser.description), newLocked: this.$store.state.users.currentUser.locked, newNoRichText: this.$store.state.users.currentUser.no_rich_text, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 04bb45a4..7025d803 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -55,8 +55,9 @@ export const parseUser = (data) => { } output.emoji = data.emojis - output.name = data.display_name - output.name_html = escape(data.display_name) + output.name = escape(data.display_name) + output.name_html = output.name + output.name_unescaped = data.display_name output.description = data.note // TODO cleanup this shit, output.description is overriden with source data From b4cfda4a20bdf2e5534de7f249d6a477043f75bf Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 3 Dec 2021 18:14:32 +0000 Subject: [PATCH 2/2] Simple policy reasons for instance specific policies --- .../mrf_transparency_panel.js | 51 +++++- .../mrf_transparency_panel.scss | 21 +++ .../mrf_transparency_panel.vue | 155 +++++++++++++----- src/i18n/en.json | 3 + src/i18n/nl.json | 3 + 5 files changed, 182 insertions(+), 51 deletions(-) create mode 100644 src/components/mrf_transparency_panel/mrf_transparency_panel.scss diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.js b/src/components/mrf_transparency_panel/mrf_transparency_panel.js index a0b600d2..3fde8106 100644 --- a/src/components/mrf_transparency_panel/mrf_transparency_panel.js +++ b/src/components/mrf_transparency_panel/mrf_transparency_panel.js @@ -1,17 +1,56 @@ import { mapState } from 'vuex' import { get } from 'lodash' +/** + * This is for backwards compatibility. We originally didn't recieve + * extra info like a reason why an instance was rejected/quarantined/etc. + * Because we didn't want to break backwards compatibility it was decided + * to add an extra "info" key. + */ +const toInstanceReasonObject = (instances, info, key) => { + return instances.map(instance => { + if (info[key] && info[key][instance] && info[key][instance]['reason']) { + return { instance: instance, reason: info[key][instance]['reason'] } + } + return { instance: instance, reason: '' } + }) +} + const MRFTransparencyPanel = { computed: { ...mapState({ federationPolicy: state => get(state, 'instance.federationPolicy'), mrfPolicies: state => get(state, 'instance.federationPolicy.mrf_policies', []), - quarantineInstances: state => get(state, 'instance.federationPolicy.quarantined_instances', []), - acceptInstances: state => get(state, 'instance.federationPolicy.mrf_simple.accept', []), - rejectInstances: state => get(state, 'instance.federationPolicy.mrf_simple.reject', []), - ftlRemovalInstances: state => get(state, 'instance.federationPolicy.mrf_simple.federated_timeline_removal', []), - mediaNsfwInstances: state => get(state, 'instance.federationPolicy.mrf_simple.media_nsfw', []), - mediaRemovalInstances: state => get(state, 'instance.federationPolicy.mrf_simple.media_removal', []), + quarantineInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.quarantined_instances', []), + get(state, 'instance.federationPolicy.quarantined_instances_info', []), + 'quarantined_instances' + ), + acceptInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.mrf_simple.accept', []), + get(state, 'instance.federationPolicy.mrf_simple_info', []), + 'accept' + ), + rejectInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.mrf_simple.reject', []), + get(state, 'instance.federationPolicy.mrf_simple_info', []), + 'reject' + ), + ftlRemovalInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.mrf_simple.federated_timeline_removal', []), + get(state, 'instance.federationPolicy.mrf_simple_info', []), + 'federated_timeline_removal' + ), + mediaNsfwInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.mrf_simple.media_nsfw', []), + get(state, 'instance.federationPolicy.mrf_simple_info', []), + 'media_nsfw' + ), + mediaRemovalInstances: state => toInstanceReasonObject( + get(state, 'instance.federationPolicy.mrf_simple.media_removal', []), + get(state, 'instance.federationPolicy.mrf_simple_info', []), + 'media_removal' + ), keywordsFtlRemoval: state => get(state, 'instance.federationPolicy.mrf_keyword.federated_timeline_removal', []), keywordsReject: state => get(state, 'instance.federationPolicy.mrf_keyword.reject', []), keywordsReplace: state => get(state, 'instance.federationPolicy.mrf_keyword.replace', []) diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.scss b/src/components/mrf_transparency_panel/mrf_transparency_panel.scss new file mode 100644 index 00000000..80ea01d4 --- /dev/null +++ b/src/components/mrf_transparency_panel/mrf_transparency_panel.scss @@ -0,0 +1,21 @@ +.mrf-section { + margin: 1em; + + table { + width:100%; + text-align: left; + padding-left:10px; + padding-bottom:20px; + + th, td { + width: 180px; + max-width: 360px; + overflow: hidden; + vertical-align: text-top; + } + + th+th, td+td { + width: auto; + } + } +} diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.vue b/src/components/mrf_transparency_panel/mrf_transparency_panel.vue index acdf822e..1787fa07 100644 --- a/src/components/mrf_transparency_panel/mrf_transparency_panel.vue +++ b/src/components/mrf_transparency_panel/mrf_transparency_panel.vue @@ -31,13 +31,24 @@

{{ $t("about.mrf.simple.accept_desc") }}

- + + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +
@@ -45,13 +56,24 @@

{{ $t("about.mrf.simple.reject_desc") }}

-
    -
  • -
+ + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +
@@ -59,13 +81,24 @@

{{ $t("about.mrf.simple.quarantine_desc") }}

-
    -
  • -
+ + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +
@@ -73,13 +106,24 @@

{{ $t("about.mrf.simple.ftl_removal_desc") }}

-
    -
  • -
+ + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +
@@ -87,13 +131,24 @@

{{ $t("about.mrf.simple.media_nsfw_desc") }}

-
    -
  • -
+ + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +
@@ -101,13 +156,24 @@

{{ $t("about.mrf.simple.media_removal_desc") }}

-
    -
  • -
+ + + + + + + + + + +
{{ $t("about.mrf.simple.instance") }}{{ $t("about.mrf.simple.reason") }}
{{ entry.instance }} + {{ $t("about.mrf.simple.not_applicable") }} + + {{ entry.reason }} +

@@ -161,7 +227,6 @@ diff --git a/src/i18n/en.json b/src/i18n/en.json index b31e4880..23a059c5 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -13,6 +13,9 @@ "mrf_policies_desc": "MRF policies manipulate the federation behaviour of the instance. The following policies are enabled:", "simple": { "simple_policies": "Instance-specific policies", + "instance": "Instance", + "reason": "Reason", + "not_applicable": "N/A", "accept": "Accept", "accept_desc": "This instance only accepts messages from the following instances:", "reject": "Reject", diff --git a/src/i18n/nl.json b/src/i18n/nl.json index 85794fed..c8a35bcc 100644 --- a/src/i18n/nl.json +++ b/src/i18n/nl.json @@ -670,6 +670,9 @@ "mrf_policies": "Ingeschakelde MRF-regels", "simple": { "simple_policies": "Instantiespecifieke regels", + "instance": "Instantie", + "reason": "Reden", + "not_applicable": "n.v.t.", "accept": "Accepteren", "accept_desc": "Deze instantie accepteert alleen berichten van de volgende instanties:", "reject": "Afwijzen",