@networkpro/web 1.25.16 → 1.25.18
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/build-and-publish.yml +3 -3
- package/.github/workflows/check-security-txt-expiry.yml +1 -1
- package/.github/workflows/lighthouse.yml +1 -1
- package/.github/workflows/playwright.yml +1 -1
- package/.github/workflows/publish-test.yml +3 -3
- package/.github/workflows/templates/publish.template.yml +3 -3
- package/.ncurc.cjs +1 -1
- package/CHANGELOG.md +82 -1
- package/eslint.config.mjs +16 -3
- package/package.json +19 -18
- package/src/app.html +1 -1
- package/src/lib/README.md +2 -2
- package/src/lib/img/qr/vcard.png +0 -0
- package/src/lib/img/qr/vcard.webp +0 -0
- package/src/lib/index.js +1 -1
- package/src/lib/pages/LicenseContent.svelte +2 -2
- package/src/lib/pages/PrivacyContent.svelte +14 -14
- package/src/lib/pages/TermsUseContent.svelte +2 -2
- package/src/lib/utils/purify.js +4 -4
- package/src/service-worker.js +32 -32
- package/static/bin/contact.vcf +2 -2
- package/static/sitemap.xml +2 -2
- package/tests/unit/server/internal/ssrBoundary.test.js +107 -0
- package/static/CNAME +0 -1
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
- name: Upgrade npm
|
|
46
46
|
run: |
|
|
47
47
|
corepack enable
|
|
48
|
-
npm install -g npm@11.
|
|
48
|
+
npm install -g npm@11.7.0
|
|
49
49
|
|
|
50
50
|
- name: Install Node.js dependencies
|
|
51
51
|
run: npm ci
|
|
@@ -130,7 +130,7 @@ jobs:
|
|
|
130
130
|
- name: Upgrade npm
|
|
131
131
|
run: |
|
|
132
132
|
corepack enable
|
|
133
|
-
npm install -g npm@11.
|
|
133
|
+
npm install -g npm@11.7.0
|
|
134
134
|
|
|
135
135
|
- name: Install Node.js dependencies
|
|
136
136
|
run: npm ci
|
|
@@ -186,7 +186,7 @@ jobs:
|
|
|
186
186
|
- name: Upgrade npm
|
|
187
187
|
run: |
|
|
188
188
|
corepack enable
|
|
189
|
-
npm install -g npm@11.
|
|
189
|
+
npm install -g npm@11.7.0
|
|
190
190
|
|
|
191
191
|
- name: Install Node.js dependencies
|
|
192
192
|
run: npm ci
|
|
@@ -48,7 +48,7 @@ jobs:
|
|
|
48
48
|
- name: Upgrade npm
|
|
49
49
|
run: |
|
|
50
50
|
corepack enable
|
|
51
|
-
npm install -g npm@11.
|
|
51
|
+
npm install -g npm@11.7.0
|
|
52
52
|
|
|
53
53
|
- name: Install Node.js dependencies
|
|
54
54
|
run: npm ci
|
|
@@ -134,7 +134,7 @@ jobs:
|
|
|
134
134
|
- name: Upgrade npm
|
|
135
135
|
run: |
|
|
136
136
|
corepack enable
|
|
137
|
-
npm install -g npm@11.
|
|
137
|
+
npm install -g npm@11.7.0
|
|
138
138
|
|
|
139
139
|
- name: Install Node.js dependencies
|
|
140
140
|
run: npm ci
|
|
@@ -195,7 +195,7 @@ jobs:
|
|
|
195
195
|
- name: Upgrade npm
|
|
196
196
|
run: |
|
|
197
197
|
corepack enable
|
|
198
|
-
npm install -g npm@11.
|
|
198
|
+
npm install -g npm@11.7.0
|
|
199
199
|
|
|
200
200
|
- name: Install Node.js dependencies
|
|
201
201
|
run: npm ci
|
|
@@ -53,7 +53,7 @@ jobs:
|
|
|
53
53
|
- name: Upgrade npm
|
|
54
54
|
run: |
|
|
55
55
|
corepack enable
|
|
56
|
-
npm install -g npm@11.
|
|
56
|
+
npm install -g npm@11.7.0
|
|
57
57
|
|
|
58
58
|
- name: Install Node.js dependencies
|
|
59
59
|
run: npm ci
|
|
@@ -134,7 +134,7 @@ jobs:
|
|
|
134
134
|
- name: Upgrade npm
|
|
135
135
|
run: |
|
|
136
136
|
corepack enable
|
|
137
|
-
npm install -g npm@11.
|
|
137
|
+
npm install -g npm@11.7.0
|
|
138
138
|
|
|
139
139
|
- name: Install Node.js dependencies
|
|
140
140
|
run: npm ci
|
|
@@ -190,7 +190,7 @@ jobs:
|
|
|
190
190
|
- name: Upgrade npm
|
|
191
191
|
run: |
|
|
192
192
|
corepack enable
|
|
193
|
-
npm install -g npm@11.
|
|
193
|
+
npm install -g npm@11.7.0
|
|
194
194
|
|
|
195
195
|
- name: Install Node.js dependencies
|
|
196
196
|
run: npm ci
|
package/.ncurc.cjs
CHANGED
|
@@ -31,7 +31,7 @@ This file is part of Network Pro.
|
|
|
31
31
|
/** @type {import('npm-check-updates').RunOptions} */
|
|
32
32
|
module.exports = {
|
|
33
33
|
// Ignore specific dependencies (prevent upgrades)
|
|
34
|
-
reject: ['vitest', '@vitest/coverage-v8', 'prettier'
|
|
34
|
+
reject: ['vitest', '@vitest/coverage-v8', 'prettier'],
|
|
35
35
|
|
|
36
36
|
// Always upgrade devDependencies as well
|
|
37
37
|
dep: 'prod,dev',
|
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,85 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## [1.25.18] - 2025-12-11
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Refreshed timestamp for root route in `sitemap.xml`.
|
|
30
|
+
- Reformatted the following files with Prettier:
|
|
31
|
+
- `src/lib/README.md`
|
|
32
|
+
- `src/lib/pages/LicenseContent.svelte`
|
|
33
|
+
- `src/lib/pages/PrivacyContent.svelte`
|
|
34
|
+
- `src/lib/pages/TermsUseContent.svelte`
|
|
35
|
+
- Bumped project version to `v1.25.18`.
|
|
36
|
+
- Updated dependencies:
|
|
37
|
+
- `prettier` `3.6.2` → `3.7.4`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## [1.25.17] - 2025-12-11
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Added SSR boundary protection test (`tests/unit/server/internal/ssrBoundary.test.js`):
|
|
46
|
+
- Detects Node-only imports (`jsdom`, `fs`, `path`, etc.) in client-visible modules.
|
|
47
|
+
- Ensures imports are properly gated behind `import.meta.env.SSR`.
|
|
48
|
+
- Prevents accidental SSR/client boundary violations in future code changes.
|
|
49
|
+
- Added support for detecting SSR-safe code paths by allowing SSR-gated dynamic imports in shared modules.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Refactored `src/service-worker.js` for improved consistency, clarity, and lint compatibility:
|
|
54
|
+
- Removed unused function parameters (`_err`) and adjusted callback signatures to align with ESLint expectations.
|
|
55
|
+
- Replaced anonymous no-op parameters with explicitly ignored placeholders using the `_` naming convention.
|
|
56
|
+
- Improved async iteration patterns in asset caching logic for better readability and maintainability.
|
|
57
|
+
- Updated JSDoc annotations for accuracy and improved editor support.
|
|
58
|
+
- Ensured all cache operations conform to structured error-handling patterns consistent with the rest of the codebase.
|
|
59
|
+
|
|
60
|
+
- Updated `src/lib/utils/purify.js`:
|
|
61
|
+
- Replaced `typeof window !== 'undefined'` guard with compile-time `import.meta.env.SSR`.
|
|
62
|
+
- Ensures Vite tree-shakes `jsdom` imports from client bundles.
|
|
63
|
+
- Fixed build failures caused by jsdom/cssstyle when bundled on the client.
|
|
64
|
+
- Preserves existing DOMPurify caching and SSR behavior.
|
|
65
|
+
|
|
66
|
+
- Enhanced ESLint `no-unused-vars` rule in `eslint.config.mjs`:
|
|
67
|
+
- Added support for ignoring unused catch parameters via `caughtErrors` and `caughtErrorsIgnorePattern`.
|
|
68
|
+
- Prevented false positives on intentionally unused error variables (e.g., `_err`).
|
|
69
|
+
- Expanded ignore patterns to match project coding conventions.
|
|
70
|
+
|
|
71
|
+
- Replaced `src/lib/img/qr/vcard.png` and `src/lib/img/qr/vcard.webp` with revised versions.
|
|
72
|
+
- Updated GitHub workflows to utilize **npm** `11.7.0`.
|
|
73
|
+
- Updated generator metadata in `src/app.html` to reflect **SvelteKit 2.49.2**.
|
|
74
|
+
- Updated `src/lib/README.md` to reflect the newly updated app constant.
|
|
75
|
+
- Updated contact information in `static/bin/contact.vcf`.
|
|
76
|
+
- Updated `CONTACT.PHONE` app constant to reflect our new phone number, (602) 428-5300.
|
|
77
|
+
- Removed `jsdom` from `.ncurc.cjs` `reject` list.
|
|
78
|
+
- Bumped project version to `v1.25.17`.
|
|
79
|
+
- Updated dependencies:
|
|
80
|
+
- `dompurify` `^3.3.0` → `^3.3.1`
|
|
81
|
+
- `posthog-js` `^1.295.0` → `^1.305.0`
|
|
82
|
+
- `svelte` `5.43.12` → `5.45.9`
|
|
83
|
+
- `@playwright/test` `^1.56.1` → `^1.57.0`
|
|
84
|
+
- `@sveltejs/adapter-vercel` `^6.1.1` → `^6.2.0`
|
|
85
|
+
- `@sveltejs/kit` `2.48.5` → `2.49.2`
|
|
86
|
+
- `browserslist` `^4.28.0` → `^4.28.1`
|
|
87
|
+
- `eslint-plugin-jsdoc` `^61.2.1` → `^61.5.0`
|
|
88
|
+
- `eslint-plugin-svelte` `^3.13.0` → `^3.13.1`
|
|
89
|
+
- `markdownlint` `^0.39.0` → `^0.40.0`
|
|
90
|
+
- `markdownlint-cli2` `0.19.0` → `0.20.0`
|
|
91
|
+
- `playwright` `^1.56.1` → `^1.57.0`
|
|
92
|
+
- `stylelint` `^16.25.0` → `^16.26.1`
|
|
93
|
+
- `svelte-eslint-parser` `^1.4.0` → `^1.4.1`
|
|
94
|
+
- `vite` `^7.2.2` → `^7.2.7`
|
|
95
|
+
- `jsdom` `26.1.0` → `27.3.0`
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
|
|
99
|
+
- Resolved client-side build failures caused by dynamic jsdom imports leaking into the Vite dependency graph.
|
|
100
|
+
- Resolved false positive ESLint errors for unused catch bindings in JS modules.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
25
104
|
## [1.25.16] - 2025-11-18
|
|
26
105
|
|
|
27
106
|
### Changed
|
|
@@ -1961,7 +2040,9 @@ This enables analytics filtering and CSP hardening for the audit environment.
|
|
|
1961
2040
|
|
|
1962
2041
|
<!-- Link references -->
|
|
1963
2042
|
|
|
1964
|
-
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.
|
|
2043
|
+
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.18...HEAD
|
|
2044
|
+
[1.25.18]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.18
|
|
2045
|
+
[1.25.17]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.17
|
|
1965
2046
|
[1.25.16]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.16
|
|
1966
2047
|
[1.25.15]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.15
|
|
1967
2048
|
[1.25.14]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.14
|
package/eslint.config.mjs
CHANGED
|
@@ -65,14 +65,27 @@ export default [
|
|
|
65
65
|
...js.configs.recommended.rules, // ESLint's core recommended rules (scoped)
|
|
66
66
|
...eslintConfigPrettier.rules, // Prettier config to disable conflicting ESLint rules (scoped)
|
|
67
67
|
...ESLINT_RULES, // Additional custom rules
|
|
68
|
-
|
|
68
|
+
|
|
69
|
+
// Updated unused variable handling:
|
|
70
|
+
// - Ignore args starting with "_"
|
|
71
|
+
// - Ignore vars starting with "_"
|
|
72
|
+
// - Allow unused catch variables named "_err" or any "_*"
|
|
73
|
+
'no-unused-vars': [
|
|
74
|
+
'error',
|
|
75
|
+
{
|
|
76
|
+
argsIgnorePattern: '^_',
|
|
77
|
+
varsIgnorePattern: '^_',
|
|
78
|
+
caughtErrors: 'all',
|
|
79
|
+
caughtErrorsIgnorePattern: '^_',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
|
|
69
83
|
'jsdoc/check-alignment': 'warn', // Ensure JSDoc block tags are aligned
|
|
70
84
|
'jsdoc/check-param-names': 'warn', // Checks parameter names in JSDoc
|
|
71
|
-
// Updated rule to allow the @updated tag
|
|
72
85
|
'jsdoc/check-tag-names': [
|
|
73
86
|
'warn',
|
|
74
87
|
{
|
|
75
|
-
definedTags: ['updated'],
|
|
88
|
+
definedTags: ['updated'], // Allow custom @updated tag
|
|
76
89
|
},
|
|
77
90
|
],
|
|
78
91
|
'jsdoc/check-types': 'warn', // Checks if types in JSDoc are defined correctly
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@networkpro/web",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.25.
|
|
4
|
+
"version": "1.25.18",
|
|
5
5
|
"description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"advisory",
|
|
@@ -85,49 +85,50 @@
|
|
|
85
85
|
"pre-push": "if [ \"$CI\" = \"true\" ]; then exit 0; else npm run checkout; fi"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"dompurify": "^3.3.
|
|
89
|
-
"posthog-js": "^1.
|
|
88
|
+
"dompurify": "^3.3.1",
|
|
89
|
+
"posthog-js": "^1.305.0",
|
|
90
90
|
"semver": "^7.7.3",
|
|
91
|
-
"svelte": "5.
|
|
91
|
+
"svelte": "5.45.9"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@eslint/compat": "^2.0.0",
|
|
95
95
|
"@eslint/js": "^9.39.1",
|
|
96
96
|
"@lhci/cli": "^0.15.1",
|
|
97
|
-
"@playwright/test": "^1.
|
|
97
|
+
"@playwright/test": "^1.57.0",
|
|
98
98
|
"@sveltejs/adapter-netlify": "^5.2.4",
|
|
99
|
-
"@sveltejs/adapter-vercel": "^6.
|
|
100
|
-
"@sveltejs/kit": "2.
|
|
99
|
+
"@sveltejs/adapter-vercel": "^6.2.0",
|
|
100
|
+
"@sveltejs/kit": "2.49.2",
|
|
101
101
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
102
102
|
"@testing-library/jest-dom": "^6.9.1",
|
|
103
103
|
"@testing-library/svelte": "^5.2.9",
|
|
104
104
|
"@vitest/coverage-v8": "3.2.4",
|
|
105
105
|
"autoprefixer": "^10.4.22",
|
|
106
|
-
"browserslist": "^4.28.
|
|
106
|
+
"browserslist": "^4.28.1",
|
|
107
107
|
"eslint": "^9.39.1",
|
|
108
108
|
"eslint-config-prettier": "^10.1.8",
|
|
109
|
-
"eslint-plugin-jsdoc": "^61.
|
|
110
|
-
"eslint-plugin-svelte": "^3.13.
|
|
109
|
+
"eslint-plugin-jsdoc": "^61.5.0",
|
|
110
|
+
"eslint-plugin-svelte": "^3.13.1",
|
|
111
111
|
"globals": "^16.5.0",
|
|
112
|
-
"
|
|
112
|
+
"globby": "^16.0.0",
|
|
113
|
+
"jsdom": "27.3.0",
|
|
113
114
|
"lightningcss": "^1.30.2",
|
|
114
|
-
"markdownlint": "^0.
|
|
115
|
-
"markdownlint-cli2": "0.
|
|
115
|
+
"markdownlint": "^0.40.0",
|
|
116
|
+
"markdownlint-cli2": "0.20.0",
|
|
116
117
|
"npm-run-all": "^4.1.5",
|
|
117
|
-
"playwright": "^1.
|
|
118
|
+
"playwright": "^1.57.0",
|
|
118
119
|
"postcss": "^8.5.6",
|
|
119
|
-
"prettier": "3.
|
|
120
|
+
"prettier": "3.7.4",
|
|
120
121
|
"prettier-plugin-svelte": "^3.4.0",
|
|
121
122
|
"simple-git-hooks": "^2.13.1",
|
|
122
|
-
"stylelint": "^16.
|
|
123
|
+
"stylelint": "^16.26.1",
|
|
123
124
|
"stylelint-config-html": "^1.1.0",
|
|
124
125
|
"stylelint-config-recommended": "^17.0.0",
|
|
125
126
|
"stylelint-order": "^7.0.0",
|
|
126
127
|
"svelte-check": "^4.3.4",
|
|
127
|
-
"svelte-eslint-parser": "^1.4.
|
|
128
|
+
"svelte-eslint-parser": "^1.4.1",
|
|
128
129
|
"svelte-preprocess": "^6.0.3",
|
|
129
130
|
"typescript": "^5.9.3",
|
|
130
|
-
"vite": "^7.2.
|
|
131
|
+
"vite": "^7.2.7",
|
|
131
132
|
"vite-plugin-devtools-json": "^1.0.0",
|
|
132
133
|
"vite-plugin-lightningcss": "^0.0.5",
|
|
133
134
|
"vite-tsconfig-paths": "^5.1.4",
|
package/src/app.html
CHANGED
package/src/lib/README.md
CHANGED
|
@@ -84,7 +84,7 @@ console.log(CONSTANTS.COMPANY_INFO.APP_NAME); // "Network Pro"
|
|
|
84
84
|
| Key | Description | Example |
|
|
85
85
|
| ---------- | ---------------------------- | ------------------------ |
|
|
86
86
|
| `NAME` | Full company name | `Network Pro Strategies` |
|
|
87
|
-
| `APP_NAME` | Application or branding name | `Network Pro™`
|
|
87
|
+
| `APP_NAME` | Application or branding name | `Network Pro™` |
|
|
88
88
|
| `YEAR` | Copyright / app year | `2025` |
|
|
89
89
|
|
|
90
90
|
### 📬 CONTACT
|
|
@@ -97,7 +97,7 @@ console.log(CONSTANTS.COMPANY_INFO.APP_NAME); // "Network Pro"
|
|
|
97
97
|
| `SECURE_LINK` | Secure contact address (link) | `contact@s.neteng.pro` |
|
|
98
98
|
| `PRIVACY` | Privacy-related contact | `privacy (at) netwk.pro` |
|
|
99
99
|
| `PRIVACY_LINK` | Privacy-related contact (link) | `privacy@netwk.pro` |
|
|
100
|
-
| `PHONE` | Company phone number | `(
|
|
100
|
+
| `PHONE` | Company phone number | `(602) 428-5300` |
|
|
101
101
|
|
|
102
102
|
### 🗂️ PAGE
|
|
103
103
|
|
package/src/lib/img/qr/vcard.png
CHANGED
|
Binary file
|
|
Binary file
|
package/src/lib/index.js
CHANGED
|
@@ -313,8 +313,8 @@ This file is part of Network Pro.
|
|
|
313
313
|
</p>
|
|
314
314
|
|
|
315
315
|
<p>
|
|
316
|
-
{COMPANY_INFO.APP_NAME} is free software: you can redistribute it and/or
|
|
317
|
-
|
|
316
|
+
{COMPANY_INFO.APP_NAME} is free software: you can redistribute it and/or modify
|
|
317
|
+
it under the terms of the
|
|
318
318
|
<strong>GNU General Public License</strong> (GNU GPL) as published by
|
|
319
319
|
the
|
|
320
320
|
<a rel={PAGE.REL} href="https://fsf.org" target={PAGE.BLANK}
|
|
@@ -163,8 +163,8 @@ This file is part of Network Pro.
|
|
|
163
163
|
{COMPANY_INFO.NAME} ("Company," "we," "us," or "our") is committed to protecting
|
|
164
164
|
the privacy of clients and website visitors. This Privacy Policy outlines
|
|
165
165
|
how we collect, use, and safeguard your information when you interact with
|
|
166
|
-
our website or services, consistent with applicable U.S. federal law and
|
|
167
|
-
|
|
166
|
+
our website or services, consistent with applicable U.S. federal law and Arizona
|
|
167
|
+
law, including Title 18, Chapter 5, Article 4 of the
|
|
168
168
|
<strong>
|
|
169
169
|
<a
|
|
170
170
|
rel={PAGE.REL}
|
|
@@ -222,8 +222,8 @@ This file is part of Network Pro.
|
|
|
222
222
|
opt-out and opt-in settings stored as browser cookies. These settings
|
|
223
223
|
override any Do Not Track (DNT) or Global Privacy Control (GPC) signals. <strong
|
|
224
224
|
>If you opt out, analytics tracking via PostHog is disabled entirely
|
|
225
|
-
until you change your preference.</strong> Your selection will persist
|
|
226
|
-
|
|
225
|
+
until you change your preference.</strong> Your selection will persist until
|
|
226
|
+
manually updated.
|
|
227
227
|
</p>
|
|
228
228
|
<p class="emphasis">
|
|
229
229
|
For convenient access, you can manage these settings through our <a
|
|
@@ -367,10 +367,10 @@ This file is part of Network Pro.
|
|
|
367
367
|
<strong>Business Transfers</strong>: In the event of a merger,
|
|
368
368
|
acquisition, or sale of assets, personal and business information may
|
|
369
369
|
be transferred
|
|
370
|
-
<em>only if the receiving party provides written assurances</em> that:
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
370
|
+
<em>only if the receiving party provides written assurances</em> that: (a)
|
|
371
|
+
the information will not be sold or misused, (b) it will be handled in a
|
|
372
|
+
manner consistent with our privacy commitments, and (c) appropriate technical
|
|
373
|
+
and contractual safeguards are in place to protect it.
|
|
374
374
|
</li>
|
|
375
375
|
</ul>
|
|
376
376
|
<p>
|
|
@@ -402,8 +402,8 @@ This file is part of Network Pro.
|
|
|
402
402
|
|
|
403
403
|
<ul>
|
|
404
404
|
<li>
|
|
405
|
-
<strong>Access, correct, or delete</strong> your personal information,
|
|
406
|
-
|
|
405
|
+
<strong>Access, correct, or delete</strong> your personal information, subject
|
|
406
|
+
to legal and contractual limitations;
|
|
407
407
|
</li>
|
|
408
408
|
<li>
|
|
409
409
|
<strong
|
|
@@ -445,10 +445,10 @@ This file is part of Network Pro.
|
|
|
445
445
|
</p>
|
|
446
446
|
{:else if link.id === 'disclaimers'}
|
|
447
447
|
<p>
|
|
448
|
-
{COMPANY_INFO.NAME} offers informational content as a public service. No
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
448
|
+
{COMPANY_INFO.NAME} offers informational content as a public service. No warranties
|
|
449
|
+
are made regarding the accuracy or completeness of such content. Consulting
|
|
450
|
+
services are governed by separate contracts. We disclaim liability for third-party
|
|
451
|
+
services integrated or referenced.
|
|
452
452
|
</p>
|
|
453
453
|
{:else if link.id === 'changes'}
|
|
454
454
|
<p>
|
|
@@ -197,8 +197,8 @@ This file is part of Network Pro.
|
|
|
197
197
|
<p>
|
|
198
198
|
{COMPANY_INFO.NAME} is based in Maricopa County, Arizona. Any legal action
|
|
199
199
|
or dispute arising from these Terms of Use shall be subject to the exclusive
|
|
200
|
-
jurisdiction of the state and federal courts located in Maricopa County,
|
|
201
|
-
|
|
200
|
+
jurisdiction of the state and federal courts located in Maricopa County, Arizona.
|
|
201
|
+
These Terms shall be governed by the
|
|
202
202
|
<strong>Arizona Revised Statutes (A.R.S.)</strong> and applicable
|
|
203
203
|
provisions of the <strong>United States Code (U.S.C.)</strong>.
|
|
204
204
|
</p>
|
package/src/lib/utils/purify.js
CHANGED
|
@@ -10,9 +10,9 @@ This file is part of Network Pro.
|
|
|
10
10
|
* @file purify.js
|
|
11
11
|
* @description Universal DOMPurify instance for SSR + client with safe build support.
|
|
12
12
|
* Secures untrusted HTML before injecting it into the DOM.
|
|
13
|
-
* @module src/lib/utils
|
|
13
|
+
* @module src/lib/utils
|
|
14
14
|
* @author Scott Lopez
|
|
15
|
-
* @updated 2025-
|
|
15
|
+
* @updated 2025-12-11
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import createDOMPurify from 'dompurify';
|
|
@@ -37,11 +37,11 @@ let jsdomWindow = null;
|
|
|
37
37
|
export async function getDOMPurify() {
|
|
38
38
|
if (DOMPurifyInstance) return DOMPurifyInstance;
|
|
39
39
|
|
|
40
|
-
if (
|
|
40
|
+
if (!import.meta.env.SSR) {
|
|
41
41
|
// ✅ Client-side: use native window
|
|
42
42
|
DOMPurifyInstance = createDOMPurify(window);
|
|
43
43
|
} else {
|
|
44
|
-
// ✅ SSR: dynamically import jsdom
|
|
44
|
+
// ✅ SSR: dynamically import jsdom — gated so Vite will tree-shake it from the client bundle
|
|
45
45
|
const { JSDOM } = await import('jsdom');
|
|
46
46
|
jsdomWindow = jsdomWindow || new JSDOM('').window;
|
|
47
47
|
DOMPurifyInstance = createDOMPurify(jsdomWindow);
|
package/src/service-worker.js
CHANGED
|
@@ -6,18 +6,20 @@ 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
|
-
|
|
9
|
+
/// <reference lib="webworker" />
|
|
10
|
+
/// <reference types="vite/client" />
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {ServiceWorkerGlobalScope}
|
|
14
|
+
*/
|
|
10
15
|
const sw = /** @type {ServiceWorkerGlobalScope} */ (
|
|
11
16
|
/** @type {unknown} */ (self)
|
|
12
17
|
);
|
|
13
18
|
|
|
14
|
-
/// <reference types="vite/client" />
|
|
15
|
-
|
|
16
19
|
const isDev = location.hostname === 'localhost';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
];
|
|
20
|
+
|
|
21
|
+
/** @type {string[]} */
|
|
22
|
+
const disallowedHosts = ['us.i.posthog.com', 'posthog.com'];
|
|
21
23
|
|
|
22
24
|
import { build, files, version } from '$service-worker';
|
|
23
25
|
|
|
@@ -27,6 +29,7 @@ const CACHE = `cache-${version}`;
|
|
|
27
29
|
/** @type {string[]} */
|
|
28
30
|
const excludedAssets = [];
|
|
29
31
|
|
|
32
|
+
/** @type {Set<string>} */
|
|
30
33
|
const IGNORE_PATHS = new Set([
|
|
31
34
|
'/.well-known/security.txt.sig',
|
|
32
35
|
'/img/banner-1280x640.png',
|
|
@@ -76,6 +79,7 @@ const ASSETS = [
|
|
|
76
79
|
),
|
|
77
80
|
];
|
|
78
81
|
|
|
82
|
+
/** @type {string[]} */
|
|
79
83
|
const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
|
|
80
84
|
|
|
81
85
|
/** @type {string[]} */
|
|
@@ -108,12 +112,12 @@ if (isDev) {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
/**
|
|
111
|
-
* Safely cache a list of assets
|
|
115
|
+
* Safely cache a list of assets.
|
|
112
116
|
*
|
|
113
117
|
* @param {Cache} cache
|
|
114
118
|
* @param {string[]} assets
|
|
115
|
-
* @param {string[]} required
|
|
116
|
-
* @returns {Promise<string[]>}
|
|
119
|
+
* @param {string[]} [required=[]]
|
|
120
|
+
* @returns {Promise<string[]>}
|
|
117
121
|
*/
|
|
118
122
|
async function cacheAssetsSafely(cache, assets, required = []) {
|
|
119
123
|
/** @type {string[]} */
|
|
@@ -150,6 +154,9 @@ async function cacheAssetsSafely(cache, assets, required = []) {
|
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
// 🔹 Install event
|
|
157
|
+
/**
|
|
158
|
+
* @param {ExtendableEvent} event
|
|
159
|
+
*/
|
|
153
160
|
sw.addEventListener('install', (event) => {
|
|
154
161
|
if (isDev) console.log('[SW] Install event');
|
|
155
162
|
|
|
@@ -160,9 +167,7 @@ sw.addEventListener('install', (event) => {
|
|
|
160
167
|
|
|
161
168
|
try {
|
|
162
169
|
cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
|
|
163
|
-
if (isDev)
|
|
164
|
-
console.log('[SW] Cached assets:', cachedPaths);
|
|
165
|
-
}
|
|
170
|
+
if (isDev) console.log('[SW] Cached assets:', cachedPaths);
|
|
166
171
|
} catch (err) {
|
|
167
172
|
if (isDev) throw err;
|
|
168
173
|
console.warn('[SW] Error while precaching (non-fatal in prod):', err);
|
|
@@ -175,8 +180,12 @@ sw.addEventListener('install', (event) => {
|
|
|
175
180
|
});
|
|
176
181
|
|
|
177
182
|
// 🔹 Activate event
|
|
183
|
+
/**
|
|
184
|
+
* @param {ExtendableEvent} event
|
|
185
|
+
*/
|
|
178
186
|
sw.addEventListener('activate', (event) => {
|
|
179
187
|
if (isDev) console.log('[SW] Activate event');
|
|
188
|
+
|
|
180
189
|
event.waitUntil(
|
|
181
190
|
(async () => {
|
|
182
191
|
const tasks = [];
|
|
@@ -210,9 +219,7 @@ sw.addEventListener('activate', (event) => {
|
|
|
210
219
|
});
|
|
211
220
|
|
|
212
221
|
/**
|
|
213
|
-
* Determine if a request should be
|
|
214
|
-
* Specifically filters out dev/build files, module imports, and source files.
|
|
215
|
-
* Only active in development mode.
|
|
222
|
+
* Determine if a request should be ignored during development.
|
|
216
223
|
*
|
|
217
224
|
* @param {URL} url
|
|
218
225
|
* @returns {boolean}
|
|
@@ -230,13 +237,13 @@ function shouldSkipDevModule(url) {
|
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
// 🔹 Fetch event
|
|
240
|
+
/**
|
|
241
|
+
* @param {FetchEvent} event
|
|
242
|
+
*/
|
|
233
243
|
sw.addEventListener('fetch', (event) => {
|
|
234
244
|
const requestUrl = new URL(event.request.url);
|
|
235
245
|
|
|
236
|
-
// ✅ Skip cross-origin requests
|
|
237
246
|
if (requestUrl.origin !== location.origin) return;
|
|
238
|
-
|
|
239
|
-
// ✅ Skip internal dev/module files (only in dev)
|
|
240
247
|
if (shouldSkipDevModule(requestUrl)) return;
|
|
241
248
|
|
|
242
249
|
if (isDev) console.log('[SW] Fetch intercepted:', event.request.url);
|
|
@@ -253,12 +260,8 @@ sw.addEventListener('fetch', (event) => {
|
|
|
253
260
|
if (event.request.mode === 'navigate') {
|
|
254
261
|
const preloadResponse = await event.preloadResponse;
|
|
255
262
|
if (preloadResponse) {
|
|
256
|
-
if (isDev)
|
|
257
|
-
console.log(
|
|
258
|
-
'[SW] Using preload response for:',
|
|
259
|
-
event.request.url,
|
|
260
|
-
);
|
|
261
|
-
}
|
|
263
|
+
if (isDev)
|
|
264
|
+
console.log('[SW] Using preload response:', event.request.url);
|
|
262
265
|
return preloadResponse;
|
|
263
266
|
}
|
|
264
267
|
}
|
|
@@ -267,18 +270,17 @@ sw.addEventListener('fetch', (event) => {
|
|
|
267
270
|
console.log('[SW] Fetching from network:', event.request.url);
|
|
268
271
|
|
|
269
272
|
return await fetch(event.request);
|
|
270
|
-
} catch (
|
|
271
|
-
if (isDev)
|
|
273
|
+
} catch (_err) {
|
|
274
|
+
if (isDev)
|
|
272
275
|
console.warn(
|
|
273
|
-
'[SW] Fetch failed; offline fallback
|
|
276
|
+
'[SW] Fetch failed; offline fallback:',
|
|
274
277
|
event.request.url,
|
|
275
|
-
err,
|
|
276
278
|
);
|
|
277
|
-
}
|
|
278
279
|
|
|
279
280
|
if (event.request.mode === 'navigate') {
|
|
280
281
|
const offline = await caches.match('/offline.html');
|
|
281
282
|
if (offline) return offline;
|
|
283
|
+
|
|
282
284
|
return new Response('<h1>Offline</h1>', {
|
|
283
285
|
headers: { 'Content-Type': 'text/html' },
|
|
284
286
|
});
|
|
@@ -289,5 +291,3 @@ sw.addEventListener('fetch', (event) => {
|
|
|
289
291
|
})(),
|
|
290
292
|
);
|
|
291
293
|
});
|
|
292
|
-
|
|
293
|
-
// @cspell:ignore precaching
|
package/static/bin/contact.vcf
CHANGED
|
@@ -2,11 +2,11 @@ BEGIN:VCARD
|
|
|
2
2
|
VERSION:3.0
|
|
3
3
|
FN:Scott Lopez
|
|
4
4
|
N:Lopez;Scott
|
|
5
|
-
TEL;TYPE=WORK,PREF=1:(
|
|
5
|
+
TEL;TYPE=WORK,PREF=1:(602) 428-5300
|
|
6
6
|
EMAIL;TYPE=WORK:support@netwk.pro
|
|
7
7
|
EMAIL;TYPE=Secure:business@s.neteng.pro
|
|
8
8
|
ADR;TYPE=WORK:;;Peoria\, AZ 85382\nUS
|
|
9
9
|
ORG:Network Pro Strategies
|
|
10
|
-
TITLE:Network Engineer
|
|
10
|
+
TITLE:Network Engineer and Consultant
|
|
11
11
|
URL:https://netwk.pro
|
|
12
12
|
END:VCARD
|
package/static/sitemap.xml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!-- Sitemap last updated 2025-11
|
|
2
|
+
<!-- Sitemap last updated 2025-12-11 -->
|
|
3
3
|
|
|
4
4
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<loc>https://netwk.pro</loc>
|
|
9
9
|
|
|
10
|
-
<lastmod>2025-11
|
|
10
|
+
<lastmod>2025-12-11</lastmod>
|
|
11
11
|
|
|
12
12
|
<changefreq>weekly</changefreq>
|
|
13
13
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tests/unit/server/ssrBoundary.test.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 ssrBoundary.test.js
|
|
11
|
+
* @description Checks for improper usage of Node
|
|
12
|
+
* @module tests/unit/server/internal
|
|
13
|
+
* @author Scott Lopez
|
|
14
|
+
* @updated 2025-12-11
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// @vitest-environment node
|
|
18
|
+
|
|
19
|
+
import fs from 'fs/promises';
|
|
20
|
+
import { globby } from 'globby';
|
|
21
|
+
|
|
22
|
+
// Node-only modules that cannot appear in client-visible code
|
|
23
|
+
const NODE_ONLY_IMPORTS = [
|
|
24
|
+
'fs',
|
|
25
|
+
'path',
|
|
26
|
+
'url',
|
|
27
|
+
'crypto',
|
|
28
|
+
'os',
|
|
29
|
+
'child_process',
|
|
30
|
+
'module',
|
|
31
|
+
'jsdom',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
// Files in these locations are ALWAYS allowed to use Node-only modules
|
|
35
|
+
const SERVER_ONLY_ALLOWLIST = [
|
|
36
|
+
'src/lib/server/',
|
|
37
|
+
'/server/',
|
|
38
|
+
'+server.js',
|
|
39
|
+
'+server.ts',
|
|
40
|
+
'.test.',
|
|
41
|
+
'.spec.',
|
|
42
|
+
'vitest.config',
|
|
43
|
+
'playwright.config',
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
function isServerOnlyFile(filePath) {
|
|
47
|
+
return SERVER_ONLY_ALLOWLIST.some((key) => filePath.includes(key));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Regex helpers
|
|
51
|
+
function createStaticImportRegex(moduleName) {
|
|
52
|
+
return new RegExp(`import\\s+[^;]*['"]${moduleName}['"]`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function createDynamicImportRegex(moduleName) {
|
|
56
|
+
return new RegExp(`import\\(['"]${moduleName}['"]\\)`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hasSSRGuard(text) {
|
|
60
|
+
// Basic detection of SSR guard presence
|
|
61
|
+
// Stronger variants are possible, but this avoids false positives
|
|
62
|
+
return /import\.meta\.env\.SSR/.test(text);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
test('no Node-only modules leak into client-visible modules', async () => {
|
|
66
|
+
const files = await globby([
|
|
67
|
+
'src/**/*.{js,ts,svelte}',
|
|
68
|
+
'!src/lib/server/**', // ignore server-only utilities
|
|
69
|
+
'!**/*.test.*',
|
|
70
|
+
'!**/*.spec.*',
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
const violations = [];
|
|
74
|
+
|
|
75
|
+
for (const file of files) {
|
|
76
|
+
if (isServerOnlyFile(file)) continue;
|
|
77
|
+
|
|
78
|
+
const text = await fs.readFile(file, 'utf8');
|
|
79
|
+
|
|
80
|
+
for (const mod of NODE_ONLY_IMPORTS) {
|
|
81
|
+
const staticMatch = createStaticImportRegex(mod).test(text);
|
|
82
|
+
const dynamicMatch = createDynamicImportRegex(mod).test(text);
|
|
83
|
+
|
|
84
|
+
if (!staticMatch && !dynamicMatch) continue;
|
|
85
|
+
|
|
86
|
+
// If SSR guarded, allow it
|
|
87
|
+
if (hasSSRGuard(text)) continue;
|
|
88
|
+
|
|
89
|
+
violations.push({
|
|
90
|
+
file,
|
|
91
|
+
module: mod,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (violations.length > 0) {
|
|
97
|
+
const formatted = violations
|
|
98
|
+
.map((v) => `❌ ${v.module} imported in ${v.file}`)
|
|
99
|
+
.join('\n');
|
|
100
|
+
|
|
101
|
+
throw new Error(
|
|
102
|
+
'SSR boundary violations detected:\n' +
|
|
103
|
+
formatted +
|
|
104
|
+
'\n\nTo fix: move to src/lib/server/, or wrap the import in import.meta.env.SSR.',
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
});
|
package/static/CNAME
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
netwk.pro
|