125 lines
3.6 KiB
JavaScript
125 lines
3.6 KiB
JavaScript
let offlineMode = true; // Set this based on your application's state
|
|
let currentPublicKey, nextPublicKey;
|
|
|
|
function arrayBufferToBase64(buffer) {
|
|
let binary = '';
|
|
const bytes = new Uint8Array(buffer);
|
|
for (let i = 0; i < bytes.byteLength; i++) {
|
|
binary += String.fromCharCode(bytes[i]);
|
|
}
|
|
return window.btoa(binary);
|
|
}
|
|
|
|
function updatePublicKeys() {
|
|
if (offlineMode) {
|
|
console.log('Running in offline mode. Skipping public key update.');
|
|
return;
|
|
}
|
|
// Fetch the current and next public keys from the server
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open('GET', 'http://localhost:9876/api/getPublicKeys', true);
|
|
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
const keys = JSON.parse(xhr.responseText);
|
|
currentPublicKey = keys.currentPublicKey;
|
|
nextPublicKey = keys.nextPublicKey;
|
|
}
|
|
};
|
|
|
|
xhr.send();
|
|
}
|
|
|
|
function encryptWithPublicKey(plaintext, pubKey) {
|
|
if (offlineMode) {
|
|
console.log('Running in offline mode. Skipping encryption.');
|
|
return Promise.resolve(plaintext);
|
|
}
|
|
// Implement RSA encryption with public key
|
|
// Assuming pubKey is in PEM format
|
|
const publicKey = new TextEncoder().encode(pubKey);
|
|
const textBuffer = new TextEncoder().encode(plaintext);
|
|
|
|
return window.crypto.subtle.importKey(
|
|
'spki',
|
|
publicKey,
|
|
{
|
|
name: 'RSA-OAEP',
|
|
hash: 'SHA-256'
|
|
},
|
|
false,
|
|
['encrypt']
|
|
).then(key => {
|
|
return window.crypto.subtle.encrypt(
|
|
{
|
|
name: 'RSA-OAEP'
|
|
},
|
|
key,
|
|
textBuffer
|
|
);
|
|
}).then(encrypted => {
|
|
return arrayBufferToBase64(encrypted);
|
|
});
|
|
}
|
|
|
|
function sendMessage() {
|
|
const xhr = new XMLHttpRequest();
|
|
const message = {
|
|
text: 'Hello, server!'
|
|
};
|
|
|
|
// Encrypt the message using the server's public key
|
|
encryptWithPublicKey(message.text, currentPublicKey).then(encryptedMessage => {
|
|
xhr.open('POST', 'http://localhost:9876/api/sendMessage', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
|
|
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
console.log('Message sent successfully:', xhr.responseText);
|
|
}
|
|
};
|
|
|
|
xhr.send(JSON.stringify({text: encryptedMessage}));
|
|
});
|
|
}
|
|
|
|
function addMessageToChat(message, sender) {
|
|
const chatWindow = document.getElementById('chat-window');
|
|
const messageDiv = document.createElement('div');
|
|
|
|
messageDiv.className = sender; // 'user' or 'server'
|
|
messageDiv.textContent = message;
|
|
|
|
chatWindow.appendChild(messageDiv);
|
|
}
|
|
|
|
function pollForMessages() {
|
|
if (offlineMode) {
|
|
console.log('Running in offline mode. Skipping message polling.');
|
|
return;
|
|
}
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open('GET', 'http://localhost:9876/api/receiveMessage', true);
|
|
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
const receivedMsg = JSON.parse(xhr.responseText);
|
|
addMessageToChat(receivedMsg.text, 'server');
|
|
}
|
|
};
|
|
|
|
xhr.send();
|
|
}
|
|
|
|
// Start polling for messages
|
|
if (!offlineMode) {
|
|
setInterval(pollForMessages, 2000); // Poll every 2 seconds
|
|
}
|
|
|
|
function main() {
|
|
if (!offlineMode) {
|
|
updatePublicKeys(); // Before joining the channel
|
|
setInterval(updatePublicKeys, 5 * 60 * 1000); // Check for new keys every 5 minutes
|
|
}
|
|
}
|