about to be able to create user
This commit is contained in:
@@ -41,9 +41,15 @@ function SafeChat() {
|
||||
|
||||
/// Create UID from a name by appending an E-Mail
|
||||
function uid(name) {
|
||||
return name+' <'+name+'@'+hostname+'>'
|
||||
return name+' <'+mail(name)+'>'
|
||||
}
|
||||
|
||||
function mail(name) {
|
||||
var hostname = window.location.hostname!='localhost'?window.location.hostname:'safechat.ch'
|
||||
return name+'@'+hostname
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// @class Crypto cryptographic functions
|
||||
/** @param view is of class SafeChat.View */
|
||||
function Crypto(controller) {
|
||||
@@ -51,42 +57,23 @@ function SafeChat() {
|
||||
/// cache client's key from local strorage
|
||||
var k = null
|
||||
|
||||
/// detect hosstname, default to safechat.ch
|
||||
var hostname = window.location.hostname!='localhost'?window.location.hostname:'safechat.ch'
|
||||
|
||||
/// detect hostname, default to safechat.ch
|
||||
/// get user key
|
||||
/** @internal key ist cached in k
|
||||
@return key */
|
||||
function key() {
|
||||
if (k) return k
|
||||
if (typeof localStorage.key == 'undefined') return null
|
||||
return k = openpgp.key.readArmored(localStorage.key)
|
||||
this.key = function() {
|
||||
if (k) return k // cached key
|
||||
if (typeof localStorage.privkey === 'undefined') return null
|
||||
return k = openpgp.key.readArmored(localStorage.privkey)
|
||||
}
|
||||
|
||||
/// get own user name
|
||||
/** get user name as user id of first public key */
|
||||
function user() {
|
||||
this.user = function() {
|
||||
if (k || key()) return k.pub.keys[0].getUserIds()[0]
|
||||
return null
|
||||
}
|
||||
|
||||
/// create New User
|
||||
function createuser(user, email, pwd) {
|
||||
controller.notice("generating keys")
|
||||
openpgp.generateKey({
|
||||
numBits: 4096,
|
||||
userIds: [{name: user, email: email}],
|
||||
passphrase: pwd
|
||||
}).then(function(keyPair) {
|
||||
controller.success("keys generated")
|
||||
localStorage.key = keyPair.privateKeyArmored
|
||||
k = keyPair.key
|
||||
}).catch(function(e) {
|
||||
console.log(e)
|
||||
controller.fatal("generating key pairs failed")
|
||||
})
|
||||
}
|
||||
|
||||
/// open private key with password
|
||||
/** @return @c true if password matches */
|
||||
function password(pwd) {
|
||||
@@ -116,8 +103,15 @@ function SafeChat() {
|
||||
return true
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
if (openpgp.initWorker("openpgp.worker.min.js"))
|
||||
console.log("asynchronous openpgp enabled")
|
||||
else
|
||||
console.log("asynchronous openpgp failed")
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// database that stores in indexed db
|
||||
function DataBase() {
|
||||
|
||||
@@ -126,6 +120,7 @@ function SafeChat() {
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// manage local copy of users
|
||||
function Users() {
|
||||
|
||||
@@ -142,6 +137,7 @@ function SafeChat() {
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// manage local copy of messages
|
||||
function Messages() {
|
||||
|
||||
@@ -152,6 +148,7 @@ function SafeChat() {
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// @class Communication client socket communication
|
||||
/** @param view is of class SafeChat.View */
|
||||
function Communication(controller) {
|
||||
@@ -163,9 +160,13 @@ function SafeChat() {
|
||||
socket.broadcast.emit(signal, data)
|
||||
}
|
||||
|
||||
function emit(signal, data) {
|
||||
function emit(signal, data, next) {
|
||||
console.log("<-snd "+signal)
|
||||
socket.emit(signal, data)
|
||||
socket.emit(signal, data, next)
|
||||
}
|
||||
|
||||
this.lookup = function(usr, next) {
|
||||
emit('user', usr, next)
|
||||
}
|
||||
|
||||
socket
|
||||
@@ -183,6 +184,7 @@ function SafeChat() {
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// @class View provides the glue to the GUI in the index.ejs file
|
||||
/** View provides the following callbacks:
|
||||
- status updates:
|
||||
@@ -299,7 +301,7 @@ function SafeChat() {
|
||||
@param msg (optional) the success message text */
|
||||
function show(id, msg) {
|
||||
console.log("state: "+id)
|
||||
if (msg) success(msg) else $("#status").hide()
|
||||
if (msg) success(msg); else $("#status").hide();
|
||||
$("#main").children(":not(#"+id+")").hide()
|
||||
$("#main #"+id).show()
|
||||
$("#main #"+id+" form input:first-child").focus()
|
||||
@@ -327,21 +329,15 @@ function SafeChat() {
|
||||
}
|
||||
|
||||
function checkFeature(id, query) {
|
||||
if (query) $('#'+id+':before')
|
||||
.css('color', 'green')
|
||||
.css('content', '✔')
|
||||
else $('#'+id+':before')
|
||||
.css('color', 'red')
|
||||
.css('content', '✘')
|
||||
if (query) $('#'+id)
|
||||
.css('color', 'green')
|
||||
.css('text-decoration', 'line-through')
|
||||
.prepend('<span>✔</span>')
|
||||
else $('#'+id)
|
||||
.css('color', 'red')
|
||||
.css('text-decoration', 'none')
|
||||
.prepend('<span>✘</span>')
|
||||
}
|
||||
|
||||
function checkFeatures() {
|
||||
this.checkFeatures = function() {
|
||||
$('ul.features').css('list-style-type', 'none')
|
||||
checkFeature("localstorage", Storage)
|
||||
checkFeature("indexeddb", window.indexedDB)
|
||||
@@ -350,6 +346,54 @@ function SafeChat() {
|
||||
checkFeature("filereader", window.FileReader)
|
||||
}
|
||||
|
||||
/// @name create new user
|
||||
/// @{
|
||||
|
||||
this.newuser = function() {
|
||||
show('newuser')
|
||||
}
|
||||
|
||||
var user = null
|
||||
var pwd = false
|
||||
|
||||
function invalid(usr) {
|
||||
return !user || !user.exists && user.name.length<3
|
||||
}
|
||||
|
||||
this.available = function(usr) {
|
||||
user = usr
|
||||
console.log("props:", invalid(user) || !pwd)
|
||||
$("#createuser").prop(":disabled", invalid(user) || !pwd)
|
||||
if (user.length==0)
|
||||
notice("please chose a user name")
|
||||
else if (user.length<3)
|
||||
notice("please chose a longer user name")
|
||||
else if (user.exists)
|
||||
notice("user name is already in use")
|
||||
else if (!pwd)
|
||||
notice("please chose a password")
|
||||
else
|
||||
success("user is ready to be created")
|
||||
}
|
||||
|
||||
this.passwords = function(pwd1, pwd2) {
|
||||
pwd = pwd1==pwd2 && pwd1.length>5
|
||||
console.log("props:", invalid(user) || !pwd)
|
||||
$("#createuser").prop(":disabled", invalid(user) || !pwd)
|
||||
if (pwd1.length==0)
|
||||
notice('please chose a password')
|
||||
else if (pwd1.length<6)
|
||||
notice('please chose a longer password')
|
||||
else if (pwd1 != pwd2)
|
||||
notice("passwords don't match")
|
||||
else if (invalid(user))
|
||||
notice("please chose a user name")
|
||||
else
|
||||
success("user is ready to be created")
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
function DataTransfer() {
|
||||
|
||||
var reboottimer = null
|
||||
@@ -405,10 +449,11 @@ function SafeChat() {
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/// @class Controller defines the programm flow
|
||||
function Controller(view) {
|
||||
|
||||
var db = new Database()
|
||||
var db = new DataBase()
|
||||
var crypto = new Crypto(this)
|
||||
var communication = new Communication(this)
|
||||
var users = new Users()
|
||||
@@ -461,6 +506,33 @@ function SafeChat() {
|
||||
|
||||
// @}
|
||||
|
||||
/// @name signals from view
|
||||
/// @{
|
||||
|
||||
/// @name new user registration
|
||||
/// @{
|
||||
|
||||
this.lookup = function(usr) {
|
||||
if (usr.length > 2) communication.lookup(uid(usr), function(res) {
|
||||
view.available(res)
|
||||
})
|
||||
}
|
||||
|
||||
this.checkpasswords = view.passwords
|
||||
|
||||
this.createuser = function(name, pwd) {
|
||||
crypto.createuser(name, name+'@'+hostname, pwd).then(function() {
|
||||
if (!crypto.password(pwd))
|
||||
fatal("private key decryption failed")
|
||||
else
|
||||
chat()
|
||||
})
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @}
|
||||
|
||||
function initBrowser() {
|
||||
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
|
||||
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction
|
||||
@@ -469,242 +541,248 @@ function SafeChat() {
|
||||
return window.indexedDB && window.crypto.getRandomValues && Storage
|
||||
}
|
||||
|
||||
function register() {
|
||||
var newuser = view.newuser
|
||||
|
||||
function chat() {
|
||||
}
|
||||
|
||||
function password() {
|
||||
|
||||
}
|
||||
|
||||
function login() {
|
||||
if (!crypto.key()) register()
|
||||
else password()
|
||||
if (!crypto.key()) newuser(); else password();
|
||||
}
|
||||
|
||||
function run() {
|
||||
this.run = function() {
|
||||
login()
|
||||
}
|
||||
|
||||
function start() {
|
||||
view.reboot = run
|
||||
this.start = function() {
|
||||
view.reboot = this.run
|
||||
var compatible = initBrowser()
|
||||
view.checkFeatures()
|
||||
if (!compatible)
|
||||
view.fatal("your browser is not supported")
|
||||
else
|
||||
run()
|
||||
this.run()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
return new Controller(new View())
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var filecontent = new Array() ///< temporary storage for attachments
|
||||
var reboottimer = null
|
||||
var filecontent = new Array() ///< temporary storage for attachments
|
||||
var reboottimer = null
|
||||
|
||||
function connectionstatus() {
|
||||
if (socket.connected) connected() else disconnected()
|
||||
}
|
||||
function connectionstatus() {
|
||||
if (socket.connected) connected(); else disconnected();
|
||||
}
|
||||
|
||||
/// Configure local groups
|
||||
/** … */
|
||||
function groups() {
|
||||
}
|
||||
/// Configure local groups
|
||||
/** … */
|
||||
function groups() {
|
||||
}
|
||||
|
||||
/// Check if password is set and matches the repeated password
|
||||
/** Checks if both passwords are identical and valid and gives
|
||||
feedback to the user.
|
||||
/// Check if password is set and matches the repeated password
|
||||
/** Checks if both passwords are identical and valid and gives
|
||||
feedback to the user.
|
||||
|
||||
Called when user edits the password fields.
|
||||
Called when user edits the password fields.
|
||||
|
||||
Sets @ref username and checks @ref password - if both are well
|
||||
defined, enables the submit button.
|
||||
Sets @ref username and checks @ref password - if both are well
|
||||
defined, enables the submit button.
|
||||
|
||||
@param pwd The password.
|
||||
@param pwd2 The repeated password. */
|
||||
function checkpwd(pwd, pwd2) {
|
||||
$("#register").submit(function(event) {
|
||||
return false
|
||||
})
|
||||
if (pwd==pwd2) password=pwd
|
||||
else password=null
|
||||
if (!password||password.length<1) password=null
|
||||
$("#createuser").prop("disabled", !(username && password))
|
||||
if (password) {
|
||||
if (username) success("user is ready to be created")
|
||||
@param pwd The password.
|
||||
@param pwd2 The repeated password. */
|
||||
function checkpwd(pwd, pwd2) {
|
||||
$("#register").submit(function(event) {
|
||||
return false
|
||||
})
|
||||
if (pwd==pwd2) password=pwd
|
||||
else password=null
|
||||
if (!password||password.length<1) password=null
|
||||
$("#createuser").prop("disabled", !(username && password))
|
||||
if (password) {
|
||||
if (username) success("user is ready to be created")
|
||||
else notice("password matches, please chose a valid user name")
|
||||
} else {
|
||||
if (username) notice("passwords don't match")
|
||||
} else {
|
||||
if (username) notice("passwords don't match")
|
||||
else if ($('#user').val()) notice("user name is already in use")
|
||||
else notice("please chose a user name")
|
||||
|
||||
else notice("please chose a user name")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the receiver of a message exists on server.
|
||||
/** Calls checknewuser.php on server and enables the message submit
|
||||
button if the receiver of the message exists on the server. */
|
||||
function checkpartner(user) {
|
||||
$("#chat").submit(function(event) {
|
||||
return false
|
||||
})
|
||||
emit("user", uid(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) {
|
||||
notice("generating keys")
|
||||
openpgp.generateKey({
|
||||
numBits: 4096,
|
||||
userIds: [{name: user, email: user+'@'+hostname}],
|
||||
passphrase: pwd
|
||||
}).then(function(keyPair) {
|
||||
success("keys generated")
|
||||
localStorage.pubkey = keyPair.publicKeyArmored
|
||||
localStorage.privkey = keyPair.privateKeyArmored
|
||||
login()
|
||||
}).catch(function(e) {
|
||||
console.log(e)
|
||||
error("generating key pairs failed")
|
||||
})
|
||||
}
|
||||
|
||||
/// Get Own Public Key
|
||||
/** @return public key object */
|
||||
function publicKey() {
|
||||
if (typeof localStorage.pubkey == 'undefined') {
|
||||
if (typeof localStorage.pubKey == 'undefined') {
|
||||
return null
|
||||
} else {
|
||||
localStorage.pubkey = localStorage.pubKey
|
||||
localStorage.removeItem(pubKey)
|
||||
}
|
||||
}
|
||||
return openpgp.key.readArmored(localStorage.pubkey)
|
||||
}
|
||||
|
||||
/// Checks if the receiver of a message exists on server.
|
||||
/** Calls checknewuser.php on server and enables the message submit
|
||||
button if the receiver of the message exists on the server. */
|
||||
function checkpartner(user) {
|
||||
$("#chat").submit(function(event) {
|
||||
return false
|
||||
})
|
||||
emit("user", uid(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) {
|
||||
notice("generating keys")
|
||||
openpgp.generateKey({
|
||||
numBits: 4096,
|
||||
userIds: [{name: user, email: user+'@'+hostname}],
|
||||
passphrase: pwd
|
||||
}).then(function(keyPair) {
|
||||
success("keys generated")
|
||||
localStorage.pubkey = keyPair.publicKeyArmored
|
||||
localStorage.privkey = keyPair.privateKeyArmored
|
||||
login()
|
||||
}).catch(function(e) {
|
||||
console.log(e)
|
||||
error("generating key pairs failed")
|
||||
})
|
||||
}
|
||||
|
||||
/// Get Own Public Key
|
||||
/** @return public key object */
|
||||
function publicKey() {
|
||||
if (typeof localStorage.pubkey == 'undefined') {
|
||||
if (typeof localStorage.pubKey == 'undefined') {
|
||||
return null
|
||||
} else {
|
||||
localStorage.pubkey = localStorage.pubKey
|
||||
localStorage.removeItem(pubKey)
|
||||
}
|
||||
/// Get Own Private Key
|
||||
/** @return private key object */
|
||||
function privateKey() {
|
||||
if (typeof localStorage.privkey == 'undefined') {
|
||||
if (typeof localStorage.privKey == 'undefined') {
|
||||
return null
|
||||
} else {
|
||||
localStorage.privkey = localStorage.privKey
|
||||
localStorage.removeItem(privKey)
|
||||
}
|
||||
return openpgp.key.readArmored(localStorage.pubkey)
|
||||
}
|
||||
return openpgp.key.readArmored(localStorage.privkey)
|
||||
}
|
||||
|
||||
/// Get Own Private Key
|
||||
/** @return private key object */
|
||||
function privateKey() {
|
||||
if (typeof localStorage.privkey == 'undefined') {
|
||||
if (typeof localStorage.privKey == 'undefined') {
|
||||
return null
|
||||
} else {
|
||||
localStorage.privkey = localStorage.privKey
|
||||
localStorage.removeItem(privKey)
|
||||
}
|
||||
}
|
||||
return openpgp.key.readArmored(localStorage.privkey)
|
||||
}
|
||||
/// Get Own User Name
|
||||
/** Get user name as user id of first public key */
|
||||
function userid() {
|
||||
if (!publicKey() ||
|
||||
publicKey().keys.length < 1 ||
|
||||
publicKey().keys[0].getUserIds().length < 1) return null
|
||||
return publicKey().keys[0].getUserIds()[0]
|
||||
}
|
||||
|
||||
/// Get Own User Name
|
||||
/** Get user name as user id of first public key */
|
||||
function userid() {
|
||||
if (!publicKey() ||
|
||||
publicKey().keys.length < 1 ||
|
||||
publicKey().keys[0].getUserIds().length < 1) return null
|
||||
return publicKey().keys[0].getUserIds()[0]
|
||||
}
|
||||
/// Clear Message Text And Attachments
|
||||
/** Does not remove the receiver's name */
|
||||
function clearmessage() {
|
||||
$("#message").prop(":disabled", true)
|
||||
filecontent = new Array()
|
||||
$('#preview').empty()
|
||||
$("#msg").val("")
|
||||
$("#message").prop(":disabled", false)
|
||||
}
|
||||
|
||||
/// Clear Message Text And Attachments
|
||||
/** Does not remove the receiver's name */
|
||||
function clearmessage() {
|
||||
$("#message").prop(":disabled", true)
|
||||
filecontent = new Array()
|
||||
$('#preview').empty()
|
||||
$("#msg").val("")
|
||||
$("#message").prop(":disabled", false)
|
||||
}
|
||||
|
||||
function guessfilename(mimetype, user, date) {
|
||||
if (!user) user = userid()
|
||||
function guessfilename(mimetype, user, date) {
|
||||
if (!user) user = userid()
|
||||
if (!date) date = new Date()
|
||||
var ext = mimetype.replace(/.*\/(x-)?/i, "")
|
||||
return pad(date.getFullYear())+pad(date.getMonth()+1)+pad(date.getDate())
|
||||
+"-"+ext+"-"+user+"@"+hostname+'.'+ext
|
||||
}
|
||||
var ext = mimetype.replace(/.*\/(x-)?/i, "")
|
||||
return pad(date.getFullYear())+pad(date.getMonth()+1)+pad(date.getDate())
|
||||
+"-"+ext+"-"+user+"@"+hostname+'.'+ext
|
||||
}
|
||||
|
||||
/// Display Image Attachments
|
||||
function attachments(files, id, from, date) {
|
||||
if (files) files.forEach(function(file) {
|
||||
console.log(file)
|
||||
if (!file.name) file.name = guessfilename(file.type, from, date)
|
||||
/// Display Image Attachments
|
||||
function attachments(files, id, from, date) {
|
||||
if (files) files.forEach(function(file) {
|
||||
console.log(file)
|
||||
if (!file.name) file.name = guessfilename(file.type, from, date)
|
||||
var a = document.createElement('a')
|
||||
a.href = file.content
|
||||
a.download = file.name
|
||||
a.target = '_blank'
|
||||
if (file.type.match('^image/')) {
|
||||
var img = document.createElement('img')
|
||||
img.title = file.name
|
||||
img.src = file.content
|
||||
a.appendChild(img)
|
||||
} else if (file.type.match('^video/')) {
|
||||
var video = document.createElement('video')
|
||||
video.controls = true
|
||||
video.title = file.name
|
||||
video.src = file.content
|
||||
a.appendChild(video)
|
||||
} else {
|
||||
var img = document.createElement('img')
|
||||
img.title = file.name
|
||||
img.src = "images/Document_sans_PICOL-PIctorial-COmmunication-Language.svg"
|
||||
a.appendChild(img)
|
||||
}
|
||||
$(id).append(a)
|
||||
a.href = file.content
|
||||
a.download = file.name
|
||||
a.target = '_blank'
|
||||
if (file.type.match('^image/')) {
|
||||
var img = document.createElement('img')
|
||||
img.title = file.name
|
||||
img.src = file.content
|
||||
a.appendChild(img)
|
||||
} else if (file.type.match('^video/')) {
|
||||
var video = document.createElement('video')
|
||||
video.controls = true
|
||||
video.title = file.name
|
||||
video.src = file.content
|
||||
a.appendChild(video)
|
||||
} else {
|
||||
var img = document.createElement('img')
|
||||
img.title = file.name
|
||||
img.src = "images/Document_sans_PICOL-PIctorial-COmmunication-Language.svg"
|
||||
a.appendChild(img)
|
||||
}
|
||||
$(id).append(a)
|
||||
})
|
||||
}
|
||||
|
||||
var recorder
|
||||
|
||||
function done() {
|
||||
if (recorder) {
|
||||
recorder.stop()
|
||||
recorder.recording(function(data) {
|
||||
previewfile(data, "video/webm")
|
||||
abort()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var recorder
|
||||
|
||||
function done() {
|
||||
if (recorder) {
|
||||
recorder.stop()
|
||||
recorder.recording(function(data) {
|
||||
previewfile(data, "video/webm")
|
||||
abort()
|
||||
})
|
||||
}
|
||||
function abort() {
|
||||
if (recorder) {
|
||||
$("#videorecorder").hide()
|
||||
recorder.release()
|
||||
delete recorder
|
||||
recorder = null
|
||||
}
|
||||
}
|
||||
|
||||
function abort() {
|
||||
if (recorder) {
|
||||
$("#videorecorder").hide()
|
||||
recorder.release()
|
||||
delete recorder recorder = null
|
||||
}
|
||||
/// Record Video from builtin camera
|
||||
function recordvideo() {
|
||||
try {
|
||||
abort()
|
||||
$("#videorecorder").show()
|
||||
recorder = new MediaStreamRecorder({
|
||||
video: {
|
||||
width: {ideal: 180},
|
||||
height: {ideal: 160}
|
||||
},
|
||||
audio: true
|
||||
})
|
||||
recorder.on("ready", function() {
|
||||
$("#videorecorder video").attr("src", recorder.preview())
|
||||
$("#videorecorder video").css("width", 180)
|
||||
$("#videorecorder video").css("height", 160)
|
||||
$("#videorecorder video").attr("width", 180)
|
||||
$("#videorecorder video").attr("height", 160)
|
||||
recorder.start()
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
error("cannot access camera", true)
|
||||
}
|
||||
}
|
||||
|
||||
/// Record Video from builtin camera
|
||||
function recordvideo() {
|
||||
try {
|
||||
abort()
|
||||
$("#videorecorder").show()
|
||||
recorder = new MediaStreamRecorder({
|
||||
video: {
|
||||
width: {ideal: 180},
|
||||
height: {ideal: 160}
|
||||
},
|
||||
audio: true
|
||||
})
|
||||
recorder.on("ready", function() {
|
||||
$("#videorecorder video").attr("src", recorder.preview())
|
||||
$("#videorecorder video").css("width", 180)
|
||||
$("#videorecorder video").css("height", 160)
|
||||
$("#videorecorder video").attr("width", 180)
|
||||
$("#videorecorder video").attr("height", 160)
|
||||
recorder.start()
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
error("cannot access camera", true)
|
||||
}
|
||||
}
|
||||
|
||||
function previewfile(content, type, name) {
|
||||
if (!name) name = guessfilename(type)
|
||||
function previewfile(content, type, name) {
|
||||
if (!name) name = guessfilename(type)
|
||||
if (type.match('^image/')) {
|
||||
var img = document.createElement("img")
|
||||
img.onload = function() { // resize image to maximum 400px
|
||||
@@ -748,334 +826,341 @@ function SafeChat() {
|
||||
img.title = name+"\n"+size(content.length)
|
||||
$("#preview").append(img)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Upload Attachment
|
||||
/** Prepares attachment to be sent in a message. If the attachment is
|
||||
an image, it resizes the image to 400px on the lager side.
|
||||
/// Upload Attachment
|
||||
/** Prepares attachment to be sent in a message. If the attachment is
|
||||
an image, it resizes the image to 400px on the lager side.
|
||||
|
||||
By now, only images are supported.
|
||||
By now, only images are supported.
|
||||
|
||||
Stores data in global variable @ref filecontent. */
|
||||
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) {
|
||||
var file = f
|
||||
var reader = new FileReader()
|
||||
reader.onload = function(evt) {
|
||||
if (evt.target.error) return error("error reading file", true)
|
||||
Stores data in global variable @ref filecontent. */
|
||||
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) {
|
||||
var file = f
|
||||
var reader = new FileReader()
|
||||
reader.onload = function(evt) {
|
||||
if (evt.target.error) return error("error reading file", true)
|
||||
if (evt.target.readyState==0) return notice("waiting for data …")
|
||||
if (evt.target.readyState==1) return notice("loading data …")
|
||||
previewfile(evt.target.result, file.type, file.name)
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
if (evt.target.readyState==1) return notice("loading data …")
|
||||
previewfile(evt.target.result, file.type, file.name)
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets Receiver's Name
|
||||
/** Called when clicked on a receiver's name. Sets focus to the
|
||||
message text field.
|
||||
|
||||
@param name The receiver's name. */
|
||||
function setreceiver(name) {
|
||||
$("#recv").val(name)
|
||||
checkpartner(name)
|
||||
$("#msg").focus()
|
||||
}
|
||||
|
||||
var userMap = null
|
||||
function users(userlist) {
|
||||
console.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)
|
||||
})
|
||||
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")
|
||||
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
|
||||
if (!usr.exists) {
|
||||
username = usr.name
|
||||
success("user name "+usr.name+" is available")
|
||||
} else {
|
||||
username = null
|
||||
error("user name "+usr.name+" is in use", true)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets Receiver's Name
|
||||
/** Called when clicked on a receiver's name. Sets focus to the
|
||||
message text field.
|
||||
|
||||
@param name The receiver's name. */
|
||||
function setreceiver(name) {
|
||||
$("#recv").val(name)
|
||||
checkpartner(name)
|
||||
$("#msg").focus()
|
||||
if ($("#chat").is(":visible") && usr.name==uid($("#recv").val())) { // same username as in receiver
|
||||
$('#send').prop("disabled", !usr.exists)
|
||||
$("label[for=send] img").css("opacity", usr.exists?"1.0":"0.4")
|
||||
$("label[for=send] img").css("filter", usr.exists?"alpha(opacity=100)":"alpha(opacity=40)")
|
||||
if (usr.exists) success("recipient exists")
|
||||
else error("unknown recipient", true)
|
||||
}
|
||||
|
||||
var userMap = null
|
||||
function users(userlist) {
|
||||
console.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)
|
||||
})
|
||||
if (userMap == null) {
|
||||
if (localStorage.userMap) {
|
||||
userMap = JSON.parse(localStorage.userMap)
|
||||
} else {
|
||||
userMap = new Array()
|
||||
}
|
||||
}
|
||||
if (usr.exists && usr.pubkey && userMap[usr.name] != usr.pubkey) {
|
||||
userMap[usr.name] = usr.pubkey
|
||||
$("#allusers").append('option value="'+htmlenc(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")
|
||||
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
|
||||
if (!usr.exists) {
|
||||
username = usr.name
|
||||
success("user name "+usr.name+" is available")
|
||||
} else {
|
||||
username = null
|
||||
error("user name "+usr.name+" is in use", true)
|
||||
}
|
||||
}
|
||||
if ($("#chat").is(":visible") && usr.name==uid($("#recv").val())) { // same username as in receiver
|
||||
$('#send').prop("disabled", !usr.exists)
|
||||
$("label[for=send] img").css("opacity", usr.exists?"1.0":"0.4")
|
||||
$("label[for=send] img").css("filter", usr.exists?"alpha(opacity=100)":"alpha(opacity=40)")
|
||||
if (usr.exists) success("recipient exists")
|
||||
else error("unknown recipient", true)
|
||||
}
|
||||
if (userMap == null) {
|
||||
if (localStorage.userMap) {
|
||||
userMap = JSON.parse(localStorage.userMap)
|
||||
} else {
|
||||
userMap = new Array()
|
||||
}
|
||||
}
|
||||
if (usr.exists && usr.pubkey && userMap[usr.name] != usr.pubkey) {
|
||||
userMap[usr.name] = usr.pubkey
|
||||
$("#allusers").append('option value="'+htmlenc(usr.name)+'"')
|
||||
localStorage.userMap = JSON.stringify(userMap)
|
||||
}
|
||||
}
|
||||
function queryuser(usr) {
|
||||
console.log("query user: "+uid(usr))
|
||||
socket.emit("user", uid(usr))
|
||||
}
|
||||
|
||||
function queryuser(usr) {
|
||||
console.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) {
|
||||
var deferredObject = $.Deferred()
|
||||
if (userMap && userMap[user]) deferredObject.resolve(userMap[user])
|
||||
/// Get a user's public key.
|
||||
/** The first time, gets it from the server, later from the cache. */
|
||||
function getPublicKey(user) {
|
||||
var deferredObject = $.Deferred()
|
||||
if (userMap && userMap[user]) deferredObject.resolve(userMap[user])
|
||||
else deferredObject.reject("unknown user")
|
||||
return deferredObject.promise()
|
||||
}
|
||||
return deferredObject.promise()
|
||||
}
|
||||
|
||||
/// Received a list of messages from server
|
||||
function messages(msgs) {
|
||||
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 …")
|
||||
msgs.forEach(function(msg) {message(msg, true)})
|
||||
status("chat")
|
||||
}
|
||||
/// Received a list of messages from server
|
||||
function messages(msgs) {
|
||||
console.log("rcv-> messages("+msgs.length+")")
|
||||
if (!password || !privateKey())
|
||||
return setTimeout(function() {emit("messages")}, 1000) // try again later
|
||||
show("allmessages")
|
||||
notice("load messages, please wait …")
|
||||
msgs.forEach(function(msg) {message(msg, true)})
|
||||
show("chat")
|
||||
}
|
||||
|
||||
/// Received a message from server
|
||||
function message(m, internal) {
|
||||
if (!internal) console.log("rcv-> message("+m.user+")")
|
||||
/// Received a message from server
|
||||
function message(m, internal) {
|
||||
if (!internal) console.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)
|
||||
var key=openpgp.key.readArmored(m.pubkey)
|
||||
if (key.err) return error("key of sender unreadable", true)
|
||||
var message = openpgp.message.readArmored(m.msg)
|
||||
var privkey = privateKey().keys[0]
|
||||
if (privkey.decrypt(password)) // prepare own key
|
||||
var privkey = privateKey().keys[0]
|
||||
if (privkey.decrypt(password)) // prepare own key
|
||||
openpgp.decrypt({
|
||||
privateKeys: privkey,
|
||||
publicKeys: key.keys,
|
||||
message: message
|
||||
}).then(function(msg) { // decryption succeded
|
||||
openpgp.decrypt({
|
||||
privateKeys: privkey,
|
||||
publicKeys: key.keys,
|
||||
message: message
|
||||
}).then(function(msg) { // decryption succeded
|
||||
openpgp.decrypt({
|
||||
privateKeys: privkey,
|
||||
publicKeys: key.keys,
|
||||
message: message
|
||||
}).then(function(msg) { // decryption succeded
|
||||
// prepend message to list of messages
|
||||
var message = JSON.parse(msg.text)
|
||||
$("#msgs") // todo: check msg.signatures[0].valid
|
||||
.prepend('<div id="id'+(m.id)+'" class="msg '+
|
||||
(m.user==userid()?"me":"other")+
|
||||
'"><div class="header">'+
|
||||
'<span class="date">'+
|
||||
(new Date(m.time)).toLocaleString()+
|
||||
'</span><span class="sender">'+
|
||||
'<a href="javascript:void(0)" '+
|
||||
'onclick="setreceiver(this.innerHTML)">'+
|
||||
htmlenc(m.user)+
|
||||
'</a>'+(message.receiver?' → <a href="javascript:void(0)" '+
|
||||
'onclick="setreceiver(this.innerHTML)">'
|
||||
+htmlenc(message.receiver)+'</a>':"")+
|
||||
'</span></div>'+
|
||||
'<div class="text">'+
|
||||
htmlenc(message.text)+
|
||||
'</div></div><div class="clear"/>')
|
||||
// show attachments
|
||||
attachments(message.files, '#id'+m.id+' .text', m.user, new Date(m.time))
|
||||
// calculate and show emoticons
|
||||
$('#id'+m.id).emoticonize()
|
||||
if (!internal) beep(m.user)
|
||||
}).catch(function(e) {
|
||||
// not for me
|
||||
success()
|
||||
})
|
||||
// prepend message to list of messages
|
||||
var message = JSON.parse(msg.text)
|
||||
$("#msgs") // todo: check msg.signatures[0].valid
|
||||
.prepend('<div id="id'+(m.id)+'" class="msg '+
|
||||
(m.user==userid()?"me":"other")+
|
||||
'"><div class="header">'+
|
||||
'<span class="date">'+
|
||||
(new Date(m.time)).toLocaleString()+
|
||||
'</span><span class="sender">'+
|
||||
'<a href="javascript:void(0)" '+
|
||||
'onclick="setreceiver(this.innerHTML)">'+
|
||||
htmlenc(m.user)+
|
||||
'</a>'+(message.receiver?' → <a href="javascript:void(0)" '+
|
||||
'onclick="setreceiver(this.innerHTML)">'
|
||||
+htmlenc(message.receiver)+'</a>':"")+
|
||||
'</span></div>'+
|
||||
'<div class="text">'+
|
||||
htmlenc(message.text)+
|
||||
'</div></div><div class="clear"/>')
|
||||
// show attachments
|
||||
attachments(message.files, '#id'+m.id+' .text', m.user, new Date(m.time))
|
||||
// calculate and show emoticons
|
||||
$('#id'+m.id).emoticonize()
|
||||
if (!internal) beep(m.user)
|
||||
}).catch(function(e) {
|
||||
// not for me
|
||||
success()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Send Message To Server
|
||||
/** 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) {
|
||||
notice("1/3 preparing message …")
|
||||
$("#message").prop(":disabled", true)
|
||||
getPublicKey(recv) // get receiver's public key
|
||||
.done(function(pk) {
|
||||
var key=openpgp.key.readArmored(pk)
|
||||
if (!pk||key.err) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("receiver's key not found", true)
|
||||
return
|
||||
}
|
||||
var privkey = privateKey().keys[0]
|
||||
privkey.decrypt(password) // get own private key ready
|
||||
var message = JSON.stringify({receiver: recv, text: txt, files: filecontent})
|
||||
notice("2/3 encrypting message …")
|
||||
openpgp.encrypt({publicKeys: key.keys.concat(publicKey().keys),
|
||||
privateKeys: privkey,
|
||||
data: message,
|
||||
armor: false})
|
||||
.then(function(msg) { // message is encrypted
|
||||
notice("3/3 sending message …")
|
||||
emit("message", {user: userid(), content: msg})
|
||||
clearmessage()
|
||||
})
|
||||
.catch(function(e) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("encryption of message failed", true)
|
||||
})
|
||||
})
|
||||
.fail(function(e) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("user not found", true)
|
||||
})
|
||||
}
|
||||
|
||||
/// Check And Set Password
|
||||
/** Check if given password matches to decrypt the private key. If so,
|
||||
store it in global temporary variable @ref password and start the
|
||||
chat. The password matches, when the private key can be decrypted.
|
||||
|
||||
@param pwd The password to check. */
|
||||
function setpw(pwd) {
|
||||
if (privateKey().keys[0].decrypt(pwd)) {
|
||||
success("password matches")
|
||||
$("#removeKey").hide()
|
||||
password = pwd
|
||||
chat()
|
||||
} else {
|
||||
notice("password does not match")
|
||||
}
|
||||
}
|
||||
|
||||
/// Create Password Entry Field
|
||||
/** Asks user for password. When user starts to enter it, it is
|
||||
permanentely checked in setpw(). As soon as the password matches,
|
||||
setpw() continues automatically. No submit is required by the
|
||||
user. */
|
||||
function getpwd() {
|
||||
if (password) return
|
||||
$("#removeKey").show()
|
||||
show("getpwd")
|
||||
}
|
||||
|
||||
function deleteUser() {
|
||||
var uid = userid()
|
||||
localStorage.removeItem(pubkey)
|
||||
localStorage.removeItem(privkey)
|
||||
error("user "+uid+" permanentely lost")
|
||||
}
|
||||
|
||||
function removeKey() {
|
||||
togglemenu()
|
||||
$("#removeKey").hide()
|
||||
show('forgotpassword')
|
||||
}
|
||||
|
||||
/// Main Chat Window
|
||||
/** Gets chat widgets from server and displays them. Starts timer for
|
||||
get() which polls for new messages. */
|
||||
var firsttime = true
|
||||
function chat() {
|
||||
if (!password) return getpwd()
|
||||
show("chat")
|
||||
if (firsttime && $('#msgs').is(':empty')) {
|
||||
firsttime = false
|
||||
notice("getting previous messages, please wait …")
|
||||
emit("messages")
|
||||
}
|
||||
}
|
||||
|
||||
/// Login User
|
||||
/** This is not really a login, it is just some kind of validation.
|
||||
The server does not care if a user is online or not, it is only
|
||||
interesting to the client to make sure, everything is fine. User
|
||||
is logged in the following way: User name and public key are sent
|
||||
to the server. If the user name exists on the server and the
|
||||
public key is the same, the user is considered logged in, his
|
||||
credentials seem to be valid. If user does not yet exits on
|
||||
server, it is created now. If user exists, but public key is
|
||||
different, then this is a complete failure, something went
|
||||
terribly wrong. */
|
||||
function login() {
|
||||
$("#username").html(userid()+"@"+hostname)
|
||||
emit("login", {name: userid(),
|
||||
pubkey: localStorage.pubkey})
|
||||
success("login sent to server")
|
||||
}
|
||||
|
||||
/// Get And Display Form To Create New User
|
||||
/** Shows user creation form. On submit, a private key is generated in
|
||||
createkeypair(), then login() creates the user. */
|
||||
function newuser() {
|
||||
show("newuser")
|
||||
}
|
||||
|
||||
/// Check if local storage is available
|
||||
function checkLocalStorage() {
|
||||
var test = 'test'
|
||||
try {
|
||||
localStorage.setItem(test, test)
|
||||
localStorage.removeItem(test)
|
||||
return true
|
||||
} catch(e) {
|
||||
show("nolocalstorage")
|
||||
error("local storage not available")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// Initial Function: Startup
|
||||
/** Decide whether to login or to create a new user */
|
||||
function start() {
|
||||
$("#menu").hide()
|
||||
//show("startup")
|
||||
if (checkLocalStorage())
|
||||
try {
|
||||
if (!userid()) {
|
||||
newuser()
|
||||
} else {
|
||||
login()
|
||||
}
|
||||
} catch (m) {
|
||||
console.log(m.stack)
|
||||
error(m)
|
||||
}
|
||||
}
|
||||
|
||||
/// Send Message To Server
|
||||
/** 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) {
|
||||
notice("1/3 preparing message …")
|
||||
$("#message").prop(":disabled", true)
|
||||
getPublicKey(recv) // get receiver's public key
|
||||
.done(function(pk) {
|
||||
var key=openpgp.key.readArmored(pk)
|
||||
if (!pk||key.err) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("receiver's key not found", true)
|
||||
return
|
||||
}
|
||||
var privkey = privateKey().keys[0]
|
||||
privkey.decrypt(password) // get own private key ready
|
||||
var message = JSON.stringify({receiver: recv, text: txt, files: filecontent})
|
||||
notice("2/3 encrypting message …")
|
||||
openpgp.encrypt({publicKeys: key.keys.concat(publicKey().keys),
|
||||
privateKeys: privkey,
|
||||
data: message,
|
||||
armor: false})
|
||||
.then(function(msg) { // message is encrypted
|
||||
notice("3/3 sending message …")
|
||||
emit("message", {user: userid(), content: msg})
|
||||
clearmessage()
|
||||
})
|
||||
.catch(function(e) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("encryption of message failed", true)
|
||||
})
|
||||
})
|
||||
.fail(function(e) {
|
||||
$("#message").prop(":disabled", false)
|
||||
error("user not found", true)
|
||||
})
|
||||
}
|
||||
var safechat = new SafeChat()
|
||||
|
||||
/// Check And Set Password
|
||||
/** Check if given password matches to decrypt the private key. If so,
|
||||
store it in global temporary variable @ref password and start the
|
||||
chat. The password matches, when the private key can be decrypted.
|
||||
function init() {
|
||||
safechat.start()
|
||||
}
|
||||
|
||||
@param pwd The password to check. */
|
||||
function setpw(pwd) {
|
||||
if (privateKey().keys[0].decrypt(pwd)) {
|
||||
success("password matches")
|
||||
$("#removeKey").hide()
|
||||
password = pwd
|
||||
chat()
|
||||
} else {
|
||||
notice("password does not match")
|
||||
}
|
||||
}
|
||||
function old() {
|
||||
/// On Load, Call @ref start
|
||||
$(window.onbeforeunload = function() {
|
||||
return "Are you sure you want to navigate away?"
|
||||
})
|
||||
/// Allow Running in Background on Android
|
||||
document.addEventListener('deviceready', function () {
|
||||
if (cordova && cordova.plugins.backgroundMode) {
|
||||
cordova.plugins.backgroundMode.enable()
|
||||
}
|
||||
}, false)
|
||||
connectionstatus()
|
||||
if (openpgp.initWorker("openpgp.worker.min.js"))
|
||||
console.log("asynchronous openpgp enabled")
|
||||
else
|
||||
console.log("asynchronous openpgp failed")
|
||||
emit('users')
|
||||
start()
|
||||
}
|
||||
|
||||
/// Create Password Entry Field
|
||||
/** Asks user for password. When user starts to enter it, it is
|
||||
permanentely checked in setpw(). As soon as the password matches,
|
||||
setpw() continues automatically. No submit is required by the
|
||||
user. */
|
||||
function getpwd() {
|
||||
if (password) return
|
||||
$("#removeKey").show()
|
||||
status("getpwd")
|
||||
}
|
||||
|
||||
function deleteUser() {
|
||||
var uid = userid()
|
||||
localStorage.removeItem(pubkey)
|
||||
localStorage.removeItem(privkey)
|
||||
error("user "+uid+" permanentely lost")
|
||||
}
|
||||
|
||||
function removeKey() {
|
||||
togglemenu()
|
||||
$("#removeKey").hide()
|
||||
status('forgotpassword')
|
||||
}
|
||||
|
||||
/// Main Chat Window
|
||||
/** Gets chat widgets from server and displays them. Starts timer for
|
||||
get() which polls for new messages. */
|
||||
var firsttime = true
|
||||
function chat() {
|
||||
if (!password) return getpwd()
|
||||
status("chat")
|
||||
if (firsttime && $('#msgs').is(':empty')) {
|
||||
firsttime = false
|
||||
notice("getting previous messages, please wait …")
|
||||
emit("messages")
|
||||
}
|
||||
}
|
||||
|
||||
/// Login User
|
||||
/** This is not really a login, it is just some kind of validation.
|
||||
The server does not care if a user is online or not, it is only
|
||||
interesting to the client to make sure, everything is fine. User
|
||||
is logged in the following way: User name and public key are sent
|
||||
to the server. If the user name exists on the server and the
|
||||
public key is the same, the user is considered logged in, his
|
||||
credentials seem to be valid. If user does not yet exits on
|
||||
server, it is created now. If user exists, but public key is
|
||||
different, then this is a complete failure, something went
|
||||
terribly wrong. */
|
||||
function login() {
|
||||
$("#username").html(userid()+"@"+hostname)
|
||||
emit("login", {name: userid(),
|
||||
pubkey: localStorage.pubkey})
|
||||
success("login sent to server")
|
||||
}
|
||||
|
||||
/// Get And Display Form To Create New User
|
||||
/** Shows user creation form. On submit, a private key is generated in
|
||||
createkeypair(), then login() creates the user. */
|
||||
function newuser() {
|
||||
status("newuser")
|
||||
}
|
||||
|
||||
/// Check if local storage is available
|
||||
function checkLocalStorage() {
|
||||
var test = 'test'
|
||||
try {
|
||||
localStorage.setItem(test, test)
|
||||
localStorage.removeItem(test)
|
||||
return true
|
||||
} catch(e) {
|
||||
status("nolocalstorage")
|
||||
error("local storage not available")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// Initial Function: Startup
|
||||
/** Decide whether to login or to create a new user */
|
||||
function start() {
|
||||
$("#menu").hide()
|
||||
//status("startup")
|
||||
if (checkLocalStorage())
|
||||
try {
|
||||
if (!userid()) {
|
||||
newuser()
|
||||
} else {
|
||||
login()
|
||||
}
|
||||
} catch (m) {
|
||||
console.log(m.stack)
|
||||
error(m)
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
/// On Load, Call @ref start
|
||||
$(window.onbeforeunload = function() {
|
||||
return "Are you sure you want to navigate away?"
|
||||
})
|
||||
/// Allow Running in Background on Android
|
||||
document.addEventListener('deviceready', function () {
|
||||
if (cordova && cordova.plugins.backgroundMode) {
|
||||
cordova.plugins.backgroundMode.enable()
|
||||
}
|
||||
}, false)
|
||||
connectionstatus()
|
||||
if (openpgp.initWorker("openpgp.worker.min.js"))
|
||||
console.log("asynchronous openpgp enabled")
|
||||
else
|
||||
console.log("asynchronous openpgp failed")
|
||||
emit('users')
|
||||
start()
|
||||
}
|
||||
|
||||
/// Start Main Loop
|
||||
$(init)
|
||||
/// Start Main Loop
|
||||
$(init)
|
||||
|
Reference in New Issue
Block a user