package io.gitlab.jfronny.inceptum.launcher.api.account; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.Entitlements.GC_Entitlements; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.Profile.GC_Profile; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.request.LoginRequest.GC_LoginRequest; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.request.XblTokenRequest.GC_XblTokenRequest; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.request.XstsTokenRequest.GC_XstsTokenRequest; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.LoginResponse.GC_LoginResponse; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.OauthTokenResponse.GC_OauthTokenResponse; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.XboxLiveAuthResponse.GC_XboxLiveAuthResponse; import io.gitlab.jfronny.commons.HttpUtils; import io.gitlab.jfronny.inceptum.launcher.model.microsoft.*; import io.gitlab.jfronny.inceptum.launcher.model.microsoft.request.*; import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.*; import java.io.IOException; import java.io.Reader; import java.net.URISyntaxException; import java.util.*; public class MicrosoftAuthAPI { public static final String MICROSOFT_LOGIN_CLIENT_ID = "90890812-00d1-48a8-8d3f-38465ef43b58"; public static final int MICROSOFT_LOGIN_REDIRECT_PORT = 28562; public static final String MICROSOFT_LOGIN_REDIRECT_URL = "http://127.0.0.1:" + MICROSOFT_LOGIN_REDIRECT_PORT; public static final String MICROSOFT_LOGIN_REDIRECT_URL_ENCODED = "http%3A%2F%2F127.0.0.1%3A" + MICROSOFT_LOGIN_REDIRECT_PORT; public static final String[] MICROSOFT_LOGIN_SCOPES = {"XboxLive.signin", "XboxLive.offline_access"}; // General Microsoft login constants public static final String MICROSOFT_LOGIN_URL = "https://login.live.com/oauth20_authorize.srf" + "?client_id=" + MICROSOFT_LOGIN_CLIENT_ID + "&prompt=select_account&cobrandid=8058f65d-ce06-4c30-9559-473c9275a65d&response_type=code" + "&scope=" + String.join("%20", MICROSOFT_LOGIN_SCOPES) + "&redirect_uri=" + MICROSOFT_LOGIN_REDIRECT_URL_ENCODED; public static final String MICROSOFT_AUTH_TOKEN_URL = "https://login.live.com/oauth20_token.srf"; public static final String MICROSOFT_XBL_AUTH_TOKEN_URL = "https://user.auth.xboxlive.com/user/authenticate"; public static final String MICROSOFT_XSTS_AUTH_TOKEN_URL = "https://xsts.auth.xboxlive.com/xsts/authorize"; public static final String MICROSOFT_MINECRAFT_LOGIN_URL = "https://api.minecraftservices.com/launcher/login"; public static final String MICROSOFT_MINECRAFT_PROFILE_URL = "https://api.minecraftservices.com/minecraft/profile"; public static final String MICROSOFT_MINECRAFT_ENTITLEMENTS_URL = "https://api.minecraftservices.com/entitlements/license?requestId="; public static OauthTokenResponse tradeCodeForAccessToken(String code) throws IOException, URISyntaxException { try (Reader r = HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL) .bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID, "code", code, "grant_type", "authorization_code", "redirect_uri", MICROSOFT_LOGIN_REDIRECT_URL, "scope", String.join(" ", MICROSOFT_LOGIN_SCOPES))) .sendReader()) { return GC_OauthTokenResponse.read(r); } } public static OauthTokenResponse refreshAccessToken(String refreshToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL) .bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID, "refresh_token", refreshToken, "grant_type", "refresh_token", "redirect_uri", MICROSOFT_LOGIN_REDIRECT_URL)) .sendReader()) { return GC_OauthTokenResponse.read(r); } } public static XboxLiveAuthResponse getXBLToken(String accessToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.post(MICROSOFT_XBL_AUTH_TOKEN_URL) .header("x-xbl-contract-version", "1") .bodyJson(GC_XblTokenRequest.toJson(new XblTokenRequest( new XblTokenRequest.Properties( "RPS", "user.auth.xboxlive.com", "d=" + accessToken ), "http://auth.xboxlive.com", "JWT" ))) .sendReader()) { return GC_XboxLiveAuthResponse.read(r); } } public static XboxLiveAuthResponse getXstsToken(String xblToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.post(MICROSOFT_XSTS_AUTH_TOKEN_URL) .header("x-xbl-contract-version", "1") .bodyJson(GC_XstsTokenRequest.toJson(new XstsTokenRequest( new XstsTokenRequest.Properties( "RETAIL", List.of(xblToken) ), "rp://api.minecraftservices.com/", "JWT" ))) .sendReader()) { return GC_XboxLiveAuthResponse.read(r); } } public static LoginResponse loginToMinecraft(String xstsToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.post(MICROSOFT_MINECRAFT_LOGIN_URL) .bodyJson(GC_LoginRequest.toJson(new LoginRequest( xstsToken, "PC_LAUNCHER" ))) .sendReader()) { return GC_LoginResponse.read(r); } } public static Entitlements getEntitlements(String accessToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.get(MICROSOFT_MINECRAFT_ENTITLEMENTS_URL + UUID.randomUUID()).bearer(accessToken).sendReader()) { return GC_Entitlements.read(r); } } public static Profile getMcProfile(String accessToken) throws IOException, URISyntaxException { try (Reader r = HttpUtils.get(MICROSOFT_MINECRAFT_PROFILE_URL).bearer(accessToken).sendReader()) { return GC_Profile.read(r); } } }