Redesign marketing pages and isolate public routes from app auth.
Give the landing, legal, and sign-in flows a consistent product shell while keeping marketing pages free of tRPC/session calls, fixing dev auth URL handling, and refreshing env and deploy docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+11
-4
@@ -3,10 +3,17 @@
|
||||
import { createAuthClient } from "better-auth/react";
|
||||
import { genericOAuthClient } from "better-auth/client/plugins";
|
||||
|
||||
/**
|
||||
* Auth client configuration
|
||||
*/
|
||||
function resolveAuthBaseUrl(): string | undefined {
|
||||
// Always use the current origin in the browser so dev works on any port
|
||||
// (e.g. 3002 when 3000 is taken), without rebuilding for NEXT_PUBLIC_APP_URL.
|
||||
if (typeof window !== "undefined") {
|
||||
return window.location.origin;
|
||||
}
|
||||
|
||||
return process.env.NEXT_PUBLIC_APP_URL;
|
||||
}
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: process.env.NEXT_PUBLIC_APP_URL,
|
||||
baseURL: resolveAuthBaseUrl(),
|
||||
plugins: [genericOAuthClient()],
|
||||
});
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { headers as nextHeaders } from "next/headers";
|
||||
import { auth } from "~/lib/auth";
|
||||
|
||||
export function hasSessionCookie(headers: Headers): boolean {
|
||||
const cookie = headers.get("cookie") ?? "";
|
||||
return (
|
||||
cookie.includes("better-auth.session_token=") ||
|
||||
cookie.includes("__Secure-better-auth.session_token=")
|
||||
);
|
||||
}
|
||||
|
||||
export async function getOptionalServerSession(headers: Headers) {
|
||||
if (!hasSessionCookie(headers)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return await auth.api.getSession({ headers });
|
||||
} catch (error) {
|
||||
console.error("[auth] Failed to resolve session:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOptionalServerSessionFromHeaders() {
|
||||
return getOptionalServerSession(await nextHeaders());
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/** Routes that do not require authentication or server session lookups. */
|
||||
export const PUBLIC_ROUTES = [
|
||||
"/",
|
||||
"/auth/signin",
|
||||
"/auth/register",
|
||||
"/auth/forgot-password",
|
||||
"/auth/reset-password",
|
||||
"/privacy",
|
||||
"/terms",
|
||||
] as const;
|
||||
|
||||
/** Path prefixes treated as public (e.g. shareable invoice links). */
|
||||
export const PUBLIC_ROUTE_PREFIXES = ["/i/"] as const;
|
||||
|
||||
export function isPublicRoute(pathname: string): boolean {
|
||||
if ((PUBLIC_ROUTES as readonly string[]).includes(pathname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return PUBLIC_ROUTE_PREFIXES.some((prefix) => pathname.startsWith(prefix));
|
||||
}
|
||||
Reference in New Issue
Block a user