feat: implement automatic key generation on channel creation
- Remove manual "Create secure keys" button requirement - Add automatic key generation trigger when "Create channel" is clicked - Implement loading state with spinner animation during key generation - Add isGeneratingKeys state management across components - Pass handleCreateOffer function as prop to EnhancedConnectionSetup - Update UI to show "Generating secure keys..." message during process - Ensure proper state cleanup on disconnect and data clearing - Improve user experience by eliminating extra click step in channel creation flow
This commit is contained in:
1 parent
5ddfd1f5b3
commit
4e7f5867b5
3 files changed
+65
-41
No files matched your search
Vendored
+28
-15
@@ -268,12 +268,15 @@ var EnhancedConnectionSetup = ({
|
||||
nextQrFrame,
|
||||
prevQrFrame,
|
||||
markAnswerCreated,
|
||||
notificationIntegrationRef
|
||||
notificationIntegrationRef,
|
||||
isGeneratingKeys,
|
||||
handleCreateOffer
|
||||
}) => {
|
||||
const [mode, setMode] = React.useState("select");
|
||||
const [notificationPermissionRequested, setNotificationPermissionRequested] = React.useState(false);
|
||||
const resetToSelect = () => {
|
||||
setMode("select");
|
||||
setIsGeneratingKeys(false);
|
||||
onClearData();
|
||||
};
|
||||
const handleVerificationConfirm = () => {
|
||||
@@ -293,8 +296,8 @@ var EnhancedConnectionSetup = ({
|
||||
if (!window.isSecureContext && window.location.protocol !== "https:" && window.location.hostname !== "localhost") {
|
||||
return;
|
||||
}
|
||||
const currentPermission = typeof Notification !== "undefined" && Notification ? Notification.permission : "denied";
|
||||
if (typeof Notification !== "undefined" && currentPermission === "default") {
|
||||
const currentPermission = Notification.permission;
|
||||
if (currentPermission === "default") {
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission === "granted") {
|
||||
try {
|
||||
@@ -307,7 +310,6 @@ var EnhancedConnectionSetup = ({
|
||||
}
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (typeof Notification === "undefined") return;
|
||||
const welcomeNotification = new Notification("SecureBit Chat", {
|
||||
body: "Notifications enabled! You will receive alerts for new messages.",
|
||||
icon: "/logo/icon-192x192.png",
|
||||
@@ -323,7 +325,7 @@ var EnhancedConnectionSetup = ({
|
||||
}
|
||||
}, 1e3);
|
||||
}
|
||||
} else if (typeof Notification !== "undefined" && currentPermission === "granted") {
|
||||
} else if (currentPermission === "granted") {
|
||||
try {
|
||||
if (window.NotificationIntegration && webrtcManagerRef.current && !notificationIntegrationRef.current) {
|
||||
const integration = new window.NotificationIntegration(webrtcManagerRef.current);
|
||||
@@ -334,7 +336,6 @@ var EnhancedConnectionSetup = ({
|
||||
}
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (typeof Notification === "undefined") return;
|
||||
const testNotification = new Notification("SecureBit Chat", {
|
||||
body: "Notifications are working! You will receive alerts for new messages.",
|
||||
icon: "/logo/icon-192x192.png",
|
||||
@@ -404,6 +405,11 @@ var EnhancedConnectionSetup = ({
|
||||
onClick: () => {
|
||||
requestNotificationPermissionOnInteraction();
|
||||
setMode("create");
|
||||
setTimeout(() => {
|
||||
if (webrtcManagerRef.current) {
|
||||
handleCreateOffer();
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
className: "card-minimal rounded-xl p-6 cursor-pointer group flex-1 create"
|
||||
}, [
|
||||
@@ -590,16 +596,15 @@ var EnhancedConnectionSetup = ({
|
||||
key: "description",
|
||||
className: "text-secondary text-sm mb-4"
|
||||
}, "Creating cryptographically strong keys and codes to protect against attacks"),
|
||||
!showOfferStep && React.createElement("button", {
|
||||
key: "create-btn",
|
||||
onClick: onCreateOffer,
|
||||
disabled: connectionStatus === "connecting",
|
||||
className: `w-full btn-primary text-white py-3 px-4 rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed`
|
||||
!showOfferStep && isGeneratingKeys && React.createElement("div", {
|
||||
key: "loading-state",
|
||||
className: "w-full py-3 px-4 rounded-lg font-medium transition-all duration-200 bg-blue-500/10 border border-blue-500/20 text-blue-400 flex items-center justify-center"
|
||||
}, [
|
||||
React.createElement("i", {
|
||||
className: "fas fa-shield-alt mr-2"
|
||||
key: "spinner",
|
||||
className: "fas fa-spinner fa-spin mr-2"
|
||||
}),
|
||||
"Create secure keys"
|
||||
"Generating secure keys..."
|
||||
]),
|
||||
showOfferStep && React.createElement("div", {
|
||||
key: "offer-result",
|
||||
@@ -1360,6 +1365,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
const [qrCodeUrl, setQrCodeUrl] = React.useState("");
|
||||
const [showQRScanner, setShowQRScanner] = React.useState(false);
|
||||
const [showQRScannerModal, setShowQRScannerModal] = React.useState(false);
|
||||
const [isGeneratingKeys, setIsGeneratingKeys2] = React.useState(false);
|
||||
const [isVerified, setIsVerified] = React.useState(false);
|
||||
const [securityLevel, setSecurityLevel] = React.useState(null);
|
||||
const [sessionTimeLeft, setSessionTimeLeft] = React.useState(0);
|
||||
@@ -1672,7 +1678,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
handleAnswerError,
|
||||
handleVerificationStateChange
|
||||
);
|
||||
if (typeof Notification !== "undefined" && Notification.permission === "granted" && window.NotificationIntegration && !notificationIntegrationRef.current) {
|
||||
if (Notification.permission === "granted" && window.NotificationIntegration && !notificationIntegrationRef.current) {
|
||||
try {
|
||||
const integration = new window.NotificationIntegration(webrtcManagerRef2.current);
|
||||
integration.init().then(() => {
|
||||
@@ -2449,6 +2455,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
};
|
||||
const handleCreateOffer = async () => {
|
||||
try {
|
||||
setIsGeneratingKeys2(true);
|
||||
setOfferData("");
|
||||
setShowOfferStep(false);
|
||||
setShowQRCode(false);
|
||||
@@ -2537,6 +2544,8 @@ var EnhancedSecureP2PChat = () => {
|
||||
id: Date.now(),
|
||||
timestamp: Date.now()
|
||||
}]);
|
||||
} finally {
|
||||
setIsGeneratingKeys2(false);
|
||||
}
|
||||
};
|
||||
const handleCreateAnswer = async () => {
|
||||
@@ -2897,6 +2906,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
setOfferInput("");
|
||||
setAnswerInput("");
|
||||
setShowOfferStep(false);
|
||||
setIsGeneratingKeys2(false);
|
||||
if (!shouldPreserveAnswerData()) {
|
||||
setShowAnswerStep(false);
|
||||
}
|
||||
@@ -2954,6 +2964,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
setAnswerInput("");
|
||||
setShowOfferStep(false);
|
||||
setShowAnswerStep(false);
|
||||
setIsGeneratingKeys2(false);
|
||||
setShowQRCode(false);
|
||||
setQrCodeUrl("");
|
||||
setShowQRScanner(false);
|
||||
@@ -3154,7 +3165,9 @@ var EnhancedSecureP2PChat = () => {
|
||||
prevQrFrame,
|
||||
// PAKE passwords removed - using SAS verification instead
|
||||
markAnswerCreated,
|
||||
notificationIntegrationRef
|
||||
notificationIntegrationRef,
|
||||
isGeneratingKeys,
|
||||
handleCreateOffer
|
||||
})
|
||||
),
|
||||
// QR Scanner Modal
|
||||
|
||||
Vendored
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../src/app.jsx"],
|
||||
"sourcesContent": ["\r\n // Enhanced Copy Button with better UX\r\n const EnhancedCopyButton = ({ text, className = \"\", children }) => {\r\n const [copied, setCopied] = React.useState(false);\r\n \r\n const handleCopy = async () => {\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n } catch (error) {\r\n console.error('Copy failed:', error);\r\n // Fallback for older browsers\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n document.body.appendChild(textArea);\r\n textArea.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(textArea);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n }\r\n };\r\n \r\n return React.createElement('button', {\r\n onClick: handleCopy,\r\n className: `${className} transition-all duration-200`\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${copied ? 'fas fa-check accent-green' : 'fas fa-copy text-secondary'} mr-2`\r\n }),\r\n copied ? 'Copied!' : children\r\n ]);\r\n };\r\n \r\n // Verification Component\r\n const VerificationStep = ({ verificationCode, onConfirm, onReject, localConfirmed, remoteConfirmed, bothConfirmed }) => {\r\n return React.createElement('div', {\r\n className: \"card-minimal rounded-xl p-6 border-purple-500/20\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center mb-4\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'icon',\r\n className: \"w-10 h-10 bg-purple-500/10 border border-purple-500/20 rounded-lg flex items-center justify-center mr-3\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-shield-alt accent-purple'\r\n })\r\n ]),\r\n React.createElement('h3', {\r\n key: 'title',\r\n className: \"text-lg font-medium text-primary\"\r\n }, \"Security verification\")\r\n ]),\r\n React.createElement('div', {\r\n key: 'content',\r\n className: \"space-y-4\"\r\n }, [\r\n React.createElement('p', {\r\n key: 'description',\r\n className: \"text-secondary text-sm\"\r\n }, \"Verify the security code with your contact via another communication channel (voice, SMS, etc.):\"),\r\n React.createElement('div', {\r\n key: 'code-display',\r\n className: \"text-center\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'code',\r\n className: \"verification-code text-2xl py-4\"\r\n }, verificationCode)\r\n ]),\r\n // Verification status indicators\r\n React.createElement('div', {\r\n key: 'verification-status',\r\n className: \"space-y-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'local-status',\r\n className: `flex items-center justify-between p-2 rounded-lg ${localConfirmed ? 'bg-green-500/10 border border-green-500/20' : 'bg-gray-500/10 border border-gray-500/20'}`\r\n }, [\r\n React.createElement('span', {\r\n Line truncated
|
||||
"mappings": "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 truncated
|
||||
"names": ["webrtcManagerRef", "offerData", "payload"]
|
||||
"sourcesContent": ["\r\n // Enhanced Copy Button with better UX\r\n const EnhancedCopyButton = ({ text, className = \"\", children }) => {\r\n const [copied, setCopied] = React.useState(false);\r\n \r\n const handleCopy = async () => {\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n } catch (error) {\r\n console.error('Copy failed:', error);\r\n // Fallback for older browsers\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n document.body.appendChild(textArea);\r\n textArea.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(textArea);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n }\r\n };\r\n \r\n return React.createElement('button', {\r\n onClick: handleCopy,\r\n className: `${className} transition-all duration-200`\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${copied ? 'fas fa-check accent-green' : 'fas fa-copy text-secondary'} mr-2`\r\n }),\r\n copied ? 'Copied!' : children\r\n ]);\r\n };\r\n \r\n // Verification Component\r\n const VerificationStep = ({ verificationCode, onConfirm, onReject, localConfirmed, remoteConfirmed, bothConfirmed }) => {\r\n return React.createElement('div', {\r\n className: \"card-minimal rounded-xl p-6 border-purple-500/20\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center mb-4\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'icon',\r\n className: \"w-10 h-10 bg-purple-500/10 border border-purple-500/20 rounded-lg flex items-center justify-center mr-3\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-shield-alt accent-purple'\r\n })\r\n ]),\r\n React.createElement('h3', {\r\n key: 'title',\r\n className: \"text-lg font-medium text-primary\"\r\n }, \"Security verification\")\r\n ]),\r\n React.createElement('div', {\r\n key: 'content',\r\n className: \"space-y-4\"\r\n }, [\r\n React.createElement('p', {\r\n key: 'description',\r\n className: \"text-secondary text-sm\"\r\n }, \"Verify the security code with your contact via another communication channel (voice, SMS, etc.):\"),\r\n React.createElement('div', {\r\n key: 'code-display',\r\n className: \"text-center\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'code',\r\n className: \"verification-code text-2xl py-4\"\r\n }, verificationCode)\r\n ]),\r\n // Verification status indicators\r\n React.createElement('div', {\r\n key: 'verification-status',\r\n className: \"space-y-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'local-status',\r\n className: `flex items-center justify-between p-2 rounded-lg ${localConfirmed ? 'bg-green-500/10 border border-green-500/20' : 'bg-gray-500/10 border border-gray-500/20'}`\r\n }, [\r\n React.createElement('span', {\r\n Line truncated
|
||||
"mappings": "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 truncated
|
||||
"names": ["setIsGeneratingKeys", "webrtcManagerRef", "offerData", "payload"]
|
||||
}
|
||||
+34
-23
@@ -281,13 +281,16 @@
|
||||
nextQrFrame,
|
||||
prevQrFrame,
|
||||
markAnswerCreated,
|
||||
notificationIntegrationRef
|
||||
notificationIntegrationRef,
|
||||
isGeneratingKeys,
|
||||
handleCreateOffer
|
||||
}) => {
|
||||
const [mode, setMode] = React.useState('select');
|
||||
const [notificationPermissionRequested, setNotificationPermissionRequested] = React.useState(false);
|
||||
|
||||
const resetToSelect = () => {
|
||||
setMode('select');
|
||||
setIsGeneratingKeys(false);
|
||||
onClearData();
|
||||
};
|
||||
|
||||
@@ -317,12 +320,10 @@
|
||||
}
|
||||
|
||||
// Check current permission status
|
||||
const currentPermission = (typeof Notification !== 'undefined' && Notification)
|
||||
? Notification.permission
|
||||
: 'denied';
|
||||
const currentPermission = Notification.permission;
|
||||
|
||||
// Only request if permission is default (not granted or denied)
|
||||
if (typeof Notification !== 'undefined' && currentPermission === 'default') {
|
||||
if (currentPermission === 'default') {
|
||||
const permission = await Notification.requestPermission();
|
||||
|
||||
if (permission === 'granted') {
|
||||
@@ -339,10 +340,9 @@
|
||||
// Handle error silently
|
||||
}
|
||||
|
||||
// Send welcome notification (only if Notifications API exists)
|
||||
// Send welcome notification
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (typeof Notification === 'undefined') return;
|
||||
const welcomeNotification = new Notification('SecureBit Chat', {
|
||||
body: 'Notifications enabled! You will receive alerts for new messages.',
|
||||
icon: '/logo/icon-192x192.png',
|
||||
@@ -363,7 +363,7 @@
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
} else if (typeof Notification !== 'undefined' && currentPermission === 'granted') {
|
||||
} else if (currentPermission === 'granted') {
|
||||
// Initialize notification integration immediately
|
||||
try {
|
||||
if (window.NotificationIntegration && webrtcManagerRef.current && !notificationIntegrationRef.current) {
|
||||
@@ -380,7 +380,6 @@
|
||||
// Test notification to confirm it works
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (typeof Notification === 'undefined') return;
|
||||
const testNotification = new Notification('SecureBit Chat', {
|
||||
body: 'Notifications are working! You will receive alerts for new messages.',
|
||||
icon: '/logo/icon-192x192.png',
|
||||
@@ -459,6 +458,12 @@
|
||||
onClick: () => {
|
||||
requestNotificationPermissionOnInteraction();
|
||||
setMode('create');
|
||||
// Автоматически запускаем генерацию ключей
|
||||
setTimeout(() => {
|
||||
if (webrtcManagerRef.current) {
|
||||
handleCreateOffer();
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
className: "card-minimal rounded-xl p-6 cursor-pointer group flex-1 create"
|
||||
}, [
|
||||
@@ -631,7 +636,7 @@
|
||||
className: "text-xl font-semibold text-primary mb-2"
|
||||
}, 'Creating a secure channel')
|
||||
]),
|
||||
|
||||
|
||||
// Step 1
|
||||
!showAnswerStep && React.createElement('div', {
|
||||
key: 'step1',
|
||||
@@ -654,16 +659,15 @@
|
||||
key: 'description',
|
||||
className: "text-secondary text-sm mb-4"
|
||||
}, "Creating cryptographically strong keys and codes to protect against attacks"),
|
||||
!showOfferStep && React.createElement('button', {
|
||||
key: 'create-btn',
|
||||
onClick: onCreateOffer,
|
||||
disabled: connectionStatus === 'connecting',
|
||||
className: `w-full btn-primary text-white py-3 px-4 rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed`
|
||||
!showOfferStep && isGeneratingKeys && React.createElement('div', {
|
||||
key: 'loading-state',
|
||||
className: "w-full py-3 px-4 rounded-lg font-medium transition-all duration-200 bg-blue-500/10 border border-blue-500/20 text-blue-400 flex items-center justify-center"
|
||||
}, [
|
||||
React.createElement('i', {
|
||||
className: 'fas fa-shield-alt mr-2'
|
||||
key: 'spinner',
|
||||
className: 'fas fa-spinner fa-spin mr-2'
|
||||
}),
|
||||
'Create secure keys'
|
||||
'Generating secure keys...'
|
||||
]),
|
||||
|
||||
showOfferStep && React.createElement('div', {
|
||||
@@ -1472,6 +1476,7 @@
|
||||
const [qrCodeUrl, setQrCodeUrl] = React.useState('');
|
||||
const [showQRScanner, setShowQRScanner] = React.useState(false);
|
||||
const [showQRScannerModal, setShowQRScannerModal] = React.useState(false);
|
||||
const [isGeneratingKeys, setIsGeneratingKeys] = React.useState(false);
|
||||
|
||||
|
||||
const [isVerified, setIsVerified] = React.useState(false);
|
||||
@@ -1904,7 +1909,7 @@
|
||||
);
|
||||
|
||||
// Initialize notification integration if permission was already granted
|
||||
if (typeof Notification !== 'undefined' && Notification.permission === 'granted' && window.NotificationIntegration && !notificationIntegrationRef.current) {
|
||||
if (Notification.permission === 'granted' && window.NotificationIntegration && !notificationIntegrationRef.current) {
|
||||
try {
|
||||
const integration = new window.NotificationIntegration(webrtcManagerRef.current);
|
||||
integration.init().then(() => {
|
||||
@@ -2800,7 +2805,7 @@
|
||||
const handleCreateOffer = async () => {
|
||||
try {
|
||||
// All security features are enabled by default
|
||||
|
||||
setIsGeneratingKeys(true);
|
||||
setOfferData('');
|
||||
setShowOfferStep(false);
|
||||
setShowQRCode(false);
|
||||
@@ -2904,6 +2909,8 @@
|
||||
id: Date.now(),
|
||||
timestamp: Date.now()
|
||||
}]);
|
||||
} finally {
|
||||
setIsGeneratingKeys(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3340,6 +3347,7 @@
|
||||
setOfferInput('');
|
||||
setAnswerInput('');
|
||||
setShowOfferStep(false);
|
||||
setIsGeneratingKeys(false);
|
||||
|
||||
if (!shouldPreserveAnswerData()) {
|
||||
setShowAnswerStep(false);
|
||||
@@ -3417,13 +3425,14 @@
|
||||
setRemoteVerificationConfirmed(false);
|
||||
setBothVerificationsConfirmed(false);
|
||||
|
||||
// Reset UI to initial state
|
||||
setOfferData('');
|
||||
setAnswerData('');
|
||||
// Reset UI to initial state
|
||||
setOfferData('');
|
||||
setAnswerData('');
|
||||
setOfferInput('');
|
||||
setAnswerInput('');
|
||||
setShowOfferStep(false);
|
||||
setShowAnswerStep(false);
|
||||
setIsGeneratingKeys(false);
|
||||
setShowQRCode(false);
|
||||
setQrCodeUrl('');
|
||||
setShowQRScanner(false);
|
||||
@@ -3662,7 +3671,9 @@
|
||||
prevQrFrame: prevQrFrame,
|
||||
// PAKE passwords removed - using SAS verification instead
|
||||
markAnswerCreated: markAnswerCreated,
|
||||
notificationIntegrationRef: notificationIntegrationRef
|
||||
notificationIntegrationRef: notificationIntegrationRef,
|
||||
isGeneratingKeys: isGeneratingKeys,
|
||||
handleCreateOffer: handleCreateOffer
|
||||
})
|
||||
),
|
||||
|
||||
|
||||
Reference in new issue
Block a user