diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 2b53c52ab8b6..f97d78090d49 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -23,6 +23,7 @@ public static class Constants public const string Fido2KeyCipherMinimumVersion = "2023.10.0"; public const string SSHKeyCipherMinimumVersion = "2024.12.0"; + public const string DenyLegacyUserMinimumVersion = "2025.5.0"; /// <summary> /// Used by IdentityServer to identify our own provider. diff --git a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs index 88691fa8f708..c9da7f751082 100644 --- a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs @@ -203,7 +203,7 @@ await _twoFactorAuthenticationValidator protected async Task FailAuthForLegacyUserAsync(User user, T context) { await BuildErrorResultAsync( - $"Encryption key migration is required. Please log in to the web vault at {_globalSettings.BaseServiceUri.VaultWithHash}", + $"Legacy encryption without a userkey is no longer supported. To recover your account, please contact support", false, context, user); } diff --git a/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs index a7c6449ff611..f89f0a5c502b 100644 --- a/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs @@ -26,6 +26,7 @@ public class CustomTokenRequestValidator : BaseRequestValidator<CustomTokenReque { private readonly UserManager<User> _userManager; private readonly IUpdateInstallationCommand _updateInstallationCommand; + private readonly Version _denyLegacyUserMinimumVersion = new(Constants.DenyLegacyUserMinimumVersion); public CustomTokenRequestValidator( UserManager<User> userManager, @@ -73,7 +74,7 @@ public async Task ValidateAsync(CustomTokenRequestValidationContext context) { // Force legacy users to the web for migration if (await _userService.IsLegacyUser(GetSubject(context)?.GetSubjectId()) && - context.Result.ValidatedRequest.ClientId != "web") + (context.Result.ValidatedRequest.ClientId != "web" || CurrentContext.ClientVersion >= _denyLegacyUserMinimumVersion)) { await FailAuthForLegacyUserAsync(null, context); return; diff --git a/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs b/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs index 38a1518d14b9..56e1551cde0d 100644 --- a/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs +++ b/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs @@ -329,7 +329,7 @@ await _factory.RegisterAsync(new RegisterRequestModel } [Theory, BitAutoData] - public async Task TokenEndpoint_GrantTypeClientCredentials_AsLegacyUser_NotOnWebClient_Fails(string deviceId) + public async Task TokenEndpoint_GrantTypeClientCredentials_AsLegacyUser_Fails(string deviceId) { var server = _factory.WithWebHostBuilder(builder => { @@ -371,7 +371,7 @@ await server.PostAsync("/accounts/register", JsonContent.Create(new RegisterRequ var errorBody = await AssertHelper.AssertResponseTypeIs<JsonDocument>(context); var error = AssertHelper.AssertJsonProperty(errorBody.RootElement, "ErrorModel", JsonValueKind.Object); var message = AssertHelper.AssertJsonProperty(error, "Message", JsonValueKind.String).GetString(); - Assert.StartsWith("Encryption key migration is required.", message); + Assert.StartsWith("Legacy encryption without a userkey is no longer supported.", message); } diff --git a/test/Identity.Test/IdentityServer/BaseRequestValidatorTests.cs b/test/Identity.Test/IdentityServer/BaseRequestValidatorTests.cs index 589aac2842ef..bf3954db3acc 100644 --- a/test/Identity.Test/IdentityServer/BaseRequestValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/BaseRequestValidatorTests.cs @@ -381,8 +381,7 @@ public async Task ValidateAsync_IsLegacyUser_FailAuthForLegacyUserAsync( // Assert Assert.True(context.GrantResult.IsError); var errorResponse = (ErrorResponseModel)context.GrantResult.CustomResponse["ErrorModel"]; - var expectedMessage = $"Encryption key migration is required. Please log in to the web " + - $"vault at {_globalSettings.BaseServiceUri.VaultWithHash}"; + var expectedMessage = "Legacy encryption without a userkey is no longer supported. To recover your account, please contact support"; Assert.Equal(expectedMessage, errorResponse.Message); }