add new hooks guide
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
import type { Handle } from '@sveltejs/kit';
|
||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
import { createPbClient } from '$lib/server/pocketbase';
|
||||||
|
import { SESSION_COOKIE, setSessionCookie, clearSessionCookie } from '$lib/server/session';
|
||||||
|
import type { SessionUser } from '$lib/server/types';
|
||||||
|
|
||||||
|
const PUBLIC_PATHS = ['/login', '/signup', '/pair'];
|
||||||
|
const ADMIN_ONLY_PREFIXES = ['/admin'];
|
||||||
|
|
||||||
|
export const handle: Handle = async ({ event, resolve }) => {
|
||||||
|
event.locals.user = null;
|
||||||
|
event.locals.pbToken = null;
|
||||||
|
|
||||||
|
const token = event.cookies.get(SESSION_COOKIE);
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
const pb = createPbClient(token);
|
||||||
|
try {
|
||||||
|
// authRefresh() does two jobs in one call:
|
||||||
|
// 1. Verifies the token. PocketBase JWTs can't be checked
|
||||||
|
// offline (the signing secret is per-record and never
|
||||||
|
// leaves PB), so this round trip IS the verification step.
|
||||||
|
// 2. Returns the current record — which is the only way to get
|
||||||
|
// username/role/famId, since PB deliberately doesn't embed
|
||||||
|
// custom fields in the token itself.
|
||||||
|
const { record, token: freshToken } = await pb.collection('users').authRefresh();
|
||||||
|
|
||||||
|
event.locals.user = {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
role: record.role,
|
||||||
|
famId: record.famId
|
||||||
|
} satisfies SessionUser;
|
||||||
|
event.locals.pbToken = freshToken;
|
||||||
|
|
||||||
|
if (freshToken !== token) {
|
||||||
|
setSessionCookie(event.cookies, freshToken);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Expired, malformed, or revoked (password/deviceToken changed
|
||||||
|
// since this token was issued) — drop it and treat as logged out.
|
||||||
|
clearSessionCookie(event.cookies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = event.url.pathname;
|
||||||
|
const isPublic = PUBLIC_PATHS.some((p) => path.startsWith(p));
|
||||||
|
|
||||||
|
if (!isPublic && !event.locals.user) {
|
||||||
|
throw redirect(303, '/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ADMIN_ONLY_PREFIXES.some((p) => path.startsWith(p)) && !event.locals.user) {
|
||||||
|
console.log("rejecting",event.locals.user);
|
||||||
|
throw redirect(303, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(event);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user