diff --git a/src/main/java/com/alttd/webinterface/config/Config.java b/src/main/java/com/alttd/webinterface/config/Config.java index f6faf29..89f7e2e 100644 --- a/src/main/java/com/alttd/webinterface/config/Config.java +++ b/src/main/java/com/alttd/webinterface/config/Config.java @@ -199,7 +199,7 @@ public final class Config { YOUR_LOGIN_CODE = getString("messages.your-login-code", YOUR_LOGIN_CODE); } - public static String LOGIN_CODE_ENDPOINT = "https://alttd.com/auth/get_login_code/"; + public static String LOGIN_CODE_ENDPOINT = "https://alttd.com/login/requestNewUserLogin/"; public static String LOGIN_ENDPOINT = "https://alttd.com/login"; public static String SECRET = ""; private static void site() { @@ -207,7 +207,6 @@ public final class Config { byte[] randomBytes = new byte[256]; new java.security.SecureRandom().nextBytes(randomBytes); SECRET = java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes); - config.getNode("secret").setValue(SECRET); } SECRET = getString("secret", SECRET); LOGIN_ENDPOINT = getString("login-endpoint", LOGIN_ENDPOINT); diff --git a/src/main/java/com/alttd/webinterface/listeners/ProxyPlayerListener.java b/src/main/java/com/alttd/webinterface/listeners/ProxyPlayerListener.java index 79ee5a8..4fff69f 100644 --- a/src/main/java/com/alttd/webinterface/listeners/ProxyPlayerListener.java +++ b/src/main/java/com/alttd/webinterface/listeners/ProxyPlayerListener.java @@ -2,6 +2,7 @@ package com.alttd.webinterface.listeners; import com.alttd.webinterface.config.Config; import com.alttd.webinterface.web_interact.AuthService; +import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.ResultedEvent; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.LoginEvent; @@ -9,6 +10,7 @@ import com.velocitypowered.api.proxy.Player; import litebans.api.Database; import litebans.api.Entry; import lombok.extern.slf4j.Slf4j; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -26,7 +28,7 @@ public class ProxyPlayerListener { public ProxyPlayerListener() { } - @Subscribe + @Subscribe(order = PostOrder.FIRST) public void playerLogin(@NotNull LoginEvent event) { final Player player = event.getPlayer(); final UUID uuid = player.getUniqueId(); @@ -43,18 +45,17 @@ public class ProxyPlayerListener { String displayMessage = ban.isPermanent() ? Config.PERM_BAN : Config.TEMP_BAN; try { - miniMessage.deserialize(displayMessage, TagResolver.resolver( + Component displayComponent = miniMessage.deserialize(displayMessage, TagResolver.resolver( Placeholder.component("base", miniMessage.deserialize(Config.BASE_MESSAGE, resolveBase(ban))), Placeholder.component("appeal_message", miniMessage.deserialize(Config.APPEAL_MESSAGE, resolveAppealMessage(uuid))), Placeholder.unparsed("duration", Instant.ofEpochMilli(ban.getDateEnd()).toString()))); + event.setResult(ResultedEvent.ComponentResult.denied(displayComponent)); } catch (IllegalStateException e) { log.error("Failed to deserialize ban message", e); event.setResult(ResultedEvent.ComponentResult.denied(miniMessage.deserialize( "Unable to display punishment and appeal code, please contact us via email at appeal@alttd.com"))); - return; } - event.setResult(ResultedEvent.ComponentResult.denied(miniMessage.deserialize(ban.getReason()))); } private static @NotNull TagResolver resolveAppealMessage(UUID uuid) { diff --git a/src/main/java/com/alttd/webinterface/web_interact/AuthService.java b/src/main/java/com/alttd/webinterface/web_interact/AuthService.java index 5d95751..75c9ac2 100644 --- a/src/main/java/com/alttd/webinterface/web_interact/AuthService.java +++ b/src/main/java/com/alttd/webinterface/web_interact/AuthService.java @@ -4,6 +4,7 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.time.Instant; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -12,8 +13,13 @@ import com.alttd.webinterface.config.Config; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + @Slf4j public class AuthService { + private static final Map cache = new ConcurrentHashMap<>(); /** * Asynchronously sends a GET request to the login endpoint with the required authorization header. @@ -23,31 +29,57 @@ public class AuthService { * or an empty Optional otherwise */ public static @NotNull CompletableFuture> getLoginCodeAsync(UUID uuid) { - String loginUrl = Config.LOGIN_CODE_ENDPOINT.replaceAll("", uuid.toString()); - - try (HttpClient client = HttpClient.newHttpClient()) { - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(loginUrl)) - .header("Authorization", "SECRET " + Config.SECRET) - .GET() - .build(); - - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(response -> { - if (response.statusCode() == 200) { - String body = response.body(); - return Optional.ofNullable(body); - } else { - log.error("Failed to get login code. Status code: {}", response.statusCode()); - return Optional.empty(); - } - }) - .exceptionally(e -> { - log.error("Exception occurred while getting login code", e); - return Optional.empty(); - }); + Optional cachedCode = getCachedCode(uuid); + if (cachedCode.isPresent()) { + return CompletableFuture.completedFuture(cachedCode); } + String loginUrl = Config.LOGIN_CODE_ENDPOINT.replaceAll("", uuid.toString()); + log.info("Contacting server for login code at {}", loginUrl); + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(loginUrl)) + .header("Authorization", "SECRET " + Config.SECRET) + .GET() + .build(); + log.info("Created request"); + + return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> { + log.info("received response"); + if (response.statusCode() == 200) { + String body = response.body(); + cache.put(uuid, new CacheEntry(body, Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(10)))); + client.close(); + return Optional.ofNullable(body); + } else { + log.error("Failed to get login code. Status code: {}", response.statusCode()); + client.close(); + return Optional.empty(); + } + }) + .exceptionally(e -> { + log.error("Exception occurred while getting login code", e); + client.close(); + return Optional.empty(); + }); } + + private static Optional getCachedCode(UUID uuid) { + CacheEntry cachedEntry = cache.get(uuid); + if (cachedEntry != null) { + if (cachedEntry.expiry.isAfter(Instant.now())) { + return Optional.of(cachedEntry.code); + } + + if (cachedEntry.expiry.isBefore(Instant.now())) { + cache.remove(uuid); + } + } + return Optional.empty(); + } + + private record CacheEntry(String code, Instant expiry) { } }