Skip to main content

Lagring av utvidelsesfiler

Lagring av utvidelsesfiler lar en aktivert utvidelse laste opp bildefiler som tilhører en låst utvidelsesøkt.

Bruk den når JSON-utvidelsestilstand ikke er nok, for eksempel:

  • puslespillbilder
  • genererte forhåndsvisninger
  • utfordringsbilder
  • utvidelsesspesifikke medier som bør ryddes opp med låsen/økten

Denne lagringen er separat fra state.*. Bruk state.* for små JSON-data. Bruk fillagring kun for binære medier.

Forhold til tilstandsendepunkter

Utvidelsesstatusen er for JSON med liten øktomfang. Fra en iframe, bruk bridge read-kommandoen i stedet for å kalle REST direkte:

state.get

Den brokommandoen ruter til:

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

Direkte backend-kall for å skrive tilstand bruker API-autentiseringsmodellen for installert utvidelse:

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

Ikke send utvikler-API-nøkler til iframe-/nettleserkode.

Bruk backend-skrevet tilstand for varige referanser og brukergrensesnittdata, for eksempel:

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

Ikke lagre binære data, base64-bilder, nettleserens blob:-URL-er eller langlivede kopier av signedUrl i tilstanden. Signerte URL-er utløper og bør oppdateres med files.get når bildet gjengis. Tilstandsskrivinger er størrelsesbegrenset av utvidelsesappens stateMaxBytes-innstilling, som standard er 64 KiB.

Lagringsmodell

Chastify lagrer utvidelsesfiler i Chastify-administrert R2-lagring.

Hver opplastede fil spores med:

  • scope: "extension"
  • appId
  • sessionId og lockId for kjøretids-/øktfiler
  • templateId for filer som er gjort krav på av en lagret låsemal
  • staged, draftId og expiresAt for oppsettopplastinger som ikke er gjort krav på ennå
  • extensionKey
  • purpose

Adminport og kvoter

Konfigurer oppstartsendepunkter

Bruk oppsettstaging bare når et oppsettgrensesnitt kjører før en utvidelsesøkt finnes.

Dette er en midlertidig opplastingsflyt. Den finnes for oppsett-/konfigurasjonsskjermer der brukeren kan laste opp en fil, deretter lukke modalvinduet eller deaktivere utvidelsen før en lås/økt opprettes. En trinnvis fil er ikke holdbar før den er gjort krav på ved å lagre utvidelseskonfigurasjonen som refererer til den.

Oppsettgrensesnitt kan sjekke tilgjengelighet og gjeldende trinnvis bruk før opplastingskontroller gjengis:

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

Svaret inkluderer stagedQuota for den nåværende brukerens utløpte, trinnvise filer på den utvidelsesappen:

{
"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

Skjemafelt:

  • file: nødvendig bildefil
  • purpose: valgfri kort identifikator som jigsaw-config-image
  • draftId: valgfri utkast-ID for oppsett; bruk samme verdi på nytt mens én oppsettmodal er åpen

Svaret inneholder en stabil file.id og en kortvarig signert URL for umiddelbar forhåndsvisning.

Eksempel på svar:

{
"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
}
}

For å gjenopprette oppsettopplastinger etter en sideoppdatering, oppgi trinnvise filer for gjeldende bruker og utvidelsesapp:

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

Valgfrie spørreparametere:

  • purpose: returner kun trinnvise filer for ett brukstilfelle for oppsett
  • draftId: returner kun filer fra et kjent oppsettutkast

Hvis draftId utelates, returnerer Chastify den gjeldende brukerens ikke-utløpte, trinnvise filer for den appen. Dette er bevisst for oppsettsgrensesnitt: en bruker kan laste opp filer, laste inn siden på nytt eller bytte enhet, og oppsettskjermen kan gjenopprette disse midlertidige opplastingene før låsen/malen lagres.

Svaret på den trinnvise listen inkluderer også stagedQuota, som rapporterer den nåværende brukerens uutløpte trinnvise bruk for den appen:

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

Oppsettgrensesnitt kan også oppdatere eller slette én trinnvis fil:

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

Gjør krav på iscenesatte filer senere

Det finnes ikke noe separat «krav»-endepunkt på nettlesersiden. En mellomlagde fil kreves automatisk når Chastify lagrer en lås- eller malutvidelseskonfigurasjon som refererer til den mellomlagde filen.

Disse rutene krever mellomlagde filer etter at lås-/maldokumentet har en ID, og ​​lagrer deretter utvidelseskonfigurasjonen på nytt med de påståtte filreferansene. Hvis kravet mislykkes, rulles den nyopprettede låsen/malen tilbake, slik at mellomlagde filer ikke blir stående knyttet til en ødelagt konfigurasjon.

Merknad om delt mal: Godkjente delte låser beholder kildemal-ID-en på den klonede aktive låsen. Malkrevde filer beholdes derfor mens eventuelle klonede låser fortsatt refererer til den malen. Hvis kildemalen slettes, forsinker Chastify slettingen av utvidelsesfilene til den siste klonede låsen som refererer til den slettede malen er slettet eller arkivert.

For å gjøre en trinnvis fil mulig å kreve, lagre en referanse som denne i utvidelseskonfigurasjonen som sendes inn av oppsettgrensesnittet:

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

Ved lagring skanner Chastify konfigurasjonen for provider: "chastify_storage"-poster med en gyldig fileId, og gjør deretter følgende:

  • bekrefter at filen tilhører gjeldende bruker og utvidelsesappen
  • avviser utløpte, trinnvise filer
  • avviser filer som allerede er gjort krav på av en annen lås-/malkontekst
  • markerer refererte iscenesatte filer som hevdet
  • binder filer som kreves til den lagrede låsen eller malen
  • fjerner midlertidige felt signedUrl, publicUrl og urlExpiresAt før konfigurasjonen lagres
  • sletter urefererte, trinnvise filer fra samme storageDraftId

