diff --git a/game-example/OAuth.cs b/game-example/OAuth.cs index 0840f08..721c4a8 100644 --- a/game-example/OAuth.cs +++ b/game-example/OAuth.cs @@ -18,7 +18,13 @@ public partial class OAuth : Control { public TcpServer RedirectServer = new(); public string RedirectUri = $"http://{Binding}:{Port}"; - public string ClientId = "client_XTcqz8gXODW6yDv-lf9KJg"; + public const string ClientId = "client_lvRAJmPuwePq5oEqoFR_Ww"; + //I have completely given up on using DPoP for this demo. + // THIS IS FOR DEMONSTRATION PURPOSES ONLY! DO NOT USE A CLIENT SECRET IN AN APP PLAYERS WILL DOWNLOAD! + //(this is bound to my localhost docker container so you can't use this secret in prod anyway) + private const string clientSecret = "8f03wNGkVL8oOqd1IUAZaYFUrZBQTIXoC2o8Wo6wXl8"; + + public bool Authorized = false; public string Token; private string refreshToken; @@ -34,6 +40,7 @@ public partial class OAuth : Control { // Called when the node enters the scene tree for the first time. public override void _Ready() { SetProcess(false); + //InitialAuth(); } // Called every frame. 'delta' is the elapsed time since the previous frame. @@ -44,17 +51,31 @@ public partial class OAuth : Control { if (!String.IsNullOrEmpty(request)) { SetProcess(false); //TODO: this seems sus, will need to check for quickslice - string authCode = request.Split("&scope")[0].Split("=")[1]; + GD.Print($"Request result: `{request}`"); + string authCode = request.Split(" HTTP/1.1")[0].Split("=")[1]; + GD.Print($"Parsed auth code: `{authCode}`"); GetTokenFromAuth(authCode); connection.PutData("HTTP/1.1 200\r\n".ToAsciiBuffer()); //TODO: response page here - connection.PutData("".ToAsciiBuffer()); + connection.PutData("Authentication complete!".ToAsciiBuffer()); RedirectServer.Stop(); } } } + public async void InitialAuth() { + LoadTokens(); + + if (!await IsTokenValid()) { + if (!await RefreshTokens()) { + Authorized = false; + return; + } + } + Authorized = true; + } + public async Task Authorize(string handle) { LoadTokens(); @@ -67,16 +88,16 @@ public partial class OAuth : Control { private void GetAuthCode(string handle) { SetProcess(true); - RedirectServer.Listen(Port, Binding); Error err = RedirectServer.Listen(Port, Binding); string[] bodyParts = [ $"client_id={ClientId}", + $"client_secret={clientSecret}", $"redirect_uri={RedirectUri}", $"response_type=code", //TODO: code challenge? $"login_hint={handle}", - $"scope=atproto transition:generic" + "scope=atproto transition:generic" ]; string url = $"{AuthUrl}?{bodyParts.Join("&")}"; @@ -92,6 +113,7 @@ public partial class OAuth : Control { string[] bodyParts = [ $"code={authCode}", $"client_id={ClientId}", + $"client_secret={clientSecret}", $"redirect_uri={RedirectUri}", "grant_type=authorization_code" ]; @@ -121,6 +143,7 @@ public partial class OAuth : Control { ]; string[] bodyParts = [ $"client_id={ClientId}", + $"client_secret={clientSecret}", $"refresh_token={refreshToken}", "grant_type=refresh_token" ]; @@ -145,6 +168,7 @@ public partial class OAuth : Control { return false; } + //TODO: Quickslice doesn't have a way to get token info! Need to refactor to check expiry + stored issue time directly private async Task IsTokenValid() { GD.Print("Checking if tokens are valid"); if (string.IsNullOrEmpty(Token)) { @@ -160,7 +184,7 @@ public partial class OAuth : Control { string body = $"access_token={Token}"; - Error err = Request.Request(TokenUrl+"info", headers, HttpClient.Method.Post, body); + Error err = Request.Request(TokenUrl, headers, HttpClient.Method.Post, body); if (err != Error.Ok) { GD.PushError($"HTTP error {err} occured while trying to check auth token validity");