From c0edac317ea6b51c0ce789963eab8c849f219a4b Mon Sep 17 00:00:00 2001 From: Mythie Date: Wed, 27 Sep 2023 07:52:24 +1000 Subject: [PATCH] fix: better share links --- .../route.tsx} | 6 ++-- .../web/src/app/(share)/share/[slug]/page.tsx | 29 +++++++++++++++---- .../src/app/(share)/share/[slug]/redirect.tsx | 11 ------- .../(signing)/sign/[token]/complete/page.tsx | 5 ++-- 4 files changed, 29 insertions(+), 22 deletions(-) rename apps/web/src/app/(share)/share/[slug]/{opengraph-image.tsx => opengraph/route.tsx} (94%) delete mode 100644 apps/web/src/app/(share)/share/[slug]/redirect.tsx diff --git a/apps/web/src/app/(share)/share/[slug]/opengraph-image.tsx b/apps/web/src/app/(share)/share/[slug]/opengraph/route.tsx similarity index 94% rename from apps/web/src/app/(share)/share/[slug]/opengraph-image.tsx rename to apps/web/src/app/(share)/share/[slug]/opengraph/route.tsx index 8751f407e..d6a2c6397 100644 --- a/apps/web/src/app/(share)/share/[slug]/opengraph-image.tsx +++ b/apps/web/src/app/(share)/share/[slug]/opengraph/route.tsx @@ -1,4 +1,4 @@ -import { ImageResponse } from 'next/server'; +import { ImageResponse, NextResponse } from 'next/server'; import { P, match } from 'ts-pattern'; @@ -21,7 +21,7 @@ type SharePageOpenGraphImageProps = { params: { slug: string }; }; -export default async function Image({ params: { slug } }: SharePageOpenGraphImageProps) { +export async function GET(_request: Request, { params: { slug } }: SharePageOpenGraphImageProps) { const [interSemiBold, interRegular, caveatRegular, shareFrameImage] = await Promise.all([ getAssetBuffer('/fonts/inter-semibold.ttf'), getAssetBuffer('/fonts/inter-regular.ttf'), @@ -32,7 +32,7 @@ export default async function Image({ params: { slug } }: SharePageOpenGraphImag const recipientOrSender = await getRecipientOrSenderByShareLinkSlug({ slug }).catch(() => null); if (!recipientOrSender) { - return null; + return NextResponse.json({ error: 'Not found' }, { status: 404 }); } const isRecipient = 'Signature' in recipientOrSender; diff --git a/apps/web/src/app/(share)/share/[slug]/page.tsx b/apps/web/src/app/(share)/share/[slug]/page.tsx index 63449f29f..2f9369f60 100644 --- a/apps/web/src/app/(share)/share/[slug]/page.tsx +++ b/apps/web/src/app/(share)/share/[slug]/page.tsx @@ -1,11 +1,30 @@ import { Metadata } from 'next'; +import { headers } from 'next/headers'; +import { redirect } from 'next/navigation'; -import { Redirect } from './redirect'; +import { APP_BASE_URL } from '@documenso/lib/constants/app'; -export const metadata: Metadata = { - title: 'Documenso - Share', +type SharePageProps = { + params: { slug: string }; }; -export default function SharePage() { - return ; +export function generateMetadata({ params: { slug } }: SharePageProps) { + return { + title: 'Documenso - Share', + description: 'I just signed a document with Documenso!', + openGraph: { + images: [`${APP_BASE_URL}/share/${slug}/opengraph`], + }, + } satisfies Metadata; +} + +export default function SharePage() { + const userAgent = headers().get('User-Agent') ?? ''; + + // https://stackoverflow.com/questions/47026171/how-to-detect-bots-for-open-graph-with-user-agent + if (/bot|facebookexternalhit|WhatsApp|google|bing|duckduckbot|MetaInspector/i.test(userAgent)) { + return null; + } + + redirect(process.env.NEXT_PUBLIC_MARKETING_URL ?? 'http://localhost:3001'); } diff --git a/apps/web/src/app/(share)/share/[slug]/redirect.tsx b/apps/web/src/app/(share)/share/[slug]/redirect.tsx deleted file mode 100644 index 5b3af0771..000000000 --- a/apps/web/src/app/(share)/share/[slug]/redirect.tsx +++ /dev/null @@ -1,11 +0,0 @@ -'use client'; - -import { useEffect } from 'react'; - -export const Redirect = () => { - useEffect(() => { - window.location.href = process.env.NEXT_PUBLIC_MARKETING_URL ?? 'http://localhost:3001'; - }, []); - - return null; -}; diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx index 0828bac40..e87b2fced 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx @@ -9,8 +9,7 @@ import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-f import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token'; import { DocumentStatus, FieldType } from '@documenso/prisma/client'; import { DocumentDownloadButton } from '@documenso/ui/components/document/document-download-button'; -import { SigningCard } from '@documenso/ui/components/signing-card'; -import { Button } from '@documenso/ui/primitives/button'; +import { SigningCard3D } from '@documenso/ui/components/signing-card'; import signingCelebration from '~/assets/signing-celebration.png'; @@ -54,7 +53,7 @@ export default async function CompletedSigningPage({ return (
{/* Card with recipient */} - +
{match(document.status)