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