tiny image host authed by forgejo
  • Go 97.9%
  • Shell 2.1%
Find a file
2026-03-03 15:14:51 -05:00
contrib feat: add unix socket support, enable disabling of listeners 2026-03-03 13:32:31 -05:00
.gitignore docs: readme and nginx 2026-01-19 14:47:59 -05:00
go.mod update deps 2026-02-01 15:01:58 -05:00
go.sum update deps 2026-02-01 15:01:58 -05:00
LICENSE that was easy 2026-01-18 17:11:33 -05:00
main.go fix: cleanup socket on exit 2026-03-03 15:14:51 -05:00
openapi.yaml forgor to xtrl+s 2026-01-27 13:06:43 -05:00
README.md feat: add unix socket support, enable disabling of listeners 2026-03-03 13:32:31 -05:00

taswira: tiny image host authed by forgejo

features

  • relies on a forgejo instance for authing users
  • handles images up to 256mib
  • handles duplicate image uploads
  • handles image deletion (also: systemd timer to delete old images)
  • uses xxhash for filename

setup

  • MUST be run behind a reverse proxy, it depends on one to serve the images and for X-Forwarded-Host/Host and X-Forwarded-Proto
  • TASWIRA_IMG_ROOT must exist before running, this wont make dirs

environment variables

TASWIRA_INSTANCE="https://example.com" # Forgejo instance to use for auth, without trailing slash
TASWIRA_IMG_ROOT="/path/to/image/dir" # dir to write images to, defaults to <process cwd>/img
TASWIRA_SUBPATH="foo/bar/baz" # reverse proxy image subpath, without leading and trailing slash
TASWIRA_PORT="6969" # listening port, default 6969

example

TODO

export TASWIRA_SUBPATH="images"

reverse proxy structure

https://example.com
/
├── images # images served here by reverse proxy
└── up # taswira served here

usage

uploading

curl -X POST --data-binary @/path/to/image.jpg -u forgejo_user:forgejo_user_token https://example.com/up # -> '{"message":"ok","url":"https://example.com/images/47af8523b269bd268d90d10818b2f28f.png"}'

deleting

deleting takes a url param hash, containing the image hash

curl -X DELETE -u forgejo_user:forgejo_user_token https://example.com/up?hash=47af8523b269bd268d90d10818b2f28f # -> '{"message":"ok"}'
  • the token only needs the read:user perm for auth
  • accepts png, jpg, and probably webp
  • no response until user is authed
  • converts all images to png and compresses
  • simple {message: string, url:string?} object response
  • error is {error: string}

known quirks

  • any user can delete any image if they know the hash (wontfix, im lazy)

todo

  • make client helper script better (ew bash wehhh)
  • temporary uploads (?expiry=)
  • named aliases? (?alias=)