5 Commits
Author SHA1 Message Date
eberkheev a0c996b19d refactor(server): extract helpers and simplify auth dispatch
- Move `sha256_hex` and cookie constants to module level; drop `token_is_hash` param in favour of regex auto-detection
- Make `_respond()` accept `status`/`headers`; add `_redirect()` helper to eliminate boilerplate in auth routes
- Simplify `_dispatch()` with a `PUBLIC_ROUTES` set and positive-logic early-return
- Restrict CORS header to file API; auth responses no longer send `Access-Control-Allow-Origin: *`
- Extract `clearPager()` in frontend and deduplicate `copyText` fallback path
2026-07-29 18:08:36 +04:00
eberkheev c467a4d254 fix(auth): stop leaking the token via URL, log and Referer
A token passed as `?token=` was accepted on every route, so it ended
up in the request log (and journald), browser history and Referer.

- drop `?token=` from _check_auth; API and download routes now take
  only the cookie or an Authorization: Bearer header
- keep pre-authenticated links working: on the index route a valid
  `?token=` is swapped for the cookie and redirected to a clean URL,
  so the secret does not linger in the address bar
- redact `token=` from log output
- send Referrer-Policy: no-referrer, and mark the cookie Secure
2026-07-27 02:08:58 +04:00
eberkheev cac59e6e67 fix(encoding): handle non-ASCII filenames on upload and download
Cyrillic names arrived as question marks and were stored that way.

Upload: BytesParser defaults to the compat32 policy, which wraps a
non-ASCII Content-Disposition in a Header with the unknown-8bit
charset, so get_filename() returned one replacement character per
UTF-8 byte and the mangled name was written to disk. Parse with
policy=HTTP, which decodes headers as UTF-8.

Download: send_header() encodes latin-1 strict, so a Cyrillic name
raised UnicodeEncodeError. Emit both Content-Disposition forms per
RFC 5987 — an ASCII fallback plus percent-encoded filename*.
2026-07-27 02:08:16 +04:00
eberkheev 6f6b7552fc feat(auth): add token authentication with SHA-256 hashed storage 2026-03-29 15:54:41 +04:00
eberkheevandClaude Opus 4.6 6a540eaf81 Split share.py into modules by responsibility
config.py  — share.config loading, constants, load_config(), client_cfg()
cert.py    — get_local_ip(), ensure_cert()
cleanup.py — cleanup_loop()
server.py  — ShareServer, Handler, file_type()
share.py   — main() entry point only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:56:58 +04:00