feat: add refresh

This commit is contained in:
2026-06-05 12:41:25 +03:00
parent d300d2eabe
commit 9d3c5b401a
8 changed files with 175 additions and 50 deletions

View File

@@ -1,11 +1,14 @@
from __future__ import annotations
from datetime import datetime, timezone
from datetime import datetime, timezone, timedelta
from ulid import ULID
from src.application.abstractions import IUnitOfWork
from src.application.contracts import IHashService, IJwtService, ILogger
from src.application.domain.dto.admin_auth import AdminLoginDto
from src.application.domain.exceptions import ApplicationException
from src.infrastructure.config import settings
from src.infrastructure.database.decorators import transactional
@@ -23,7 +26,15 @@ class AdminLoginCommand:
self._logger = logger
@transactional
async def __call__(self, *, login: str, password: str) -> AdminLoginDto:
async def __call__(
self,
*,
login: str,
password: str,
device_id: str | None,
ip: str | None,
user_agent: str | None,
) -> AdminLoginDto:
login = (login or '').strip()
if not login:
raise ApplicationException(status_code=400, message='Login is required')
@@ -40,9 +51,32 @@ class AdminLoginCommand:
now = datetime.now(timezone.utc)
await self._unit_of_work.admin_user_repository.update_last_login(admin.id, last_login_at=now)
resolved_device_id = device_id or str(ULID())
sid = str(ULID())
jti = str(ULID())
jti_hash = await self._hash_service.hash(value=jti)
refresh_expires_at = now + timedelta(seconds=int(settings.JWT_REFRESH_TTL_SECONDS))
await self._unit_of_work.admin_session_repository.upsert_by_device(
admin_user_id=admin.id,
device_id=resolved_device_id,
sid=sid,
refresh_jti_hash=jti_hash,
refresh_expires_at=refresh_expires_at,
user_agent=user_agent,
ip=ip,
now=now,
)
access_token = await self._jwt_service.create_access_token(
user_id=admin.id,
role=admin.role,
sid=sid,
)
refresh_token = await self._jwt_service.create_refresh_token(
user_id=admin.id,
sid=sid,
refresh_jti=jti,
)
self._logger.info(f'Admin logged in admin_user_id={admin.id}')
@@ -54,5 +88,7 @@ class AdminLoginCommand:
last_name=admin.last_name,
role=admin.role,
access_token=access_token,
refresh_token=refresh_token,
device_id=resolved_device_id,
last_login_at=now,
)