Commit Graph

108 Commits

Author SHA1 Message Date
forust 67e0c6e60c fix(deps): bump aiohttp/idna/pyasn1 to close 43 pip-audit CVEs
ci / lint-prettier (push) Successful in 6s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / lint-audit (push) Successful in 41s
ci / publish (push) Successful in 27s
2026-09-10 12:08:50 +02:00
forust d863b5144a fix(ci): restore noqa E402 on deferred imports
ci / lint-prettier (push) Successful in 8s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 4s
ci / lint-audit (push) Failing after 47s
ci / publish (push) Successful in 13s
2026-09-10 12:03:18 +02:00
forust b92f8d8914 remove REVIEW.md from repo 2026-09-10 11:50:12 +02:00
forust 4c12e8bb0c fix(ui): vertically center empty-state action button
ci / lint-prettier (push) Failing after 12s
ci / lint-ruff (push) Failing after 5s
ci / lint-yaml (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / lint-audit (push) Failing after 44s
ci / publish (push) Has been skipped
2026-09-08 12:45:36 +02:00
forust c17c408f52 fix(ui): hide account-tabs when no accounts 2026-09-08 12:40:04 +02:00
forust ef62b8e94a style(webui): unify UI across all pages to solid modern system
tokens instead of hardcoded, v9 everywhere, dialog guarded, confirm->dialog, empty unified, health out of nav, swagger icons/topbar, gutters, th uppercase, content 1280 centered.
2026-09-08 12:30:50 +02:00
forust 2a75537fb9 fix(server): k8s rollout readiness
ci / lint-prettier (push) Failing after 10s
ci / lint-ruff (push) Failing after 4s
ci / lint-yaml (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 5s
ci / lint-audit (push) Failing after 49s
ci / publish (push) Has been skipped
- TRUSTED_HOSTS env: configurable trusted hostnames for proxy-domain access (default stays strict: localhost/loopback/private IP); k8s manifest sets tg.workstation.internal (L-8 follow-up)
- Media allowlist +10: mkv/mk3d/heic/tgs/flv/3gp/ogv/asf/wmv/djvu (live disk has .tgs x44, .mkv x2)
- Cache buster: app.js?v=4 -> ?v=5 so browsers pick up the new bundle
- +6 tests (64 passing); REVIEW.md updated with live-cluster rollout notes
2026-09-07 13:36:16 +02:00
forust bc2e93353a fix(server): close residual review findings F-5..F-8
- Continuous endpoints reject non-list channels (400), null no longer wipes stored list (F-5)
- '@'-prefixed legacy channel values normalized on load/save in manager and store (F-6)
- _run_loop guarded: unexpected exceptions logged, backoff retry, no silent thread death (F-7)
- +8 tests: continuous validation, normalization, loop survival, join-timeout/tombstone (F-8)
- 58 tests passing; REVIEW.md updated
2026-09-07 13:00:25 +02:00
forust e93e68db7e fix(server): harden deployment, media, state, jobs
- Lock down /media/: deny state.json, DBs, sessions; allowlist extensions incl. archives/docs (M-1)
- parse_bool() fixes; HEAD 404; shutdown drains queue; range edge cases (M-3, M-4, M-7, M-8)
- int() coercion -> 400; no filesystem paths in errors; path-only access log (M-19, L-1)
- Security headers, QR TTL 60s, trusted-host allowlist, legacy add/remove via update() (L-4, L-5, L-6, L-8)
- Clean continuous channels on import and migration; restart-during-drain; tombstone managers (F-1, F-3, F-4)
- Durability: fsync + unique tmp + stale sweep + 0600/0700 perms (M-10, M-18)
- Jobs run on dedicated loop thread; set_scrape_media passthrough; media chunked; state throttled;
  exact media file reuse; honest scrape failure status (M-11, M-12, M-13, M-14)
- Health aggregates per-account; legacy GETs delegate post-migration (M-15, M-9)
- k8s: runAsNonRoot 1000 + resource limits, no readOnlyRootFilesystem (M-16)
- UI: dropped-invalid and credentials-reentry toasts; swagger XSS-safe (F-2, L-9, L-2)
- CI: non-blocking pip-audit job in both workflows (L-3)
- 50 tests passing; REVIEW.md updated (C-1/M-20 won't fix: local-only by design)
2026-09-07 12:36:33 +02:00
forust a2468a2a2c fix(server): harden auth, SSE, state, scraping
- Fix SSE streams not terminating on successful jobs (C-2)
- Anchor data/session paths to BASE_DIR instead of CWD (C-3)
- Guard TelegramAuthManager state with RLock (H-1)
- Replace millisecond job ids with uuid4 (H-2)
- Always redact api_id/api_hash on export, drop include_secrets (H-3)
- Enforce JSON content-type + same-origin on mutating requests (H-4)
- Rate-limit auth attempts and phone-code requests (H-5)
- Deep-copy StateStore.load() on all paths (H-6)
- Cap FloodWait retries in forward_message (H-7)
- De-duplicate forwarding handler registration (H-8)
- Validate continuous channels at ingest, join scrape thread on account
  removal, fix refresh_config status under lock, cap SSE streams and
  JSON body size (M-5, M-6, M-17)
- Add regression tests (33 passing) and REVIEW.md
2026-09-07 11:54:13 +02:00
forust 59824940c6 Refine stat panel spacing and remove icons
ci / lint-prettier (push) Successful in 9s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 4s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 4s
ci / publish (push) Successful in 1m15s
2026-09-06 20:29:23 +02:00
forust 70ac1ce73e feat(webui): add dashboard stat details
ci / lint-prettier (push) Successful in 11s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 8s
ci / validate (push) Successful in 7s
ci / publish (push) Successful in 30s
2026-07-26 19:53:19 +02:00
forust 81e69865ce fix(webui): bust stylesheet cache
ci / lint-prettier (push) Successful in 26s
ci / lint-ruff (push) Successful in 11s
ci / lint-yaml (push) Successful in 18s
ci / lint-dockerfiles (push) Successful in 11s
ci / validate (push) Successful in 7s
ci / publish (push) Successful in 19s
2026-07-26 19:47:48 +02:00
forust 418c4d6192 fix(webui): prevent dashboard horizontal offset
ci / lint-prettier (push) Successful in 12s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 11s
ci / publish (push) Successful in 16s
2026-07-26 19:45:23 +02:00
forust 5956ea36a8 style(webui): match dashboard reference
ci / lint-yaml (push) Successful in 6s
ci / lint-prettier (push) Successful in 11s
ci / lint-ruff (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 7s
ci / publish (push) Successful in 19s
2026-07-26 19:29:04 +02:00
forust 93c8d00af6 style(webui): format stylesheet
ci / lint-prettier (push) Successful in 11s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 9s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 7s
ci / publish (push) Successful in 2m3s
2026-07-26 19:02:11 +02:00
forust 08f8196bf9 style(webui): match GPU Radar visual system
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 4s
ci / publish (push) Has been skipped
ci / lint-prettier (push) Failing after 11s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 5s
2026-07-26 18:56:41 +02:00
forust b963cf07df ci: restore docker-based lint and validate jobs
ci / lint-prettier (push) Successful in 6s
ci / lint-ruff (push) Successful in 3s
ci / lint-yaml (push) Successful in 3s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 4s
ci / publish (push) Successful in 5s
2026-06-30 01:12:51 +02:00
forust 849bf97c97 ci: run lint and validate tools locally
ci / lint-dockerfiles (push) Failing after 1s
ci / validate (push) Failing after 1s
ci / publish (push) Has been skipped
ci / lint-prettier (push) Failing after 3s
ci / lint-ruff (push) Successful in 1s
ci / lint-yaml (push) Successful in 1s
2026-06-30 00:15:02 +02:00
forust 145e7de7f4 Harden scraper inputs and exports
ci / lint-prettier (push) Successful in 7s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 4s
ci / publish (push) Successful in 8s
2026-06-29 17:27:43 +02:00
forust 27296caf69 Merge branch 'dev'
ci / lint-prettier (push) Successful in 7s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 5s
ci / validate (push) Successful in 4s
ci / lint-dockerfiles (push) Successful in 4s
ci / publish (push) Successful in 8s
2026-06-28 01:04:17 +02:00
forust a11ed6c5ba Simplify web UI theme
ci / lint-prettier (push) Successful in 8s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 4s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 6s
ci / publish (push) Successful in 10s
2026-06-28 01:02:24 +02:00
forust 56f15e0ba5 Parallelize CI lint jobs
ci / lint-prettier (push) Successful in 8s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 5s
ci / lint-dockerfiles (push) Successful in 31s
ci / validate (push) Successful in 5s
ci / publish (push) Successful in 7s
2026-06-28 00:57:21 +02:00
forust 26b6344f7a Format web UI assets
ci / lint (push) Successful in 12s
ci / validate (push) Successful in 7s
ci / publish (push) Successful in 8s
2026-06-28 00:55:11 +02:00
forust 6bc8d6ed36 Polish web UI styling
ci / lint (push) Failing after 8s
ci / validate (push) Successful in 6s
ci / publish (push) Has been skipped
2026-06-28 00:53:54 +02:00
forust 01a0d9c6d4 Add CI workflow comment
ci / lint (push) Successful in 21s
ci / validate (push) Successful in 8s
ci / publish (push) Successful in 8s
2026-06-28 00:41:38 +02:00
forust d3beeb6b2d feat: show next continuous run on dashboard
ci / lint (push) Successful in 15s
ci / validate (push) Successful in 6s
ci / publish (push) Failing after 2s
2026-06-28 00:38:18 +02:00
forust 24d4898865 Revert "Run CI linters without Docker"
This reverts commit a74b8bfd14.
2026-06-28 00:37:48 +02:00
forust a74b8bfd14 Run CI linters without Docker 2026-06-28 00:36:17 +02:00
forust a2c5ca7f2b feat: add dedicated account settings page 2026-06-28 00:36:05 +02:00
forust 715cb448b7 Combine CI and publish workflows
ci / lint (push) Successful in 14s
ci / validate (push) Successful in 10s
ci / publish (push) Failing after 2s
2026-06-28 00:31:13 +02:00
forust ec4805f027 Add Docker publish pipeline 2026-06-27 23:01:57 +02:00
forust 5b27852b97 fix: URL-decode channel_id path params, strip @ prefix for state lookup 2026-06-27 21:53:52 +02:00
forust c5d0a7c7e5 docs: refresh API explorer for updated endpoints 2026-06-27 21:47:45 +02:00
forust 23bb370836 feat: polish multi-account dashboard and viewer 2026-06-27 21:47:45 +02:00
forust ff1ca13a03 feat: harden multi-account backend and add tests 2026-06-27 21:47:45 +02:00
forust 7aa5c84e63 fix: add search param to legacy /api/channels/{id}/messages endpoint 2026-06-27 21:28:08 +02:00
forust 881e7ddfca Harden account import/continuous behavior and finish multi-account UI polish 2026-06-27 21:26:18 +02:00
forust 59cdad220a Fix account tab persistence and viewer fallback 2026-06-27 19:09:07 +02:00
forust 9b72c3128e Merge branch 'dev' 2026-06-27 16:30:36 +02:00
forust 3eb6bdf534 docs: update README for multi-account, bump app.js cache version 2026-06-27 15:58:10 +02:00
forust f0d207bdea feat: add account selector dropdown in message viewer 2026-06-27 15:51:19 +02:00
forust 1bd385e054 fix: add WAL mode for session SQLite to prevent 'database is locked', persist active account tab in localStorage 2026-06-27 15:45:05 +02:00
forust 93f2b94dd2 chore: update entry points for multi-account
- main.py calls migrate_legacy_state() before starting server
- health.py accepts account_ids parameter for per-account health checks
- _continuous_check returns per-account status instead of single snapshot
2026-06-27 15:21:02 +02:00
forust eb69a89d91 feat: add multi-account message viewer support
- viewer.html shows account name in header
- viewer.js loads account list from /api/accounts, auto-selects first account
- Account-aware API endpoints (/api/accounts/{id}/... or legacy /api/...)
- Chat list redesign with avatar initials, preview text, time, message count
- loadViewerAccount() helper fetches account info and user ID
2026-06-27 15:20:56 +02:00
forust 62a6a492e0 feat: add per-account web UI with account tabs
- Account tab bar with tab switching (loadAccounts, switchAccount)
- Per-account dashboard panel showing auth status, channels, jobs, continuous
- Settings dialog with account management (add/delete accounts, credentials)
- Auth forms per account (QR, phone, password, set credentials)
- All action buttons with error handling (alert on failure)
- AMOLED dark theme with Telegram-style message bubbles
- Account tab and account list CSS styles
2026-06-27 15:20:49 +02:00
forust bb4e28a710 feat: add per-account API, auth, and continuous orchestration
- TelegramAuthManager rewritten for per-account clients/auth state
- ContinuousScrapeOrchestrator managing per-account continuous loops
- Full /api/accounts/* REST endpoints: CRUD, auth (QR/phone/password),
  channels, jobs, continuous config, settings, media toggle
- Legacy backward compat via legacy_account_id auto-detection
  (old /api/auth/*, /api/channels/*, /api/jobs/* still work for legacy
  single-account mode)
- load_messages() accepts account_id parameter for per-account data
- auth_status_for(), list_channels_snapshot() per-account helpers
- OpenAPI spec updated with all /api/accounts/* endpoints
2026-06-27 15:20:27 +02:00
forust 220d04b3a6 feat: make scraper and job service account-aware
- OptimizedTelegramScraper accepts account_id parameter;
  sets DATA_DIR to data/accounts/<id>/ when provided
- Session path uses account_session_path() for per-account session files
- initialize_client() reads per-account credentials from account state store
- ScraperJobService passes account_id from payload to scraper constructor
- Per-account state loaded from AccountStateStore before scraping
2026-06-27 15:20:15 +02:00
forust 6e3966aeb5 feat: add multi-account data layer with legacy migration
- GlobalStateStore for account registry in global state.json
- AccountStateStore for per-account settings (channels, credentials, continuous config)
- migrate_legacy_state() copies legacy data/ to data/accounts/default/
  with progress logging; renames session.session to default.session
- Helpers: account_data_dir(), account_session_path(), list_accounts(),
  load_account(), save_account(), get_account_store(), get_global_store()
- StateStore accepts defaults parameter for flexible default values
2026-06-27 15:20:09 +02:00
forust f5ef74bda6 Merge dev into main: lint fixes and config updates 2026-06-19 11:52:34 +02:00