mirror of
https://github.com/darkwire/darkwire.io.git
synced 2025-07-18 18:54:52 +00:00
Use crypto web API and prevent usage in unsupported browsers
This commit is contained in:
parent
6e1986b375
commit
39e4d3d56c
107
src/js/main.js
107
src/js/main.js
@ -45,6 +45,18 @@ $(function() {
|
||||
|
||||
if (!roomId) return;
|
||||
|
||||
if ((!window.crypto && !window.msCrypto) || !window.crypto.subtle) {
|
||||
$('#no-crypto').modal({
|
||||
backdrop: 'static',
|
||||
show: false,
|
||||
keyboard: false
|
||||
})
|
||||
$('#no-crypto').modal('show');
|
||||
return;
|
||||
}
|
||||
|
||||
var crypto = window.crypto;
|
||||
|
||||
let socket = io(roomId);
|
||||
$('#roomIdKey').text(roomId.replace('/', ''));
|
||||
|
||||
@ -82,7 +94,9 @@ $(function() {
|
||||
// Sends a chat message
|
||||
function sendMessage () {
|
||||
// Don't allow sending if key is empty
|
||||
if (!encryptionKey.trim().length) return;
|
||||
if (!$('.key').text().trim().length) return;
|
||||
|
||||
var vector = crypto.getRandomValues(new Uint8Array(16));
|
||||
|
||||
let message = $inputMessage.val();
|
||||
// Prevent markup from being injected into the message
|
||||
@ -96,18 +110,20 @@ $(function() {
|
||||
message: message
|
||||
});
|
||||
// tell server to execute 'new message' and send along one parameter
|
||||
socket.emit('new message', encrypt(message));
|
||||
createKey(encryptionKey)
|
||||
.then(function(key) {
|
||||
return encryptData(message, key, vector);
|
||||
})
|
||||
.then(function(data) {
|
||||
var encryptedData = new Uint8Array(data);
|
||||
socket.emit('new message', {
|
||||
message: convertArrayBufferViewtoString(encryptedData),
|
||||
vector: convertArrayBufferViewtoString(vector)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function encrypt(text) {
|
||||
return CryptoJS.AES.encrypt(text, $key.val()).toString();
|
||||
}
|
||||
|
||||
function decrypt(text) {
|
||||
return CryptoJS.AES.decrypt(text, $key.val()).toString(CryptoJS.enc.Utf8) || text;
|
||||
}
|
||||
|
||||
// Log a message
|
||||
function log (message, options) {
|
||||
let html = options && options.html === true || false;
|
||||
@ -327,7 +343,6 @@ $(function() {
|
||||
// Whenever the server emits 'new message', update the chat body
|
||||
socket.on('new message', function (data) {
|
||||
// Don't show messages if no key
|
||||
|
||||
if (!isActive) {
|
||||
newMessages++;
|
||||
favicon.badge(newMessages);
|
||||
@ -335,8 +350,26 @@ $(function() {
|
||||
beep.play();
|
||||
}
|
||||
}
|
||||
data.message = decrypt(data.message);
|
||||
addChatMessage(data);
|
||||
|
||||
var username = data.username;
|
||||
|
||||
createKey(encryptionKey)
|
||||
.then(function(key) {
|
||||
var msg = convertStringToArrayBufferView(data.message);
|
||||
var vector = convertStringToArrayBufferView(data.vector);
|
||||
return decryptData(msg, key, vector)
|
||||
})
|
||||
.then(function(data) {
|
||||
var decryptedData = new Uint8Array(data);
|
||||
var msg = convertArrayBufferViewtoString(decryptedData);
|
||||
addChatMessage({
|
||||
username: username,
|
||||
message: msg
|
||||
});
|
||||
})
|
||||
.catch(function() {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// Whenever the server emits 'user joined', log it in the chat body
|
||||
@ -468,7 +501,8 @@ $(function() {
|
||||
|
||||
function updateKeyVal(val) {
|
||||
$('.key').val(val);
|
||||
$('.key').text(val);
|
||||
$('.key').text(val);
|
||||
|
||||
encryptionKey = val;
|
||||
$('textarea.share-text').val("Let's chat on darkwire.io at https://darkwire.io" + roomId + " using the passphrase " + encryptionKey);
|
||||
autosize.update($('textarea.share-text'));
|
||||
@ -551,6 +585,49 @@ $(function() {
|
||||
|
||||
$('input.bs-switch').on('switchChange.bootstrapSwitch', function(event, state) {
|
||||
soundEnabled = state;
|
||||
});
|
||||
});
|
||||
|
||||
function convertStringToArrayBufferView(str) {
|
||||
var bytes = new Uint8Array(str.length);
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
bytes[i] = str.charCodeAt(i);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function convertArrayBufferViewtoString(buffer) {
|
||||
var str = "";
|
||||
for (var i = 0; i < buffer.byteLength; i++) {
|
||||
str += String.fromCharCode(buffer[i]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function createKey(password) {
|
||||
return crypto.subtle.digest({
|
||||
name: "SHA-256"
|
||||
}, convertStringToArrayBufferView(password))
|
||||
.then(function(result) {
|
||||
return window.crypto.subtle.importKey("raw", result, {
|
||||
name: "AES-CBC"
|
||||
}, false, ["encrypt", "decrypt"]);
|
||||
});
|
||||
}
|
||||
|
||||
function encryptData(data, key, vector) {
|
||||
return crypto.subtle.encrypt({
|
||||
name: "AES-CBC",
|
||||
iv: vector
|
||||
}, key, convertStringToArrayBufferView(data));
|
||||
}
|
||||
|
||||
function decryptData(data, key, vector) {
|
||||
return crypto.subtle.decrypt({
|
||||
name: "AES-CBC",
|
||||
iv: vector
|
||||
}, key, data);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -19,7 +19,8 @@ class Room {
|
||||
// we tell the client to execute 'new message'
|
||||
socket.broadcast.emit('new message', {
|
||||
username: socket.username,
|
||||
message: data
|
||||
message: data.message,
|
||||
vector: data.vector
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -180,6 +180,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="no-crypto" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Browser Not Supported</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Your browser does not support the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Crypto" target="_blank">Crypto Web API</a>.</p>
|
||||
<p>Try using the lastest version of Chrome, Firefox or Safari.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
|
||||
<script src="https://cdn.socket.io/socket.io-1.4.3.js"></script>
|
||||
<script src="/favicon.js"></script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user