web-client/src/lib/auth.ts
Markov e655bba89b feat: JWT token auth (local + future Authentik)
- JWT via jose (HS256, 7d expiry)
- Login API: POST /api/auth/login → returns token
- Verify API: GET /api/auth/me
- Middleware checks Bearer header or cookie
- Token stored in localStorage + cookie (for SSR)
- Authentik button (disabled, placeholder)
- Auth headers auto-added to API requests
2026-02-15 19:05:37 +01:00

28 lines
800 B
TypeScript

import { SignJWT, jwtVerify } from "jose";
const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET || "team-board-dev-secret-change-me");
const TOKEN_EXPIRY = "7d";
export interface TokenPayload {
sub: string; // username
name: string; // display name
provider: string; // "local" | "authentik"
}
export async function createToken(payload: TokenPayload): Promise<string> {
return new SignJWT({ ...payload })
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime(TOKEN_EXPIRY)
.sign(JWT_SECRET);
}
export async function verifyToken(token: string): Promise<TokenPayload | null> {
try {
const { payload } = await jwtVerify(token, JWT_SECRET);
return payload as unknown as TokenPayload;
} catch {
return null;
}
}