Hoppa till huvudinnehåll

Lagring av tilläggsfiler

Lagring av tilläggsfiler låter ett aktiverat tillägg ladda upp bildfiler som tillhör en låst tilläggssession.

Använd den när JSON-tilläggsstatus inte är tillräckligt, till exempel:

  • pusselbilder
  • genererade förhandsvisningar
  • utmaningsfoton
  • tilläggsspecifik media som bör rensas med lås/session

Denna lagring är separat från state.*. Använd state.* för små JSON-data. Använd fillagring endast för binära medier.

Relation till tillståndsändpunkter

Tilläggets tillstånd är för JSON med liten sessionsomfattning. Använd kommandot bridge read från en iframe istället för att anropa REST direkt:

state.get

Den bryggkommandorutten till:

GET /api/extensions/sessions/:sessionId/state

Direkta backend-anrop för att skriva tillstånd använder autentiseringsmodellen för installerade extensions-API:er:

Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Skicka inte utvecklar-API-nycklar till iframe/webbläsarkod.

Använd backend-skrivet tillstånd för varaktiga referenser och UI-data, till exempel:

{
"puzzleImageFileId": "file_record_id",
"selectedImageIds": ["file_record_id"],
"lastOpenedTab": "images"
}

Lagra inte binära data, base64-bilder, webbläsarens blob:-URL:er eller långlivade kopior av signedUrl i tillståndet. Signerade URL:er upphör att gälla och bör uppdateras med files.get när bilden renderas. Tillståndsskrivningar begränsas av tilläggsappens stateMaxBytes-inställning, som standard är 64 KiB.

Lagringsmodell

Chastify lagrar tilläggsfiler i Chastify-hanterad R2-lagring.

Varje uppladdad fil spåras med:

  • scope: "extension"
  • appId
  • sessionId och lockId för runtime-/sessionsfiler
  • templateId för filer som anspråk gjorts av en sparad låsmall
  • staged, draftId och expiresAt för installationsuppladdningar som ännu inte har gjorts anspråk på
  • extensionKey
  • purpose

Admin Gate och kvoter

Konfigurera mellanlagringsslutpunkter

Använd endast installationsintervall när ett installationsgränssnitt körs innan en tilläggssession finns.

Detta är ett tillfälligt uppladdningsflöde. Det finns för installations-/konfigurationsskärmar där användaren kan ladda upp en fil och sedan stänga modalfönstret eller inaktivera tillägget innan en låsning/session skapas. En mellanlagrad fil är inte hållbar förrän den antas genom att spara tilläggskonfigurationen som refererar till den.

Installationsgränssnitt kan kontrollera tillgänglighet och aktuell stegvis användning innan uppladdningskontroller renderas:

GET /api/extensions/apps/:appId/files/capabilities

Svaret inkluderar stagedQuota för den aktuella användarens oförfallna mellanlagrade filer i den tilläggsappen:

{
"enabled": true,
"provider": "r2",
"r2Configured": true,
"supportsStagedSetupFiles": true,
"stagedQuota": {
"bytesUsed": 123456,
"fileCount": 1,
"maxBytes": 10485760,
"remainingBytes": 10362304
}
}
POST /api/extensions/apps/:appId/files/stage
Content-Type: multipart/form-data

Formulärfält:

  • file: obligatorisk bildfil
  • purpose: valfri kort identifierare såsom jigsaw-config-image
  • draftId: valfritt utkast-ID för installation; återanvänd samma värde medan en installationsmodal är öppen

Svaret innehåller en stabil file.id och en kortlivad signerad URL för omedelbar förhandsgranskning.

Exempelsvar:

{
"file": {
"id": "file_record_id",
"signedUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"publicUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"urlExpiresAt": "2026-05-28T12:10:00.000Z",
"sizeBytes": 123456,
"originalName": "puzzle.jpg",
"mimeType": "image/webp",
"purpose": "jigsaw-config-image",
"uploadedAt": "2026-05-28T12:00:00.000Z"
},
"stagedQuota": {
"bytesUsed": 123456,
"fileCount": 1,
"maxBytes": 10485760,
"remainingBytes": 10362304
}
}

För att återställa installationsuppladdningar efter en siduppdatering, lista mellanlagrade filer för den aktuella användaren och tilläggsappen:

GET /api/extensions/apps/:appId/files/staged?purpose=jigsaw-config-image

Valfria frågeparametrar:

  • purpose: returnera endast mellanlagrade filer för ett installationsfall
  • draftId: returnerar endast filer från ett känt installationsutkast

Om draftId utelämnas returnerar Chastify den aktuella användarens oförutsedda mellanlagrade filer för den appen. Detta är avsiktligt för installationsgränssnitt: en användare kan ladda upp filer, ladda om sidan eller byta enhet, och installationsskärmen kan återställa dessa tillfälliga uppladdningar innan låset/mallen sparas.

Svaret för den etappade listan inkluderar även stagedQuota, som rapporterar den aktuella användarens oförutsedda etappade användning för den appen:

{
"items": [],
"stagedQuota": {
"bytesUsed": 123456,
"fileCount": 1,
"maxBytes": 10485760,
"remainingBytes": 10362304
}
}

