You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
High:
- Token revocation now invalidates active sessions immediately. Sessions
track source_token_id; revoke/delete/scope-change calls
_invalidate_token_sessions() to purge both in-memory and DB sessions.
- Migration 010 stamping checks all 3 artifacts (viewer_tokens,
app_settings, viewer_accounts.no_download) before stamping complete.
Medium-High:
- no_download and source_token_id persisted in viewer_sessions table.
save_session() stores both; _viewer_session_to_dict() returns both;
_resolve_session() restores them on DB fallback/restart.
Medium:
- create_viewer() now reads and passes is_active and no_download from
request body to create_viewer_account().
- no_download no longer breaks inline media. Only explicit downloads
(download=1 query param) and exports are blocked. Frontend hides
download buttons for restricted users.
- Token expiry timezone fixed: frontend converts datetime-local to
UTC ISO before sending.
Low-Medium:
- Audit log filter uses startswith() instead of exact match, so
"viewer_updated" matches "viewer_updated:username".
Standards:
- Version bumped to 7.2.0 in pyproject.toml and src/__init__.py
- SECURITY.md: added 7.x.x as supported
- pyproject.toml: added viewer optional dep group for Pillow
- CHANGELOG updated with all security/fix entries
Tests (12 new):
- Token revocation invalidates sessions (revoke, delete, scope change)
- Label-only update preserves sessions
- no_download blocks explicit download but allows inline
- no_download blocks export
- no_download persisted via save_session
- source_token_id persisted and tracked
- no_download restored from DB session
- create_viewer passes no_download and is_active flags
Copy file name to clipboardExpand all lines: docs/CHANGELOG.md
+17-6Lines changed: 17 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,24 +11,35 @@ For upgrade instructions, see [Upgrading](#upgrading) at the bottom.
11
11
### Added
12
12
13
13
-**Share tokens** — Admins can create link-shareable tokens scoped to specific chats. Recipients authenticate via token without needing an account. Tokens support expiry dates, revocation, and use tracking
14
-
-**Download restrictions** — `no_download` flag on both viewer accounts and share tokens. Server-side enforcement blocks media file downloads (avatars and thumbnails remain accessible)
14
+
-**Download restrictions** — `no_download` flag on both viewer accounts and share tokens. Restricted users can still view media inline but cannot explicitly download files or export chat history. Download buttons hidden in the UI for restricted users
15
15
-**On-demand thumbnails** — WebP thumbnail generation at whitelisted sizes (200px, 400px) with disk caching under `{media_root}/.thumbs/`. Includes Pillow decompression bomb protection and path traversal guards
16
16
-**App settings** — Key-value `app_settings` table for cross-container configuration, with admin CRUD endpoints
-**Audit log improvements** — Action-based filtering in admin panel (prefix match for suffixed events like `viewer_updated:username`), token auth events tracked (`token_auth_success`, `token_auth_failed`, `token_created`, etc.)
18
18
-**Admin chat picker metadata** — Chat picker now returns `username`, `first_name`, `last_name` for better display
19
19
-**Token management UI** — New "Share Tokens" tab in admin panel with create, revoke, and delete controls. Plaintext token shown once at creation with copy button
20
20
-**Token login UI** — Login page has a "Share Token" tab for token-based authentication
21
21
22
+
### Security
23
+
24
+
-**Token revocation enforced on active sessions** — Revoking, deleting, or changing scope/permissions of a share token immediately invalidates all sessions created from that token. Sessions track `source_token_id` for precise invalidation
25
+
-**Session persistence includes restrictions** — `no_download` and `source_token_id` are now persisted in `viewer_sessions` table, surviving container restarts. Previously `no_download` was lost after restart, silently granting download access
26
+
-**Export endpoint respects no_download** — The `GET /api/chats/{chat_id}/export` endpoint now returns 403 for restricted users
27
+
22
28
### Fixed
23
29
24
-
-**Python 2 except syntax** — Fixed `except X, Y:` patterns (valid but semantically wrong in Python 3.14 — catches X and binds to Y instead of catching both) to `except (X, Y):` throughout `main.py`
30
+
-**Create viewer passes all flags** — `is_active` and `no_download` from the admin form are now correctly passed through to `create_viewer_account()`. Previously both flags were silently ignored on creation
31
+
-**Token expiry timezone handling** — Frontend now converts local datetime to UTC ISO before sending to the backend, fixing early/late expiry for non-UTC admins
32
+
-**Audit filter matches suffixed actions** — Filter now uses prefix matching so "viewer_updated" catches "viewer_updated:username"
33
+
-**Migration stamping checks all artifacts** — Entrypoint now checks `viewer_tokens`, `app_settings`, AND `viewer_accounts.no_download` before stamping migration 010 as complete
25
34
26
35
### Changed
27
36
28
-
-**Migration 010** — Consolidated idempotent migration creates `viewer_tokens`, `app_settings` tables and adds `no_download` column to `viewer_accounts`
29
-
-**Entrypoint stamping** — Updated both PostgreSQL and SQLite stamping blocks to detect migration 010 artifacts
37
+
-**Migration 010** — Consolidated idempotent migration creates `viewer_tokens`, `app_settings` tables and adds `no_download` column to `viewer_accounts`. Also adds `no_download` and `source_token_id` columns to `viewer_sessions`
38
+
-**Entrypoint stamping** — Updated both PostgreSQL and SQLite stamping blocks to detect all migration 010 artifacts
30
39
-**Dockerfile.viewer** — Added Pillow system dependencies (libjpeg, libwebp) for thumbnail generation
0 commit comments