rewrite website
This commit is contained in:
77
src/util/session.ts
Normal file
77
src/util/session.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import type { AstroCookies, AstroCookieSetOptions } from 'astro';
|
||||
import { ActionError } from 'astro:actions';
|
||||
import crypto from 'node:crypto';
|
||||
import { Permissions } from './permissions.ts';
|
||||
import { ADMIN_COOKIE } from 'astro:env/server';
|
||||
|
||||
export class Session {
|
||||
static readonly #cookieOptions: AstroCookieSetOptions = {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
sameSite: 'lax'
|
||||
};
|
||||
static #sessions: Session[] = [];
|
||||
|
||||
readonly sessionId: string;
|
||||
readonly adminId: number;
|
||||
readonly permissions: Permissions;
|
||||
|
||||
private constructor(sessionId: string, adminId: number, permissions: Permissions) {
|
||||
this.sessionId = sessionId;
|
||||
this.adminId = adminId;
|
||||
this.permissions = permissions;
|
||||
|
||||
Session.#sessions.push(this);
|
||||
}
|
||||
|
||||
invalidate(cookies?: AstroCookies) {
|
||||
for (let i = 0; i < Session.#sessions.length; i++) {
|
||||
if (Session.#sessions[i] == this) {
|
||||
Session.#sessions = Session.#sessions.splice(i, 1);
|
||||
if (cookies) cookies.delete(ADMIN_COOKIE, Session.#cookieOptions);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static newSession(adminId: number, permissions: Permissions, cookies: AstroCookies) {
|
||||
const session = new Session(crypto.randomBytes(16).toString('hex'), adminId, permissions);
|
||||
Session.#sessions.push(session);
|
||||
|
||||
cookies.set(ADMIN_COOKIE, session.sessionId, Session.#cookieOptions);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
static sessionFromCookies(cookies: AstroCookies, neededPermissions?: Permissions) {
|
||||
const sessionId = cookies.get(ADMIN_COOKIE);
|
||||
if (!sessionId) return null;
|
||||
|
||||
for (const session of Session.#sessions) {
|
||||
if (session.sessionId == sessionId.value) {
|
||||
if (neededPermissions && !session.permissions.hasPermissions(neededPermissions)) {
|
||||
break;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static actionSessionFromCookies(cookies: AstroCookies, neededPermissions?: Permissions) {
|
||||
const sessionId = cookies.get(ADMIN_COOKIE);
|
||||
if (!sessionId) throw new ActionError({ code: 'UNAUTHORIZED' });
|
||||
|
||||
for (const session of Session.#sessions) {
|
||||
if (session.sessionId == sessionId.value) {
|
||||
if (neededPermissions && !session.permissions.hasPermissions(neededPermissions)) {
|
||||
throw new ActionError({ code: 'UNAUTHORIZED' });
|
||||
}
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ActionError({ code: 'UNAUTHORIZED' });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user