diff --git a/ui/src/pages/Admin/RolesTab.tsx b/ui/src/pages/Admin/RolesTab.tsx index 514551fb..c616cc31 100644 --- a/ui/src/pages/Admin/RolesTab.tsx +++ b/ui/src/pages/Admin/RolesTab.tsx @@ -179,7 +179,7 @@ export default function RolesTab({ highlightId, onHighlightConsumed }: { highlig )}
- {role.description || '\u2014'} \u00b7{' '} + {role.description || '\u2014'} {'\u00b7'}{' '} {getAssignmentCount(role)} assignments
diff --git a/ui/src/pages/Admin/UserManagement.module.css b/ui/src/pages/Admin/UserManagement.module.css index b4864871..d2b0b423 100644 --- a/ui/src/pages/Admin/UserManagement.module.css +++ b/ui/src/pages/Admin/UserManagement.module.css @@ -156,3 +156,8 @@ color: var(--error); font-size: 12px; } + +.hintText { + font-size: 12px; + color: var(--text-muted); +} diff --git a/ui/src/pages/Admin/UsersTab.tsx b/ui/src/pages/Admin/UsersTab.tsx index 34dbc278..c30808cb 100644 --- a/ui/src/pages/Admin/UsersTab.tsx +++ b/ui/src/pages/Admin/UsersTab.tsx @@ -67,8 +67,11 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig const [newDisplay, setNewDisplay] = useState(''); const [newEmail, setNewEmail] = useState(''); const [newPassword, setNewPassword] = useState(''); + const [newPasswordConfirm, setNewPasswordConfirm] = useState(''); const [newProvider, setNewProvider] = useState<'local' | 'oidc'>('local'); + const passwordMismatch = newPassword.length > 0 && newPasswordConfirm.length > 0 && newPassword !== newPasswordConfirm; + // Password reset state const [resettingPassword, setResettingPassword] = useState(false); const [newPw, setNewPw] = useState(''); @@ -145,6 +148,7 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig setNewDisplay(''); setNewEmail(''); setNewPassword(''); + setNewPasswordConfirm(''); setNewProvider('local'); }, onError: (err: unknown) => { @@ -241,12 +245,24 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig onChange={(e) => setNewEmail(e.target.value)} /> {newProvider === 'local' && ( - setNewPassword(e.target.value)} - /> + <> + setNewPassword(e.target.value)} + /> + setNewPasswordConfirm(e.target.value)} + /> + {passwordMismatch && ( + Passwords do not match + )} + Min 12 chars, 3 of 4: uppercase, lowercase, number, special + )} {newProvider === 'oidc' && ( @@ -258,7 +274,7 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig @@ -270,7 +286,8 @@ export default function UsersTab({ highlightId, onHighlightConsumed }: { highlig disabled={ !newUsername.trim() || (newProvider === 'local' && !newPassword.trim()) || - duplicateUsername + duplicateUsername || + passwordMismatch } > Create