Fix CSP errors, MIME types, and Service Worker issues
Some checks failed
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled

- Move CSP frame-ancestors and report-uri to HTTP headers
- Fix font-src to allow fonts.gstatic.com
- Add MIME type configuration for .jsx files
- Improve Service Worker error handling with cache fallback
- Rebuild application
This commit is contained in:
lockbitchat
2026-01-06 23:01:32 -04:00
parent ebcf2dcaac
commit 4b8c8829f1
4 changed files with 70 additions and 42 deletions

View File

@@ -1,6 +1,35 @@
# SecureBit.chat - Apache Configuration
# Comprehensive caching configuration for forced updates
# ============================================
# MIME TYPES - MUST BE FIRST (before other rules)
# ============================================
# Critical: Set MIME types BEFORE any other rules to ensure correct Content-Type headers
<IfModule mod_mime.c>
# JavaScript modules - explicit order matters
AddType application/javascript .jsx
AddType application/javascript .mjs
AddType application/javascript .js
AddType application/json .json
# Fonts
AddType font/woff .woff
AddType font/woff2 .woff2
AddType application/font-woff .woff
AddType application/font-woff2 .woff2
# Service Worker
AddType application/manifest+json .webmanifest
</IfModule>
# Force Content-Type headers (override any server defaults)
<IfModule mod_headers.c>
# All JavaScript files including JSX - CRITICAL for ES modules
<FilesMatch "\.(js|mjs|jsx)$">
Header always set Content-Type "application/javascript; charset=utf-8"
</FilesMatch>
</IfModule>
# Enable mod_rewrite
<IfModule mod_rewrite.c>
RewriteEngine On
@@ -116,9 +145,9 @@
Header set X-Frame-Options "DENY"
</IfModule>
# Content Security Policy (already configured in HTML, but can add header)
# Content Security Policy (frame-ancestors and report-uri only work in HTTP headers, not meta tags)
<IfModule mod_headers.c>
# Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';"
Header set Content-Security-Policy "frame-ancestors 'none'; report-uri /csp-report; report-to csp-endpoint;"
</IfModule>
# ============================================
@@ -133,25 +162,6 @@
AddOutputFilterByType DEFLATE font/woff font/woff2 application/font-woff application/font-woff2
</IfModule>
# ============================================
# MIME TYPES
# ============================================
<IfModule mod_mime.c>
# JavaScript modules
AddType application/javascript .js .mjs
AddType application/json .json
# Fonts
AddType font/woff .woff
AddType font/woff2 .woff2
AddType application/font-woff .woff
AddType application/font-woff2 .woff2
# Service Worker
AddType application/javascript .js
AddType application/manifest+json .webmanifest
</IfModule>
# ============================================
# CLOUDFLARE RULES

View File

@@ -6,20 +6,17 @@
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self';
style-src 'self';
font-src 'self';
style-src 'self' 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com data:;
connect-src 'self' https: wss: ws:;
img-src 'self' data: https:;
media-src 'none';
object-src 'none';
frame-src 'none';
frame-ancestors 'none';
worker-src 'self';
manifest-src 'self';
form-action 'self';
upgrade-insecure-requests;
report-uri /csp-report;
report-to csp-endpoint;">
upgrade-insecure-requests;">
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
@@ -150,13 +147,13 @@
<!-- Update Manager - система принудительного обновления -->
<script src="src/utils/updateManager.js"></script>
<script type="module" src="src/components/UpdateChecker.jsx"></script>
<script type="module" src="dist/qr-local.js?v=1767082143567"></script>
<script type="module" src="src/components/QRScanner.js?v=1767082143567"></script>
<script type="module" src="dist/qr-local.js?v=1767754446404"></script>
<script type="module" src="src/components/QRScanner.js?v=1767754446404"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="dist/app-boot.js?v=1767082143567"></script>
<script type="module" src="dist/app.js?v=1767082143567"></script>
<script type="module" src="dist/app-boot.js?v=1767754446404"></script>
<script type="module" src="dist/app.js?v=1767754446404"></script>
<script src="src/scripts/pwa-register.js"></script>
<script src="./src/pwa/install-prompt.js" type="module"></script>

View File

@@ -1,10 +1,10 @@
{
"version": "1767082143567",
"buildVersion": "1767082143567",
"version": "1767754446404",
"buildVersion": "1767754446404",
"appVersion": "4.7.56",
"buildTime": "2025-12-30T08:09:03.641Z",
"buildId": "1767082143567-f136d0d",
"gitHash": "f136d0d",
"buildTime": "2026-01-07T02:54:06.493Z",
"buildId": "1767754446404-ebcf2dc",
"gitHash": "ebcf2dc",
"generated": true,
"generatedAt": "2025-12-30T08:09:03.642Z"
"generatedAt": "2026-01-07T02:54:06.494Z"
}

31
sw.js
View File

@@ -232,9 +232,22 @@ self.addEventListener('fetch', (event) => {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache'
}
}).catch(() => {
// Fallback if network is unavailable - return error
return new Response('Network unavailable', { status: 503 });
}).catch((error) => {
// Log error for debugging
console.warn('⚠️ Failed to fetch JS file:', url.pathname, error.message);
// Try to get from cache as fallback
return caches.match(event.request).then(cachedResponse => {
if (cachedResponse) {
console.log('📦 Using cached version of:', url.pathname);
return cachedResponse;
}
// Only return 503 if no cache available
return new Response('Network unavailable', {
status: 503,
statusText: 'Service Unavailable',
headers: { 'Content-Type': 'text/plain' }
});
});
})
);
return;
@@ -299,10 +312,18 @@ async function networkFirst(request) {
// Clone the response before caching
const responseToCache = networkResponse.clone();
const cache = await caches.open(DYNAMIC_CACHE);
cache.put(request, responseToCache);
cache.put(request, responseToCache).catch(err => {
console.warn('⚠️ Cache put failed (non-critical):', err.message);
});
}
return networkResponse;
}
return networkResponse;
// If response is not ok, try cache
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
return networkResponse; // Return the non-ok response anyway
} catch (error) {
console.warn('⚠️ Network-first strategy failed:', error.message);
const cachedResponse = await caches.match(request);