diff --git a/app/auth.py b/app/auth.py index a4cdb88..abf2ca6 100644 --- a/app/auth.py +++ b/app/auth.py @@ -23,7 +23,6 @@ def create_token(user_id: int, username: str) -> str: payload = { "user_id": user_id, "username": username, - "exp": datetime.utcnow() + timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS), } return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM) diff --git a/app/routes/auth.py b/app/routes/auth.py index 9c1acc5..d2e945b 100644 --- a/app/routes/auth.py +++ b/app/routes/auth.py @@ -68,7 +68,7 @@ async def login( token = create_token(user["id"], user["username"]) resp = RedirectResponse("/dashboard", status_code=302) - resp.set_cookie(key="token", value=token, httponly=True, max_age=43200) + resp.set_cookie(key="token", value=token, httponly=True) return resp finally: conn.close() diff --git a/main.py b/main.py index e93ba34..2ef5b68 100644 --- a/main.py +++ b/main.py @@ -1,95 +1,103 @@ -import os -import sys -from pathlib import Path - -sys.path.insert(0, str(Path(__file__).parent)) - -from fastapi import FastAPI, Request, Depends -from fastapi.responses import RedirectResponse -from fastapi.staticfiles import StaticFiles -from fastapi.templating import Jinja2Templates -from fastapi.middleware.cors import CORSMiddleware -import uvicorn - -from app.database import init_db -from app.auth import decode_token - -app = FastAPI(title="RIPS Manager", version="1.0.0") - -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], -) - -templates = Jinja2Templates( - directory=os.path.join(os.path.dirname(__file__), "app", "templates") -) -app.state.templates = templates - - -def get_user_from_request(request: Request): - cookies = dict(request.cookies) - token = cookies.get("token") - if not token: - auth = request.headers.get("Authorization", "") - if auth.startswith("Bearer "): - token = auth[7:] - if token: - decoded = decode_token(token) - if decoded: - return decoded - print(f" [AUTH] Invalid token: {token[:30]}...", flush=True) - return None - - -@app.middleware("http") -async def auth_middleware(request: Request, call_next): - public_paths = ["/auth/login", "/auth/register", "/auth/api/login"] - if request.url.path in public_paths or request.url.path.startswith("/static"): - return await call_next(request) - - if request.url.path.startswith("/auth"): - return await call_next(request) - - user = get_user_from_request(request) - print(f" [AUTH] path={request.url.path} user={user['username'] if user else None} cookies={dict(request.cookies)}", flush=True) - if not user: - if request.url.path.startswith("/api/"): - from fastapi.responses import JSONResponse - print(f" [AUTH] -> 401 JSON for /api/ path", flush=True) - return JSONResponse({"detail": "Not authenticated"}, status_code=401) - print(f" [AUTH] -> 307 redirect to /auth/login", flush=True) - return RedirectResponse(url="/auth/login") - - request.state.user = user - return await call_next(request) - - -@app.on_event("startup") -async def startup(): - init_db() - - -@app.get("/") -async def root(): - return RedirectResponse(url="/dashboard") - - -# Register routes -from app.routes import auth, dashboard, config, queries, terceros, transaccion, logs, automation - -app.include_router(auth.router) -app.include_router(dashboard.router) -app.include_router(config.router) -app.include_router(queries.router) -app.include_router(terceros.router) -app.include_router(transaccion.router) -app.include_router(logs.router) -app.include_router(automation.router) - - -if __name__ == "__main__": - uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=True) +import os +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) + +from fastapi import FastAPI, Request, Depends +from fastapi.responses import RedirectResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from fastapi.middleware.cors import CORSMiddleware +import uvicorn + +from app.database import init_db +from app.auth import decode_token + +app = FastAPI(title="RIPS Manager", version="1.0.0") + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +templates = Jinja2Templates( + directory=os.path.join(os.path.dirname(__file__), "app", "templates") +) +app.state.templates = templates + + +def get_user_from_request(request: Request): + cookies = dict(request.cookies) + token = cookies.get("token") + if not token: + auth = request.headers.get("Authorization", "") + if auth.startswith("Bearer "): + token = auth[7:] + if token: + decoded = decode_token(token) + if decoded: + return decoded + print(f" [AUTH] Invalid token: {token[:30]}...", flush=True) + return None + + +@app.middleware("http") +async def auth_middleware(request: Request, call_next): + public_paths = ["/auth/login", "/auth/register", "/auth/api/login"] + if request.url.path in public_paths or request.url.path.startswith("/static"): + return await call_next(request) + + if request.url.path.startswith("/auth"): + return await call_next(request) + + user = get_user_from_request(request) + print(f" [AUTH] path={request.url.path} user={user['username'] if user else None} cookies={dict(request.cookies)}", flush=True) + if not user: + if request.url.path.startswith("/api/"): + from fastapi.responses import JSONResponse + print(f" [AUTH] -> 401 JSON for /api/ path", flush=True) + return JSONResponse({"detail": "Not authenticated"}, status_code=401) + print(f" [AUTH] -> 307 redirect to /auth/login", flush=True) + return RedirectResponse(url="/auth/login") + + request.state.user = user + return await call_next(request) + + +@app.on_event("startup") +async def startup(): + init_db() + + +@app.get("/") +async def root(): + return RedirectResponse(url="/dashboard") + + +# Register routes +from app.routes import auth, dashboard, config, queries, terceros, transaccion, logs, automation + +app.include_router(auth.router) +app.include_router(dashboard.router) +app.include_router(config.router) +app.include_router(queries.router) +app.include_router(terceros.router) +app.include_router(transaccion.router) +app.include_router(logs.router) +app.include_router(automation.router) + + +if __name__ == "__main__": + import socket + hostname = socket.gethostname() + try: + lan_ip = socket.gethostbyname(hostname) + except: + lan_ip = "0.0.0.0" + print(f" Local: http://localhost:8080") + print(f" Red: http://{lan_ip}:8080") + uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=False) diff --git a/run.ps1 b/run.ps1 index 0eceaf9..f1f51a0 100644 --- a/run.ps1 +++ b/run.ps1 @@ -1,22 +1,24 @@ -Set-Location $PSScriptRoot - -$python = Get-Command python -ErrorAction SilentlyContinue -if (-not $python) { - Write-Host "Descargando Python 3.12..." - Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.12.9/python-3.12.9-amd64.exe" -OutFile "$env:TEMP\python-installer.exe" - Write-Host "Instalando Python..." - Start-Process -Wait -FilePath "$env:TEMP\python-installer.exe" -ArgumentList "/quiet InstallAllUsers=0 PrependPath=1 Include_test=0" - Write-Host "Python instalado. Cerra y abri PowerShell de nuevo." - Read-Host "Enter para salir" - exit -} - -Write-Host "Instalando dependencias..." -python -m pip install -q -r requirements.txt - -Write-Host "`n==========================================" -Write-Host " Servidor: http://localhost:8080" -Write-Host " Presiona Ctrl+C para detener" -Write-Host "==========================================`n" - -python main.py +Set-Location $PSScriptRoot + +$python = Get-Command python -ErrorAction SilentlyContinue +if (-not $python) { + Write-Host "Descargando Python 3.12..." + Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.12.9/python-3.12.9-amd64.exe" -OutFile "$env:TEMP\python-installer.exe" + Write-Host "Instalando Python..." + Start-Process -Wait -FilePath "$env:TEMP\python-installer.exe" -ArgumentList "/quiet InstallAllUsers=0 PrependPath=1 Include_test=0" + Write-Host "Python instalado. Cerra y abri PowerShell de nuevo." + Read-Host "Enter para salir" + exit +} + +Write-Host "Instalando dependencias..." +python -m pip install -q -r requirements.txt + +$ip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -like "192.*" -or $_.IPAddress -like "10.*" -or $_.IPAddress -like "172.*"} | Select-Object -First 1).IPAddress +Write-Host "`n==========================================" +Write-Host " Local: http://localhost:8080" +if ($ip) { Write-Host " Red: http://$($ip):8080" } +Write-Host " Presiona Ctrl+C para detener" +Write-Host "==========================================`n" + +python main.py