Merge branch 'xss-fixes' into 'main'
Security and docker fixes See merge request framasoft/mobilizon!1500
This commit is contained in:
@@ -347,7 +347,7 @@ const asyncData = async (query: string): Promise<void> => {
|
||||
|
||||
const result =
|
||||
(await searchAddressLoad(undefined, queryVars)) ||
|
||||
(await searchAddressRefetch(queryVars))?.data
|
||||
(await searchAddressRefetch(queryVars))?.data;
|
||||
|
||||
if (!result) {
|
||||
isFetching.value = false;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<div
|
||||
class="mb-2 line-clamp-3"
|
||||
dir="auto"
|
||||
v-html="saneSummary"
|
||||
v-html="group.summary"
|
||||
v-if="showSummary"
|
||||
/>
|
||||
<div>
|
||||
@@ -91,7 +91,6 @@ import { addressFullName } from "@/types/address.model";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import AccountGroup from "vue-material-design-icons/AccountGroup.vue";
|
||||
import Account from "vue-material-design-icons/Account.vue";
|
||||
import { htmlToText } from "@/utils/html";
|
||||
import { computed } from "vue";
|
||||
import LinkOrRouterLink from "../core/LinkOrRouterLink.vue";
|
||||
|
||||
@@ -108,8 +107,6 @@ const props = withDefaults(
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const saneSummary = computed(() => htmlToText(props.group.summary ?? ""));
|
||||
|
||||
const isInternal = computed(() => {
|
||||
return props.isRemoteGroup && props.isLoggedIn === false;
|
||||
});
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-3 prose dark:prose-invert lg:prose-xl line-clamp-2"
|
||||
class="mt-3 prose dark:prose-invert lg:prose-xl prose-p:m-0 line-clamp-2"
|
||||
v-if="member.parent.summary"
|
||||
v-html="htmlToText(member.parent.summary)"
|
||||
v-html="member.parent.summary"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -95,7 +95,6 @@ import DotsHorizontal from "vue-material-design-icons/DotsHorizontal.vue";
|
||||
import AccountGroup from "vue-material-design-icons/AccountGroup.vue";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import { htmlToText } from "@/utils/html";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
defineProps<{
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
{{ t("Reported by an unknown actor") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="" v-if="report.content" v-html="report.content" />
|
||||
<div class="line-clamp-1" v-if="report.content">
|
||||
{{ report.content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import nl2br from "@/filters/utils";
|
||||
import {
|
||||
formatDateString,
|
||||
formatTimeString,
|
||||
@@ -11,6 +10,5 @@ export default {
|
||||
vue.filter("formatDateString", formatDateString);
|
||||
vue.filter("formatTimeString", formatTimeString);
|
||||
vue.filter("formatDateTimeString", formatDateTimeString);
|
||||
vue.filter("nl2br", nl2br);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* New Line to <br>
|
||||
*
|
||||
* @param {string} str Input text
|
||||
* @return {string} Filtered text
|
||||
*/
|
||||
export default function nl2br(str: string): string {
|
||||
return `${str}`.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, "$1<br>");
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { i18n } from "@/utils/i18n";
|
||||
const t = i18n.global.t;
|
||||
|
||||
export enum ConversationRouteName {
|
||||
CONVERSATION_LIST = "DISCUSSION_LIST",
|
||||
CONVERSATION_LIST = "CONVERSATION_LIST",
|
||||
CONVERSATION = "CONVERSATION",
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
export function nl2br(text: string): string {
|
||||
return text.replace(/(?:\r\n|\r|\n)/g, "<br>");
|
||||
}
|
||||
|
||||
export function htmlToText(html: string) {
|
||||
const template = document.createElement("template");
|
||||
const trimmedHTML = html.trim();
|
||||
template.innerHTML = trimmedHTML;
|
||||
const text = template.content.textContent;
|
||||
template.remove();
|
||||
return text;
|
||||
}
|
||||
|
||||
export const getValueFromMeta = (name: string): string | null => {
|
||||
const element = document.querySelector(`meta[name="${name}"]`);
|
||||
if (element && element.getAttribute("content")) {
|
||||
|
||||
@@ -613,8 +613,8 @@ const organizerDomain = computed((): string | undefined => {
|
||||
});
|
||||
|
||||
const nonPassedRelatedEvents = computed((): IEvent[] | undefined => {
|
||||
let relatedEvents = event.value?.relatedEvents;
|
||||
|
||||
const relatedEvents = event.value?.relatedEvents;
|
||||
|
||||
return relatedEvents?.filter((relatedEvent: IEvent) => {
|
||||
const endsOn = relatedEvent.endsOn
|
||||
? new Date(relatedEvent.endsOn)
|
||||
|
||||
@@ -189,16 +189,15 @@
|
||||
<p v-else>
|
||||
{{ props.row.metadata.message }}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
class="button is-text"
|
||||
<o-button
|
||||
variant="primary"
|
||||
v-if="props.row.metadata.message.length > MESSAGE_ELLIPSIS_LENGTH"
|
||||
@click.stop="toggleQueueDetails(props.row)"
|
||||
>
|
||||
{{
|
||||
openDetailedRows[props.row.id] ? t("View less") : t("View more")
|
||||
}}
|
||||
</button>
|
||||
</o-button>
|
||||
</div>
|
||||
<p v-else class="has-text-grey-dark">
|
||||
{{ t("No message") }}
|
||||
@@ -212,7 +211,9 @@
|
||||
</span>
|
||||
</o-table-column>
|
||||
<template #detail="props">
|
||||
<article v-html="nl2br(props.row.metadata.message)" />
|
||||
<p>
|
||||
{{ props.row.metadata.message }}
|
||||
</p>
|
||||
</template>
|
||||
<template #empty>
|
||||
<EmptyContent icon="account-circle" :inline="true">
|
||||
@@ -265,7 +266,6 @@ import {
|
||||
UPDATE_PARTICIPANT,
|
||||
} from "@/graphql/event";
|
||||
import { usernameWithDomain } from "@/types/actor";
|
||||
import { nl2br } from "@/utils/html";
|
||||
import { asyncForEach } from "@/utils/asyncForEach";
|
||||
import RouteName from "@/router/name";
|
||||
import { useCurrentActorClient } from "@/composition/apollo/actor";
|
||||
|
||||
@@ -261,7 +261,7 @@ const copyURL = async (): Promise<void> => {
|
||||
|
||||
onGroupResult(async ({ data }) => {
|
||||
if (!data) return;
|
||||
editableGroup.value = data.group;
|
||||
editableGroup.value = { ...data.group };
|
||||
try {
|
||||
avatarFile.value = await buildFileFromIMedia(editableGroup.value?.avatar);
|
||||
bannerFile.value = await buildFileFromIMedia(editableGroup.value?.banner);
|
||||
|
||||
@@ -216,11 +216,9 @@
|
||||
</div>
|
||||
<p v-else>{{ t("Unknown actor") }}</p>
|
||||
</div>
|
||||
<div
|
||||
class="prose dark:prose-invert"
|
||||
v-if="report.content"
|
||||
v-html="nl2br(report.content)"
|
||||
/>
|
||||
<div class="prose dark:prose-invert" v-if="report.content">
|
||||
{{ report.content }}
|
||||
</div>
|
||||
<p v-else>{{ t("No comment") }}</p>
|
||||
</div>
|
||||
</section>
|
||||
@@ -407,7 +405,6 @@ import {
|
||||
} from "@/types/actor";
|
||||
import { DELETE_EVENT } from "@/graphql/event";
|
||||
import uniq from "lodash/uniq";
|
||||
import { nl2br } from "@/utils/html";
|
||||
import { DELETE_COMMENT } from "@/graphql/comment";
|
||||
import { IComment } from "@/types/comment.model";
|
||||
import { ActorType, AntiSpamFeedback, ReportStatusEnum } from "@/types/enums";
|
||||
|
||||
Reference in New Issue
Block a user