@networkpro/web 1.7.4 → 1.7.9

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/_redirects CHANGED
@@ -1,2 +1,5 @@
1
1
  https://www.netwk.pro/* https://netwk.pro/:splat 301
2
2
  /privacy-policy /privacy 301
3
+
4
+ # New redirect for Netlify function proxy
5
+ /api/* /.netlify/functions/:splat 200
package/budget.json ADDED
@@ -0,0 +1,34 @@
1
+ [
2
+ {
3
+ "path": "/*",
4
+ "resourceSizes": [
5
+ { "resourceType": "script", "budget": 300 },
6
+ { "resourceType": "stylesheet", "budget": 100 },
7
+ { "resourceType": "image", "budget": 350 },
8
+ { "resourceType": "font", "budget": 200 },
9
+ { "resourceType": "other", "budget": 150 },
10
+ { "resourceType": "document", "budget": 50 },
11
+ { "resourceType": "total", "budget": 1000 }
12
+ ],
13
+ "resourceCounts": [
14
+ { "resourceType": "third-party", "budget": 15 },
15
+ { "resourceType": "script", "budget": 15 },
16
+ { "resourceType": "stylesheet", "budget": 5 },
17
+ { "resourceType": "image", "budget": 15 },
18
+ { "resourceType": "font", "budget": 10 },
19
+ { "resourceType": "other", "budget": 10 },
20
+ { "resourceType": "total", "budget": 60 }
21
+ ]
22
+ },
23
+ {
24
+ "path": "/foss-spotlight",
25
+ "resourceSizes": [
26
+ { "resourceType": "image", "budget": 500 },
27
+ { "resourceType": "total", "budget": 1200 }
28
+ ],
29
+ "resourceCounts": [
30
+ { "resourceType": "image", "budget": 25 },
31
+ { "resourceType": "total", "budget": 75 }
32
+ ]
33
+ }
34
+ ]
package/cspell.json CHANGED
@@ -12,6 +12,7 @@
12
12
  "Embedder",
13
13
  "Ente",
14
14
  "esbuild",
15
+ "fontawesome",
15
16
  "foss",
16
17
  "geolocation",
17
18
  "heliboard",
@@ -39,6 +40,7 @@
39
40
  "SIEM",
40
41
  "SPDY",
41
42
  "stylelintignore",
43
+ "stylesheet",
42
44
  "Subsite",
43
45
  "subsites",
44
46
  "Supercookie",
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "sideEffects": [
5
5
  "./.netlify/shims.js"
6
6
  ],
7
- "version": "1.7.4",
7
+ "version": "1.7.9",
8
8
  "description": "Locking Down Networks, Unlocking Confidence | Security, Networking, Privacy — Network Pro Strategies",
9
9
  "keywords": [
10
10
  "advisory",
@@ -21,14 +21,11 @@ export async function handle({ event, resolve }) {
21
21
  const isProdEnvironment =
22
22
  process.env.NODE_ENV === "production" || process.env.ENV_MODE === "prod";
23
23
 
24
- if (!isProdEnvironment) {
25
- console.log("ENV_MODE:", process.env.ENV_MODE);
26
- }
24
+ console.log("[CSP Debug] NODE_ENV:", process.env.NODE_ENV);
25
+ console.log("[CSP Debug] ENV_MODE:", process.env.ENV_MODE);
27
26
 
28
27
  // Determine report URI
29
- const reportUri = isProdEnvironment
30
- ? "/.netlify/functions/cspReport"
31
- : "/api/mock-csp";
28
+ const reportUri = isProdEnvironment ? "/api/cspReport" : "/api/mock-csp";
32
29
 
33
30
  // Construct base policy
34
31
  const cspDirectives = [
@@ -46,7 +46,7 @@ This file is part of Network Pro.
46
46
  */
47
47
  const pageInfo = {
48
48
  title: "FOSS Spotlight",
49
- lastUpdated: "May 26, 2025",
49
+ lastUpdated: "May 30, 2025",
50
50
  };
51
51
 
52
52
  /** @type {any} */
