130 lines
3.5 KiB
JavaScript
130 lines
3.5 KiB
JavaScript
/*
|
|
this file is part of secmsg, and is licensed under the AGPL.
|
|
please see the terms of the license in the file LICENSE.
|
|
|
|
copyright 2023 randomuser
|
|
*/
|
|
'use strict';
|
|
|
|
/* get element ids */
|
|
const loginview = document.getElementById("loginview");
|
|
const chatview = document.getElementById("chatview");
|
|
const chatinput = document.getElementById("inputform");
|
|
const passwordform = document.getElementById("passwordform");
|
|
const messagebox = document.getElementById("messagebox");
|
|
const socketserver = "ws://" + window.location.hostname + ":5000/client";
|
|
|
|
/* globals */
|
|
var secret;
|
|
var socket;
|
|
let date = new Date();
|
|
var username = sjcl.codec.hex.fromBits(
|
|
sjcl.hash.sha256.hash(
|
|
date.toString()
|
|
)
|
|
).slice(0, 6);
|
|
var sentinel = "SECMSG_CONFIRMED";
|
|
var inChat = 0;
|
|
|
|
function hexToRGB(h) {
|
|
let r, g, b;
|
|
r = Number("0x" + h[1] + h[2]);
|
|
g = Number("0x" + h[3] + h[4]);
|
|
b = Number("0x" + h[5] + h[6]);
|
|
|
|
return [r, g, b];
|
|
}
|
|
|
|
function RGBToHex(col) {
|
|
let r = col[0];
|
|
let g = col[1];
|
|
let b = col[2];
|
|
|
|
r = r.toString(16);
|
|
g = g.toString(16);
|
|
b = b.toString(16);
|
|
|
|
if (r.length == 1)
|
|
r = "0" + r;
|
|
if (g.length == 1)
|
|
g = "0" + g;
|
|
if (b.length == 1)
|
|
b = "0" + b;
|
|
|
|
return "#" + r + g + b;
|
|
}
|
|
|
|
function invertColor(col) {
|
|
let r = Math.abs(col[0] - 255);
|
|
let g = Math.abs(col[1] - 255);
|
|
let b = Math.abs(col[2] - 255);
|
|
|
|
return [r, g, b]
|
|
}
|
|
|
|
/* configure blocking and none */
|
|
loginview.style.display = "block"
|
|
chatview.style.display = "none"
|
|
|
|
function appendToChatBuffer(msg) {
|
|
let splitted = msg.split(": ")
|
|
let username = splitted[0]
|
|
let message = splitted[1]
|
|
const elem = document.createElement("p");
|
|
let color = "#" + username
|
|
let inverted = RGBToHex(invertColor(hexToRGB(color)))
|
|
let usernametag = document.createElement("span");
|
|
usernametag.style.backgroundColor = color;
|
|
usernametag.style.color = inverted;
|
|
usernametag.innerHTML = username;
|
|
|
|
let text = document.createTextNode(": " + message);
|
|
|
|
elem.appendChild(usernametag);
|
|
elem.appendChild(text);
|
|
messagebox.appendChild(elem);
|
|
setTimeout(function () {elem.remove(); }, message.length / 40 * 1000 * 3);
|
|
}
|
|
|
|
/* loginview button configuration */
|
|
passwordform.addEventListener("keyup", function(event) {
|
|
if (event.keyCode === 13) {
|
|
secret = passwordform.value
|
|
loginview.style.display = "none"
|
|
chatview.style.display = "block"
|
|
inChat = 1;
|
|
chatinput.focus()
|
|
|
|
/* connect to ws server */
|
|
socket = new WebSocket(socketserver)
|
|
|
|
socket.onmessage = function(e) {
|
|
let decrypted = sjcl.decrypt(secret, JSON.parse(e.data))
|
|
/* look for the sentinel */
|
|
if (decrypted.slice(0, sentinel.length) === sentinel) {
|
|
appendToChatBuffer(decrypted.slice(sentinel.length))
|
|
}
|
|
};
|
|
}
|
|
})
|
|
|
|
chatinput.addEventListener("keyup", function(event) {
|
|
if (event.keyCode === 13) { // enter was pressed
|
|
let message = chatinput.value
|
|
appendToChatBuffer(username + ": " + message);
|
|
let cyphertext = JSON.stringify(sjcl.encrypt(secret, sentinel + username + ": " + message))
|
|
socket.send(cyphertext)
|
|
chatinput.value = ""
|
|
}
|
|
});
|
|
|
|
document.addEventListener('visibilitychange', function() {
|
|
if (inChat) {
|
|
if (document.visibilityState === 'visible') {
|
|
chatview.style.display = "none";
|
|
} else {
|
|
chatview.style.display = "visible";
|
|
}
|
|
}
|
|
});
|