From f23a759c20a0bcdabd8cb561e511c25a22597360 Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:00:23 -0300 Subject: [PATCH] test(api): session fixture mints the login shape; changelog covers SEC-C/SEC-D Refs #12969 --- .../fixes/12969-batches-delete-completed-ownership.md | 2 +- src/lib/db/batches.ts | 6 +++--- tests/unit/batches-delete-completed-route-scope.test.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/changelog.d/fixes/12969-batches-delete-completed-ownership.md b/changelog.d/fixes/12969-batches-delete-completed-ownership.md index da4081d555..e602446524 100644 --- a/changelog.d/fixes/12969-batches-delete-completed-ownership.md +++ b/changelog.d/fixes/12969-batches-delete-completed-ownership.md @@ -1 +1 @@ -- **fix(api):** `DELETE /v1/batches/delete-completed` now sweeps only the calling API key's own completed batches (batches with no owner stay out of a key-scoped sweep on purpose), with an explicit instance-wide mode reserved for authenticated dashboard sessions, a 401 for a presented key that is unknown, revoked, deactivated, banned or expired (never falling through to the session branch), audit logging of every sweep, a sanitized 500 on failure and an atomic sweep so a mid-way error never leaves a batch pointing at a nulled file (GHSA-wvxc-jp3v-5mg5) ([#12969](https://github.com/diegosouzapw/OmniRoute/pull/12969)) +- **fix(api):** `DELETE /v1/batches/delete-completed` now sweeps only the calling API key's own completed batches (batches with no owner stay out of a key-scoped sweep on purpose), with an explicit instance-wide mode reserved for authenticated dashboard sessions, a 401 for a presented key that is unknown, revoked, deactivated, banned or expired (never falling through to the session branch), audit logging of every sweep, a sanitized 500 on failure, an owner-scoped file half (a key-scoped sweep never nulls a file another tenant owns) and an atomic sweep — chunked in 200-batch transactions in instance mode — so a mid-way error never leaves a batch pointing at a nulled file (GHSA-wvxc-jp3v-5mg5) ([#12969](https://github.com/diegosouzapw/OmniRoute/pull/12969)) diff --git a/src/lib/db/batches.ts b/src/lib/db/batches.ts index bcdf31ed1a..b981c511d0 100644 --- a/src/lib/db/batches.ts +++ b/src/lib/db/batches.ts @@ -421,6 +421,9 @@ export function deleteBatch(id: string): boolean { */ export type DeleteCompletedBatchesScope = { apiKeyId: string } | { allTenants: true }; +/** Instance-wide sweeps commit in chunks of this many batches (SEC-D). */ +export const INSTANCE_SWEEP_CHUNK = 200; + /** * Delete completed batches and the files they reference. * @@ -457,9 +460,6 @@ export type DeleteCompletedBatchesScope = { apiKeyId: string } | { allTenants: t * list is bounded by that key's completed batches — should a single key ever * own more than ~32k completed batches, chunk key mode the same way. */ -/** Instance-wide sweeps commit in chunks of this many batches (SEC-D). */ -export const INSTANCE_SWEEP_CHUNK = 200; - export function deleteCompletedBatches(scope: DeleteCompletedBatchesScope): { deletedBatches: number; deletedFiles: number; diff --git a/tests/unit/batches-delete-completed-route-scope.test.ts b/tests/unit/batches-delete-completed-route-scope.test.ts index 5fdf9c7755..421db2064d 100644 --- a/tests/unit/batches-delete-completed-route-scope.test.ts +++ b/tests/unit/batches-delete-completed-route-scope.test.ts @@ -49,7 +49,7 @@ const ROUTE_URL = "http://localhost/api/v1/batches/delete-completed"; async function sessionCookie(): Promise { const secret = new TextEncoder().encode(process.env.JWT_SECRET); - const jwt = await new SignJWT({ sub: "admin" }) + const jwt = await new SignJWT({ authenticated: true, sub: "admin" }) .setProtectedHeader({ alg: "HS256" }) .setExpirationTime("1h") .sign(secret);