fix: strip markdown from meta description tag in users page (#8769)
* fix: remove markdown validation * feat: use markdown stripped bio * fix: use remove markdown * fix: type errors --------- Co-authored-by: alannnc <alannnc@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>pull/8892/head^2
parent
0ca0cc3265
commit
959488910f
|
@ -115,12 +115,11 @@
|
||||||
"react-select": "^5.7.0",
|
"react-select": "^5.7.0",
|
||||||
"react-timezone-select": "^1.4.0",
|
"react-timezone-select": "^1.4.0",
|
||||||
"react-use-intercom": "1.5.1",
|
"react-use-intercom": "1.5.1",
|
||||||
"remark": "^14.0.2",
|
"remove-markdown": "^0.5.0",
|
||||||
"rrule": "^2.7.1",
|
"rrule": "^2.7.1",
|
||||||
"sanitize-html": "^2.10.0",
|
"sanitize-html": "^2.10.0",
|
||||||
"schema-dts": "^1.1.0",
|
"schema-dts": "^1.1.0",
|
||||||
"short-uuid": "^4.2.0",
|
"short-uuid": "^4.2.0",
|
||||||
"strip-markdown": "^5.0.0",
|
|
||||||
"stripe": "^9.16.0",
|
"stripe": "^9.16.0",
|
||||||
"superjson": "1.9.1",
|
"superjson": "1.9.1",
|
||||||
"tailwindcss-radix": "^2.6.0",
|
"tailwindcss-radix": "^2.6.0",
|
||||||
|
@ -153,6 +152,7 @@
|
||||||
"@types/qrcode": "^1.4.3",
|
"@types/qrcode": "^1.4.3",
|
||||||
"@types/react": "18.0.26",
|
"@types/react": "18.0.26",
|
||||||
"@types/react-phone-number-input": "^3.0.14",
|
"@types/react-phone-number-input": "^3.0.14",
|
||||||
|
"@types/remove-markdown": "^0.3.1",
|
||||||
"@types/sanitize-html": "^2.9.0",
|
"@types/sanitize-html": "^2.9.0",
|
||||||
"@types/stripe": "^8.0.417",
|
"@types/stripe": "^8.0.417",
|
||||||
"@types/uuid": "8.3.1",
|
"@types/uuid": "8.3.1",
|
||||||
|
|
|
@ -23,6 +23,7 @@ import defaultEvents, {
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import useTheme from "@calcom/lib/hooks/useTheme";
|
import useTheme from "@calcom/lib/hooks/useTheme";
|
||||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||||
|
import { stripMarkdown } from "@calcom/lib/stripMarkdown";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { baseEventTypeSelect } from "@calcom/prisma/selects";
|
import { baseEventTypeSelect } from "@calcom/prisma/selects";
|
||||||
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||||
|
@ -37,7 +38,16 @@ import PageWrapper from "@components/PageWrapper";
|
||||||
import { ssrInit } from "@server/lib/ssr";
|
import { ssrInit } from "@server/lib/ssr";
|
||||||
|
|
||||||
export default function User(props: inferSSRProps<typeof getServerSideProps> & EmbedProps) {
|
export default function User(props: inferSSRProps<typeof getServerSideProps> & EmbedProps) {
|
||||||
const { users, profile, eventTypes, isDynamicGroup, dynamicNames, dynamicUsernames, isSingleUser } = props;
|
const {
|
||||||
|
users,
|
||||||
|
profile,
|
||||||
|
eventTypes,
|
||||||
|
isDynamicGroup,
|
||||||
|
dynamicNames,
|
||||||
|
dynamicUsernames,
|
||||||
|
isSingleUser,
|
||||||
|
markdownStrippedBio,
|
||||||
|
} = props;
|
||||||
const [user] = users; //To be used when we only have a single user, not dynamic group
|
const [user] = users; //To be used when we only have a single user, not dynamic group
|
||||||
useTheme(user.theme);
|
useTheme(user.theme);
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
|
@ -107,11 +117,9 @@ export default function User(props: inferSSRProps<typeof getServerSideProps> & E
|
||||||
<>
|
<>
|
||||||
<HeadSeo
|
<HeadSeo
|
||||||
title={isDynamicGroup ? dynamicNames.join(", ") : nameOrUsername}
|
title={isDynamicGroup ? dynamicNames.join(", ") : nameOrUsername}
|
||||||
description={
|
description={isDynamicGroup ? `Book events with ${dynamicUsernames.join(", ")}` : markdownStrippedBio}
|
||||||
isDynamicGroup ? `Book events with ${dynamicUsernames.join(", ")}` : (user.bio as string) || ""
|
|
||||||
}
|
|
||||||
meeting={{
|
meeting={{
|
||||||
title: isDynamicGroup ? "" : `${user.bio}`,
|
title: isDynamicGroup ? "" : markdownStrippedBio,
|
||||||
profile: { name: `${profile.name}`, image: null },
|
profile: { name: `${profile.name}`, image: null },
|
||||||
users: isDynamicGroup
|
users: isDynamicGroup
|
||||||
? dynamicUsernames.map((username, index) => ({ username, name: dynamicNames[index] }))
|
? dynamicUsernames.map((username, index) => ({ username, name: dynamicNames[index] }))
|
||||||
|
@ -342,6 +350,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||||
|
|
||||||
const safeBio = markdownToSafeHTML(user.bio) || "";
|
const safeBio = markdownToSafeHTML(user.bio) || "";
|
||||||
|
|
||||||
|
const markdownStrippedBio = stripMarkdown(user?.bio || "");
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
users,
|
users,
|
||||||
|
@ -361,6 +370,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||||
dynamicNames,
|
dynamicNames,
|
||||||
dynamicUsernames,
|
dynamicUsernames,
|
||||||
isSingleUser,
|
isSingleUser,
|
||||||
|
markdownStrippedBio,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@ import type { SatoriOptions } from "satori";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { Meeting, App, Generic } from "@calcom/lib/OgImages";
|
import { Meeting, App, Generic } from "@calcom/lib/OgImages";
|
||||||
import { md } from "@calcom/lib/markdownIt";
|
|
||||||
|
|
||||||
const calFont = fetch(new URL("../../../../public/fonts/cal.ttf", import.meta.url)).then((res) =>
|
const calFont = fetch(new URL("../../../../public/fonts/cal.ttf", import.meta.url)).then((res) =>
|
||||||
res.arrayBuffer()
|
res.arrayBuffer()
|
||||||
|
@ -75,12 +74,10 @@ export default async function handler(req: NextApiRequest) {
|
||||||
imageType,
|
imageType,
|
||||||
});
|
});
|
||||||
|
|
||||||
const title_ = md.render(title).replace(/(<([^>]+)>)/gi, "");
|
|
||||||
|
|
||||||
const img = new ImageResponse(
|
const img = new ImageResponse(
|
||||||
(
|
(
|
||||||
<Meeting
|
<Meeting
|
||||||
title={title_}
|
title={title}
|
||||||
profile={{ name: meetingProfileName, image: meetingImage }}
|
profile={{ name: meetingProfileName, image: meetingImage }}
|
||||||
users={names.map((name, index) => ({ name, username: usernames[index] }))}
|
users={names.map((name, index) => ({ name, username: usernames[index] }))}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import useTheme from "@calcom/lib/hooks/useTheme";
|
import useTheme from "@calcom/lib/hooks/useTheme";
|
||||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||||
import { getTeamWithMembers } from "@calcom/lib/server/queries/teams";
|
import { getTeamWithMembers } from "@calcom/lib/server/queries/teams";
|
||||||
|
import { stripMarkdown } from "@calcom/lib/stripMarkdown";
|
||||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { Avatar, AvatarGroup, Button, EmptyScreen, HeadSeo } from "@calcom/ui";
|
import { Avatar, AvatarGroup, Button, EmptyScreen, HeadSeo } from "@calcom/ui";
|
||||||
|
@ -26,7 +27,7 @@ import Team from "@components/team/screens/Team";
|
||||||
import { ssrInit } from "@server/lib/ssr";
|
import { ssrInit } from "@server/lib/ssr";
|
||||||
|
|
||||||
export type TeamPageProps = inferSSRProps<typeof getServerSideProps>;
|
export type TeamPageProps = inferSSRProps<typeof getServerSideProps>;
|
||||||
function TeamPage({ team, isUnpublished }: TeamPageProps) {
|
function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
|
||||||
useTheme(team.theme);
|
useTheme(team.theme);
|
||||||
const showMembers = useToggleQuery("members");
|
const showMembers = useToggleQuery("members");
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
|
@ -105,7 +106,7 @@ function TeamPage({ team, isUnpublished }: TeamPageProps) {
|
||||||
title={teamName}
|
title={teamName}
|
||||||
description={teamName}
|
description={teamName}
|
||||||
meeting={{
|
meeting={{
|
||||||
title: team?.bio || "",
|
title: markdownStrippedBio,
|
||||||
profile: { name: `${team.name}`, image: getPlaceholderAvatar(team.logo, team.name) },
|
profile: { name: `${team.name}`, image: getPlaceholderAvatar(team.logo, team.name) },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -201,10 +202,13 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||||
return { ...member, safeBio: markdownToSafeHTML(member.bio || "") };
|
return { ...member, safeBio: markdownToSafeHTML(member.bio || "") };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const markdownStrippedBio = stripMarkdown(team?.bio || "");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
team: { ...team, safeBio, members },
|
team: { ...team, safeBio, members },
|
||||||
trpcState: ssr.dehydrate(),
|
trpcState: ssr.dehydrate(),
|
||||||
|
markdownStrippedBio,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import removeMd from "remove-markdown";
|
||||||
|
|
||||||
|
export function stripMarkdown(md: string) {
|
||||||
|
return removeMd(md);
|
||||||
|
}
|
Loading…
Reference in New Issue