Browse Source

fix: save in-progress UI and server changes

Made-with: Cursor
pull/6453/head
Priyanka Punukollu 1 month ago
parent
commit
1aaa1f22bd
  1. 20
      chat_ui.html
  2. 34
      main.py

20
chat_ui.html

@ -5840,14 +5840,18 @@
} }
})(); })();
// ── Auth guard — redirect to login if no token ── // ── Auth: auto-fetch token when missing (no login required) ──
const _token = localStorage.getItem('gf_token'); (async function initAuth() {
if (!_token) { if (!localStorage.getItem('gf_token')) {
window.location.replace('/login'); try {
const r = await fetch('/auth/auto');
const d = await r.json();
if (d.success && d.token) {
localStorage.setItem('gf_token', d.token);
if (d.name) localStorage.setItem('gf_user_name', d.name);
}
} catch { /* continue without token — backend uses env */ }
} }
// ── Load user profile from localStorage (set at login) ──
(function loadUser() {
const name = localStorage.getItem('gf_user_name') || 'Investor'; const name = localStorage.getItem('gf_user_name') || 'Investor';
const initials = name.slice(0, 2).toUpperCase(); const initials = name.slice(0, 2).toUpperCase();
document.getElementById('user-avatar').textContent = initials; document.getElementById('user-avatar').textContent = initials;
@ -9125,7 +9129,7 @@
localStorage.removeItem('gf_user_email'); localStorage.removeItem('gf_user_email');
localStorage.removeItem(STORAGE_KEY); localStorage.removeItem(STORAGE_KEY);
// Clear session-specific memory (keep watchlist / memory by default — user owns those) // Clear session-specific memory (keep watchlist / memory by default — user owns those)
window.location.replace('/login'); window.location.replace('/');
}); });
// ── Clear session ── // ── Clear session ──

34
main.py

@ -5,13 +5,15 @@ from datetime import datetime
from fastapi import FastAPI, Response from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse, HTMLResponse, JSONResponse from fastapi.responses import RedirectResponse, StreamingResponse, HTMLResponse, JSONResponse
from pydantic import BaseModel from pydantic import BaseModel
from dotenv import load_dotenv from dotenv import load_dotenv
import httpx import httpx
from langchain_core.messages import HumanMessage, AIMessage from langchain_core.messages import HumanMessage, AIMessage
load_dotenv() load_dotenv()
# Load agent/.env so ANTHROPIC_API_KEY, GHOSTFOLIO_BEARER_TOKEN, etc. are available
load_dotenv(os.path.join(os.path.dirname(__file__), "agent", ".env"))
from graph import build_graph from graph import build_graph
from state import AgentState from state import AgentState
@ -393,10 +395,34 @@ async def auth_login(req: LoginRequest):
} }
@app.get("/login", response_class=HTMLResponse, include_in_schema=False) @app.get("/auth/auto")
async def auth_auto():
"""
No-login auth: returns the configured token and user info without credentials.
Enables the app to work without a login page.
"""
token = os.getenv("GHOSTFOLIO_BEARER_TOKEN", "")
base_url = os.getenv("GHOSTFOLIO_BASE_URL", "http://localhost:3333")
display_name = "Investor"
try:
async with httpx.AsyncClient(timeout=4.0) as client:
r = await client.get(
f"{base_url}/api/v1/user",
headers={"Authorization": f"Bearer {token}"},
)
if r.status_code == 200:
data = r.json()
alias = data.get("settings", {}).get("alias") or ""
display_name = alias or "Investor"
except Exception:
pass
return {"success": True, "token": token, "name": display_name}
@app.get("/login", include_in_schema=False)
async def login_page(): async def login_page():
with open(os.path.join(os.path.dirname(__file__), "login.html")) as f: """Redirect to chat — login is bypassed."""
return f.read() return RedirectResponse(url="/", status_code=302)
@app.get("/me") @app.get("/me")

Loading…
Cancel
Save