some fixes; asynchronous message decryption to keep browser responsive
This commit is contained in:
@@ -995,7 +995,7 @@ module.exports = {
|
|||||||
|
|
||||||
show_version: true,
|
show_version: true,
|
||||||
show_comment: true,
|
show_comment: true,
|
||||||
versionstring: "OpenPGP.js v1.2.0",
|
versionstring: "OpenPGP.js v1.3.0",
|
||||||
commentstring: "http://openpgpjs.org",
|
commentstring: "http://openpgpjs.org",
|
||||||
|
|
||||||
keyserver: "keyserver.linux.it", // "pgp.mit.edu:11371"
|
keyserver: "keyserver.linux.it", // "pgp.mit.edu:11371"
|
||||||
@@ -5255,7 +5255,6 @@ function ii(a, b, c, d, x, s, t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function md51(s) {
|
function md51(s) {
|
||||||
txt = '';
|
|
||||||
var n = s.length,
|
var n = s.length,
|
||||||
state = [1732584193, -271733879, -1732584194, 271733878],
|
state = [1732584193, -271733879, -1732584194, 271733878],
|
||||||
i;
|
i;
|
||||||
@@ -15922,6 +15921,10 @@ S2K.prototype.write = function () {
|
|||||||
bytes += this.salt;
|
bytes += this.salt;
|
||||||
bytes += String.fromCharCode(this.c);
|
bytes += String.fromCharCode(this.c);
|
||||||
break;
|
break;
|
||||||
|
case 'gnu':
|
||||||
|
throw new Error("GNU s2k type not supported.");
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown s2k type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
@@ -15950,8 +15953,8 @@ S2K.prototype.produce_key = function (passphrase, numBytes) {
|
|||||||
|
|
||||||
case 'iterated':
|
case 'iterated':
|
||||||
var isp = [],
|
var isp = [],
|
||||||
count = s2k.get_count();
|
count = s2k.get_count(),
|
||||||
data = s2k.salt + passphrase;
|
data = s2k.salt + passphrase;
|
||||||
|
|
||||||
while (isp.length * data.length < count)
|
while (isp.length * data.length < count)
|
||||||
isp.push(data);
|
isp.push(data);
|
||||||
@@ -15962,6 +15965,12 @@ S2K.prototype.produce_key = function (passphrase, numBytes) {
|
|||||||
isp = isp.substr(0, count);
|
isp = isp.substr(0, count);
|
||||||
|
|
||||||
return crypto.hash.digest(algorithm, prefix + isp);
|
return crypto.hash.digest(algorithm, prefix + isp);
|
||||||
|
|
||||||
|
case 'gnu':
|
||||||
|
throw new Error("GNU s2k type not supported.");
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown s2k type.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16655,8 +16664,8 @@ AsyncProxy.prototype.decryptKey = function(privateKey, password) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.tasks.push({ resolve:function(data) {
|
self.tasks.push({ resolve:function(data) {
|
||||||
var packetlist = packet.List.fromStructuredClone(data);
|
var packetlist = packet.List.fromStructuredClone(data),
|
||||||
data = new key.Key(packetlist);
|
data = new key.Key(packetlist);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
}, reject:reject });
|
}, reject:reject });
|
||||||
});
|
});
|
||||||
@@ -16683,8 +16692,8 @@ AsyncProxy.prototype.decryptKeyPacket = function(privateKey, keyIds, password) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.tasks.push({ resolve:function(data) {
|
self.tasks.push({ resolve:function(data) {
|
||||||
var packetlist = packet.List.fromStructuredClone(data);
|
var packetlist = packet.List.fromStructuredClone(data),
|
||||||
data = new key.Key(packetlist);
|
data = new key.Key(packetlist);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
}, reject:reject });
|
}, reject:reject });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,193 @@
|
|||||||
|
;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||||
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3.0 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
window = {}; // to make UMD bundles work
|
||||||
|
|
||||||
|
// Mozilla bind polyfill because phantomjs is stupid
|
||||||
|
if (!Function.prototype.bind) {
|
||||||
|
Function.prototype.bind = function(oThis) {
|
||||||
|
if (typeof this !== "function") {
|
||||||
|
// closest thing possible to the ECMAScript 5 internal IsCallable function
|
||||||
|
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
|
||||||
|
}
|
||||||
|
|
||||||
|
var aArgs = Array.prototype.slice.call(arguments, 1),
|
||||||
|
fToBind = this,
|
||||||
|
FNOP = function() {},
|
||||||
|
fBound = function() {
|
||||||
|
return fToBind.apply(this instanceof FNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
|
||||||
|
};
|
||||||
|
|
||||||
|
FNOP.prototype = this.prototype;
|
||||||
|
fBound.prototype = new FNOP();
|
||||||
|
|
||||||
|
return fBound;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
importScripts('openpgp.js');
|
||||||
|
|
||||||
|
var MIN_SIZE_RANDOM_BUFFER = 40000;
|
||||||
|
var MAX_SIZE_RANDOM_BUFFER = 60000;
|
||||||
|
|
||||||
|
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
||||||
|
|
||||||
|
self.onmessage = function (event) {
|
||||||
|
var data = null,
|
||||||
|
err = null,
|
||||||
|
msg = event.data,
|
||||||
|
correct = false;
|
||||||
|
|
||||||
|
switch (msg.event) {
|
||||||
|
case 'configure':
|
||||||
|
for (var i in msg.config) {
|
||||||
|
window.openpgp.config[i] = msg.config[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'seed-random':
|
||||||
|
if (!(msg.buf instanceof Uint8Array)) {
|
||||||
|
msg.buf = new Uint8Array(msg.buf);
|
||||||
|
}
|
||||||
|
window.openpgp.crypto.random.randomBuffer.set(msg.buf);
|
||||||
|
break;
|
||||||
|
case 'encrypt-message':
|
||||||
|
if (!msg.keys.length) {
|
||||||
|
msg.keys = [msg.keys];
|
||||||
|
}
|
||||||
|
msg.keys = msg.keys.map(packetlistCloneToKey);
|
||||||
|
window.openpgp.encryptMessage(msg.keys, msg.text).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'sign-and-encrypt-message':
|
||||||
|
if (!msg.publicKeys.length) {
|
||||||
|
msg.publicKeys = [msg.publicKeys];
|
||||||
|
}
|
||||||
|
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||||
|
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||||
|
window.openpgp.signAndEncryptMessage(msg.publicKeys, msg.privateKey, msg.text).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'decrypt-message':
|
||||||
|
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||||
|
msg.message = packetlistCloneToMessage(msg.message.packets);
|
||||||
|
window.openpgp.decryptMessage(msg.privateKey, msg.message).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'decrypt-and-verify-message':
|
||||||
|
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||||
|
if (!msg.publicKeys.length) {
|
||||||
|
msg.publicKeys = [msg.publicKeys];
|
||||||
|
}
|
||||||
|
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||||
|
msg.message = packetlistCloneToMessage(msg.message.packets);
|
||||||
|
window.openpgp.decryptAndVerifyMessage(msg.privateKey, msg.publicKeys, msg.message).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'sign-clear-message':
|
||||||
|
msg.privateKeys = msg.privateKeys.map(packetlistCloneToKey);
|
||||||
|
window.openpgp.signClearMessage(msg.privateKeys, msg.text).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'verify-clear-signed-message':
|
||||||
|
if (!msg.publicKeys.length) {
|
||||||
|
msg.publicKeys = [msg.publicKeys];
|
||||||
|
}
|
||||||
|
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||||
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
|
||||||
|
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
|
||||||
|
window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message).then(function(data) {
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'generate-key-pair':
|
||||||
|
window.openpgp.generateKeyPair(msg.options).then(function(data) {
|
||||||
|
data.key = data.key.toPacketlist();
|
||||||
|
response({event: 'method-return', data: data});
|
||||||
|
}).catch(function(e) {
|
||||||
|
response({event: 'method-return', err: e.message});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'decrypt-key':
|
||||||
|
try {
|
||||||
|
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||||
|
correct = msg.privateKey.decrypt(msg.password);
|
||||||
|
if (correct) {
|
||||||
|
data = msg.privateKey.toPacketlist();
|
||||||
|
} else {
|
||||||
|
err = 'Wrong password';
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
err = e.message;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
break;
|
||||||
|
case 'decrypt-key-packet':
|
||||||
|
try {
|
||||||
|
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||||
|
msg.keyIds = msg.keyIds.map(window.openpgp.Keyid.fromClone);
|
||||||
|
correct = msg.privateKey.decryptKeyPacket(msg.keyIds, msg.password);
|
||||||
|
if (correct) {
|
||||||
|
data = msg.privateKey.toPacketlist();
|
||||||
|
} else {
|
||||||
|
err = 'Wrong password';
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
err = e.message;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown Worker Event.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function response(event) {
|
||||||
|
if (window.openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
|
||||||
|
postMessage({event: 'request-seed'});
|
||||||
|
}
|
||||||
|
postMessage(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function packetlistCloneToKey(packetlistClone) {
|
||||||
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||||
|
return new window.openpgp.key.Key(packetlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
function packetlistCloneToMessage(packetlistClone) {
|
||||||
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||||
|
return new window.openpgp.message.Message(packetlist);
|
||||||
|
}
|
||||||
|
},{}]},{},[1])
|
||||||
|
;
|
||||||
@@ -117,11 +117,10 @@ function success(text) {
|
|||||||
@param msg The success message text */
|
@param msg The success message text */
|
||||||
function status(id, msg) {
|
function status(id, msg) {
|
||||||
console.log("state: "+id);
|
console.log("state: "+id);
|
||||||
if (msg) success(msg); else $("#status").fadeOut('slow');
|
if (msg) success(msg); else $("#status").hide();
|
||||||
$("#main").children(":not(#"+id+")").hide();
|
$("#main").children(":not(#"+id+")").hide();
|
||||||
$("#main #"+id).fadeIn("slow", function() {
|
$("#main #"+id).show();
|
||||||
$("#main #"+id+" form input:first-child").focus();
|
$("#main #"+id+" form input:first-child").focus();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function emit(signal, data) {
|
function emit(signal, data) {
|
||||||
@@ -147,10 +146,18 @@ function connectionstatus() {
|
|||||||
if (socket.connected) connected(); else disconnected();
|
if (socket.connected) connected(); else disconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function htmlenc(html) {
|
||||||
|
return $('<div/>').text(html).html();
|
||||||
|
}
|
||||||
|
|
||||||
|
function htmldec(data) {
|
||||||
|
return $('<div/>').html(data).text();
|
||||||
|
}
|
||||||
|
|
||||||
/// Alert user
|
/// Alert user
|
||||||
/** Alert user, e.g. that a new message has arrived. */
|
/** Alert user, e.g. that a new message has arrived. */
|
||||||
function beep(user) {
|
function beep(user) {
|
||||||
success("message from "+user+" received");
|
if (user) success("message from "+htmlenc(user)+" received");
|
||||||
navigator.vibrate =
|
navigator.vibrate =
|
||||||
navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
|
navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
|
||||||
if (navigator.vibrate) {
|
if (navigator.vibrate) {
|
||||||
@@ -313,9 +320,11 @@ function userid() {
|
|||||||
/// Clear Message Text And Attachments
|
/// Clear Message Text And Attachments
|
||||||
/** Does not remove the receiver's name */
|
/** Does not remove the receiver's name */
|
||||||
function clearmessage() {
|
function clearmessage() {
|
||||||
|
$("#message").prop(":disabled", true);
|
||||||
filecontent = new Array();
|
filecontent = new Array();
|
||||||
$('#preview').empty();
|
$('#preview').empty();
|
||||||
$("#msg").val("");
|
$("#msg").val("");
|
||||||
|
$("#message").prop(":disabled", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display Image Attachments
|
/// Display Image Attachments
|
||||||
@@ -392,8 +401,11 @@ var userMap = null;
|
|||||||
function users(userlist) {
|
function users(userlist) {
|
||||||
console.log("rcv-> users");
|
console.log("rcv-> users");
|
||||||
userMap = new Array();
|
userMap = new Array();
|
||||||
|
$("#allusers").empty();
|
||||||
userlist.forEach(function(usr) {
|
userlist.forEach(function(usr) {
|
||||||
userMap[usr.name] = usr.pubkey;
|
userMap[usr.name] = usr.pubkey;
|
||||||
|
$("#allusers").append('<option value="'+htmlenc(usr.name)+'">')
|
||||||
|
$("#allusers").hide();
|
||||||
console.log(" user: "+usr.name);
|
console.log(" user: "+usr.name);
|
||||||
});
|
});
|
||||||
localStorage.userMap = JSON.stringify(userMap);
|
localStorage.userMap = JSON.stringify(userMap);
|
||||||
@@ -440,6 +452,7 @@ function user(usr) {
|
|||||||
}
|
}
|
||||||
if (usr.exists && usr.pubkey && userMap[usr.name] != usr.pubkey) {
|
if (usr.exists && usr.pubkey && userMap[usr.name] != usr.pubkey) {
|
||||||
userMap[usr.name] = usr.pubkey;
|
userMap[usr.name] = usr.pubkey;
|
||||||
|
$("#allusers").append('option value="'+htmlenc(usr.name)+'"')
|
||||||
localStorage.userMap = JSON.stringify(userMap);
|
localStorage.userMap = JSON.stringify(userMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,13 +467,13 @@ function getPublicKey(user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Received a list of messages from server
|
/// Received a list of messages from server
|
||||||
function messages(ms) {
|
function messages(msgs) {
|
||||||
console.log("rcv-> messages");
|
console.log("rcv-> messages("+msgs.length+")");
|
||||||
|
if (!password || !privateKey())
|
||||||
|
return setTimeout(function() {emit("messages");}, 1000); // try again later
|
||||||
|
status("allmessages");
|
||||||
notice("load messages, please wait …");
|
notice("load messages, please wait …");
|
||||||
ms.forEach(function(msg) {
|
msgs.forEach(function(msg) {message(msg, false);});
|
||||||
message(msg, false);
|
|
||||||
});
|
|
||||||
success("ready");
|
|
||||||
status("chat");
|
status("chat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,12 +522,12 @@ function message(m, signaling=true) {
|
|||||||
the receiver's public key, then send it to the server. */
|
the receiver's public key, then send it to the server. */
|
||||||
function sendmessage(recv, txt) {
|
function sendmessage(recv, txt) {
|
||||||
notice("1/3 preparing message …");
|
notice("1/3 preparing message …");
|
||||||
$("#message").fadeOut("slow");
|
$("#message").prop(":disabled", true);
|
||||||
getPublicKey(recv) // get receiver's public key
|
getPublicKey(recv) // get receiver's public key
|
||||||
.done(function(pk) {
|
.done(function(pk) {
|
||||||
var key=openpgp.key.readArmored(pk);
|
var key=openpgp.key.readArmored(pk);
|
||||||
if (!pk||key.err) {
|
if (!pk||key.err) {
|
||||||
$("#message").fadeIn("slow");
|
$("#message").prop(":disabled", false);
|
||||||
error("receiver's key not found", true);
|
error("receiver's key not found", true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -529,15 +542,14 @@ function sendmessage(recv, txt) {
|
|||||||
clearmessage();
|
clearmessage();
|
||||||
})
|
})
|
||||||
.catch(function(e) {
|
.catch(function(e) {
|
||||||
$("#message").fadeIn("slow");
|
$("#message").prop(":disabled", false);
|
||||||
error("encryption of message failed", true);
|
error("encryption of message failed", true);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.fail(function(e) {
|
.fail(function(e) {
|
||||||
$("#message").fadeIn("slow");
|
$("#message").prop(":disabled", false);
|
||||||
error("user not found", true);
|
error("user not found", true);
|
||||||
});
|
});
|
||||||
$("#message").fadeIn("slow");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check And Set Password
|
/// Check And Set Password
|
||||||
@@ -583,12 +595,15 @@ function removeKey() {
|
|||||||
/// Main Chat Window
|
/// Main Chat Window
|
||||||
/** Gets chat widgets from server and displays them. Starts timer for
|
/** Gets chat widgets from server and displays them. Starts timer for
|
||||||
get() which polls for new messages. */
|
get() which polls for new messages. */
|
||||||
|
var firsttime = true;
|
||||||
function chat() {
|
function chat() {
|
||||||
if (!password) return getpwd();
|
if (!password) return getpwd();
|
||||||
if ($('#msgs').is(':empty'))
|
status("chat");
|
||||||
|
if (firsttime && $('#msgs').is(':empty')) {
|
||||||
|
firsttime = false;
|
||||||
|
notice("getting previous messages, please wait …");
|
||||||
emit("messages");
|
emit("messages");
|
||||||
else
|
}
|
||||||
status("chat");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Login User
|
/// Login User
|
||||||
@@ -670,6 +685,10 @@ function init() {
|
|||||||
socket.on("message", message);
|
socket.on("message", message);
|
||||||
socket.on("messages", messages);
|
socket.on("messages", messages);
|
||||||
connectionstatus();
|
connectionstatus();
|
||||||
|
if (openpgp.initWorker("javascripts/openpgp.worker.js"))
|
||||||
|
console.log("asynchronous openpgp enabled");
|
||||||
|
else
|
||||||
|
console.log("asynchronous openpgp failed");
|
||||||
emit('users');
|
emit('users');
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,6 +188,11 @@ td:last-child {
|
|||||||
.clear {
|
.clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
:disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: alpha(opacity=40); /* MSIE */
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
label[for=send] img {
|
label[for=send] img {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
filter: alpha(opacity=40); /* MSIE */
|
filter: alpha(opacity=40); /* MSIE */
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ module.exports = function(sql) {
|
|||||||
|
|
||||||
socket.on("messages", function(msg) {
|
socket.on("messages", function(msg) {
|
||||||
console.log("-> signal: messages");
|
console.log("-> signal: messages");
|
||||||
sql.query("select * from message, user where message.user = user.name", [],
|
sql.query("select * from message, user where message.user = user.name order by message.id", [],
|
||||||
function(err, res, flds) {
|
function(err, res, flds) {
|
||||||
emit('messages', res);
|
emit('messages', res);
|
||||||
});
|
});
|
||||||
|
|||||||
+10
-1
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
||||||
|
<!-- Register New User -->
|
||||||
<div id="newuser" style="display: none">
|
<div id="newuser" style="display: none">
|
||||||
<h2>Register User</h2>
|
<h2>Register User</h2>
|
||||||
<p>All you need to start is a username and a password:</p>
|
<p>All you need to start is a username and a password:</p>
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
up your keys.</p>
|
up your keys.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Enter Password -->
|
||||||
<div id="getpwd" style="display: none">
|
<div id="getpwd" style="display: none">
|
||||||
<form>
|
<form>
|
||||||
<input placeholder="please enter password" id="pwd" oninput="setpw(this.value)"
|
<input placeholder="please enter password" id="pwd" oninput="setpw(this.value)"
|
||||||
@@ -106,10 +108,12 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Chat Screen -->
|
||||||
<div id="chat" style="display: none">
|
<div id="chat" style="display: none">
|
||||||
<div id="message">
|
<div id="message">
|
||||||
<form id="chat" autocomplete="off" onsubmit="sendmessage(this.elements['recv'].value, this.elements['msg'].value)">
|
<form id="chat" autocomplete="off" onsubmit="sendmessage(this.elements['recv'].value, this.elements['msg'].value)">
|
||||||
<input placeholder="receiver" autocomplete="off" type="text" id="recv" oninput="checkpartner(this.value)" />
|
<input placeholder="receiver" autocomplete="off" type="text" list="allusers" id="recv" oninput="checkpartner(this.value)" />
|
||||||
|
<datalist id="allusers"></datalist>
|
||||||
<input placeholder="message" autocomplete="off" type="text" id="msg"/>
|
<input placeholder="message" autocomplete="off" type="text" id="msg"/>
|
||||||
<div class="buttongroup">
|
<div class="buttongroup">
|
||||||
<span class="toolbutton">
|
<span class="toolbutton">
|
||||||
@@ -149,6 +153,7 @@
|
|||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Password Forgotten -->
|
||||||
<div id="forgotpassword" style="display: none">
|
<div id="forgotpassword" style="display: none">
|
||||||
<h2>Password Forgotten</h2>
|
<h2>Password Forgotten</h2>
|
||||||
<div class="warning"><strong>Warning!</strong>
|
<div class="warning"><strong>Warning!</strong>
|
||||||
@@ -174,6 +179,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Error: Missing JavaScript -->
|
||||||
<noscript>
|
<noscript>
|
||||||
<h2>JavasScript Required!</h2>
|
<h2>JavasScript Required!</h2>
|
||||||
<p>This is a secure and encryptet chat application, that runs
|
<p>This is a secure and encryptet chat application, that runs
|
||||||
@@ -184,15 +190,18 @@
|
|||||||
<p><a href="<%= projecturl %>" target="_blank">more information</a></p>
|
<p><a href="<%= projecturl %>" target="_blank">more information</a></p>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
|
<!-- Error: Missing LocalStorage -->
|
||||||
<div id="nolocalstorage" style="display: none">
|
<div id="nolocalstorage" style="display: none">
|
||||||
<p>No access to local storage. Please allow access to local
|
<p>No access to local storage. Please allow access to local
|
||||||
storage, i.e. do not block cookies.<p>
|
storage, i.e. do not block cookies.<p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Notice: Setup Messages -->
|
||||||
<div id="allmessages" style="display: none">
|
<div id="allmessages" style="display: none">
|
||||||
<p>Setting up all previous messages, please wait …</p>
|
<p>Setting up all previous messages, please wait …</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Notice: Startup -->
|
||||||
<div id="startup">
|
<div id="startup">
|
||||||
<p>Starting up …</p>
|
<p>Starting up …</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user