From 3aa5d91463efa663b67743ab1408de9f1aef496d Mon Sep 17 00:00:00 2001 From: ArielLeyva Date: Wed, 7 Jan 2026 04:21:22 -0500 Subject: [PATCH 1/2] fix: request current password when deleting users --- frontend/src/api/settings.ts | 4 ++++ frontend/src/api/users.ts | 9 ++++++++- frontend/src/views/settings/Profile.vue | 2 +- frontend/src/views/settings/User.vue | 2 +- http/http.go | 1 + http/settings.go | 8 ++++++++ http/users.go | 15 +++++++++++++-- 7 files changed, 36 insertions(+), 5 deletions(-) diff --git a/frontend/src/api/settings.ts b/frontend/src/api/settings.ts index 6f806279..a10eaa59 100644 --- a/frontend/src/api/settings.ts +++ b/frontend/src/api/settings.ts @@ -4,6 +4,10 @@ export function get() { return fetchJSON(`/api/settings`, {}); } +export function getAuthMethod() { + return fetchJSON<{ authMethod: string }>(`/api/settings/auth-method`, {}); +} + export async function update(settings: ISettings) { await fetchURL(`/api/settings`, { method: "PUT", diff --git a/frontend/src/api/users.ts b/frontend/src/api/users.ts index 56e1d0f3..0876a1ef 100644 --- a/frontend/src/api/users.ts +++ b/frontend/src/api/users.ts @@ -42,8 +42,15 @@ export async function update( }); } -export async function remove(id: number) { +export async function remove( + id: number, + currentPassword: string | null = null +) { await fetchURL(`/api/users/${id}`, { method: "DELETE", + body: JSON.stringify({ + what: "user", + ...(currentPassword != null ? { current_password: currentPassword } : {}), + }), }); } diff --git a/frontend/src/views/settings/Profile.vue b/frontend/src/views/settings/Profile.vue index 328b2f1a..3eb06706 100644 --- a/frontend/src/views/settings/Profile.vue +++ b/frontend/src/views/settings/Profile.vue @@ -142,7 +142,7 @@ onMounted(async () => { dateFormat.value = authStore.user.dateFormat; aceEditorTheme.value = authStore.user.aceEditorTheme; layoutStore.loading = false; - const { authMethod } = await settings.get(); + const { authMethod } = await settings.getAuthMethod(); isCurrentPasswordRequired.value = authMethod == "json"; return true; diff --git a/frontend/src/views/settings/User.vue b/frontend/src/views/settings/User.vue index be46fabb..4e49a5fc 100644 --- a/frontend/src/views/settings/User.vue +++ b/frontend/src/views/settings/User.vue @@ -146,7 +146,7 @@ const deleteUser = async (e: Event) => { return false; } try { - await api.remove(user.value.id); + await api.remove(user.value.id, currentPassword.value); router.push({ path: "/settings/users" }); $showSuccess(t("settings.userDeleted")); } catch (err) { diff --git a/http/http.go b/http/http.go index bb57f395..e03b5ec0 100644 --- a/http/http.go +++ b/http/http.go @@ -80,6 +80,7 @@ func NewHandler( api.PathPrefix("/share").Handler(monkey(shareDeleteHandler, "/api/share")).Methods("DELETE") api.Handle("/settings", monkey(settingsGetHandler, "")).Methods("GET") + api.Handle("/settings/auth-method", monkey(authMethodGetHandler, "")).Methods("GET") api.Handle("/settings", monkey(settingsPutHandler, "")).Methods("PUT") api.PathPrefix("/raw").Handler(monkey(rawHandler, "/api/raw")).Methods("GET") diff --git a/http/settings.go b/http/settings.go index a07d322e..2ec438a6 100644 --- a/http/settings.go +++ b/http/settings.go @@ -42,6 +42,14 @@ var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, return renderJSON(w, r, data) }) +var authMethodGetHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + data := &settingsData{ + AuthMethod: d.settings.AuthMethod, + } + + return renderJSON(w, r, data) +} + var settingsPutHandler = withAdmin(func(_ http.ResponseWriter, r *http.Request, d *data) (int, error) { req := &settingsData{} err := json.NewDecoder(r.Body).Decode(req) diff --git a/http/users.go b/http/users.go index adae7729..a1ebf9bd 100644 --- a/http/users.go +++ b/http/users.go @@ -103,8 +103,19 @@ var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request return renderJSON(w, r, u) }) -var userDeleteHandler = withSelfOrAdmin(func(_ http.ResponseWriter, _ *http.Request, d *data) (int, error) { - err := d.store.Users.Delete(d.raw.(uint)) +var userDeleteHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + req, err := getUser(w, r) + if err != nil { + return http.StatusBadRequest, err + } + + if d.settings.AuthMethod == auth.MethodJSONAuth { + if !users.CheckPwd(req.CurrentPassword, d.user.Password) { + return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect + } + } + + err = d.store.Users.Delete(d.raw.(uint)) if err != nil { return errToStatus(err), err } From ce81b8bcabaeef11b1ecb668b6fee6462ad3218f Mon Sep 17 00:00:00 2001 From: ArielLeyva Date: Thu, 8 Jan 2026 09:55:41 -0500 Subject: [PATCH 2/2] fix: get auth method from the frontend constants --- frontend/src/api/settings.ts | 4 ---- frontend/src/views/settings/Profile.vue | 4 ++-- frontend/src/views/settings/User.vue | 7 ++----- http/http.go | 1 - http/settings.go | 8 -------- 5 files changed, 4 insertions(+), 20 deletions(-) diff --git a/frontend/src/api/settings.ts b/frontend/src/api/settings.ts index a10eaa59..6f806279 100644 --- a/frontend/src/api/settings.ts +++ b/frontend/src/api/settings.ts @@ -4,10 +4,6 @@ export function get() { return fetchJSON(`/api/settings`, {}); } -export function getAuthMethod() { - return fetchJSON<{ authMethod: string }>(`/api/settings/auth-method`, {}); -} - export async function update(settings: ISettings) { await fetchURL(`/api/settings`, { method: "PUT", diff --git a/frontend/src/views/settings/Profile.vue b/frontend/src/views/settings/Profile.vue index 3eb06706..6028acd6 100644 --- a/frontend/src/views/settings/Profile.vue +++ b/frontend/src/views/settings/Profile.vue @@ -96,11 +96,12 @@