diff --git a/frontend/src/Calendar/iCal/CalendarLinkModalContent.js b/frontend/src/Calendar/iCal/CalendarLinkModalContent.js index 3f85a3673..21ccfaeab 100644 --- a/frontend/src/Calendar/iCal/CalendarLinkModalContent.js +++ b/frontend/src/Calendar/iCal/CalendarLinkModalContent.js @@ -36,7 +36,7 @@ function getUrls(state) { icalUrl += `tags=${tags.toString()}&`; } - icalUrl += `apikey=${window.Radarr.apiKey}`; + icalUrl += `apikey=${encodeURIComponent(window.Radarr.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 0603fb435..fc67b759b 100644 --- a/frontend/src/Components/SignalRConnector.js +++ b/frontend/src/Components/SignalRConnector.js @@ -61,7 +61,7 @@ function Logger(minimumLogLevel) { } Logger.prototype.cleanse = function(message) { - const apikey = new RegExp(`access_token=${window.Radarr.apiKey}`, 'g'); + const apikey = new RegExp(`access_token=${encodeURIComponent(window.Radarr.apiKey)}`, 'g'); return message.replace(apikey, 'access_token=(removed)'); }; @@ -105,7 +105,7 @@ class SignalRConnector extends Component { this.connection = new signalR.HubConnectionBuilder() .configureLogging(new Logger(signalR.LogLevel.Information)) - .withUrl(`${url}?access_token=${window.Radarr.apiKey}`) + .withUrl(`${url}?access_token=${encodeURIComponent(window.Radarr.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 23537273d..f24fee140 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -48,6 +48,7 @@ "Announced": "Announced", "AnnouncedMsg": "Movie is announced", "ApiKey": "API Key", + "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",