Emails: Add Expires header (#20285)

* Add `Expiry` header to emails, set default expiry to 30 days and allow user config via `appsettings`

* Remove `IsSmtpExpirationConfigured` as it will always have a value

* Check for `emailExpiration` value

* Removed `EmailExpiration` default value as it should be opt-in

* Simplify SMTP email expiration condition

* Fix APICompat issue

* Add implementation to `NotImplementedEmailSender`

* Rename `emailExpiration` to `expires` to match the SMTP header

* Obsolete interfaces without `expires` parameter, delegate to an existing method.

* Set expiry TimeSpan values from user configurable settings with defaults

* Fix formating

* Handle breaking changes, add obsoletion messages and simplify interfaces.

* Fix default of invite expires timespan (was being parsed as 72 days not 72 hours).

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
Rick Butterfield
2025-10-09 13:27:53 +01:00
committed by GitHub
parent 767894b723
commit bcedc8de2a
12 changed files with 131 additions and 31 deletions

View File

@@ -181,6 +181,11 @@ public class GlobalSettings
/// </summary>
public bool IsSmtpServerConfigured => !string.IsNullOrWhiteSpace(Smtp?.Host);
/// <summary>
/// Gets a value indicating whether SMTP expiry is configured.
/// </summary>
public bool IsSmtpExpiryConfigured => Smtp?.EmailExpiration != null && Smtp?.EmailExpiration.HasValue == true;
/// <summary>
/// Gets a value indicating whether there is a physical pickup directory configured.
/// </summary>

View File

@@ -34,6 +34,9 @@ public class SecuritySettings
internal const string StaticAuthorizeCallbackLogoutPathName = "/umbraco/logout";
internal const string StaticAuthorizeCallbackErrorPathName = "/umbraco/error";
internal const string StaticPasswordResetEmailExpiry = "01:00:00";
internal const string StaticUserInviteEmailExpiry = "3.00:00:00";
/// <summary>
/// Gets or sets a value indicating whether to keep the user logged in.
/// </summary>
@@ -159,4 +162,16 @@ public class SecuritySettings
/// </summary>
[DefaultValue(StaticAuthorizeCallbackErrorPathName)]
public string AuthorizeCallbackErrorPathName { get; set; } = StaticAuthorizeCallbackErrorPathName;
/// <summary>
/// Gets or sets the expiry time for password reset emails.
/// </summary>
[DefaultValue(StaticPasswordResetEmailExpiry)]
public TimeSpan PasswordResetEmailExpiry { get; set; } = TimeSpan.Parse(StaticPasswordResetEmailExpiry);
/// <summary>
/// Gets or sets the expiry time for user invite emails.
/// </summary>
[DefaultValue(StaticUserInviteEmailExpiry)]
public TimeSpan UserInviteEmailExpiry { get; set; } = TimeSpan.Parse(StaticUserInviteEmailExpiry);
}

View File

@@ -96,4 +96,9 @@ public class SmtpSettings : ValidatableEntryBase
/// Gets or sets a value for the SMTP password.
/// </summary>
public string? Password { get; set; }
/// <summary>
/// Gets or sets a value for the time until an email expires.
/// </summary>
public TimeSpan? EmailExpiration { get; set; }
}