Files
famdone/frontend/src/lib/server/pocketbase.ts
T
2026-08-17 07:41:58 +01:00

64 lines
2.5 KiB
TypeScript

import PocketBase from 'pocketbase';
import { redirect } from '@sveltejs/kit';
import type { RequestEvent } from '@sveltejs/kit';
import { SERVER_IP } from '$app/env/public';
import { PB_EMAIL, PB_PASSWORD } from '$app/env/private';
export const PB_ENDPOINT = import.meta.env.PROD ? '/pb' : `http://${SERVER_IP}:8090`;
// Server-side PB client, pre-authenticated as the given user's token.
// Used for CRUD as the authenticated user so PB collection rules apply
// (famId scoping) instead of running everything as superuser.
export function createPbClient(token?: string) {
const pb = new PocketBase(PB_ENDPOINT);
if (token) pb.authStore.save(token, null);
return pb;
}
// Authenticated PB client for the current request's admin/member session.
// Requires an active session; redirects to /login otherwise.
export function pbUser(event: RequestEvent) {
if (!event.locals.user || !event.locals.pbToken) {
throw redirect(303, '/login');
}
return createPbClient(event.locals.pbToken);
}
// Superuser PB client (memoized). Reserved for server-only privileged
// operations that must bypass collection rules: creating child users, minting
// OTP-login tokens, and verifying OTPs against the superuser-only otp.
let superClient: PocketBase | null = null;
export async function createSuperClient() {
if (superClient) return superClient;
const pb = new PocketBase(PB_ENDPOINT);
await pb.collection('_superusers').authWithPassword(String(PB_EMAIL), String(PB_PASSWORD));
superClient = pb;
return pb;
}
// Superuser CRUD facade, built on the memoized SDK superuser client. All
// server PB access (authenticated user + superuser) lives in this one module.
export const pbAdmin = {
async getList(collection: string, filter = '') {
const pb = await createSuperClient();
const options: { filter?: string } = {};
if (filter) options.filter = filter;
return pb.collection(collection).getFullList(options);
},
async getOne(collection: string, id: string) {
const pb = await createSuperClient();
return pb.collection(collection).getOne(id);
},
async create(collection: string, data: Record<string, unknown>) {
const pb = await createSuperClient();
return pb.collection(collection).create(data);
},
async update(collection: string, id: string, data: Record<string, unknown>) {
const pb = await createSuperClient();
return pb.collection(collection).update(id, data);
},
async remove(collection: string, id: string) {
const pb = await createSuperClient();
return pb.collection(collection).delete(id);
}
};