Extract auth into hooks/useAuth; move form state into its pages
Build and Push Docker Image / build-and-push (push) Successful in 6m28s

- useAuth owns authUser/authServerDown, the startup session check, and
  signIn/logout, so every sign-in path runs the same follow-up (switch
  local storage to the account, load reader ink). Previously reader ink
  only loaded on a page refresh, not right after logging in.
- Login/2FA form state now lives in AuthPage, and 2FA setup, password
  change, and podcast name state in SettingsPage (23 fewer context
  values; typing in these forms no longer re-renders all of App).
- Add tests for form sign-in, 2FA, session restore + logout, and the
  Settings podcast-name prefill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Opus 5.5 committed 2026-09-22 14:44:52 -04:00
1 parent 009fa1e78f
commit 49ffefed54
5 files changed
+162 -113

No files matched your search

+11 -16
View File
@@ -1,19 +1,16 @@
import { useState } from 'react';
import { useApp } from '../context/AppContext.js';
import { loginUser, registerUser, verifyMfaLogin, logoutUser } from '../syncService.js';
import { switchStorageUser } from '../utils/bibleUtils.jsx';
export default function AuthPage() {
const {
authMode, setAuthMode,
authForm, setAuthForm,
authError, setAuthError,
authBusy, setAuthBusy,
authMfaPending, setAuthMfaPending,
authMfaCode, setAuthMfaCode,
authMfaUseBackup, setAuthMfaUseBackup,
setAuthUser,
setProjectIndex,
} = useApp();
const { signIn } = useApp();
const [authMode, setAuthMode] = useState('login'); // 'login' | 'register'
const [authForm, setAuthForm] = useState({ email: '', password: '' });
const [authError, setAuthError] = useState('');
const [authBusy, setAuthBusy] = useState(false);
const [authMfaPending, setAuthMfaPending] = useState(false); // password ok, waiting on TOTP/backup code
const [authMfaCode, setAuthMfaCode] = useState('');
const [authMfaUseBackup, setAuthMfaUseBackup] = useState(false);
const submitAuth = async (e) => {
e.preventDefault();
@@ -30,8 +27,7 @@ export default function AuthPage() {
setAuthMfaPending(true);
return;
}
setAuthUser(result.data);
setProjectIndex(switchStorageUser(result.data.id));
signIn(result.data);
};
const submitMfa = async (e) => {
@@ -48,8 +44,7 @@ export default function AuthPage() {
}
setAuthMfaPending(false);
setAuthMfaCode('');
setAuthUser(result.data);
setProjectIndex(switchStorageUser(result.data.id));
signIn(result.data);
};
if (authMfaPending) {