@networkpro/web 1.12.9 → 1.13.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.
- package/CHANGELOG.md +26 -1
- package/README.md +8 -8
- package/eslint.config.mjs +48 -48
- package/netlify/edge-functions/csp-report.js +31 -31
- package/package.json +1 -1
- package/playwright.config.js +14 -14
- package/postcss.config.mjs +1 -1
- package/scripts/auditScripts.js +16 -16
- package/scripts/bundleCss.js +5 -5
- package/scripts/checkEnv.js +6 -6
- package/scripts/checkNode.js +10 -10
- package/scripts/checkVersions.js +6 -6
- package/scripts/flattenHeaders.js +13 -13
- package/scripts/generateTest.js +5 -5
- package/scripts/openReport.js +3 -3
- package/scripts/validateHeaders.js +13 -13
- package/src/hooks.client.ts +1 -1
- package/src/hooks.server.js +31 -31
- package/src/lib/components/Badges.svelte +9 -9
- package/src/lib/components/CodeBlock.svelte +1 -1
- package/src/lib/components/ContainerSection.svelte +1 -1
- package/src/lib/components/FullWidthSection.svelte +3 -3
- package/src/lib/components/LegalNav.svelte +6 -6
- package/src/lib/components/Logo.svelte +9 -9
- package/src/lib/components/MetaTags.svelte +3 -3
- package/src/lib/components/PWAInstallButton.svelte +4 -4
- package/src/lib/components/RedirectPage.svelte +4 -4
- package/src/lib/components/SocialMedia.svelte +16 -16
- package/src/lib/components/foss/FossItemContent.svelte +18 -18
- package/src/lib/components/layout/Footer.svelte +17 -17
- package/src/lib/components/layout/HeaderDefault.svelte +16 -16
- package/src/lib/components/layout/HeaderHome.svelte +14 -14
- package/src/lib/images.js +34 -34
- package/src/lib/index.js +15 -15
- package/src/lib/meta.js +29 -29
- package/src/lib/pages/AboutContent.svelte +24 -24
- package/src/lib/pages/FossContent.svelte +12 -12
- package/src/lib/pages/HomeContent.svelte +6 -6
- package/src/lib/pages/LicenseContent.svelte +38 -38
- package/src/lib/pages/PGPContent.svelte +23 -23
- package/src/lib/pages/PrivacyContent.svelte +39 -39
- package/src/lib/pages/PrivacyDashboard.svelte +12 -12
- package/src/lib/pages/TermsConditionsContent.svelte +28 -28
- package/src/lib/pages/TermsUseContent.svelte +26 -26
- package/src/lib/registerServiceWorker.js +25 -25
- package/src/lib/stores/posthog.js +13 -13
- package/src/lib/stores/trackingPreferences.js +19 -19
- package/src/lib/unregisterServiceWorker.js +1 -1
- package/src/lib/utils/purify.js +4 -4
- package/src/lib/utils/utm.js +2 -2
- package/src/routes/+error.svelte +4 -4
- package/src/routes/+layout.js +6 -6
- package/src/routes/+layout.svelte +29 -29
- package/src/routes/+page.server.js +2 -2
- package/src/routes/+page.svelte +9 -9
- package/src/routes/about/+page.server.js +2 -2
- package/src/routes/about/+page.svelte +7 -7
- package/src/routes/api/mock-csp/+server.js +3 -3
- package/src/routes/consultation/+page.svelte +5 -5
- package/src/routes/contact/+page.svelte +5 -5
- package/src/routes/foss-spotlight/+page.server.js +2 -2
- package/src/routes/foss-spotlight/+page.svelte +7 -7
- package/src/routes/license/+page.server.js +2 -2
- package/src/routes/license/+page.svelte +7 -7
- package/src/routes/pgp/+page.server.js +2 -2
- package/src/routes/pgp/+page.svelte +7 -7
- package/src/routes/pgp/[key]/+server.js +9 -9
- package/src/routes/privacy/+page.server.js +2 -2
- package/src/routes/privacy/+page.svelte +7 -7
- package/src/routes/privacy-dashboard/+page.server.js +2 -2
- package/src/routes/privacy-dashboard/+page.svelte +8 -8
- package/src/routes/privacy-rights/+page.svelte +5 -5
- package/src/routes/status/+page.server.js +2 -2
- package/src/routes/terms-conditions/+page.server.js +2 -2
- package/src/routes/terms-conditions/+page.svelte +7 -7
- package/src/routes/terms-of-use/+page.server.js +2 -2
- package/src/routes/terms-of-use/+page.svelte +7 -7
- package/src/service-worker.js +86 -86
- package/static/disableSw.js +2 -2
- package/static/offline.html +7 -7
- package/stylelint.config.js +56 -56
- package/svelte.config.js +6 -6
- package/tests/e2e/app.spec.js +25 -25
- package/tests/e2e/mobile.spec.js +18 -18
- package/tests/e2e/shared/helpers.js +4 -4
- package/tests/internal/auditCoverage.test.js +24 -24
- package/tests/unit/checkEnv.test.js +10 -10
- package/tests/unit/checkVersions.test.js +4 -4
- package/tests/unit/csp-report.test.js +24 -24
- package/tests/unit/demo.test.js +3 -3
- package/tests/unit/lib/utils/purify.test.js +12 -12
- package/tests/unit/routes/page.svelte.test.js +10 -10
- package/tests/unit/unregisterServiceWorker.test.js +5 -5
- package/tests/unit/utm.test.js +13 -13
- package/vite.config.js +5 -5
- package/vitest-setup-client.js +4 -4
- package/vitest.config.client.js +15 -15
- package/vitest.config.server.js +13 -13
package/scripts/checkNode.js
CHANGED
|
@@ -19,23 +19,23 @@ This file is part of Network Pro.
|
|
|
19
19
|
* @updated 2025-05-23
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { execSync } from
|
|
23
|
-
import fs from
|
|
24
|
-
import path from
|
|
25
|
-
import semver from
|
|
26
|
-
import { fileURLToPath } from
|
|
22
|
+
import { execSync } from 'child_process';
|
|
23
|
+
import fs from 'fs';
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import semver from 'semver';
|
|
26
|
+
import { fileURLToPath } from 'url';
|
|
27
27
|
|
|
28
28
|
const __filename = fileURLToPath(import.meta.url);
|
|
29
29
|
const __dirname = path.dirname(__filename);
|
|
30
30
|
|
|
31
31
|
// Load engines from package.json
|
|
32
32
|
const pkg = JSON.parse(
|
|
33
|
-
fs.readFileSync(path.resolve(__dirname,
|
|
33
|
+
fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf8'),
|
|
34
34
|
);
|
|
35
35
|
const { node: nodeRange, npm: npmRange } = pkg.engines;
|
|
36
36
|
|
|
37
37
|
// Determine if this is running as part of npm's postinstall hook
|
|
38
|
-
const isPostInstall = process.env.npm_lifecycle_event ===
|
|
38
|
+
const isPostInstall = process.env.npm_lifecycle_event === 'postinstall';
|
|
39
39
|
|
|
40
40
|
let hasError = false;
|
|
41
41
|
|
|
@@ -54,7 +54,7 @@ if (!semver.satisfies(process.version, nodeRange)) {
|
|
|
54
54
|
let npmVersion = null;
|
|
55
55
|
|
|
56
56
|
try {
|
|
57
|
-
npmVersion = execSync(
|
|
57
|
+
npmVersion = execSync('npm --version').toString().trim();
|
|
58
58
|
if (!semver.satisfies(npmVersion, npmRange)) {
|
|
59
59
|
const msg = `npm ${npmVersion} does not satisfy required range: ${npmRange}`;
|
|
60
60
|
if (isPostInstall) {
|
|
@@ -65,13 +65,13 @@ try {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
} catch (err) {
|
|
68
|
-
console.error(
|
|
68
|
+
console.error('❌ Failed to check npm version:', err.message);
|
|
69
69
|
process.exit(1);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// Final output
|
|
73
73
|
if (!hasError) {
|
|
74
|
-
if (!process.env.CI || process.env.VERBOSE ===
|
|
74
|
+
if (!process.env.CI || process.env.VERBOSE === 'true') {
|
|
75
75
|
console.log(
|
|
76
76
|
`✅ Node (${process.version}) matches ${nodeRange}, and npm (${npmVersion}) matches ${npmRange}`,
|
|
77
77
|
);
|
package/scripts/checkVersions.js
CHANGED
|
@@ -16,10 +16,10 @@ This file is part of Network Pro.
|
|
|
16
16
|
* @updated 2025-05-20
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { execSync } from
|
|
20
|
-
import fs from
|
|
21
|
-
import path from
|
|
22
|
-
import semver from
|
|
19
|
+
import { execSync } from 'child_process';
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import path from 'path';
|
|
22
|
+
import semver from 'semver';
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* @typedef {object} VersionCheckResult
|
|
@@ -38,12 +38,12 @@ import semver from "semver";
|
|
|
38
38
|
*/
|
|
39
39
|
export function checkVersions() {
|
|
40
40
|
const pkg = JSON.parse(
|
|
41
|
-
fs.readFileSync(path.resolve(
|
|
41
|
+
fs.readFileSync(path.resolve('./package.json'), 'utf8'),
|
|
42
42
|
);
|
|
43
43
|
const { node: nodeRange, npm: npmRange } = pkg.engines;
|
|
44
44
|
|
|
45
45
|
const nodeVersion = process.version;
|
|
46
|
-
const npmVersion = execSync(
|
|
46
|
+
const npmVersion = execSync('npm --version').toString().trim();
|
|
47
47
|
|
|
48
48
|
const nodeValid = semver.satisfies(nodeVersion, nodeRange);
|
|
49
49
|
const npmValid = semver.satisfies(npmVersion, npmRange);
|
|
@@ -15,30 +15,30 @@ This file is part of Network Pro.
|
|
|
15
15
|
* @updated 2025-05-18
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import fs from
|
|
18
|
+
import fs from 'fs';
|
|
19
19
|
|
|
20
|
-
const HEADERS_PATH =
|
|
21
|
-
const OUTPUT_PATH =
|
|
20
|
+
const HEADERS_PATH = './.headers_new'; // update if needed
|
|
21
|
+
const OUTPUT_PATH = './_headers.flattened';
|
|
22
22
|
|
|
23
|
-
const lines = fs.readFileSync(HEADERS_PATH,
|
|
23
|
+
const lines = fs.readFileSync(HEADERS_PATH, 'utf-8').split('\n');
|
|
24
24
|
const output = [];
|
|
25
25
|
|
|
26
26
|
let cspLines = [];
|
|
27
27
|
let inCSP = false;
|
|
28
28
|
|
|
29
29
|
for (const line of lines) {
|
|
30
|
-
if (line.trim().startsWith(
|
|
30
|
+
if (line.trim().startsWith('Content-Security-Policy:')) {
|
|
31
31
|
inCSP = true;
|
|
32
32
|
cspLines.push(line.trim());
|
|
33
|
-
} else if (inCSP && line.startsWith(
|
|
33
|
+
} else if (inCSP && line.startsWith(' ')) {
|
|
34
34
|
cspLines.push(line.trim());
|
|
35
35
|
} else {
|
|
36
36
|
if (inCSP) {
|
|
37
37
|
// Output flattened CSP
|
|
38
38
|
const flattened = cspLines
|
|
39
|
-
.join(
|
|
40
|
-
.replace(/\s*;\s*/g,
|
|
41
|
-
.replace(/\s+/g,
|
|
39
|
+
.join(' ')
|
|
40
|
+
.replace(/\s*;\s*/g, '; ') // Normalize spacing
|
|
41
|
+
.replace(/\s+/g, ' ')
|
|
42
42
|
.trim();
|
|
43
43
|
output.push(` ${flattened}`);
|
|
44
44
|
cspLines = [];
|
|
@@ -51,12 +51,12 @@ for (const line of lines) {
|
|
|
51
51
|
// Handle edge case: CSP is last in file
|
|
52
52
|
if (cspLines.length > 0) {
|
|
53
53
|
const flattened = cspLines
|
|
54
|
-
.join(
|
|
55
|
-
.replace(/\s*;\s*/g,
|
|
56
|
-
.replace(/\s+/g,
|
|
54
|
+
.join(' ')
|
|
55
|
+
.replace(/\s*;\s*/g, '; ')
|
|
56
|
+
.replace(/\s+/g, ' ')
|
|
57
57
|
.trim();
|
|
58
58
|
output.push(` ${flattened}`);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
fs.writeFileSync(OUTPUT_PATH, output.join(
|
|
61
|
+
fs.writeFileSync(OUTPUT_PATH, output.join('\n'));
|
|
62
62
|
console.log(`Flattened headers written to ${OUTPUT_PATH}`);
|
package/scripts/generateTest.js
CHANGED
|
@@ -17,13 +17,13 @@ This file is part of Network Pro.
|
|
|
17
17
|
* @updated 2025-06-01
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import fs from
|
|
21
|
-
import path from
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import path from 'path';
|
|
22
22
|
|
|
23
23
|
const [, , targetFile] = process.argv;
|
|
24
24
|
|
|
25
25
|
if (!targetFile) {
|
|
26
|
-
console.error(
|
|
26
|
+
console.error('Usage: node generateTest.js <path/to/yourFile.js>');
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -32,7 +32,7 @@ const parsed = path.parse(absolutePath);
|
|
|
32
32
|
|
|
33
33
|
const testFileName = `${parsed.name}.test.js`;
|
|
34
34
|
const testFilePath = path.join(
|
|
35
|
-
parsed.dir.replace(
|
|
35
|
+
parsed.dir.replace('src', 'tests/unit'),
|
|
36
36
|
testFileName,
|
|
37
37
|
);
|
|
38
38
|
|
|
@@ -42,7 +42,7 @@ const scaffold = `/**
|
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
44
|
import { describe, it, expect } from "vitest";
|
|
45
|
-
import * as Module from "${path.relative(path.dirname(testFilePath), absolutePath).replace(/\\/g,
|
|
45
|
+
import * as Module from "${path.relative(path.dirname(testFilePath), absolutePath).replace(/\\/g, '/')}";
|
|
46
46
|
|
|
47
47
|
describe("${parsed.name}", () => {
|
|
48
48
|
it("should have tests", () => {
|
package/scripts/openReport.js
CHANGED
|
@@ -16,9 +16,9 @@ This file is part of Network Pro.
|
|
|
16
16
|
* @updated 2025-06-09
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { exec } from
|
|
20
|
-
import { dirname, join } from
|
|
21
|
-
import { fileURLToPath } from
|
|
19
|
+
import { exec } from 'child_process';
|
|
20
|
+
import { dirname, join } from 'path';
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
22
|
|
|
23
23
|
// ESM replacement for __dirname
|
|
24
24
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -16,10 +16,10 @@ This file is part of Network Pro.
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
// validate-headers.js
|
|
19
|
-
import fs from
|
|
19
|
+
import fs from 'fs';
|
|
20
20
|
|
|
21
|
-
const file =
|
|
22
|
-
const lines = fs.readFileSync(file,
|
|
21
|
+
const file = './_headers';
|
|
22
|
+
const lines = fs.readFileSync(file, 'utf-8').split('\n');
|
|
23
23
|
|
|
24
24
|
let currentPath = null;
|
|
25
25
|
let errors = [];
|
|
@@ -30,15 +30,15 @@ let headerValueBuffer = [];
|
|
|
30
30
|
function flushBufferedHeader(lineNum) {
|
|
31
31
|
if (!currentHeader) return;
|
|
32
32
|
|
|
33
|
-
const value = headerValueBuffer.join(
|
|
33
|
+
const value = headerValueBuffer.join(' ').trim();
|
|
34
34
|
|
|
35
|
-
if (currentHeader !==
|
|
35
|
+
if (currentHeader !== 'Content-Security-Policy' && value.endsWith(';')) {
|
|
36
36
|
errors.push(
|
|
37
37
|
`Line ${lineNum}: Header '${currentHeader}' should not end with a semicolon`,
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if (currentHeader ===
|
|
41
|
+
if (currentHeader === 'Content-Security-Policy' && !value.endsWith(';')) {
|
|
42
42
|
errors.push(
|
|
43
43
|
`Line ${lineNum}: 'Content-Security-Policy' must end with a semicolon`,
|
|
44
44
|
);
|
|
@@ -52,7 +52,7 @@ for (let i = 0; i < lines.length; i++) {
|
|
|
52
52
|
const line = lines[i];
|
|
53
53
|
const trimmed = line.trim();
|
|
54
54
|
|
|
55
|
-
if (trimmed.startsWith(
|
|
55
|
+
if (trimmed.startsWith('/*')) {
|
|
56
56
|
if (currentPath) {
|
|
57
57
|
errors.push(
|
|
58
58
|
`Line ${i + 1}: Multiple '/*' blocks detected. Only one is allowed in Netlify _headers`,
|
|
@@ -62,10 +62,10 @@ for (let i = 0; i < lines.length; i++) {
|
|
|
62
62
|
continue;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
if (trimmed ===
|
|
65
|
+
if (trimmed === '') continue;
|
|
66
66
|
|
|
67
|
-
if (line.startsWith(
|
|
68
|
-
const colonIndex = line.indexOf(
|
|
67
|
+
if (line.startsWith(' ')) {
|
|
68
|
+
const colonIndex = line.indexOf(':');
|
|
69
69
|
|
|
70
70
|
if (colonIndex !== -1) {
|
|
71
71
|
// New header
|
|
@@ -88,9 +88,9 @@ for (let i = 0; i < lines.length; i++) {
|
|
|
88
88
|
flushBufferedHeader(lines.length);
|
|
89
89
|
|
|
90
90
|
if (errors.length) {
|
|
91
|
-
console.error(
|
|
92
|
-
errors.forEach((e) => console.error(
|
|
91
|
+
console.error('❌ Header validation failed:');
|
|
92
|
+
errors.forEach((e) => console.error(' -', e));
|
|
93
93
|
process.exit(1);
|
|
94
94
|
} else {
|
|
95
|
-
console.log(
|
|
95
|
+
console.log('✅ _headers file passed validation!');
|
|
96
96
|
}
|
package/src/hooks.client.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const init = undefined;
|
|
|
18
18
|
* @param error - The uncaught error object
|
|
19
19
|
*/
|
|
20
20
|
export function handleError(error: Error) {
|
|
21
|
-
console.error(
|
|
21
|
+
console.error('[CLIENT] Unhandled error:', error);
|
|
22
22
|
|
|
23
23
|
// Future: send to error reporting service
|
|
24
24
|
// e.g., Sentry.captureException(error);
|
package/src/hooks.server.js
CHANGED
|
@@ -17,15 +17,15 @@ export async function handle({ event, resolve }) {
|
|
|
17
17
|
// Determine environment flags
|
|
18
18
|
// Default to development policy if neither test nor prod
|
|
19
19
|
const isTestEnvironment =
|
|
20
|
-
process.env.NODE_ENV ===
|
|
20
|
+
process.env.NODE_ENV === 'test' || process.env.ENV_MODE === 'ci';
|
|
21
21
|
const isProdEnvironment =
|
|
22
|
-
process.env.NODE_ENV ===
|
|
22
|
+
process.env.NODE_ENV === 'production' || process.env.ENV_MODE === 'prod';
|
|
23
23
|
|
|
24
|
-
console.log(
|
|
25
|
-
console.log(
|
|
24
|
+
console.log('[CSP Debug] NODE_ENV:', process.env.NODE_ENV);
|
|
25
|
+
console.log('[CSP Debug] ENV_MODE:', process.env.ENV_MODE);
|
|
26
26
|
|
|
27
27
|
// Determine report URI
|
|
28
|
-
const reportUri = isProdEnvironment ?
|
|
28
|
+
const reportUri = isProdEnvironment ? '/api/csp-report' : '/api/mock-csp';
|
|
29
29
|
|
|
30
30
|
// Construct base policy
|
|
31
31
|
const cspDirectives = [
|
|
@@ -40,7 +40,7 @@ export async function handle({ event, resolve }) {
|
|
|
40
40
|
"base-uri 'self';",
|
|
41
41
|
"object-src 'none';",
|
|
42
42
|
"frame-ancestors 'none';",
|
|
43
|
-
|
|
43
|
+
'upgrade-insecure-requests;',
|
|
44
44
|
`report-uri ${reportUri};`,
|
|
45
45
|
];
|
|
46
46
|
|
|
@@ -55,37 +55,37 @@ export async function handle({ event, resolve }) {
|
|
|
55
55
|
cspDirectives[5] = "connect-src 'self';";
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
response.headers.set(
|
|
58
|
+
response.headers.set('Content-Security-Policy', cspDirectives.join(' '));
|
|
59
59
|
|
|
60
60
|
// Set other security headers
|
|
61
61
|
response.headers.set(
|
|
62
|
-
|
|
62
|
+
'Permissions-Policy',
|
|
63
63
|
[
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
].join(
|
|
64
|
+
'fullscreen=(self)',
|
|
65
|
+
'sync-xhr=()',
|
|
66
|
+
'camera=()',
|
|
67
|
+
'microphone=()',
|
|
68
|
+
'geolocation=()',
|
|
69
|
+
'clipboard-read=()',
|
|
70
|
+
'clipboard-write=(self)',
|
|
71
|
+
'payment=()',
|
|
72
|
+
'usb=()',
|
|
73
|
+
'hid=()',
|
|
74
|
+
'gamepad=()',
|
|
75
|
+
'serial=()',
|
|
76
|
+
'publickey-credentials-get=()',
|
|
77
|
+
'browsing-topics=()',
|
|
78
|
+
].join(', '),
|
|
79
79
|
);
|
|
80
80
|
|
|
81
|
-
response.headers.set(
|
|
82
|
-
response.headers.set(
|
|
83
|
-
response.headers.set(
|
|
81
|
+
response.headers.set('X-Content-Type-Options', 'nosniff');
|
|
82
|
+
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
83
|
+
response.headers.set('X-Frame-Options', 'DENY');
|
|
84
84
|
|
|
85
|
-
if (process.env.ENV_MODE !==
|
|
85
|
+
if (process.env.ENV_MODE !== 'test' && process.env.ENV_MODE !== 'ci') {
|
|
86
86
|
response.headers.set(
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
'Strict-Transport-Security',
|
|
88
|
+
'max-age=31536000; includeSubDomains;', // No preload here
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -97,10 +97,10 @@ export async function handle({ event, resolve }) {
|
|
|
97
97
|
* @type {import('@sveltejs/kit').HandleServerError}
|
|
98
98
|
*/
|
|
99
99
|
export function handleError({ error, event }) {
|
|
100
|
-
console.error(
|
|
100
|
+
console.error('🔴 SSR Error in route:', event.url.pathname);
|
|
101
101
|
console.error(error);
|
|
102
102
|
|
|
103
103
|
return {
|
|
104
|
-
message:
|
|
104
|
+
message: 'A server-side error occurred',
|
|
105
105
|
};
|
|
106
106
|
}
|
|
@@ -7,10 +7,10 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import { base } from
|
|
10
|
+
import { base } from '$app/paths';
|
|
11
11
|
// Import badges for licenses
|
|
12
|
-
import { ccBadge, gplBadge } from
|
|
13
|
-
import { CONSTANTS } from
|
|
12
|
+
import { ccBadge, gplBadge } from '$lib';
|
|
13
|
+
import { CONSTANTS } from '$lib';
|
|
14
14
|
|
|
15
15
|
// Log the base path to verify its value
|
|
16
16
|
//console.log("Base path:", base);
|
|
@@ -41,16 +41,16 @@ This file is part of Network Pro.
|
|
|
41
41
|
{
|
|
42
42
|
href: ccbyLink,
|
|
43
43
|
src: ccBadge,
|
|
44
|
-
alt:
|
|
45
|
-
width:
|
|
46
|
-
height:
|
|
44
|
+
alt: 'Creative Commons BY',
|
|
45
|
+
width: '160px',
|
|
46
|
+
height: '24px',
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
href: gplLink,
|
|
50
50
|
src: gplBadge,
|
|
51
|
-
alt:
|
|
52
|
-
width:
|
|
53
|
-
height:
|
|
51
|
+
alt: 'GPL 3.0 or Later',
|
|
52
|
+
width: '120px',
|
|
53
|
+
height: '24px',
|
|
54
54
|
},
|
|
55
55
|
];
|
|
56
56
|
</script>
|
|
@@ -17,16 +17,16 @@ This file is part of Network Pro.
|
|
|
17
17
|
* Additional classes for the outer full-width wrapper
|
|
18
18
|
* @type {string}
|
|
19
19
|
*/
|
|
20
|
-
export let outerClass =
|
|
20
|
+
export let outerClass = '';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Additional classes for the inner container
|
|
24
24
|
* @type {string}
|
|
25
25
|
*/
|
|
26
|
-
export let containerClass =
|
|
26
|
+
export let containerClass = '';
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
|
-
<div class={`full-width-section ${centered ?
|
|
29
|
+
<div class={`full-width-section ${centered ? 'centered' : ''} ${outerClass}`}>
|
|
30
30
|
<div class={`container ${containerClass}`}>
|
|
31
31
|
<slot></slot>
|
|
32
32
|
</div>
|
|
@@ -7,8 +7,8 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import { base } from
|
|
11
|
-
import { CONSTANTS } from
|
|
10
|
+
import { base } from '$app/paths';
|
|
11
|
+
import { CONSTANTS } from '$lib';
|
|
12
12
|
|
|
13
13
|
// Log the base path to verify its value
|
|
14
14
|
//console.log("Base path:", base);
|
|
@@ -38,21 +38,21 @@ This file is part of Network Pro.
|
|
|
38
38
|
[
|
|
39
39
|
{
|
|
40
40
|
href: privacyLink,
|
|
41
|
-
text:
|
|
41
|
+
text: 'Privacy Policy',
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
href: pdashLink,
|
|
45
|
-
text:
|
|
45
|
+
text: 'Privacy Dashboard',
|
|
46
46
|
},
|
|
47
47
|
],
|
|
48
48
|
[
|
|
49
49
|
{
|
|
50
50
|
href: termsLink,
|
|
51
|
-
text:
|
|
51
|
+
text: 'Terms of Use',
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
href: licenseLink,
|
|
55
|
-
text:
|
|
55
|
+
text: 'Legal',
|
|
56
56
|
},
|
|
57
57
|
],
|
|
58
58
|
];
|
|
@@ -8,43 +8,43 @@ This file is part of Network Pro.
|
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
10
|
// Import logo images
|
|
11
|
-
import { logoPng, logoWbp } from
|
|
11
|
+
import { logoPng, logoWbp } from '$lib';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Decoding mode for the image.
|
|
15
15
|
* @type {"sync" | "async" | "auto"}
|
|
16
16
|
*/
|
|
17
|
-
export let decoding =
|
|
17
|
+
export let decoding = 'sync';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Loading mode for the image.
|
|
21
21
|
* @type {"eager" | "lazy"}
|
|
22
22
|
*/
|
|
23
|
-
export let loading =
|
|
23
|
+
export let loading = 'eager';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* CSS class for the logo image.
|
|
27
27
|
* @type {string}
|
|
28
28
|
*/
|
|
29
|
-
export let className =
|
|
29
|
+
export let className = 'logo';
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Alt text for the logo image.
|
|
33
33
|
* @type {string}
|
|
34
34
|
*/
|
|
35
|
-
export let alt =
|
|
35
|
+
export let alt = 'Network Pro Strategies';
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* First part of the company slogan.
|
|
39
39
|
* @type {string}
|
|
40
40
|
*/
|
|
41
|
-
export let sloganA =
|
|
41
|
+
export let sloganA = 'Locking Down Networks';
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Second part of the company slogan.
|
|
45
45
|
* @type {string}
|
|
46
46
|
*/
|
|
47
|
-
export let sloganB =
|
|
47
|
+
export let sloganB = 'Unlocking Confidence™';
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Enable/disable display of the slogan.
|
|
@@ -74,13 +74,13 @@ This file is part of Network Pro.
|
|
|
74
74
|
* Fetch priority for the logo image.
|
|
75
75
|
* @type {"high" | "low" | "auto"}
|
|
76
76
|
*/
|
|
77
|
-
export let fetchpriority =
|
|
77
|
+
export let fetchpriority = 'high';
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Tagline text to display.
|
|
81
81
|
* @type {string}
|
|
82
82
|
*/
|
|
83
|
-
export let tagline =
|
|
83
|
+
export let tagline = 'Security | Networking | Privacy';
|
|
84
84
|
</script>
|
|
85
85
|
|
|
86
86
|
<!-- BEGIN LOGO AND SITE TITLE -->
|
|
@@ -10,7 +10,7 @@ This file is part of Network Pro.
|
|
|
10
10
|
export let title;
|
|
11
11
|
export let description;
|
|
12
12
|
|
|
13
|
-
import { CONSTANTS } from
|
|
13
|
+
import { CONSTANTS } from '$lib';
|
|
14
14
|
|
|
15
15
|
console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
|
|
16
16
|
|
|
@@ -18,9 +18,9 @@ This file is part of Network Pro.
|
|
|
18
18
|
|
|
19
19
|
// Static shared values
|
|
20
20
|
const ogUrl = LINKS.HOME;
|
|
21
|
-
const ogImg =
|
|
21
|
+
const ogImg = '/img/banner-og-1200x630.png';
|
|
22
22
|
const companyName = COMPANY_INFO.NAME;
|
|
23
|
-
const twitterAct =
|
|
23
|
+
const twitterAct = '@NetEng_Pro';
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<svelte:head>
|
|
@@ -7,8 +7,8 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import { onMount } from
|
|
11
|
-
import { fade } from
|
|
10
|
+
import { onMount } from 'svelte';
|
|
11
|
+
import { fade } from 'svelte/transition';
|
|
12
12
|
|
|
13
13
|
let show = false;
|
|
14
14
|
|
|
@@ -26,10 +26,10 @@ This file is part of Network Pro.
|
|
|
26
26
|
show = true;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
window.addEventListener(
|
|
29
|
+
window.addEventListener('pwa-install-available', handleInstallPrompt);
|
|
30
30
|
|
|
31
31
|
return () => {
|
|
32
|
-
window.removeEventListener(
|
|
32
|
+
window.removeEventListener('pwa-install-available', handleInstallPrompt);
|
|
33
33
|
};
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -7,19 +7,19 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import { onMount } from
|
|
11
|
-
import FullWidthSection from
|
|
10
|
+
import { onMount } from 'svelte';
|
|
11
|
+
import FullWidthSection from '$lib/components/FullWidthSection.svelte';
|
|
12
12
|
|
|
13
13
|
export let to;
|
|
14
14
|
export let delay = 3;
|
|
15
15
|
|
|
16
16
|
onMount(() => {
|
|
17
17
|
if (!to) {
|
|
18
|
-
console.warn(
|
|
18
|
+
console.warn('⛔ No redirect target provided');
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
console.log(
|
|
22
|
+
console.log('✅ Starting redirect to:', to);
|
|
23
23
|
|
|
24
24
|
setTimeout(() => {
|
|
25
25
|
window.location.href = to;
|