Add session-based authentication with login/logout
- Users and sessions tables (Argon2 password hashing, SHA-256 session tokens) - Server hooks validate session cookie on every request - (app) routes redirect to /login if not authenticated - Login page with email/password, styled matching budget app - Logout via POST form action (invalidates session) - User display name and sign out button in header - create-user CLI script: npm run create-user <email> <password> [name] - 30-day sessions with auto-refresh after 15 days Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
import type { LayoutServerLoad } from './$types';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { devices, components } from '$lib/server/db/schema.js';
|
||||
import { count, eq, or, and } from 'drizzle-orm';
|
||||
|
||||
export const load: LayoutServerLoad = async () => {
|
||||
export const load: LayoutServerLoad = async ({ locals }) => {
|
||||
if (!locals.user) {
|
||||
redirect(302, '/login');
|
||||
}
|
||||
|
||||
const [deviceCount] = await db.select({ value: count() }).from(devices).where(eq(devices.disabled, false));
|
||||
const [componentCount] = await db.select({ value: count() }).from(components);
|
||||
const [repairCount] = await db
|
||||
@@ -12,6 +17,7 @@ export const load: LayoutServerLoad = async () => {
|
||||
.where(and(eq(devices.disabled, false), or(eq(devices.condition, 'In Repair'), eq(devices.condition, 'Waiting for Repair'))));
|
||||
|
||||
return {
|
||||
user: locals.user,
|
||||
counts: {
|
||||
devices: deviceCount?.value ?? 0,
|
||||
components: componentCount?.value ?? 0,
|
||||
|
||||
@@ -37,6 +37,15 @@
|
||||
|
||||
<div class="ml-auto flex items-center gap-3">
|
||||
<ThemeToggle />
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{data.user.displayName ?? data.user.email}</span>
|
||||
<form method="POST" action="/logout">
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-md px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
||||
>
|
||||
Sign Out
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user