@networkpro/web 1.24.4 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/branch-guard.yml +53 -0
- package/CHANGELOG.md +106 -2
- package/cspell.json +1 -0
- package/package.json +13 -5
- package/src/hooks.server.js +38 -44
- package/src/lib/stores/posthog.js +22 -5
- package/src/lib/utils/env.js +74 -0
- package/src/service-worker.js +2 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# .github/workflows/branch-guard.yml
|
|
2
|
+
#
|
|
3
|
+
# Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
4
|
+
# SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
# This file is part of Network Pro
|
|
6
|
+
#
|
|
7
|
+
# Warns if commits are pushed directly to master/main instead of via PR.
|
|
8
|
+
# Does NOT block the commit — it just posts a workflow summary and log warning.
|
|
9
|
+
|
|
10
|
+
name: Branch Guard
|
|
11
|
+
|
|
12
|
+
on:
|
|
13
|
+
push:
|
|
14
|
+
branches:
|
|
15
|
+
- master
|
|
16
|
+
- main
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
warn-direct-commit:
|
|
23
|
+
runs-on: ubuntu-24.04
|
|
24
|
+
steps:
|
|
25
|
+
- name: Check commit source
|
|
26
|
+
run: |
|
|
27
|
+
commit_msg="${{ github.event.head_commit.message }}"
|
|
28
|
+
actor="${{ github.actor }}"
|
|
29
|
+
branch="${GITHUB_REF##*/}"
|
|
30
|
+
|
|
31
|
+
echo "📝 Commit message: $commit_msg"
|
|
32
|
+
echo "👤 Actor: $actor"
|
|
33
|
+
echo "🌿 Branch: $branch"
|
|
34
|
+
|
|
35
|
+
# Define known safe patterns (merge or bot commits)
|
|
36
|
+
if echo "$commit_msg" | grep -Eq "Merge pull request|See merge request|Merge branch|(#\d+)$"; then
|
|
37
|
+
echo "✅ Merge-related commit detected — no warning."
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
if [[ "$actor" == "dependabot[bot]" ]] || [[ "$actor" == "renovate[bot]" ]] || [[ "$actor" == "github-actions[bot]" ]]; then
|
|
42
|
+
echo "🤖 Bot commit detected — skipping warning."
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Otherwise, warn for direct commits
|
|
47
|
+
echo "::warning ::⚠️ Direct commit to $branch by $actor."
|
|
48
|
+
{
|
|
49
|
+
echo "### ⚠️ Direct Commit Detected"
|
|
50
|
+
echo "A commit was pushed directly to \`$branch\` by **$actor**."
|
|
51
|
+
echo ""
|
|
52
|
+
echo "💡 It's recommended to use pull requests for traceability and CI validation."
|
|
53
|
+
} >> $GITHUB_STEP_SUMMARY
|
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,108 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## [1.25.0]
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Introduced unified environment detection utility (`src/lib/utils/env.js`) with full **JSDoc typing**.
|
|
30
|
+
- Normalizes `process.env` and `import.meta.env` usage across SSR (Node) and client contexts.
|
|
31
|
+
- Safely handles browser environments where `process` is undefined.
|
|
32
|
+
- Provides standardized flags for:
|
|
33
|
+
- `isDev`, `isProd`, `isAudit`, `isCI`, and `isTest`
|
|
34
|
+
- Enables consistent environment checks across analytics, CSP, and runtime logic.
|
|
35
|
+
|
|
36
|
+
- Added hybrid **environment + host-based analytics guard** in `src/lib/stores/posthog.js`.
|
|
37
|
+
- Automatically disables PostHog tracking in `audit` mode or when hostname matches `*.audit.netwk.pro`.
|
|
38
|
+
- Prevents analytics initialization during development and test contexts.
|
|
39
|
+
- Uses the shared `detectEnvironment()` utility for centralized logic.
|
|
40
|
+
- Improves runtime logging for environment-specific behavior.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Updated `hooks.server.js` to include a dedicated **audit environment block** for Content Security Policy (CSP).
|
|
45
|
+
- Hardened audit CSP by removing all analytics-related sources (`posthog.com`, `posthog-assets.com`).
|
|
46
|
+
- Redirects CSP violation reporting to the mock endpoint (`/api/mock-csp`) in audit mode.
|
|
47
|
+
- Preserves full HSTS and other production security headers for audit deployments.
|
|
48
|
+
- Added clear separation between `test`, `audit`, and `prod` security policies.
|
|
49
|
+
- Improved console debugging for environment detection (`NODE_ENV`, `ENV_MODE`).
|
|
50
|
+
|
|
51
|
+
- Refactored **environment detection logic** for improved reliability across client and server contexts.
|
|
52
|
+
- Added unified environment resolver at `src/lib/utils/env.js` to standardize detection for `dev`, `prod`, `audit`, `ci`, and `test` modes.
|
|
53
|
+
- Ensures consistent handling of both `process.env.*` (Node/SSR) and `import.meta.env.*` (Vite/client) variables.
|
|
54
|
+
- Prevents mismatched behavior between browser-side analytics (`posthog.js`) and server-side policies (`hooks.server.js`).
|
|
55
|
+
- Automatically falls back to `'unknown'` if no explicit mode is set, avoiding build-time exceptions.
|
|
56
|
+
|
|
57
|
+
- Refactored **Branch Guard** workflow (`.github/workflows/branch-guard.yml`) for improved accuracy and reduced noise.
|
|
58
|
+
- Adjusted detection logic to **ignore merge commits**, Dependabot updates, and automated actions.
|
|
59
|
+
- Ensures workflow warnings are shown **only for true direct commits** to protected branches (`master`, `main`).
|
|
60
|
+
- Simplified step output and summary formatting for clearer reporting in the Actions log and job summary.
|
|
61
|
+
- Maintains lightweight permissions (`contents: read`) and executes entirely without repository writes.
|
|
62
|
+
- Improves reliability of branch protection monitoring without affecting CI or merge operations.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- Resolved client-side crash in browser environments caused by `process.env` being undefined.
|
|
67
|
+
- Implemented defensive checks in `env.js` for `process` availability.
|
|
68
|
+
- Eliminated reference errors during client-side initialization of analytics.
|
|
69
|
+
|
|
70
|
+
### Developer Experience
|
|
71
|
+
|
|
72
|
+
- Simplified future configuration by consolidating environment checks into a single typed utility.
|
|
73
|
+
- Improved maintainability and Vercel compatibility by ensuring `.env.audit` and `PUBLIC_ENV_MODE` variables propagate correctly to both client and server environments.
|
|
74
|
+
|
|
75
|
+
### Developer Notes
|
|
76
|
+
|
|
77
|
+
- When deploying audit builds, ensure Vercel environment variables include:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
ENV_MODE=audit
|
|
81
|
+
PUBLIC_ENV_MODE=audit
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This enables analytics filtering and CSP hardening for the audit environment.
|
|
85
|
+
|
|
86
|
+
- Audit deployments retain full HTTPS and security headers but omit telemetry and external CSP reporting.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## [1.24.5]
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- Introduced **Branch Guard workflow** (`.github/workflows/branch-guard.yml`) to automatically enforce branch protection policies.
|
|
95
|
+
- Ensures consistent branch naming conventions.
|
|
96
|
+
- Blocks direct pushes to protected branches (e.g., `master`, `main`, and `release/*`).
|
|
97
|
+
- Provides early validation for pull requests and feature branches to maintain repository integrity.
|
|
98
|
+
- Introduced comprehensive pre-push checks for code consistency and style compliance.
|
|
99
|
+
- Added optional `simple-git-hooks` configuration to automate local linting before commits or pushes.
|
|
100
|
+
- Implemented `lint:all` script using `npm-run-all` for efficient, parallel execution of linters.
|
|
101
|
+
- Ensures **ESLint**, **Stylelint**, **Markdownlint**, and **Prettier** all run before code is committed, improving codebase hygiene and preventing formatting drift.
|
|
102
|
+
- Designed for **developer-side speed and reliability**, running linters in parallel while deferring `format` (Prettier) until after lint checks complete for safety.
|
|
103
|
+
- Added **hybrid linting configuration**:
|
|
104
|
+
- Parallel execution for static lint tasks (`eslint`, `stylelint`, `markdownlint`).
|
|
105
|
+
- Sequential Prettier formatting step for deterministic, race-free execution.
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
- Reorganized local linting commands for clarity and consistency, consolidating redundant sequential scripts into the `lint:all` aggregator.
|
|
110
|
+
- Improved developer experience with faster pre-push validations and clearer script naming conventions.
|
|
111
|
+
- Bumped project version to `v1.24.5`.
|
|
112
|
+
|
|
113
|
+
### Developer Experience
|
|
114
|
+
|
|
115
|
+
- Enhanced local development workflow by introducing **fast, parallel linting** and **optional pre-commit hooks**, reducing turnaround time for style and quality checks.
|
|
116
|
+
- Simplified npm scripts for readability and maintainability by adopting `npm-run-all` as the central task runner.
|
|
117
|
+
|
|
118
|
+
### Notes
|
|
119
|
+
|
|
120
|
+
- For instructions on installing and configuring the new dependencies, please see the **[Editor Configuration](https://github.com/netwk-pro/netwk-pro.github.io/wiki/Editor-Configuration#automation)** section of the [Wiki](https://github.com/netwk-pro/netwk-pro.github.io/wiki).
|
|
121
|
+
|
|
122
|
+
> **Note:** Version `1.24.4` was merged but not tagged or released.
|
|
123
|
+
> Subsequent updates are reflected in `v1.24.5` and later.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
25
127
|
## [1.24.4]
|
|
26
128
|
|
|
27
129
|
### Documentation
|
|
@@ -250,7 +352,7 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
250
352
|
- Updated the text of `ServicesContent.svelte`.
|
|
251
353
|
- Increased default Playwright test timeouts for navigation-sensitive suites (Desktop and Mobile) to improve stability under CI latency conditions.
|
|
252
354
|
- Implemented `Promise.all()` pattern for combined click and navigation waits, reducing flakiness in route transition tests.
|
|
253
|
-
- Updated the `
|
|
355
|
+
- Updated the `about` link navigation tests in both Desktop and Mobile scenarios to include:
|
|
254
356
|
- Explicit `page.waitForLoadState('domcontentloaded')` calls before assertions.
|
|
255
357
|
- Extended per-suite timeouts (`90s`) using `test.setTimeout(90000)` for reliability on slower environments.
|
|
256
358
|
- Added fallback `waitForURL('\*\*/about', { timeout: 60000 })` to ensure deterministic routing checks.
|
|
@@ -1481,7 +1583,9 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
1481
1583
|
|
|
1482
1584
|
<!-- Link references -->
|
|
1483
1585
|
|
|
1484
|
-
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.
|
|
1586
|
+
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.0...HEAD
|
|
1587
|
+
[1.25.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.0
|
|
1588
|
+
[1.24.5]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.24.5
|
|
1485
1589
|
[1.24.4]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.24.4
|
|
1486
1590
|
[1.24.3]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.24.3
|
|
1487
1591
|
[1.24.2]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.24.2
|
package/cspell.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@networkpro/web",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.25.0",
|
|
5
5
|
"description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"advisory",
|
|
@@ -35,22 +35,24 @@
|
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"dev": "vite dev",
|
|
38
|
+
"dev:audit": "vite --mode audit",
|
|
38
39
|
"start": "npm run dev",
|
|
39
40
|
"dev:vercel": "vercel dev",
|
|
40
41
|
"build": "vite build",
|
|
42
|
+
"build:audit": "vite build --mode audit",
|
|
41
43
|
"build:vercel": "vercel build",
|
|
42
44
|
"preview": "vite preview",
|
|
43
45
|
"css:bundle": "node scripts/bundleCss.js",
|
|
44
|
-
"prepare": "svelte-kit sync || echo ''",
|
|
46
|
+
"prepare": "svelte-kit sync && npx simple-git-hooks || echo ''",
|
|
45
47
|
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
|
46
48
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
|
47
49
|
"type-check": "svelte-check --tsconfig ./jsconfig.json",
|
|
48
50
|
"lint:types": "npm run type-check",
|
|
49
51
|
"check:env": "node scripts/checkEnv.js",
|
|
50
52
|
"check:node": "node scripts/checkNode.js",
|
|
51
|
-
"checkout": "npm
|
|
53
|
+
"checkout": "npm-run-all check:node test:all lint:all check",
|
|
52
54
|
"verify": "npm run checkout",
|
|
53
|
-
"delete": "rm -rf
|
|
55
|
+
"delete": "rm -rf .svelte-kit node_modules package-lock.json",
|
|
54
56
|
"clean": "npm run delete && npm cache clean --force && npm install",
|
|
55
57
|
"upgrade": "ncu -u --format group --color",
|
|
56
58
|
"check:updates": "ncu --format group --color",
|
|
@@ -69,14 +71,18 @@
|
|
|
69
71
|
"lint:jsdoc": "eslint . --ext .js,.cjs,.mjs,.svelte --max-warnings=0",
|
|
70
72
|
"lint:css": "stylelint \"**/*.{css,svelte}\" --ignore-path .stylelintignore",
|
|
71
73
|
"lint:md": "npx markdownlint-cli2 \"**/*.{md,markdown}\" \"#node_modules/**\" \"#playwright-report/**\" \"#test-results/**\"",
|
|
72
|
-
"lint:all": "npm run lint && npm run lint:md && npm run lint:css && npm run format",
|
|
73
74
|
"format": "prettier --check .",
|
|
74
75
|
"format:fix": "prettier --write .",
|
|
76
|
+
"lint:all": "npm-run-all --parallel --print-label lint lint:md lint:css --sequential format",
|
|
75
77
|
"lhci": "lhci",
|
|
76
78
|
"lhci:run": "lhci autorun --config=.lighthouserc.cjs",
|
|
77
79
|
"audit:coverage": "vitest run tests/internal/auditCoverage.test.js",
|
|
78
80
|
"postinstall": "npm run check:node"
|
|
79
81
|
},
|
|
82
|
+
"simple-git-hooks": {
|
|
83
|
+
"pre-commit": "if [ \"$CI\" = \"true\" ]; then exit 0; else npm run lint:all; fi",
|
|
84
|
+
"pre-push": "if [ \"$CI\" = \"true\" ]; then exit 0; else npm run checkout; fi"
|
|
85
|
+
},
|
|
80
86
|
"dependencies": {
|
|
81
87
|
"dompurify": "^3.3.0",
|
|
82
88
|
"posthog-js": "^1.284.0",
|
|
@@ -105,10 +111,12 @@
|
|
|
105
111
|
"lightningcss": "^1.30.2",
|
|
106
112
|
"markdownlint": "^0.39.0",
|
|
107
113
|
"markdownlint-cli2": "^0.18.1",
|
|
114
|
+
"npm-run-all": "^4.1.5",
|
|
108
115
|
"playwright": "^1.56.1",
|
|
109
116
|
"postcss": "^8.5.6",
|
|
110
117
|
"prettier": "3.6.2",
|
|
111
118
|
"prettier-plugin-svelte": "^3.4.0",
|
|
119
|
+
"simple-git-hooks": "^2.13.1",
|
|
112
120
|
"stylelint": "^16.25.0",
|
|
113
121
|
"stylelint-config-html": "^1.1.0",
|
|
114
122
|
"stylelint-config-recommended": "^17.0.0",
|
package/src/hooks.server.js
CHANGED
|
@@ -6,33 +6,25 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
|
6
6
|
This file is part of Network Pro.
|
|
7
7
|
========================================================================== */
|
|
8
8
|
|
|
9
|
+
import { detectEnvironment } from '$lib/utils/env.js';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* SvelteKit server hook to set Content Security Policy (CSP) header.
|
|
11
13
|
* @type {import('@sveltejs/kit').Handle}
|
|
12
14
|
*/
|
|
13
15
|
export async function handle({ event, resolve }) {
|
|
14
|
-
// Create the response
|
|
15
16
|
const response = await resolve(event);
|
|
17
|
+
const { isAudit, isTest, isProd } = detectEnvironment();
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
// Default to development policy if neither test nor prod
|
|
19
|
-
const isTestEnvironment =
|
|
20
|
-
process.env.NODE_ENV === 'development' ||
|
|
21
|
-
process.env.ENV_MODE === 'dev' ||
|
|
22
|
-
process.env.ENV_MODE === 'ci';
|
|
23
|
-
const isProdEnvironment =
|
|
24
|
-
process.env.NODE_ENV === 'production' || process.env.ENV_MODE === 'prod';
|
|
25
|
-
|
|
26
|
-
console.log('[CSP Debug] NODE_ENV:', process.env.NODE_ENV);
|
|
27
|
-
console.log('[CSP Debug] ENV_MODE:', process.env.ENV_MODE);
|
|
19
|
+
console.log('[CSP Debug ENV]', detectEnvironment());
|
|
28
20
|
|
|
29
21
|
// Determine report URI
|
|
30
22
|
const reportUri =
|
|
31
|
-
|
|
23
|
+
isProd && !isTest && !isAudit
|
|
32
24
|
? 'https://csp.netwk.pro/.netlify/functions/csp-report'
|
|
33
25
|
: '/api/mock-csp';
|
|
34
26
|
|
|
35
|
-
//
|
|
27
|
+
// Base hardened policy
|
|
36
28
|
const cspDirectives = [
|
|
37
29
|
"default-src 'self';",
|
|
38
30
|
"script-src 'self' 'unsafe-inline' https://us.i.posthog.com https://us-assets.i.posthog.com;",
|
|
@@ -45,40 +37,45 @@ export async function handle({ event, resolve }) {
|
|
|
45
37
|
"object-src 'none';",
|
|
46
38
|
"frame-ancestors 'none';",
|
|
47
39
|
'upgrade-insecure-requests;',
|
|
48
|
-
// Report CSP violations to external endpoint hosted at csp.netwk.pro
|
|
49
|
-
`report-uri ${reportUri};`,
|
|
50
|
-
'report-to csp-endpoint;',
|
|
51
40
|
];
|
|
52
41
|
|
|
53
|
-
//
|
|
54
|
-
if (
|
|
42
|
+
// 🧪 Looser CSP for local/CI test environments
|
|
43
|
+
if (isTest) {
|
|
55
44
|
cspDirectives[1] =
|
|
56
45
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:* ws://localhost:*;";
|
|
57
|
-
cspDirectives[2] =
|
|
58
|
-
|
|
59
|
-
cspDirectives[
|
|
60
|
-
cspDirectives[4] = "img-src 'self' data: http://localhost:*;";
|
|
61
|
-
cspDirectives[5] =
|
|
46
|
+
cspDirectives[2] = "style-src 'self' 'unsafe-inline' http://localhost:*;";
|
|
47
|
+
cspDirectives[3] = "img-src 'self' data: http://localhost:*;";
|
|
48
|
+
cspDirectives[4] =
|
|
62
49
|
"connect-src 'self' http://localhost:* ws://localhost:* https://us.i.posthog.com https://us-assets.i.posthog.com;";
|
|
63
50
|
}
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}),
|
|
77
|
-
);
|
|
52
|
+
// 🧩 Hardened CSP for audit environment — no analytics, no CSP reporting
|
|
53
|
+
if (isAudit) {
|
|
54
|
+
cspDirectives[1] = "script-src 'self' 'unsafe-inline';";
|
|
55
|
+
cspDirectives[2] = "style-src 'self' 'unsafe-inline';";
|
|
56
|
+
cspDirectives[3] = "img-src 'self' data:;";
|
|
57
|
+
cspDirectives[4] = "connect-src 'self';";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 📋 Attach CSP report directives ONLY in production
|
|
61
|
+
if (isProd && !isAudit && !isTest) {
|
|
62
|
+
cspDirectives.push(`report-uri ${reportUri};`, 'report-to csp-endpoint;');
|
|
78
63
|
|
|
64
|
+
response.headers.set(
|
|
65
|
+
'Report-To',
|
|
66
|
+
JSON.stringify({
|
|
67
|
+
group: 'csp-endpoint',
|
|
68
|
+
max_age: 10886400, // 18 weeks
|
|
69
|
+
endpoints: [{ url: reportUri }],
|
|
70
|
+
include_subdomains: true,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ✅ Apply final CSP
|
|
79
76
|
response.headers.set('Content-Security-Policy', cspDirectives.join(' '));
|
|
80
77
|
|
|
81
|
-
//
|
|
78
|
+
// Standard security headers
|
|
82
79
|
response.headers.set(
|
|
83
80
|
'Permissions-Policy',
|
|
84
81
|
[
|
|
@@ -103,10 +100,10 @@ export async function handle({ event, resolve }) {
|
|
|
103
100
|
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
104
101
|
response.headers.set('X-Frame-Options', 'DENY');
|
|
105
102
|
|
|
106
|
-
if (
|
|
103
|
+
if (!isTest) {
|
|
107
104
|
response.headers.set(
|
|
108
105
|
'Strict-Transport-Security',
|
|
109
|
-
'max-age=31536000; includeSubDomains;',
|
|
106
|
+
'max-age=31536000; includeSubDomains;',
|
|
110
107
|
);
|
|
111
108
|
}
|
|
112
109
|
|
|
@@ -120,8 +117,5 @@ export async function handle({ event, resolve }) {
|
|
|
120
117
|
export function handleError({ error, event }) {
|
|
121
118
|
console.error('🔴 SSR Error in route:', event.url.pathname);
|
|
122
119
|
console.error(error);
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
message: 'A server-side error occurred',
|
|
126
|
-
};
|
|
120
|
+
return { message: 'A server-side error occurred' };
|
|
127
121
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
remindUserToReconsent,
|
|
16
16
|
trackingPreferences,
|
|
17
17
|
} from '$lib/stores/trackingPreferences.js';
|
|
18
|
+
import { detectEnvironment } from '$lib/utils/env.js';
|
|
18
19
|
import { get, writable } from 'svelte/store';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -38,24 +39,39 @@ let ph = null;
|
|
|
38
39
|
/**
|
|
39
40
|
* Initializes the PostHog analytics client if tracking is permitted.
|
|
40
41
|
* Uses dynamic import to avoid SSR failures.
|
|
42
|
+
*
|
|
41
43
|
* @returns {Promise<void>}
|
|
42
44
|
*/
|
|
43
45
|
export async function initPostHog() {
|
|
44
46
|
if (initialized || typeof window === 'undefined') return;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
const { isAudit, isDev, isTest, mode } = detectEnvironment();
|
|
49
|
+
|
|
50
|
+
// 🌐 Hybrid hostname + environment guard
|
|
51
|
+
const host = window.location.hostname;
|
|
52
|
+
const isAuditHost = /(^|\.)audit\.netwk\.pro$/i.test(host);
|
|
53
|
+
const effectiveAudit = isAudit || isAuditHost;
|
|
54
|
+
|
|
55
|
+
if (effectiveAudit) {
|
|
56
|
+
console.info(`[PostHog] Skipping analytics (${mode} mode, host: ${host}).`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 🧱 Skip entirely in dev/test contexts
|
|
61
|
+
if (isDev || isTest) {
|
|
62
|
+
console.info('[PostHog] Skipping init in dev/test mode.');
|
|
48
63
|
return;
|
|
49
64
|
}
|
|
50
65
|
|
|
66
|
+
// 🚀 Production analytics logic (with user consent)
|
|
51
67
|
initialized = true;
|
|
52
68
|
|
|
53
69
|
const { enabled } = get(trackingPreferences);
|
|
54
70
|
trackingEnabled.set(enabled);
|
|
55
|
-
showReminder.set(get(remindUserToReconsent));
|
|
71
|
+
showReminder.set(get(remindUserToReconsent));
|
|
56
72
|
|
|
57
73
|
if (!enabled) {
|
|
58
|
-
console.log('[PostHog] Tracking
|
|
74
|
+
console.log('[PostHog] Tracking disabled — user opted out.');
|
|
59
75
|
return;
|
|
60
76
|
}
|
|
61
77
|
|
|
@@ -63,6 +79,7 @@ export async function initPostHog() {
|
|
|
63
79
|
const posthogModule = await import('posthog-js');
|
|
64
80
|
ph = posthogModule.default;
|
|
65
81
|
|
|
82
|
+
// ✅ Initialize PostHog
|
|
66
83
|
// cspell:disable-next-line
|
|
67
84
|
ph.init('phc_Qshfo6AXzh4pS7aPigfqyeo4qj1qlyh7gDuHDeVMSR0', {
|
|
68
85
|
api_host: '/relay-MSR0/',
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
src/lib/utils/env.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @file env.js
|
|
11
|
+
* @description Unified environment detection utility.
|
|
12
|
+
* Normalizes process.env and import.meta.env for consistent behavior
|
|
13
|
+
* across SvelteKit server (SSR), client (browser), and build-time contexts.
|
|
14
|
+
*
|
|
15
|
+
* Supports: dev, prod, ci, test, audit.
|
|
16
|
+
*
|
|
17
|
+
* @module src/lib/utils
|
|
18
|
+
* @author Scott Lopez
|
|
19
|
+
* @updated 2025-11-02
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* import { detectEnvironment } from '$lib/utils/env.js';
|
|
23
|
+
* const { isAudit, isProd } = detectEnvironment();
|
|
24
|
+
* if (isAudit) console.log('Running in audit mode');
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {object} EnvironmentInfo
|
|
29
|
+
* @property {string} mode - The detected environment mode (`dev`, `prod`, `audit`, etc.).
|
|
30
|
+
* @property {boolean} isDev - True when running in a development or local environment.
|
|
31
|
+
* @property {boolean} isProd - True when running in production.
|
|
32
|
+
* @property {boolean} isAudit - True when running in audit / staging environments.
|
|
33
|
+
* @property {boolean} isCI - True when running in continuous integration (CI) pipelines.
|
|
34
|
+
* @property {boolean} isTest - True when running under test or mock environments.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Normalizes environment detection across client, SSR, and build contexts.
|
|
39
|
+
* Uses `import.meta.env` for Vite build-time vars and `process.env` for runtime vars.
|
|
40
|
+
*
|
|
41
|
+
* @returns {EnvironmentInfo} Normalized environment context flags.
|
|
42
|
+
*/
|
|
43
|
+
export function detectEnvironment() {
|
|
44
|
+
/** @type {string | undefined} */
|
|
45
|
+
const viteMode = import.meta.env?.MODE;
|
|
46
|
+
/** @type {string | undefined} */
|
|
47
|
+
const publicEnvMode = import.meta.env?.PUBLIC_ENV_MODE;
|
|
48
|
+
|
|
49
|
+
/** @type {string | undefined} */
|
|
50
|
+
const nodeEnv =
|
|
51
|
+
typeof process !== 'undefined' && process?.env?.NODE_ENV
|
|
52
|
+
? process.env.NODE_ENV
|
|
53
|
+
: undefined;
|
|
54
|
+
|
|
55
|
+
/** @type {string | undefined} */
|
|
56
|
+
const envMode =
|
|
57
|
+
typeof process !== 'undefined' && process?.env?.ENV_MODE
|
|
58
|
+
? process.env.ENV_MODE
|
|
59
|
+
: undefined;
|
|
60
|
+
|
|
61
|
+
// Fallback order — guarantees a mode string even if nothing is set
|
|
62
|
+
/** @type {string} */
|
|
63
|
+
const mode = envMode || publicEnvMode || viteMode || nodeEnv || 'unknown';
|
|
64
|
+
|
|
65
|
+
// Return a normalized, typed object
|
|
66
|
+
return {
|
|
67
|
+
mode,
|
|
68
|
+
isDev: ['development', 'dev'].includes(mode),
|
|
69
|
+
isProd: ['production', 'prod'].includes(mode),
|
|
70
|
+
isAudit: mode === 'audit',
|
|
71
|
+
isCI: mode === 'ci',
|
|
72
|
+
isTest: mode === 'test',
|
|
73
|
+
};
|
|
74
|
+
}
|
package/src/service-worker.js
CHANGED
|
@@ -38,10 +38,11 @@ const IGNORE_PATHS = new Set([
|
|
|
38
38
|
'/pgp/contact@s.neteng.pro.asc',
|
|
39
39
|
'/pgp/github@sl.neteng.cc.asc',
|
|
40
40
|
'/pgp/security@s.neteng.pro.asc',
|
|
41
|
-
'/pgp/support@
|
|
41
|
+
'/pgp/support@netwk.pro.asc',
|
|
42
42
|
'/screenshots/desktop-foss.png',
|
|
43
43
|
'/webfonts/fa-brands-400.ttf',
|
|
44
44
|
'/webfonts/fa-solid-900.ttf',
|
|
45
|
+
'/7cbb39ce-750b-43da-83b8-8980e5554d4d.txt',
|
|
45
46
|
'/robots.txt',
|
|
46
47
|
'/sitemap.xml',
|
|
47
48
|
'/CNAME',
|