From 62243cb716cd041b1d787089e85c9b3def7d0a99 Mon Sep 17 00:00:00 2001 From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com> Date: Mon, 9 Dec 2024 10:17:08 +0000 Subject: [PATCH] Application Insights front-end telemetry (#613) * Corrected indentation * Delete App Insights cookies if consent is rejected * Inject App Insights web sdk if feature is enabled * Set connection string instead of defaulting to instrumentation key * Updated Cookie Consent Policy * Use npm package for app insights web configuration * Asset build workflow --- .../Pages/Public/Cookies.cshtml | 47 ++- .../Pages/Shared/_Layout.cshtml | 25 +- .../Pages/_ViewImports.cshtml | 2 +- .../Services/AnalyticsConsentService.cs | 18 +- .../Dfe.ManageFreeSchoolProjects/Startup.cs | 5 +- .../appsettings.json | 3 +- .../wwwroot/package-lock.json | 356 +++++++++++++++++- .../wwwroot/package.json | 4 +- .../wwwroot/src/application-insights.js | 16 + .../wwwroot/webpack.appinsights.config.js | 9 + 10 files changed, 446 insertions(+), 39 deletions(-) create mode 100644 Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/src/application-insights.js create mode 100644 Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/webpack.appinsights.config.js diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Public/Cookies.cshtml b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Public/Cookies.cshtml index 2adf8bce8..60293cf7d 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Public/Cookies.cshtml +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Public/Cookies.cshtml @@ -117,6 +117,8 @@

Analytics cookies (optional)

+ +

Google Analytics

With your permission, we use Google Analytics to collect data about how you use this website. This information helps us to improve our website.

Google Analytics is not allowed to use or share our analytics data with anyone. @@ -127,8 +129,7 @@

  • any errors you see while using this website
  • what you click on while you are visiting the website
  • - - +

    Google Analytics stores the following cookies:

    @@ -150,6 +151,46 @@
    + +

    Application Insights

    +

    We use Azure Application Insights software to collect information about how you use this website. We do this to help make sure the site is meeting the needs of its users and to help us make improvements.

    +

    Azure Application Insights stores information about:

    + +

    We don't allow Microsoft to use or share our analytics data.

    + +

    Azure Application Insights sets the following cookies:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NamePurposeExpires
    ai_sessionThis helps us track activity happening over a single browser session1 hour
    ai_userThis helps us to identify the number of distinct users accessing the site over time by tracking if you've visited before1 year
    ai_authuserThis helps us to identify authenticated users and how they interact with the siteWhen you close your browser
    +
    @@ -180,4 +221,4 @@ data-module="govuk-button" data-disable-with="Save changes">
    - \ No newline at end of file + diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Shared/_Layout.cshtml b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Shared/_Layout.cshtml index 8cf24160a..9755f0d5d 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Shared/_Layout.cshtml +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/Shared/_Layout.cshtml @@ -3,7 +3,8 @@ @inject Microsoft.FeatureManagement.IFeatureManager _featureManager @{ - var showAnalytics = _configuration["GoogleAnalytics:Enable"] == "Yes" && _analytisConsentService.HasConsent(); + var hasConsented = _analytisConsentService.HasConsent(); + var showAnalytics = _configuration["GoogleAnalytics:Enable"] == "Yes" && hasConsented; var titleDescription = Context.Request.Path == "/project-type" ? string.Empty @@ -12,7 +13,8 @@ var widePage = ViewData["WidePage"] != null ? "mfsp-wider-page" : string.Empty; - + bool.TryParse(_configuration["ApplicationInsights:BrowserAnalyticsEnabled"], out bool enableAppInsightsBrowserAnalytics); + var authenticatedUserId = Context.User.Identity is not null && Context.User.Identity.IsAuthenticated ? Context.User.Identity.Name ?? "Unknown" : "Anonymous"; } @@ -34,6 +36,21 @@ } + @if (hasConsented && enableAppInsightsBrowserAnalytics) + { + + + + + + } + + @@ -114,8 +131,8 @@ } } - + - \ No newline at end of file + diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/_ViewImports.cshtml b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/_ViewImports.cshtml index 9b5c847e6..1202c0192 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/_ViewImports.cshtml +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Pages/_ViewImports.cshtml @@ -4,4 +4,4 @@ @using Dfe.ManageFreeSchoolProjects.Extensions @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Dfe.ManageFreeSchoolProjects -@addTagHelper *, NetEscapades.AspNetCore.SecurityHeaders.TagHelpers \ No newline at end of file +@addTagHelper *, NetEscapades.AspNetCore.SecurityHeaders.TagHelpers diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Services/AnalyticsConsentService.cs b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Services/AnalyticsConsentService.cs index f59a199e0..98e35424d 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Services/AnalyticsConsentService.cs +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Services/AnalyticsConsentService.cs @@ -25,9 +25,9 @@ public AnalyticsConsentService(IHttpContextAccessor httpContextAccessor, IConfig var domain = _configuration["GoogleAnalytics:Domain"]; if (!string.IsNullOrEmpty(domain)) { - AnalyticsDomain = domain; - } - } + AnalyticsDomain = domain; + } + } public bool? ConsentValue() { @@ -66,20 +66,20 @@ private void SetConsent(bool consent) _httpContextAccessor.HttpContext.Response.Cookies.Append(ConsentCookieName, consent.ToString(), cookieOptions); var request = _httpContextAccessor.HttpContext.Request; - if (!consent) + if (!consent) { foreach (var cookie in request.Cookies.Keys) { - if (cookie.StartsWith("_ga") || cookie.Equals("_gid")) + if (cookie.StartsWith("_ga") || cookie.Equals("_gid") || cookie.StartsWith("ai_")) { //Delete if domain is the same - _httpContextAccessor.HttpContext.Response.Cookies.Delete(cookie); + _httpContextAccessor.HttpContext.Response.Cookies.Delete(cookie); //Delete if domain matches - need both as we wont be sent the cookie if the domain doesnt match - _httpContextAccessor.HttpContext.Response.Cookies.Delete(cookie, new CookieOptions() { Domain = AnalyticsDomain}); - } + _httpContextAccessor.HttpContext.Response.Cookies.Delete(cookie, new CookieOptions() { Domain = AnalyticsDomain, Secure = true }); + } } } } } -} \ No newline at end of file +} diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Startup.cs b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Startup.cs index f07971c56..481cde3ac 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Startup.cs +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/Startup.cs @@ -161,7 +161,10 @@ public void ConfigureServices(IServiceCollection services) } }); - services.AddApplicationInsightsTelemetry(); + services.AddApplicationInsightsTelemetry(options => + { + options.ConnectionString = Configuration["ApplicationInsights:ConnectionString"]; + }); services.AddHttpClient("MfspClient", (_, client) => { diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/appsettings.json b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/appsettings.json index 55d5abd9b..ac682c00f 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/appsettings.json +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/appsettings.json @@ -25,7 +25,8 @@ "AllowedRoles": "user" }, "ApplicationInsights": { - "ConnectionString": "secret" + "ConnectionString": "secret", + "BrowserAnalyticsEnabled": false }, "CypressTestSecret": "secret", "AuthenticationExpirationInMinutes": 60, diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package-lock.json b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package-lock.json index 904ddeaa1..50f412a17 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package-lock.json +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "@microsoft/applicationinsights-web": "^3.2.2", "accessible-autocomplete": "^3.0.0", "dfe-frontend": "2.0.1", "govuk-frontend": "5.4.1", @@ -45,15 +46,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/set-array": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", @@ -85,10 +77,183 @@ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@microsoft/applicationinsights-analytics-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-3.2.2.tgz", + "integrity": "sha512-i6/7hYO7lFPE1rMARG6c4bGTuUJUiPb9GRfwMhzArpG39fqduCWpH6y2PdlwZzjyDQAxIOgBiSfLddgsAVoYOA==", + "dependencies": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-cfgsync-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-cfgsync-js/-/applicationinsights-cfgsync-js-3.2.2.tgz", + "integrity": "sha512-W4sQmQC9ZXN8ETYHcXQZl7kMACDkiC/a26OYx9IW8CzgZUI0U3hfDRonaj/1AMkM6zZbC2Zuto4vqpex7abJEg==", + "dependencies": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-channel-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.2.2.tgz", + "integrity": "sha512-4ruoKxgZYYa+K8JJu8RMY0egKazS8xClbx70NQHa/rJ7JYFgN3OIEIBZtFoMcHR8Vg7MEsNE5/wV6o7WWJkVIA==", + "dependencies": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-common": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.2.2.tgz", + "integrity": "sha512-e1C35gdkFSzWyUUR1S8FvisXW3nT3p6wWsLNs+vUKLOTQzsvW3XpNMVtNCq4MfHWiYDuz1lPSzo2eENaij1fVA==", + "dependencies": { + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-core-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.2.2.tgz", + "integrity": "sha512-dF6LZ4ahdhoHufw+N7OXRDzWT8QN193Dvpd8GLqEZdR/KtCTofPSI63yumu+ZkzKYadf1S3w2xg0OmbdyXexoQ==", + "dependencies": { + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-dependencies-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-3.2.2.tgz", + "integrity": "sha512-15EUVU6Kh0B400i/2YNy+V9xMhOwnpzAMTAiyFo90Q1SC5rJIsmzqjAWQnFmxAeq5YQoZ2FuQQpD2qsUajVEQQ==", + "dependencies": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-properties-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-3.2.2.tgz", + "integrity": "sha512-ovT123foF4WquHdk6f51YpRacx7ZgST7iwqRA/jshy/7NVqlu05JbrVB8IlrxNausdaRwX5CvSCca+SQbOW0ZA==", + "dependencies": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-shims": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz", + "integrity": "sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==", + "dependencies": { + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" } }, + "node_modules/@microsoft/applicationinsights-web": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-3.2.2.tgz", + "integrity": "sha512-DBJ83Fe7nHzH7QgMKFQrBN/Gbhoo5JgMQkBzJeTb5hMfNZUFOBEHWjytBdU9MEZVpa+Vk+RPQ72IOc0txbnJYw==", + "dependencies": { + "@microsoft/applicationinsights-analytics-js": "3.2.2", + "@microsoft/applicationinsights-cfgsync-js": "3.2.2", + "@microsoft/applicationinsights-channel-js": "3.2.2", + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-dependencies-js": "3.2.2", + "@microsoft/applicationinsights-properties-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/dynamicproto-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.3.tgz", + "integrity": "sha512-JTWTU80rMy3mdxOjjpaiDQsTLZ6YSGGqsjURsY6AUQtIj0udlF/jYmhdLZu8693ZIC0T1IwYnFa0+QeiMnziBA==", + "dependencies": { + "@nevware21/ts-utils": ">= 0.10.4 < 2.x" + } + }, + "node_modules/@nevware21/ts-async": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.1.tgz", + "integrity": "sha512-O2kN8n2HpDWJ7Oji+oTMnhITrCndmrNvrHbGDwAIBydx+FWvLE/vrw4QwnRRMvSCa2AJrcP59Ryklxv30KfkWQ==", + "dependencies": { + "@nevware21/ts-utils": ">= 0.11.2 < 2.x" + } + }, + "node_modules/@nevware21/ts-utils": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.2.tgz", + "integrity": "sha512-80W8BkS09kkGuUHJX50Fqq+QqAslxUaOQytH+3JhRacXs1EpEt2JOOkYKytqFZAYir3SeH9fahniEaDzIBxlUw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2151,6 +2316,13 @@ "node": ">=8.0" } }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD", + "peer": true + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -2390,12 +2562,6 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, "@jridgewell/set-array": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", @@ -2424,10 +2590,156 @@ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + } + } + }, + "@microsoft/applicationinsights-analytics-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-3.2.2.tgz", + "integrity": "sha512-i6/7hYO7lFPE1rMARG6c4bGTuUJUiPb9GRfwMhzArpG39fqduCWpH6y2PdlwZzjyDQAxIOgBiSfLddgsAVoYOA==", + "requires": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" } }, + "@microsoft/applicationinsights-cfgsync-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-cfgsync-js/-/applicationinsights-cfgsync-js-3.2.2.tgz", + "integrity": "sha512-W4sQmQC9ZXN8ETYHcXQZl7kMACDkiC/a26OYx9IW8CzgZUI0U3hfDRonaj/1AMkM6zZbC2Zuto4vqpex7abJEg==", + "requires": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-channel-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.2.2.tgz", + "integrity": "sha512-4ruoKxgZYYa+K8JJu8RMY0egKazS8xClbx70NQHa/rJ7JYFgN3OIEIBZtFoMcHR8Vg7MEsNE5/wV6o7WWJkVIA==", + "requires": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-common": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.2.2.tgz", + "integrity": "sha512-e1C35gdkFSzWyUUR1S8FvisXW3nT3p6wWsLNs+vUKLOTQzsvW3XpNMVtNCq4MfHWiYDuz1lPSzo2eENaij1fVA==", + "requires": { + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-core-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.2.2.tgz", + "integrity": "sha512-dF6LZ4ahdhoHufw+N7OXRDzWT8QN193Dvpd8GLqEZdR/KtCTofPSI63yumu+ZkzKYadf1S3w2xg0OmbdyXexoQ==", + "requires": { + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-dependencies-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-3.2.2.tgz", + "integrity": "sha512-15EUVU6Kh0B400i/2YNy+V9xMhOwnpzAMTAiyFo90Q1SC5rJIsmzqjAWQnFmxAeq5YQoZ2FuQQpD2qsUajVEQQ==", + "requires": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-properties-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-3.2.2.tgz", + "integrity": "sha512-ovT123foF4WquHdk6f51YpRacx7ZgST7iwqRA/jshy/7NVqlu05JbrVB8IlrxNausdaRwX5CvSCca+SQbOW0ZA==", + "requires": { + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/applicationinsights-shims": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz", + "integrity": "sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==", + "requires": { + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" + } + }, + "@microsoft/applicationinsights-web": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-3.2.2.tgz", + "integrity": "sha512-DBJ83Fe7nHzH7QgMKFQrBN/Gbhoo5JgMQkBzJeTb5hMfNZUFOBEHWjytBdU9MEZVpa+Vk+RPQ72IOc0txbnJYw==", + "requires": { + "@microsoft/applicationinsights-analytics-js": "3.2.2", + "@microsoft/applicationinsights-cfgsync-js": "3.2.2", + "@microsoft/applicationinsights-channel-js": "3.2.2", + "@microsoft/applicationinsights-common": "3.2.2", + "@microsoft/applicationinsights-core-js": "3.2.2", + "@microsoft/applicationinsights-dependencies-js": "3.2.2", + "@microsoft/applicationinsights-properties-js": "3.2.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.1 < 2.x", + "@nevware21/ts-utils": ">= 0.11.1 < 2.x" + } + }, + "@microsoft/dynamicproto-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.3.tgz", + "integrity": "sha512-JTWTU80rMy3mdxOjjpaiDQsTLZ6YSGGqsjURsY6AUQtIj0udlF/jYmhdLZu8693ZIC0T1IwYnFa0+QeiMnziBA==", + "requires": { + "@nevware21/ts-utils": ">= 0.10.4 < 2.x" + } + }, + "@nevware21/ts-async": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.1.tgz", + "integrity": "sha512-O2kN8n2HpDWJ7Oji+oTMnhITrCndmrNvrHbGDwAIBydx+FWvLE/vrw4QwnRRMvSCa2AJrcP59Ryklxv30KfkWQ==", + "requires": { + "@nevware21/ts-utils": ">= 0.11.2 < 2.x" + } + }, + "@nevware21/ts-utils": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.2.tgz", + "integrity": "sha512-80W8BkS09kkGuUHJX50Fqq+QqAslxUaOQytH+3JhRacXs1EpEt2JOOkYKytqFZAYir3SeH9fahniEaDzIBxlUw==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3851,6 +4163,12 @@ "is-number": "^7.0.0" } }, + "tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "peer": true + }, "unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package.json b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package.json index f443346c2..1d9255a6d 100644 --- a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package.json +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/package.json @@ -2,7 +2,8 @@ "scripts": { "build": "npm run build:assets && npm run build:frontend", "build:frontend": "webpack", - "build:assets": "webpack --config webpack.assets.config.js", + "build:assets": "webpack --config webpack.assets.config.js & npm run build:assets:application-insights", + "build:assets:application-insights": "webpack --config webpack.appinsights.config.js", "build:watch": "webpack --watch" }, "devDependencies": { @@ -20,6 +21,7 @@ "accessible-autocomplete": "^3.0.0", "dfe-frontend": "2.0.1", "govuk-frontend": "5.4.1", + "@microsoft/applicationinsights-web": "^3.2.2", "jquery": "^3.6.1" } } diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/src/application-insights.js b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/src/application-insights.js new file mode 100644 index 000000000..a786f777d --- /dev/null +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/src/application-insights.js @@ -0,0 +1,16 @@ +// App Insights frontend +import { ApplicationInsights } from '@microsoft/applicationinsights-web' + +const clickPluginInstance = new Microsoft.ApplicationInsights.ClickAnalyticsPlugin(); +const appInsights = new ApplicationInsights({ config: { + connectionString: window.appInsights.connectionString, + extensions: [ clickPluginInstance ], + extensionConfig: { [clickPluginInstance.identifier] : { + autoCapture : true, + dataTags: { useDefaultContentNameOrId: true } + } }, +} }); + +appInsights.loadAppInsights(); +appInsights.setAuthenticatedUserContext(window.appInsights.authenticatedUserId, null, true); +appInsights.trackPageView(); diff --git a/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/webpack.appinsights.config.js b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/webpack.appinsights.config.js new file mode 100644 index 000000000..d872596f9 --- /dev/null +++ b/Dfe.ManageFreeSchoolProjects/Dfe.ManageFreeSchoolProjects/wwwroot/webpack.appinsights.config.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + entry: ['./src/application-insights.js', './node_modules/@microsoft/applicationinsights-web/dist/es5/applicationinsights-web.min.js'], + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'application-insights.min.js', + } +};