From f60a64ed43a28acec254a50789159f77d0ca2c5f Mon Sep 17 00:00:00 2001 From: Xavier B Date: Thu, 11 Apr 2024 06:35:04 -0400 Subject: [PATCH 1/2] fix(og): use fqdn for og:image --- src/pages/artist/[id].tsx | 14 ++++++++++++-- src/pages/user/[id]/[[...deeplink]].tsx | 10 +++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/pages/artist/[id].tsx b/src/pages/artist/[id].tsx index fcaffeb7..0a515026 100644 --- a/src/pages/artist/[id].tsx +++ b/src/pages/artist/[id].tsx @@ -41,6 +41,7 @@ const Genres: FC> = ({ genres }) => ( type Props = SSRProps & { artist: statsfm.Artist; + origin: string; }; export const getServerSideProps: GetServerSideProps = async (ctx) => { @@ -60,15 +61,21 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { const user = await fetchUser(ctx); + let protocol = ctx.req.headers['x-forwarded-proto'] ?? 'https'; + if (process.env.NODE_ENV === 'development') protocol = 'http'; + + const { host } = ctx.req.headers; + return { props: { artist, user, + origin: `${protocol}://${host}` ?? 'https://stats.fm', }, }; }; -const Artist: NextPage = ({ artist }) => { +const Artist: NextPage = ({ artist, origin }) => { const api = useApi(); const { user } = useAuth(); @@ -169,7 +176,10 @@ const Artist: NextPage = ({ artist }) => { <> {`${artist.name} music, stats and more`} - + = async (ctx) => { `; rel="alternate"; type="application/json+oembed"; title=""`, ); + let protocol = ctx.req.headers['x-forwarded-proto'] ?? 'https'; + if (process.env.NODE_ENV === 'development') protocol = 'http'; + + const { host } = ctx.req.headers; + return { props: { userProfile, @@ -141,6 +147,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { range: range && range.toUpperCase() in BetterRange ? range : null, year: year != null ? parseInt(year, 10) : null, }, + origin: `${protocol}://${host}` ?? 'https://stats.fm', }, }; }; @@ -151,6 +158,7 @@ const User: NextPage = ({ friendCount, scrollIntoView, selectedTimeframe: { range, year }, + origin, }) => { const api = useApi(); const router = useRouter(); @@ -353,7 +361,7 @@ const User: NextPage = ({ Date: Thu, 11 Apr 2024 07:16:37 -0400 Subject: [PATCH 2/2] chore: create helper function to get a url's origin --- .../OpenGraph/Artist/OpenGraphDefaultArtist.tsx | 10 ++-------- .../OpenGraph/User/OpenGraphDefaultUser.tsx | 10 ++-------- src/pages/api/auth/apple.ts | 12 ++++-------- src/pages/api/auth/spotify.ts | 12 ++++-------- src/pages/artist/[id].tsx | 9 ++------- src/pages/user/[id]/[[...deeplink]].tsx | 9 ++------- src/utils/ssrUtils.ts | 9 +++++++++ 7 files changed, 25 insertions(+), 46 deletions(-) diff --git a/src/components/OpenGraph/Artist/OpenGraphDefaultArtist.tsx b/src/components/OpenGraph/Artist/OpenGraphDefaultArtist.tsx index 1c1fcb47..38bbcd31 100644 --- a/src/components/OpenGraph/Artist/OpenGraphDefaultArtist.tsx +++ b/src/components/OpenGraph/Artist/OpenGraphDefaultArtist.tsx @@ -1,6 +1,7 @@ /* eslint-disable jsx-a11y/alt-text */ import { Logo } from '@/components/Logo'; import formatter from '@/utils/formatter'; +import { getOrigin } from '@/utils/ssrUtils'; import type { Artist } from '@/utils/statsfm'; import type Api from '@statsfm/statsfm.js'; import type { NextApiRequest } from 'next'; @@ -11,14 +12,7 @@ export function OpenGraphDefaultArtist( _: Api, artist: Artist, ): ReactElement> { - const protocol = - process.env.NODE_ENV === 'development' - ? 'http' - : req.headers['x-forwarded-proto'] ?? 'https'; - - const { host } = req.headers; - - const origin = `${protocol}://${host}`; + const origin = getOrigin(req); return (
diff --git a/src/components/OpenGraph/User/OpenGraphDefaultUser.tsx b/src/components/OpenGraph/User/OpenGraphDefaultUser.tsx index 966d3f3f..d737c068 100644 --- a/src/components/OpenGraph/User/OpenGraphDefaultUser.tsx +++ b/src/components/OpenGraph/User/OpenGraphDefaultUser.tsx @@ -1,6 +1,7 @@ /* eslint-disable jsx-a11y/alt-text */ import { Logo } from '@/components/Logo'; import { PlusBadgePrefilled } from '@/components/User/PlusBadge'; +import { getOrigin } from '@/utils/ssrUtils'; import { splitStringAtLength } from '@/utils/string'; import type { UserPublic } from '@statsfm/statsfm.js'; import type Api from '@statsfm/statsfm.js'; @@ -12,14 +13,7 @@ export function OpenGraphDefaultUser( _: Api, user: UserPublic, ): ReactElement> { - const protocol = - process.env.NODE_ENV === 'development' - ? 'http' - : req.headers['x-forwarded-proto'] ?? 'https'; - - const { host } = req.headers; - - const origin = `${protocol}://${host}`; + const origin = getOrigin(req); const customId = user.customId ?? user.id; diff --git a/src/pages/api/auth/apple.ts b/src/pages/api/auth/apple.ts index b50dc9f7..2641540c 100644 --- a/src/pages/api/auth/apple.ts +++ b/src/pages/api/auth/apple.ts @@ -1,17 +1,13 @@ +import { getOrigin } from '@/utils/ssrUtils'; import type { NextApiRequest, NextApiResponse } from 'next'; const handler = (req: NextApiRequest, res: NextApiResponse) => { - let protocol = req.headers['x-forwarded-proto'] ?? 'https'; - if (process.env.NODE_ENV === 'development') protocol = 'http'; + let origin = getOrigin(req); - let { host } = req.headers; - - if (host?.includes('spotistats.app')) { - host = host.replace('spotistats.app', 'stats.fm'); + if (origin.includes('spotistats.app')) { + origin = origin.replace('spotistats.app', 'stats.fm'); } - const origin = `${protocol}://${host}`; - // remove the extra httpOnly cookie which is no longer in use const cookies = [ 'identityToken=; Path=/; Domain=.stats.fm; HttpOnly=false; Expires=Thu, 01 Jan 1970 00:00:00 GMT', diff --git a/src/pages/api/auth/spotify.ts b/src/pages/api/auth/spotify.ts index cee64a8e..a8fe2ff6 100644 --- a/src/pages/api/auth/spotify.ts +++ b/src/pages/api/auth/spotify.ts @@ -1,17 +1,13 @@ +import { getOrigin } from '@/utils/ssrUtils'; import type { NextApiRequest, NextApiResponse } from 'next'; const handler = (req: NextApiRequest, res: NextApiResponse) => { - let protocol = req.headers['x-forwarded-proto'] ?? 'https'; - if (process.env.NODE_ENV === 'development') protocol = 'http'; + let origin = getOrigin(req); - let { host } = req.headers; - - if (host?.includes('spotistats.app')) { - host = host.replace('spotistats.app', 'stats.fm'); + if (origin.includes('spotistats.app')) { + origin = origin.replace('spotistats.app', 'stats.fm'); } - const origin = `${protocol}://${host}`; - // remove the extra httpOnly cookie which is no longer in use const cookies = [ 'identityToken=; Path=/; Domain=.stats.fm; HttpOnly=false; Expires=Thu, 01 Jan 1970 00:00:00 GMT', diff --git a/src/pages/artist/[id].tsx b/src/pages/artist/[id].tsx index 0a515026..cf38df16 100644 --- a/src/pages/artist/[id].tsx +++ b/src/pages/artist/[id].tsx @@ -16,7 +16,7 @@ import { StatsCardContainer } from '@/components/Stats'; import { useScrollPercentage } from '@/hooks/use-scroll-percentage'; import { event } from 'nextjs-google-analytics'; import type { SSRProps } from '@/utils/ssrUtils'; -import { fetchUser, getApiInstance } from '@/utils/ssrUtils'; +import { fetchUser, getApiInstance, getOrigin } from '@/utils/ssrUtils'; import formatter from '@/utils/formatter'; import { SpotifyLink, AppleMusicLink } from '@/components/SocialLink'; import dayjs from 'dayjs'; @@ -61,16 +61,11 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { const user = await fetchUser(ctx); - let protocol = ctx.req.headers['x-forwarded-proto'] ?? 'https'; - if (process.env.NODE_ENV === 'development') protocol = 'http'; - - const { host } = ctx.req.headers; - return { props: { artist, user, - origin: `${protocol}://${host}` ?? 'https://stats.fm', + origin: getOrigin(ctx.req), }, }; }; diff --git a/src/pages/user/[id]/[[...deeplink]].tsx b/src/pages/user/[id]/[[...deeplink]].tsx index 240063cb..fee52cf3 100644 --- a/src/pages/user/[id]/[[...deeplink]].tsx +++ b/src/pages/user/[id]/[[...deeplink]].tsx @@ -17,7 +17,7 @@ import Head from 'next/head'; import { Button } from '@/components/Button'; import clsx from 'clsx'; import type { SSRProps } from '@/utils/ssrUtils'; -import { getApiInstance, fetchUser } from '@/utils/ssrUtils'; +import { getApiInstance, fetchUser, getOrigin } from '@/utils/ssrUtils'; import { FriendStatus } from '@/utils/statsfm'; import { event } from 'nextjs-google-analytics'; import { useScrollPercentage } from '@/hooks/use-scroll-percentage'; @@ -131,11 +131,6 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { `; rel="alternate"; type="application/json+oembed"; title=""`, ); - let protocol = ctx.req.headers['x-forwarded-proto'] ?? 'https'; - if (process.env.NODE_ENV === 'development') protocol = 'http'; - - const { host } = ctx.req.headers; - return { props: { userProfile, @@ -147,7 +142,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { range: range && range.toUpperCase() in BetterRange ? range : null, year: year != null ? parseInt(year, 10) : null, }, - origin: `${protocol}://${host}` ?? 'https://stats.fm', + origin: getOrigin(ctx.req), }, }; }; diff --git a/src/utils/ssrUtils.ts b/src/utils/ssrUtils.ts index d7d27166..a06b83c9 100644 --- a/src/utils/ssrUtils.ts +++ b/src/utils/ssrUtils.ts @@ -30,3 +30,12 @@ export const fetchUser = async (ctx: any): Promise => { return user; }; + +export const getOrigin = (req: any): string => { + let protocol = req.headers['x-forwarded-proto'] ?? 'https'; + if (process.env.NODE_ENV === 'development') protocol = 'http'; + + const { host } = req.headers; + + return `${protocol}://${host}` ?? 'https://stats.fm'; +};