diff --git a/app/common/src/main/java/stirling/software/common/configuration/AppConfig.java b/app/common/src/main/java/stirling/software/common/configuration/AppConfig.java index e24a92d6a3d..4c638c7cc67 100644 --- a/app/common/src/main/java/stirling/software/common/configuration/AppConfig.java +++ b/app/common/src/main/java/stirling/software/common/configuration/AppConfig.java @@ -271,9 +271,14 @@ public String licenseType() { return "NORMAL"; } - @Bean(name = "disablePixel") - public boolean disablePixel() { - return Boolean.parseBoolean(env.getProperty("DISABLE_PIXEL", "false")); + @Bean(name = "scarfEnabled") + public boolean scarfEnabled() { + return applicationProperties.getSystem().isScarfEnabled(); + } + + @Bean(name = "posthogEnabled") + public boolean posthogEnabled() { + return applicationProperties.getSystem().isPosthogEnabled(); } @Bean(name = "machineType") diff --git a/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java b/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java index 0ffe2e26e90..9193eff7fb4 100644 --- a/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java +++ b/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java @@ -320,6 +320,8 @@ public static class System { private String tessdataDir; private Boolean enableAlphaFunctionality; private Boolean enableAnalytics; + private Boolean enablePosthog; + private Boolean enableScarf; private Datasource datasource; private Boolean disableSanitize; private int maxDPI; @@ -333,6 +335,18 @@ public static class System { public boolean isAnalyticsEnabled() { return this.getEnableAnalytics() != null && this.getEnableAnalytics(); } + + public boolean isPosthogEnabled() { + // Treat null as enabled when analytics is enabled + return this.isAnalyticsEnabled() + && (this.getEnablePosthog() == null || this.getEnablePosthog()); + } + + public boolean isScarfEnabled() { + // Treat null as enabled when analytics is enabled + return this.isAnalyticsEnabled() + && (this.getEnableScarf() == null || this.getEnableScarf()); + } } @Data diff --git a/app/common/src/main/java/stirling/software/common/service/PostHogService.java b/app/common/src/main/java/stirling/software/common/service/PostHogService.java index 2bc21983237..070dea694ba 100644 --- a/app/common/src/main/java/stirling/software/common/service/PostHogService.java +++ b/app/common/src/main/java/stirling/software/common/service/PostHogService.java @@ -56,7 +56,7 @@ public PostHogService( } private void captureSystemInfo() { - if (!applicationProperties.getSystem().isAnalyticsEnabled()) { + if (!applicationProperties.getSystem().isPosthogEnabled()) { return; } try { @@ -67,7 +67,7 @@ private void captureSystemInfo() { } public void captureEvent(String eventName, Map properties) { - if (!applicationProperties.getSystem().isAnalyticsEnabled()) { + if (!applicationProperties.getSystem().isPosthogEnabled()) { return; } diff --git a/app/core/src/main/resources/messages_en_GB.properties b/app/core/src/main/resources/messages_en_GB.properties index 69a5833d5b9..22007db4d14 100644 --- a/app/core/src/main/resources/messages_en_GB.properties +++ b/app/core/src/main/resources/messages_en_GB.properties @@ -1898,6 +1898,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off. cookieBanner.preferencesModal.analytics.title=Analytics cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with. +cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics +cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel #scannerEffect scannerEffect.title=Scanner Effect diff --git a/app/core/src/main/resources/messages_en_US.properties b/app/core/src/main/resources/messages_en_US.properties index e550e9c0d56..9f3c79307f9 100644 --- a/app/core/src/main/resources/messages_en_US.properties +++ b/app/core/src/main/resources/messages_en_US.properties @@ -1898,6 +1898,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off. cookieBanner.preferencesModal.analytics.title=Analytics cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with. +cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics +cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel #scannerEffect scannerEffect.title=Scanner Effect diff --git a/app/core/src/main/resources/settings.yml.template b/app/core/src/main/resources/settings.yml.template index b68a2b15464..e6b13812be3 100644 --- a/app/core/src/main/resources/settings.yml.template +++ b/app/core/src/main/resources/settings.yml.template @@ -109,7 +109,9 @@ system: showUpdateOnlyAdmin: false # only admins can see when a new update is available, depending on showUpdate it must be set to 'true' customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored. - enableAnalytics: null # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true + enableAnalytics: null # Master toggle for analytics: set to 'true' to enable all analytics, 'false' to disable all analytics, or leave as 'null' to prompt admin on first launch + enablePosthog: null # Enable PostHog analytics (open-source product analytics): set to 'true' to enable, 'false' to disable, or 'null' to enable by default when analytics is enabled + enableScarf: null # Enable Scarf pixel: set to 'true' to enable, 'false' to disable, or 'null' to enable by default when analytics is enabled enableUrlToPDF: false # Set to 'true' to enable URL to PDF, INTERNAL ONLY, known security issues, should not be used externally disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML) maxDPI: 500 # Maximum allowed DPI for PDF to image conversion diff --git a/app/core/src/main/resources/static/js/thirdParty/cookieconsent-config.js b/app/core/src/main/resources/static/js/thirdParty/cookieconsent-config.js index 7199184847c..d13cb7d1452 100644 --- a/app/core/src/main/resources/static/js/thirdParty/cookieconsent-config.js +++ b/app/core/src/main/resources/static/js/thirdParty/cookieconsent-config.js @@ -3,6 +3,19 @@ import './cookieconsent.umd.js'; // Enable dark mode document.documentElement.classList.add('cc--darkmode'); +// Build analytics services dynamically based on backend config +const analyticsServices = {}; +if (typeof posthogEnabled !== 'undefined' && posthogEnabled) { + analyticsServices.posthog = { + label: cookieBannerPreferencesModalPosthogLabel + }; +} +if (typeof scarfEnabled !== 'undefined' && scarfEnabled) { + analyticsServices.scarf = { + label: cookieBannerPreferencesModalScarfLabel + }; +} + CookieConsent.run({ guiOptions: { consentModal: { @@ -22,7 +35,9 @@ CookieConsent.run({ necessary: { readOnly: true }, - analytics: {} + analytics: { + services: analyticsServices + } }, language: { default: "en", diff --git a/app/core/src/main/resources/templates/fragments/common.html b/app/core/src/main/resources/templates/fragments/common.html index 49c95891436..2883d905c8e 100644 --- a/app/core/src/main/resources/templates/fragments/common.html +++ b/app/core/src/main/resources/templates/fragments/common.html @@ -168,14 +168,51 @@ - - + + @@ -221,7 +258,7 @@ return; } - window.CookieConsent.acceptedCategory('analytics')? + window.CookieConsent.acceptedService('posthog', 'analytics')? posthog.opt_in_capturing() : posthog.opt_out_capturing(); } const stirlingPDFLabel = /*[[${@StirlingPDFLabel}]]*/ ''; @@ -248,6 +285,8 @@ const cookieBannerPreferencesModalNecessaryDescription = /*[[#{cookieBanner.preferencesModal.necessary.description}]]*/ ""; const cookieBannerPreferencesModalAnalyticsTitle = /*[[#{cookieBanner.preferencesModal.analytics.title}]]*/ ""; const cookieBannerPreferencesModalAnalyticsDescription = /*[[#{cookieBanner.preferencesModal.analytics.description}]]*/ ""; + const cookieBannerPreferencesModalPosthogLabel = /*[[#{cookieBanner.preferencesModal.analytics.posthog.label}]]*/ ""; + const cookieBannerPreferencesModalScarfLabel = /*[[#{cookieBanner.preferencesModal.analytics.scarf.label}]]*/ ""; if (analyticsEnabled) { !function (t, e) {