Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/wallet-ui/src/app/[ecosystem]/(authed)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async function Layout(props: {

const { children } = props;

await authedOnly();
await authedOnly(params.ecosystem);
const ecosystem = await getEcosystemInfo(params.ecosystem);
return (
<div className="flex w-full flex-col items-stretch">
Expand Down
6 changes: 4 additions & 2 deletions apps/wallet-ui/src/app/[ecosystem]/login/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { getCurrentUser } from "../../../lib/auth";

export default async function Layout({
children,
}: { children: React.ReactNode }) {
params,
}: { children: React.ReactNode; params: Promise<{ ecosystem: string }> }) {
const { ecosystem } = await params;
const userAddress = await getCurrentUser();
if (userAddress) {
redirect(`/wallet/${userAddress}`);
redirect(`${ecosystem}/wallet/${userAddress}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The redirect path is missing a leading forward slash, which could cause navigation issues. The correct path should be:

redirect(`/${ecosystem}/wallet/${userAddress}`)

Spotted by Graphite Reviewer

Is this helpful? React 👍 or 👎 to let us know.

}

return (
Expand Down
13 changes: 8 additions & 5 deletions apps/wallet-ui/src/app/[ecosystem]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { getCurrentUser } from "@/lib/auth";
import { redirect } from "next/navigation";

export default async function Page() {
const user = await getCurrentUser();
if (user) {
redirect("/wallet/${user}");
export default async function Page({
params,
}: { params: Promise<{ ecosystem: string }> }) {
const { ecosystem } = await params;
const address = await getCurrentUser();
if (address) {
redirect(`${ecosystem}/wallet/${address}`);
}
redirect("/login");
redirect(`${ecosystem}/login`);
}
12 changes: 7 additions & 5 deletions apps/wallet-ui/src/app/[ecosystem]/wc/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import { redirect } from "next/navigation";

export default async function Page(props: {
searchParams: Promise<{ uri: string }>;
params: Promise<{ ecosystem: string }>;
}) {
const searchParams = await props.searchParams;

const { uri } = searchParams;
const [{ uri }, { ecosystem }] = await Promise.all([
props.searchParams,
props.params,
]);

const currentUser = await getCurrentUser();

if (!currentUser) {
redirect(`/login?uri=${encodeURIComponent(uri)}`);
redirect(`${ecosystem}/login?uri=${encodeURIComponent(uri)}`);
}

redirect(`/wallet/${currentUser}?uri=${encodeURIComponent(uri)}`);
redirect(`${ecosystem}/wallet/${currentUser}?uri=${encodeURIComponent(uri)}`);
}
4 changes: 4 additions & 0 deletions apps/wallet-ui/src/components/ConnectButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import { logout } from "@/lib/auth";
import { client } from "@/lib/client";
import { useTheme } from "next-themes";
import {
Expand All @@ -23,6 +24,9 @@ export default function ConnectButton({
wallets={[ecosystemWallet(ecosystem)]}
client={client}
theme={theme === "light" ? "light" : "dark"}
onDisconnect={() => {
logout();
}}
/>
);
}
2 changes: 1 addition & 1 deletion apps/wallet-ui/src/components/ConnectEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function ConnectEmbed() {
const success = await login(loginParams);
if (success) {
router.push(
`/wallet/${loginParams.payload.address}?${searchParams.toString()}`,
`/${params.ecosystem}/wallet/${loginParams.payload.address}?${searchParams.toString()}`,
);
}
},
Expand Down
9 changes: 6 additions & 3 deletions apps/wallet-ui/src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,23 @@ export async function login(payload: VerifyLoginPayloadParams) {
secure: process.env.NODE_ENV !== "development",
sameSite: "strict",
maxAge: 3600,
domain: process.env.NEXT_PUBLIC_ROOT_DOMAIN,
domain:
process.env.NODE_ENV === "development"
? "localhost"
: process.env.NEXT_PUBLIC_ROOT_DOMAIN,
path: "/",
});
return true;
}
return false;
}

export async function authedOnly() {
export async function authedOnly(ecosystem?: string) {
const loggedIn = await getCurrentUser();
if (loggedIn) {
return;
}
redirect("/login");
redirect(`/${ecosystem || ""}/login`);
}

export async function isLoggedIn(): Promise<boolean> {
Expand Down
45 changes: 17 additions & 28 deletions apps/wallet-ui/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
import { type NextRequest, NextResponse } from "next/server";

export const config = {
matcher: [
/*
* Match all paths except for:
* 1. /api routes
* 2. /_next (Next.js internals)
* 3. /_static (inside /public)
* 4. all root files inside /public (e.g. /favicon.ico)
*/
"/((?!api/|_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)",
],
};
export const config = { matcher: "/((?!.*\\.).*)" };

const ROOT_DOMAIN = process.env.NEXT_PUBLIC_ROOT_DOMAIN;
export default async function middleware(req: NextRequest) {
// Get the request hostname (e.g. demo.thirdweb.com)
const hostname = req.headers.get("host");
export function middleware(request: NextRequest) {
const url = request.nextUrl;
const hostname = request.headers.get("host") || "";

const searchParams = req.nextUrl.searchParams.toString();
const url = req.nextUrl;
const path = `${url.pathname}${
searchParams.length > 0 ? `?${searchParams}` : ""
}`;
// Match pattern: something.ecosystem.domain.tld
const match = hostname.match(/^([^.]+)\.ecosystem\.([^.]+\.[^.]+)$/);

// keep root application at `/`
if (hostname === ROOT_DOMAIN || hostname === null) {
return NextResponse.next();
}
if (match) {
const [_, subdomain, primaryDomain] = match;

// Redirect to ecosystem.domain.tld/subdomain
const newUrl = new URL(`${url.protocol}//ecosystem.${primaryDomain}`);
newUrl.pathname = `/${subdomain}${url.pathname}`;
newUrl.search = url.search;

// rewrite everything else to `/[ecosystem]/... dynamic route
const ecosystem = hostname.split(".")[0];
// 308 is permanent redirect, preserves request method
return NextResponse.redirect(newUrl, 308);
}

return NextResponse.rewrite(new URL(`/${ecosystem}${path}`, req.url));
return NextResponse.next();
}