Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions chart/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ spec:
# Optional: config without it means no banner, not a failed pod
optional: true

- name: MATOMO_MODE
valueFrom:
configMapKeyRef:
name: {{ .Release.Name }}-config
key: matomoMode
# Optional: config without it means direct tracking, not a failed pod
optional: true

ports:
- containerPort: 80
imagePullPolicy: Always
2 changes: 2 additions & 0 deletions chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ config:
frontendOnly: "false"
environment: local
prodUrl: https://test.platform.moleculemaker.org
# 'proxied': Matomo hits go through this app's nginx, without cookies. Anything else: direct.
matomoMode: direct
extraDeploy: []
27 changes: 27 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
#!/bin/bash

# With MATOMO_MODE=proxied, serve the Matomo tracker from this app's own origin, at paths
# ad blockers don't recognize: no "matomo" or "piwik" in the path, and no .php extension
# (EasyPrivacy blocks *.php?action_name=). Hits keep the visitor's IP in X-Forwarded-For.
mkdir -p /etc/nginx/matomo-proxy
rm -f /etc/nginx/matomo-proxy/*.conf
if [ "$MATOMO_MODE" = "proxied" ]; then
upstream="${MATOMO_UPSTREAM:-http://matomo.matomo.svc.cluster.local}"
cat > /etc/nginx/matomo-proxy/locations.conf <<CONF
location = /px/s.js {
proxy_pass ${upstream}/matomo.js;
proxy_ssl_server_name on;
# Don't pass this app's cookies or credentials to Matomo, or let Matomo set cookies here.
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_hide_header Set-Cookie;
}
location = /px/h {
proxy_pass ${upstream}/matomo.php;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_hide_header Set-Cookie;
}
CONF
fi

envsubst < /usr/share/nginx/html/assets/config/envvars.tpl.json > /usr/share/nginx/html/assets/config/envvars.json && exec nginx -g 'daemon off;'
4 changes: 4 additions & 0 deletions nginx/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ server {

#error_page 404 /404.html;

# Matomo proxy locations, written by entrypoint.sh only when MATOMO_MODE=proxied.
# nginx won't start if a proxy_pass host doesn't resolve, so they can't live here.
include /etc/nginx/matomo-proxy/*.conf;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
Expand Down
4 changes: 4 additions & 0 deletions src/app/models/envvars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ export interface EnvVars {
environment: string;
// The released tool, linked from that banner. Empty for local development.
prodUrl: string;

// 'proxied' sends Matomo hits through this app's nginx without cookies; anything else
// (including empty) sends them straight to matomo.mmli2.ncsa.illinois.edu.
matomoMode: string;
}
1 change: 1 addition & 0 deletions src/app/testing/environment-service.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const envConfig: EnvVars = {
frontendOnly: 'true',
environment: 'prod', // no staging banner in other components' specs
prodUrl: 'http://environment-service.stub',
matomoMode: 'direct',
};

export function provideEnvironmentServiceStub() {
Expand Down
4 changes: 3 additions & 1 deletion src/assets/config/envvars.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
"frontendOnly": "false",

"environment": "local",
"prodUrl": ""
"prodUrl": "",

"matomoMode": "direct"
}
4 changes: 3 additions & 1 deletion src/assets/config/envvars.tpl.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"frontendOnly": "${FRONTEND_ONLY}",

"environment": "${ENVIRONMENT}",
"prodUrl": "${PROD_URL}"
"prodUrl": "${PROD_URL}",

"matomoMode": "${MATOMO_MODE}"
}

37 changes: 25 additions & 12 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { importProvidersFrom, inject, provideAppInitializer } from '@angular/cor
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { MatomoModule, MatomoRouterModule } from 'ngx-matomo-client';
import { MatomoInitializerService, MatomoModule, MatomoRouterModule, MatomoTracker } from 'ngx-matomo-client';
import { MenuModule } from 'primeng/menu';
import { ApiModule, Configuration } from '@api/mmli-backend/v1';
import { DialogModule } from 'primeng/dialog';
Expand All @@ -15,10 +15,6 @@ import { APP_IDENTITY } from './app/app-identity';
import { definePreset } from '@primeuix/themes';
import Aura from '@primeng/themes/aura';

const initAppFn = (envService: EnvironmentService) => {
return () => envService.loadEnvConfig("/assets/config/envvars.json");
};

const MyPreset = definePreset(Aura, {
semantic: {
colorScheme: {
Expand All @@ -38,10 +34,8 @@ const MyPreset = definePreset(Aura, {
bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(
MatomoModule.forRoot({
siteId: APP_IDENTITY.matomoSiteId,
trackerUrl: 'https://matomo.mmli2.ncsa.illinois.edu/'
}),
// configured once envvars.json has loaded, below
MatomoModule.forRoot({ mode: 'deferred' }),
MatomoRouterModule.forRoot(),
MenuModule,
ApiModule.forRoot(() => new Configuration()),
Expand All @@ -50,9 +44,28 @@ bootstrapApplication(AppComponent, {
AppRoutingModule,
),
EnvironmentService,
provideAppInitializer(() => {
const initializerFn = (initAppFn)(inject(EnvironmentService));
return initializerFn();
provideAppInitializer(async () => {
const envService = inject(EnvironmentService);
const matomo = inject(MatomoInitializerService);
const tracker = inject(MatomoTracker);
await envService.loadEnvConfig("/assets/config/envvars.json");

if (envService.getEnvConfig().matomoMode === 'proxied') {
// Through this app's own nginx (locations written by entrypoint.sh), which ad
// blockers don't recognize, and without cookies, so no consent banner is needed.
tracker.disableCookies();
matomo.initializeTracker({
siteId: APP_IDENTITY.matomoSiteId,
trackerUrl: '/px/',
trackerUrlSuffix: 'h',
scriptUrl: '/px/s.js',
});
} else {
matomo.initializeTracker({
siteId: APP_IDENTITY.matomoSiteId,
trackerUrl: 'https://matomo.mmli2.ncsa.illinois.edu/',
});
}
}),
provideHttpClient(withInterceptorsFromDi()),
provideStore(),
Expand Down
Loading