add shared login pin mechansim
This commit is contained in:
@@ -1,22 +1,66 @@
|
||||
import type { Cookies } from '@sveltejs/kit';
|
||||
|
||||
// The PocketBase JWT lives in a single cookie shared by:
|
||||
// PocketBase JWTs live in cookies shared by:
|
||||
// - the server hooks (authRefresh -> locals.user)
|
||||
// - the client SDK (seeded from page.data.pbToken -> authenticated famStore reads/subscribe)
|
||||
// httpOnly keeps the token out of reach of browser JS/XSS; the client receives
|
||||
// httpOnly keeps tokens out of reach of browser JS/XSS; the client receives
|
||||
// the token server-side via the layout load (pbToken) and seeds pb.authStore.
|
||||
// Secure flag is set in prod so it's only sent over HTTPS.
|
||||
export const SESSION_COOKIE = 'pb_token';
|
||||
// Shared-device multi-session: children hold ONE cookie per account
|
||||
// (`pb_token_<userId>`); `pb_active` names which one is the current session.
|
||||
// Parents stay on the single `pb_token`.
|
||||
export const CHILD_COOKIE_PREFIX = 'pb_token_';
|
||||
export const ACTIVE_COOKIE = 'pb_active';
|
||||
const MAX_AGE = 60 * 60 * 24 * 5; // 5 days — matches the PB users auth token duration
|
||||
|
||||
export function setSessionCookie(cookies: Cookies, token: string) {
|
||||
cookies.set(SESSION_COOKIE, token, {
|
||||
function cookieOpts() {
|
||||
return {
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
sameSite: 'lax' as const,
|
||||
path: '/',
|
||||
maxAge: MAX_AGE,
|
||||
secure: import.meta.env.PROD
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function setSessionCookie(cookies: Cookies, token: string) {
|
||||
cookies.set(SESSION_COOKIE, token, cookieOpts());
|
||||
}
|
||||
|
||||
export function childSessionCookie(userId: string) {
|
||||
return `${CHILD_COOKIE_PREFIX}${userId}`;
|
||||
}
|
||||
|
||||
export function setChildSessionCookie(cookies: Cookies, userId: string, token: string) {
|
||||
cookies.set(childSessionCookie(userId), token, cookieOpts());
|
||||
}
|
||||
|
||||
export function clearChildSession(cookies: Cookies, userId: string) {
|
||||
cookies.delete(childSessionCookie(userId), { path: '/' });
|
||||
}
|
||||
|
||||
export function setActiveChild(cookies: Cookies, userId: string) {
|
||||
cookies.set(ACTIVE_COOKIE, userId, cookieOpts());
|
||||
}
|
||||
|
||||
export function clearActiveChild(cookies: Cookies) {
|
||||
cookies.delete(ACTIVE_COOKIE, { path: '/' });
|
||||
}
|
||||
|
||||
// Ids of every child that has a session cookie on this device.
|
||||
export function scanChildSessions(cookies: Cookies): string[] {
|
||||
return cookies
|
||||
.getAll()
|
||||
.filter((c) => c.name.startsWith(CHILD_COOKIE_PREFIX))
|
||||
.map((c) => c.name.slice(CHILD_COOKIE_PREFIX.length))
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
// Remove every child session on this device (logout-all).
|
||||
export function clearDeviceSessions(cookies: Cookies) {
|
||||
for (const id of scanChildSessions(cookies)) clearChildSession(cookies, id);
|
||||
clearActiveChild(cookies);
|
||||
}
|
||||
|
||||
export function clearSessionCookie(cookies: Cookies) {
|
||||
@@ -50,4 +94,4 @@ export function setPlatformSession(cookies: Cookies, token: string) {
|
||||
|
||||
export function clearPlatformSession(cookies: Cookies) {
|
||||
cookies.delete(PLATFORM_SESSION_COOKIE, { path: '/' });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user