Implement password change function

This commit is contained in:
2025-07-16 08:42:09 +02:00
parent 37f381c884
commit f518723a0e
10 changed files with 219 additions and 48 deletions

View File

@ -0,0 +1,113 @@
<template>
<div class="space-y-4">
<form @submit.prevent="changePassword" ref="passwordChangeForm">
<sl-input
label="Current password"
type="password"
autocomplete="current-password"
placeholder="Current Password"
required
help-text="Enter your current password"
:value="currentPassword"
@input="checkCurrent"
@sl-input="currentPassword = $event.target.value"
ref="currentPasswordField"
password-toggle
></sl-input>
<sl-input
label="New Password"
type="password"
required
placeholder="New Password"
autocomplete="new-password"
help-text="Enter your new password"
:value="newPassword"
@sl-input="newPassword = $event.target.value"
ref="newPasswordField"
password-toggle
></sl-input>
<sl-input
label="New Password (repeat)"
type="password"
required
placeholder="New Password"
autocomplete="new-password"
help-text="Confirm your new password by typing it again"
:value="newPasswordConfirm"
@sl-input="newPasswordConfirm = $event.target.value"
@blur="checkPasswords"
ref="newPasswordFieldConfirm"
password-toggle
></sl-input>
<sl-button class="mr-4" type="submit" variant="primary">Change Password</sl-button>
<sl-button variant="default" @click="cancelChangePassword">Cancel</sl-button>
</form>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useAlertsStore } from '@/store/useAlertsStore'
import { SshecretAdmin } from '@/client'
import type { UserPasswordChange } from '@/client'
import { assertSdkResponseOk } from '@/api/assertSdkResponseOk'
import { ApiError, ValidationError } from '@/api/errors'
import { setFieldValidation } from '@/api/validation'
const currentPassword = ref<string>('')
const newPassword = ref<string>('')
const newPasswordConfirm = ref<string>('')
const passwordChangeForm = ref<HTMLFormElement>()
const currentPasswordField = ref<SlInput>()
const newPasswordField = ref<SlInput>()
const newPasswordFieldConfirm = ref<Slinput>()
const alerts = useAlertsStore()
const emit = defineEmits<{ (e: 'changed'): void; (e: 'cancel'): void }>()
function checkCurrent() {
setFieldValidation(currentPasswordField)
currentPasswordField.value.reportValidity()
}
function checkPasswords() {
if (newPassword.value !== newPasswordConfirm.value) {
setFieldValidation(newPasswordFieldConfirm, 'Passwords do not match match')
} else {
setFieldValidation(newPasswordFieldConfirm)
}
}
function resetForm() {
passwordChangeForm.value?.reset()
}
function cancelChangePassword() {
resetForm()
emit('cancel')
}
async function changePassword() {
const data: UserPasswordChange = {
current_password: currentPassword.value,
new_password: newPassword.value,
new_password_confirm: newPasswordConfirm.value,
}
const response = await SshecretAdmin.changePasswordApiV1PasswordPost({ body: data })
try {
assertSdkResponseOk(response)
emit('changed')
resetForm()
} catch (err) {
if (err instanceof ValidationError) {
// This should be caught in js, but we might as well
setFieldValidation(newPasswordFieldConfirm, 'Passwords do not match match')
} else if (err instanceof ApiError && err.message.includes('Invalid current password')) {
setFieldValidation(currentPasswordField, 'Invalid current password')
} else {
alerts.showAlert(err.message, 'error', 'Error changing password')
}
}
}
</script>