feat(auth): reset a forgotten password by mail

"Passwort vergessen?" appears on the login screen when SMTP and BASE_URL
are configured. The request always gets the same answer and sends the mail
in the background (at most every 2 minutes per account). The link holds a
random token valid once for one hour; only its SHA-256 is stored. Setting
the new password invalidates all open links and ends every session. The
app removes the token from the address bar and offers a way back for
expired links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-29 08:06:56 +01:00
1 parent 677fe0fc0a
commit 5e20710aa7
16 files changed
+489 -8

No files matched your search

+9
View File
@@ -188,6 +188,15 @@ export const api = {
return res;
},
// Public: always the same answer, whether the address exists or not
async requestPasswordReset(email: string): Promise<void> {
await request('/api/v1/auth/forgot-password', { method: 'POST', body: JSON.stringify({ email }) });
},
async resetPassword(token: string, password: string): Promise<void> {
await request('/api/v1/auth/reset-password', { method: 'POST', body: JSON.stringify({ token, password }) });
},
async login(loginOrEmail: string, password: string): Promise<{ token: string; user: User }> {
const res = await request<{ token: string; user: User }>('/api/v1/auth/login', {
method: 'POST',
+2
View File
@@ -8,6 +8,8 @@ export interface AuthStatus {
instanceName: string;
demoMode?: boolean;
sharingMode?: SharingMode;
// "Passwort vergessen?" works (SMTP and BASE_URL configured)
passwordReset?: boolean;
// Impressum / Datenschutz of this instance (LEGAL_* environment variables)
legal?: {
imprintUrl?: string;