@networkpro/web 1.14.2 → 1.15.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/README.md +6 -4
  3. package/_redirects +4 -2
  4. package/cspell.json +2 -0
  5. package/netlify/edge-functions/csp-report.js +22 -15
  6. package/package.json +3 -4
  7. package/scripts/testRedirects.js +84 -0
  8. package/src/app.html +1 -1
  9. package/src/lib/components/RedirectPage.svelte +2 -34
  10. package/src/lib/components/layout/HeaderDefault.svelte +8 -3
  11. package/src/lib/components/layout/HeaderHome.svelte +8 -3
  12. package/src/lib/pages/AboutContent.svelte +1 -1
  13. package/src/lib/pages/HomeContent.svelte +3 -9
  14. package/src/lib/pages/LicenseContent.svelte +1 -2
  15. package/src/lib/pages/PrivacyContent.svelte +45 -31
  16. package/src/lib/pages/PrivacyDashboard.svelte +0 -1
  17. package/src/lib/pages/TermsConditionsContent.svelte +2 -2
  18. package/src/lib/stores/trackingPreferences.js +6 -0
  19. package/src/lib/styles/css/default.css +31 -4
  20. package/src/lib/styles/global.min.css +1 -1
  21. package/src/lib/utils/getUTMParams.js +43 -0
  22. package/src/lib/utils/purify.js +1 -1
  23. package/src/lib/utils/redirect.js +52 -0
  24. package/src/lib/utils/utm.js +31 -8
  25. package/src/routes/consultation/+page.svelte +16 -2
  26. package/src/routes/contact/+page.svelte +17 -3
  27. package/src/routes/links/+page.svelte +24 -5
  28. package/src/routes/posts/+page.svelte +24 -5
  29. package/src/routes/privacy-rights/+page.svelte +19 -3
  30. package/tests/unit/{unregisterServiceWorker.test.js → client/lib/unregisterServiceWorker.test.js} +2 -2
  31. package/tests/unit/client/lib/utils/redirect.test.js +80 -0
  32. package/tests/unit/client/lib/utils/utm.test.js +59 -0
  33. package/tests/unit/{routes → client/routes}/page.svelte.test.js +2 -2
  34. package/tests/unit/{checkEnv.test.js → server/checkEnv.test.js} +2 -2
  35. package/tests/unit/{checkVersions.test.js → server/checkVersions.test.js} +2 -2
  36. package/tests/unit/{csp-report.test.js → server/csp-report.test.js} +2 -2
  37. package/tests/{internal → unit/server/internal}/auditCoverage.test.js +13 -6
  38. package/tests/unit/{lib → server/lib}/utils/purify.test.js +2 -2
  39. package/vitest.config.client.js +1 -4
  40. package/vitest.config.server.js +1 -1
  41. package/tests/unit/utm.test.js +0 -49
package/CHANGELOG.md CHANGED
@@ -22,6 +22,82 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
22
22
 
23
23
  ---
24
24
 
