web-production-saas-starter/next_b2b_starter/lib/auth/stytch-client.ts
2025-12-16 18:54:41 +04:00

74 lines
1.6 KiB
TypeScript

/**
* Client-safe utilities that use passed config instead of reading env
* These functions are pure and can be safely used in client components
*/
import type { StytchClientConfig } from "./config-types";
export interface LoginUrlOptions {
returnTo?: string;
}
export interface LogoutUrlOptions {
returnTo?: string;
}
function sanitizeReturnTo(value: string | undefined): string | undefined {
if (!value) return undefined;
const trimmed = value.trim();
if (!trimmed.startsWith("/") || trimmed.startsWith("//")) {
return undefined;
}
return trimmed;
}
function resolveRoute(
baseUrl: string,
path: string,
fallback: string
): URL {
const trimmed = path?.trim();
if (!trimmed) {
return new URL(fallback, `${baseUrl}/`);
}
if (/^https?:\/\//i.test(trimmed)) {
return new URL(trimmed);
}
const cleanPath = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
return new URL(cleanPath, `${baseUrl}/`);
}
export function buildLoginUrl(
config: StytchClientConfig,
options?: LoginUrlOptions
): string {
const url = resolveRoute(config.baseUrl, config.loginPath, "/auth");
const returnTo = sanitizeReturnTo(options?.returnTo);
if (returnTo) {
url.searchParams.set("returnTo", returnTo);
}
return url.toString();
}
export function buildLogoutUrl(
config: StytchClientConfig,
options?: LogoutUrlOptions
): string {
const url = resolveRoute(
config.baseUrl,
config.logoutPath,
"/api/auth/logout"
);
const returnTo = sanitizeReturnTo(options?.returnTo);
if (returnTo) {
url.searchParams.set("returnTo", returnTo);
}
return url.toString();
}