260717_0
This commit is contained in:
@@ -12,6 +12,8 @@ from fastapi.responses import Response
|
||||
|
||||
from config.config_db import get_db_pool
|
||||
from config.config_system import (
|
||||
DEVICE_TOKEN_COOKIE_NAME,
|
||||
EMAIL_REVERIFY_DAYS,
|
||||
PASSWORD_BCRYPT_ROUNDS,
|
||||
SESSION_COOKIE_NAME,
|
||||
SESSION_COOKIE_SECURE,
|
||||
@@ -39,6 +41,30 @@ def hash_user_agent(user_agent: str) -> str:
|
||||
return hashlib.sha256(normalized.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def generate_device_token() -> str:
|
||||
return secrets.token_urlsafe(32)
|
||||
|
||||
|
||||
def hash_device_token(token: str) -> str:
|
||||
return hashlib.sha256(token.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def get_device_token_cookie(request: Request) -> str | None:
|
||||
return request.cookies.get(DEVICE_TOKEN_COOKIE_NAME)
|
||||
|
||||
|
||||
def set_device_token_cookie(response: Response, token: str) -> None:
|
||||
response.set_cookie(
|
||||
key=DEVICE_TOKEN_COOKIE_NAME,
|
||||
value=token,
|
||||
max_age=EMAIL_REVERIFY_DAYS * 24 * 60 * 60,
|
||||
secure=SESSION_COOKIE_SECURE,
|
||||
httponly=True,
|
||||
samesite="lax",
|
||||
path="/",
|
||||
)
|
||||
|
||||
|
||||
def set_session_cookie(response: Response, session_id: str) -> None:
|
||||
response.set_cookie(
|
||||
key=SESSION_COOKIE_NAME,
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import Any
|
||||
import aiomysql
|
||||
|
||||
from config.config_db import get_db_pool
|
||||
from config.config_system import OTP_VALID_MINUTES
|
||||
from config.config_system import EMAIL_REVERIFY_DAYS, OTP_VALID_MINUTES
|
||||
|
||||
|
||||
def _company_code() -> str:
|
||||
@@ -152,8 +152,7 @@ async def complete_registration(user_id: int, is_master: bool) -> None:
|
||||
pool = get_db_pool()
|
||||
async with pool.acquire() as connection, connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
"""UPDATE users SET status = 'NO_COMPANY', last_email_verified_at = CURRENT_TIMESTAMP,
|
||||
auth_expires_at = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 3 MONTH)
|
||||
"""UPDATE users SET status = 'NO_COMPANY', last_email_verified_at = CURRENT_TIMESTAMP
|
||||
WHERE id = %s""",
|
||||
(user_id,),
|
||||
)
|
||||
@@ -226,23 +225,49 @@ async def clear_login_failures(user_id: int) -> None:
|
||||
await connection.commit()
|
||||
|
||||
|
||||
async def has_known_browser(user_id: int, user_agent_hash: str) -> bool:
|
||||
async def has_trusted_device(user_id: int, token_hash: str) -> bool:
|
||||
valid_after = datetime.utcnow() - timedelta(days=EMAIL_REVERIFY_DAYS)
|
||||
pool = get_db_pool()
|
||||
async with pool.acquire() as connection, connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
"SELECT 1 FROM trusted_devices WHERE user_id = %s AND user_agent_hash = %s LIMIT 1",
|
||||
(user_id, user_agent_hash),
|
||||
"""SELECT id FROM trusted_devices
|
||||
WHERE user_id = %s AND token_hash = %s AND last_used_at >= %s LIMIT 1""",
|
||||
(user_id, token_hash, valid_after),
|
||||
)
|
||||
return await cursor.fetchone() is not None
|
||||
row = await cursor.fetchone()
|
||||
if not row:
|
||||
return False
|
||||
await cursor.execute(
|
||||
"UPDATE trusted_devices SET last_used_at = CURRENT_TIMESTAMP WHERE id = %s",
|
||||
(row[0],),
|
||||
)
|
||||
await connection.commit()
|
||||
return True
|
||||
|
||||
|
||||
async def trust_browser(user_id: int, user_agent_hash: str) -> None:
|
||||
async def trust_device(
|
||||
user_id: int,
|
||||
token_hash: str,
|
||||
user_agent_hash: str,
|
||||
previous_token_hash: str | None = None,
|
||||
) -> None:
|
||||
pool = get_db_pool()
|
||||
async with pool.acquire() as connection, connection.cursor() as cursor:
|
||||
if previous_token_hash:
|
||||
await cursor.execute(
|
||||
"""UPDATE trusted_devices
|
||||
SET token_hash = %s, user_agent_hash = %s,
|
||||
verified_at = CURRENT_TIMESTAMP, last_used_at = CURRENT_TIMESTAMP
|
||||
WHERE user_id = %s AND token_hash = %s""",
|
||||
(token_hash, user_agent_hash, user_id, previous_token_hash),
|
||||
)
|
||||
if cursor.rowcount:
|
||||
await connection.commit()
|
||||
return
|
||||
await cursor.execute(
|
||||
"""INSERT INTO trusted_devices (user_id, user_agent_hash)
|
||||
VALUES (%s, %s) ON DUPLICATE KEY UPDATE last_used_at = CURRENT_TIMESTAMP""",
|
||||
(user_id, user_agent_hash),
|
||||
"""INSERT INTO trusted_devices (user_id, user_agent_hash, token_hash)
|
||||
VALUES (%s, %s, %s)""",
|
||||
(user_id, user_agent_hash, token_hash),
|
||||
)
|
||||
await connection.commit()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user