Add guest cart drawer, Continue handoff, and shared customer login.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
ad05241a77
commit
16340c3b48
@@ -0,0 +1,123 @@
|
||||
/** Shared auth cookies so storefront + customer.{domain} share one login. */
|
||||
|
||||
export const SHARED_ACCESS_TOKEN_KEY = "meshkee_customer_access_token";
|
||||
export const SHARED_REFRESH_TOKEN_KEY = "meshkee_customer_refresh_token";
|
||||
|
||||
const CHUNK_SIZE = 2800;
|
||||
const MAX_CHUNKS = 24;
|
||||
|
||||
function cookieDomain(): string | undefined {
|
||||
if (typeof window === "undefined") return undefined;
|
||||
const host = window.location.hostname.toLowerCase();
|
||||
if (host === "localhost" || host === "127.0.0.1") return undefined;
|
||||
const parts = host.split(".").filter(Boolean);
|
||||
if (parts.length < 2) return undefined;
|
||||
return `.${parts.slice(-2).join(".")}`;
|
||||
}
|
||||
|
||||
function readRawCookie(name: string): string | null {
|
||||
if (typeof document === "undefined") return null;
|
||||
const prefix = `${name}=`;
|
||||
const match = document.cookie.split("; ").find((row) => row.startsWith(prefix));
|
||||
if (!match) return null;
|
||||
return match.slice(prefix.length);
|
||||
}
|
||||
|
||||
function writeRawCookie(name: string, value: string | null) {
|
||||
if (typeof document === "undefined") return;
|
||||
const domain = cookieDomain();
|
||||
if (value == null) {
|
||||
let cookie = `${name}=; path=/; max-age=0; SameSite=Lax`;
|
||||
if (domain) cookie += `; domain=${domain}`;
|
||||
document.cookie = cookie;
|
||||
return;
|
||||
}
|
||||
const maxAge = 60 * 60 * 24 * 30;
|
||||
let cookie = `${name}=${value}; path=/; max-age=${maxAge}; SameSite=Lax`;
|
||||
if (domain) cookie += `; domain=${domain}`;
|
||||
document.cookie = cookie;
|
||||
}
|
||||
|
||||
function clearChunkedCookie(name: string) {
|
||||
writeRawCookie(name, null);
|
||||
const n = Number(readRawCookie(`${name}_n`) || "0");
|
||||
writeRawCookie(`${name}_n`, null);
|
||||
for (let i = 0; i < Math.max(n, MAX_CHUNKS); i++) {
|
||||
writeRawCookie(`${name}_${i}`, null);
|
||||
}
|
||||
}
|
||||
|
||||
function writeCookie(name: string, value: string | null) {
|
||||
clearChunkedCookie(name);
|
||||
if (value == null || value === "") return;
|
||||
|
||||
const encoded = encodeURIComponent(value);
|
||||
if (encoded.length <= 3500) {
|
||||
writeRawCookie(name, encoded);
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks: string[] = [];
|
||||
for (let i = 0; i < encoded.length; i += CHUNK_SIZE) {
|
||||
chunks.push(encoded.slice(i, i + CHUNK_SIZE));
|
||||
}
|
||||
writeRawCookie(`${name}_n`, String(chunks.length));
|
||||
chunks.forEach((chunk, i) => writeRawCookie(`${name}_${i}`, chunk));
|
||||
}
|
||||
|
||||
function readCookie(name: string): string | null {
|
||||
const n = Number(readRawCookie(`${name}_n`) || "0");
|
||||
if (n > 0) {
|
||||
let encoded = "";
|
||||
for (let i = 0; i < n; i++) {
|
||||
const part = readRawCookie(`${name}_${i}`);
|
||||
if (part == null) return null;
|
||||
encoded += part;
|
||||
}
|
||||
try {
|
||||
return decodeURIComponent(encoded);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const raw = readRawCookie(name);
|
||||
if (raw == null) return null;
|
||||
try {
|
||||
return decodeURIComponent(raw);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function writeSharedAuthCookies(accessToken: string, refreshToken?: string) {
|
||||
writeCookie(SHARED_ACCESS_TOKEN_KEY, accessToken);
|
||||
if (refreshToken) writeCookie(SHARED_REFRESH_TOKEN_KEY, refreshToken);
|
||||
}
|
||||
|
||||
export function clearSharedAuthCookies() {
|
||||
writeCookie(SHARED_ACCESS_TOKEN_KEY, null);
|
||||
writeCookie(SHARED_REFRESH_TOKEN_KEY, null);
|
||||
}
|
||||
|
||||
export function readSharedAccessToken(): string | null {
|
||||
return readCookie(SHARED_ACCESS_TOKEN_KEY);
|
||||
}
|
||||
|
||||
export function readSharedRefreshToken(): string | null {
|
||||
return readCookie(SHARED_REFRESH_TOKEN_KEY);
|
||||
}
|
||||
|
||||
export function hydrateLocalTokensFromSharedCookies(
|
||||
accessKey = SHARED_ACCESS_TOKEN_KEY,
|
||||
refreshKey = SHARED_REFRESH_TOKEN_KEY,
|
||||
): boolean {
|
||||
if (typeof window === "undefined") return false;
|
||||
if (localStorage.getItem(accessKey)) return false;
|
||||
const access = readSharedAccessToken();
|
||||
if (!access) return false;
|
||||
localStorage.setItem(accessKey, access);
|
||||
const refresh = readSharedRefreshToken();
|
||||
if (refresh) localStorage.setItem(refreshKey, refresh);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user