diff --git a/src/cartsnitch_api/auth/dependencies.py b/src/cartsnitch_api/auth/dependencies.py index 4eac005..390b40e 100644 --- a/src/cartsnitch_api/auth/dependencies.py +++ b/src/cartsnitch_api/auth/dependencies.py @@ -4,7 +4,6 @@ Validates Better-Auth session tokens from cookies or Bearer header. Sessions are verified by querying the shared sessions table directly. """ -import hashlib from datetime import UTC, datetime from fastapi import Cookie, Depends, Header, HTTPException, Request, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer @@ -27,14 +26,12 @@ SECURE_SESSION_COOKIE_NAME = "__Secure-better-auth.session_token" async def _validate_session_token(token: str, db: AsyncSession) -> str: """Validate a Better-Auth session token against the sessions table. - Better-Auth v1.2+ stores SHA-256(raw_token) in the DB. - The cookie/Bearer header carries the raw token, so we hash before lookup. + Better-Auth stores the raw token in the DB. The cookie/Bearer header + carries the same raw token, so we compare directly. """ - token_hash = hashlib.sha256(token.encode()).hexdigest() - result = await db.execute( text("SELECT user_id, expires_at FROM sessions WHERE token = :token"), - {"token": token_hash}, + {"token": token}, ) row = result.first() diff --git a/tests/conftest.py b/tests/conftest.py index 647dbd9..bb84c20 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,6 @@ Session-based auth: tests create users and sessions directly in the DB, matching the Better-Auth session validation flow. """ -import hashlib import secrets import uuid from datetime import UTC, datetime, timedelta @@ -137,14 +136,13 @@ async def client(db_engine): async def _create_test_user_and_session(client: AsyncClient, db_engine, **user_overrides) -> tuple[dict, str]: """Create a test user and a valid session directly in the DB. - Returns (user_dict, session_token). Better-Auth v1.2+ stores SHA-256 - hashed tokens in the DB, so the token is hashed before insertion. + Returns (user_dict, session_token). Better-Auth stores the raw token + in the DB, so we insert it as-is. """ user_id = str(uuid.uuid4()) email = user_overrides.get("email", "test@example.com") display_name = user_overrides.get("display_name", "Test User") session_token = secrets.token_urlsafe(32) - token_hash = hashlib.sha256(session_token.encode()).hexdigest() session_id = str(uuid.uuid4()) now = datetime.now(UTC).isoformat() expires = (datetime.now(UTC) + timedelta(days=7)).isoformat() @@ -172,7 +170,7 @@ async def _create_test_user_and_session(client: AsyncClient, db_engine, **user_o ), { "id": session_id, - "token": token_hash, + "token": session_token, "user_id": user_id, "expires_at": expires, "created_at": now, diff --git a/tests/test_auth/test_auth_endpoints.py b/tests/test_auth/test_auth_endpoints.py index 83e49d7..7b096ae 100644 --- a/tests/test_auth/test_auth_endpoints.py +++ b/tests/test_auth/test_auth_endpoints.py @@ -74,7 +74,6 @@ async def test_delete_me(client, auth_headers): @pytest.mark.asyncio async def test_expired_session_rejected(client, db_engine): """Expired sessions must be rejected.""" - import hashlib import secrets import uuid from datetime import UTC, datetime, timedelta @@ -83,7 +82,6 @@ async def test_expired_session_rejected(client, db_engine): user_id = str(uuid.uuid4()) session_token = secrets.token_urlsafe(32) - token_hash = hashlib.sha256(session_token.encode()).hexdigest() now = datetime.now(UTC).isoformat() expired = (datetime.now(UTC) - timedelta(hours=1)).isoformat() @@ -110,7 +108,7 @@ async def test_expired_session_rejected(client, db_engine): ), { "id": str(uuid.uuid4()), - "token": token_hash, + "token": session_token, "uid": user_id, "ea": expired, "ca": now,