fix: add password constraint validation to all password-set/change forms

Login forms correctly only check for empty fields (no password
constraints needed). But password-reset, password-set, and
password-change forms now enforce constraints client-side:

- App reset-password: add PasswordRequirements component,
  confirmation mismatch check, canSubmit guard, disabled button
- Portal wachtwoord-resetten: add canSubmit guard, confirmation
  check, disabled button (PasswordRequirements was rendered but
  not enforced)
- App SecurityTab (change password): replace static requirements
  list with interactive PasswordRequirements, add canSubmit guard

Also created PasswordRequirements.vue component for the organizer
app (portal already had one).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 20:58:26 +02:00
parent 824b28897e
commit dac6aa4c30
4 changed files with 97 additions and 37 deletions

View File

@@ -26,6 +26,20 @@ const showPasswordConfirmation = ref(false)
const errorMessage = ref('')
const isSubmitting = ref(false)
const passwordReqsRef = ref<InstanceType<typeof PasswordRequirements>>()
const confirmationError = computed(() => {
if (!passwordConfirmation.value) return ''
if (password.value !== passwordConfirmation.value) return 'Wachtwoorden komen niet overeen'
return ''
})
const canSubmit = computed(() =>
password.value.length > 0
&& passwordConfirmation.value.length > 0
&& password.value === passwordConfirmation.value
&& (passwordReqsRef.value?.allMet ?? false),
)
async function onSubmit(): Promise<void> {
errorMessage.value = ''
@@ -34,6 +48,7 @@ async function onSubmit(): Promise<void> {
return
}
if (!canSubmit.value) return
isSubmitting.value = true
try {
await apiClient.post('/auth/reset-password', {
@@ -121,7 +136,10 @@ async function onSubmit(): Promise<void> {
:append-inner-icon="showPassword ? 'tabler-eye-off' : 'tabler-eye'"
@click:append-inner="showPassword = !showPassword"
/>
<PasswordRequirements :password="password" />
<PasswordRequirements
ref="passwordReqsRef"
:password="password"
/>
</VCol>
<VCol cols="12">
@@ -131,6 +149,7 @@ async function onSubmit(): Promise<void> {
placeholder="············"
:type="showPasswordConfirmation ? 'text' : 'password'"
autocomplete="new-password"
:error-messages="confirmationError ? [confirmationError] : undefined"
:append-inner-icon="showPasswordConfirmation ? 'tabler-eye-off' : 'tabler-eye'"
@click:append-inner="showPasswordConfirmation = !showPasswordConfirmation"
/>
@@ -141,6 +160,7 @@ async function onSubmit(): Promise<void> {
block
type="submit"
:loading="isSubmitting"
:disabled="!canSubmit"
>
Wachtwoord opslaan
</VBtn>