@networkpro/web 1.12.9 → 1.13.1

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 (108) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/README.md +26 -18
  3. package/cspell.json +1 -0
  4. package/eslint.config.mjs +48 -48
  5. package/netlify/edge-functions/csp-report.js +31 -31
  6. package/package.json +3 -3
  7. package/playwright.config.js +14 -14
  8. package/postcss.config.mjs +1 -1
  9. package/scripts/auditScripts.js +16 -16
  10. package/scripts/bundleCss.js +5 -5
  11. package/scripts/checkEnv.js +6 -6
  12. package/scripts/checkNode.js +10 -10
  13. package/scripts/checkVersions.js +6 -6
  14. package/scripts/flattenHeaders.js +13 -13
  15. package/scripts/generateTest.js +5 -5
  16. package/scripts/openReport.js +3 -3
  17. package/scripts/validateHeaders.js +13 -13
  18. package/src/app.html +0 -9
  19. package/src/hooks.client.ts +1 -1
  20. package/src/hooks.server.js +31 -32
  21. package/src/lib/components/Badges.svelte +10 -10
  22. package/src/lib/components/CodeBlock.svelte +1 -1
  23. package/src/lib/components/ContainerSection.svelte +1 -1
  24. package/src/lib/components/FullWidthSection.svelte +3 -3
  25. package/src/lib/components/LegalNav.svelte +7 -7
  26. package/src/lib/components/Logo.svelte +9 -9
  27. package/src/lib/components/MetaTags.svelte +4 -4
  28. package/src/lib/components/PWAInstallButton.svelte +4 -4
  29. package/src/lib/components/RedirectPage.svelte +4 -4
  30. package/src/lib/components/SocialMedia.svelte +16 -16
  31. package/src/lib/components/foss/FossItemContent.svelte +27 -58
  32. package/src/lib/components/foss/ObtainiumBlock.svelte +64 -0
  33. package/src/lib/components/layout/Footer.svelte +18 -18
  34. package/src/lib/components/layout/HeaderDefault.svelte +16 -16
  35. package/src/lib/components/layout/HeaderHome.svelte +14 -14
  36. package/src/lib/data/fossData.js +22 -10
  37. package/src/lib/images.js +34 -34
  38. package/src/lib/img/obtainium.png +0 -0
  39. package/src/lib/img/obtainium.webp +0 -0
  40. package/src/lib/index.js +15 -15
  41. package/src/lib/meta.js +29 -29
  42. package/src/lib/pages/AboutContent.svelte +24 -24
  43. package/src/lib/pages/FossContent.svelte +13 -13
  44. package/src/lib/pages/HomeContent.svelte +7 -7
  45. package/src/lib/pages/LicenseContent.svelte +39 -39
  46. package/src/lib/pages/PGPContent.svelte +23 -23
  47. package/src/lib/pages/PrivacyContent.svelte +39 -39
  48. package/src/lib/pages/PrivacyDashboard.svelte +12 -12
  49. package/src/lib/pages/TermsConditionsContent.svelte +29 -29
  50. package/src/lib/pages/TermsUseContent.svelte +26 -26
  51. package/src/lib/registerServiceWorker.js +25 -25
  52. package/src/lib/stores/posthog.js +13 -13
  53. package/src/lib/stores/trackingPreferences.js +19 -19
  54. package/src/lib/styles/css/default.css +30 -0
  55. package/src/lib/styles/global.min.css +1 -1
  56. package/src/lib/types/fossTypes.js +9 -2
  57. package/src/lib/unregisterServiceWorker.js +1 -1
  58. package/src/lib/utils/purify.js +4 -4
  59. package/src/lib/utils/utm.js +2 -2
  60. package/src/routes/+error.svelte +4 -4
  61. package/src/routes/+layout.js +6 -6
  62. package/src/routes/+layout.svelte +29 -29
  63. package/src/routes/+page.server.js +2 -2
  64. package/src/routes/+page.svelte +9 -9
  65. package/src/routes/about/+page.server.js +2 -2
  66. package/src/routes/about/+page.svelte +7 -7
  67. package/src/routes/api/mock-csp/+server.js +3 -3
  68. package/src/routes/consultation/+page.svelte +5 -5
  69. package/src/routes/contact/+page.svelte +5 -5
  70. package/src/routes/foss-spotlight/+page.server.js +2 -2
  71. package/src/routes/foss-spotlight/+page.svelte +7 -7
  72. package/src/routes/license/+page.server.js +2 -2
  73. package/src/routes/license/+page.svelte +7 -7
  74. package/src/routes/pgp/+page.server.js +2 -2
  75. package/src/routes/pgp/+page.svelte +7 -7
  76. package/src/routes/pgp/[key]/+server.js +9 -9
  77. package/src/routes/privacy/+page.server.js +2 -2
  78. package/src/routes/privacy/+page.svelte +7 -7
  79. package/src/routes/privacy-dashboard/+page.server.js +2 -2
  80. package/src/routes/privacy-dashboard/+page.svelte +8 -8
  81. package/src/routes/privacy-rights/+page.svelte +5 -5
  82. package/src/routes/status/+page.server.js +2 -2
  83. package/src/routes/terms-conditions/+page.server.js +2 -2
  84. package/src/routes/terms-conditions/+page.svelte +7 -7
  85. package/src/routes/terms-of-use/+page.server.js +2 -2
  86. package/src/routes/terms-of-use/+page.svelte +7 -7
  87. package/src/service-worker.js +86 -86
  88. package/static/bin/heliboard.json +8 -0
  89. package/static/disableSw.js +2 -2
  90. package/static/offline.html +7 -7
  91. package/stylelint.config.js +56 -56
  92. package/svelte.config.js +6 -6
  93. package/tests/e2e/app.spec.js +27 -27
  94. package/tests/e2e/mobile.spec.js +18 -18
  95. package/tests/e2e/shared/helpers.js +4 -4
  96. package/tests/internal/auditCoverage.test.js +24 -24
  97. package/tests/unit/checkEnv.test.js +10 -10
  98. package/tests/unit/checkVersions.test.js +4 -4
  99. package/tests/unit/csp-report.test.js +24 -24
  100. package/tests/unit/demo.test.js +3 -3
  101. package/tests/unit/lib/utils/purify.test.js +12 -12
  102. package/tests/unit/routes/page.svelte.test.js +10 -10
  103. package/tests/unit/unregisterServiceWorker.test.js +5 -5
  104. package/tests/unit/utm.test.js +13 -13
  105. package/vite.config.js +5 -5
  106. package/vitest-setup-client.js +4 -4
  107. package/vitest.config.client.js +15 -15
  108. package/vitest.config.server.js +13 -13