Installationsgränssnitten kan också uppdatera eller ta bort en mellanlagrad fil:

GET /api/extensions/apps/:appId/files/:fileId
DELETE /api/extensions/apps/:appId/files/staged/:fileId

Anspråk på mellanlagrade filer senare

Det finns ingen separat "anspråks"-slutpunkt på webbläsarsidan. En mellanlagrad fil anspråks automatiskt när Chastify sparar en lås- eller malltilläggskonfiguration som refererar till den mellanlagrade filen.

Dessa rutter gör anspråk på mellanlagrade filer efter att lås-/malldokumentet har ett ID, och sparar sedan tilläggskonfigurationen igen med de anspråkade filreferenserna. Om anspråket misslyckas återställs det nyskapade låset/mallen så att mellanlagrade filer inte lämnas kvar kopplade till en trasig konfiguration.

Obs om delad mall: accepterade delade lås behåller källmall-ID:t på det klonade aktiva låset. Mallanspråktagna filer behålls därför medan eventuella klonade lås fortfarande refererar till den mallen. Om källmallen tas bort, fördröjer Chastify borttagningen av dess tilläggsfiler tills det sista klonade låset som refererar till den borttagna mallen har tagits bort eller arkiverats.

För att göra en mellanlagrad fil anspråkbar, lagra en referens som denna i tilläggskonfigurationen som skickas av installationsgränssnittet:

{
"storageDraftId": "draft_123",
"images": [
{
"id": "file_record_id",
"provider": "chastify_storage",
"fileId": "file_record_id",
"url": "extension-file:file_record_id",
"title": "Puzzle image"
}
]
}

Vid sparning skannar Chastify konfigurationen efter provider: "chastify_storage"-poster med en giltig fileId och gör sedan följande:

  • verifierar att filen tillhör den aktuella användaren och tilläggsappen
  • avvisar utgångna, mellanlagrade filer
  • avvisar filer som redan har gjorts anspråk på av en annan lås-/mallkontext
  • markerar refererade mellanlagrade filer som anspråk
  • binder anspråkgjorda filer till det sparade låset eller mallen
  • tar bort de tillfälliga fälten signedUrl, publicUrl och urlExpiresAt innan konfigurationen sparas
  • tar bort orefererade mellanlagrade filer från samma storageDraftId

Övergivna mellanlagrade filer som aldrig sparas raderas genom rensning efter att de har löpt ut.

Så här uppdaterar du en förhandsgranskning av installationen för ett fil-ID som ägs av den aktuella användaren och tilläggsappen:

GET /api/extensions/apps/:appId/files/:fileId

Sessionsslutpunkter

Dessa slutpunkter kräver normal auktorisering och omfång för tilläggssessioner.

Basväg:

/api/extensions/sessions/:sessionId/files

Förmågor

Kontrollera detta innan du renderar uppladdningskontroller.

GET /api/extensions/sessions/:sessionId/files/capabilities

Kräver locks:read.

Exempelsvar:

{
"enabled": true,
"provider": "r2",
"r2Configured": true,
"settings": {
"enabled": true,
"maxFileBytes": 10485760,
"maxBytesPerApp": 524288000,
"maxBytesPerSession": 52428800,
"maxStagedBytesPerUserPerApp": 10485760,
"allowedMimePrefixes": ["image/"]
}
}

Lista filer

GET /api/extensions/sessions/:sessionId/files

Kräver locks:read.

Exempelsvar:

{
"items": [
{
"id": "file_record_id",
"signedUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"publicUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"urlExpiresAt": "2026-05-28T12:10:00.000Z",
"sizeBytes": 123456,
"originalName": "puzzle.jpg",
"mimeType": "image/webp",
"purpose": "puzzle-image",
"uploadedAt": "2026-05-28T12:00:00.000Z"
}
]
}

Hämta en fil

Använd detta när ditt tillägg redan har ett lagrat fil-ID och bara behöver en ny signerad R2-länk.

GET /api/extensions/sessions/:sessionId/files/:fileId

Kräver locks:read.

Filen måste tillhöra samma tilläggsapp, session och lås.

Exempelsvar:

{
"file": {
"id": "file_record_id",
"signedUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"publicUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"urlExpiresAt": "2026-05-28T12:10:00.000Z",
"sizeBytes": 123456,
"originalName": "puzzle.jpg",
"mimeType": "image/webp",
"purpose": "puzzle-image",
"uploadedAt": "2026-05-28T12:00:00.000Z"
}
}

Ladda upp fil

POST /api/extensions/sessions/:sessionId/files
Content-Type: multipart/form-data

Kräver locks:write.

Formulärfält:

  • file: obligatorisk bildfil
  • purpose: valfri kort identifierare såsom puzzle-image eller preview

Exempel:

curl "https://chastify.net/api/extensions/sessions/SESSION_ID/files" \
-X POST \
-F "purpose=puzzle-image" \

Exempelsvar:

