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:
1 parent
677fe0fc0a
commit
5e20710aa7
16 files changed
+489
-8
No files matched your search
+20
-1
@@ -120,6 +120,17 @@ export const App: React.FC = () => {
|
||||
instanceName: 'MindSift',
|
||||
});
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
// Link from the password reset mail (?resetToken=…); removed from the address bar right away
|
||||
const [resetToken, setResetToken] = useState<string | null>(() => {
|
||||
try {
|
||||
return new URLSearchParams(window.location.search).get('resetToken');
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
useEffect(() => {
|
||||
if (resetToken) window.history.replaceState(null, '', window.location.pathname);
|
||||
}, [resetToken]);
|
||||
const [customThemes, setCustomThemes] = useState<UserTheme[]>([]);
|
||||
const allThemes = useMemo(() => [...AVAILABLE_THEMES, ...customThemes.map(customThemeOption)], [customThemes]);
|
||||
const [stats, setStats] = useState<DashboardStats>({
|
||||
@@ -666,11 +677,19 @@ export const App: React.FC = () => {
|
||||
}
|
||||
|
||||
// Show Setup Wizard or Login Screen if needsSetup or not logged in
|
||||
if (authStatus.needsSetup || !user) {
|
||||
if (authStatus.needsSetup || !user || resetToken) {
|
||||
return (
|
||||
<SetupAndAuthView
|
||||
authStatus={authStatus}
|
||||
onAuthenticated={handleAuthenticated}
|
||||
resetToken={resetToken}
|
||||
onResetDone={() => {
|
||||
// The new password ended every session, this one included
|
||||
setResetToken(null);
|
||||
clearToken();
|
||||
setUser(null);
|
||||
}}
|
||||
onResetCancel={() => setResetToken(null)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user