feat(users): require password confirmation when creating an app user

Both create paths (Users > Add User page and the CreateUserModal used during
device onboarding) now have a Confirm Password field. A mismatch shows an
inline error and blocks the create call, so a typo can't silently become the
user's Firebase Auth password. The confirm value is client-side only and is
never sent to the backend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 15:40:51 +03:00
co-authored by Claude Opus 5.5
parent c1df3b5aa3
commit 36f9540a89
2 changed files with 43 additions and 11 deletions
+27 -10
View File
@@ -319,6 +319,7 @@ export default function UserForm() {
quickSettingsPIN: '',
password: '',
})
const [confirmPassword, setConfirmPassword] = useState('')
const [uid, setUid] = useState('')
const [loading, setLoading] = useState(false)
const [saving, setSaving] = useState(false)
@@ -356,6 +357,10 @@ export default function UserForm() {
const handleSubmit = async (e) => {
e.preventDefault()
setError('')
if (!isEdit && form.password !== confirmPassword) {
setError('Passwords do not match.')
return
}
setSaving(true)
try {
if (isEdit) {
@@ -437,16 +442,28 @@ export default function UserForm() {
/>
</div>
{!isEdit && (
<FormField
label="Password"
name="password"
type="password"
value={form.password}
onChange={set('password')}
required
placeholder="Min. 6 characters"
hint="Used to sign into the mobile app immediately — this creates the Firebase Auth account."
/>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
<FormField
label="Password"
name="password"
type="password"
value={form.password}
onChange={set('password')}
required
placeholder="Min. 6 characters"
hint="Used to sign into the mobile app immediately — this creates the Firebase Auth account."
/>
<FormField
label="Confirm Password"
name="confirm_password"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
placeholder="Re-enter password"
error={confirmPassword && form.password !== confirmPassword ? 'Passwords do not match.' : undefined}
/>
</div>
)}
<StatusToggle value={form.status} onChange={setVal('status')} />
</div>