diff --git a/Tests/Helpers/TestSetup.cs b/Tests/Helpers/TestSetup.cs index 5bbf1e0..5fab7a2 100644 --- a/Tests/Helpers/TestSetup.cs +++ b/Tests/Helpers/TestSetup.cs @@ -23,23 +23,23 @@ namespace VRCAuthProxy.Tests.Helpers /// public static Config CreateTestConfig() { - var config = new Config(); - config.Accounts = new List + return new Config { - new ConfigAccount + Accounts = new List { - username = "testuser1", - password = "testpassword1", - totpSecret = "TESTSECRET1" - }, - new ConfigAccount - { - username = "testuser2", - password = "testpassword2" + new ConfigAccount + { + username = "testuser1", + password = "testpassword1", + totpSecret = "TESTSECRET1" + }, + new ConfigAccount + { + username = "testuser2", + password = "testpassword2" + } } }; - - return config; } } } \ No newline at end of file diff --git a/Tests/Integration/ProxyIntegrationTests.cs b/Tests/Integration/ProxyIntegrationTests.cs index 257e686..7b7a487 100644 --- a/Tests/Integration/ProxyIntegrationTests.cs +++ b/Tests/Integration/ProxyIntegrationTests.cs @@ -52,11 +52,17 @@ namespace VRCAuthProxy.Tests.Integration .WithHeader("Content-Type", "application/json") .WithBody(@"[{""id"":""usr_test1"",""displayName"":""TestUser1""},{""id"":""usr_test2"",""displayName"":""TestUser2""}]")); - // Create a client - var httpClient = new HttpClient(); + // Create a client with the test setup + var handler = new HttpClientHandler { UseCookies = true }; + var mockServerUrls = mockServer.Urls; + if (mockServerUrls == null || !mockServerUrls.Any()) + { + throw new InvalidOperationException("Mock server URLs not available"); + } + var baseUri = mockServerUrls.First(); // Call the users endpoint directly - var baseUri = mockServer.Urls.First(); + var httpClient = new HttpClient(handler); var response = await httpClient.GetAsync($"{baseUri}/api/1/users"); // Assert @@ -90,11 +96,17 @@ namespace VRCAuthProxy.Tests.Integration .WithHeader("Content-Type", "application/json") .WithBody(@"[{""id"":""wrld_test1"",""name"":""TestWorld1""},{""id"":""wrld_test2"",""name"":""TestWorld2""}]")); - // Create a client - var httpClient = new HttpClient(); + // Create a client with the test setup + var handler = new HttpClientHandler { UseCookies = true }; + var mockServerUrls = mockServer.Urls; + if (mockServerUrls == null || !mockServerUrls.Any()) + { + throw new InvalidOperationException("Mock server URLs not available"); + } + var baseUri = mockServerUrls.First(); // First authenticate - var baseUri = mockServer.Urls.First(); + var httpClient = new HttpClient(handler); await httpClient.GetAsync($"{baseUri}/api/1/auth/user"); // Then call the worlds endpoint diff --git a/Tests/Integration/VRChatAuthenticationTests.cs b/Tests/Integration/VRChatAuthenticationTests.cs index 9b21096..3e65caf 100644 --- a/Tests/Integration/VRChatAuthenticationTests.cs +++ b/Tests/Integration/VRChatAuthenticationTests.cs @@ -38,9 +38,14 @@ namespace VRCAuthProxy.Tests.Integration // Create a client with the test setup var handler = new HttpClientHandler { UseCookies = true }; + var mockServerUrls = mockServer.Urls; + if (mockServerUrls == null || !mockServerUrls.Any()) + { + throw new InvalidOperationException("Mock server URLs not available"); + } var httpClient = new HttpClient(handler) { - BaseAddress = new Uri(mockServer.Urls.First()) + BaseAddress = new Uri(mockServerUrls.First()) }; // Act @@ -82,7 +87,7 @@ namespace VRCAuthProxy.Tests.Integration mockServer.Given(Request.Create() .WithPath("/api/1/auth/twofactorauth/totp/verify") .UsingPost() - .WithBody(x => x.Contains("code"))) + .WithBody(x => x != null && x.Contains("code"))) .RespondWith(Response.Create() .WithStatusCode(200) .WithHeader("Content-Type", "application/json") @@ -101,9 +106,14 @@ namespace VRCAuthProxy.Tests.Integration // Create a client with the test setup var handler = new HttpClientHandler { UseCookies = true }; + var mockServerUrls = mockServer.Urls; + if (mockServerUrls == null || !mockServerUrls.Any()) + { + throw new InvalidOperationException("Mock server URLs not available"); + } var httpClient = new HttpClient(handler) { - BaseAddress = new Uri(mockServer.Urls.First()) + BaseAddress = new Uri(mockServerUrls.First()) }; // Act - First authenticate which will indicate TOTP is required diff --git a/VRCAuthProxy/Config.cs b/VRCAuthProxy/Config.cs index d68abee..c7df150 100644 --- a/VRCAuthProxy/Config.cs +++ b/VRCAuthProxy/Config.cs @@ -4,21 +4,26 @@ namespace VRCAuthProxy; public class ConfigAccount { - public string username { get; set; } - public string password { get; set; } + public required string username { get; set; } + public required string password { get; set; } public string? totpSecret { get; set; } } public class iConfig { - public List accounts { get; set; } + public required List accounts { get; set; } } // Load config from appsettings.json public class Config { private static Config? _instance; - public List Accounts { get; set; } + public required List Accounts { get; set; } + + public Config() + { + Accounts = new List(); + } public static Config Instance { @@ -31,8 +36,12 @@ public class Config public static Config Load() { - var config = new Config(); var configPath = Path.Combine(AppContext.BaseDirectory, "appsettings.json"); + var config = new Config + { + Accounts = new List() + }; + if (File.Exists(configPath)) { var json = File.ReadAllText(configPath); diff --git a/VRCAuthProxy/Program.cs b/VRCAuthProxy/Program.cs index 733026f..0e5af6e 100644 --- a/VRCAuthProxy/Program.cs +++ b/VRCAuthProxy/Program.cs @@ -155,7 +155,7 @@ app.Use(async (context, next) => var result = await source.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) { - await target.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); + await target.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, result.CloseStatusDescription, CancellationToken.None); break; } await target.SendAsync(new ArraySegment(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);