Forlatte, trinnvise filer som aldri lagres, slettes ved opprydding etter utløpsdatoen.

Slik oppdaterer du en forhåndsvisning av oppsettet for en fil-ID som eies av gjeldende bruker og utvidelsesapp:

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

Øktens sluttpunkter

Disse endepunktene krever vanlig autorisasjon og omfang for utvidelsesøkter.

Basissti:

/api/extensions/sessions/:sessionId/files

Evner

Sjekk dette før du gjengir opplastingskontroller.

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

Krever locks:read.

Eksempel på svar:

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

Liste over filer

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

Krever locks:read.

Eksempel på svar:

{
"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"
}
]
}

Få én fil

Bruk dette når utvidelsen din allerede har en lagret fil-ID og bare trenger en ny signert R2-lenke.

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

Krever locks:read.

Filen må tilhøre samme utvidelsesapp, økt og lås.

Eksempel på svar:

{
"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"
}
}

Last opp fil

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

Krever locks:write.

Skjemafelt:

  • file: nødvendig bildefil
  • purpose: valgfri kort identifikator som puzzle-image eller preview

Eksempel:

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

Eksempel på svar:

{
"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"
}
}

Vanlige opplastingsfeil:

  • 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

Slett fil

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

Krever locks:write.

Filen må tilhøre samme utvidelsesapp, økt og lås.

Iframe Bridge-handlinger

Iframe-utvidelser kan bruke den overordnede webbroen for lesing av kjøretidsfiler. Opplasting og sletting av kjøretidsfiler er øktmutasjoner og bør utføres av backend-en din med en app-scoped Developer API-nøkkel pluss 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øttede brohandlinger:

  • files.capabilities -> sjekk om fillagring er aktivert og hvilke kvoter som gjelder
  • files.list -> liste filer som eies av gjeldende utvidelsesøkt
  • files.get -> oppdater én signert R2-URL fra en lagret fil-ID

Oppsett av iframes kan bruke flere bronavn før en kjøretidssesjon eksisterer. I oppsettmodus oppretter files.upload mellomlagde filer, files.list/files.staged.list viser uutløpte mellomlagde filer for gjeldende bruker og app, og files.delete sletter en mellomlagd fil. Oppsettskonteksten init inkluderer storageDraftId. Inkluder denne verdien i den lagrede konfigurasjonen som storageDraftId hvis du vil at Chastify skal rense urefererte filer fra samme utkast umiddelbart ved lagring.

Oppsettet files.upload godtar også dataUrl for enkle iframe-klienter:

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

Foretrekk opplastinger av File eller Blob når det er mulig. Bruk dataUrl kun for små genererte bilder fordi base64-nyttelaster er større i minnet.

Den stabile filidentifikatoren er id.

Bruk signedUrl for å vise eller laste ned filen. Signerte lenker er kortvarige R2 GetObject-URL-er generert av Chastify. publicUrl beholdes som et kompatibilitetsalias og inneholder for øyeblikket den samme signerte URL-en.

Når en signert lenke utløper, ring GET /api/extensions/sessions/:sessionId/files/:fileId for å motta en ny lenke for én lagret fil, eller GET /api/extensions/sessions/:sessionId/files for å oppdatere alle lenker til øktfiler.

Oppryddingens livssyklus

Utvidelsesfiler ryddes opp via en BullMQ-støttet oppryddingskø.

Opprydding er planlagt når:

  • en utvidelsesapp er slettet
  • Lås-/øktutvidelsesdokumenter slettes under fjerning av lås/arkivopprydding
  • en fil slettes eksplisitt via sesjonsfilens endepunkt

Køen holder kostbar R2-sletting og databaseopprydding unna forespørselsbanen. Hvis køopprydding mislykkes, går serveren tilbake til opprydding i prosessen etter svaret der en forespørselskontekst finnes, eller direkte beste-innsats-opprydding i livssyklusopprydding på lavere nivå.

Ytelsesnotater

  • Funksjonskontroller bør utføres før opplastingsgrensesnittet vises.
  • Opplastinger er begrenset av grenser per fil, per økt og per app.
  • Kvotekontroller bruker indekserte UserFile-metadata for scope + appId, scope + sessionId og scope + lockId.
  • Rydde opp strømmer som samsvarer med filoppføringer i stedet for å laste alle URL-er inn i minnet.
  • Opplastede rasterbilder behandles og lagres som optimaliserte webbilder.

Sikkerhetsnotater

  • Ikke bruk URL-adresser for bilde fra utvidelser som bevis på at de er fullført.
  • Lagre kun Chastify-utstedte filposter som klarerte filutvidelser.
  • Bind filoppføringer til appId, sessionId og lockId.
  • Håndhev locks:write for opplastinger og slettinger.
  • Valider MIME-typen og avvis SVG.
  • Hold administratorkontrollerte kvoter aktivert før du tillater bred offentlig bruk.
  • Bruk validering på serversiden for alle arbeidsflyter som er avhengige av opplastede filer.

Direkteruter vs. bro

Bruk iframe-broen når utvidelsen din kjører inne i Chastify. Den beholder Chastify-autentisering på den overordnede siden og unngår at rutedetaljer eksponeres for iframe-en.

Bruk direkte øktruter kun fra førsteparts Chastify-grensesnitt eller klarerte backend-flyter som allerede har gyldig autorisasjon for utvidelsesøkt.