mirror of
https://github.com/diced/zipline.git
synced 2026-04-28 10:43:06 -07:00
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
import { detectClient, ZiplineClient } from '@/lib/api/detect';
|
|
import { config } from '@/lib/config';
|
|
import { prisma } from '@/lib/db';
|
|
import { randomCharacters } from '@/lib/random';
|
|
import { FastifyReply, FastifyRequest } from 'fastify';
|
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
import { getIronSession, type SessionOptions } from 'iron-session';
|
|
|
|
const cookieOptions: NonNullable<SessionOptions['cookieOptions']> = {
|
|
// 2 weeks
|
|
maxAge: 60 * 60 * 24 * 14,
|
|
expires: new Date(Date.now() + 60 * 60 * 24 * 14 * 1000),
|
|
path: '/',
|
|
sameSite: 'lax',
|
|
httpOnly: true,
|
|
// secure is set in below session functions based on config
|
|
};
|
|
|
|
export type ZiplineSession = {
|
|
id: string | null;
|
|
sessionId: string | null;
|
|
client: ZiplineClient;
|
|
};
|
|
|
|
export async function getSession(
|
|
req: FastifyRequest | IncomingMessage,
|
|
reply: FastifyReply | ServerResponse<IncomingMessage>,
|
|
) {
|
|
cookieOptions.secure = config.core.returnHttpsUrls;
|
|
|
|
const rawReq = (req as FastifyRequest).raw || req;
|
|
const rawRes = (reply as FastifyReply).raw || reply;
|
|
|
|
const session = await getIronSession<ZiplineSession>(
|
|
rawReq as IncomingMessage,
|
|
rawRes as ServerResponse<IncomingMessage>,
|
|
{
|
|
password: config.core.secret,
|
|
cookieName: 'zipline_session',
|
|
cookieOptions,
|
|
},
|
|
);
|
|
|
|
const headers = (req as FastifyRequest).headers || (req as IncomingMessage).headers;
|
|
session.client = detectClient(<Record<string, string>>headers);
|
|
|
|
return session;
|
|
}
|
|
|
|
export async function saveSession(
|
|
session: Awaited<ReturnType<typeof getSession>>,
|
|
user: { id: string } & Record<string, any>,
|
|
overwriteSessions = true,
|
|
) {
|
|
cookieOptions.secure = config.core.returnHttpsUrls;
|
|
|
|
session.id = user.id;
|
|
|
|
if (overwriteSessions || !session.sessionId) {
|
|
const sessionId = randomCharacters(32);
|
|
session.sessionId = sessionId;
|
|
|
|
if (overwriteSessions) {
|
|
await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: {
|
|
sessions: {
|
|
set: [
|
|
{
|
|
id: sessionId,
|
|
client: session.client.client,
|
|
device: session.client.device,
|
|
ua: session.client.ua,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: {
|
|
sessions: {
|
|
create: {
|
|
id: sessionId,
|
|
client: session.client.client,
|
|
device: session.client.device,
|
|
ua: session.client.ua,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
await session.save();
|
|
}
|