25
+ ## [1.15.0] - 2025-07-01
26
+
27
+ ### Added
28
+
29
+ - `redirect.js` utility to handle browser-aware redirects with fallback logic for Firefox.
30
+ - Unit test for `redirect.js` under `tests/unit/client/lib/utils/redirect.test.js`.
31
+ - `/consultation` redirect route to `utm.js` UTM-tracking logic.
32
+ - Redirect from `/foss` to `/foss-spotlight` in `_redirects`.
33
+ - `scripts/testRedirect.js` to verify Netlify/SvelteKit trailing slash redirect behavior.
34
+ - `test:redirects` script in package.json to trigger `scripts/testRedirects.js`
35
+ - Logic to suppress `rel="noopener noreferrer"` on internal redirects in `HeaderHome.svelte` and `HeaderDefault.svelte`
36
+ - `redirect` flag to navigation metadata to distinguish internal redirect behavior in `HeaderHome.svelte` and `HeaderDefault.svelte`
37
+
38
+ ### Changed
39
+
40
+ - Bumped version to **v1.15.0**
41
+ - Restructured unit tests:
42
+ - Moved `purify.test.js` to `tests/unit/client/lib/utils/`
43
+ - Moved `utm.test.js` to `tests/unit/client/lib/utils/`
44
+ - Moved `unregisterServiceWorker.test.js` to `tests/unit/client/lib/utils/`
45
+ - Moved `page.svelte.test.js` to `tests/unit/client/routes/`
46
+ - Moved `checkEnv.test.js`, `checkVersions.test.js`, and `csp-report.test.js` to `tests/unit/server/`
47
+ - Moved `auditCoverage.test.js` to `tests/unit/server/internal/`
48
+ - Refactored `_redirects` file:
49
+ - Removed trailing slashes to match SvelteKit/Netlify conventions.
50
+ - Updated `RedirectPage.svelte` to use `redirectWithBrowserAwareness()` for better cross-browser redirect behavior.
51
+ - Refactored all relevant `+page.svelte` files to remove local redirect timeouts and centralize logic in `RedirectPage`.
52
+ - Updated `vitest.config.client.js` and `vitest.config.server.js` to:
53
+ - Reflect new directory structure
54
+ - Properly assign `jsdom` for client-side tests and `node` for server-side tests
55
+ - `/consultation`, `/contact`, `/links`, `/posts`, and `/privacy-rights` `+page.svelte` files updated to capture UTM parameters in a privacy-preserving manner.
56
+ - Moved inline styles from `RedirectPage.svelte` to `src/lib/styles/css/default.css`, including `@keyframes spin` animation used by `.loading-spinner`
57
+ - Removed unnecessary `rel` attribute from internal links in `AboutContent.svelte`, `LicenseContent.svelte`, and `PrivacyDashboard.svelte`
58
+ - Updated project README with revised directory structure reflecting separate client/server test folders.
59
+ - Upgraded dependencies:
60
+ - `globals` `^16.2.0` → `^16.3.0`
61
+
62
+ ### Fixed
63
+
64
+ - Firefox-specific issue where delayed `window.location.replace()` triggered a new tab instead of redirecting in the same window — now handled by bypassing the delay in Firefox.
65
+ - Prevented server-context tests from breaking due to `window` usage by scoping them to client-only environments.
66
+
67
+ ## Removed
68
+
69
+ - `head:flatten` and `head:validate` scripts in package.json, as the `_headers` file has been deprecated
70
+
71
+ ---
72
+
73
+ ## [1.14.3] - 2025-06-30
74
+
75
+ ### Added
76
+
77
+ - Manual event capture for redirect pages using PostHog, with automatic UTM parameter extraction
78
+ - Utility function `getUTMParams` for parsing UTM query values from URLs
79
+ - `trackingEnabled` named export from `trackingPreferences.js` for cleaner consumption
80
+
81
+ ### Changed
82
+
83
+ - Bumped version to **v1.14.3**
84
+ - Refactored redirect logic in multiple pages to integrate UTM-aware analytics
85
+ - All redirect pages now consistently open in a new browser tab using `<a>` fallback
86
+ - Enhanced `utm.js` logic to support campaign identification for `/contact`, `/links`, `/posts`, and `/privacy-rights`
87
+ - Updated `generator` metadata in `app.html` to `SvelteKit 2.22.2`
88
+ - Modified `HomeContent.svelte` to use app constant for blog link
89
+ - Removed inline styles from redirect pages and integrated them into the main stylesheet
90
+ - Renamed "Data Sharing" section in Privacy Policy to "Legal Requests and Data Disclosure"
91
+ - Expanded the above section to strengthen users' legal rights and privacy protections
92
+ - Updated Privacy Policy effective date to June 30, 2025
93
+
94
+ ### Fixed
95
+
96
+ - Reinstated filtering logic in `csp-report.js` to suppress low-value or noisy CSP violations
97
+ - Resolved `ReferenceError` in `utm.test.js` by reordering mocked imports for `$app/environment` and `$app/stores` to comply with Vitest's hoisting behavior
98
+
99
+ ---
100
+
25
101
  ## [1.14.2] - 2025-06-30
26
102
 
27
103
  ### Added
@@ -539,7 +615,8 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
539
615
 
540
616
  <!-- Link references -->
541
617
 
