From 617400c19f397f7232822346b8a928ec489db145 Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Thu, 15 Oct 2026 21:09:27 +0100 Subject: [PATCH] Enforce client ownership in clients CRUD put/post Non-super-admin PUT updated the client whose id equalled the user's id; it now updates the requested client only if the user owns it. POST no longer lets non-super-admins overwrite existing clients by id. Co-Authored-By: Claude Opus 5.5 --- .../api/admin/crud/(tables)/clients/post.ts | 6 ++-- .../api/admin/crud/(tables)/clients/put.ts | 35 ++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/pages/api/admin/crud/(tables)/clients/post.ts b/src/pages/api/admin/crud/(tables)/clients/post.ts index f0a5e8d..ff43d72 100644 --- a/src/pages/api/admin/crud/(tables)/clients/post.ts +++ b/src/pages/api/admin/crud/(tables)/clients/post.ts @@ -21,7 +21,7 @@ export default async function ( if (!is_user_allowed_to_post_any.success) { final_insert_data = final_insert_data.map((fid) => ({ - ...fid, + ..._.omit(fid, ["id"]), user_id: user.id, })); } @@ -29,7 +29,9 @@ export default async function ( const POST = await BunSQLite.insert({ table, data: final_insert_data, - update_on_duplicate: body?.update_on_duplicate, + update_on_duplicate: is_user_allowed_to_post_any.success + ? body?.update_on_duplicate + : false, }); return POST; diff --git a/src/pages/api/admin/crud/(tables)/clients/put.ts b/src/pages/api/admin/crud/(tables)/clients/put.ts index 13a4633..bbf9094 100644 --- a/src/pages/api/admin/crud/(tables)/clients/put.ts +++ b/src/pages/api/admin/crud/(tables)/clients/put.ts @@ -1,5 +1,6 @@ +import type { BUN_SQLITE_WGUI_CLIENTS } from "@/db/types/db"; import checkUserAccess from "@/src/functions/backend/auth/check-user-access"; -import type { AdminCrudAPIParams } from "@/src/types"; +import type { AdminCrudAPIParams, TableType } from "@/src/types"; import BunSQLite from "@moduletrace/bun-sqlite"; import type { APIResponseObject } from "@moduletrace/bunext/types"; import runClientSetup from "./(functions)/run-client-setup"; @@ -23,17 +24,41 @@ export default async function ( }); let final_sql_query = _.merge(query?.sql_query, body?.sql_query) || {}; - let targetId = id; + let update_data: BUN_SQLITE_WGUI_CLIENTS = { ...body.update_data }; if (!is_user_allowed_to_put.success) { + const existing_res = await BunSQLite.select< + BUN_SQLITE_WGUI_CLIENTS, + TableType + >({ + table: "clients", + targetId: id, + }); + + const existing = existing_res.singleRes; + + if (!existing?.id) { + return { + success: false, + msg: `Client not found`, + }; + } + + if (existing.user_id != user.id) { + return { + success: false, + msg: `Unauthorized`, + }; + } + final_sql_query = {}; - targetId = user.id; + update_data = _.omit(update_data, ["id", "user_id"]); } const PUT = await BunSQLite.update({ table, - data: body.update_data, - targetId, + data: update_data, + targetId: id, query: final_sql_query, });