feat(admin): expose the two document-vault limits

The admin settings GET/PUT carry documentMaxFileBytes (1 MiB – 100 MiB;
the hard ceiling exists because single-shot GCM + bounded in-memory reads
are load-bearing past it, and the upload-time resolver clamps again as
defence-in-depth) and documentQuotaBytes (10 MiB – 1 TiB instance
default). The admin user PUT accepts a nullable per-user quota override;
null clears it back to the instance default. Cookie-only requireAdmin()
guards both surfaces as before — Bearer tokens cannot reach them.

Task: W1-T13.
This commit is contained in:
Marc-André Bombeck committed 2026-07-07 11:06:04 +02:00
1 parent de9e528614
commit 155b74ccf4
3 files changed
+62 -1

No files matched your search

+25 -1
View File
@@ -19,6 +19,16 @@ const updateUserSchema = z.object({
// v1.23 — per-user "require a second factor" override. Effective requirement
// is the OR of this and the instance-wide AppSettings.mfaRequired policy.
mfaEnforced: z.boolean().optional(),
// Document vault — per-user storage-quota override in bytes. Null clears
// the override (the instance default applies again). Same bounds as the
// instance-wide setting.
documentQuotaBytes: z
.number()
.int()
.min(10_485_760)
.max(1_099_511_627_776)
.nullable()
.optional(),
});
export const PUT = apiHandler(
@@ -70,6 +80,12 @@ export const PUT = apiHandler(
...(parsed.data.mfaEnforced !== undefined && {
mfaEnforced: parsed.data.mfaEnforced,
}),
...(parsed.data.documentQuotaBytes !== undefined && {
documentQuotaBytes:
parsed.data.documentQuotaBytes === null
? null
: BigInt(parsed.data.documentQuotaBytes),
}),
},
select: {
id: true,
@@ -78,6 +94,7 @@ export const PUT = apiHandler(
role: true,
createdAt: true,
mfaEnforced: true,
documentQuotaBytes: true,
},
});
@@ -87,6 +104,13 @@ export const PUT = apiHandler(
details: { targetUserId: id, changes: parsed.data },
});
return apiSuccess(updatedUser);
return apiSuccess({
...updatedUser,
// BigInt → Number for the JSON envelope; null = no override.
documentQuotaBytes:
updatedUser.documentQuotaBytes === null
? null
: Number(updatedUser.documentQuotaBytes),
});
},
);