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,43 +541,48 @@ 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
|
||||
|
||||
function connectionstatus() {
|
||||
if (socket.connected) connected() else disconnected()
|
||||
if (socket.connected) connected(); else disconnected();
|
||||
}
|
||||
|
||||
/// Configure local groups
|
||||
@@ -673,7 +750,8 @@ function SafeChat() {
|
||||
if (recorder) {
|
||||
$("#videorecorder").hide()
|
||||
recorder.release()
|
||||
delete recorder recorder = null
|
||||
delete recorder
|
||||
recorder = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,10 +930,10 @@ function SafeChat() {
|
||||
console.log("rcv-> messages("+msgs.length+")")
|
||||
if (!password || !privateKey())
|
||||
return setTimeout(function() {emit("messages")}, 1000) // try again later
|
||||
status("allmessages")
|
||||
show("allmessages")
|
||||
notice("load messages, please wait …")
|
||||
msgs.forEach(function(msg) {message(msg, true)})
|
||||
status("chat")
|
||||
show("chat")
|
||||
}
|
||||
|
||||
/// Received a message from server
|
||||
@@ -905,6 +983,7 @@ function SafeChat() {
|
||||
// not for me
|
||||
success()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Send Message To Server
|
||||
@@ -970,7 +1049,7 @@ function SafeChat() {
|
||||
function getpwd() {
|
||||
if (password) return
|
||||
$("#removeKey").show()
|
||||
status("getpwd")
|
||||
show("getpwd")
|
||||
}
|
||||
|
||||
function deleteUser() {
|
||||
@@ -983,7 +1062,7 @@ function SafeChat() {
|
||||
function removeKey() {
|
||||
togglemenu()
|
||||
$("#removeKey").hide()
|
||||
status('forgotpassword')
|
||||
show('forgotpassword')
|
||||
}
|
||||
|
||||
/// Main Chat Window
|
||||
@@ -992,7 +1071,7 @@ function SafeChat() {
|
||||
var firsttime = true
|
||||
function chat() {
|
||||
if (!password) return getpwd()
|
||||
status("chat")
|
||||
show("chat")
|
||||
if (firsttime && $('#msgs').is(':empty')) {
|
||||
firsttime = false
|
||||
notice("getting previous messages, please wait …")
|
||||
@@ -1022,7 +1101,7 @@ function SafeChat() {
|
||||
/** Shows user creation form. On submit, a private key is generated in
|
||||
createkeypair(), then login() creates the user. */
|
||||
function newuser() {
|
||||
status("newuser")
|
||||
show("newuser")
|
||||
}
|
||||
|
||||
/// Check if local storage is available
|
||||
@@ -1033,7 +1112,7 @@ function SafeChat() {
|
||||
localStorage.removeItem(test)
|
||||
return true
|
||||
} catch(e) {
|
||||
status("nolocalstorage")
|
||||
show("nolocalstorage")
|
||||
error("local storage not available")
|
||||
}
|
||||
return false
|
||||
@@ -1043,7 +1122,7 @@ function SafeChat() {
|
||||
/** Decide whether to login or to create a new user */
|
||||
function start() {
|
||||
$("#menu").hide()
|
||||
//status("startup")
|
||||
//show("startup")
|
||||
if (checkLocalStorage())
|
||||
try {
|
||||
if (!userid()) {
|
||||
@@ -1057,7 +1136,13 @@ function SafeChat() {
|
||||
}
|
||||
}
|
||||
|
||||
var safechat = new SafeChat()
|
||||
|
||||
function init() {
|
||||
safechat.start()
|
||||
}
|
||||
|
||||
function old() {
|
||||
/// On Load, Call @ref start
|
||||
$(window.onbeforeunload = function() {
|
||||
return "Are you sure you want to navigate away?"
|
||||
|
||||
@@ -79,7 +79,7 @@ module.exports = function(sql) {
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("user", function(name) {
|
||||
socket.on("user", function(name, fn) {
|
||||
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) {
|
||||
@@ -87,7 +87,20 @@ module.exports = function(sql) {
|
||||
result.exists = true;
|
||||
result.pubkey = res[0].pubkey;
|
||||
}
|
||||
emit('user', result);
|
||||
fn(result);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("lookup", function(name, fn) {
|
||||
console.log("-> signal: lookup("+name+")")
|
||||
var result = false
|
||||
sql.query("select pubkey from user where name = ?",
|
||||
[name],
|
||||
function(err, res, flds) {
|
||||
if (!err && res && res.length) {
|
||||
result = true;
|
||||
}
|
||||
fn(result)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -51,21 +51,12 @@
|
||||
<div id="newuser" style="display: none">
|
||||
<h2>Register User</h2>
|
||||
<p>All you need to start is a username and a password:</p>
|
||||
<form id="register" autocomplete="off">
|
||||
<input placeholder="username" autocomplete="off" type="text" id="user"/>
|
||||
<input placeholder="password" autocomplete="off" type="password" id="pwd" oninput="checkpwd(this.value, document.getElementById('pwd2').value)"/>
|
||||
<input placeholder="repeat password" autocomplete="off" type="password" id="pwd2" oninput="checkpwd(document.getElementById('pwd').value, this.value)"/>
|
||||
<button id="createuser" disabled>register</button>
|
||||
<form id="register" autocomplete="off" onsubmit="safechat.createuser(document.getElementById('user').value, document.getElementById('pwd').value)">
|
||||
<input placeholder="username" autocomplete="off" type="text" id="user" oninput="safechat.lookup(this.value)" />
|
||||
<input placeholder="password" autocomplete="off" type="password" id="pwd" oninput="safechat.checkpasswords(this.value, document.getElementById('pwd2').value)"/>
|
||||
<input placeholder="repeat password" autocomplete="off" type="password" id="pwd2" oninput="safechat.checkpasswords(document.getElementById('pwd').value, this.value)"/>
|
||||
<input id="createuser" type="submit" value="register" disabled />
|
||||
</form>
|
||||
<script>
|
||||
$("#user").on("input", function() {
|
||||
queryuser($('#user').val());
|
||||
});
|
||||
$("#createuser").on("click", function(event) {
|
||||
createkeypair($('#user').val(), $('#pwd').val());
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
<p>Please chose any username, e.g. a pseudonym, your e-mail,
|
||||
your phone number, your real name, and chose a safe
|
||||
password.</p>
|
||||
@@ -184,9 +175,9 @@
|
||||
|
||||
<!-- Fatal: Abort -->
|
||||
|
||||
<div id="fatal">
|
||||
<div id="fatal" style="display: none">
|
||||
<h2 id="fatal-msg">Failure</h2>
|
||||
<p>The SafeChat has been aborted due to a fatal error.</p>
|
||||
<p>SafeChat has been aborted due to a fatal error.</p>
|
||||
<p>There is a problem in your browser. Please try to reload. If the problem persists, please update your web browser or try SafeChat in another browser.</p>
|
||||
<p>The following java script features are required:</p>
|
||||
<ul class="features">
|
||||
|
||||
Reference in New Issue
Block a user