From b37fd60b859b771f5dd5415157e133457b045d75 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 8 May 2023 06:56:26 +0300 Subject: [PATCH] API key improvements Fixed: Special characters in API key New: Add heathcheck for API Key (cherry picked from commit 9325140b90f8ac625ae5b26075748c22f6f06158) Closes #2466 --- .../Calendar/iCal/CalendarLinkModalContent.js | 2 +- frontend/src/Components/SignalRConnector.js | 4 +-- .../Checks/ApiKeyValidationCheck.cs | 35 +++++++++++++++++++ src/NzbDrone.Core/Localization/Core/en.json | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/NzbDrone.Core/HealthCheck/Checks/ApiKeyValidationCheck.cs diff --git a/frontend/src/Calendar/iCal/CalendarLinkModalContent.js b/frontend/src/Calendar/iCal/CalendarLinkModalContent.js index d905f2ee0..df5f6c6b6 100644 --- a/frontend/src/Calendar/iCal/CalendarLinkModalContent.js +++ b/frontend/src/Calendar/iCal/CalendarLinkModalContent.js @@ -33,7 +33,7 @@ function getUrls(state) { icalUrl += `tags=${tags.toString()}&`; } - icalUrl += `pastDays=${pastDays}&futureDays=${futureDays}&apikey=${window.Readarr.apiKey}`; + icalUrl += `pastDays=${pastDays}&futureDays=${futureDays}&apikey=${encodeURIComponent(window.Readarr.apiKey)}`; const iCalHttpUrl = `${window.location.protocol}//${icalUrl}`; const iCalWebCalUrl = `webcal://${icalUrl}`; diff --git a/frontend/src/Components/SignalRConnector.js b/frontend/src/Components/SignalRConnector.js index c52bbd2fd..da7b49e93 100644 --- a/frontend/src/Components/SignalRConnector.js +++ b/frontend/src/Components/SignalRConnector.js @@ -62,7 +62,7 @@ function Logger(minimumLogLevel) { } Logger.prototype.cleanse = function(message) { - const apikey = new RegExp(`access_token=${window.Readarr.apiKey}`, 'g'); + const apikey = new RegExp(`access_token=${encodeURIComponent(window.Readarr.apiKey)}`, 'g'); return message.replace(apikey, 'access_token=(removed)'); }; @@ -106,7 +106,7 @@ class SignalRConnector extends Component { this.connection = new signalR.HubConnectionBuilder() .configureLogging(new Logger(signalR.LogLevel.Information)) - .withUrl(`${url}?access_token=${window.Readarr.apiKey}`) + .withUrl(`${url}?access_token=${encodeURIComponent(window.Readarr.apiKey)}`) .withAutomaticReconnect({ nextRetryDelayInMilliseconds: (retryContext) => { if (retryContext.elapsedMilliseconds > 180000) { diff --git a/src/NzbDrone.Core/HealthCheck/Checks/ApiKeyValidationCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/ApiKeyValidationCheck.cs new file mode 100644 index 000000000..77e76d2a3 --- /dev/null +++ b/src/NzbDrone.Core/HealthCheck/Checks/ApiKeyValidationCheck.cs @@ -0,0 +1,35 @@ +using NLog; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.Configuration.Events; +using NzbDrone.Core.Lifecycle; +using NzbDrone.Core.Localization; + +namespace NzbDrone.Core.HealthCheck.Checks +{ + [CheckOn(typeof(ApplicationStartedEvent))] + [CheckOn(typeof(ConfigSavedEvent))] + public class ApiKeyValidationCheck : HealthCheckBase + { + private readonly IConfigFileProvider _configFileProvider; + private readonly Logger _logger; + + public ApiKeyValidationCheck(IConfigFileProvider configFileProvider, ILocalizationService localizationService, Logger logger) + : base(localizationService) + { + _configFileProvider = configFileProvider; + _logger = logger; + } + + public override HealthCheck Check() + { + if (_configFileProvider.ApiKey.Length < 20) + { + _logger.Warn("Please update your API key to be at least 20 characters long. You can do this via settings or the config file"); + + return new HealthCheck(GetType(), HealthCheckResult.Warning, _localizationService.GetLocalizedString("ApiKeyValidationHealthCheckMessage"), "#invalid-api-key"); + } + + return new HealthCheck(GetType()); + } + } +} diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index c2bea533e..4c75d95bd 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -33,6 +33,7 @@ "AnalyticsEnabledHelpTextWarning": "Requires restart to take effect", "AnyEditionOkHelpText": "Readarr will automatically switch to the edition best matching downloaded files", "ApiKeyHelpTextWarning": "Requires restart to take effect", + "ApiKeyValidationHealthCheckMessage": "Please update your API key to be at least 20 characters long. You can do this via settings or the config file", "AppDataDirectory": "AppData directory", "AppDataLocationHealthCheckMessage": "Updating will not be possible to prevent deleting AppData on Update", "ApplicationURL": "Application URL",