diff --git a/nodejs/public/javascripts/safechat.js b/nodejs/public/javascripts/safechat.js index db17ee3..001d8ed 100644 --- a/nodejs/public/javascripts/safechat.js +++ b/nodejs/public/javascripts/safechat.js @@ -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 $('
').text(html).html() } /// decode html encoded text @see htmlenc function htmldec(data) { + log(' function htmldec(data)') return $('').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('✔') @@ -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('