mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Fix token expiration
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
DATABASE_URL = "sqlite:///./data/database.db"
|
DATABASE_URL = "sqlite:///./data/database.db"
|
||||||
JWT_ALGORITHM = "HS256"
|
JWT_ALGORITHM = "HS256"
|
||||||
ACCESS_TOKEN_EXPIRE_HOURS = 24
|
# Token inactivity expiration - token expires if not used for this duration
|
||||||
|
TOKEN_INACTIVITY_EXPIRE_HOURS = 30 * 24 # 30 days of inactivity
|
||||||
|
# Maximum token lifetime (safety net) - tokens expire after this regardless of usage
|
||||||
|
MAX_TOKEN_LIFETIME_HOURS = 365 * 24 # 1 year maximum
|
||||||
OWNER_USERNAME = "denis0001-dev"
|
OWNER_USERNAME = "denis0001-dev"
|
||||||
JWT_SECRET_KEY = os.getenv("JWT_SECRET")
|
JWT_SECRET_KEY = os.getenv("JWT_SECRET")
|
||||||
|
|
||||||
|
|||||||
+15
-2
@@ -1,4 +1,4 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from fastapi import Depends, HTTPException, Request, status
|
from fastapi import Depends, HTTPException, Request, status
|
||||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@@ -66,7 +66,20 @@ def get_current_user(
|
|||||||
headers={"WWW-Authenticate": "Bearer"},
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Touch last_seen on valid session
|
# Check if session has been inactive for too long (sliding expiration)
|
||||||
|
from constants import TOKEN_INACTIVITY_EXPIRE_HOURS
|
||||||
|
inactivity_threshold = datetime.now() - timedelta(hours=TOKEN_INACTIVITY_EXPIRE_HOURS)
|
||||||
|
if device_session.last_seen < inactivity_threshold:
|
||||||
|
# Session expired due to inactivity - revoke it
|
||||||
|
device_session.revoked = True
|
||||||
|
db.commit()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Session expired due to inactivity",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Touch last_seen on valid session (sliding expiration - extends token life)
|
||||||
device_session.last_seen = datetime.now()
|
device_session.last_seen = datetime.now()
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -4,16 +4,17 @@ import jwt
|
|||||||
from typing import Optional, Any
|
from typing import Optional, Any
|
||||||
import bcrypt
|
import bcrypt
|
||||||
|
|
||||||
from constants import ACCESS_TOKEN_EXPIRE_HOURS, JWT_SECRET_KEY, JWT_ALGORITHM
|
from constants import MAX_TOKEN_LIFETIME_HOURS, JWT_SECRET_KEY, JWT_ALGORITHM
|
||||||
|
|
||||||
# JWT Helper Functions
|
# JWT Helper Functions
|
||||||
def create_token(user_id: int, username: str, session_id: str) -> str:
|
def create_token(user_id: int, username: str, session_id: str) -> str:
|
||||||
expire = datetime.now() + timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS)
|
# Set a long expiration as safety net (actual expiration based on inactivity)
|
||||||
|
expire = datetime.now() + timedelta(hours=MAX_TOKEN_LIFETIME_HOURS)
|
||||||
payload = {
|
payload = {
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"username": username,
|
"username": username,
|
||||||
"session_id": session_id,
|
"session_id": session_id,
|
||||||
"exp": expire
|
"exp": int(expire.timestamp()) # JWT exp must be Unix timestamp (int)
|
||||||
}
|
}
|
||||||
return jwt.encode(payload, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM)
|
return jwt.encode(payload, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user