forked from
baileytownsend.dev/atproto-sveltekit-template
WIP: Another at:// production from me
1import { db } from '$lib/server/db';
2import type { Handle, ServerInit } from '@sveltejs/kit';
3import { migrate } from 'drizzle-orm/node-postgres/migrator';
4import { env } from '$env/dynamic/private';
5
6import { HOUR } from '@atproto/common';
7import { getSessionManager, SessionRestorationError } from '$lib/server/session';
8
9
10
11export const init: ServerInit = async () => {
12 // Run Drizzle migrations on server startup
13 await migrate(db, { migrationsFolder: env.MIGRATIONS_FOLDER ?? 'drizzle' });
14
15
16 // Start a background job to clean up state every hour, which is recommended in the oauth docs
17 setInterval(async () => {
18 //TODO prob should do one for the session store as well for expired sessions
19 }, HOUR); // Run every hour
20};
21
22export const handle: Handle = async ({ event, resolve }) => {
23 const token = event.cookies.get('session') ?? null;
24 if (token === null) {
25 event.locals.session = null;
26 event.locals.atpAgent = null;
27 return resolve(event);
28 }
29
30 const sessionManager = await getSessionManager();
31
32 try {
33 const { atpAgent, did, handle } = await sessionManager.getSessionFromRequest(event);
34
35 if(atpAgent == null){
36 event.locals.session = null;
37 event.locals.atpAgent = null;
38 return resolve(event);
39 }
40
41 // Store atpAgent in locals (server-side only, not serialized)
42 event.locals.atpAgent = atpAgent;
43
44 // Store only serializable data in session (gets passed to client via load functions)
45 event.locals.session = {
46 did,
47 handle
48 };
49 } catch (err) {
50 if (err instanceof SessionRestorationError) {
51 //You can propagate this error to the frontend to let your users know their session unexpectedly ended
52 //I opted out of not completely implementing this since everyone may have a different idea of what to do in their apps
53 //For instance I would use the cache to create a flash message that when loaded it deletes and show it on the layout
54 } else {
55 // Unexpected error, re-throw
56 throw err;
57 }
58
59 event.locals.session = null;
60 event.locals.atpAgent = null;
61 }
62
63 return resolve(event);
64};