Added: Make Lidarr CSP compatible

Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
pull/342/head
Qstick 6 years ago
parent 44ad754c86
commit 0d7cd8009f

@ -52,18 +52,7 @@
<div id="root" class="root"></div> <div id="root" class="root"></div>
</body> </body>
<script type="text/javascript"> <script src="/initialize.js" data-no-hash></script>
window.Lidarr = {
apiRoot: 'API_ROOT',
apiKey: 'API_KEY',
release: 'APP_RELEASE',
version: 'APP_VERSION',
branch: 'APP_BRANCH',
analytics: APP_ANALYTICS,
urlBase: 'URL_BASE',
isProduction: IS_PRODUCTION
};
</script>
<script src="/polyfills.js"></script> <script src="/polyfills.js"></script>
<script src="/vendor.js"></script> <script src="/vendor.js"></script>
<script src="/preload.js"></script> <script src="/preload.js"></script>

@ -0,0 +1,54 @@
using System.IO;
using Nancy;
using Nancy.Responses;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Configuration;
namespace Lidarr.Http.Frontend
{
public class InitializeJsModule : NancyModule
{
private readonly IConfigFileProvider _configFileProvider;
private readonly IAnalyticsService _analyticsService;
public InitializeJsModule(IConfigFileProvider configFileProvider,
IAnalyticsService analyticsService)
{
_configFileProvider = configFileProvider;
_analyticsService = analyticsService;
Get["/initialize.js"] = x => Index();
}
private Response Index()
{
// TODO: Move away from window.Lidarr and prefetch the information returned here when starting the UI
return new StreamResponse(GetContentStream, "application/javascript");
}
private Stream GetContentStream()
{
var urlBase = _configFileProvider.UrlBase;
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.WriteLine("window.Lidarr = {");
writer.WriteLine($" apiRoot: '{urlBase}/api/v1',");
writer.WriteLine($" apiKey: '{_configFileProvider.ApiKey}',");
writer.WriteLine($" release: '{BuildInfo.Release}',");
writer.WriteLine($" version: '{BuildInfo.Version.ToString()}',");
writer.WriteLine($" branch: '{_configFileProvider.Branch.ToLower()}',");
writer.WriteLine($" analytics: {_analyticsService.IsEnabled.ToString().ToLowerInvariant()},");
writer.WriteLine($" urlBase: '{urlBase}',");
writer.WriteLine($" isProduction: {RuntimeInfo.IsProduction.ToString().ToLowerInvariant()}");
writer.WriteLine("};");
writer.Flush();
stream.Position = 0;
return stream;
}
}
}

@ -74,16 +74,9 @@ namespace Lidarr.Http.Frontend.Mappers
return string.Format("{0}=\"{1}{2}\"", match.Groups["attribute"].Value, UrlBase, url); return string.Format("{0}=\"{1}{2}\"", match.Groups["attribute"].Value, UrlBase, url);
}); });
text = ReplaceText(text);
_generatedContent = text; _generatedContent = text;
return _generatedContent; return _generatedContent;
} }
protected virtual string ReplaceText(string text)
{
return text;
}
} }
} }

