fix(auth): allow API keys to delete/edit archives via new can_manage_archives scope (#1888)

DELETE /api/v1/archives/{id} rejected every API key with 403
"API keys cannot be used for administrative operations", regardless of
the print's owner or the key's scopes. ARCHIVES_DELETE_ALL/_OWN (and the
create/update variants) were on the denylist and absent from the scope
allowlist, so require_ownership_permission fell through to the generic
admin-denied 403 — the whole archive-management surface was unreachable
for API keys. Same regression class as the #1832 library/maintenance
carve-outs.

Add a can_manage_archives per-key scope: ARCHIVES_CREATE, ARCHIVES_
UPDATE_OWN/_ALL and ARCHIVES_DELETE_OWN/_ALL move from the denylist to
the allowlist under it (OWN and ALL fold into the same scope, matching
can_manage_library). ARCHIVES_PURGE stays admin-only — it drops the
print's Quick Stats contribution, mirroring LIBRARY_PURGE. Column
defaults TRUE for UI-created keys; existing rows backfill to FALSE so the
upgrade never silently widens scope. Bundled SpoolBuddy kiosk key stays
minimally scoped (False). Migration is dialect-agnostic and verified on
fresh SQLite and Postgres 17.

Adds the Settings API-key toggle + badge (11-locale i18n) and extends the
RBAC scope matrix to cover all five archive-management permissions.
This commit is contained in:
maziggy
2026-07-03 08:01:54 +02:00
parent 0452b25750
commit 6358e9544e
23 changed files with 142 additions and 19 deletions
+3
View File
@@ -1049,6 +1049,7 @@ export interface APIKey {
can_manage_library: boolean;
can_manage_inventory: boolean;
can_manage_maintenance: boolean;
can_manage_archives: boolean;
can_access_cloud: boolean;
can_update_energy_cost: boolean;
printer_ids: number[] | null;
@@ -1066,6 +1067,7 @@ export interface APIKeyCreate {
can_manage_library?: boolean;
can_manage_inventory?: boolean;
can_manage_maintenance?: boolean;
can_manage_archives?: boolean;
can_access_cloud?: boolean;
can_update_energy_cost?: boolean;
printer_ids?: number[] | null;
@@ -1084,6 +1086,7 @@ export interface APIKeyUpdate {
can_manage_library?: boolean;
can_manage_inventory?: boolean;
can_manage_maintenance?: boolean;
can_manage_archives?: boolean;
can_access_cloud?: boolean;
can_update_energy_cost?: boolean;
printer_ids?: number[] | null;