diff --git a/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt b/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt index bf55b90..5cdac17 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt @@ -13,6 +13,7 @@ import com.viaversion.aas.handler.forward import com.viaversion.aas.handler.setCompression import com.viaversion.aas.util.IntendedState import com.viaversion.aas.util.StacklessException +import com.viaversion.aas.web.TempLoginInfo import com.viaversion.viaversion.api.protocol.packet.State import com.viaversion.viaversion.api.protocol.version.ProtocolVersion import com.viaversion.viaversion.api.type.Type @@ -281,7 +282,8 @@ class LoginState : ConnectionState { frontOnline = info.frontOnline info.backName?.also { backName = info.backName } } - if (VIAaaSConfig.forceOnlineMode) frontOnline = true + val isLink = backAddress!!.host == "link" + if (VIAaaSConfig.forceOnlineMode || isLink) frontOnline = true if (frontOnline != null) { when (frontOnline) { false -> callbackPlayerId.complete(generateOfflinePlayerUuid(frontName)) @@ -290,6 +292,7 @@ class LoginState : ConnectionState { } val id = callbackPlayerId.await() mcLogger.info("Login: {} {} {}", handler.endRemoteAddress, frontName, id) + if (isLink) return@launch handleTempCode(handler, frontName, id) } connectBack( handler, @@ -308,6 +311,12 @@ class LoginState : ConnectionState { } } + private fun handleTempCode(handler: MinecraftHandler, name: String, id: UUID) { + val info = TempLoginInfo(secureRandom.nextInt().toUInt().toString(36), name, id) + AspirinServer.viaWebServer.tempCodes.put(name.lowercase(), info) + handler.disconnect("Your temp code is: ${info.tempCode}") + } + override fun disconnect(handler: MinecraftHandler, msg: String) { super.disconnect(handler, msg) diff --git a/src/main/kotlin/com/viaversion/aas/handler/state/StatusState.kt b/src/main/kotlin/com/viaversion/aas/handler/state/StatusState.kt index 63b96d0..f62fad2 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/state/StatusState.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/state/StatusState.kt @@ -76,7 +76,9 @@ class StatusState : ConnectionState { handler.data.frontChannel.setAutoRead(false) handler.coroutineScope.launch(Dispatchers.IO) { try { - if (address != null) { + if (address?.host == "link") { + handler.disconnect("Join to link your account") + } else if (address != null) { connectBack(handler, address!!, IntendedState.STATUS) } else { handler.disconnect("VIAaaS") diff --git a/src/main/kotlin/com/viaversion/aas/web/TempLoginInfo.kt b/src/main/kotlin/com/viaversion/aas/web/TempLoginInfo.kt new file mode 100644 index 0000000..e6f263a --- /dev/null +++ b/src/main/kotlin/com/viaversion/aas/web/TempLoginInfo.kt @@ -0,0 +1,5 @@ +package com.viaversion.aas.web + +import java.util.UUID + +data class TempLoginInfo(val tempCode: String, val username: String, val id: UUID) diff --git a/src/main/kotlin/com/viaversion/aas/web/WebLogin.kt b/src/main/kotlin/com/viaversion/aas/web/WebLogin.kt index 4f0c0ac..665c032 100644 --- a/src/main/kotlin/com/viaversion/aas/web/WebLogin.kt +++ b/src/main/kotlin/com/viaversion/aas/web/WebLogin.kt @@ -9,11 +9,7 @@ import com.viaversion.aas.util.StacklessException import com.viaversion.viaversion.api.protocol.version.ProtocolVersion import io.ktor.client.call.* import io.ktor.client.request.* -import io.ktor.client.request.forms.* -import io.ktor.http.* import io.ktor.server.websocket.* -import kotlinx.coroutines.future.await -import java.net.URLEncoder import java.time.Duration import java.util.* import kotlin.math.absoluteValue @@ -31,7 +27,7 @@ class WebLogin : WebState { when (obj["action"].asString) { "offline_login" -> handleOfflineLogin(webClient, msg, obj) - "minecraft_id_login" -> handleMcIdLogin(webClient, obj) + "temp_code_login" -> handleTempCodeLogin(webClient, obj) "listen_login_requests" -> handleListenLogins(webClient, obj) "unlisten_login_requests" -> handleUnlisten(webClient, obj) "session_hash_response" -> handleSessionResponse(webClient, obj) @@ -83,25 +79,22 @@ class WebLogin : WebState { webLogger.info("Token gen: {}: offline {} {}", webClient.id, username, uuid) } - private suspend fun handleMcIdLogin(webClient: WebClient, obj: JsonObject) { + private suspend fun handleTempCodeLogin(webClient: WebClient, obj: JsonObject) { val username = obj["username"].asString val code = obj["code"].asString - val check = AspirinServer.httpClient.submitForm( - "https://api.minecraft.id/gateway/verify/${URLEncoder.encode(username, Charsets.UTF_8)}", - formParameters = parametersOf("code", code), - ).body() + val cacheKey = username.lowercase() + val check = webClient.server.tempCodes.getIfPresent(cacheKey) - if (check["valid"].asBoolean) { - val mcIdUser = check["username"].asString - val uuid = check["uuid"]?.asString?.let { parseUndashedId(it.replace("-", "")) } - ?: webClient.server.usernameToIdCache[mcIdUser].await() - ?: throw StacklessException("Failed to get UUID from minecraft.id") + if (check != null && check.tempCode == code) { + webClient.server.tempCodes.invalidate(cacheKey) + val mcIdUser = check.username + val uuid = check.id val token = webClient.server.generateToken(uuid, mcIdUser) webClient.ws.sendSerialized(loginSuccessJson(mcIdUser, uuid, token)) - webLogger.info("Token gen: {}: {} {}", webClient.id, mcIdUser, uuid) + webLogger.info("Token gen: {}: temp code {} {}", webClient.id, mcIdUser, uuid) } else { webClient.ws.sendSerialized(loginNotSuccess()) webLogger.info("Token gen fail: {}: {}", webClient.id, username) diff --git a/src/main/kotlin/com/viaversion/aas/web/WebServer.kt b/src/main/kotlin/com/viaversion/aas/web/WebServer.kt index 9a6116b..fbfdcb2 100644 --- a/src/main/kotlin/com/viaversion/aas/web/WebServer.kt +++ b/src/main/kotlin/com/viaversion/aas/web/WebServer.kt @@ -75,6 +75,9 @@ class WebServer { val minecraftAccessTokens = CacheBuilder.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .build() + val tempCodes = CacheBuilder.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .build() // lowercase username fun generateToken(account: UUID, username: String): String { return JWT.create() diff --git a/src/main/resources/web/index.html b/src/main/resources/web/index.html index f9b5989..3b4cda1 100644 --- a/src/main/resources/web/index.html +++ b/src/main/resources/web/index.html @@ -97,9 +97,6 @@
    -