Files
EasyTier/easytier-web/frontend/src/components/ChangePassword.vue
T
fanyang 3f3e36e653 feat(web): warn on default-password accounts
Track built-in admin and user accounts that still use their
seeded password so the web UI can prompt operators to
rotate credentials after deployment.

- Persist must-change-password state for seeded accounts.
- Clear the reminder after password changes and validate
  empty-password updates.
- Keep the migration and auth API behavior explicit.
2026-04-05 17:31:22 +08:00

71 lines
2.2 KiB
Vue

<script lang="ts" setup>
import { computed, inject, ref } from 'vue';
import { Card, Password, Button } from 'primevue';
import { useToast } from 'primevue/usetoast';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import ApiClient from '../modules/api';
import { clearMustChangePasswordFlag } from '../modules/auth-status';
const dialogRef = inject<any>('dialogRef');
const api = computed<ApiClient>(() => dialogRef.value.data.api);
const password = ref('');
const toast = useToast();
const router = useRouter();
const { t } = useI18n();
const passwordIsEmpty = computed(() => password.value.trim().length === 0);
const changePassword = async () => {
if (passwordIsEmpty.value) {
toast.add({
severity: 'warn',
summary: t('web.common.warning'),
detail: t('web.settings.new_password_empty'),
life: 3000,
});
return;
}
try {
await api.value.change_password(password.value);
toast.add({
severity: 'success',
summary: t('web.common.success'),
detail: t('web.main.password_changed_relogin'),
life: 3000,
});
clearMustChangePasswordFlag();
dialogRef.value.close();
router.push({ name: 'login' });
} catch (error) {
toast.add({
severity: 'error',
summary: t('web.common.error'),
detail: error instanceof Error ? error.message : String(error),
life: 3000,
});
}
}
</script>
<template>
<div class="flex items-center justify-center">
<Card class="w-full max-w-md p-6">
<template #header>
<h2 class="text-2xl font-semibold text-center">{{ t('web.main.change_password') }}
</h2>
</template>
<template #content>
<div class="flex flex-col space-y-4">
<Password v-model="password" :placeholder="t('web.settings.new_password')" :feedback="false"
toggleMask />
<Button @click="changePassword" :label="t('web.common.confirm')"
:disabled="passwordIsEmpty" />
</div>
</template>
</Card>
</div>
</template>