Update authentication system, database models, and UI components
This commit is contained in:
137
magic.py
137
magic.py
@ -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
|
||||
|
Reference in New Issue
Block a user