diff --git a/frappe/core/doctype/security_settings/security_settings.py b/frappe/core/doctype/security_settings/security_settings.py index be52808e01..478e4e909b 100644 --- a/frappe/core/doctype/security_settings/security_settings.py +++ b/frappe/core/doctype/security_settings/security_settings.py @@ -1,7 +1,7 @@ # Copyright (c) 2026, Frappe Technologies and contributors # For license information, please see license.txt -from datetime import datetime +from datetime import UTC, datetime import frappe import frappe.utils @@ -33,13 +33,16 @@ class SecuritySettings(Document): @property def security_txt(self): - return "\n\n".join( - [ - self.public_policy_section, - self.public_contacts_section, - self.public_languages_section, - self.public_expires_section, - ] + return ( + "\n\n".join( + [ + self.public_policy_section, + self.public_contacts_section, + self.public_languages_section, + self.public_expires_section, + ] + ) + + "\n" ) @property @@ -64,9 +67,11 @@ class SecuritySettings(Document): @property def public_expires_section(self): expires = self.public_expires or frappe.utils.add_years(frappe.utils.now_datetime(), 1) - expires = (isinstance(expires, str) and datetime.fromisoformat(expires)) or expires + if isinstance(expires, str): + expires = datetime.fromisoformat(expires) expires = expires.replace(microsecond=0) - value = expires.isoformat() + expires = expires.astimezone(UTC) + value = expires.strftime("%Y-%m-%dT%H:%M:%SZ") return f"Expires: {value}" def with_protocol(self, url: str, type_: str) -> str: diff --git a/frappe/core/doctype/security_settings/test_security_settings.py b/frappe/core/doctype/security_settings/test_security_settings.py index a398bb8b10..9052e407cc 100644 --- a/frappe/core/doctype/security_settings/test_security_settings.py +++ b/frappe/core/doctype/security_settings/test_security_settings.py @@ -1,7 +1,7 @@ # Copyright (c) 2026, Frappe Technologies and Contributors # License: MIT. See LICENSE -from datetime import datetime, timedelta +from datetime import UTC, datetime, timedelta import frappe from frappe.tests import UnitTestCase @@ -240,7 +240,9 @@ class TestSecuritySettings(UnitTestCase): doc.validate_expires() def test_public_expires_section_future_date(self): - future_date = datetime(2027, 12, 31, 23, 59, 59) + from datetime import timezone + + future_date = datetime(2027, 12, 31, 23, 59, 59, tzinfo=UTC) doc = frappe.get_doc( { "doctype": "Security Settings", @@ -248,17 +250,17 @@ class TestSecuritySettings(UnitTestCase): } ) section = doc.public_expires_section - self.assertIn("2027-12-31T23:59:59", section) + self.assertIn("2027-12-31T23:59:59Z", section) def test_public_expires_section_string(self): doc = frappe.get_doc( { "doctype": "Security Settings", - "public_expires": "2027-12-31T23:59:59", + "public_expires": "2027-12-31T23:59:59+00:00", } ) section = doc.public_expires_section - self.assertIn("2027-12-31T23:59:59", section) + self.assertIn("2027-12-31T23:59:59Z", section) def test_public_expires_section_default(self): doc = frappe.get_doc({"doctype": "Security Settings"})