diff --git a/src/infrastructure/config/settings.py b/src/infrastructure/config/settings.py index 01a2495..7335da5 100644 --- a/src/infrastructure/config/settings.py +++ b/src/infrastructure/config/settings.py @@ -55,9 +55,11 @@ class Settings(BaseSettings): CSRF_COOKIE_HTTPONLY: bool = True CSRF_COOKIE_SAMESITE: Literal['Lax', 'Strict', 'None'] = 'Lax' CSRF_COOKIE_PATH: str = '/' - CSRF_COOKIE_DOMAIN: str | None = None + CSRF_COOKIE_DOMAIN: str | None = 'elcsa.ru' AUTH_COOKIE_SECURE: bool = False + AUTH_COOKIE_DOMAIN: str | None = 'elcsa.ru' + CORS_ALLOW_ORIGIN_REGEX: str = r'https?://([a-z0-9-]+\.)*elcsa\.ru(:\d+)?$' DOCS_USERNAME: str = 'admin' DOCS_PASSWORD: str = 'admin' @@ -103,6 +105,13 @@ class Settings(BaseSettings): return None return v + @field_validator('AUTH_COOKIE_DOMAIN', mode='before') + @classmethod + def empty_auth_domain_to_none(cls, v): + if v is None or (isinstance(v, str) and not v.strip()): + return None + return v + @field_validator('REDIS_PASSWORD', mode='before') @classmethod def empty_redis_password_to_none(cls, v): diff --git a/src/main.py b/src/main.py index b9921d9..c220947 100644 --- a/src/main.py +++ b/src/main.py @@ -171,7 +171,7 @@ app.add_middleware( app.add_middleware( CORSMiddleware, - allow_origin_regex=r'https?://.+', + allow_origin_regex=settings.CORS_ALLOW_ORIGIN_REGEX, allow_credentials=True, allow_methods=['*'], allow_headers=['*'], diff --git a/src/presentation/routing/auth.py b/src/presentation/routing/auth.py index 192e364..8ce269e 100644 --- a/src/presentation/routing/auth.py +++ b/src/presentation/routing/auth.py @@ -83,6 +83,7 @@ async def registration( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=60 * 60 * 24 * 365 * 5 ) @@ -93,6 +94,7 @@ async def registration( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_ACCESS_TTL_SECONDS), ) response.set_cookie( @@ -102,6 +104,7 @@ async def registration( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_REFRESH_TTL_SECONDS), ) return response @@ -174,6 +177,7 @@ async def login( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=60 * 60 * 24 * 365 * 5 ) @@ -184,6 +188,7 @@ async def login( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_ACCESS_TTL_SECONDS), ) @@ -194,6 +199,7 @@ async def login( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_REFRESH_TTL_SECONDS), ) @@ -211,8 +217,8 @@ async def logout_current( await command(refresh_token=refresh_token) response = ORJSONResponse({'ok': True}) - response.delete_cookie('access_token', path='/') - response.delete_cookie('refresh_token', path='/') + response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) + response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) return response diff --git a/src/presentation/routing/jwt.py b/src/presentation/routing/jwt.py index e12349c..b953a74 100644 --- a/src/presentation/routing/jwt.py +++ b/src/presentation/routing/jwt.py @@ -22,8 +22,8 @@ async def refresh_tokens( if not refresh_token: response = ORJSONResponse({'ok': False, 'error': 'No refresh token'}, status_code=401) - response.delete_cookie('access_token', path='/') - response.delete_cookie('refresh_token', path='/') + response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) + response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) return response ip = request.client.host if request.client else None @@ -33,8 +33,8 @@ async def refresh_tokens( access, refresh = await command(refresh_token=refresh_token, ip=ip, user_agent=user_agent) except ApplicationException: response = ORJSONResponse({'result': False}, status_code=401) - response.delete_cookie('access_token', path='/') - response.delete_cookie('refresh_token', path='/') + response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) + response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN) return response response = ORJSONResponse({'result': True}) @@ -46,6 +46,7 @@ async def refresh_tokens( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_ACCESS_TTL_SECONDS), ) response.set_cookie( @@ -55,6 +56,7 @@ async def refresh_tokens( secure=settings.AUTH_COOKIE_SECURE, samesite='lax', path='/', + domain=settings.AUTH_COOKIE_DOMAIN, max_age=int(settings.JWT_REFRESH_TTL_SECONDS), ) return response