From de696bd4ee495e2ea540cdbe9e6278ab9ff7bf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20=22Wega=22=20Weglarz?= <82312488+ThomasWega@users.noreply.github.com> Date: Tue, 8 Sep 2026 21:41:28 +0200 Subject: [PATCH 1/3] Fixed cracked players with premium names not being able to join the server (register) at all --- .../auth/username/UsernameResolutionService.kt | 17 ++++++++++++----- ...UsernameResolutionServiceIntegrationTests.kt | 11 ++++++----- .../unit/auth/UsernameResolutionServiceTests.kt | 11 ++++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/navauth-common/src/main/kotlin/pl/spcode/navauth/common/application/auth/username/UsernameResolutionService.kt b/navauth-common/src/main/kotlin/pl/spcode/navauth/common/application/auth/username/UsernameResolutionService.kt index 3b3738a..ff16cb1 100644 --- a/navauth-common/src/main/kotlin/pl/spcode/navauth/common/application/auth/username/UsernameResolutionService.kt +++ b/navauth-common/src/main/kotlin/pl/spcode/navauth/common/application/auth/username/UsernameResolutionService.kt @@ -75,7 +75,10 @@ constructor(private val userService: UserService, private val profileService: Pr // check if the letter case changed if ( correspondingPremiumProfile.name != existingUserIgnoreCase.username && - correspondingPremiumProfile.name.value.equals(existingUserIgnoreCase.username.value, true) + correspondingPremiumProfile.name.value.equals( + existingUserIgnoreCase.username.value, + true, + ) ) { userService.migrateUsername(existingUserIgnoreCase, correspondingPremiumProfile.name) return success( @@ -87,7 +90,13 @@ constructor(private val userService: UserService, private val profileService: Pr if (existingUserIgnoreCase != null && !existingUserIgnoreCase.isPremium) { if (isPremiumNickname) { - return if (existingUserIgnoreCase.username == correspondingPremiumProfile.name) { + // Check if usernames match case-insensitively (allow case variants as same account) + val sameNameIgnoreCase = + existingUserIgnoreCase.username.value.equals( + correspondingPremiumProfile.name.value, + ignoreCase = true, + ) + return if (sameNameIgnoreCase) { success( EncryptionType.NONE, PostUsernameResolutionState.NONPREMIUM_WITH_SAME_PREMIUM_NICKNAME, @@ -131,10 +140,8 @@ constructor(private val userService: UserService, private val profileService: Pr ) ) } - return success(EncryptionType.ENFORCE_PREMIUM, PostUsernameResolutionState.NEW_ACCOUNT) - } else { - return success(EncryptionType.NONE, PostUsernameResolutionState.NEW_ACCOUNT) } + return success(EncryptionType.NONE, PostUsernameResolutionState.NEW_ACCOUNT) } throw IllegalStateException( diff --git a/navauth-common/src/test/kotlin/integration/auth/UsernameResolutionServiceIntegrationTests.kt b/navauth-common/src/test/kotlin/integration/auth/UsernameResolutionServiceIntegrationTests.kt index 0e886dd..bb09569 100644 --- a/navauth-common/src/test/kotlin/integration/auth/UsernameResolutionServiceIntegrationTests.kt +++ b/navauth-common/src/test/kotlin/integration/auth/UsernameResolutionServiceIntegrationTests.kt @@ -55,7 +55,7 @@ class UsernameResolutionServiceIntegrationTests { } @Test - fun `new premium user returns success premium encryption type`() { + fun `new premium user returns success none encryption type`() { val username = Username(generateRandomString(10)) fakeProfileService.addProfile(username, MojangProfile(MojangId(UUID.randomUUID()), username)) @@ -63,7 +63,7 @@ class UsernameResolutionServiceIntegrationTests { assertEquals( UsernameResResult.Success( - EncryptionType.ENFORCE_PREMIUM, + EncryptionType.NONE, PostUsernameResolutionState.NEW_ACCOUNT, ), result, @@ -117,7 +117,7 @@ class UsernameResolutionServiceIntegrationTests { } @Test - fun `existing nonpremium user conflict with different case premium username returns failure`() { + fun `existing nonpremium user conflict with different case premium username returns success`() { val username = Username(generateRandomString(10)) val premiumUsername = Username(invertCase(username.value)) val premiumProfile = MojangProfile(MojangId(UUID.randomUUID()), premiumUsername) @@ -128,8 +128,9 @@ class UsernameResolutionServiceIntegrationTests { val result = usernameResolutionService.resolveUsernameConflicts(username, existingUser) assertEquals( - UsernameResResult.Failure( - UsernameResFailureReason.NonPremiumWithPremiumConflict(premiumUsername.value) + UsernameResResult.Success( + EncryptionType.NONE, + PostUsernameResolutionState.NONPREMIUM_WITH_SAME_PREMIUM_NICKNAME, ), result, ) diff --git a/navauth-common/src/test/kotlin/unit/auth/UsernameResolutionServiceTests.kt b/navauth-common/src/test/kotlin/unit/auth/UsernameResolutionServiceTests.kt index 57e1a67..cdd12eb 100644 --- a/navauth-common/src/test/kotlin/unit/auth/UsernameResolutionServiceTests.kt +++ b/navauth-common/src/test/kotlin/unit/auth/UsernameResolutionServiceTests.kt @@ -52,7 +52,7 @@ class UsernameResolutionServiceTests : service = UsernameResolutionService(mockUserService, mockProfileService) } - test("new premium user returns success, premium encryption type") { + test("new premium user returns success, none type") { val username = Username(generateRandomString(10)) val premiumProfile = MojangProfile(MojangId(UUID.randomUUID()), username) every { mockProfileService.fetchProfileInfo(username, any()) } returns premiumProfile @@ -62,7 +62,7 @@ class UsernameResolutionServiceTests : result shouldBe UsernameResResult.Success( - EncryptionType.ENFORCE_PREMIUM, + EncryptionType.NONE, PostUsernameResolutionState.NEW_ACCOUNT, ) } @@ -127,7 +127,7 @@ class UsernameResolutionServiceTests : UsernameResResult.Success(EncryptionType.NONE, PostUsernameResolutionState.NO_CHANGE) } - test("existing nonpremium user conflict with different case premium username returns failure") { + test("existing nonpremium user conflict with different case premium username returns success") { val username = Username(generateRandomString(10)) // make sure the premium profile has a different username case val premiumUsername = Username(invertCase(username.value)) @@ -138,8 +138,9 @@ class UsernameResolutionServiceTests : val result = service.resolveUsernameConflicts(username, existingUser) result shouldBe - UsernameResResult.Failure( - UsernameResFailureReason.NonPremiumWithPremiumConflict(premiumUsername.value) + UsernameResResult.Success( + EncryptionType.NONE, + PostUsernameResolutionState.NONPREMIUM_WITH_SAME_PREMIUM_NICKNAME, ) } From bdf6da1cdaa43a95927f1fac121b04e6febb39e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20=22Wega=22=20Weglarz?= <82312488+ThomasWega@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:34:25 +0200 Subject: [PATCH 2/3] Fixed cracked players with premium names not being able to join the server (register) at all --- .gitignore | 6 +- .idea/gradle.xml | 2 +- .idea/misc.xml | 3 + gradlew | 0 gradlew.bat | 0 .../credentials/UserCredentialsService.kt | 10 +--- .../common/application/user/UserService.kt | 43 +++------------ .../domain/credentials/UserCredentials.kt | 14 +---- .../spcode/navauth/common/domain/user/User.kt | 19 ++----- .../common/infra/auth/LoginAuthSession.kt | 50 ++++++++--------- .../infra/persistence/mapper/UserMapper.kt | 2 - .../migrator/librelogin/LibreLoginMigrator.kt | 10 ++-- .../auth/UsernameResolutionServiceTests.kt | 5 +- .../command/admin/PlayerLookupAdminCommand.kt | 2 - .../command/user/ChangePasswordCommand.kt | 5 -- .../velocity/command/user/LoginCommand.kt | 2 +- .../command/user/TwoFactorSetupCommand.kt | 55 +++++-------------- .../infra/auth/VelocityLoginAuthSession.kt | 8 +-- .../listener/velocity/LoginListeners.kt | 11 +--- 19 files changed, 72 insertions(+), 175 deletions(-) mode change 100644 => 100755 gradlew mode change 100644 => 100755 gradlew.bat diff --git a/.gitignore b/.gitignore index 97510a7..2a14e4e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,11 +11,7 @@ build/ !**/src/test/**/build/ ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -.idea/AndroidProjectSystem.xml +.idea/ *.iws *.iml *.ipr diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 25956e9..169b8d9 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -16,7 +16,7 @@