diff --git a/README.md b/README.md index dd38b3d..8c80af4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ --- -## ✨ What's New in v4.01.412 +## ✨ What's New in v4.01.413 ### 🔒 Comprehensive Connection Security Overhaul * **Advanced mutex framework** with 15-second timeout protection @@ -254,7 +254,7 @@ open http://localhost:8000 ## 🗺️ Development Roadmap -**Current:** v4.01.412 — PWA & File Transfer Edition ✅ +**Current:** v4.01.413 — PWA & File Transfer Edition ✅ * Progressive Web App installation * Secure P2P file transfer system @@ -551,6 +551,6 @@ SecureBit.chat: --- -**Latest Release: v4.01.412** — PWA & Secure File Transfer +**Latest Release: v4.01.413** — PWA & Secure File Transfer diff --git a/SECURITY_DISCLAIMER.md b/SECURITY_DISCLAIMER.md index 5bd97a9..23391aa 100644 --- a/SECURITY_DISCLAIMER.md +++ b/SECURITY_DISCLAIMER.md @@ -1,6 +1,6 @@ # Security Disclaimer and Terms of Use -## 🔒 SecureBit.chat Enhanced Security Edition v4.01.412 +## 🔒 SecureBit.chat Enhanced Security Edition v4.01.413 ### Important Legal Notice @@ -203,6 +203,6 @@ This software is created to: --- *Last Updated: 08.07.2025* -*Version: Enhanced Security Edition v4.01.412* +*Version: Enhanced Security Edition v4.01.413* **USE AT YOUR OWN RISK AND RESPONSIBILITY** \ No newline at end of file diff --git a/index.html b/index.html index 5c0c3ed..fb48b33 100644 --- a/index.html +++ b/index.html @@ -161,7 +161,7 @@ icon: "fas fa-shield-halved", color: "orange", title: "12-Layer Military Security", - description: "Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA. Enhanced Security Edition v4.01.412 provides military-grade protection exceeding government standards." + description: "Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA. Enhanced Security Edition v4.01.413 provides military-grade protection exceeding government standards." }, { icon: "fas fa-bolt", @@ -511,7 +511,7 @@ Enhanced Security Edition Comparison
- SecureBit.chat v4.01.412 Enhanced Security Edition vs leading secure messengers + SecureBit.chat v4.01.413 Enhanced Security Edition vs leading secure messengers
SecureBit.chat dominates in 11 out of 15 security categories, establishing itself as the most secure P2P messenger available. @@ -3944,7 +3944,23 @@ if ('serviceWorker' in navigator) { newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { console.log('🆕 PWA: New version available'); - showUpdateNotification(); + + // Проверяем, установлено ли приложение как PWA + const isPWAInstalled = window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true || + (window.pwaInstallPrompt && window.pwaInstallPrompt.isInstalled); + + if (isPWAInstalled) { + // Если это PWA, показываем уведомление об обновлении + showUpdateNotification(); + } else { + // Если это браузер, показываем промпт установки + if (window.pwaInstallPrompt && !window.pwaInstallPrompt.isInstalled) { + setTimeout(() => { + window.pwaInstallPrompt.showInstallOptions(); + }, 2000); + } + } } }); }); @@ -3966,17 +3982,64 @@ if ('serviceWorker' in navigator) { navigator.serviceWorker.ready.then(registration => { console.log('🎯 PWA: Service Worker ready'); + // Проверяем статус установки PWA + const isPWAInstalled = window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true; + + console.log('🔍 PWA Installation Status:', { + isStandalone: isPWAInstalled, + displayMode: window.matchMedia('(display-mode: standalone)').matches, + iosStandalone: window.navigator.standalone === true + }); + if (window.pwaInstallPrompt && window.pwaInstallPrompt.setServiceWorkerRegistration) { window.pwaInstallPrompt.setServiceWorkerRegistration(registration); + + // Если PWA уже установлено, обновляем статус + if (isPWAInstalled && !window.pwaInstallPrompt.isInstalled) { + console.log('✅ PWA already installed, updating status'); + window.pwaInstallPrompt.isInstalled = true; + window.pwaInstallPrompt.hideInstallPrompts(); + } } if (window.pwaOfflineManager && window.pwaOfflineManager.setServiceWorkerRegistration) { window.pwaOfflineManager.setServiceWorkerRegistration(registration); } }); + + // Слушаем сообщения от Service Worker + navigator.serviceWorker.addEventListener('message', (event) => { + console.log('📨 Message from Service Worker:', event.data); + + if (event.data && event.data.type === 'SW_ACTIVATED') { + console.log('🔄 Service Worker activated, checking for updates...'); + + // Проверяем, установлено ли приложение как PWA + const isPWAInstalled = window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true || + (window.pwaInstallPrompt && window.pwaInstallPrompt.isInstalled); + + if (isPWAInstalled) { + // Если это PWA, показываем уведомление об обновлении + setTimeout(() => { + showUpdateNotification(); + }, 1000); + } else { + // Если это браузер, показываем промпт установки + if (window.pwaInstallPrompt && !window.pwaInstallPrompt.isInstalled) { + setTimeout(() => { + window.pwaInstallPrompt.showInstallOptions(); + }, 2000); + } + } + } + }); } function showUpdateNotification() { + console.log('🆕 Showing update notification for PWA'); + const notification = document.createElement('div'); notification.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-blue-500 text-white p-4 rounded-lg shadow-lg z-50 max-w-sm'; notification.innerHTML = ` @@ -4058,6 +4121,30 @@ function checkPWASupport() { document.addEventListener('DOMContentLoaded', () => { checkPWASupport(); + + // Дополнительная проверка PWA Install Prompt после полной загрузки + setTimeout(() => { + if (window.pwaInstallPrompt) { + console.log('🔍 Final PWA Install Prompt status check...'); + + // Используем новый метод для проверки статуса + window.PWAUtils.checkInstallationStatus(); + + console.log('📱 Final PWA status:', { + isInstalled: window.pwaInstallPrompt.isInstalled, + displayMode: window.matchMedia('(display-mode: standalone)').matches, + iosStandalone: window.navigator.standalone === true + }); + } + }, 2000); + + // Дополнительная проверка через 5 секунд для надежности + setTimeout(() => { + if (window.pwaInstallPrompt) { + console.log('🔍 Delayed PWA status check...'); + window.PWAUtils.checkInstallationStatus(); + } + }, 5000); }); window.PWAUtils = { @@ -4087,6 +4174,38 @@ window.PWAUtils = { } else { console.warn('⚠️ PWA Install Prompt not initialized'); } + }, + + // Новый метод для принудительной проверки статуса установки + checkInstallationStatus: () => { + const isPWAInstalled = window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true; + + console.log('🔍 PWA Installation Status Check:', { + isStandalone: isPWAInstalled, + displayMode: window.matchMedia('(display-mode: standalone)').matches, + iosStandalone: window.navigator.standalone === true, + pwaInstallPrompt: !!window.pwaInstallPrompt, + pwaInstallPromptInstalled: window.pwaInstallPrompt ? window.pwaInstallPrompt.isInstalled : false + }); + + if (window.pwaInstallPrompt && isPWAInstalled && !window.pwaInstallPrompt.isInstalled) { + console.log('✅ Updating PWA Install Prompt status to installed'); + window.pwaInstallPrompt.isInstalled = true; + window.pwaInstallPrompt.hideInstallPrompts(); + } + + return isPWAInstalled; + }, + + // Метод для сброса статуса установки (для тестирования) + resetInstallationStatus: () => { + if (window.pwaInstallPrompt) { + window.pwaInstallPrompt.isInstalled = false; + window.pwaInstallPrompt.installationChecked = false; + window.pwaInstallPrompt.checkInstallationStatus(); + console.log('🔄 PWA Installation status reset'); + } } }; diff --git a/src/components/ui/Header.jsx b/src/components/ui/Header.jsx index 56c5427..690badd 100644 --- a/src/components/ui/Header.jsx +++ b/src/components/ui/Header.jsx @@ -497,7 +497,7 @@ const EnhancedMinimalHeader = ({ React.createElement('p', { key: 'subtitle', className: 'text-xs sm:text-sm text-muted hidden sm:block' - }, 'End-to-end freedom. v4.01.412') + }, 'End-to-end freedom. v4.01.413') ]) ]), diff --git a/src/pwa/install-prompt.js b/src/pwa/install-prompt.js index ac903ee..0bff821 100644 --- a/src/pwa/install-prompt.js +++ b/src/pwa/install-prompt.js @@ -6,6 +6,7 @@ class PWAInstallPrompt { this.installBanner = null; this.dismissedCount = 0; this.maxDismissals = 3; + this.installationChecked = false; this.init(); } @@ -18,39 +19,80 @@ class PWAInstallPrompt { this.createInstallButton(); this.loadInstallPreferences(); - if (this.isIOSSafari() && !this.isInstalled && this.shouldShowPrompt()) { - setTimeout(() => { - this.showIOSInstallInstructions(); - }, 3000); + // Проверяем статус установки периодически для iOS + if (this.isIOSSafari()) { + this.startInstallationMonitoring(); } console.log('✅ PWA Install Prompt initialized'); } checkInstallationStatus() { - if (window.matchMedia('(display-mode: standalone)').matches || - window.navigator.standalone === true) { + // Проверяем различные способы определения установки PWA + const isStandalone = window.matchMedia('(display-mode: standalone)').matches; + const isIOSStandalone = window.navigator.standalone === true; + const hasInstallPreference = this.loadInstallPreferences().installed; + + // Проверяем, установлено ли приложение + if (isStandalone || isIOSStandalone || hasInstallPreference) { this.isInstalled = true; console.log('📱 App is already installed as PWA'); document.body.classList.add('pwa-installed'); + + // Скрываем все промпты установки + this.hideInstallPrompts(); + + // Если это iOS, добавляем специальный класс + if (this.isIOSSafari()) { + document.body.classList.add('ios-pwa'); + } + + this.installationChecked = true; return true; } - if (this.isIOSSafari()) { - this.isInstalled = window.navigator.standalone === true; - if (this.isInstalled) { - console.log('📱 iOS PWA detected'); - document.body.classList.add('pwa-installed', 'ios-pwa'); - } - } - - document.body.classList.add(this.isInstalled ? 'pwa-installed' : 'pwa-browser'); + // Если не установлено, добавляем соответствующие классы + document.body.classList.add('pwa-browser'); if (this.isIOSSafari()) { document.body.classList.add('ios-safari'); } - return this.isInstalled; + this.installationChecked = true; + return false; + } + + startInstallationMonitoring() { + // Для iOS Safari мониторим изменения в standalone режиме + let wasStandalone = window.navigator.standalone; + + const checkStandalone = () => { + const isStandalone = window.navigator.standalone; + + if (isStandalone && !wasStandalone && !this.isInstalled) { + console.log('✅ iOS PWA installation detected'); + this.isInstalled = true; + this.hideInstallPrompts(); + this.showInstallSuccess(); + document.body.classList.remove('pwa-browser'); + document.body.classList.add('pwa-installed', 'ios-pwa'); + + // Сохраняем предпочтение установки + this.saveInstallPreference('installed', true); + } + + wasStandalone = isStandalone; + }; + + // Проверяем каждые 2 секунды + setInterval(checkStandalone, 2000); + + // Также проверяем при изменении видимости страницы + window.addEventListener('visibilitychange', () => { + if (!document.hidden) { + setTimeout(checkStandalone, 1000); + } + }); } setupEventListeners() { @@ -59,6 +101,7 @@ class PWAInstallPrompt { event.preventDefault(); this.deferredPrompt = event; + // Показываем промпт только если приложение не установлено if (!this.isInstalled && this.shouldShowPrompt()) { this.showInstallOptions(); } @@ -75,6 +118,7 @@ class PWAInstallPrompt { document.body.classList.add('pwa-installed'); }); + // Дополнительная проверка для iOS if (this.isIOSSafari()) { let wasStandalone = window.navigator.standalone; @@ -91,6 +135,9 @@ class PWAInstallPrompt { this.showInstallSuccess(); document.body.classList.remove('pwa-browser'); document.body.classList.add('pwa-installed', 'ios-pwa'); + + // Сохраняем предпочтение установки + this.saveInstallPreference('installed', true); } wasStandalone = isStandalone; @@ -166,7 +213,15 @@ class PWAInstallPrompt { } showInstallOptions() { - if (this.isInstalled) return; + // Дополнительная проверка статуса установки + if (!this.installationChecked) { + this.checkInstallationStatus(); + } + + if (this.isInstalled) { + console.log('💿 App is already installed, not showing install options'); + return; + } if (this.isIOSSafari()) { this.showInstallButton(); @@ -178,6 +233,11 @@ class PWAInstallPrompt { } showInstallButton() { + // Дополнительная проверка статуса установки + if (!this.installationChecked) { + this.checkInstallationStatus(); + } + if (this.installButton && !this.isInstalled) { this.installButton.classList.remove('hidden'); @@ -190,10 +250,22 @@ class PWAInstallPrompt { }, 100); console.log('💿 Install button shown'); + } else { + console.log('💿 Install button not shown - app is installed or button not available'); } } showInstallBanner() { + // Дополнительная проверка статуса установки + if (!this.installationChecked) { + this.checkInstallationStatus(); + } + + if (this.isInstalled) { + console.log('💿 App is installed, not showing install banner'); + return; + } + if (!this.installBanner) { this.createInstallBanner(); } @@ -205,18 +277,27 @@ class PWAInstallPrompt { }, 1000); console.log('💿 Install banner shown'); + } else { + console.log('💿 Install banner not shown - app is installed or banner not available'); } } hideInstallPrompts() { + console.log('💿 Hiding all install prompts'); + if (this.installButton) { this.installButton.classList.add('hidden'); + console.log('💿 Install button hidden'); } if (this.installBanner) { this.installBanner.classList.remove('show'); this.installBanner.style.transform = 'translateY(100%)'; + console.log('💿 Install banner hidden'); } + + // Устанавливаем флаг установки + this.isInstalled = true; } async handleInstallClick() { @@ -358,6 +439,8 @@ class PWAInstallPrompt { } showInstallSuccess() { + console.log('✅ Showing installation success notification'); + const notification = document.createElement('div'); notification.className = 'fixed top-4 right-4 bg-green-500 text-white p-4 rounded-lg shadow-lg z-50 max-w-sm transform translate-x-full transition-transform duration-300'; @@ -387,12 +470,37 @@ class PWAInstallPrompt { notification.classList.add('translate-x-full'); setTimeout(() => notification.remove(), 300); }, 5000); + + // Скрываем все промпты установки + this.hideInstallPrompts(); } shouldShowPrompt() { + // Если приложение уже установлено, не показываем промпт + if (this.isInstalled) { + console.log('💿 App is already installed, not showing install prompt'); + return false; + } + + // Дополнительная проверка статуса установки + if (!this.installationChecked) { + this.checkInstallationStatus(); + } + + // Если после проверки приложение установлено, не показываем промпт + if (this.isInstalled) { + console.log('💿 App installation confirmed, not showing install prompt'); + return false; + } + const preferences = this.loadInstallPreferences(); - if (this.isInstalled) return false; + // Проверяем, не было ли приложение уже установлено + if (preferences.installed) { + console.log('💿 Installation preference found, not showing install prompt'); + this.isInstalled = true; + return false; + } if (this.isIOSSafari()) { const lastShown = preferences.ios_instructions_shown; diff --git a/src/pwa/pwa-manager.js b/src/pwa/pwa-manager.js index 90190e8..a94d8d9 100644 --- a/src/pwa/pwa-manager.js +++ b/src/pwa/pwa-manager.js @@ -1,5 +1,5 @@ // PWA Offline Manager for SecureBit.chat -// Enhanced Security Edition v4.01.412 +// Enhanced Security Edition v4.01.413 // Handles offline functionality, data synchronization, and user experience class PWAOfflineManager { diff --git a/sw.js b/sw.js index d7e32be..0b5fcab 100644 --- a/sw.js +++ b/sw.js @@ -1,5 +1,5 @@ // SecureBit.chat Service Worker -// Enhanced Security Edition v4.01.412 +// Enhanced Security Edition v4.01.413 const CACHE_NAME = 'securebit-v4.0.3'; const STATIC_CACHE = 'securebit-static-v4.0.3'; @@ -96,32 +96,41 @@ self.addEventListener('install', (event) => { ); }); -// Activate event - clean up old caches +// Activate event - clean up old caches and notify about updates self.addEventListener('activate', (event) => { console.log('🚀 Service Worker activating...'); event.waitUntil( - caches.keys() - .then((cacheNames) => { - return Promise.all( - cacheNames.map((cacheName) => { - if (cacheName !== STATIC_CACHE && - cacheName !== DYNAMIC_CACHE && - cacheName !== CACHE_NAME) { - console.log('🗑️ Deleting old cache:', cacheName); - return caches.delete(cacheName); - } - }) - ); - }) - .then(() => { - console.log('✅ Service Worker activated'); - // Claim all clients immediately - return self.clients.claim(); - }) + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames.map(cacheName => { + // Remove old caches + if (cacheName !== STATIC_CACHE && cacheName !== DYNAMIC_CACHE && cacheName !== CACHE_NAME) { + console.log(`🗑️ Removing old cache: ${cacheName}`); + return caches.delete(cacheName); + } + }) + ); + }).then(() => { + console.log('✅ Service Worker activated and old caches cleaned'); + + // Notify all clients about the update + return self.clients.claim().then(() => { + self.clients.matchAll().then(clients => { + clients.forEach(client => { + client.postMessage({ + type: 'SW_ACTIVATED', + timestamp: Date.now() + }); + }); + }); + }); + }) ); }); +// Удаляем дублирующийся код activate event + // Fetch event - handle requests with security-aware caching self.addEventListener('fetch', (event) => { const url = new URL(event.request.url); @@ -352,4 +361,4 @@ self.addEventListener('unhandledrejection', (event) => { console.error('❌ Service Worker unhandled rejection:', event.reason); }); -console.log('🔧 SecureBit.chat Service Worker loaded - Enhanced Security Edition v4.01.412'); \ No newline at end of file +console.log('🔧 SecureBit.chat Service Worker loaded - Enhanced Security Edition v4.01.413'); \ No newline at end of file