@networkpro/web 1.6.1 → 1.6.3
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/README.md +1 -1
- package/cspell.json +2 -1
- package/netlify.toml +1 -0
- package/package.json +3 -2
- package/src/hooks.server.js +15 -14
- package/src/lib/components/PostHog.svelte +24 -0
- package/src/lib/pages/AboutContent.svelte +1 -1
- package/src/routes/+layout.js +2 -0
- package/src/routes/+layout.svelte +13 -2
- package/src/service-worker.js +5 -2
- package/tests/e2e/app.spec.js +24 -0
- package/tests/e2e/mobile.spec.js +14 -0
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ All infrastructure and data flows are designed with **maximum transparency, self
|
|
|
33
33
|
├── .github/workflows # CI workflows and automation
|
|
34
34
|
├── .vscode/ # Recommended VS Code settings, extensions
|
|
35
35
|
├── netlify-functions/
|
|
36
|
-
│ └── cspReport.js
|
|
36
|
+
│ └── cspReport.js # Serverless function to receive and log CSP violation reports
|
|
37
37
|
├── scripts/ # Utility scripts
|
|
38
38
|
├── src/
|
|
39
39
|
│ ├── lib/ # Reusable components, styles, utilities
|
package/cspell.json
CHANGED
package/netlify.toml
CHANGED
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"./.netlify/shims.js"
|
|
6
6
|
],
|
|
7
|
-
"version": "1.6.
|
|
7
|
+
"version": "1.6.3",
|
|
8
8
|
"description": "Locking Down Networks, Unlocking Confidence | Security, Networking, Privacy — Network Pro Strategies",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"advisory",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"nodemailer": "^7.0.3",
|
|
81
|
-
"
|
|
81
|
+
"posthog-js": "^1.246.0",
|
|
82
82
|
"semver": "^7.7.2",
|
|
83
83
|
"svelte": "5.33.2"
|
|
84
84
|
},
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
"markdownlint-cli2": "^0.18.1",
|
|
107
107
|
"mdsvex": "^0.12.6",
|
|
108
108
|
"normalize.css": "^8.0.1",
|
|
109
|
+
"playwright": "^1.52.0",
|
|
109
110
|
"postcss": "^8.5.3",
|
|
110
111
|
"prettier": "^3.5.3",
|
|
111
112
|
"prettier-plugin-svelte": "^3.4.0",
|
package/src/hooks.server.js
CHANGED
|
@@ -14,6 +14,8 @@ export async function handle({ event, resolve }) {
|
|
|
14
14
|
// Create the response
|
|
15
15
|
const response = await resolve(event);
|
|
16
16
|
|
|
17
|
+
console.log("ENV_MODE:", process.env.ENV_MODE);
|
|
18
|
+
|
|
17
19
|
// Check if the environment is for testing
|
|
18
20
|
const isTestEnvironment =
|
|
19
21
|
process.env.NODE_ENV === "test" || process.env.ENV_MODE === "ci";
|
|
@@ -43,18 +45,19 @@ export async function handle({ event, resolve }) {
|
|
|
43
45
|
response.headers.set(
|
|
44
46
|
"Content-Security-Policy",
|
|
45
47
|
[
|
|
46
|
-
"default-src 'self';",
|
|
47
|
-
"script-src 'self' 'unsafe-inline';", // Allow
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
48
|
+
"default-src 'self';",
|
|
49
|
+
"script-src 'self' 'unsafe-inline' https://us.i.posthog.com https://us-assets.i.posthog.com;", // Allow PostHog's script from both sources
|
|
50
|
+
"script-src-elem 'self' 'unsafe-inline' https://us.i.posthog.com https://us-assets.i.posthog.com;", // Allow inline scripts from PostHog's sources
|
|
51
|
+
"style-src 'self' 'unsafe-inline';",
|
|
52
|
+
"img-src 'self' data:;",
|
|
53
|
+
"connect-src 'self' https://us.i.posthog.com https://us-assets.i.posthog.com;", // Allow connections to both PostHog sources
|
|
54
|
+
"font-src 'self' data:;",
|
|
55
|
+
"form-action 'self';",
|
|
56
|
+
"base-uri 'self';",
|
|
57
|
+
"object-src 'none';",
|
|
58
|
+
"frame-ancestors 'none';",
|
|
59
|
+
"upgrade-insecure-requests;",
|
|
60
|
+
`report-uri ${process.env.ENV_MODE === "prod" ? "/.netlify/functions/cspReport" : "/api/mock-csp"};`,
|
|
58
61
|
].join(" "),
|
|
59
62
|
);
|
|
60
63
|
}
|
|
@@ -94,5 +97,3 @@ export async function handle({ event, resolve }) {
|
|
|
94
97
|
|
|
95
98
|
return response;
|
|
96
99
|
}
|
|
97
|
-
|
|
98
|
-
// cspell:ignore licdn
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- ==========================================================================
|
|
2
|
+
src/lib/components/PostHog.svelte
|
|
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
|
+
<script>
|
|
10
|
+
import posthog from "posthog-js";
|
|
11
|
+
import { onMount } from "svelte";
|
|
12
|
+
import { browser } from "$app/environment";
|
|
13
|
+
|
|
14
|
+
// cspell:disable
|
|
15
|
+
onMount(() => {
|
|
16
|
+
if (browser) {
|
|
17
|
+
posthog.init("phc_Qshfo6AXzh4pS7aPigfqyeo4qj1qlyh7gDuHDeVMSR0", {
|
|
18
|
+
api_host: "https://us.i.posthog.com",
|
|
19
|
+
person_profiles: "identified_only",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
//cspell:enable
|
|
24
|
+
</script>
|
package/src/routes/+layout.js
CHANGED
|
@@ -25,6 +25,10 @@ This file is part of Network Pro.
|
|
|
25
25
|
import faviconSvg from "$lib/img/favicon.svg";
|
|
26
26
|
import appleTouchIcon from "$lib/img/icon-180x180.png";
|
|
27
27
|
|
|
28
|
+
// Declare PostHog as null initially
|
|
29
|
+
/** @type {typeof import('$lib/components/PostHog.svelte').default | null} */
|
|
30
|
+
let PostHog = null;
|
|
31
|
+
|
|
28
32
|
if (browser) {
|
|
29
33
|
// Preload logo images
|
|
30
34
|
[logoPng, logoWbp].forEach((src) => {
|
|
@@ -40,6 +44,11 @@ This file is part of Network Pro.
|
|
|
40
44
|
onMount(() => {
|
|
41
45
|
console.log("[APP] onMount triggered in +layout.svelte");
|
|
42
46
|
registerServiceWorker();
|
|
47
|
+
|
|
48
|
+
// Dynamically import PostHog component only in the browser
|
|
49
|
+
import("$lib/components/PostHog.svelte").then((module) => {
|
|
50
|
+
PostHog = module.default;
|
|
51
|
+
});
|
|
43
52
|
});
|
|
44
53
|
}
|
|
45
54
|
|
|
@@ -49,8 +58,6 @@ This file is part of Network Pro.
|
|
|
49
58
|
const metaDescription =
|
|
50
59
|
data?.meta?.description ||
|
|
51
60
|
"Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro™";
|
|
52
|
-
|
|
53
|
-
// Pathname normalization takes place in +layout.js
|
|
54
61
|
</script>
|
|
55
62
|
|
|
56
63
|
<svelte:head>
|
|
@@ -83,6 +90,10 @@ This file is part of Network Pro.
|
|
|
83
90
|
</header>
|
|
84
91
|
<!-- END HEADER -->
|
|
85
92
|
|
|
93
|
+
{#if PostHog}
|
|
94
|
+
<PostHog /> <!-- Add PostHog component when it's loaded -->
|
|
95
|
+
{/if}
|
|
96
|
+
|
|
86
97
|
<main>
|
|
87
98
|
<slot />
|
|
88
99
|
</main>
|
package/src/service-worker.js
CHANGED
|
@@ -12,7 +12,10 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
|
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
const isDev = location.hostname === "localhost";
|
|
15
|
-
const disallowedHosts = [
|
|
15
|
+
const disallowedHosts = [
|
|
16
|
+
"us.i.posthog.com", // Add PostHog to disallowed hosts
|
|
17
|
+
"posthog.com", // Add PostHog to disallowed hosts
|
|
18
|
+
];
|
|
16
19
|
|
|
17
20
|
import { build, files, version } from "$service-worker";
|
|
18
21
|
|
|
@@ -25,8 +28,8 @@ const excludedAssets = [];
|
|
|
25
28
|
//TODO: Remove files in docs once migrated to documentation subsite
|
|
26
29
|
|
|
27
30
|
const IGNORE_PATHS = new Set([
|
|
28
|
-
"/docs/Home.md",
|
|
29
31
|
"/docs/extensions.md",
|
|
32
|
+
"/docs/Home.md",
|
|
30
33
|
"/img/banner-1280x640.png",
|
|
31
34
|
"/img/banner-og-1200x630.png",
|
|
32
35
|
"/img/logo-transparent.png",
|
package/tests/e2e/app.spec.js
CHANGED
|
@@ -19,6 +19,10 @@ test.describe("Desktop Tests", () => {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
22
|
+
|
|
23
|
+
// Add a small timeout before navigating to the page
|
|
24
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
25
|
+
|
|
22
26
|
await page.goto("/");
|
|
23
27
|
|
|
24
28
|
// Wait for the page to fully load
|
|
@@ -33,6 +37,10 @@ test.describe("Desktop Tests", () => {
|
|
|
33
37
|
page,
|
|
34
38
|
}) => {
|
|
35
39
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
40
|
+
|
|
41
|
+
// Add a small timeout before navigating to the page
|
|
42
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
43
|
+
|
|
36
44
|
await page.goto("/");
|
|
37
45
|
|
|
38
46
|
// Ensure the navigation bar is visible
|
|
@@ -48,6 +56,10 @@ test.describe("Desktop Tests", () => {
|
|
|
48
56
|
// Simplified Footer Visibility Test
|
|
49
57
|
test("should display the footer correctly", async ({ page }) => {
|
|
50
58
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
59
|
+
|
|
60
|
+
// Add a small timeout before navigating to the page
|
|
61
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
62
|
+
|
|
51
63
|
await page.goto("/");
|
|
52
64
|
|
|
53
65
|
// Check that the footer is visible
|
|
@@ -58,6 +70,10 @@ test.describe("Desktop Tests", () => {
|
|
|
58
70
|
// Simplified Test for Clickable Links (e.g., 'about' link)
|
|
59
71
|
test("should ensure the 'about' link is clickable", async ({ page }) => {
|
|
60
72
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
73
|
+
|
|
74
|
+
// Add a small timeout before navigating to the page
|
|
75
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
76
|
+
|
|
61
77
|
await page.goto("/");
|
|
62
78
|
|
|
63
79
|
// Ensure the "about" link is visible and clickable
|
|
@@ -84,6 +100,10 @@ test.describe("Mobile Tests", () => {
|
|
|
84
100
|
}
|
|
85
101
|
|
|
86
102
|
await page.setViewportSize({ width: 375, height: 667 }); // Mobile size (e.g., iPhone 6)
|
|
103
|
+
|
|
104
|
+
// Add a small timeout before navigating to the page
|
|
105
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
106
|
+
|
|
87
107
|
await page.goto("/");
|
|
88
108
|
|
|
89
109
|
// Wait for the page to fully load
|
|
@@ -96,6 +116,10 @@ test.describe("Mobile Tests", () => {
|
|
|
96
116
|
// Simplified Test for mobile content visibility
|
|
97
117
|
test("should display main content correctly on mobile", async ({ page }) => {
|
|
98
118
|
await page.setViewportSize({ width: 375, height: 667 }); // Mobile size
|
|
119
|
+
|
|
120
|
+
// Add a small timeout before navigating to the page
|
|
121
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
122
|
+
|
|
99
123
|
await page.goto("/");
|
|
100
124
|
|
|
101
125
|
// Check that the main heading is visible on mobile
|
package/tests/e2e/mobile.spec.js
CHANGED
|
@@ -19,6 +19,10 @@ test.describe("Mobile Tests", () => {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
await page.setViewportSize({ width: 375, height: 667 }); // Mobile size (e.g., iPhone 6)
|
|
22
|
+
|
|
23
|
+
// Add a small timeout before navigating to the page
|
|
24
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
25
|
+
|
|
22
26
|
await page.goto("/");
|
|
23
27
|
|
|
24
28
|
// Wait for the page to load and for the title element to be available
|
|
@@ -44,6 +48,10 @@ test.describe("Mobile Tests", () => {
|
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
await page.setViewportSize({ width: 375, height: 667 }); // Mobile size
|
|
51
|
+
|
|
52
|
+
// Add a small timeout before navigating to the page
|
|
53
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
54
|
+
|
|
47
55
|
await page.goto("/");
|
|
48
56
|
|
|
49
57
|
// Wait for the page to load
|
|
@@ -63,6 +71,10 @@ test.describe("Mobile Tests", () => {
|
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
await page.setViewportSize({ width: 375, height: 667 }); // Mobile size
|
|
74
|
+
|
|
75
|
+
// Add a small timeout before navigating to the page
|
|
76
|
+
await page.waitForTimeout(1500); // Wait for 1.5 seconds
|
|
77
|
+
|
|
66
78
|
await page.goto("/");
|
|
67
79
|
|
|
68
80
|
// Wait for the page to load
|
|
@@ -77,3 +89,5 @@ test.describe("Mobile Tests", () => {
|
|
|
77
89
|
await expect(page).toHaveURL(/\/about/);
|
|
78
90
|
});
|
|
79
91
|
});
|
|
92
|
+
|
|
93
|
+
// cspell:ignore domcontentloaded
|