diff --git a/CHANGELOG.md b/CHANGELOG.md index aa84de5bb..38911e5e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +## [0.28.0] +- Updates timestamps to use UTC instead of GMT as the timezone + ## [0.27.0] - 2024-12-30 - Added OAuth2Provider recipe diff --git a/setup.py b/setup.py index 9dd20f4cd..cfdcbd999 100644 --- a/setup.py +++ b/setup.py @@ -83,7 +83,7 @@ setup( name="supertokens_python", - version="0.27.0", + version="0.28.0", author="SuperTokens", license="Apache 2.0", author_email="team@supertokens.com", diff --git a/supertokens_python/constants.py b/supertokens_python/constants.py index 20af8716b..48bf82850 100644 --- a/supertokens_python/constants.py +++ b/supertokens_python/constants.py @@ -15,7 +15,7 @@ from __future__ import annotations SUPPORTED_CDI_VERSIONS = ["5.2"] -VERSION = "0.27.0" +VERSION = "0.28.0" TELEMETRY = "/telemetry" USER_COUNT = "/users/count" USER_DELETE = "/user/remove" diff --git a/supertokens_python/framework/django/django_response.py b/supertokens_python/framework/django/django_response.py index 7184abe35..264a314f4 100644 --- a/supertokens_python/framework/django/django_response.py +++ b/supertokens_python/framework/django/django_response.py @@ -51,7 +51,7 @@ def set_cookie( key=key, value=value, expires=datetime.fromtimestamp(ceil(expires / 1000)).strftime( - "%a, %d %b %Y %H:%M:%S GMT" + "%a, %d %b %Y %H:%M:%S UTC" ), path=path, domain=domain, diff --git a/tests/Django/test_django.py b/tests/Django/test_django.py index 4291524e3..fad5204a5 100644 --- a/tests/Django/test_django.py +++ b/tests/Django/test_django.py @@ -296,7 +296,7 @@ async def test_login_handle(self): try: datetime.strptime( - cookies["sAccessToken"]["expires"], "%a, %d %b %Y %H:%M:%S GMT" + cookies["sAccessToken"]["expires"], "%a, %d %b %Y %H:%M:%S UTC" ) except ValueError: assert False, "cookies expiry time doesn't have the correct format" diff --git a/tests/test_logger.py b/tests/test_logger.py index 24f5a7973..978f4e0c5 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -3,7 +3,7 @@ import logging import os import sys -from datetime import datetime as real_datetime +from datetime import datetime as real_datetime, timezone from unittest import TestCase from unittest.mock import MagicMock, patch @@ -43,7 +43,7 @@ def teardown_method(self, _): @patch("supertokens_python.logger.datetime", wraps=real_datetime) def test_1_json_msg_format(self, datetime_mock: MagicMock): enable_debug_logging() - datetime_mock.now.return_value = real_datetime(2000, 1, 1) + datetime_mock.now.return_value = real_datetime(2000, 1, 1, tzinfo=timezone.utc) with self.assertLogs(level="DEBUG") as captured: log_debug_message("API replied with status 200") @@ -52,7 +52,7 @@ def test_1_json_msg_format(self, datetime_mock: MagicMock): out = json.loads(record.msg) assert out == { - "t": "2000-01-01T00:00Z", + "t": "2000-01-01T00:00:00+00Z", "sdkVer": VERSION, "message": "API replied with status 200", "file": "../tests/test_logger.py:49", diff --git a/tests/test_session.py b/tests/test_session.py index e7b9f8f2d..9dc4b4559 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -13,7 +13,7 @@ # under the License. import asyncio -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from typing import Any, Dict, List, Optional from unittest.mock import MagicMock @@ -663,15 +663,13 @@ async def test_token_cookie_expires( for c in response.cookies.jar: if c.name == "sAccessToken": # 100 years (set by the SDK) # some time must have elasped since the cookie was set. So less than current time - assert ( - datetime.fromtimestamp(c.expires or 0) - timedelta(days=365.25 * 100) - < datetime.now() - ) + assert datetime.fromtimestamp(c.expires or 0, tz=timezone.utc) - timedelta( + days=365.25 * 100 + ) < datetime.now(tz=timezone.utc) if c.name == "sRefreshToken": # 100 days (set by the core) - assert ( - datetime.fromtimestamp(c.expires or 0) - timedelta(days=100) - < datetime.now() - ) + assert datetime.fromtimestamp(c.expires or 0, tz=timezone.utc) - timedelta( + days=100 + ) < datetime.now(tz=timezone.utc) assert response.headers["anti-csrf"] != "" assert response.headers["front-token"] != "" @@ -693,15 +691,13 @@ async def test_token_cookie_expires( for c in response.cookies.jar: if c.name == "sAccessToken": # 100 years (set by the SDK) # some time must have elasped since the cookie was set. So less than current time - assert ( - datetime.fromtimestamp(c.expires or 0) - timedelta(days=365.25 * 100) - < datetime.now() - ) + assert datetime.fromtimestamp(c.expires or 0, tz=timezone.utc) - timedelta( + days=365.25 * 100 + ) < datetime.now(tz=timezone.utc) if c.name == "sRefreshToken": # 100 days (set by the core) - assert ( - datetime.fromtimestamp(c.expires or 0) - timedelta(days=100) - < datetime.now() - ) + assert datetime.fromtimestamp(c.expires or 0, tz=timezone.utc) - timedelta( + days=100 + ) < datetime.now(tz=timezone.utc) assert response.headers["anti-csrf"] != "" assert response.headers["front-token"] != "" diff --git a/tests/thirdparty/test_thirdparty.py b/tests/thirdparty/test_thirdparty.py index bab1371a6..1c21dc1d9 100644 --- a/tests/thirdparty/test_thirdparty.py +++ b/tests/thirdparty/test_thirdparty.py @@ -1,4 +1,4 @@ -import datetime +from datetime import datetime, timezone import json from base64 import b64encode from typing import Dict, Any, Optional @@ -208,7 +208,7 @@ async def test_signinup_when_validate_access_token_throws(fastapi_client: TestCl async def test_signinup_works_when_validate_access_token_does_not_throw( fastapi_client: TestClient, mocker: MockerFixture ): - time = str(datetime.datetime.now()) + time = str(datetime.now(tz=timezone.utc)) mocker.patch( "supertokens_python.recipe.thirdparty.providers.custom.get_supertokens_user_info_result_from_raw_user_info", return_value=UserInfo( @@ -276,7 +276,7 @@ async def test_signinup_works_when_validate_access_token_does_not_throw( async def test_signinup_android_without_redirect_uri( fastapi_client: TestClient, mocker: MockerFixture ): - time = str(datetime.datetime.now()) + time = str(datetime.now(tz=timezone.utc)) mocker.patch( "supertokens_python.recipe.thirdparty.providers.custom.get_supertokens_user_info_result_from_raw_user_info", return_value=UserInfo( diff --git a/tests/utils.py b/tests/utils.py index 62a267c54..ebe2b6451 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -13,7 +13,7 @@ # under the License. import asyncio import json -from datetime import datetime, timezone +from datetime import datetime from http.cookies import SimpleCookie from os import environ, kill, remove, scandir from pathlib import Path @@ -313,11 +313,7 @@ def assert_info_clears_tokens(info: Dict[str, Any], token_transfer_method: str): def get_unix_timestamp(expiry: str): - return int( - datetime.strptime(expiry, "%a, %d %b %Y %H:%M:%S GMT") - .replace(tzinfo=timezone.utc) - .timestamp() - ) + return int(datetime.strptime(expiry, "%a, %d %b %Y %H:%M:%S UTC").timestamp()) def verify_within_5_second_diff(n1: int, n2: int):