Update authentication system, database models, and UI components

This commit is contained in:
oib
2025-08-07 19:39:22 +02:00
parent d497492186
commit 72f79b1059
48 changed files with 5328 additions and 1642 deletions

137
magic.py
View File

@ -12,58 +12,107 @@ import json
router = APIRouter()
@router.post("/magic-login")
async def magic_login(request: Request, response: Response, db: Session = Depends(get_db), token: str = Form(...)):
print(f"[magic-login] Received token: {token}")
user = db.exec(select(User).where(User.token == token)).first()
print(f"[magic-login] User lookup: {'found' if user else 'not found'}")
if not user:
print("[magic-login] Invalid or expired token")
return RedirectResponse(url="/?error=Invalid%20or%20expired%20token", status_code=302)
if datetime.utcnow() - user.token_created > timedelta(minutes=30):
print(f"[magic-login] Token expired for user: {user.username}")
return RedirectResponse(url="/?error=Token%20expired", status_code=302)
# Mark user as confirmed if not already
if not user.confirmed:
user.confirmed = True
user.ip = request.client.host
db.add(user)
print(f"[magic-login] User {user.username} confirmed.")
# Create a new session for the user (valid for 1 hour)
session_token = secrets.token_urlsafe(32)
expires_at = datetime.utcnow() + timedelta(hours=1)
async def magic_login(request: Request, response: Response, token: str = Form(...)):
# Debug messages disabled
# Create new session
session = DBSession(
token=session_token,
user_id=user.username,
ip_address=request.client.host or "",
user_agent=request.headers.get("user-agent", ""),
expires_at=expires_at,
is_active=True
# Use the database session context manager
with get_db() as db:
try:
# Look up user by token
user = db.query(User).filter(User.token == token).first()
# Debug messages disabled
if not user:
# Debug messages disabled
raise HTTPException(status_code=401, detail="Invalid or expired token")
if datetime.utcnow() - user.token_created > timedelta(minutes=30):
# Debug messages disabled
raise HTTPException(status_code=401, detail="Token expired")
# Mark user as confirmed if not already
if not user.confirmed:
user.confirmed = True
user.ip = request.client.host
db.add(user)
# Debug messages disabled
# Create a new session for the user (valid for 24 hours)
session_token = secrets.token_urlsafe(32)
expires_at = datetime.utcnow() + timedelta(hours=24)
# Create new session
session = DBSession(
token=session_token,
uid=user.email or user.username, # Use email as UID
ip_address=request.client.host or "",
user_agent=request.headers.get("user-agent", ""),
expires_at=expires_at,
is_active=True
)
db.add(session)
db.commit()
# Store user data for use after the session is committed
user_email = user.email or user.username
username = user.username
except Exception as e:
db.rollback()
# Debug messages disabled
# Debug messages disabled
raise HTTPException(status_code=500, detail="Database error during login")
# Determine if we're running in development (localhost) or production
is_localhost = request.url.hostname == "localhost"
# Prepare response data
response_data = {
"success": True,
"message": "Login successful",
"user": {
"email": user_email,
"username": username
},
"token": session_token # Include the token in the JSON response
}
# Create the response
response = JSONResponse(
content=response_data,
status_code=200
)
db.add(session)
db.commit()
# Set cookie with the session token (valid for 1 hour)
# Set cookies
response.set_cookie(
key="sessionid",
value=session_token,
httponly=True,
secure=not request.url.hostname == "localhost",
samesite="lax",
max_age=3600, # 1 hour
secure=not is_localhost,
samesite="lax" if is_localhost else "none",
max_age=86400, # 24 hours
path="/"
)
print(f"[magic-login] Session created for user: {user.username}")
# Redirect to success page
return RedirectResponse(
url=f"/?login=success&confirmed_uid={user.username}",
status_code=302,
headers=dict(response.headers)
response.set_cookie(
key="uid",
value=user_email,
samesite="lax" if is_localhost else "none",
secure=not is_localhost,
max_age=86400, # 24 hours
path="/"
)
response.set_cookie(
key="authToken",
value=session_token,
samesite="lax" if is_localhost else "none",
secure=not is_localhost,
max_age=86400, # 24 hours
path="/"
)
# Debug messages disabled
# Debug messages disabled
# Debug messages disabled
return response