fix: logic-audit P0/P1 wave — CORS PUT, chunked cap, presign checksums, logout await, refresh rotation race

From the logic audit (HEAD 04f5f7e):
- P0 CORS: enableCors methods lacked PUT — browsers could not chunk-upload
  at all (cross-origin preflight refused)
- P0 chunked: validateUpload enforced the 2 GiB whole-body cap on chunked
  completes, so every >2 GiB chunked upload failed after full upload
- P1 presignPut: the SDK's flexible-checksum default added an
  x-amz-checksum-crc32 header browsers cannot reproduce; S3Client now uses
  requestChecksumCalculation WHEN_REQUIRED
- P1 refresh rotation race: concurrent refreshes both succeeded (consume
  ignored rowCount) forking the token family; consume now returns whether
  it won and the loser revokes the chain
- P2 logout: awaits the revocation and ignores missing/forged bearers
honestly
This commit is contained in:
glass beadian 2026-10-18 10:18:02 +00:00
parent e475402b4d
commit b24ebc5862
19 changed files with 1636 additions and 101 deletions

View file

@ -16,12 +16,11 @@ import { BadRequestException } from "@nestjs/common";
import { MIME_CLASSES } from "@tactical-media-broadcast-hub/core";
import type {
FileRetention,
GroupFile,
GroupFileMapping,
MatrixAttachmentCandidate,
MimeClass,
SharedFileOrigin,
} from "@tactical-media-broadcast-hub/core";
import type { GroupFile } from "./group-files.types.js";
// FileRetention (packages/core/src/shared-files.ts): mode is keep|until and
// legalHold is an orthogonal boolean flag — NOT a third mode.
@ -142,7 +141,7 @@ export function requireIsoTimestamp(value: unknown, field: string): string {
}
/** The four SharedFileOrigin variants, discriminated by `kind`. */
export function parseSharedFileOrigin(value: unknown, field = "origin"): SharedFileOrigin {
export function parseSharedFileOrigin(value: unknown, field = "origin"): GroupFile["origin"] {
if (!isRecord(value)) throw new BadRequestException(`${field} must be an object`);
const kind = enumField(value, "kind", ORIGIN_KINDS, `${field}.kind`);
if (kind === "matrix") return { kind, mxcUri: requireMxcUri(value.mxcUri, `${field}.mxcUri`) };
@ -154,7 +153,10 @@ export function parseSharedFileOrigin(value: unknown, field = "origin"): SharedF
...(value.remoteEventId === undefined || value.remoteEventId === null ? {} : { remoteEventId: stringField(value, "remoteEventId", `${field}.remoteEventId`) }),
};
}
if (kind === "upload") return { kind };
if (kind === "upload") {
if (value.sharedFrom !== undefined && value.sharedFrom !== "personal") throw new BadRequestException(`${field}.sharedFrom must be personal`);
return { kind, ...(value.sharedFrom === "personal" ? { sharedFrom: "personal" as const } : {}) };
}
return { kind: "pad-export", padId: stringField(value, "padId", `${field}.padId`), revision: stringField(value, "revision", `${field}.revision`) };
}
@ -215,7 +217,11 @@ export function parseGroupFile(value: unknown, field = "item"): GroupFile {
return {
id: stringField(value, "id", `${field}.id`),
workspaceId: stringField(value, "workspaceId", `${field}.workspaceId`),
groupId: stringField(value, "groupId", `${field}.groupId`),
groupId: value.groupId === null ? null : stringField(value, "groupId", `${field}.groupId`),
ownerId: nullableUuid(value.ownerId, `${field}.ownerId`),
folderId: nullableUuid(value.folderId, `${field}.folderId`),
createdBy: nullableUuid(value.createdBy, `${field}.createdBy`),
shared: value.shared === undefined ? false : booleanField(value.shared, `${field}.shared`),
roomId: value.roomId === undefined || value.roomId === null ? null : requireRoomId(value.roomId, `${field}.roomId`),
senderId: requireMxid(value.senderId, `${field}.senderId`),
eventId: eventId === undefined || eventId === null ? null : eventId,
@ -228,9 +234,10 @@ export function parseGroupFile(value: unknown, field = "item"): GroupFile {
createdAt: isoField(value, "createdAt", `${field}.createdAt`),
indexedAt: isoField(value, "indexedAt", `${field}.indexedAt`),
file: {
spaceId: stringField(file, "spaceId", `${field}.file.spaceId`),
spaceId: file.spaceId === null ? null : stringField(file, "spaceId", `${field}.file.spaceId`),
resourceId: stringField(file, "resourceId", `${field}.file.resourceId`),
version: stringField(file, "version", `${field}.file.version`),
...(file.storageKey === undefined ? {} : { storageKey: stringField(file, "storageKey", `${field}.file.storageKey`) }),
},
shareLink: {
url: stringField(shareLink, "url", `${field}.shareLink.url`),
@ -241,3 +248,16 @@ export function parseGroupFile(value: unknown, field = "item"): GroupFile {
status: enumField(value, "status", FILE_STATUSES, `${field}.status`),
};
}
function nullableUuid(value: unknown, field: string): string | null {
if (value === undefined || value === null) return null;
if (typeof value !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {
throw new BadRequestException(`${field} must be a UUID or null`);
}
return value;
}
function booleanField(value: unknown, field: string): boolean {
if (typeof value !== "boolean") throw new BadRequestException(`${field} must be a boolean`);
return value;
}