A photo picked before sign-in was saved in the browser, but after reload the preview was empty and there was no way to remove it. The picker also accepted empty files, huge files, SVGs, and text renamed as .png.
This restores the staged photo so it can be previewed and removed, and checks size, real file type, and whether the image can be read — on the device and on the server.
Changes
Community photo step rehydrates the staged file on mount and keeps the remove control
Remove clears the preview, the draft URL, and the staged file so sign-in cannot bring it back
Shared client/server validation: empty files, 5 MB photo / 10 MB attachment caps, magic-byte type (not the filename), image decode, and explicit SVG rejection
Clear errors for those cases; custom-method uploads use the same checker and error copy
Tests for restore/remove and for empty, oversized, SVG, and spoofed files
Restore / remove: add a photo, reload. The preview should return with Remove uploaded photo. Remove it; the Upload control should come back. Reload again — the photo should stay gone.
Rejects: try a 0-byte file, a 17 MB file, an .svg, and a text file renamed .png. Each should show a specific error and should not stage or upload.
Signed-in (optional): sign in, add a real JPEG/PNG/WebP/GIF under 5 MB. It should upload and persist. Invalid files should still be rejected before the request.
Optional: npx tsc --noEmit and npx vitest run.
Notes
Anonymous picks still wait for sign-in to upload; validation runs before staging so a bad file never sits in IndexedDB.
Knip still reports unused seedDataRoot; that is unrelated.
## Overview
A photo picked before sign-in was saved in the browser, but after reload the preview was empty and there was no way to remove it. The picker also accepted empty files, huge files, SVGs, and text renamed as `.png`.
This restores the staged photo so it can be previewed and removed, and checks size, real file type, and whether the image can be read — on the device and on the server.
## Changes
- Community photo step rehydrates the staged file on mount and keeps the remove control
- Remove clears the preview, the draft URL, and the staged file so sign-in cannot bring it back
- Shared client/server validation: empty files, 5 MB photo / 10 MB attachment caps, magic-byte type (not the filename), image decode, and explicit SVG rejection
- Clear errors for those cases; custom-method uploads use the same checker and error copy
- Tests for restore/remove and for empty, oversized, SVG, and spoofed files
## Screenshots
## How to Test
1. `npm run dev` → [http://localhost:3000/create/community-upload](http://localhost:3000/create/community-upload) (stay signed out).
2. **Restore / remove:** add a photo, reload. The preview should return with **Remove uploaded photo**. Remove it; the Upload control should come back. Reload again — the photo should stay gone.
3. **Rejects:** try a 0-byte file, a 17 MB file, an `.svg`, and a text file renamed `.png`. Each should show a specific error and should not stage or upload.
4. **Signed-in (optional):** sign in, add a real JPEG/PNG/WebP/GIF under 5 MB. It should upload and persist. Invalid files should still be rejected before the request.
5. Optional: `npx tsc --noEmit` and `npx vitest run`.
## Notes
- Anonymous picks still wait for sign-in to upload; validation runs before staging so a bad file never sits in IndexedDB.
- Knip still reports unused `seedDataRoot`; that is unrelated.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Overview
A photo picked before sign-in was saved in the browser, but after reload the preview was empty and there was no way to remove it. The picker also accepted empty files, huge files, SVGs, and text renamed as
.png.This restores the staged photo so it can be previewed and removed, and checks size, real file type, and whether the image can be read — on the device and on the server.
Changes
Screenshots
How to Test
npm run dev→ http://localhost:3000/create/community-upload (stay signed out)..svg, and a text file renamed.png. Each should show a specific error and should not stage or upload.npx tsc --noEmitandnpx vitest run.Notes
seedDataRoot; that is unrelated.