package/CHANGELOG.md CHANGED
@@ -22,6 +22,68 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
22
22
 
23
23
  ---
24
24
 
25
+ ## [1.13.1] - 2025-06-12
26
+
27
+ ### Added
28
+
29
+ - Modularized `ObtainiumBlock.svelte` component for cleaner integration in `FossItemContent.svelte`
30
+ - `heliboard.json` Obtainium configuration file for download
31
+ - Dark mode-compatible styling for Obtainium blocks in the main stylesheet
32
+
33
+ ### Changed
34
+
35
+ - Version bumped to **v1.13.1**
36
+ - Removed unnecessary PostHog preload script from `app.html`
37
+ - Removed `script-src-elem 'self' 'unsafe-inline'` from CSP policy
38
+ - Replaced existing Obtainium images with optimized versions
39
+ - Revised `<title>` metadata for the root route
40
+ - Commented out debugging `console.log` statements in the following files:
41
+ - `Badges.svelte`
42
+ - `LegalNav.svelte`
43
+ - `MetaTags.svelte`
44
+ - `Footer.svelte`
45
+ - `FossItemContent.svelte`
46
+ - `FossContent.svelte`
47
+ - `HomeContent.svelte`
48
+ - `LicenseContent.svelte`
49
+ - `TermsConditionsContent.svelte`
50
+ - Revised type definitions in `src/lib/types/fossTypes.js`
51
+ - Added optional `obtainium` property to `FossItem`
52
+ - Removed unused `hideLabels` property
53
+ - Refactored `FossItemContent.svelte` to better support and display Obtainium download links and metadata
54
+ - Updated `README.md` to reflect the correct location of the `static/pgp/` directory
55
+ - Revised the `hooks.server.js` section in `README.md` to improve accuracy and reflect current CSP behavior
56
+ - Updated `tests/e2e/app.spec.js` to assert the correct title for the root route
57
+ - Upgraded dependencies:
58
+ - `posthog-js` `^1.250.2` → `^1.252.0`
59
+ - `eslint-plugin-jsdoc` `^50.8.0` → `^51.0.1`
60
+
61
+ ---
62
+
63
+ ## [1.13.0] - 2025-06-11
64
+
65
+ ### Added
66
+
67
+ - Introduced `/pgp` route to publish OpenPGP contact information, download links, and QR codes
68
+ - Added `.well-known/humans.txt` to document project authorship
69
+ - Added `.well-known/security.txt` to define the official security contact and vulnerability disclosure policy
70
+ - Linked OpenPGP keys to external directories for validation (e.g. keys.openpgp.org)
71
+ - Added new GitHub Actions workflow: `check-security-txt-expiry.yml` to monitor `security.txt` expiration
72
+
73
+ ### Changed
74
+
75
+ - Enforced `"singleQuote": true` in `.prettierrc` and formatted the codebase using Prettier
76
+ - Updated `src/service-worker.js` to exclude `security.txt.asc` from caching
77
+ - CSP policy updated to allow `clipboard-write` for improved UX on PGP fingerprint buttons
78
+ - Clarified that addresses under the `s.neteng.pro` domain are powered by Proton Mail and support native E2EE
79
+ - Revised `SECURITY.md` and `security.txt` with accurate Proton Mail usage notes and PGP policy references
80
+
81
+ ### Removed
82
+
83
+ - Legacy reference to a "coming soon" PGP section in `SECURITY.md` (now live and linked)
84
+
85
+ ---
86
+
25
87
  ## [1.12.9] - 2025-06-11
