🐛 Fix og image url failing validation (#1403)

This commit is contained in:
Luke Vella 2024-10-20 11:37:28 +01:00 committed by GitHub
parent 304976aee4
commit ec2643a8ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 22 deletions

View file

@ -1,5 +1,6 @@
import { prisma } from "@rallly/database";
import { Metadata } from "next";
import { notFound } from "next/navigation";
import { InvitePage } from "@/app/[locale]/invite/[urlId]/invite-page";
import { getTranslation } from "@/app/i18n";
@ -35,12 +36,22 @@ export async function generateMetadata({
const { t } = await getTranslation(locale);
if (!poll) {
return null;
notFound();
}
const { title, id, user } = poll;
const author = user?.name || t("guest");
const author =
user?.name ||
t("guest", {
ns: "app",
defaultValue: "Guest",
});
const ogImageUrl = absoluteUrl("/api/og-image-poll", {
title,
author,
});
return {
title,
@ -51,10 +62,7 @@ export async function generateMetadata({
url: `/invite/${id}`,
images: [
{
url: `${absoluteUrl("/api/og-image-poll", {
title,
author,
})}`,
url: ogImageUrl,
width: 1200,
height: 630,
alt: title,

View file

@ -0,0 +1,53 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { absoluteUrl } from "./absolute-url";
describe("absoluteUrl", () => {
describe("when NEXT_PUBLIC_BASE_URL is set", () => {
beforeAll(() => {
process.env.NEXT_PUBLIC_BASE_URL = "https://example.com";
});
afterAll(() => {
delete process.env.NEXT_PUBLIC_BASE_URL;
});
it("should return the value of NEXT_PUBLIC_BASE_URL", () => {
expect(absoluteUrl()).toBe("https://example.com");
});
it("should return the correct absolute URL with query params", () => {
expect(absoluteUrl("/", { test: "test" })).toBe(
"https://example.com/?test=test",
);
});
it("should return the correct absolute URL with a subpath and query params", () => {
expect(absoluteUrl("/test", { test: "test" })).toBe(
"https://example.com/test?test=test",
);
});
});
describe("when NEXT_PUBLIC_BASE_URL is not set", () => {
it("should return the correct absolute URL with a subpath and query params", () => {
expect(absoluteUrl("/test", { test: "test" })).toBe(
"http://localhost:3000/test?test=test",
);
});
describe("when NEXT_PUBLIC_VERCEL_URL is set", () => {
beforeAll(() => {
process.env.NEXT_PUBLIC_VERCEL_URL = "example.vercel.com";
});
afterAll(() => {
delete process.env.NEXT_PUBLIC_VERCEL_URL;
});
it("should return the correct absolute URL with a subpath and query params", () => {
expect(absoluteUrl("/test", { test: "test" })).toBe(
"https://example.vercel.com/test?test=test",
);
});
});
});
});

View file

@ -15,27 +15,21 @@ function joinPath(baseUrl: string, subpath = "") {
return baseUrl;
}
export function objectToQueryString(obj: Record<string, string>) {
const parts = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (value !== undefined) {
parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
}
}
}
return parts.join("&");
}
export function absoluteUrl(subpath = "", query?: Record<string, string>) {
const queryString = query ? `?${objectToQueryString(query)}` : "";
export function absoluteUrl(subpath = "", query: Record<string, string> = {}) {
const baseUrl =
process.env.NEXT_PUBLIC_BASE_URL ??
getVercelUrl() ??
`http://localhost:${port}`;
return joinPath(baseUrl, subpath) + queryString;
const url = new URL(subpath, baseUrl);
Object.entries(query).forEach(([key, value]) => {
url.searchParams.set(key, value);
});
const urlString = url.href;
return urlString.endsWith("/") ? urlString.slice(0, -1) : urlString;
}
export function shortUrl(subpath = "") {