From ac6ac14a230267bd81600edae7466532bf8b7674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Thu, 22 Feb 2024 00:25:31 -0700 Subject: [PATCH] fix: more og avatar fixes (#13817) --- .../features/eventtypes/lib/getPublicEvent.ts | 33 ++++++++++++++++--- packages/lib/OgImages.tsx | 4 ++- packages/lib/constants.ts | 2 +- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/features/eventtypes/lib/getPublicEvent.ts b/packages/features/eventtypes/lib/getPublicEvent.ts index 5878b3db6d..44726c0650 100644 --- a/packages/features/eventtypes/lib/getPublicEvent.ts +++ b/packages/features/eventtypes/lib/getPublicEvent.ts @@ -25,7 +25,7 @@ import { } from "@calcom/prisma/zod-utils"; import type { UserProfile } from "@calcom/types/UserProfile"; -const userSelect = { +const userSelect = Prisma.validator()({ id: true, avatarUrl: true, username: true, @@ -35,7 +35,15 @@ const userSelect = { darkBrandColor: true, theme: true, metadata: true, -}; + organization: { + select: { + id: true, + name: true, + slug: true, + calVideoLogo: true, + }, + }, +}); const publicEventSelect = Prisma.validator()({ id: true, @@ -283,12 +291,12 @@ type Event = Prisma.EventTypeGetPayload; function getProfileFromEvent(event: Event) { const { team, hosts, owner } = event; - const profile = team || hosts?.[0]?.user || owner; + const nonTeamprofile = hosts?.[0]?.user || owner; + const profile = team || nonTeamprofile; if (!profile) throw new Error("Event has no owner"); const username = "username" in profile ? profile.username : team?.slug; const weekStart = hosts?.[0]?.user?.weekStart || owner?.weekStart || "Monday"; - const basePath = team ? `/team/${username}` : `/${username}`; const eventMetaData = EventTypeMetaDataSchema.parse(event.metadata || {}); const userMetaData = userMetadataSchema.parse(profile.metadata || {}); @@ -296,7 +304,22 @@ function getProfileFromEvent(event: Event) { username, name: profile.name, weekStart, - image: team ? undefined : `${basePath}/avatar.png`, + image: team + ? undefined + : // TODO: There must be a better way to do this, maybe a prisma middleware? + // This should come pre-proccessed from the database IMO instead of replacing everywhere + getUserAvatarUrl({ + username: username || "", + profile: { + id: nonTeamprofile?.id || null, + username: username || null, + organizationId: nonTeamprofile?.organization?.id || null, + organization: nonTeamprofile?.organization + ? { ...nonTeamprofile?.organization, requestedSlug: null } + : null, + }, + avatarUrl: nonTeamprofile?.avatarUrl, + }), logo: !team ? undefined : team.logo, brandColor: profile.brandColor, darkBrandColor: profile.darkBrandColor, diff --git a/packages/lib/OgImages.tsx b/packages/lib/OgImages.tsx index 88f562be4b..6c4e45dca1 100644 --- a/packages/lib/OgImages.tsx +++ b/packages/lib/OgImages.tsx @@ -46,6 +46,8 @@ const joinMultipleNames = (names: string[] = []) => { return `${names.length > 0 ? `${names.join(", ")} & ${lastName}` : lastName}`; }; +const makeAbsoluteUrl = (url: string) => (/^https?:\/\//.test(url) ? url : `${CAL_URL}${url}`); + /** * Test urls: * 1. 1 user http://localhost:3000/api/social/og/image?type=meeting&title=super%20long%20event%20title%20for%20testing%20purposes&meetingProfileName=Pro%20Example&meetingImage=http://localhost:3000/pro/avatar.png&names=Pro%20Example&usernames=pro @@ -62,7 +64,7 @@ export const constructMeetingImage = ( `?type=meeting`, `&title=${encodeURIComponent(title)}`, `&meetingProfileName=${encodeURIComponent(profile.name)}`, - profile.image && `&meetingImage=${encodeURIComponent(profile.image)}`, + profile.image && `&meetingImage=${encodeURIComponent(makeAbsoluteUrl(profile.image))}`, `${users.map((user) => `&names=${encodeURIComponent(user.name)}`).join("")}`, `${users.map((user) => `&usernames=${encodeURIComponent(user.username)}`).join("")}`, // Joining a multiline string for readability. diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts index 4b90e3dc68..ecfbce9790 100644 --- a/packages/lib/constants.ts +++ b/packages/lib/constants.ts @@ -83,7 +83,7 @@ export const SEO_IMG_DEFAULT = `${CAL_URL}/og-image.png`; // parameters you pass to the /api/social/og/image endpoint, you wrap them in encodeURIComponent // as well, otherwise the URL won't be valid. export const SEO_IMG_OGIMG = `${CAL_URL}/_next/image?w=1200&q=100&url=${encodeURIComponent( - "/api/social/og/image" + `${CAL_URL}/api/social/og/image` )}`; export const SEO_IMG_OGIMG_VIDEO = `${CAL_URL}/video-og-image.png`; export const IS_STRIPE_ENABLED = !!(