Checkpoint SHD dashboard design system
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { dev } from '$app/environment';
|
||||
import { getDatabase } from '$lib/server/database';
|
||||
import type { Cookies } from '@sveltejs/kit';
|
||||
import { createHash, randomBytes, randomUUID } from 'node:crypto';
|
||||
|
||||
const COOKIE_NAME = 'shd_session';
|
||||
const SESSION_SECONDS = 60 * 60 * 24 * 30;
|
||||
|
||||
export type AuthUser = {
|
||||
id: string;
|
||||
username: string;
|
||||
role: string;
|
||||
discordLinked: boolean;
|
||||
};
|
||||
|
||||
function hashToken(token: string): string {
|
||||
return createHash('sha256').update(token).digest('hex');
|
||||
}
|
||||
|
||||
export async function createSession(cookies: Cookies, userId: string): Promise<void> {
|
||||
const database = await getDatabase();
|
||||
const token = randomBytes(32).toString('base64url');
|
||||
const now = new Date();
|
||||
const expiresAt = new Date(now.getTime() + SESSION_SECONDS * 1000);
|
||||
const insert = await database.prepare(
|
||||
'INSERT INTO sessions (id, user_id, token_hash, expires_at, created_at) VALUES (?, ?, ?, ?, ?)'
|
||||
);
|
||||
|
||||
await insert.run(
|
||||
randomUUID(),
|
||||
userId,
|
||||
hashToken(token),
|
||||
expiresAt.toISOString(),
|
||||
now.toISOString()
|
||||
);
|
||||
|
||||
cookies.set(COOKIE_NAME, token, {
|
||||
path: '/',
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
secure: !dev,
|
||||
maxAge: SESSION_SECONDS
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSessionUser(cookies: Cookies): Promise<AuthUser | null> {
|
||||
const token = cookies.get(COOKIE_NAME);
|
||||
if (!token) return null;
|
||||
|
||||
const database = await getDatabase();
|
||||
const statement = await database.prepare(`
|
||||
SELECT users.id, users.username, users.role, users.discord_id
|
||||
FROM sessions
|
||||
JOIN users ON users.id = sessions.user_id
|
||||
WHERE sessions.token_hash = ? AND sessions.expires_at > ?
|
||||
`);
|
||||
const user = await statement.get(hashToken(token), new Date().toISOString());
|
||||
|
||||
if (!user) {
|
||||
cookies.delete(COOKIE_NAME, { path: '/' });
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: String(user.id),
|
||||
username: String(user.username),
|
||||
role: String(user.role),
|
||||
discordLinked: typeof user.discord_id === 'string'
|
||||
};
|
||||
}
|
||||
|
||||
export async function destroySession(cookies: Cookies): Promise<void> {
|
||||
const token = cookies.get(COOKIE_NAME);
|
||||
|
||||
if (token) {
|
||||
const database = await getDatabase();
|
||||
const statement = await database.prepare('DELETE FROM sessions WHERE token_hash = ?');
|
||||
await statement.run(hashToken(token));
|
||||
}
|
||||
|
||||
cookies.delete(COOKIE_NAME, { path: '/' });
|
||||
}
|
||||
Reference in New Issue
Block a user