26
88
 
27
89
  ### Added
@@ -286,7 +348,9 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
286
348
 
287
349
  <!-- Link references -->
288
350
 
289
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.12.9...HEAD
351
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.13.1...HEAD
352
+ [1.13.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.1
353
+ [1.13.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.13.0
290
354
  [1.12.9]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.9
291
355
  [1.12.8]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.8
292
356
  [1.12.7]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.12.7
package/README.md CHANGED
@@ -77,16 +77,17 @@ This project follows the principles of [Keep a Changelog](https://keepachangelog
77
77
  │ │ └── csp-report.js # Receives CSP violation reports
78
78
  ├── scripts/ # General-purpose utility scripts
79
79
  ├── src/
80
- │ ├── app.html # Entry HTML (CSP meta, bootstrapping)
81
- │ ├── hooks.client.ts # Client-side error handling
82
- │ ├── hooks.server.js # Injects CSP headers and permissions policy
83
80
  │ ├── lib/ # Components, utilities, types, styles
84
81
  │ │ ├── components/ # Svelte components
85
82
  │ │ ├── data/ # Custom data (e.g. JSON, metadata, constants)
86
83
  │ │ └── utils/ # Helper utilities
87
84
  │ ├── routes/ # SvelteKit pages (+page.svelte, +server.js)
85
+ │ ├── app.html # Entry HTML (CSP meta, bootstrapping)
86
+ │ ├── hooks.client.ts # Client-side error handling
87
+ │ ├── hooks.server.js # Injects CSP headers and permissions policy
88
88
  │ └── service-worker.js # Custom PWA service worker
89
89
  ├── static/ # Public assets served at site root
90
+ │ ├── pgp/
90
91
  │ ├── disableSw.js # Service worker bypass (via ?nosw param)
91
92
  │ ├── manifest.json # PWA metadata
92
93
  │ ├── robots.txt # SEO: allow/disallow crawlers
@@ -180,6 +181,8 @@ ENV_MODE=dev # Options: dev, test, ci, preview, prod
180
181
 
181
182
  To streamline onboarding and enforce project conventions, you may use the optional helper scripts:
182
183
 
184
+ <!-- FIXME: Create a bootstrap.local.sh file -->
185
+
183
186
  | File/Script | Description |
184
187
  | ---------------------------------- | --------------------------------------------------------------------------------- |
185
188
  | `.env.template` | Template for local environment variables |
@@ -221,12 +224,12 @@ This script runs `scripts/checkNode.js`, which compares your current Node.js and
221
224
  **_Node Version Check (snippet from `scripts/checkNode.js`)_**
222
225
 
223
226
  ```javascript
224
- const semver = require("semver");
225
- const { engines } = require("../package.json");
227
+ const semver = require('semver');
228
+ const { engines } = require('../package.json');
226
229
 
227
230
  const requiredNode = engines.node;
228
231
  const requiredNpm = engines.npm;
229
- const isPostInstall = process.env.npm_lifecycle_event === "postinstall";
232
+ const isPostInstall = process.env.npm_lifecycle_event === 'postinstall';
230
233
 
231
234
  let hasError = false;
232
235
 
@@ -236,8 +239,8 @@ if (!semver.satisfies(process.version, requiredNode)) {
236
239
  if (!isPostInstall) hasError = true;
237
240
  }
238
241
 
239
- const npmVersion = require("child_process")
240
- .execSync("npm -v")
242
+ const npmVersion = require('child_process')
243
+ .execSync('npm -v')
241
244
  .toString()
242
245
  .trim();
243
246
 
@@ -248,7 +251,7 @@ if (!semver.satisfies(npmVersion, requiredNpm)) {
248
251
  }
249
252
 
250
253
  if (!hasError) {
251
- console.log("✅ Node and npm versions are valid.");
254
+ console.log('✅ Node and npm versions are valid.');
252
255
  } else {
253
256
  process.exit(1);
254
257
  }
@@ -279,16 +282,21 @@ This project includes custom runtime configuration files for enhancing security,
279
282
 
280
283
  Located at `src/hooks.server.js`, this file is responsible for injecting dynamic security headers. It includes:
281
284
 
282
- - Content Security Policy (CSP) with support for relaxed directives (inline scripts allowed)
283
- - Permissions Policy to explicitly disable unnecessary browser APIs
284
- - X-Content-Type-Options, X-Frame-Options, and Referrer-Policy headers
285
+ - A Content Security Policy (CSP) configured with relaxed directives to permit inline scripts and styles (`'unsafe-inline'`)
286
+ - A Permissions Policy to explicitly disable unnecessary browser APIs
287
+ - Standard security headers such as `X-Content-Type-Options`, `X-Frame-Options`, and `Referrer-Policy`
288
+
289
+ > ℹ️ A stricter CSP (excluding `'unsafe-inline'`) was attempted but reverted due to framework-level and third-party script compatibility issues. The current policy allows inline scripts to ensure stability across SvelteKit and analytics features such as PostHog.
290
+
291
+ #### Future Improvements
285
292
 
286
- > 💡 The CSP nonce feature has been disabled. Inline scripts are now allowed through the policy using the `"script-src 'self' 'unsafe-inline'"` directive. If you wish to use nonces in the future, you can re-enable them by uncommenting the relevant sections in `hooks.server.js` and modifying your inline `<script>` tags.
293
+ To implement a strict nonce-based CSP in the future:
287
294
 
288
- To re-enable nonce generation for inline scripts in the future:
295
+ 1. Add nonce generation and injection logic in `hooks.server.js`
296
+ 2. Update all inline `<script>` tags (e.g. in `app.html`) to include `nonce="__cspNonce__"`
297
+ 3. Ensure any analytics libraries or dynamic scripts support nonced or external loading
289
298
 
290
- 1. Uncomment the nonce generation and injection logic in `hooks.server.js`.
291
- 2. Add `nonce="__cspNonce__"` to inline `<script>` blocks in `app.html` or route templates.
299
+ Note: Strict CSP adoption may require restructuring third-party integrations and deeper framework coordination.
292
300
 
293
301
  > 💡 The `[headers]` block in `netlify.toml` has been deprecated — all headers are now set dynamically from within SvelteKit.
294
302
 
@@ -343,7 +351,7 @@ It unregisters **all active service worker registrations** and logs the result.
343
351
  Located at `static/disableSw.js`, this file sets a global flag if the URL contains the `?nosw` query parameter:
344
352
 
345
353
  ```js
346
- if (location.search.includes("nosw")) {
354
+ if (location.search.includes('nosw')) {
347
355
  window.__DISABLE_SW__ = true;
348
356
  }
349
357
  ```
@@ -365,7 +373,7 @@ https://netwk.pro/?nosw
365
373
  To register the service worker conditionally, call the function from client code:
366
374
 
367
375
  ```js
368
- import { registerServiceWorker } from "$lib/registerServiceWorker.js";
376
+ import { registerServiceWorker } from '$lib/registerServiceWorker.js';
369
377
 
370
378
  registerServiceWorker();
371
379
  ```
package/cspell.json CHANGED
@@ -44,6 +44,7 @@
44
44
  "netwk",
45
45
  "networkpro",
46
46
  "Nextcloud",
47
+ "nonced",
47
48
  "noopener",
48
49
  "noreferrer",
49
50
  "nosniff",
package/eslint.config.mjs CHANGED
@@ -6,57 +6,57 @@ 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 js from "@eslint/js"; // Provides ESLint core rules and recommended config
10
- import eslintConfigPrettier from "eslint-config-prettier"; // Prettier config to disable conflicting ESLint rules
11
- import jsdocPlugin from "eslint-plugin-jsdoc"; // JSDoc plugin
12
- import sveltePlugin from "eslint-plugin-svelte"; // Svelte plugin
13
- import globals from "globals";
14
- import svelteParser from "svelte-eslint-parser"; // Svelte parser
9
+ import js from '@eslint/js'; // Provides ESLint core rules and recommended config
10
+ import eslintConfigPrettier from 'eslint-config-prettier'; // Prettier config to disable conflicting ESLint rules
11
+ import jsdocPlugin from 'eslint-plugin-jsdoc'; // JSDoc plugin
12
+ import sveltePlugin from 'eslint-plugin-svelte'; // Svelte plugin
13
+ import globals from 'globals';
14
+ import svelteParser from 'svelte-eslint-parser'; // Svelte parser
15
15
 
16
16
  const GLOBALS = {
17
17
  ...globals.browser,
18
18
  ...globals.node,
19
- self: "readonly",
20
- location: "readonly",
21
- indexedDB: "readonly",
19
+ self: 'readonly',
20
+ location: 'readonly',
21
+ indexedDB: 'readonly',
22
22
  ...globals.vitest, // Add Vitest globals for test functions like afterEach, describe, etc.
23
23
  };
24
24
 
25
25
  // Define general ESLint rules (non-Svelte-specific)
26
26
  const ESLINT_RULES = {
27
- indent: "off", // Turn off the 'indent' rule, managed by Prettier
28
- quotes: "off", // Turn off the 'quotes' rule, managed by Prettier
29
- semi: "off", // Turn off the 'semi' rule, managed by Prettier
27
+ indent: 'off', // Turn off the 'indent' rule, managed by Prettier
28
+ quotes: 'off', // Turn off the 'quotes' rule, managed by Prettier
29
+ semi: 'off', // Turn off the 'semi' rule, managed by Prettier
30
30
  };
31
31
 
32
32
  export default [
33
33
  // Global ignores
34
34
  {
35
35
  ignores: [
36
- ".*", // Hidden files
37
- "*.xml", // XML files
38
- "**/.cache/**", // Cache directories
39
- "**/.vscode/**", // VSCode-specific files
40
- "**/coverage/**", // Coverage reports
41
- "**/build/**", // Distribution files
42
- "package.json", // NPM package manifest
43
- "package-lock.json", // NPM lockfile
44
- "**/playwright-report/**", // Playwright report files
45
- "node_modules/", // Node.js dependencies
46
- "**/test-results/**", // Test results
47
- ".vite/", // Vite-specific cache directory
48
- "*.lock", // Lock files
49
- ".env*", // Environment files
36
+ '.*', // Hidden files
37
+ '*.xml', // XML files
38
+ '**/.cache/**', // Cache directories
39
+ '**/.vscode/**', // VSCode-specific files
40
+ '**/coverage/**', // Coverage reports
41
+ '**/build/**', // Distribution files
42
+ 'package.json', // NPM package manifest
43
+ 'package-lock.json', // NPM lockfile
44
+ '**/playwright-report/**', // Playwright report files
45
+ 'node_modules/', // Node.js dependencies
46
+ '**/test-results/**', // Test results
47
+ '.vite/', // Vite-specific cache directory
48
+ '*.lock', // Lock files
49
+ '.env*', // Environment files
50
50
  ],
51
51
  },
52
52
 
53
53
  // General JavaScript/Node.js configuration
54
54
  {
55
- files: ["**/*.mjs", "**/*.js"],
55
+ files: ['**/*.mjs', '**/*.js'],
56
56
  languageOptions: {
57
57
  globals: GLOBALS,
58
- ecmaVersion: "latest",
59
- sourceType: "module",
58
+ ecmaVersion: 'latest',
59
+ sourceType: 'module',
60
60
  },
61
61
  plugins: {
62
62
  jsdoc: jsdocPlugin, // Include JSDoc plugin
@@ -65,21 +65,21 @@ 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
- "no-unused-vars": ["error", { argsIgnorePattern: "^_" }], // Ignore unused variables starting with an underscore
69
- "jsdoc/check-alignment": "warn", // Ensure JSDoc block tags are aligned
70
- "jsdoc/check-param-names": "warn", // Checks parameter names in JSDoc
68
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], // Ignore unused variables starting with an underscore
69
+ 'jsdoc/check-alignment': 'warn', // Ensure JSDoc block tags are aligned
70
+ 'jsdoc/check-param-names': 'warn', // Checks parameter names in JSDoc
71
71
  // Updated rule to allow the @updated tag
72
- "jsdoc/check-tag-names": [
73
- "warn",
72
+ 'jsdoc/check-tag-names': [
73
+ 'warn',
74
74
  {
75
- definedTags: ["updated"],
75
+ definedTags: ['updated'],
76
76
  },
77
77
  ],
78
- "jsdoc/check-types": "warn", // Checks if types in JSDoc are defined correctly
79
- "jsdoc/require-param": "warn", // Requires @param in JSDoc
80
- "jsdoc/require-returns": "warn", // Requires @returns in JSDoc
81
- "jsdoc/require-jsdoc": [
82
- "warn",
78
+ 'jsdoc/check-types': 'warn', // Checks if types in JSDoc are defined correctly
79
+ 'jsdoc/require-param': 'warn', // Requires @param in JSDoc
80
+ 'jsdoc/require-returns': 'warn', // Requires @returns in JSDoc
81
+ 'jsdoc/require-jsdoc': [
82
+ 'warn',
83
83
  {
84
84
  publicOnly: true,
85
85
  require: {
@@ -94,33 +94,33 @@ export default [
94
94
 
95
95
  // Svelte-specific configuration
96
96
  {
97
- files: ["**/*.svelte"],
97
+ files: ['**/*.svelte'],
98
98
  plugins: { svelte: sveltePlugin }, // Use imported Svelte plugin
99
99
  languageOptions: {
100
100
  parser: svelteParser, // Use imported Svelte parser
101
101
  globals: GLOBALS, // Your global variables
102
- ecmaVersion: "latest", // Use "latest" for Svelte to leverage modern features
103
- sourceType: "module",
102
+ ecmaVersion: 'latest', // Use "latest" for Svelte to leverage modern features
103
+ sourceType: 'module',
104
104
  },
105
105
  rules: {
106
106
  ...sveltePlugin.configs.recommended.rules, // Svelte recommended rules
107
107
  ...sveltePlugin.configs.prettier.rules, // Prettier compatibility for Svelte
108
- "svelte/no-at-html-tags": "warn", // Warn on use of @html (security risk)
109
- "svelte/require-optimized-style-attribute": "warn", // Recommend optimized style attributes
108
+ 'svelte/no-at-html-tags': 'warn', // Warn on use of @html (security risk)
109
+ 'svelte/require-optimized-style-attribute': 'warn', // Recommend optimized style attributes
110
110
  },
111
111
  },
112
112
 
113
113
  // Vitest-specific configuration
114
114
  {
115
- files: ["**/*.test.js", "**/*.spec.js", "**/vitest-setup-client.js"], // Test-related files
115
+ files: ['**/*.test.js', '**/*.spec.js', '**/vitest-setup-client.js'], // Test-related files
116
116
  languageOptions: {
117
117
  globals: {
118
118
  ...GLOBALS,
119
- afterEach: "readonly", // Explicitly declare afterEach as a global
119
+ afterEach: 'readonly', // Explicitly declare afterEach as a global
120
120
  },
121
121
  },
122
122
  rules: {
123
- "no-undef": "off", // Turn off no-undef for test globals
123
+ 'no-undef': 'off', // Turn off no-undef for test globals
124
124
  },
125
125
  },
126
126
  ];
@@ -27,29 +27,29 @@ This file is part of Network Pro.
27
27
  * @returns {Promise<Response>} HTTP Response with status 204 or 405
28
28
  */
29
29
  export default async (request, _context) => {
30
- if (request.method !== "POST") {
31
- return new Response("Method Not Allowed", { status: 405 });
30
+ if (request.method !== 'POST') {
31
+ return new Response('Method Not Allowed', { status: 405 });
32
32
  }
33
33
 
34
34
  try {
35
35
  const body = await request.json();
36
- const report = body["csp-report"];
36
+ const report = body['csp-report'];
37
37
 
38
38
  // Ignore if report is missing or malformed
39
- if (!report || typeof report !== "object") {
39
+ if (!report || typeof report !== 'object') {
40
40
  return new Response(null, { status: 204 });
41
41
  }
42
42
 
43
- const violated = report["violated-directive"] ?? "";
44
- const blockedUri = report["blocked-uri"] ?? "";
43
+ const violated = report['violated-directive'] ?? '';
44
+ const blockedUri = report['blocked-uri'] ?? '';
45
45
 
46
46
  // Filter: Skip img-src violations and empty URIs
47
47
  const ignored = [
48
- violated.startsWith("img-src"),
49
- blockedUri === "",
50
- blockedUri === "about",
51
- blockedUri.startsWith("chrome-extension://"),
52
- blockedUri.startsWith("moz-extension://"),
48
+ violated.startsWith('img-src'),
49
+ blockedUri === '',
50
+ blockedUri === 'about',
51
+ blockedUri.startsWith('chrome-extension://'),
52
+ blockedUri.startsWith('moz-extension://'),
53
53
  ].some(Boolean);
54
54
 
55
55
  if (ignored) {
@@ -60,15 +60,15 @@ export default async (request, _context) => {
60
60
  await sendToNtfy(violated, blockedUri, report);
61
61
 
62
62
  // Log useful violations
63
- console.log("[CSP-Edge] Violation:", {
63
+ console.log('[CSP-Edge] Violation:', {
64
64
  directive: violated,
65
65
  uri: blockedUri,
66
- referrer: report["referrer"],
67
- source: report["source-file"],
68
- line: report["line-number"],
66
+ referrer: report['referrer'],
67
+ source: report['source-file'],
68
+ line: report['line-number'],
69
69
  });
70
70
  } catch (err) {
71
- console.warn("[CSP-Edge] Failed to parse CSP report:", err.message);
71
+ console.warn('[CSP-Edge] Failed to parse CSP report:', err.message);
72
72
  }
73
73
 
74
74
  return new Response(null, { status: 204 });
@@ -87,13 +87,13 @@ const VIOLATION_TTL_MS = 60_000;
87
87
  */
88
88
  async function sendToNtfy(violated, blockedUri, report) {
89
89
  const highRiskDirectives = [
90
- "script-src",
91
- "form-action",
92
- "frame-ancestors",
93
- "base-uri",
90
+ 'script-src',
91
+ 'form-action',
92
+ 'frame-ancestors',
93
+ 'base-uri',
94
94
  ];
95
95
 
96
- const directiveKey = violated.split(" ")[0]; // strip fallback values or sources
96
+ const directiveKey = violated.split(' ')[0]; // strip fallback values or sources
97
97
  const isHighRisk = highRiskDirectives.includes(directiveKey);
98
98
  console.log(`[CSP-Edge] Checking directive: ${directiveKey}`);
99
99
  if (!isHighRisk) return;
@@ -120,23 +120,23 @@ async function sendToNtfy(violated, blockedUri, report) {
120
120
  }
121
121
  }
122
122
 
123
- const topicUrl = "https://ntfy.neteng.pro/csp-alerts";
123
+ const topicUrl = 'https://ntfy.neteng.pro/csp-alerts';
124
124
 
125
125
  const message = [
126
126
  `🚨 CSP Violation Detected`,
127
127
  `Directive: ${violated}`,
128
128
  `Blocked URI: ${blockedUri}`,
129
- `Referrer: ${report.referrer || "N/A"}`,
130
- `Source: ${report["source-file"] || "N/A"}`,
131
- `Line: ${report["line-number"] || "N/A"}`,
132
- ].join("\n");
129
+ `Referrer: ${report.referrer || 'N/A'}`,
130
+ `Source: ${report['source-file'] || 'N/A'}`,
131
+ `Line: ${report['line-number'] || 'N/A'}`,
132
+ ].join('\n');
133
133
 
134
134
  await fetch(topicUrl, {
135
- method: "POST",
135
+ method: 'POST',
136
136
  headers: {
137
- "Content-Type": "text/plain",
138
- "X-Title": "High-Risk CSP Violation",
139
- "X-Priority": "5",
137
+ 'Content-Type': 'text/plain',
138
+ 'X-Title': 'High-Risk CSP Violation',
139
+ 'X-Priority': '5',
140
140
  },
141
141
  body: message,
142
142
  });
@@ -147,5 +147,5 @@ async function sendToNtfy(violated, blockedUri, report) {
147
147
  * This sets the endpoint route to /api/csp-report
148
148
  */
149
149
  export const config = {
150
- path: "/api/csp-report",
150
+ path: '/api/csp-report',
151
151
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.12.9",
4
+ "version": "1.13.1",
5
5
  "description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advisory",
@@ -80,7 +80,7 @@
80
80
  },
81
81
  "dependencies": {
82
82
  "dompurify": "^3.2.6",
83
- "posthog-js": "^1.250.2",
83
+ "posthog-js": "^1.252.0",
84
84
  "semver": "^7.7.2",
85
85
  "svelte": "5.34.1"
86
86
  },
@@ -99,7 +99,7 @@
99
99
  "browserslist": "^4.25.0",
100
100
  "eslint": "^9.28.0",
101
101
  "eslint-config-prettier": "^10.1.5",
102
- "eslint-plugin-jsdoc": "^50.8.0",
102
+ "eslint-plugin-jsdoc": "^51.0.1",
103
103
  "eslint-plugin-svelte": "^3.9.2",
104
104
  "globals": "^16.2.0",
105
105
  "jsdom": "^26.1.0",
@@ -7,14 +7,14 @@ This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
9
  // @ts-check
10
- import { defineConfig, devices } from "@playwright/test";
10
+ import { defineConfig, devices } from '@playwright/test';
11
11
 
12
12
  /**
13
13
  * @see https://playwright.dev/docs/test-configuration
14
14
  */
15
15
  export default defineConfig({
16
- testDir: "./tests/e2e",
17
- testMatch: "*.spec.js",
16
+ testDir: './tests/e2e',
17
+ testMatch: '*.spec.js',
18
18
 
19
19
  /* Run tests in files in parallel */
20
20
  fullyParallel: true,
@@ -29,12 +29,12 @@ export default defineConfig({
29
29
  workers: process.env.CI ? 1 : undefined,
30
30
 
31
31
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
32
- reporter: "html",
32
+ reporter: 'html',
33
33
 
34
34
  /* Shared settings for all projects */
35
35
  use: {
36
- baseURL: "http://localhost:4173?nosw", // Update to use preview server URL
37
- trace: "on-first-retry",
36
+ baseURL: 'http://localhost:4173?nosw', // Update to use preview server URL
37
+ trace: 'on-first-retry',
38
38
  timeout: 60000, // Default action timeout of 60 seconds for each step
39
39
  navigationTimeout: 60000, // Timeout for navigation operations
40
40
  },
@@ -43,16 +43,16 @@ export default defineConfig({
43
43
  projects: [
44
44
  // Desktop Browsers
45
45
  {
46
- name: "chromium",
46
+ name: 'chromium',
47
47
  use: {
48
- browserName: "chromium", // Use Chromium browser
48
+ browserName: 'chromium', // Use Chromium browser
49
49
  headless: true, // Enable true headless mode
50
50
  },
51
51
  },
52
52
  {
53
- name: "firefox",
53
+ name: 'firefox',
54
54
  use: {
55
- ...devices["Desktop Firefox"], // Use default Firefox settings
55
+ ...devices['Desktop Firefox'], // Use default Firefox settings
56
56
  },
57
57
  },
58
58
  // FIXME: Webkit and Safari consistently failing, disabled for now
@@ -65,9 +65,9 @@ export default defineConfig({
65
65
 
66
66
  // Mobile Browsers
67
67
  {
68
- name: "Mobile Chrome",
68
+ name: 'Mobile Chrome',
69
69
  use: {
70
- ...devices["Galaxy S9+"], // Use the Galaxy S9+ device profile
70
+ ...devices['Galaxy S9+'], // Use the Galaxy S9+ device profile
71
71
  headless: true, // Enable true headless mode
72
72
  },
73
73
  },
@@ -82,8 +82,8 @@ export default defineConfig({
82
82
 
83
83
  /* Run your local preview server before starting the tests */
84
84
  webServer: {
85
- command: "npm run preview", // Use preview server
86
- url: "http://localhost:4173?nosw", // Match the preview server URL
85
+ command: 'npm run preview', // Use preview server
86
+ url: 'http://localhost:4173?nosw', // Match the preview server URL
87
87
  reuseExistingServer: !process.env.CI,
88
88
  timeout: 60 * 1000, // wait up to 60 seconds for preview to be ready
89
89
  },
@@ -6,7 +6,7 @@ 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 autoprefixer from "autoprefixer";
9
+ import autoprefixer from 'autoprefixer';
10
10
 
11
11
  export default {
12
12
  plugins: [