fix: validate current password with a modal (#5805)

This commit is contained in:
Ariel Leyva
2026-03-06 09:26:41 -05:00
committed by GitHub
parent 4af3f85e64
commit 177c7cfcce
4 changed files with 102 additions and 25 deletions

View File

@@ -0,0 +1,58 @@
<template>
<div class="card floating">
<div class="card-title">
<h2>{{ $t("prompts.currentPassword") }}</h2>
</div>
<div class="card-content">
<p>
{{ $t("prompts.currentPasswordMessage") }}
</p>
<input
id="focus-prompt"
class="input input--block"
type="text"
@keyup.enter="submit"
v-model="password"
/>
</div>
<div class="card-action">
<button
class="button button--flat button--grey"
@click="cancel"
:aria-label="$t('buttons.cancel')"
:title="$t('buttons.cancel')"
>
{{ $t("buttons.cancel") }}
</button>
<button
@click="submit"
class="button button--flat"
type="submit"
:aria-label="$t('buttons.ok')"
:title="$t('buttons.ok')"
>
{{ $t("buttons.ok") }}
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useLayoutStore } from "@/stores/layout";
const layoutStore = useLayoutStore();
const { currentPrompt } = layoutStore;
const password = ref("");
const submit = (event: Event) => {
currentPrompt?.confirm(event, password.value);
};
const cancel = () => {
layoutStore.closeHovers();
};
</script>

View File

@@ -28,6 +28,7 @@ import ShareDelete from "./ShareDelete.vue";
import Upload from "./Upload.vue";
import DiscardEditorChanges from "./DiscardEditorChanges.vue";
import ResolveConflict from "./ResolveConflict.vue";
import CurrentPassword from "./CurrentPassword.vue";
const layoutStore = useLayoutStore();
@@ -50,6 +51,7 @@ const components = new Map<string, any>([
["deleteUser", DeleteUser],
["discardEditorChanges", DiscardEditorChanges],
["resolve-conflict", ResolveConflict],
["current-password", CurrentPassword],
]);
const modal = computed(() => {

View File

@@ -175,7 +175,9 @@
"filesInDest": "Files in destination",
"override": "Overwrite",
"skip": "Skip",
"forbiddenError": "Forbidden Error"
"forbiddenError": "Forbidden Error",
"currentPassword": "Your password",
"currentPasswordMessage": "Enter your password to validate this action."
},
"search": {
"images": "Images",

View File

@@ -15,19 +15,6 @@
:isDefault="false"
:isNew="isNew"
/>
<p v-if="isCurrentPasswordRequired">
<label for="currentPassword">{{
t("settings.currentPassword")
}}</label>
<input
class="input input--block"
type="password"
v-model="currentPassword"
id="currentPassword"
autocomplete="current-password"
/>
</p>
</div>
<div class="card-action">
@@ -77,7 +64,6 @@ const error = ref<StatusError>();
const originalUser = ref<IUser>();
const user = ref<IUser>();
const createUserDir = ref<boolean>(false);
const currentPassword = ref<string>("");
const isCurrentPasswordRequired = ref<boolean>(false);
const $showError = inject<IToastError>("$showError")!;
@@ -134,16 +120,30 @@ const fetchData = async () => {
}
};
const deletePrompt = () =>
layoutStore.showHover({ prompt: "deleteUser", confirm: deleteUser });
const deletePrompt = () => {
if (isCurrentPasswordRequired.value) {
layoutStore.showHover({
prompt: "current-password",
confirm: (event: Event, currentPassword: string) => {
event.preventDefault();
layoutStore.closeHovers();
deleteUser(currentPassword);
},
});
} else {
layoutStore.showHover({
prompt: "deleteUser",
confirm: () => deleteUser(""),
});
}
};
const deleteUser = async (e: Event) => {
e.preventDefault();
const deleteUser = async (currentPassword: string) => {
if (!user.value) {
return false;
}
try {
await api.remove(user.value.id, currentPassword.value);
await api.remove(user.value.id, currentPassword);
router.push({ path: "/settings/users" });
$showSuccess(t("settings.userDeleted"));
} catch (err) {
@@ -157,8 +157,25 @@ const deleteUser = async (e: Event) => {
return true;
};
const save = async (event: Event) => {
const save = (event: Event) => {
event.preventDefault();
if (isCurrentPasswordRequired.value) {
layoutStore.showHover({
prompt: "current-password",
confirm: (event: Event, currentPassword: string) => {
event.preventDefault();
layoutStore.closeHovers();
send(currentPassword);
},
});
} else {
send("");
}
return true;
};
const send = async (currentPassword: string) => {
if (!user.value) {
return false;
}
@@ -170,11 +187,11 @@ const save = async (event: Event) => {
...user.value,
};
const loc = await api.create(newUser, currentPassword.value);
const loc = await api.create(newUser, currentPassword);
router.push({ path: loc || "/settings/users" });
$showSuccess(t("settings.userCreated"));
} else {
await api.update(user.value, ["all"], currentPassword.value);
await api.update(user.value, ["all"], currentPassword);
if (user.value.id === authStore.user?.id) {
authStore.updateUser(user.value);
@@ -185,7 +202,5 @@ const save = async (event: Event) => {
} catch (e: any) {
$showError(e);
}
return true;
};
</script>