logging for tests

master
Marc Wäckerlin 7 years ago
parent 693ecbefe5
commit 34a9bf3eb3
  1. 178
      nodejs/public/javascripts/safechat.js
  2. 1
      nodejs/sockets/index.js
  3. 2
      nodejs/views/index.ejs

@ -37,6 +37,11 @@
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
function log() {
//[].push.call(arguments, (new Error()).stack)
console.log.apply(null, arguments)
}
function SafeChat() {
/// Create UID from a name by appending an E-Mail
@ -105,9 +110,9 @@ function SafeChat() {
//------------------------------------------------------------------------------
if (openpgp.initWorker("openpgp.worker.min.js"))
console.log("asynchronous openpgp enabled")
log("asynchronous openpgp enabled")
else
console.log("asynchronous openpgp failed")
log("asynchronous openpgp failed")
}
@ -156,16 +161,19 @@ function SafeChat() {
var socket = io.connect()
function broadcast(signal, data) {
console.log("<=snd "+signal)
log(' function broadcast(signal, data)')
log("<=snd "+signal)
socket.broadcast.emit(signal, data)
}
function emit(signal, data, next) {
console.log("<-snd "+signal)
log(' function emit(signal, data, next)')
log("<-snd "+signal)
socket.emit(signal, data, next)
}
this.lookup = function(usr, next) {
log(' this.lookup = function(usr, next)')
emit('user', usr, next)
}
@ -198,22 +206,26 @@ function SafeChat() {
/// Padding for numbers in dates
function pad(n) {
log(' function pad(n)')
return n<10 ? '0'+n : n
}
/// escape text to show in html @see htmldec
function htmlenc(html) {
log(' function htmlenc(html)')
return $('<div/>').text(html).html()
}
/// decode html encoded text @see htmlenc
function htmldec(data) {
log(' function htmldec(data)')
return $('<div/>').html(data).text()
}
/// alert user accoustically or by vibration
/** alert user, e.g. that a new message has arrived. */
function beep() {
log(' function beep()')
if (navigator.vibrate) navigator.vibrate(1000)
(new Audio("sounds/beep.mp3")).play()
}
@ -222,6 +234,7 @@ function SafeChat() {
/** something completely failed, abort
@param msg */
function fatal(msg) {
log(' function fatal(msg)')
if (nexttimer) clearTimeout(nexttimer)
if (msg) {
error(msg)
@ -236,6 +249,7 @@ function SafeChat() {
Strings are shown to the user, structures are logged only.
@param next (optional) next function to call */
function error(data, next) {
log(' function error(data, next)')
if (nexttimer) clearTimeout(nexttimer)
$("#status").hide()
$("#status").addClass("error")
@ -244,14 +258,14 @@ function SafeChat() {
if (data) {
if (typeof data == 'string') {
$("#status").html(data)
console.log("error: "+data)
log("error: "+data)
} else {
$("#status").html('error')
console.log("error: "+JSON.stringify(data))
log("error: "+JSON.stringify(data))
}
} else {
$("#status").html('error')
console.log("error")
log("error")
}
$("#status").show()
if (next) nexttimer = setTimeout(function() {
@ -264,16 +278,17 @@ function SafeChat() {
/** shows an notice message and logs to console.
@param text (optional) The data is a string. */
function notice(text) {
log(' function notice(text)')
$("#status").hide()
$("#status").addClass("notice")
$("#status").removeClass("error")
$("#status").removeClass("success")
if (text) {
$("#status").html(text)
console.log("notice: "+text)
log("notice: "+text)
} else {
$("#status").html('')
console.log("notice")
log("notice")
}
$("#status").show()
}
@ -282,16 +297,17 @@ function SafeChat() {
/** shows an success message and logs to console.
@param text (optional) The data is a string. */
function success(text) {
log(' function success(text)')
$("#status").hide()
$("#status").addClass("success")
$("#status").removeClass("error")
$("#status").removeClass("notice")
if (text) {
$("#status").html(text)
console.log("success: "+text)
log("success: "+text)
} else {
$("#status").html('')
console.log("success")
log("success")
}
$("#status").show()
}
@ -300,7 +316,8 @@ function SafeChat() {
/** @param id html id to be shown.
@param msg (optional) the success message text */
function show(id, msg) {
console.log("state: "+id)
log(' function show(id, msg)')
log("state: "+id)
if (msg) success(msg); else $("#status").hide();
$("#main").children(":not(#"+id+")").hide()
$("#main #"+id).show()
@ -309,7 +326,8 @@ function SafeChat() {
/// show server connected status
function connected() {
console.log("server connected")
log(' function connected()')
log("server connected")
$("#connectionstatus #bad").hide()
$("#connectionstatus #good").show()
success("server connected")
@ -317,18 +335,21 @@ function SafeChat() {
/// show server disconnected status
function disconnected() {
console.log("server disconnected")
log(' function disconnected()')
log("server disconnected")
$("#connectionstatus #good").hide()
$("#connectionstatus #bad").show()
error("server disconnected", true)
}
/// toggle menu display
function togglemenu() {
this.togglemenu = function() {
log(' function togglemenu()')
$("#menu").toggle()
}
function checkFeature(id, query) {
log(' function checkFeature(id, query)')
if (query) $('#'+id)
.css('color', 'green')
.prepend('<span>&#x2714;</span>')
@ -338,6 +359,7 @@ function SafeChat() {
}
this.checkFeatures = function() {
log(' this.checkFeatures = function()')
$('ul.features').css('list-style-type', 'none')
checkFeature("localstorage", Storage)
checkFeature("indexeddb", window.indexedDB)
@ -350,6 +372,7 @@ function SafeChat() {
/// @{
this.newuser = function() {
log(' this.newuser = function()')
show('newuser')
}
@ -357,12 +380,14 @@ function SafeChat() {
var pwd = false
function invalid(usr) {
log(' function invalid(usr)')
return !user || !user.exists && user.name.length<3
}
this.available = function(usr) {
log(' this.available = function(usr)')
user = usr
console.log("props:", invalid(user) || !pwd)
log("props:", invalid(user) || !pwd)
$("#createuser").prop(":disabled", invalid(user) || !pwd)
if (user.length==0)
notice("please chose a user name")
@ -377,8 +402,10 @@ function SafeChat() {
}
this.passwords = function(pwd1, pwd2) {
log(' this.passwords = function(pwd1, pwd2)')
return
pwd = pwd1==pwd2 && pwd1.length>5
console.log("props:", invalid(user) || !pwd)
log("props:", invalid(user) || !pwd)
$("#createuser").prop(":disabled", invalid(user) || !pwd)
if (pwd1.length==0)
notice('please chose a password')
@ -395,6 +422,7 @@ function SafeChat() {
/// @}
function DataTransfer() {
log(' function DataTransfer()')
var reboottimer = null
var data = new DataTransfer()
@ -419,6 +447,7 @@ function SafeChat() {
/// Upload Profile Backup
function restore(evt) {
log(' function restore(evt)')
for (var i=0, f; f=evt.target.files[i]; ++i) {
var file = f
var reader = new FileReader()
@ -431,7 +460,7 @@ function SafeChat() {
localStorage.pubkey = parsed.pubkey
localStorage.privkey = parsed.privkey
success("backup is restored")
console.log("reboot after restore in 2s")
log("reboot after restore in 2s")
if (!reboottimer && reboot) reboottimer = setTimeout(function() {
reboottimer = null
}, 2000)
@ -452,6 +481,7 @@ function SafeChat() {
//==============================================================================
/// @class Controller defines the programm flow
function Controller(view) {
log(' function Controller(view)')
var db = new DataBase()
var crypto = new Crypto(this)
@ -468,35 +498,48 @@ function SafeChat() {
/// @}
/// @name access to view
/// @{
this.togglemenu = view.togglemenu
/// @}
/// @name signals from server
/// @{
function fail(msg) {
console.log('rcv-> fail('+msg+')')
log(' function fail(msg)')
log('rcv-> fail('+msg+')')
error(msg)
}
function loggedin() {
console.log("rcv-> login")
log(' function loggedin()')
log("rcv-> login")
success("login successful")
chat()
}
function user(usr) {
console.log("rcv-> user")
log(' function user(usr)')
log("rcv-> user")
if (usr.exits) users.add(usr)
}
function users() {
console.log("rcv-> users")
log(' function users()')
log("rcv-> users")
}
function message(msg) {
console.log("rcv-> message")
log(' function message(msg)')
log("rcv-> message")
}
function messages(msgs) {
console.log("rcv-> messages")
log(' function messages(msgs)')
log("rcv-> messages")
}
this.connected = view.connected
@ -513,6 +556,8 @@ function SafeChat() {
/// @{
this.lookup = function(usr) {
log(' this.lookup = function(usr)')
return
if (usr.length > 2) communication.lookup(uid(usr), function(res) {
view.available(res)
})
@ -521,6 +566,7 @@ function SafeChat() {
this.checkpasswords = view.passwords
this.createuser = function(name, pwd) {
log(' this.createuser = function(name, pwd)')
crypto.createuser(name, name+'@'+hostname, pwd).then(function() {
if (!crypto.password(pwd))
fatal("private key decryption failed")
@ -534,38 +580,52 @@ function SafeChat() {
/// @}
function initBrowser() {
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
log(' function initBrowser()')
log('A')
//window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
log('B')
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction
log('C')
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
log('D')
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate
log('E')
log(' end of function initBrowser()')
return window.indexedDB && window.crypto.getRandomValues && Storage
}
var newuser = view.newuser
function chat() {
log(' function chat()')
}
function password() {
log(' function password()')
}
function login() {
log(' function login()')
if (!crypto.key()) newuser(); else password();
}
this.run = function() {
log(' this.run = function()')
login()
}
this.start = function() {
log(' this.start = function()')
view.reboot = this.run
var compatible = initBrowser()
view.checkFeatures()
if (!compatible)
if (!compatible) {
log('incompatible')
view.fatal("your browser is not supported")
else
} else {
log('incompatible')
this.run()
}
}
}
@ -582,12 +642,14 @@ var filecontent = new Array() ///< temporary storage for attachments
var reboottimer = null
function connectionstatus() {
log('function connectionstatus()')
if (socket.connected) connected(); else disconnected();
}
/// Configure local groups
/** … */
function groups() {
log('function groups()')
}
/// Check if password is set and matches the repeated password
@ -602,6 +664,7 @@ function groups() {
@param pwd The password.
@param pwd2 The repeated password. */
function checkpwd(pwd, pwd2) {
log('function checkpwd(pwd, pwd2)')
$("#register").submit(function(event) {
return false
})
@ -624,6 +687,7 @@ function checkpwd(pwd, pwd2) {
/** Calls checknewuser.php on server and enables the message submit
button if the receiver of the message exists on the server. */
function checkpartner(user) {
log('function checkpartner(user)')
$("#chat").submit(function(event) {
return false
})
@ -633,6 +697,7 @@ function checkpartner(user) {
/// Create Local Public-/Private-Key Pair
/** Called if user has not yet his keys, just generates a new key pair. */
function createkeypair(user, pwd) {
log('function createkeypair(user, pwd)')
notice("generating keys")
openpgp.generateKey({
numBits: 4096,
@ -644,7 +709,7 @@ function createkeypair(user, pwd) {
localStorage.privkey = keyPair.privateKeyArmored
login()
}).catch(function(e) {
console.log(e)
log(e)
error("generating key pairs failed")
})
}
@ -652,6 +717,7 @@ function createkeypair(user, pwd) {
/// Get Own Public Key
/** @return public key object */
function publicKey() {
log('function publicKey()')
if (typeof localStorage.pubkey == 'undefined') {
if (typeof localStorage.pubKey == 'undefined') {
return null
@ -666,6 +732,7 @@ function publicKey() {
/// Get Own Private Key
/** @return private key object */
function privateKey() {
log('function privateKey()')
if (typeof localStorage.privkey == 'undefined') {
if (typeof localStorage.privKey == 'undefined') {
return null
@ -680,6 +747,7 @@ function privateKey() {
/// Get Own User Name
/** Get user name as user id of first public key */
function userid() {
log('function userid()')
if (!publicKey() ||
publicKey().keys.length < 1 ||
publicKey().keys[0].getUserIds().length < 1) return null
@ -689,6 +757,7 @@ function userid() {
/// Clear Message Text And Attachments
/** Does not remove the receiver's name */
function clearmessage() {
log('function clearmessage()')
$("#message").prop(":disabled", true)
filecontent = new Array()
$('#preview').empty()
@ -697,6 +766,7 @@ function clearmessage() {
}
function guessfilename(mimetype, user, date) {
log('function guessfilename(mimetype, user, date)')
if (!user) user = userid()
if (!date) date = new Date()
var ext = mimetype.replace(/.*\/(x-)?/i, "")
@ -706,8 +776,9 @@ function guessfilename(mimetype, user, date) {
/// Display Image Attachments
function attachments(files, id, from, date) {
log('function attachments(files, id, from, date)')
if (files) files.forEach(function(file) {
console.log(file)
log(file)
if (!file.name) file.name = guessfilename(file.type, from, date)
var a = document.createElement('a')
a.href = file.content
@ -737,6 +808,7 @@ function attachments(files, id, from, date) {
var recorder
function done() {
log('function done()')
if (recorder) {
recorder.stop()
recorder.recording(function(data) {
@ -747,6 +819,7 @@ function done() {
}
function abort() {
log('function abort()')
if (recorder) {
$("#videorecorder").hide()
recorder.release()
@ -757,6 +830,7 @@ function abort() {
/// Record Video from builtin camera
function recordvideo() {
log('function recordvideo()')
try {
abort()
$("#videorecorder").show()
@ -776,12 +850,13 @@ function recordvideo() {
recorder.start()
})
} catch (e) {
console.log(e)
log(e)
error("cannot access camera", true)
}
}
function previewfile(content, type, name) {
log('function previewfile(content, type, name)')
if (!name) name = guessfilename(type)
if (type.match('^image/')) {
var img = document.createElement("img")
@ -836,6 +911,7 @@ function previewfile(content, type, name) {
Stores data in global variable @ref filecontent. */
function fileupload(evt) {
log('function fileupload(evt)')
if (!window.FileReader)
return error("your browser does not support file upload", true)
for (var i=0, f; f=evt.target.files[i]; ++i) {
@ -857,6 +933,7 @@ function fileupload(evt) {
@param name The receiver's name. */
function setreceiver(name) {
log('function setreceiver(name)')
$("#recv").val(name)
checkpartner(name)
$("#msg").focus()
@ -864,21 +941,23 @@ function setreceiver(name) {
var userMap = null
function users(userlist) {
console.log("rcv-> users")
log('function users(userlist)')
log("rcv-> users")
userMap = new Array()
$("#allusers").empty()
userlist.forEach(function(usr) {
userMap[usr.name] = usr.pubkey
$("#allusers").append('<option value="'+htmlenc(usr.name)+'">')
$("#allusers").hide()
console.log(" user: "+usr.name)
log(" user: "+usr.name)
})
localStorage.userMap = JSON.stringify(userMap)
}
function user(usr) {
if (usr.exists) console.log("rcv-> user("+usr.name+")")
else console.log("rcv-> user("+usr.name+"): name is available")
log('function user(usr)')
if (usr.exists) log("rcv-> user("+usr.name+")")
else log("rcv-> user("+usr.name+"): name is available")
if ($("#newuser").is(":visible") && usr.name==uid($('#user').val())) {
// same username as in the create user form
$("#createuser").prop("disabled", usr.exists) // todo: check password
@ -912,13 +991,15 @@ function user(usr) {
}
function queryuser(usr) {
console.log("query user: "+uid(usr))
log('function queryuser(usr)')
log("query user: "+uid(usr))
socket.emit("user", uid(usr))
}
/// Get a user's public key.
/** The first time, gets it from the server, later from the cache. */
function getPublicKey(user) {
log('function getPublicKey(user)')
var deferredObject = $.Deferred()
if (userMap && userMap[user]) deferredObject.resolve(userMap[user])
else deferredObject.reject("unknown user")
@ -927,7 +1008,8 @@ function getPublicKey(user) {
/// Received a list of messages from server
function messages(msgs) {
console.log("rcv-> messages("+msgs.length+")")
log('function messages(msgs)')
log("rcv-> messages("+msgs.length+")")
if (!password || !privateKey())
return setTimeout(function() {emit("messages")}, 1000) // try again later
show("allmessages")
@ -938,7 +1020,8 @@ function messages(msgs) {
/// Received a message from server
function message(m, internal) {
if (!internal) console.log("rcv-> message("+m.user+")")
log('function message(m, internal)')
if (!internal) log("rcv-> message("+m.user+")")
if (!password || !privateKey()) return
var key=openpgp.key.readArmored(m.pubkey)
if (key.err) return error("key of sender unreadable", true)
@ -990,6 +1073,7 @@ function message(m, internal) {
/** User wants to send a message. Encrypt message with own private and
the receiver's public key, then send it to the server. */
function sendmessage(recv, txt) {
log('function sendmessage(recv, txt)')
notice("1/3 preparing message …")
$("#message").prop(":disabled", true)
getPublicKey(recv) // get receiver's public key
@ -1031,6 +1115,8 @@ function sendmessage(recv, txt) {
@param pwd The password to check. */
function setpw(pwd) {
log('function setpw(pwd)')
return
if (privateKey().keys[0].decrypt(pwd)) {
success("password matches")
$("#removeKey").hide()
@ -1047,12 +1133,14 @@ function setpw(pwd) {
setpw() continues automatically. No submit is required by the
user. */
function getpwd() {
log('function getpwd()')
if (password) return
$("#removeKey").show()
show("getpwd")
}
function deleteUser() {
log('function deleteUser()')
var uid = userid()
localStorage.removeItem(pubkey)
localStorage.removeItem(privkey)
@ -1060,6 +1148,7 @@ function deleteUser() {
}
function removeKey() {
log('function removeKey()')
togglemenu()
$("#removeKey").hide()
show('forgotpassword')
@ -1070,6 +1159,7 @@ function removeKey() {
get() which polls for new messages. */
var firsttime = true
function chat() {
log('function chat()')
if (!password) return getpwd()
show("chat")
if (firsttime && $('#msgs').is(':empty')) {
@ -1091,6 +1181,7 @@ function chat() {
different, then this is a complete failure, something went
terribly wrong. */
function login() {
log('function login()')
$("#username").html(userid()+"@"+hostname)
emit("login", {name: userid(),
pubkey: localStorage.pubkey})
@ -1101,11 +1192,13 @@ function login() {
/** Shows user creation form. On submit, a private key is generated in
createkeypair(), then login() creates the user. */
function newuser() {
log('function newuser()')
show("newuser")
}
/// Check if local storage is available
function checkLocalStorage() {
log('function checkLocalStorage()')
var test = 'test'
try {
localStorage.setItem(test, test)
@ -1121,6 +1214,7 @@ function checkLocalStorage() {
/// Initial Function: Startup
/** Decide whether to login or to create a new user */
function start() {
log('function start()')
$("#menu").hide()
//show("startup")
if (checkLocalStorage())
@ -1131,7 +1225,7 @@ function start() {
login()
}
} catch (m) {
console.log(m.stack)
log(m.stack)
error(m)
}
}
@ -1139,10 +1233,12 @@ function start() {
var safechat = new SafeChat()
function init() {
log('function init()')
safechat.start()
}
function old() {
log('function old()')
/// On Load, Call @ref start
$(window.onbeforeunload = function() {
return "Are you sure you want to navigate away?"
@ -1155,9 +1251,9 @@ function old() {
}, false)
connectionstatus()
if (openpgp.initWorker("openpgp.worker.min.js"))
console.log("asynchronous openpgp enabled")
log("asynchronous openpgp enabled")
else
console.log("asynchronous openpgp failed")
log("asynchronous openpgp failed")
emit('users')
start()
}

@ -83,6 +83,7 @@ module.exports = function(sql) {
console.log("-> signal: user("+name+")");
var result = {name: name, exists: false, pubkey: null};
sql.query("select pubkey from user where name = ?", [name], function(err, res, flds) {
console.log('user in db', err, res, flds)
if (!err && res && res.length) {
result.exists = true;
result.pubkey = res[0].pubkey;

@ -24,7 +24,7 @@
<span id="good" title="connected" style="display: none">&#x2714;</span>
<span id="bad" title="disconnected">&#x2718;</span>
</span>
<img id="menuicon" onclick="togglemenu()" src="images/menu.svg" />
<img id="menuicon" onclick="safechat.togglemenu()" src="images/menu.svg" />
</div>
</div>

Loading…
Cancel
Save