Add login-page site gate and refresh marketing site for complex-care positioning.

Replace HTTP Basic Auth with a branded /login flow and signed session cookie, using Next.js 16's proxy convention for route protection.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 02:21:58 -04:00
co-authored by Cursor
parent d521c66903
commit b0636ba5ce
18 changed files with 877 additions and 252 deletions
+53
View File
@@ -0,0 +1,53 @@
export const AUTH_COOKIE_NAME = "medscribe_site_access";
const ACCESS_PAYLOAD = "medscribe-site-access-v1";
async function signAccessToken(password: string): Promise<string> {
const key = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(password),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"],
);
const signature = await crypto.subtle.sign(
"HMAC",
key,
new TextEncoder().encode(ACCESS_PAYLOAD),
);
return btoa(String.fromCharCode(...new Uint8Array(signature)));
}
function timingSafeEqual(a: string, b: string): boolean {
if (a.length !== b.length) return false;
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}
return result === 0;
}
export async function verifyAccessToken(
password: string,
token: string | undefined,
): Promise<boolean> {
if (!token) return false;
const expected = await signAccessToken(password);
return timingSafeEqual(expected, token);
}
export async function createAccessCookieValue(
password: string,
): Promise<string> {
return signAccessToken(password);
}
export function safeRedirectPath(path: string | null | undefined): string {
if (!path?.startsWith("/") || path.startsWith("//")) return "/";
return path;
}