secmsg/secmsg/static/main.js

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";
}
}
});