@@ -48,6 +48,16 @@ export function registerServiceWorker() {
48
48
  .then((registration) => {
49
49
  console.log("✅ Service Worker registered with scope:", registration.scope);
50
50
 
51
+ // 🧼 Manual cleanup of unexpected caches
52
+ caches.keys().then((keys) => {
53
+ keys.forEach((key) => {
54
+ if (!key.startsWith("cache-")) {
55
+ console.log("🧹 Deleting unexpected cache:", key);
56
+ caches.delete(key);
57
+ }
58
+ });
59
+ });
60
+
51
61
  registration.addEventListener("updatefound", () => {
52
62
  const newWorker = registration.installing;
53
63
  console.log("[SW-CLIENT] New service worker installing...");
@@ -33,7 +33,6 @@ const IGNORE_PATHS = new Set([
33
33
  "/docs/extensions.md",
34
34
  "/docs/Home.md",
35
35
  "/img/banner-1280x640.png",
36
- "/img/banner-og-1200x630.png",
37
36
  "/img/logo-transparent.png",
38
37
  "/img/logo.png",
39
38
  "/img/svelte.png",
@@ -55,6 +54,7 @@ const ASSETS = [
55
54
 
56
55
  const shouldExclude =
57
56
  path.startsWith("http") ||
57
+ path.startsWith("/assets/") ||
58
58
  disallowedHosts.some(
59
59
  (host) => hostname === host || hostname.endsWith(`.${host}`),
60
60
  ) ||
@@ -74,25 +74,105 @@ const ASSETS = [
74
74
 
75
75
  const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
76
76
 
77
+ /** @type {string[]} */
78
+ const REQUIRED_ASSETS = [
79
+ "/disableSw.js",
80
+ "/favicon.ico",
81
+ "/icon-192x192.png",
82
+ "/icon-512x512-maskable.png",
83
+ "/icon-512x512.png",
84
+ "/icon-contact.png",
85
+ "/icon-services.png",
86
+ "/icon-splash.png",
87
+ "/img/banner-og-1200x630.png",
88
+ "/img/qr/pgp-contact.png",
89
+ "/img/qr/pgp-github.png",
90
+ "/img/qr/pgp-support.png",
91
+ "/img/qr/vcard.png",
92
+ "/manifest.json",
93
+ "/offline.html",
94
+ "/offline.min.css",
95
+ "/screenshots/desktop-about.png",
96
+ "/screenshots/desktop-home.png",
97
+ "/screenshots/mobile-foss.png",
98
+ "/screenshots/mobile-home.png",
99
+ "/styles/brands.min.css",
100
+ "/styles/fontawesome.min.css",
101
+ "/styles/global.min.css",
102
+ "/styles/solid.min.css",
103
+ "/webfonts/fa-brands-400.woff2",
104
+ "/webfonts/fa-solid-900.woff2",
105
+ "/.well-known/dnt-policy-1.0.txt",
106
+ ];
107
+
77
108
  if (isDev) {
78
109
  console.log("[SW] Assets to precache:", ASSETS);
79
110
  console.log("[SW] Excluded assets:", uniqueExcludedAssets);
80
111
  }
81
112
 
113
+ /**
114
+ * Safely cache a list of assets, logging or throwing if required assets fail.
115
+ *
116
+ * @param {Cache} cache
117
+ * @param {string[]} assets
118
+ * @param {string[]} required
119
+ * @returns {Promise<string[]>} Cached asset paths
120
+ */
121
+ async function cacheAssetsSafely(cache, assets, required = []) {
122
+ /** @type {string[]} */
123
+ const cachedPaths = [];
124
+
125
+ await Promise.all(
126
+ assets.map(async (asset) => {
127
+ try {
128
+ await cache.add(asset);
129
+ cachedPaths.push(asset);
130
+ } catch (err) {
131
+ const msg =
132
+ err instanceof Error
133
+ ? `[SW] Failed to cache ${asset}: ${err.message}`
134
+ : `[SW] Failed to cache ${asset}: Unknown error`;
135
+
136
+ if (isDev) {
137
+ throw new Error(msg);
138
+ } else {
139
+ console.warn(msg);
140
+ }
141
+ }
142
+ }),
143
+ );
144
+
145
+ const missing = required.filter((req) => !cachedPaths.includes(req));
146
+ if (missing.length > 0) {
147
+ const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(", ")}`;
148
+ if (isDev) throw new Error(errorMsg);
149
+ console.error(errorMsg);
150
+ }
151
+
152
+ return cachedPaths;
153
+ }
154
+
82
155
  // 🔹 Install event
83
156
  sw.addEventListener("install", (event) => {
84
157
  if (isDev) console.log("[SW] Install event");
158
+
85
159
  event.waitUntil(
86
160
  (async () => {
87
161
  const cache = await caches.open(CACHE);
162
+ let cachedPaths = [];
163
+
88
164
  try {
89
- await cache.addAll(ASSETS);
90
- if (isDev) console.log("[SW] Precaching complete");
91
- sw.skipWaiting();
92
- if (isDev) console.log("[SW] skipWaiting() called");
165
+ cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
166
+ if (isDev) {
167
+ console.log("[SW] Cached assets:", cachedPaths);
168
+ }
93
169
  } catch (err) {
94
- if (isDev) console.warn("[SW] Failed to precache some assets:", err);
170
+ if (isDev) throw err;
171
+ console.warn("[SW] Error while precaching (non-fatal in prod):", err);
95
172
  }
173
+
174
+ await sw.skipWaiting();
175
+ if (isDev) console.log("[SW] skipWaiting() called");
96
176
  })(),
97
177
  );
98
178
  });
@@ -112,12 +192,12 @@ sw.addEventListener("activate", (event) => {
112
192
  tasks.push(
113
193
  caches.keys().then((keys) =>
114
194
  Promise.all(
115
- keys.map((key) => {
116
- if (key !== CACHE) {
195
+ keys
196
+ .filter((key) => key !== CACHE)
197
+ .map((key) => {
117
198
  if (isDev) console.log("[SW] Deleting old cache:", key);
118
199
  return caches.delete(key);
119
- }
120
- }),
200
+ }),
121
201
  ),
122
202
  ),
123
203
  );