Harden archive bot for production; exempt container egress in edge firewall
- archive_sync_state keyed by room per migration 029 (drop synthetic id cursor) - putStaging buffers the stream and sends content-length (oCIS rejects chunked) - mimeClass passthrough from sniffed payload - edge-firewall: RETURN docker-bridge ingress before the CF-range catch-all so container egress (Matrix/R2/platform) survives the 80/443 source filter - files scaffold: keep the ocdav data-gateway hop on-loopback
This commit is contained in:
parent
23bd4dd5ad
commit
2cb77ae6b4
9 changed files with 211 additions and 38 deletions
|
|
@ -7,7 +7,7 @@ import type { MatrixEvent, RoomEncryption } from "./events.js";
|
|||
import { claimKey, replyTxnId } from "./keys.js";
|
||||
import type { MatrixPort, MediaDownload, SyncResult } from "./matrix.js";
|
||||
import { ArchiveProcessor } from "./processor.js";
|
||||
import type { ArchiveRecord, ArchiveStore, OutboxRow } from "./store.js";
|
||||
import type { ArchiveRecord, ArchiveStore, OutboxRow, RoomCursorTarget } from "./store.js";
|
||||
import type { LibraryPort, LibraryResource } from "./webdav.js";
|
||||
|
||||
const mapping: RoomMapping = {
|
||||
|
|
@ -87,12 +87,14 @@ class FakeLibrary implements LibraryPort {
|
|||
|
||||
class FakeStore implements ArchiveStore {
|
||||
cursor: string | null = null;
|
||||
roomsSaved = new Set<string>();
|
||||
outbox = new Map<string, OutboxRow & { claimKey: string }>();
|
||||
archive: (ArchiveRecord & { available: boolean })[] = [];
|
||||
async loadCursor(): Promise<string | null> {
|
||||
async loadCursor(_rooms: readonly RoomCursorTarget[]): Promise<string | null> {
|
||||
return this.cursor;
|
||||
}
|
||||
async saveCursor(_ws: readonly string[], cursor: string): Promise<void> {
|
||||
async saveCursor(rooms: readonly RoomCursorTarget[], cursor: string): Promise<void> {
|
||||
for (const room of rooms) this.roomsSaved.add(room.roomId);
|
||||
this.cursor = cursor;
|
||||
}
|
||||
async claim(_ws: string, _room: string, _event: string, key: string): Promise<OutboxRow> {
|
||||
|
|
@ -165,6 +167,7 @@ describe("ArchiveProcessor", () => {
|
|||
expect(await processor.runBatch(signal)).toEqual({ advanced: true, retryAt: null });
|
||||
|
||||
expect(store.cursor).toBe("s1");
|
||||
expect([...store.roomsSaved]).toEqual([mapping.roomId]);
|
||||
expect(store.archive).toHaveLength(1);
|
||||
const row = store.archive[0];
|
||||
expect(row).toMatchObject({ mime: "image/png", mimeClass: "image", safeName: "cat.png", originalName: "../cat", byteSize: PNG.byteLength });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue