84 lines
1.9 KiB
TypeScript
84 lines
1.9 KiB
TypeScript
import { PUBLIC_COOKIES_SECURE, PUBLIC_DOMAIN } from '$env/static/public';
|
|
import { parseBool } from '$lib/env';
|
|
import type { Cookies } from '@sveltejs/kit';
|
|
|
|
interface CookieInfo {
|
|
name: string;
|
|
value: string;
|
|
options: {
|
|
SameSite?: 'Strict' | 'Lax' | 'None';
|
|
Secure: boolean;
|
|
Partitioned: boolean;
|
|
HttpOnly: boolean;
|
|
Expires?: Date;
|
|
'Max-Age'?: number;
|
|
Path?: string;
|
|
Domain?: string;
|
|
};
|
|
}
|
|
|
|
function parseCookieHeader(headerValue: string): CookieInfo {
|
|
const [nv, ...options] = headerValue.split(';');
|
|
const [name, value] = nv.split('=').map((v) => v.trim());
|
|
const cookie: CookieInfo = {
|
|
name,
|
|
value,
|
|
options: {
|
|
Secure: false,
|
|
Partitioned: false,
|
|
HttpOnly: false
|
|
}
|
|
};
|
|
|
|
options.forEach((option) => {
|
|
const [key, value] = option.split('=').map((v) => v.trim());
|
|
switch (key) {
|
|
case 'Secure':
|
|
cookie.options.Secure = true;
|
|
break;
|
|
case 'SameSite':
|
|
cookie.options.SameSite = value as 'Strict' | 'Lax' | 'None';
|
|
break;
|
|
case 'Partitioned':
|
|
cookie.options.Partitioned = true;
|
|
break;
|
|
case 'HttpOnly':
|
|
cookie.options.HttpOnly = true;
|
|
break;
|
|
case 'Expires':
|
|
cookie.options.Expires = new Date(value);
|
|
break;
|
|
case 'Max-Age':
|
|
cookie.options['Max-Age'] = parseInt(value, 10);
|
|
break;
|
|
case 'Path':
|
|
cookie.options.Path = value;
|
|
break;
|
|
case 'Domain':
|
|
cookie.options.Domain = value;
|
|
break;
|
|
}
|
|
});
|
|
|
|
return cookie;
|
|
}
|
|
|
|
export function passthroughSession(response: Response, cookies: Cookies) {
|
|
if (response.ok) {
|
|
const cookieHeader = response.headers.get('Set-Cookie');
|
|
if (!cookieHeader) {
|
|
return;
|
|
}
|
|
const info = parseCookieHeader(cookieHeader);
|
|
cookies.set(info.name, info.value, {
|
|
httpOnly: info.options.HttpOnly,
|
|
secure: parseBool(PUBLIC_COOKIES_SECURE),
|
|
sameSite: 'strict',
|
|
domain: PUBLIC_DOMAIN,
|
|
expires: info.options.Expires,
|
|
maxAge: info.options['Max-Age'],
|
|
path: info.options.Path ?? '/'
|
|
});
|
|
}
|
|
}
|