Skip to content

Instantly share code, notes, and snippets.

@SagnikPradhan
Created June 15, 2022 01:53
Show Gist options
  • Save SagnikPradhan/fe52272e5931a8ea4cbb43817ec6496b to your computer and use it in GitHub Desktop.
Save SagnikPradhan/fe52272e5931a8ea4cbb43817ec6496b to your computer and use it in GitHub Desktop.
Koa sessions
export interface Context<Data> extends Koa.DefaultContext {
session: Session<Data>;
}
export class Session<Data> {
protected static cookieName = "sessId" as const;
protected static httpOnly = true as const;
protected static maxAge = 1000 * 60 * 2;
protected static sameSite = "lax" as const;
#id: string;
#prisma: PrismaClient;
#context: Context<Data>;
constructor(prisma: PrismaClient, context: Context<Data>) {
this.#prisma = prisma;
this.#context = context;
this.#id = this.#context.cookies.get(Session.cookieName) || nanoid();
}
/** Get session data */
public async get() {
await this.#prisma.session.deleteMany({
where: { expiresAt: { lte: new Date() } },
});
const session = await this.#prisma.session.findUnique({
where: { id: this.#id },
});
if (!session) return {};
const data = session.data as Data;
const expiresAt = new Date(Date.now() + Session.maxAge);
await this.#prisma.session.update({
where: { id: this.#id },
data: { expiresAt },
});
return data;
}
/** Updates session data and returns a copy */
public async set(data: Jsonify<Data>) {
const expiresAt = new Date(Date.now() + Session.maxAge);
const session = await this.#prisma.session.upsert({
where: { id: this.#id },
create: { id: this.#id, data, expiresAt },
update: { id: this.#id, data, expiresAt },
});
this.#context.cookies.set(Session.cookieName, this.#id, {
httpOnly: Session.httpOnly,
maxAge: Session.maxAge,
sameSite: Session.sameSite,
});
return session.data as Data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment