feat(07.3-03): backend remember_me — TTL split + cookie Max-Age + 3 promoted tests
- services/auth.py: create_refresh_token gains remember_me=False param; selects 16h or 30d TTL (D-09, D-10, D-11) - api/auth.py: LoginRequest.remember_me bool field; _set_refresh_cookie remember_me param for conditional max_age; login handler threads remember_me through both calls (D-11, RM-03) - test_auth_es256.py: promote RM-01, RM-02, RM-03 stubs — all 9 phase tests now PASSED
This commit is contained in:
+17
-5
@@ -59,6 +59,7 @@ class LoginRequest(BaseModel):
|
||||
password: str
|
||||
totp_code: Optional[str] = None
|
||||
backup_code: Optional[str] = None
|
||||
remember_me: bool = False
|
||||
|
||||
|
||||
class ChangePasswordRequest(BaseModel):
|
||||
@@ -68,8 +69,19 @@ class ChangePasswordRequest(BaseModel):
|
||||
|
||||
# ── Helper: set httpOnly refresh cookie ──────────────────────────────────────
|
||||
|
||||
def _set_refresh_cookie(response: Response, raw_token: str) -> None:
|
||||
"""Set the httpOnly Secure SameSite=Strict refresh cookie (CLAUDE.md constraint)."""
|
||||
def _set_refresh_cookie(
|
||||
response: Response, raw_token: str, remember_me: bool = False
|
||||
) -> None:
|
||||
"""Set the httpOnly Secure SameSite=Strict refresh cookie (CLAUDE.md constraint).
|
||||
|
||||
remember_me=False (default): Max-Age = refresh_token_expire_hours * 3600 (16h, D-11, RM-03)
|
||||
remember_me=True: Max-Age = refresh_token_expire_days * 86400 (30d, D-11, RM-03)
|
||||
"""
|
||||
max_age = (
|
||||
settings.refresh_token_expire_days * 86400
|
||||
if remember_me
|
||||
else settings.refresh_token_expire_hours * 3600
|
||||
)
|
||||
response.set_cookie(
|
||||
key="refresh_token",
|
||||
value=raw_token,
|
||||
@@ -77,7 +89,7 @@ def _set_refresh_cookie(response: Response, raw_token: str) -> None:
|
||||
secure=True,
|
||||
samesite="strict",
|
||||
path="/api/auth/refresh",
|
||||
max_age=settings.refresh_token_expire_days * 86400,
|
||||
max_age=max_age,
|
||||
)
|
||||
|
||||
|
||||
@@ -276,8 +288,8 @@ async def login(
|
||||
|
||||
# Issue tokens
|
||||
access_token = auth_service.create_access_token(str(user.id), user.role)
|
||||
raw_refresh = await auth_service.create_refresh_token(session, user.id)
|
||||
_set_refresh_cookie(response, raw_refresh)
|
||||
raw_refresh = await auth_service.create_refresh_token(session, user.id, remember_me=body.remember_me)
|
||||
_set_refresh_cookie(response, raw_refresh, remember_me=body.remember_me)
|
||||
|
||||
# D-13: login success event
|
||||
await write_audit_log(
|
||||
|
||||
Reference in New Issue
Block a user