diff --git a/app/api.py b/app/api.py new file mode 100644 index 00000000..f768e26a --- /dev/null +++ b/app/api.py @@ -0,0 +1,32 @@ +from fastapi import APIRouter, Request, HTTPException, status +from hashlib import md5 + +router = APIRouter() + +@router.get("/whoami") +async def whoami(request: Request): + """ + Returns user info if logged in, else 401. + Example response: + { + "email": "someone@example.com", + "picture": "https://www.gravatar.com/avatar/..." + } + """ + user = request.session.get("user") + if not user: + raise HTTPException(status_code=401, detail="Not logged in") + + email = user.get("email") + if not email: + raise HTTPException(status_code=400, detail="User has no email in session") + + # Generate Gravatar URL from email + # For more options, see: https://en.gravatar.com/site/implement/images/ + email_hash = md5(email.strip().lower().encode()).hexdigest() + gravatar_url = f"https://www.gravatar.com/avatar/{email_hash}?d=identicon" + + return { + "email": email, + "picture": gravatar_url + } \ No newline at end of file diff --git a/app/main.py b/app/main.py index b2d43b0c..654e6cbf 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import os -from fastapi import FastAPI, HTTPException, UploadFile, File +from fastapi import FastAPI, HTTPException, UploadFile, File, status from starlette.middleware.sessions import SessionMiddleware from starlette.config import Config from starlette.middleware.trustedhost import TrustedHostMiddleware @@ -13,9 +13,17 @@ from app.tasks.upload_to_dropbox import upload_to_dropbox from app.tasks.upload_to_paperless import upload_to_paperless from app.tasks.upload_to_nextcloud import upload_to_nextcloud from app.tasks.send_to_all import send_to_all_destinations +from pathlib import Path + +from app.api import router as api_router from app.frontend import router as frontend_router from app.auth import router as auth_router +BASE_DIR = Path(__file__).resolve().parent # this is /app in many Docker setups +FRONTEND_DIR = BASE_DIR / "frontend" + + + # Load configuration from .env for the session key config = Config(".env") SESSION_SECRET = config( @@ -163,6 +171,15 @@ async def ui_upload(file: UploadFile = File(...)): task = upload_to_s3.delay(target_path) return {"task_id": task.id, "status": "queued"} +@app.exception_handler(404) +async def custom_404_handler(request: Request, exc: HTTPException): + return FileResponse( + FRONTEND_DIR / "404.html", + status_code=status.HTTP_404_NOT_FOUND + ) + # Include the frontend and auth routers app.include_router(frontend_router) app.include_router(auth_router) +app.include_router(api_router, prefix="/api") + diff --git a/frontend/index.html b/frontend/index.html index 444e61d4..9f8854ef 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -124,8 +124,12 @@ const resp = await fetch("/api/whoami"); if (resp.ok) { const data = await resp.json(); - document.getElementById("authSection").innerHTML = - `Logged in as ${data.email} Logout`; + // data.picture is the Gravatar URL + document.getElementById("authSection").innerHTML = ` + User Avatar + Logged in as ${data.email} + Logout + `; } else { // If 401 or other non-OK status => show Login link document.getElementById("authSection").innerHTML =