@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 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 # Serverless function to receive and log CSP violation reports
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
@@ -20,7 +20,7 @@
20
20
  "Maricopa",
21
21
  "mdsvex",
22
22
  "neteng",
23
- "NETPRO",
23
+ "netpro",
24
24
  "netwk",
25
25
  "networkpro",
26
26
  "Nextcloud",
@@ -29,6 +29,7 @@
29
29
  "nosniff",
30
30
  "nosw",
31
31
  "obtainium",
32
+ "posthog",
32
33
  "SIEM",
33
34
  "stylelintignore",
34
35
  "Subsite",
package/netlify.toml CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  [build.environment]
6
6
  NODE_VERSION = "22"
7
+ ENV_MODE = "prod"
7
8
 
8
9
  [dev]
9
10
  command = "npm run dev"
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "sideEffects": [
5
5
  "./.netlify/shims.js"
6
6
  ],
7
- "version": "1.6.1",
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
- "playwright": "^1.52.0",
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",
@@ -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';", // Allow resources from same origin
47
- "script-src 'self' 'unsafe-inline';", // Allow inline scripts
48
- "style-src 'self' 'unsafe-inline';", // Allow inline styles
49
- "img-src 'self' data:;", // Allow images from same origin and data URIs
50
- "connect-src 'self';", // Allow connections only to same origin
51
- "font-src 'self' data:;", // Allow fonts from same origin and data URIs
52
- "form-action 'self';", // Allow forms to post to same origin
53
- "base-uri 'self';", // Restrict base URIs to same origin
54
- "object-src 'none';", // Block all object sources
55
- "frame-ancestors 'none';", // Prevent framing of the site
56
- "upgrade-insecure-requests;", // Automatically upgrade HTTP to HTTPS
57
- `report-uri ${process.env.ENV_MODE === "prod" ? "/.netlify/functions/cspReport" : "/api/mock-csp"};`, // Add CSP report URI for violations
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>
@@ -57,7 +57,7 @@ This file is part of Network Pro.
57
57
  },
58
58
  {
59
59
  label: "Markdown",
60
- href: "https://netwk.pro/docs",
60
+ href: "https://docs.netwk.pro",
61
61
  target: "_self",
62
62
  },
63
63
  ];
@@ -42,3 +42,5 @@ export function load({ url }) {
42
42
  meta: currentMeta, // Return the meta data (either from the route or the fallback)
43
43
  };
44
44
  }
45
+
46
+ // cspell:ignore posthog
@@ -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>
@@ -12,7 +12,10 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
12
12
  );
13
13
 
14
14
  const isDev = location.hostname === "localhost";
15
- const disallowedHosts = ["licdn.com"];
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",
@@ -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
@@ -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