security: Zufallspasswörter beim Erststart, kryptographisch sichere JTI-Generierung
- seedDefaultUsers: generiert kryptographisch zufällige Passwörter (crypto/rand) statt hartkodiertes "archivmailrockz" — Passwörter werden einmalig im Terminal angezeigt und können danach nicht wiederhergestellt werden - generateJTI: verwendet crypto/rand (16 Byte, hex) statt time.UnixNano XOR deadbeef Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+10
-3
@@ -1,3 +1,5 @@
|
||||
import { clearAuthCache } from "@/lib/auth-cache";
|
||||
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "";
|
||||
|
||||
async function request<T>(
|
||||
@@ -16,9 +18,7 @@ async function request<T>(
|
||||
});
|
||||
|
||||
if (res.status === 401) {
|
||||
if (typeof window !== "undefined") {
|
||||
window.location.href = "/";
|
||||
}
|
||||
clearAuthCache();
|
||||
throw new Error("Unauthorized");
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ export interface SearchHit {
|
||||
to?: string;
|
||||
subject?: string;
|
||||
date?: string;
|
||||
size?: number;
|
||||
has_attachments?: boolean;
|
||||
}
|
||||
|
||||
export interface SearchResponse {
|
||||
@@ -155,6 +157,7 @@ export async function getMe(): Promise<MeResponse> {
|
||||
}
|
||||
|
||||
export async function logout(): Promise<void> {
|
||||
clearAuthCache();
|
||||
await request<void>("/api/auth/logout", { method: "POST" });
|
||||
}
|
||||
|
||||
@@ -164,6 +167,8 @@ export async function searchEmails(params: {
|
||||
to?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
sort?: string;
|
||||
has_attachment?: boolean;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
}): Promise<SearchResponse> {
|
||||
@@ -173,6 +178,8 @@ export async function searchEmails(params: {
|
||||
if (params.to) sp.set("to", params.to);
|
||||
if (params.date_from) sp.set("date_from", params.date_from);
|
||||
if (params.date_to) sp.set("date_to", params.date_to);
|
||||
if (params.sort) sp.set("sort", params.sort);
|
||||
if (params.has_attachment !== undefined) sp.set("has_attachment", String(params.has_attachment));
|
||||
if (params.page) sp.set("page", String(params.page));
|
||||
if (params.page_size) sp.set("page_size", String(params.page_size));
|
||||
return request<SearchResponse>(`/api/search?${sp.toString()}`);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { MeResponse } from "@/lib/api";
|
||||
|
||||
let cachedUser: MeResponse | null = null;
|
||||
|
||||
export function getCachedUser(): MeResponse | null {
|
||||
return cachedUser;
|
||||
}
|
||||
|
||||
export function setCachedUser(user: MeResponse | null): void {
|
||||
cachedUser = user;
|
||||
}
|
||||
|
||||
export function clearAuthCache(): void {
|
||||
cachedUser = null;
|
||||
}
|
||||
Reference in New Issue
Block a user