mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-04 12:58:11 +03:00
fix: resize profile images on upload and cache redirect responses (#1564)
* fix: resize profile images on upload and add cache headers Profile pictures were stored at original upload size (up to 1 MB) but only ever displayed at 32–128 px, so every page load downloaded the full original image. Additionally, no Cache-Control headers were set anywhere in the pipeline, forcing a fresh round-trip through the API redirect and CDN on every page view. - Resize JPEG/PNG pfps to max 256×256 and banners to max 1920×1080 via sharp before storing; re-encode to WebP at 85% quality (GIFs skipped to preserve the animated-GIF easter egg) - Hash the resized buffer so the CDN path reflects what's on disk - Set ContentType and CacheControl: immutable on S3 PutObject so CDN edges and browsers cache the objects indefinitely (safe because paths are content-addressed via SHA-256) - Add Cache-Control: public, max-age=3600, stale-while-revalidate=86400 to the GET /pfp and GET /banner redirect responses so browsers cache the userId→CDN-URL mapping and skip the API hop on repeat visits Fixes #1553 * chore: apply biome formatting * chore: generate ImportTimestop kanel type * feat: add backfill-media script to migrate existing profile images One-off script that reads every user's existing pfp and banner from S3, runs them through the same sharp resize/WebP pipeline as new uploads, stores the result under the new content-addressed key with immutable cache headers, and updates custom_pfp_location/custom_banner_location in the DB. Features: - --dry-run flag to preview changes without writing anything - Skips objects already at optimal size (idempotent) - Gracefully handles missing S3 objects (logs + skips) - Summary stats at the end - Reads S3 config from CLI args or TACHI_CDN_SAVE_LOCATION_* env vars * chore: apply biome formatting to backfill-media * fix: resize animated GIFs to animated WebP via sharp animated:true * test: rewrite change-pfp/banner tests as real S3 + sharp integration Remove the CDN mock entirely. Tests now pass real image buffers through sharp and verify the stored S3 object via CDNRetrieve: - PNG/JPEG input → assert stored object is WebP, dimensions ≤256×256, smaller than the original - GIF input → assert stored object is WebP - Hash returned from the action == SHA256 of the stored WebP bytes (not the original upload) - Delete tests upload a real pfp then delete it and verify CDNRetrieve throws afterwards Also move change-pfp.test.ts from the isolated vitest project back to the default pool now that it no longer uses vi.mock. * chore: apply biome formatting to test file * fix: use POSTGRES_TEST_HOST env var in bot vitest setup Both vitest.globalSetup.ts and vitest.setup.ts hardcoded 'tachi-postgres' (the dev server), but just bot-db-test-template-reset creates the template on 'tachi-postgres-test' (the tmpfs test server). Workers then failed to clone the template because they were looking on the wrong host. Mirrors the pattern already used in the server package: process.env.POSTGRES_TEST_HOST ?? 'tachi-postgres-test' * fix: update pfp router tests for WebP resize pipeline The PUT tests were comparing the stored S3 bytes directly to the original upload buffer. Since we now resize and re-encode to WebP, this always fails. Also, following the mockApi redirect to fetch the bytes added a slow supertest round-trip. Replace with: read custom_pfp_location from the DB after PUT, fetch the stored object directly via CDNRetrieve, and assert it is smaller than the original (non-deterministic WebP compression makes exact byte comparison inappropriate). * fix: update banner router tests for WebP resize pipeline * fix: tests * fix: ci
This commit is contained in:
@@ -43,17 +43,19 @@ jobs:
|
||||
env:
|
||||
NODE_ENV: "test"
|
||||
services:
|
||||
tachi-postgres:
|
||||
tachi-postgres-test:
|
||||
image: postgres:18
|
||||
env:
|
||||
POSTGRES_USER: tachi
|
||||
POSTGRES_PASSWORD: tachi
|
||||
POSTGRES_DB: postgres
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
options: >-
|
||||
--health-cmd "pg_isready -U tachi"
|
||||
--health-interval 5s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
--tmpfs /var/lib/postgresql/data:rw,size=1g
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
@@ -71,6 +73,8 @@ jobs:
|
||||
run: bun run --filter tachi-bot test
|
||||
env:
|
||||
NODE_ENV: "test"
|
||||
POSTGRES_TEST_HOST: tachi-postgres-test
|
||||
POSTGRES_TEST_URL: postgresql://tachi:tachi@tachi-postgres-test
|
||||
|
||||
docker-push:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
Reference in New Issue
Block a user