Fix CSP errors, MIME types, and Service Worker issues
- 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:
52
.htaccess
52
.htaccess
@@ -1,6 +1,35 @@
|
|||||||
# SecureBit.chat - Apache Configuration
|
# SecureBit.chat - Apache Configuration
|
||||||
# Comprehensive caching configuration for forced updates
|
# 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
|
# Enable mod_rewrite
|
||||||
<IfModule mod_rewrite.c>
|
<IfModule mod_rewrite.c>
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
@@ -116,9 +145,9 @@
|
|||||||
Header set X-Frame-Options "DENY"
|
Header set X-Frame-Options "DENY"
|
||||||
</IfModule>
|
</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>
|
<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>
|
</IfModule>
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
@@ -133,25 +162,6 @@
|
|||||||
AddOutputFilterByType DEFLATE font/woff font/woff2 application/font-woff application/font-woff2
|
AddOutputFilterByType DEFLATE font/woff font/woff2 application/font-woff application/font-woff2
|
||||||
</IfModule>
|
</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
|
# CLOUDFLARE RULES
|
||||||
|
|||||||
17
index.html
17
index.html
@@ -6,20 +6,17 @@
|
|||||||
<meta http-equiv="Content-Security-Policy"
|
<meta http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self';
|
content="default-src 'self';
|
||||||
script-src 'self';
|
script-src 'self';
|
||||||
style-src 'self';
|
style-src 'self' 'unsafe-inline';
|
||||||
font-src 'self';
|
font-src 'self' https://fonts.gstatic.com data:;
|
||||||
connect-src 'self' https: wss: ws:;
|
connect-src 'self' https: wss: ws:;
|
||||||
img-src 'self' data: https:;
|
img-src 'self' data: https:;
|
||||||
media-src 'none';
|
media-src 'none';
|
||||||
object-src 'none';
|
object-src 'none';
|
||||||
frame-src 'none';
|
frame-src 'none';
|
||||||
frame-ancestors 'none';
|
|
||||||
worker-src 'self';
|
worker-src 'self';
|
||||||
manifest-src 'self';
|
manifest-src 'self';
|
||||||
form-action 'self';
|
form-action 'self';
|
||||||
upgrade-insecure-requests;
|
upgrade-insecure-requests;">
|
||||||
report-uri /csp-report;
|
|
||||||
report-to csp-endpoint;">
|
|
||||||
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
||||||
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
|
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
|
||||||
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
|
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
|
||||||
@@ -150,13 +147,13 @@
|
|||||||
<!-- Update Manager - система принудительного обновления -->
|
<!-- Update Manager - система принудительного обновления -->
|
||||||
<script src="src/utils/updateManager.js"></script>
|
<script src="src/utils/updateManager.js"></script>
|
||||||
<script type="module" src="src/components/UpdateChecker.jsx"></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="dist/qr-local.js?v=1767754446404"></script>
|
||||||
<script type="module" src="src/components/QRScanner.js?v=1767082143567"></script>
|
<script type="module" src="src/components/QRScanner.js?v=1767754446404"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="dist/app-boot.js?v=1767082143567"></script>
|
<script type="module" src="dist/app-boot.js?v=1767754446404"></script>
|
||||||
<script type="module" src="dist/app.js?v=1767082143567"></script>
|
<script type="module" src="dist/app.js?v=1767754446404"></script>
|
||||||
|
|
||||||
<script src="src/scripts/pwa-register.js"></script>
|
<script src="src/scripts/pwa-register.js"></script>
|
||||||
<script src="./src/pwa/install-prompt.js" type="module"></script>
|
<script src="./src/pwa/install-prompt.js" type="module"></script>
|
||||||
|
|||||||
12
meta.json
12
meta.json
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"version": "1767082143567",
|
"version": "1767754446404",
|
||||||
"buildVersion": "1767082143567",
|
"buildVersion": "1767754446404",
|
||||||
"appVersion": "4.7.56",
|
"appVersion": "4.7.56",
|
||||||
"buildTime": "2025-12-30T08:09:03.641Z",
|
"buildTime": "2026-01-07T02:54:06.493Z",
|
||||||
"buildId": "1767082143567-f136d0d",
|
"buildId": "1767754446404-ebcf2dc",
|
||||||
"gitHash": "f136d0d",
|
"gitHash": "ebcf2dc",
|
||||||
"generated": true,
|
"generated": true,
|
||||||
"generatedAt": "2025-12-30T08:09:03.642Z"
|
"generatedAt": "2026-01-07T02:54:06.494Z"
|
||||||
}
|
}
|
||||||
31
sw.js
31
sw.js
@@ -232,9 +232,22 @@ self.addEventListener('fetch', (event) => {
|
|||||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||||
'Pragma': 'no-cache'
|
'Pragma': 'no-cache'
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch((error) => {
|
||||||
// Fallback if network is unavailable - return error
|
// Log error for debugging
|
||||||
return new Response('Network unavailable', { status: 503 });
|
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;
|
return;
|
||||||
@@ -299,10 +312,18 @@ async function networkFirst(request) {
|
|||||||
// Clone the response before caching
|
// Clone the response before caching
|
||||||
const responseToCache = networkResponse.clone();
|
const responseToCache = networkResponse.clone();
|
||||||
const cache = await caches.open(DYNAMIC_CACHE);
|
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) {
|
} catch (error) {
|
||||||
console.warn('⚠️ Network-first strategy failed:', error.message);
|
console.warn('⚠️ Network-first strategy failed:', error.message);
|
||||||
const cachedResponse = await caches.match(request);
|
const cachedResponse = await caches.match(request);
|
||||||
|
|||||||
Reference in New Issue
Block a user