Repository navigation
Conversation
…empts, holds Korail-app-style mobile page served by the same FastAPI service. Credentials live only in process memory for the session (30 min idle / 8 h absolute / logout) and as create-time variables of each per-job sandbox. httpOnly SameSite=Strict cookie, CSRF header on mutations, login rate limit, CSP. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
8 tasks
|
@dev-dooi must be a member of the chasehuh team on Vercel to deploy. Learn more about collaboration on Vercel and other options here. |
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15. Stacked on #14 (base branch
fable/railway-per-job-workers); merge #14 first, then this.What
Web dashboard, Korail-app flow, one Railway service.
train/server/web.py+train/server/static/served by the same FastAPI app as the bearer/jobsAPI. Mobile-first vanilla HTML/JS/CSS, Korean UI: 로그인 → 출발/도착/가는날/출발시각 조회 → 열차 목록 (특실/일반실 예약가능/매진) → 예약 시도 sheet (좌석 등급, A/B/C/D 좌석 위치, 최대 시도 시간, 조회 간격, 알림만) → 예약 시도 탭 (status, sandbox id, egress IP, log tail, 취소) → 예약 내역 탭 (미결제 holds, 결제기한, 예약 취소).Routes:
POST /web/login,GET /web/me,POST /web/logout,POST /web/search,POST|GET|DELETE /web/jobs[/:id],GET /web/holds,DELETE /web/holds/:rsv_id. Search, holds list and hold cancel are single Korail calls from the session's client; reserve attempts never run in the web process —POST /web/jobsreuses the #14JobRunner, injecting the session credentials as create-time sandbox variables (JobRunner.create(spec, worker_env=…, owner=masked id)).Where the password lives, and for how long (
train/server/session.py)Korailclient: idle TTL 30 min, absolute TTL 8 h, orPOST /web/logout(calls Korail logout and nulls the password). Never on disk, DB, logs, job records (owneris the masked id), or the cookie (random id only).max_minutes+ 5 min grace at most, then destroyed).Browser security:
HttpOnly; Secure; SameSite=Strictsession cookie (server-side store);X-CSRF-Tokenrequired on every mutating/web/*route (token handed out at login /GET /web/me, never in a cookie); login is JSON-only; login rate limit 5 failures per 15 min per client IP and per Korail id (Korail locks memberships after 5 bad passwords; the limiter fails closed before the 5th reaches Korail); CSPdefault-src 'self',X-Frame-Options: DENY,Referrer-Policy: no-referrer,Cache-Control: no-storeon API responses, OpenAPI/docs endpoints disabled; Korail error codes surfaced (502 Korail <code>: <msg>,401on expired Korail session).Hosting: new Railway service
webin projecttrain_chasehuh_com(idf1293bf8…), Dockerfile build,PORT=8000, healthcheck/healthz. Variables documented in README. Custom domaintrain.chasehuh.comattached (target port 8000).Also fixed here:
ZoneInfo("Asia/Seoul")from #14 crashes on the sandbox image (no tzdata) — replaced with a fixed UTC+9 offset. Thesessions=injection bug (empty store was falsy) is fixed too.Verified (2026-09-17)
login → search → job (sandbox variables = session creds, not in the record) → worker exit 0 → reserved + destroyed → holds → cancel hold → logout (creds dropped), bad-password 401 with Korail code, rate limit 429 +Retry-After, CSRF 403, session idle expiry, cookie flags, static page + headers, bearer/jobsunchanged./healthz, page served with CSP/DENY headers,/web/me401,/jobs401,/docs404. One bearermonitor_onlyjob from the deployed service booted from checkpointtrain-web-preview, egress IP152.55.176.61, polled the real timetable, hit its 2-min deadline →idle_timeout→ sandbox destroyed. Uvicorn access logs show paths only.train-web-previewis kept because the preview service points at it.Needs verification
train.chasehuh.comstill CNAMEs to Vercel. In Cloudflare setCNAME train → 7jqnbgvz.up.railway.appandTXT _railway-verify.train → railway-verify=c8a0241b6e4db491621a5c1682990c685495cc340f76154416c27b89e5cb7747; Railway then verifies and issues TLS (my Cloudflare tokens here are expired).RAILWAY_API_TOKENon thewebservice is my CLI session token, which expires ~04:27 UTC today.projectTokenCreate/apiTokenCreatereturn Not Authorized from the CLI session. Create a project token in the dashboard (projecttrain_chasehuh_com→ Settings → Tokens) and set it asRAILWAY_TOKEN(then deleteRAILWAY_API_TOKEN).reservefrom the dashboard: only on a Chase-named trip.🤖 Generated with Claude Code