Commit Graph

73 Commits

Author SHA1 Message Date
ruslan beb2781123 Fix request-access: add Telegram env to compose, fix log_event calls 2026-05-14 06:28:58 +00:00
ruslan a0b1754ddb Rename modal title to Запрос на доступ 2026-05-14 06:25:04 +00:00
ruslan ce39573618 Fix login-request-btn width after a→button change 2026-05-14 06:24:11 +00:00
ruslan f740420a77 Add request access modal on login page with Telegram notification
- Modal form: name, company, email, phone (required), manager (optional), product checkboxes
- Products loaded from DB via GET /api/public/services-by-category (public route)
- POST /api/request-access sends styled Telegram message with divider and emojis
- Dark-themed modal matching login page design
- CSS: overlay, card, fields, checkbox list, error, footer buttons
2026-05-14 06:22:39 +00:00
ruslan 3e640fbe15 revert: restore CSS to working state before logo column experiments 2026-05-12 13:29:08 +00:00
ruslan eda342cf43 fix: logo in own grid column, content never overlaps 2026-05-12 13:27:09 +00:00
ruslan e8d1515f89 fix: reserve space for fixed page-logo, prevent content overlap 2026-05-12 13:24:05 +00:00
ruslan 4f52ae8566 style: add gap between avatar and username in header 2026-05-12 13:20:47 +00:00
ruslan 30ce37b906 fix: remove first_name/last_name from all models except User 2026-05-12 13:01:29 +00:00
ruslan 4268b19a37 fix: remove first_name/last_name from Service model (was added by mistake) 2026-05-12 12:59:38 +00:00
ruslan 6aa40eb5c2 feat: add first_name/last_name to users, avatar in header, neutral dashboard bg 2026-05-12 12:51:47 +00:00
ruslan dedf4aea77 dashboard: replace informal welcome text with product name 2026-05-12 12:44:44 +00:00
ruslan fff7ecdce2 login: left panel 1/4, distrib button, text tweaks, dashboard light theme polish 2026-05-12 12:42:12 +00:00
ruslan 666093f1c6 login: logo only in top-left corner, left panel 1/3 right panel 2/3 2026-05-11 08:54:25 +00:00
ruslan 020793a3e2 redesign: stylish two-column login page (dark navy split layout) 2026-05-11 08:50:02 +00:00
ruslan 55da535f44 feat: project description block on login page 2026-05-11 08:43:50 +00:00
ruslan d7716fa569 design: stylish request-access button on login page 2026-05-08 13:05:02 +00:00
ruslan 116ffba42d feat: add Yandex Metrika counter (id=109119977) to all pages 2026-05-08 13:03:46 +00:00
ruslan b9f1e375d3 feat: request access button on login page (mailto rgalyaviev) 2026-05-08 12:59:15 +00:00
ruslan 1dc5a0eb34 fix: replace favicon with correct local file 2026-05-07 07:26:15 +00:00
ruslan 983065ac9f fix: use favicon.png instead of svg 2026-05-07 07:23:56 +00:00
ruslan 7e94ddaf8d fix: rdp target field readonly, host/port/domain/sec oninput rebuilds target 2026-05-06 11:43:26 +00:00
ruslan a137729704 design: username left in header, white elegant font 2026-05-04 13:35:32 +00:00
ruslan bbe1e27582 design: logo fixed left below header 2026-05-04 13:33:55 +00:00
ruslan 16c06ac166 design: move logo below header strip, scrolls with page 2026-05-04 13:32:43 +00:00
ruslan 535d71709e fix: dark header background, original logo color 2026-05-04 13:08:24 +00:00
ruslan 045b21c514 design: dark minimal header 2026-05-04 13:06:29 +00:00
ruslan bff5ffac1c perf: compress logo and favicon (1.7MB -> 7KB / 610B) 2026-05-04 06:32:16 +00:00
ruslan 3d8ccd30b6 fix: add hash_password to auth imports in main.py 2026-05-01 16:47:48 +00:00
ruslan dc90569631 fix: call connect_rdp_slot on session reuse
Previously connect_rdp_slot was only called when creating a new session.
If the API container restarted, existing sessions had should_be_connected=false
and xfreerdp never started. Now connect is triggered on every /go/<slug> visit
when an RDP session already exists.
2026-05-01 16:11:30 +00:00
ruslan 38dc206f5a fix: add missing user_is_valid import from auth in main.py 2026-05-01 12:56:19 +00:00
ruslan fb4af8cfe6 fix: add missing import secrets in main.py 2026-05-01 12:55:02 +00:00
ruslan 58cb8b1035 feat: on-demand RDP - connect xfreerdp only when session opens
Replaces always-on xfreerdp with on-demand model (load 12 to under 1 at idle).
- rdp-proxy/manager.py: HTTP server port 7001 managing xfreerdp lifecycle
- rdp-proxy/entrypoint.sh: starts Xvfb+x11vnc+websockify+manager, no auto-connect
- rdp-proxy/Dockerfile: adds python3, copies manager.py, exposes 7001
- runtime.py: connect_rdp_slot and disconnect_rdp_slot via manager HTTP API
- terminate_session_record: disconnect instead of container restart
- main.py: calls connect_rdp_slot in background thread on session create
- maintenance.py: cleanup_loop disconnects on expire, run_maintenance_service
  includes RDP slot init, maintenance_runner fixed to import maintenance
