forked from
samuel.fm/statusphere-react
the statusphere demo reworked into a vite/react app in a monorepo
1import { IncomingMessage, ServerResponse } from 'node:http'
2import { Agent } from '@atproto/api'
3import { Request, Response } from 'express'
4import { getIronSession, SessionOptions } from 'iron-session'
5
6import { AppContext } from '#/context'
7import { env } from '#/lib/env'
8
9type Session = { did: string }
10
11// Common session options
12const sessionOptions: SessionOptions = {
13 cookieName: 'sid',
14 password: env.COOKIE_SECRET,
15 cookieOptions: {
16 secure: env.NODE_ENV === 'production',
17 httpOnly: true,
18 sameSite: true,
19 path: '/',
20 // Don't set domain explicitly - let browser determine it
21 domain: undefined,
22 },
23}
24
25export async function getSessionAgent(
26 req: IncomingMessage | Request,
27 res: ServerResponse<IncomingMessage> | Response,
28 ctx: AppContext,
29) {
30 const session = await getIronSession<Session>(req, res, sessionOptions)
31
32 if (!session.did) {
33 return null
34 }
35
36 try {
37 const oauthSession = await ctx.oauthClient.restore(session.did)
38 return oauthSession ? new Agent(oauthSession) : null
39 } catch (err) {
40 ctx.logger.warn({ err }, 'oauth restore failed')
41 session.destroy()
42 return null
43 }
44}
45
46export async function getSession(req: Request, res: Response) {
47 return getIronSession<Session>(req, res, sessionOptions)
48}