542
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.14.2...HEAD
618
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.15.0...HEAD
619
+ [1.15.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.15.0
543
620
  [1.14.2]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.14.2
544
621
  [1.14.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.14.1
545
622
  [1.14.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.14.0
package/README.md CHANGED
@@ -92,10 +92,12 @@ This project follows the principles of [Keep a Changelog](https://keepachangelog
92
92
  │ ├── robots.txt # SEO: allow/disallow crawlers
93
93
  │ └── sitemap.xml # SEO: full site map
94
94
  ├── tests/
95
- │ ├── e2e/ # Playwright end-to-end tests
96
- ├── internal/ # Internal audit/test helpers
97
- │ └── auditCoverage.test.js # Warns about untested source modules
98
- └── unit/ # Vitest unit tests
95
+ │ ├── e2e/ # Playwright end-to-end tests
96
+ └── unit/ # Vitest unit tests
97
+ ├── client/ # Client-side (jsdom) unit tests
98
+ ├── server/ # Server-side (node) unit tests
99
+ │ │ └── internal/ # Internal audit/test helpers
100
+ │ │ └── auditCoverage.test.js # Warns about untested source modules
99
101
  ├── _redirects # Netlify redirect rules
100
102
  ├── CHANGELOG.md # Chronological record of notable project changes
101
103
  ├── netlify.toml # Netlify configuration
package/_redirects CHANGED
@@ -3,13 +3,15 @@ https://www.netwk.pro/* https://netwk.pro/:splat 301
3
3
 
4
4
  # Redirect /privacy-policy (and variants) to /privacy
5
5
  /privacy-policy /privacy 301
6
- /privacy-policy/ /privacy 301
7
6
  /privacy-policy/* /privacy/:splat 301
8
7
 
9
8
  # Redirect /legal (and variants) to /license
10
9
  /legal /license 301
11
- /legal/ /license 301
12
10
  /legal/* /license/:splat 301
13
11
 
12
+ # Redirect /foss (and variants) to /foss-spotlight
13
+ /foss /foss-spotlight 301
14
+ /foss/* /foss-spotlight/:splat 301
15
+
14
16
  # Redirect for Netlify function proxy
15
17
  /api/* /.netlify/functions/:splat 200
package/cspell.json CHANGED
@@ -37,6 +37,7 @@
37
37
  "lighthouserc",
38
38
  "lightningcss",
39
39
  "linksheet",
40
+ "linktree",
40
41
  "lsheet",
41
42
  "Mailvelope",
42
43
  "Maricopa",
@@ -59,6 +60,7 @@
59
60
  "obtainium",
60
61
  "openpgp",
61
62
  "opgp",
63
+ "pallyy",
62
64
  "posthog",
63
65
  "precaching",
64
66
  "prefs",
@@ -43,20 +43,25 @@ export default async (request, _context) => {
43
43
  const violated = report['violated-directive'] ?? '';
44
44
  const blockedUri = report['blocked-uri'] ?? '';
45
45
 
46
- /*
47
- // Filter: Skip img-src violations and empty URIs
48
- const ignored = [
49
- violated.startsWith('img-src'),
50
- blockedUri === '',
51
- blockedUri === 'about',
52
- blockedUri.startsWith('chrome-extension://'),
53
- blockedUri.startsWith('moz-extension://'),
54
- ].some(Boolean);
55
-
56
- if (ignored) {
57
- return new Response(null, { status: 204 });
58
- }
59
- */
46
+ // Filter: Skip noisy or unactionable reports
47
+ const ignored = [
48
+ violated.startsWith('img-src'),
49
+ blockedUri === '',
50
+ blockedUri === 'eval',
51
+ blockedUri === 'about',
52
+ blockedUri.startsWith('chrome-extension://'),
53
+ blockedUri.startsWith('moz-extension://'),
54
+ !report['source-file'],
55
+ !report['document-uri'],
56
+ ].some(Boolean);
57
+
58
+ if (ignored) {
59
+ console.log('[CSP-Edge] Ignored low-value violation:', {
60
+ directive: violated,
61
+ uri: blockedUri,
62
+ });
63
+ return new Response(null, { status: 204 });
64
+ }
60
65
 
61
66
  // Send alert for high-risk directives
62
67
  await sendToNtfy(violated, blockedUri, report);
@@ -97,7 +102,9 @@ async function sendToNtfy(violated, blockedUri, report) {
97
102
 
98
103
  const directiveKey = violated.split(' ')[0]; // strip fallback values or sources
99
104
  const isHighRisk = highRiskDirectives.includes(directiveKey);
100
- console.log(`[CSP-Edge] Checking directive: ${directiveKey}`);
105
+ console.log(
106
+ `[CSP-Edge] Directive ${directiveKey} is ${isHighRisk ? '' : 'not '}high-risk`,
107
+ );
101
108
  if (!isHighRisk) return;
102
109
 
103
110
  const key = `${violated}|${blockedUri}`;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.14.2",
4
+ "version": "1.15.0",
5
5
  "description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advisory",
@@ -60,6 +60,7 @@
60
60
  "test:watch": "vitest --config vitest.config.client.js --watch",
61
61
  "test:coverage": "npm run test:client -- --run --coverage && npm run test:server -- --run --coverage",
62
62
  "test:e2e": "npx playwright test --retries=1",
63
+ "test:redirects": "node scripts/testRedirects.js",
63
64
  "coverage:client": "node scripts/openReport.js client",
64
65
  "coverage:server": "node scripts/openReport.js server",
65
66
  "coverage:open": "npm run coverage:client && npm run coverage:server",
@@ -74,8 +75,6 @@
74
75
  "lhci": "lhci",
75
76
  "lhci:run": "lhci autorun --config=.lighthouserc.cjs",
76
77
  "audit:coverage": "vitest run tests/internal/auditCoverage.test.js",
77
- "head:flatten": "node scripts/flattenHeaders.js",
78
- "head:validate": "node scripts/validateHeaders.js",
79
78
  "postinstall": "npm run check:node"
80
79
  },
81
80
  "dependencies": {
@@ -101,7 +100,7 @@
101
100
  "eslint-config-prettier": "^10.1.5",
102
101
  "eslint-plugin-jsdoc": "^51.3.1",
103
102
  "eslint-plugin-svelte": "^3.10.1",
104
- "globals": "^16.2.0",
103
+ "globals": "^16.3.0",
105
104
  "jsdom": "^26.1.0",
106
105
  "lightningcss": "^1.30.1",
107
106
  "markdownlint": "^0.38.0",
@@ -0,0 +1,84 @@
1
+ /* ==========================================================================
2
+ scripts/testRedirects.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 testRedirects.js
11
+ * @description Tests Netlify redirects against actual endpoints to verify
12
+ * trailing-slash behavior.
13
+ *
14
+ * @module scripts/
15
+ * @author SunDevil311
16
+ * @updated 2025-07-01
17
+ */
18
+
19
+ import https from 'https';
20
+ import { URL } from 'url';
21
+
22
+ /**
23
+ * @typedef {object} RedirectTest
24
+ * @property {string} from - The source URL to test.
25
+ * @property {string} to - The expected destination URL.
26
+ */
27
+
28
+ /** @type {RedirectTest[]} */
29
+ const urls = [
30
+ { from: 'https://netwk.pro/privacy-policy', to: 'https://netwk.pro/privacy' },
31
+ {
32
+ from: 'https://netwk.pro/privacy-policy/',
33
+ to: 'https://netwk.pro/privacy',
34
+ },
35
+ { from: 'https://netwk.pro/foss', to: 'https://netwk.pro/foss-spotlight' },
36
+ { from: 'https://netwk.pro/foss/', to: 'https://netwk.pro/foss-spotlight' },
37
+ {
38
+ from: 'https://www.netwk.pro/foss',
39
+ to: 'https://netwk.pro/foss-spotlight',
40
+ },
41
+ ];
42
+
43
+ /**
44
+ * Tests a single redirect by making a GET request and checking the status code and location header.
45
+ * @param {RedirectTest} redirect - The redirect configuration to test.
46
+ * @returns {Promise<boolean>} - Resolves to true if the redirect is correct, false otherwise.
47
+ */
48
+ function testRedirect({ from, to }) {
49
+ return new Promise((resolve) => {
50
+ const req = https.request(new URL(from), { method: 'GET' }, (res) => {
51
+ const location = res.headers.location;
52
+ const expectedPath = new URL(to).pathname;
53
+
54
+ if (res.statusCode === 301 && location === expectedPath) {
55
+ console.log(`✅ ${from} → ${location}`);
56
+ resolve(true);
57
+ } else {
58
+ console.error(
59
+ `❌ ${from} → Expected 301 to ${expectedPath}, got ${res.statusCode} to ${location}`,
60
+ );
61
+ resolve(false);
62
+ }
63
+ });
64
+
65
+ req.on('error', (err) => {
66
+ console.error(`❌ ${from} → Network error: ${err.message}`);
67
+ resolve(false);
68
+ });
69
+
70
+ req.end();
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Runs all redirect tests and exits the process with a status code reflecting success or failure.
76
+ * @returns {Promise<void>}
77
+ */
78
+ const runTests = async () => {
79
+ const results = await Promise.all(urls.map(testRedirect));
80
+ const failed = results.filter((r) => !r).length;
81
+ process.exit(failed > 0 ? 1 : 0);
82
+ };
83
+
84
+ runTests();
package/src/app.html CHANGED
@@ -63,7 +63,7 @@
63
63
  content="bx4ham0zkpvzztzu213bhpt76m9siq" />
64
64
  <!-- cspell:enable -->
65
65
 
66
- <meta name="generator" content="SvelteKit 2.21.5" />
66
+ <meta name="generator" content="SvelteKit 2.22.2" />
67
67
 
68
68
  <script src="/disableSw.js"></script>
69
69
 
@@ -8,6 +8,7 @@ This file is part of Network Pro.
8
8
 
9
9
  <script>
10
10
  import { onMount } from 'svelte';
11
+ import { redirectWithBrowserAwareness } from '$lib/utils/redirect.js';
11
12
  import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
13
 
13
14
  export let to;
@@ -15,16 +16,7 @@ This file is part of Network Pro.
15
16
  export let delay = 3;
16
17
 
17
18
  onMount(() => {
18
- if (!to) {
19
- console.warn('⛔ No redirect target provided');
20
- return;
21
- }
22
-
23
- console.log('✅ Starting redirect to:', to);
24
-
25
- setTimeout(() => {
26
- window.location.href = to;
27
- }, delay * 1000);
19
+ redirectWithBrowserAwareness(to, delay);
28
20
  });
29
21
  </script>
30
22
 
@@ -47,27 +39,3 @@ This file is part of Network Pro.
47
39
  </FullWidthSection>
48
40
 
49
41
  <!-- END MAIN CONTENT -->
50
-
51
- <style>
52
- .redirect-content {
53
- text-align: center;
54
- font-family: system-ui, sans-serif;
55
- margin-top: 2rem; /* adjust as needed */
56
- }
57
-
58
- .loading-spinner {
59
- width: 48px;
60
- height: 48px;
61
- margin: 2rem auto;
62
- border: 4px solid #ddd;
63
- animation: spin 1s linear infinite;
64
- border-radius: 50%;
65
- border-top: 4px solid #ffc627;
66
- }
67
-
68
- @keyframes spin {
69
- to {
70
- transform: rotate(360deg);
71
- }
72
- }
73
- </style>
@@ -22,6 +22,8 @@ This file is part of Network Pro.
22
22
  const lhubLink = `${base}/links`;
23
23
  const fossLink = `${base}/foss-spotlight`;
24
24
  const blogLink = 'https://blog.netwk.pro';
25
+ const discussLink =
26
+ 'https://github.com/netwk-pro/netwk-pro.github.io/discussions';
25
27
 
26
28
  /**
27
29
  * Navigation link object.
@@ -30,6 +32,7 @@ This file is part of Network Pro.
30
32
  * @property {string} href - The URL or anchor the link points to.
31
33
  * @property {string} target - Specifies where to open the link (e.g., "_self" or "_blank").
32
34
  * @property {boolean} external - Whether the link points to an external resource.
35
+ * @property {boolean} [redirect=false] - Indicates whether the external link is actually an internal redirect.
33
36
  */
34
37
 
35
38
  /**
@@ -48,15 +51,17 @@ This file is part of Network Pro.
48
51
  },
49
52
  {
50
53
  label: 'discussions',
51
- href: 'https://github.com/netwk-pro/netwk-pro.github.io/discussions',
54
+ href: discussLink,
52
55
  target: PAGE.BLANK,
53
56
  external: true,
57
+ redirect: false,
54
58
  },
55
59
  {
56
60
  label: 'link hub',
57
61
  href: lhubLink,
58
62
  target: PAGE.BLANK,
59
63
  external: true,
64
+ redirect: true,
60
65
  },
61
66
  ];
62
67
 
@@ -69,8 +74,8 @@ This file is part of Network Pro.
69
74
 
70
75
  <!-- BEGIN DEFAULT HEADER -->
71
76
  <nav class="center-nav" aria-label="Site navigation">
72
- {#each nav as { label, href, target, external }, index}
73
- <a {href} {target} rel={external ? rel : undefined}>
77
+ {#each nav as { label, href, target, external, redirect }, index}
78
+ <a {href} {target} rel={!redirect && external ? rel : undefined}>
74
79
  {label}
75
80
  </a>
76
81
  {#if external}
@@ -21,6 +21,8 @@ This file is part of Network Pro.
21
21
  const fossLink = `${base}/foss-spotlight`;
22
22
  const lhubLink = `${base}/links`;
23
23
  const blogLink = 'https://blog.netwk.pro';
24
+ const discussLink =
25
+ 'https://github.com/netwk-pro/netwk-pro.github.io/discussions';
24
26
 
25
27
  /**
26
28
  * Navigation link object.
@@ -29,6 +31,7 @@ This file is part of Network Pro.
29
31
  * @property {string} href - The URL or anchor the link points to.
30
32
  * @property {string} target - Specifies where to open the link (e.g., "_self" or "_blank").
31
33
  * @property {boolean} external - Whether the link points to an external resource.
34
+ * @property {boolean} [redirect=false] - Indicates whether the external link is actually an internal redirect.
32
35
  */
33
36
 
34
37
  /**
@@ -46,15 +49,17 @@ This file is part of Network Pro.
46
49
  },
47
50
  {
48
51
  label: 'discussions',
49
- href: 'https://github.com/netwk-pro/netwk-pro.github.io/discussions',
52
+ href: discussLink,
50
53
  target: PAGE.BLANK,
51
54
  external: true,
55
+ redirect: false,
52
56
  },
53
57
  {
54
58
  label: 'link hub',
55
59
  href: lhubLink,
56
60
  target: PAGE.BLANK,
57
61
  external: true,
62
+ redirect: true,
58
63
  },
59
64
  ];
60
65
 
@@ -67,8 +72,8 @@ This file is part of Network Pro.
67
72
 
68
73
  <!-- BEGIN HOME HEADER -->
69
74
  <nav class="center-nav" aria-label="Homepage navigation">
70
- {#each nav as { label, href, target, external }, index}
71
- <a {href} {target} rel={external ? rel : undefined}>
75
+ {#each nav as { label, href, target, external, redirect }, index}
76
+ <a {href} {target} rel={!redirect && external ? rel : undefined}>
72
77
  {label}
73
78
  </a>
74
79
  {#if external}
@@ -217,7 +217,7 @@ This file is part of Network Pro.
217
217
  <div class="spacer"></div>
218
218
 
219
219
  <p>
220
- <a rel={PAGE.REL} href={contactLink} target={PAGE.BLANK}>Let's connect</a>
220
+ <a href={contactLink} target={PAGE.BLANK}>Let's connect</a>
221
221
  to discuss how we can help secure and strengthen your business today.
222
222
  </p>
223
223
 
@@ -15,7 +15,7 @@ This file is part of Network Pro.
15
15
 
16
16
  //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
17
17
 
18
- const { COMPANY_INFO, PAGE, NAV } = CONSTANTS;
18
+ const { COMPANY_INFO, LINKS, PAGE, NAV } = CONSTANTS;
19
19
 
20
20
  /**
21
21
  * URL to the FOSS Spotlight page, using the base path
@@ -23,12 +23,6 @@ This file is part of Network Pro.
23
23
  */
24
24
  const spotlightLink = `${base}/foss-spotlight`;
25
25
 
26
- /**
27
- * URL to the external blog
28
- * @type {string}
29
- */
30
- const blogLink = 'https://blog.netwk.pro';
31
-
32
26
  /**
33
27
  * CSS class for the index headings.
34
28
  * @type {string}
@@ -69,7 +63,7 @@ This file is part of Network Pro.
69
63
  📡
70
64
  <em>
71
65
  <strong>Stay informed:</strong> Follow our
72
- <a href={blogLink} target={PAGE.SELF}>blog</a>
66
+ <a href={LINKS.BLOG} target={PAGE.SELF}>blog</a>
73
67
  and social channels for actionable insights, implementation guides, and the latest
74
68
  cybersecurity developments.
75
69
  </em>
@@ -81,7 +75,7 @@ This file is part of Network Pro.
81
75
 
82
76
  <p class={classLarge}>
83
77
  <strong>
84
- <a href={blogLink} target={PAGE.SELF}>{COMPANY_INFO.APP_NAME} Blog</a>
78
+ <a href={LINKS.BLOG} target={PAGE.SELF}>{COMPANY_INFO.APP_NAME} Blog</a>
85
79
  </strong>
86
80
  </p>
87
81
 
@@ -487,8 +487,7 @@ This file is part of Network Pro.
487
487
  {:else if link.id === 'contact'}
488
488
  <p>
489
489
  The Company can be contacted via our
490
- <a rel={PAGE.REL} href={contactLink} target={PAGE.BLANK}
491
- >Contact Form</a>
490
+ <a href={contactLink} target={PAGE.BLANK}>Contact Form</a>
492
491
  or by email at:<br />
493
492
  📧 <strong>{CONTACT.EMAIL}</strong>
494
493
  </p>