From 496d502cd2ab143d428cbc937c7b9d1d576a9207 Mon Sep 17 00:00:00 2001 From: glax Date: Sat, 3 Jun 2023 21:26:29 +0200 Subject: [PATCH] Kavita Auth is a pain. --- Tranga-API/Program.cs | 4 +-- Tranga-CLI/Tranga_Cli.cs | 44 +++++++++++++++++++++--------- Tranga/LibraryManager.cs | 20 +++++++------- Tranga/LibraryManagers/Kavita.cs | 46 ++++++++++++++++++++++++++------ Tranga/LibraryManagers/Komga.cs | 4 +-- Tranga/TaskManager.cs | 6 ++--- Website/apiConnector.js | 13 +++++++-- Website/index.html | 3 ++- Website/interaction.js | 17 +++++++----- 9 files changed, 109 insertions(+), 48 deletions(-) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index 1b6b8bd..5d42e70 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -210,7 +210,7 @@ app.MapDelete("/Queue/Dequeue", (string taskType, string? connectorName, string? app.MapGet("/Settings/Get", () => taskManager.settings); app.MapPost("/Settings/Update", - (string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaApiKey) => - taskManager.UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaApiKey)); + (string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaUsername, string? kavitaPassword) => + taskManager.UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaUsername, kavitaPassword)); app.Run(); \ No newline at end of file diff --git a/Tranga-CLI/Tranga_Cli.cs b/Tranga-CLI/Tranga_Cli.cs index 106a59c..060ec06 100644 --- a/Tranga-CLI/Tranga_Cli.cs +++ b/Tranga-CLI/Tranga_Cli.cs @@ -47,32 +47,32 @@ public static class Tranga_Cli if (tmpUrlKomga.Length > 0) { Console.WriteLine("Username:"); - string? tmpUser = Console.ReadLine(); - while (tmpUser is null || tmpUser.Length < 1) - tmpUser = Console.ReadLine(); + string? tmpKomgaUser = Console.ReadLine(); + while (tmpKomgaUser is null || tmpKomgaUser.Length < 1) + tmpKomgaUser = Console.ReadLine(); Console.WriteLine("Password:"); - string tmpPass = string.Empty; + string tmpKomgaPass = string.Empty; ConsoleKey key; do { var keyInfo = Console.ReadKey(intercept: true); key = keyInfo.Key; - if (key == ConsoleKey.Backspace && tmpPass.Length > 0) + if (key == ConsoleKey.Backspace && tmpKomgaPass.Length > 0) { Console.Write("\b \b"); - tmpPass = tmpPass[0..^1]; + tmpKomgaPass = tmpKomgaPass[0..^1]; } else if (!char.IsControl(keyInfo.KeyChar)) { Console.Write("*"); - tmpPass += keyInfo.KeyChar; + tmpKomgaPass += keyInfo.KeyChar; } } while (key != ConsoleKey.Enter); settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Komga)); - settings.libraryManagers.Add(new Komga(tmpUrlKomga, tmpUser, tmpPass, logger)); + settings.libraryManagers.Add(new Komga(tmpUrlKomga, tmpKomgaUser, tmpKomgaPass, logger)); } Console.WriteLine($"Kavita BaseURL [{settings.libraryManagers.FirstOrDefault(lm => lm.GetType() == typeof(Kavita))?.baseUrl}]:"); @@ -82,12 +82,32 @@ public static class Tranga_Cli if (tmpUrlKavita.Length > 0) { Console.WriteLine("Username:"); - string? tmpApiKey = Console.ReadLine(); - while (tmpApiKey is null || tmpApiKey.Length < 1) - tmpApiKey = Console.ReadLine(); + string? tmpKavitaUser = Console.ReadLine(); + while (tmpKavitaUser is null || tmpKavitaUser.Length < 1) + tmpKavitaUser = Console.ReadLine(); + + Console.WriteLine("Password:"); + string tmpKavitaPass = string.Empty; + ConsoleKey key; + do + { + var keyInfo = Console.ReadKey(intercept: true); + key = keyInfo.Key; + + if (key == ConsoleKey.Backspace && tmpKavitaPass.Length > 0) + { + Console.Write("\b \b"); + tmpKavitaPass = tmpKavitaPass[0..^1]; + } + else if (!char.IsControl(keyInfo.KeyChar)) + { + Console.Write("*"); + tmpKavitaPass += keyInfo.KeyChar; + } + } while (key != ConsoleKey.Enter); settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Kavita)); - settings.libraryManagers.Add(new Kavita(tmpUrlKavita, tmpApiKey, logger)); + settings.libraryManagers.Add(new Kavita(tmpUrlKavita, tmpKavitaUser, tmpKavitaPass, logger)); } logger.WriteLine("Tranga_CLI", "Loaded."); diff --git a/Tranga/LibraryManager.cs b/Tranga/LibraryManager.cs index f8eb76b..bd08baa 100644 --- a/Tranga/LibraryManager.cs +++ b/Tranga/LibraryManager.cs @@ -17,7 +17,7 @@ public abstract class LibraryManager public LibraryType libraryType { get; } public string baseUrl { get; } - protected string auth { get; } //Base64 encoded, if you use your password everywhere, you have problems + public string auth { get; } //Base64 encoded, if you use your password everywhere, you have problems protected Logger? logger; /// Base-URL of Komga instance, no trailing slashes(/) @@ -39,11 +39,10 @@ public abstract class LibraryManager protected static class NetClient { - public static Stream MakeRequest(string url, string auth, Logger? logger) + public static Stream MakeRequest(string url, string authScheme, string auth, Logger? logger) { - HttpClientHandler clientHandler = new (); - HttpClient client = new(clientHandler); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); + HttpClient client = new(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authScheme, auth); HttpRequestMessage requestMessage = new () { @@ -55,22 +54,21 @@ public abstract class LibraryManager logger?.WriteLine("LibraryManager", $"{(int)response.StatusCode} {response.StatusCode}: {response.ReasonPhrase}"); if(response.StatusCode is HttpStatusCode.Unauthorized && response.RequestMessage!.RequestUri!.AbsoluteUri != url) - return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, auth, logger); + return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger); else if (response.IsSuccessStatusCode) return response.Content.ReadAsStream(); else return Stream.Null; } - public static bool MakePost(string url, string auth, Logger? logger) + public static bool MakePost(string url, string authScheme, string auth, Logger? logger) { - HttpClientHandler clientHandler = new (); - HttpClient client = new(clientHandler) + HttpClient client = new() { DefaultRequestHeaders = { { "Accept", "application/json" }, - { "Authorization", new AuthenticationHeaderValue("Basic", auth).ToString() } + { "Authorization", new AuthenticationHeaderValue(authScheme, auth).ToString() } } }; HttpRequestMessage requestMessage = new () @@ -83,7 +81,7 @@ public abstract class LibraryManager logger?.WriteLine("LibraryManager", $"{(int)response.StatusCode} {response.StatusCode}: {response.ReasonPhrase}"); if(response.StatusCode is HttpStatusCode.Unauthorized && response.RequestMessage!.RequestUri!.AbsoluteUri != url) - return MakePost(response.RequestMessage!.RequestUri!.AbsoluteUri, auth, logger); + return MakePost(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger); else if (response.IsSuccessStatusCode) return true; else diff --git a/Tranga/LibraryManagers/Kavita.cs b/Tranga/LibraryManagers/Kavita.cs index c266e9e..9abc66d 100644 --- a/Tranga/LibraryManagers/Kavita.cs +++ b/Tranga/LibraryManagers/Kavita.cs @@ -1,20 +1,50 @@ -using System.Text.Json; -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; using Logging; +using Newtonsoft.Json; +using JsonSerializer = System.Text.Json.JsonSerializer; namespace Tranga.LibraryManagers; public class Kavita : LibraryManager { - public Kavita(string baseUrl, string apiKey, Logger? logger) : base(baseUrl, apiKey, logger, LibraryType.Kavita) + + public Kavita(string baseUrl, string username, string password, Logger? logger) : base(baseUrl, GetToken(baseUrl, username, password), logger, LibraryType.Kavita) { } + + [JsonConstructor] + public Kavita(string baseUrl, string auth, Logger? logger) : base(baseUrl, auth, logger, LibraryType.Kavita) + { + } + + private static string GetToken(string baseUrl, string username, string password) + { + HttpClient client = new() + { + DefaultRequestHeaders = + { + { "Accept", "application/json" } + } + }; + HttpRequestMessage requestMessage = new () + { + Method = HttpMethod.Post, + RequestUri = new Uri($"{baseUrl}/api/Account/login"), + Content = new StringContent($"{{\"username\":\"{username}\",\"password\":\"{password}\"}}", System.Text.Encoding.UTF8, "application/json") + }; + + HttpResponseMessage response = client.Send(requestMessage); + JsonObject? result = JsonSerializer.Deserialize(response.Content.ReadAsStream()); + if (result is not null) + return result!["token"]!.GetValue(); + else return ""; + } public override void UpdateLibrary() { logger?.WriteLine(this.GetType().ToString(), $"Updating Libraries"); foreach (KavitaLibrary lib in GetLibraries()) - NetClient.MakePost($"{baseUrl}/api/Library/scan?libraryId={lib.id}", auth, logger); + NetClient.MakePost($"{baseUrl}/api/Library/scan?libraryId={lib.id}", "Bearer", auth, logger); } /// @@ -24,7 +54,7 @@ public class Kavita : LibraryManager private IEnumerable GetLibraries() { logger?.WriteLine(this.GetType().ToString(), $"Getting Libraries"); - Stream data = NetClient.MakeRequest($"{baseUrl}/api/Library", auth, logger); + Stream data = NetClient.MakeRequest($"{baseUrl}/api/Library", "Bearer", auth, logger); if (data == Stream.Null) { logger?.WriteLine(this.GetType().ToString(), $"No libraries returned"); @@ -42,7 +72,7 @@ public class Kavita : LibraryManager foreach (JsonNode? jsonNode in result) { var jObject = (JsonObject?)jsonNode; - string libraryId = jObject!["id"]!.GetValue(); + int libraryId = jObject!["id"]!.GetValue(); string libraryName = jObject!["name"]!.GetValue(); ret.Add(new KavitaLibrary(libraryId, libraryName)); } @@ -52,10 +82,10 @@ public class Kavita : LibraryManager private struct KavitaLibrary { - public string id { get; } + public int id { get; } public string name { get; } - public KavitaLibrary(string id, string name) + public KavitaLibrary(int id, string name) { this.id = id; this.name = name; diff --git a/Tranga/LibraryManagers/Komga.cs b/Tranga/LibraryManagers/Komga.cs index 39586c1..bacc2c6 100644 --- a/Tranga/LibraryManagers/Komga.cs +++ b/Tranga/LibraryManagers/Komga.cs @@ -25,7 +25,7 @@ public class Komga : LibraryManager { logger?.WriteLine(this.GetType().ToString(), $"Updating Libraries"); foreach (KomgaLibrary lib in GetLibraries()) - NetClient.MakePost($"{baseUrl}/api/v1/libraries/{lib.id}/scan", auth, logger); + NetClient.MakePost($"{baseUrl}/api/v1/libraries/{lib.id}/scan", "Basic", auth, logger); } /// @@ -35,7 +35,7 @@ public class Komga : LibraryManager private IEnumerable GetLibraries() { logger?.WriteLine(this.GetType().ToString(), $"Getting Libraries"); - Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", auth, logger); + Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", "Basic", auth, logger); if (data == Stream.Null) { logger?.WriteLine(this.GetType().ToString(), $"No libraries returned"); diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index 4fa189c..39df502 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -47,17 +47,17 @@ public class TaskManager taskChecker.Start(); } - public void UpdateSettings(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaApiKey) + public void UpdateSettings(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaUsername, string? kavitaPassword) { if (komgaUrl is not null && komgaAuth is not null && komgaUrl.Length > 0 && komgaAuth.Length > 0) { settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Komga)); settings.libraryManagers.Add(new Komga(komgaUrl, komgaAuth, logger)); } - if (kavitaUrl is not null && kavitaApiKey is not null && kavitaUrl.Length > 0 && kavitaApiKey.Length > 0) + if (kavitaUrl is not null && kavitaUsername is not null && kavitaPassword is not null && kavitaUrl.Length > 0 && kavitaUsername.Length > 0 && kavitaPassword.Length > 0) { settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Kavita)); - settings.libraryManagers.Add(new Kavita(kavitaUrl, kavitaApiKey, logger)); + settings.libraryManagers.Add(new Kavita(kavitaUrl, kavitaUsername, kavitaPassword, logger)); } if (downloadLocation is not null && downloadLocation.Length > 0) settings.downloadLocation = downloadLocation; diff --git a/Website/apiConnector.js b/Website/apiConnector.js index f7640a6..f79700f 100644 --- a/Website/apiConnector.js +++ b/Website/apiConnector.js @@ -104,8 +104,17 @@ function EnqueueTask(taskType, connectorName, publicationId){ PostData(uri); } -function UpdateSettings(downloadLocation, komgaUrl, komgaAuth){ - var uri = apiUri + `/Settings/Update?downloadLocation=${downloadLocation}&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`; +function UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaUser, kavitaPass){ + var uri = apiUri + "/Settings/Update?" + if(downloadLocation != ""){ + uri += "&downloadLocation="+downloadLocation; + } + if(komgaUrl != "" && komgaAuth != ""){ + uri += `&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`; + } + if(kavitaUrl != "" && kavitaUser != "" && kavitaPass != ""){ + uri += `&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUser}&kavitaPassword=${kavitaPass}`; + } PostData(uri); } diff --git a/Website/index.html b/Website/index.html index 95eb751..1d6ad85 100644 --- a/Website/index.html +++ b/Website/index.html @@ -99,7 +99,8 @@ Kavita
Configured: ✅❌
- + +
diff --git a/Website/interaction.js b/Website/interaction.js index 8662f01..66eaafc 100644 --- a/Website/interaction.js +++ b/Website/interaction.js @@ -27,7 +27,8 @@ const settingKomgaUrl = document.querySelector("#komgaUrl"); const settingKomgaUser = document.querySelector("#komgaUsername"); const settingKomgaPass = document.querySelector("#komgaPassword"); const settingKavitaUrl = document.querySelector("#kavitaUrl"); -const settingKavitaApi = document.querySelector("#kavitaApiKey"); +const settingKavitaUser = document.querySelector("#kavitaUsername"); +const settingKavitaPass = document.querySelector("#kavitaPassword"); const libraryUpdateTime = document.querySelector("#libraryUpdateTime"); const settingKomgaConfigured = document.querySelector("#komgaConfigured"); const settingKavitaConfigured = document.querySelector("#kavitaConfigured"); @@ -243,7 +244,8 @@ function GetSettingsClick(){ settingKomgaUser.value = ""; settingKomgaPass.value = ""; settingKavitaUrl.value = ""; - settingKavitaApi.value = ""; + settingKavitaUser.value = ""; + settingKavitaPass.value = ""; settingKomgaConfigured.innerText = "❌"; settingKavitaConfigured.innerText = "❌"; @@ -254,12 +256,13 @@ function GetSettingsClick(){ json.libraryManagers.forEach(lm => { if(lm.libraryType == 0){ settingKomgaUrl.placeholder = lm.baseUrl; - settingKomgaUser.placeholder = "Configured"; + settingKomgaUser.placeholder = "User"; settingKomgaPass.placeholder = "***"; settingKomgaConfigured.innerText = "✅"; - } else if(libraryType == 1){ + } else if(lm.libraryType == 1){ settingKavitaUrl.placeholder = lm.baseUrl; - settingKavitaApi.placeholder = "***"; + settingKavitaUser.placeholder = "User"; + settingKavitaPass.placeholder = "***"; settingKavitaConfigured.innerText = "✅"; } }); @@ -282,8 +285,8 @@ function UpdateLibrarySettings(){ UpdateSettings("", settingKomgaUrl.placeholder, auth, "", ""); } - if(settingKavitaUrl.value != "" && settingKavitaApi != ""){ - UpdateSettings("", "", "", settingKavitaUrl.value, settingKavitaApi.value); + if(settingKavitaUrl.value != "" && settingKavitaUser.value != "" && settingKavitaPass.value != ""){ + UpdateSettings("", "", "", settingKavitaUrl.value, settingKavitaUser.value, settingKavitaPass.value); } CreateTask("UpdateLibraries", libraryUpdateTime.value, "","",""); setTimeout(() => GetSettingsClick(), 100);