Skip to content

Commit

Permalink
Encode analytics ids in script (#17369)
Browse files Browse the repository at this point in the history
* Encode analytics ids in script

* Apply suggestions
  • Loading branch information
sebastienros authored Jan 17, 2025
1 parent 6bfa5c8 commit 41cf7e8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Filters;
Expand All @@ -12,16 +13,19 @@ public sealed class FacebookPixelFilter : IAsyncResultFilter
{
private readonly IResourceManager _resourceManager;
private readonly ISiteService _siteService;
private readonly HtmlString _code = new("<!-- Meta Pixel Code -->\r\n<script>\r\n!function(f,b,e,v,n,t,s)\r\n{if(f.fbq)return;n=f.fbq=function(){n.callMethod?\r\nn.callMethod.apply(n,arguments):n.queue.push(arguments)};\r\nif(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\r\nn.queue=[];t=b.createElement(e);t.async=!0;\r\nt.src=v;s=b.getElementsByTagName(e)[0];\r\ns.parentNode.insertBefore(t,s)}(window, document,'script',\r\n'https://connect.facebook.net/en_US/fbevents.js');\r\nfbq('init', MetaPixelId);\r\nfbq('track', 'PageView');\r\n</script>\r\n<!-- End Meta Pixel Code -->");
private readonly JavaScriptEncoder _jsEncoder;

private HtmlString _scriptsCache;
private static readonly HtmlString _preamble = new("<!-- Meta Pixel Code -->\r\n<script>\r\n!function(f,b,e,v,n,t,s)\r\n{if(f.fbq)return;n=f.fbq=function(){n.callMethod?\r\nn.callMethod.apply(n,arguments):n.queue.push(arguments)};\r\nif(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\r\nn.queue=[];t=b.createElement(e);t.async=!0;\r\nt.src=v;s=b.getElementsByTagName(e)[0];\r\ns.parentNode.insertBefore(t,s)}(window, document,'script',\r\n'https://connect.facebook.net/en_US/fbevents.js');\r\nfbq('init', '");
private static readonly HtmlString _end = new HtmlString("');\r\nfbq('track', 'PageView');\r\n</script>\r\n<!-- End Meta Pixel Code -->");

public FacebookPixelFilter(
IResourceManager resourceManager,
ISiteService siteService)
ISiteService siteService,
JavaScriptEncoder jsEncoder)
{
_resourceManager = resourceManager;
_siteService = siteService;
_jsEncoder = jsEncoder;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
Expand All @@ -31,21 +35,15 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE
{
var canTrack = context.HttpContext.Features.Get<ITrackingConsentFeature>()?.CanTrack ?? true;

if (_scriptsCache == null && canTrack)
if (canTrack)
{
var settings = await _siteService.GetSettingsAsync<FacebookPixelSettings>();

if (!string.IsNullOrWhiteSpace(settings?.PixelId))
if (settings is not null)
{
_scriptsCache = new HtmlString($"<script>const MetaPixelId = '{settings.PixelId.Replace("'", "")}';</script>");
_resourceManager.RegisterHeadScript(new HtmlContentBuilder([_preamble, _jsEncoder.Encode(settings.PixelId), _end]));
}
}

if (_scriptsCache != null)
{
_resourceManager.RegisterHeadScript(_scriptsCache);
_resourceManager.RegisterHeadScript(_code);
}
}

await next.Invoke();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Filters;
Expand All @@ -12,15 +13,23 @@ public sealed class GoogleAnalyticsFilter : IAsyncResultFilter
{
private readonly IResourceManager _resourceManager;
private readonly ISiteService _siteService;
private readonly JavaScriptEncoder _jsEncoder;
private readonly UrlEncoder _urlEncoder;

private HtmlString _scriptsCache;
private static readonly HtmlString _preamble = new($"<!-- Global site tag (gtag.js) - Google Analytics -->\n<script async src=\"https://www.googletagmanager.com/gtag/js?id=");
private static readonly HtmlString _middle = new HtmlString($"\"></script>\n<script>window.dataLayer = window.dataLayer || [];function gtag() {{ dataLayer.push(arguments); }}gtag('js', new Date());gtag('config', '");
private static readonly HtmlString _end = new HtmlString($"')</script>\n<!-- End Global site tag (gtag.js) - Google Analytics -->");

public GoogleAnalyticsFilter(
IResourceManager resourceManager,
ISiteService siteService)
ISiteService siteService,
JavaScriptEncoder jsEncoder,
UrlEncoder urlEncoder)
{
_resourceManager = resourceManager;
_siteService = siteService;
_jsEncoder = jsEncoder;
_urlEncoder = urlEncoder;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
Expand All @@ -30,20 +39,15 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE
{
var canTrack = context.HttpContext.Features.Get<ITrackingConsentFeature>()?.CanTrack ?? true;

if (_scriptsCache == null && canTrack)
if (canTrack)
{
var settings = await _siteService.GetSettingsAsync<GoogleAnalyticsSettings>();

if (!string.IsNullOrWhiteSpace(settings?.TrackingID))
if (settings is not null)
{
_scriptsCache = new HtmlString($"<!-- Global site tag (gtag.js) - Google Analytics -->\n<script async src=\"https://www.googletagmanager.com/gtag/js?id={settings.TrackingID}\"></script>\n<script>window.dataLayer = window.dataLayer || [];function gtag() {{ dataLayer.push(arguments); }}gtag('js', new Date());gtag('config', '{settings.TrackingID}')</script>\n<!-- End Global site tag (gtag.js) - Google Analytics -->");
_resourceManager.RegisterHeadScript(new HtmlContentBuilder([_preamble, _urlEncoder.Encode(settings.TrackingID), _middle, _jsEncoder.Encode(settings.TrackingID), _end]));
}
}

if (_scriptsCache != null)
{
_resourceManager.RegisterHeadScript(_scriptsCache);
}
}

await next.Invoke();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Filters;
Expand All @@ -12,15 +13,19 @@ public sealed class GoogleTagManagerFilter : IAsyncResultFilter
{
private readonly IResourceManager _resourceManager;
private readonly ISiteService _siteService;
private readonly JavaScriptEncoder _jsEncoder;

private HtmlString _scriptsCache;
private static readonly HtmlString _preamble = new("<!-- Google Tag Manager -->\n<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n })(window,document,'script','dataLayer','");
private static readonly HtmlString _end= new HtmlString("');</script>\n<!-- End Google Tag Manager -->");

public GoogleTagManagerFilter(
IResourceManager resourceManager,
ISiteService siteService)
ISiteService siteService,
JavaScriptEncoder jsEncoder)
{
_resourceManager = resourceManager;
_siteService = siteService;
_jsEncoder = jsEncoder;
}

public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
Expand All @@ -30,20 +35,15 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE
{
var canTrack = context.HttpContext.Features.Get<ITrackingConsentFeature>()?.CanTrack ?? true;

if (_scriptsCache == null && canTrack)
if (canTrack)
{
var settings = await _siteService.GetSettingsAsync<GoogleTagManagerSettings>();

if (!string.IsNullOrWhiteSpace(settings?.ContainerID))
if (settings is not null)
{
_scriptsCache = new HtmlString("<!-- Google Tag Manager -->\n<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n })(window,document,'script','dataLayer','" + settings.ContainerID + "');</script>\n<!-- End Google Tag Manager -->");
_resourceManager.RegisterHeadScript(new HtmlContentBuilder([_preamble, _jsEncoder.Encode(settings.ContainerID), _end]));
}
}

if (_scriptsCache != null)
{
_resourceManager.RegisterHeadScript(_scriptsCache);
}
}

await next.Invoke();
Expand Down

0 comments on commit 41cf7e8

Please sign in to comment.