2026-05-01 10:12:52 +00:00
ruslan 82024a36c4 fix: add missing sqlalchemy imports (select, text, delete, update) to main.py 2026-05-01 09:51:24 +00:00
ruslan b8dd023233 fix: add missing runtime imports (route_ready, docker_client, ensure_universal_pool, get_universal_pool_status) 2026-05-01 09:48:42 +00:00
ruslan 1c7caec021 fix: add missing config imports to main.py (GO_*_LOCK_TIMEOUT, WEB_POOL_BUFFER) 2026-05-01 09:45:55 +00:00
ruslan c8c77048c7 refactor: split main.py into modules (config, database, models, utils, auth, runtime, maintenance)
main.py was ~3000 lines with models, routes, Docker ops, maintenance all mixed.
Split into 7 focused modules:
- config.py: env vars and constants
- database.py: SQLAlchemy engine, SessionLocal, Base, get_db
- models.py: ORM models and enums
- utils.py: logging, formatting, icon handling, misc helpers
- auth.py: password hashing, cookies, CSRF, user dependency
- runtime.py: all Docker operations, pool management, session lifecycle
- maintenance.py: cleanup loop, schema bootstrap, startup logic
- main.py: FastAPI app, middleware, all route handlers only
2026-05-01 09:40:06 +00:00
ruslan cf68bc848f Fix CSRF SameSite=Strict breaking login on iPad/Safari
Safari (iPadOS/iOS) blocks SameSite=Strict cookies on the initial
top-level navigation when it considers the request cross-site (links
from messengers, email, QR codes). The CSRF cookie was therefore never
set on first visit, and the subsequent login POST failed with 403
"CSRF failed".

Switch the CSRF cookie to SameSite=Lax — this is the OWASP recommended
default and matches industry practice. The auth (session) cookie keeps
SameSite=Strict, since it is only issued after a successful first-party
login POST and needs the stricter binding.
2026-04-30 17:38:20 +00:00
ruslan 23c1f6e342 Chromium: Russian language, autofill passwords from svc_login/svc_password via Login Data 2026-04-30 07:22:31 +00:00
ruslan 3f20fe5991 Fix: category delete button broken by double-quote conflict in onclick attr 2026-04-28 21:07:14 +00:00
ruslan 154ec35384 Block mobile devices: show desktop-only page 2026-04-28 20:52:24 +00:00
ruslan 8f3617afdd Remove copy buttons from credentials panels 2026-04-28 13:49:47 +00:00
ruslan beb6828520 Add credentials panel on view page; remove copy buttons from dashboard cards 2026-04-28 13:47:46 +00:00
ruslan 2d65d98116 fix: link z-index:0, tile z-index:1 pointer-events:none, scroll restored 2026-04-28 13:29:53 +00:00
ruslan 1ab5af28b5 fix: link overlay pattern — credentials never trigger navigation 2026-04-28 13:17:32 +00:00
ruslan bfcf5f565b fix: card height 672px (-30%) 2026-04-28 13:08:29 +00:00
ruslan af02c0d059 fix: card height 960px, credentials always visible, only comment scrolls 2026-04-28 13:02:19 +00:00
ruslan 530d901a45 fix: fixed card height 480px, icon constrained, info-area scrolls 2026-04-28 12:57:21 +00:00
ruslan 7a7c6e30e3 fix: tile-info-area shares space between credentials+comment, scroll restored 2026-04-28 12:48:59 +00:00
ruslan 6ccba89216 fix: equal card height — categories always at bottom, comment clips to fill 2026-04-28 12:33:12 +00:00