@ -3,7 +3,6 @@ using System.IO;
using NLog; using NLog;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
namespace Lidarr.Http.Frontend.Mappers namespace Lidarr.Http.Frontend.Mappers
@ -11,25 +10,20 @@ namespace Lidarr.Http.Frontend.Mappers
public class IndexHtmlMapper : HtmlMapperBase public class IndexHtmlMapper : HtmlMapperBase
{ {
private readonly IConfigFileProvider _configFileProvider; private readonly IConfigFileProvider _configFileProvider;
private readonly IAnalyticsService _analyticsService;
private static string API_KEY; private static string API_KEY;
public IndexHtmlMapper(IAppFolderInfo appFolderInfo, public IndexHtmlMapper(IAppFolderInfo appFolderInfo,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IConfigFileProvider configFileProvider, IConfigFileProvider configFileProvider,
IAnalyticsService analyticsService,
Func<ICacheBreakerProvider> cacheBreakProviderFactory, Func<ICacheBreakerProvider> cacheBreakProviderFactory,
Logger logger) Logger logger)
: base(diskProvider, cacheBreakProviderFactory, logger) : base(diskProvider, cacheBreakProviderFactory, logger)
{ {
_configFileProvider = configFileProvider; _configFileProvider = configFileProvider;
_analyticsService = analyticsService;
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "index.html"); HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "index.html");
UrlBase = configFileProvider.UrlBase; UrlBase = configFileProvider.UrlBase;
API_KEY = configFileProvider.ApiKey;
} }
public override string Map(string resourceUrl) public override string Map(string resourceUrl)
@ -47,19 +41,5 @@ namespace Lidarr.Http.Frontend.Mappers
!resourceUrl.StartsWith("/login"); !resourceUrl.StartsWith("/login");
} }
protected override string ReplaceText(string text)
{
text = text.Replace("API_ROOT", UrlBase + "/api/v1");
text = text.Replace("API_KEY", API_KEY);
text = text.Replace("RELEASE", BuildInfo.Release);
text = text.Replace("APP_VERSION", BuildInfo.Version.ToString());
text = text.Replace("APP_BRANCH", _configFileProvider.Branch.ToLower());
text = text.Replace("APP_ANALYTICS", _analyticsService.IsEnabled.ToString().ToLowerInvariant());
text = text.Replace("URL_BASE", UrlBase);
text = text.Replace("IS_PRODUCTION", RuntimeInfo.IsProduction.ToString().ToLowerInvariant());
return text;
}
} }
} }

@ -37,7 +37,7 @@ namespace Lidarr.Http.Frontend.Mappers
} }
return resourceUrl.StartsWith("/content") || return resourceUrl.StartsWith("/content") ||
resourceUrl.EndsWith(".js") || (resourceUrl.EndsWith(".js") && !resourceUrl.EndsWith("initialize.js")) ||
resourceUrl.EndsWith(".map") || resourceUrl.EndsWith(".map") ||
resourceUrl.EndsWith(".css") || resourceUrl.EndsWith(".css") ||
(resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) || (resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) ||

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Nancy; using Nancy;
using NLog; using NLog;
using NzbDrone.Core.Configuration;
using Lidarr.Http.Frontend.Mappers; using Lidarr.Http.Frontend.Mappers;
namespace Lidarr.Http.Frontend namespace Lidarr.Http.Frontend
@ -11,14 +10,12 @@ namespace Lidarr.Http.Frontend
public class StaticResourceModule : NancyModule public class StaticResourceModule : NancyModule
{ {
private readonly IEnumerable<IMapHttpRequestsToDisk> _requestMappers; private readonly IEnumerable<IMapHttpRequestsToDisk> _requestMappers;
private readonly IConfigFileProvider _configFileProvider;
private readonly Logger _logger; private readonly Logger _logger;
public StaticResourceModule(IEnumerable<IMapHttpRequestsToDisk> requestMappers, IConfigFileProvider configFileProvider, Logger logger) public StaticResourceModule(IEnumerable<IMapHttpRequestsToDisk> requestMappers, Logger logger)
{ {
_requestMappers = requestMappers; _requestMappers = requestMappers;
_configFileProvider = configFileProvider;
_logger = logger; _logger = logger;
Get["/{resource*}"] = x => Index(); Get["/{resource*}"] = x => Index();

@ -91,6 +91,7 @@
<Compile Include="Extensions\ReqResExtensions.cs" /> <Compile Include="Extensions\ReqResExtensions.cs" />
<Compile Include="Extensions\RequestExtensions.cs" /> <Compile Include="Extensions\RequestExtensions.cs" />
<Compile Include="Frontend\CacheableSpecification.cs" /> <Compile Include="Frontend\CacheableSpecification.cs" />
<Compile Include="Frontend\InitializeJsModule.cs" />
<Compile Include="Frontend\Mappers\BackupFileMapper.cs" /> <Compile Include="Frontend\Mappers\BackupFileMapper.cs" />
<Compile Include="Frontend\Mappers\CacheBreakerProvider.cs" /> <Compile Include="Frontend\Mappers\CacheBreakerProvider.cs" />
<Compile Include="Frontend\Mappers\FaviconMapper.cs" /> <Compile Include="Frontend\Mappers\FaviconMapper.cs" />

Loading…
Cancel
Save