Skip to content

Commit

Permalink
Merge branch 'main' into link-webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
steven-tey authored Oct 14, 2024
2 parents 3ae0cdd + 4eb1698 commit 9214f8a
Show file tree
Hide file tree
Showing 26 changed files with 307 additions and 176 deletions.
2 changes: 1 addition & 1 deletion apps/web/app/[domain]/placeholder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default function PlaceholderContent() {
</motion.p>
<motion.a
variants={STAGGER_CHILD_VARIANTS}
href={createHref("/", domain, {
href={createHref("/home", domain, {
utm_source: "Custom Domain",
utm_medium: "Welcome Page",
utm_campaign: domain,
Expand Down
8 changes: 1 addition & 7 deletions apps/web/app/api/auth/account-exists/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isWhitelistedEmail } from "@/lib/edge-config";
import { DATABASE_URL, conn } from "@/lib/planetscale";
import { conn } from "@/lib/planetscale";
import { ratelimit } from "@/lib/upstash";
import { ipAddress } from "@vercel/functions";
import { NextRequest, NextResponse } from "next/server";
Expand All @@ -15,12 +15,6 @@ export async function POST(req: NextRequest) {

const { email } = (await req.json()) as { email: string };

if (!DATABASE_URL) {
return new Response("Database connection not established", {
status: 500,
});
}

if (!process.env.NEXT_PUBLIC_IS_DUB) {
return NextResponse.json({ accountExists: true, hasPassword: true });
}
Expand Down
2 changes: 2 additions & 0 deletions apps/web/app/api/domains/[domain]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const PATCH = withWorkspace(
slug: newDomain,
placeholder,
expiredUrl,
notFoundUrl,
archived,
} = updateDomainBodySchema.parse(await parseRequestBody(req));

Expand Down Expand Up @@ -88,6 +89,7 @@ export const PATCH = withWorkspace(
...(placeholder && { placeholder }),
...(workspace.plan != "free" && {
expiredUrl,
notFoundUrl,
}),
},
});
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/api/domains/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const GET = withWorkspace(
export const POST = withWorkspace(
async ({ req, workspace, session }) => {
const body = await parseRequestBody(req);
const { slug, placeholder, expiredUrl } =
const { slug, placeholder, expiredUrl, notFoundUrl } =
createDomainBodySchema.parse(body);

const totalDomains = await prisma.domain.count({
Expand Down Expand Up @@ -102,6 +102,7 @@ export const POST = withWorkspace(
...(placeholder && { placeholder }),
...(workspace.plan !== "free" && {
expiredUrl,
notFoundUrl,
}),
},
}),
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/banned/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default async function BannedPage() {
This link has been banned for violating our terms of service.
</p>
<a
href="https://dub.co"
href="https://dub.co/home"
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
Expand Down
14 changes: 7 additions & 7 deletions apps/web/app/expired/[domain]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getLinkViaEdge } from "@/lib/planetscale";
import { getDomainViaEdge } from "@/lib/planetscale/get-domain-via-edge";
import { Background, Footer, Nav, NavMobile } from "@dub/ui";
import { CircleHalfDottedClock } from "@dub/ui/src/icons";
import { constructMetadata } from "@dub/utils";
import { TimerOff } from "lucide-react";
import { redirect } from "next/navigation";

export const runtime = "edge";
Expand All @@ -13,12 +13,12 @@ export const metadata = constructMetadata({
noIndex: true,
});

export default async function ExpiredPage({
export default async function ExpiredLinkPage({
params,
}: {
params: { domain: string };
}) {
const domain = await getLinkViaEdge(params.domain, "_root");
const domain = await getDomainViaEdge(params.domain);

if (domain?.expiredUrl) {
redirect(domain.expiredUrl);
Expand All @@ -29,16 +29,16 @@ export default async function ExpiredPage({
<NavMobile />
<Nav />
<div className="z-10 mx-2 my-10 flex max-w-md flex-col items-center space-y-5 px-2.5 text-center sm:mx-auto sm:max-w-lg sm:px-0 lg:mb-16">
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-full border border-gray-300 bg-white/30">
<TimerOff className="h-6 w-6 text-gray-400" />
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-full border border-gray-300 bg-white/80">
<CircleHalfDottedClock className="h-6 w-6 text-gray-400" />
</div>
<h1 className="font-display text-5xl font-bold">Expired Link</h1>
<p className="text-lg text-gray-600">
This link has expired. Please contact the owner of this link to get a
new one.
</p>
<a
href="https://dub.co"
href="https://dub.co/home"
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
Expand Down
49 changes: 49 additions & 0 deletions apps/web/app/not-found/[domain]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { getDomainViaEdge } from "@/lib/planetscale/get-domain-via-edge";
import { Background, Footer, Nav, NavMobile } from "@dub/ui";
import { constructMetadata } from "@dub/utils";
import { redirect } from "next/navigation";

export const runtime = "edge";

export const metadata = constructMetadata({
title: "Link Not Found – Dub.co",
description:
"This link does not exist on Dub.co. Please check the URL and try again.",
noIndex: true,
});

export default async function NotFoundLinkPage({
params,
}: {
params: { domain: string };
}) {
const domain = await getDomainViaEdge(params.domain);

if (domain?.notFoundUrl) {
redirect(domain.notFoundUrl);
}

return (
<main className="flex min-h-screen flex-col justify-between">
<NavMobile />
<Nav />
<div className="z-10 mx-2 my-10 flex max-w-md flex-col items-center space-y-5 px-2.5 text-center sm:mx-auto sm:max-w-lg sm:px-0 lg:mb-16">
<div className="font-display mx-auto flex h-20 w-20 items-center justify-center rounded-full border border-gray-300 bg-white/80 text-lg font-bold text-gray-400">
404
</div>
<h1 className="font-display text-5xl font-bold">Link Not Found</h1>
<p className="text-lg text-gray-600">
This link does not exist. Please check the URL and try again.
</p>
<a
href="https://dub.co/home"
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
</a>
</div>
<Footer />
<Background />
</main>
);
}
9 changes: 3 additions & 6 deletions apps/web/lib/middleware/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,10 @@ export default async function LinkMiddleware(
const linkData = await getLinkViaEdge(domain, key);

if (!linkData) {
// short link not found, redirect to root
// short link not found, rewrite to not-found page
// TODO: log 404s (https://github.com/dubinc/dub/issues/559)
return NextResponse.redirect(new URL("/", req.url), {
headers: {
...DUB_HEADERS,
},
status: 302,
return NextResponse.rewrite(new URL(`/not-found/${domain}`, req.url), {
headers: DUB_HEADERS,
});
}

Expand Down
152 changes: 0 additions & 152 deletions apps/web/lib/planetscale.ts

This file was deleted.

12 changes: 12 additions & 0 deletions apps/web/lib/planetscale/check-if-key-exists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { punyEncode } from "@dub/utils";
import { conn } from "./connection";

export const checkIfKeyExists = async (domain: string, key: string) => {
const { rows } =
(await conn.execute(
"SELECT 1 FROM Link WHERE domain = ? AND `key` = ? LIMIT 1",
[domain, punyEncode(decodeURIComponent(key))], // we need to make sure that the key is always URI-decoded + punycode-encoded (cause that's how we store it in MySQL)
)) || {};

return rows && Array.isArray(rows) && rows.length > 0;
};
9 changes: 9 additions & 0 deletions apps/web/lib/planetscale/check-if-user-exists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { conn } from "./connection";

export const checkIfUserExists = async (userId: string) => {
const { rows } =
(await conn.execute("SELECT 1 FROM User WHERE id = ? LIMIT 1", [userId])) ||
{};

return rows && Array.isArray(rows) && rows.length > 0;
};
5 changes: 5 additions & 0 deletions apps/web/lib/planetscale/connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { connect } from "@planetscale/database";

export const conn = connect({
url: process.env.PLANETSCALE_DATABASE_URL || process.env.DATABASE_URL,
});
11 changes: 11 additions & 0 deletions apps/web/lib/planetscale/get-domain-via-edge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { conn } from "./connection";
import { EdgeDomainProps } from "./types";

export const getDomainViaEdge = async (domain: string) => {
const { rows } =
(await conn.execute("SELECT * FROM Domain WHERE slug = ?", [domain])) || {};

return rows && Array.isArray(rows) && rows.length > 0
? (rows[0] as EdgeDomainProps)
: null;
};
18 changes: 18 additions & 0 deletions apps/web/lib/planetscale/get-link-by-identifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Link } from "@prisma/client";
import { conn } from "./connection";

// Get link by workspaceId and identifier
export const getLinkByIdentifier = async (
workspaceId: string,
identifier: string,
) => {
const { rows } =
(await conn.execute(
"SELECT * FROM Link WHERE projectId = ? AND identifier = ?",
[workspaceId, identifier],
)) || {};

return rows && Array.isArray(rows) && rows.length > 0
? (rows[0] as Link)
: null;
};
Loading

0 comments on commit 9214f8a

Please sign in to comment.