{
"file": {
"id": "file_record_id",
"signedUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"publicUrl": "https://chastify.<account-id>.r2.cloudflarestorage.com/extensions/abc.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
"urlExpiresAt": "2026-05-28T12:10:00.000Z",
"sizeBytes": 123456,
"originalName": "puzzle.jpg",
"mimeType": "image/webp",
"purpose": "puzzle-image",
"uploadedAt": "2026-05-28T12:00:00.000Z"
}
}

Vanliga uppladdningsfel:

  • extension_file_storage_disabled
  • extension_file_storage_requires_r2
  • file_too_large
  • invalid_file_type
  • extension_app_storage_quota_exceeded
  • extension_session_storage_quota_exceeded
  • extension_staged_user_app_storage_quota_exceeded

Ta bort fil

DELETE /api/extensions/sessions/:sessionId/files/:fileId

Kräver locks:write.

Filen måste tillhöra samma tilläggsapp, session och lås.

Iframe-bryggåtgärder

Iframe-tillägg kan använda den överordnade webbbryggan för läsning av runtime-filer. Uppladdning och borttagning av runtime-filer är sessionsmutationer och bör utföras av din backend med en app-scope Developer API-nyckel plus x-chastify-main-token.

const capabilities = await bridge.request("files.capabilities", {});

const refreshed = await bridge.request("files.get", {
fileId: "file_record_id"
});

image.src = refreshed.file.signedUrl;

Stödda bryggåtgärder:

  • files.capabilities -> kontrollera om fillagring är aktiverad och vilka kvoter som gäller
  • files.list -> lista filer som ägs av den aktuella tilläggssessionen
  • files.get -> uppdatera en signerad R2-URL från ett lagrat fil-ID

Installations-iframes kan använda ytterligare bryggnamn innan en runtime-session existerar. I installationsläge skapar files.upload mellanlagrade filer, files.list/files.staged.list listar outgångna mellanlagrade filer för den aktuella användaren och appen, och files.delete tar bort en mellanlagrad fil. Installations-init-kontexten inkluderar storageDraftId; inkludera det värdet i din sparade konfiguration som storageDraftId om du vill att Chastify ska rensa orefererade filer från samma utkast omedelbart när det sparas.

Installationsprogrammet files.upload accepterar även dataUrl för enkla iframe-klienter:

await bridge.request("files.upload", {
dataUrl: canvas.toDataURL("image/webp", 0.9),
filename: "preview.webp",
purpose: "preview"
}, 60000);

Föredra uppladdningar av File eller Blob när det är möjligt. Använd endast dataUrl för små genererade bilder eftersom base64-nyttolaster är större i minnet.

Den stabila filidentifieraren är id.

Använd signedUrl för att visa eller ladda ner filen. Signerade länkar är kortlivade R2 GetObject-URL:er som genereras av Chastify. publicUrl behålls som ett kompatibilitetsalias och innehåller för närvarande samma signerade URL.

När en signerad länk upphör att gälla, anropa GET /api/extensions/sessions/:sessionId/files/:fileId för att få en ny länk för en lagrad fil, eller GET /api/extensions/sessions/:sessionId/files för att uppdatera alla sessionsfilslänkar.

Rengöringslivscykel

Tilläggsfiler rensas via en BullMQ-baserad rensningskö.

Städning är planerad när:

  • en tilläggsapp har raderats
  • Lås-/sessionstilläggsdokument raderas under borttagning av lås/arkivrensning
  • en fil tas uttryckligen bort via sessionsfilens slutpunkt

Kön håller dyr R2-borttagning och databasrensning borta från sökvägen för begäran. Om köuppkopplingen misslyckas återgår servern till rensning under processen efter svaret där en begärankontext finns, eller direkt rensning med bästa möjliga insats i livscykelrensning på lägre nivå.

Prestandanteckningar

  • Funktionskontroller bör utföras innan uppladdningsgränssnittet visas.
  • Uppladdningar begränsas av gränser per fil, per session och per app.
  • Kvotkontroller använder indexerade UserFile-metadata för scope + appId, scope + sessionId och scope + lockId.
  • Rensa strömmar som matchar filposter istället för att läsa in alla URL:er i minnet.
  • Uppladdade rasterbilder bearbetas och lagras som optimerade webbbilder.

Säkerhetsanmärkningar

  • Behandla inte bild-URL:er från tillägg som pålitliga bevis på slutförande.
  • Lagra endast Chastify-utfärdade filposter som betrodda tilläggsfiler.
  • Bind filposter till appId, sessionId och lockId.
  • Tillämpa locks:write för uppladdningar och borttagningar.
  • Validera MIME-typen och avvisa SVG.
  • Håll administratörsstyrda kvoter aktiverade innan du tillåter bred offentlig användning.
  • Använd serversidesvalidering för alla arbetsflöden som är beroende av uppladdade filer.

Direkta rutter kontra bro

Använd iframe-bryggan när ditt tillägg körs inuti Chastify. Det behåller Chastify-autentiseringen på den överordnade sidan och undviker att ruttinformation exponeras för iframen.

Använd endast direkta sessionsrutter från förstaparts Chastify-gränssnitt eller betrodda backend-flöden som redan har giltig auktorisering för tilläggssession.