The sess_id from the connect/login redirect is Zerodha's OAuth session
identifier. Without it in the twofa POST, Zerodha returns profile:{}
(regular web login) instead of redirect_url with request_token.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Following the connect/login redirect chain overwrites kf_session with a
plain web session, stripping the OAuth context. Stop at the first 302
so kf_session retains the api_key OAuth context through the twofa step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Referer on POST was causing Zerodha to reject login with Invalid username.
Add Accept, Accept-Language, Origin headers for proper browser-like requests.
Keep redirect_url body check for twofa. Add login step debug logging.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: X-Kite-Version header on web login endpoints caused Zerodha
to return plain profile response instead of OAuth redirect_url.
Changes:
- Remove X-Kite-Version from session headers (only valid for Kite Connect API)
- Use allow_redirects=False on connect/login GET to preserve OAuth cookie
- Add Referer header to login/twofa POSTs
- Check data.redirect_url in twofa JSON body (modern Zerodha SPA behavior)
- Keep Location header fallback for legacy behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prints twofa response status, Location header, and body so we can see
exactly what Zerodha returns after TOTP submission.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without first GETting the connect/login URL with the api_key,
Zerodha doesn't know which app is logging in and never returns
a request_token after TOTP — causing the redirect loop to fail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Frontend (app.quantfortune.com) fetches API (api.quantfortune.com).
With SameSite=Lax the browser won't send the cookie on cross-origin
fetch calls, so the server sees no session and the request fails.
Adding COOKIE_DOMAIN=.quantfortune.com makes the cookie valid for
all subdomains. Mohan needs to add this to .env and restart.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Session cookie was scoped to api.quantfortune.com only.
Setting COOKIE_DOMAIN=.quantfortune.com in .env makes the
cookie shared across all subdomains so app.quantfortune.com
can authenticate against api.quantfortune.com.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auth_service.py: RESET_OTP_SECRET no longer crashes at import; read lazily
inside _hash_otp() so the module always loads cleanly
- main.py: _validate_runtime_secrets() now checks both BROKER_TOKEN_KEY and
RESET_OTP_SECRET together, reporting all missing vars in one clear message
- .env.example: documents every required/optional env var with generation commands
With load_dotenv() + .env file, all secrets survive pm2 restarts automatically.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds python-dotenv so secrets survive pm2 restarts without relying on
PM2 env vars. Validates the Fernet key format at startup so a bad/missing
key fails immediately with a clear message rather than crashing mid-request.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces STRATEGY_REGISTRY, alpha_shield_allocation(), and compute_weights()
in strategy.py. Updates runner.py to dynamically load equity symbol, gold
symbol, and SMA window from the registry based on strategy_name, enabling
Alpha Shield (JUNIORBEES.NS + GOLDBEES.NS, 60M SMA) alongside Golden Nifty.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New auto_login_service.py: stores encrypted credentials (login ID,
password, TOTP secret), performs headless Zerodha login via pyotp,
and refreshes the session daily at 6:05 AM IST via background thread
- New auto_login router: setup, status, remove, and manual trigger endpoints
- Scheduler started at app boot alongside existing daemons
- Added pyotp==2.9.0 dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Set connected=FALSE (was TRUE) when expiring broker session so the
dashboard correctly reflects disconnected state
- Notify user by email when their Zerodha session expires so they know
to reconnect before the next SIP execution
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>