in the middle of rewriting it
This commit is contained in:
@@ -3,7 +3,6 @@ module.exports = function(config) {
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
config.multipleStatements = true;
|
config.multipleStatements = true;
|
||||||
var pool = mysql.createPool(config);
|
var pool = mysql.createPool(config);
|
||||||
console.log(__dirname+'/schema.sql')
|
|
||||||
pool.query(fs.readFileSync(__dirname+'/schema.sql').toString());
|
pool.query(fs.readFileSync(__dirname+'/schema.sql').toString());
|
||||||
if (config.max_allowed_packet)
|
if (config.max_allowed_packet)
|
||||||
pool.query("set global max_allowed_packet=?", [config.max_allowed_packet]);
|
pool.query("set global max_allowed_packet=?", [config.max_allowed_packet]);
|
||||||
|
9
nodejs/etc/systemd/system/safechat.service
Normal file
9
nodejs/etc/systemd/system/safechat.service
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Secure and Encrypted Chat Server
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/nodejs /usr/share/safechat/nodejs/safechat > /var/log/safechat.log
|
||||||
|
Restart=on-abort
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@@ -20,8 +20,8 @@
|
|||||||
start -> newuser [label="if no keys exist"];
|
start -> newuser [label="if no keys exist"];
|
||||||
start -> login [label="if keys exist"];
|
start -> login [label="if keys exist"];
|
||||||
newuser -> createkeypair [label="on submit"];
|
newuser -> createkeypair [label="on submit"];
|
||||||
createkeypair -> "openpgp.generateKeyPair";
|
createkeypair -> "openpgp.generateKey";
|
||||||
"openpgp.generateKeyPair" -> login [label="keys generated in local store"];
|
"openpgp.generateKey" -> login [label="keys generated in local store"];
|
||||||
login -> chat [label="user is valid on server"];
|
login -> chat [label="user is valid on server"];
|
||||||
chat -> getpwd [label="password not yet entered"];
|
chat -> getpwd [label="password not yet entered"];
|
||||||
getpwd -> setpw [label="on input"];
|
getpwd -> setpw [label="on input"];
|
||||||
@@ -33,20 +33,88 @@
|
|||||||
sendmessage -> chat [label="remain in chat"];
|
sendmessage -> chat [label="remain in chat"];
|
||||||
}
|
}
|
||||||
@enddot
|
@enddot
|
||||||
*/
|
*/
|
||||||
// 1 2 3 4 5 6 7 8
|
// 1 2 3 4 5 6 7 8
|
||||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
function SafeChatClient(success, notice, error) {
|
||||||
|
|
||||||
|
/// Cache Client's Key from local Strorage
|
||||||
|
var k = null;
|
||||||
|
|
||||||
|
/// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get Own User Name
|
||||||
|
/** Get user name as user id of first public key */
|
||||||
|
function uid() {
|
||||||
|
if (k || key()) return k.pub.keys[0].getUserIds()[0]
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create New User
|
||||||
|
function createuser(user, email, pwd) {
|
||||||
|
notice("generating keys")
|
||||||
|
openpgp.generateKey({
|
||||||
|
numBits: 4096,
|
||||||
|
userIds: [{name: user, email: email}],
|
||||||
|
passphrase: pwd
|
||||||
|
}).then(function(keyPair) {
|
||||||
|
success("keys generated")
|
||||||
|
localStorage.key = keyPair.privateKeyArmored
|
||||||
|
k = keyPair.key
|
||||||
|
}).catch(function(e) {
|
||||||
|
console.log(e)
|
||||||
|
error("generating key pairs failed")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function password(pwd) {
|
||||||
|
return (k || keys()) && k.keys[0].decrypt(pwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encrypt Message
|
||||||
|
function encrypt(targetkeys, message, done, failed) {
|
||||||
|
if (!k) return false
|
||||||
|
openpgp.encrypt({
|
||||||
|
publicKeys: targets.keys.concat(k.keys),
|
||||||
|
privateKeys: k,
|
||||||
|
data: message,
|
||||||
|
armor: false})
|
||||||
|
.then(done)
|
||||||
|
.else(failed)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Decrypt Message
|
||||||
|
function decrypt(message) {
|
||||||
|
if (!k) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var password = null; ///< password, only stored temporary, until reload
|
var password = null; ///< password, only stored temporary, until reload
|
||||||
var username = null; ///< username, only used during registration
|
var username = null; ///< username, only used during registration
|
||||||
var filecontent = new Array(); ///< temporary storage for attachments
|
var filecontent = new Array(); ///< temporary storage for attachments
|
||||||
var socket = io.connect();
|
var socket = io.connect();
|
||||||
|
var hostname = window.location.hostname!='localhost'?window.location.hostname:'safechat.ch';
|
||||||
|
|
||||||
/// Padding for numbers in dates
|
/// Padding for numbers in dates
|
||||||
function pad(n) {
|
function pad(n) {
|
||||||
return n<10 ? '0'+n : n
|
return n<10 ? '0'+n : n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function uid(name) {
|
||||||
|
return name+' <'+name+'@'+hostname+'>';
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert number of bytes to readable text
|
/// Convert number of bytes to readable text
|
||||||
function size(num) {
|
function size(num) {
|
||||||
if (num>0.6*1024) {
|
if (num>0.6*1024) {
|
||||||
@@ -206,7 +274,7 @@ function backup() {
|
|||||||
var now = new Date();
|
var now = new Date();
|
||||||
download.download =
|
download.download =
|
||||||
pad(now.getFullYear())+pad(now.getMonth()+1)+pad(now.getDate())+
|
pad(now.getFullYear())+pad(now.getMonth()+1)+pad(now.getDate())+
|
||||||
"-"+userid()+"@"+window.location.hostname+".bak";
|
"-"+userid()+"@"+hostname+".bak";
|
||||||
var clickEvent = new MouseEvent("click", {
|
var clickEvent = new MouseEvent("click", {
|
||||||
"view": window,
|
"view": window,
|
||||||
"bubbles": true,
|
"bubbles": true,
|
||||||
@@ -284,16 +352,16 @@ function checkpartner(user) {
|
|||||||
$("#chat").submit(function(event) {
|
$("#chat").submit(function(event) {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
emit("user", user);
|
emit("user", uid(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Local Public-/Private-Key Pair
|
/// Create Local Public-/Private-Key Pair
|
||||||
/** Called if user has not yet his keys, just generates a new key pair. */
|
/** Called if user has not yet his keys, just generates a new key pair. */
|
||||||
function createkeypair(user, pwd) {
|
function createkeypair(user, pwd) {
|
||||||
notice("generating keys");
|
notice("generating keys");
|
||||||
openpgp.generateKeyPair({
|
openpgp.generateKey({
|
||||||
numBits: 4096,
|
numBits: 4096,
|
||||||
userId: user,
|
userIds: [{name: user, email: user+'@'+hostname}],
|
||||||
passphrase: pwd
|
passphrase: pwd
|
||||||
}).then(function(keyPair) {
|
}).then(function(keyPair) {
|
||||||
success("keys generated");
|
success("keys generated");
|
||||||
@@ -301,7 +369,8 @@ function createkeypair(user, pwd) {
|
|||||||
localStorage.privkey = keyPair.privateKeyArmored;
|
localStorage.privkey = keyPair.privateKeyArmored;
|
||||||
login();
|
login();
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
error("generating key pairs failed");
|
console.log(e)
|
||||||
|
error("generating key pairs failed")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +426,7 @@ function guessfilename(mimetype, user, date) {
|
|||||||
if (!date) date = new Date();
|
if (!date) date = new Date();
|
||||||
var ext = mimetype.replace(/.*\/(x-)?/i, "");
|
var ext = mimetype.replace(/.*\/(x-)?/i, "");
|
||||||
return pad(date.getFullYear())+pad(date.getMonth()+1)+pad(date.getDate())
|
return pad(date.getFullYear())+pad(date.getMonth()+1)+pad(date.getDate())
|
||||||
+"-"+ext+"-"+user+"@"+window.location.hostname+'.'+ext;
|
+"-"+ext+"-"+user+"@"+hostname+'.'+ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display Image Attachments
|
/// Display Image Attachments
|
||||||
@@ -545,7 +614,7 @@ function loggedin() {
|
|||||||
function user(usr) {
|
function user(usr) {
|
||||||
if (usr.exists) console.log("rcv-> user("+usr.name+")");
|
if (usr.exists) console.log("rcv-> user("+usr.name+")");
|
||||||
else console.log("rcv-> user("+usr.name+"): name is available");
|
else console.log("rcv-> user("+usr.name+"): name is available");
|
||||||
if ($("#newuser").is(":visible") && usr.name==$('#user').val()) {
|
if ($("#newuser").is(":visible") && usr.name==uid($('#user').val())) {
|
||||||
// same username as in the create user form
|
// same username as in the create user form
|
||||||
$("#createuser").prop("disabled", usr.exists); // todo: check password
|
$("#createuser").prop("disabled", usr.exists); // todo: check password
|
||||||
if (!usr.exists) {
|
if (!usr.exists) {
|
||||||
@@ -556,7 +625,7 @@ function user(usr) {
|
|||||||
error("user name "+usr.name+" is in use", true);
|
error("user name "+usr.name+" is in use", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($("#chat").is(":visible") && usr.name==$("#recv").val()) { // same username as in receiver
|
if ($("#chat").is(":visible") && usr.name==uid($("#recv").val())) { // same username as in receiver
|
||||||
$('#send').prop("disabled", !usr.exists);
|
$('#send').prop("disabled", !usr.exists);
|
||||||
$("label[for=send] img").css("opacity", usr.exists?"1.0":"0.4");
|
$("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)");
|
$("label[for=send] img").css("filter", usr.exists?"alpha(opacity=100)":"alpha(opacity=40)");
|
||||||
@@ -577,6 +646,11 @@ function user(usr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function queryuser(usr) {
|
||||||
|
console.log("query user: "+uid(usr));
|
||||||
|
socket.emit("user", uid(usr));
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a user's public key.
|
/// Get a user's public key.
|
||||||
/** The first time, gets it from the server, later from the cache. */
|
/** The first time, gets it from the server, later from the cache. */
|
||||||
function getPublicKey(user) {
|
function getPublicKey(user) {
|
||||||
@@ -606,8 +680,11 @@ function message(m, internal) {
|
|||||||
var message = openpgp.message.readArmored(m.msg);
|
var message = openpgp.message.readArmored(m.msg);
|
||||||
var privkey = privateKey().keys[0];
|
var privkey = privateKey().keys[0];
|
||||||
if (privkey.decrypt(password)) // prepare own key
|
if (privkey.decrypt(password)) // prepare own key
|
||||||
openpgp.decryptAndVerifyMessage(privkey, key.keys, message)
|
openpgp.decrypt({
|
||||||
.then(function(msg) { // decryption succeded
|
privateKeys: privkey,
|
||||||
|
publicKeys: key.keys,
|
||||||
|
message: message
|
||||||
|
}).then(function(msg) { // decryption succeded
|
||||||
// prepend message to list of messages
|
// prepend message to list of messages
|
||||||
var message = JSON.parse(msg.text);
|
var message = JSON.parse(msg.text);
|
||||||
$("#msgs") // todo: check msg.signatures[0].valid
|
$("#msgs") // todo: check msg.signatures[0].valid
|
||||||
@@ -632,8 +709,7 @@ function message(m, internal) {
|
|||||||
// calculate and show emoticons
|
// calculate and show emoticons
|
||||||
$('#id'+m.id).emoticonize();
|
$('#id'+m.id).emoticonize();
|
||||||
if (!internal) beep(m.user);
|
if (!internal) beep(m.user);
|
||||||
})
|
}).catch(function(e) {
|
||||||
.catch(function(e) {
|
|
||||||
// not for me
|
// not for me
|
||||||
success();
|
success();
|
||||||
});
|
});
|
||||||
@@ -657,9 +733,10 @@ function sendmessage(recv, txt) {
|
|||||||
privkey.decrypt(password); // get own private key ready
|
privkey.decrypt(password); // get own private key ready
|
||||||
var message = JSON.stringify({receiver: recv, text: txt, files: filecontent});
|
var message = JSON.stringify({receiver: recv, text: txt, files: filecontent});
|
||||||
notice("2/3 encrypting message …");
|
notice("2/3 encrypting message …");
|
||||||
openpgp.signAndEncryptMessage(key.keys.concat(publicKey().keys),
|
openpgp.encrypt({publicKeys: key.keys.concat(publicKey().keys),
|
||||||
privkey,
|
privateKeys: privkey,
|
||||||
message)
|
data: message,
|
||||||
|
armor: false})
|
||||||
.then(function(msg) { // message is encrypted
|
.then(function(msg) { // message is encrypted
|
||||||
notice("3/3 sending message …");
|
notice("3/3 sending message …");
|
||||||
emit("message", {user: userid(), content: msg});
|
emit("message", {user: userid(), content: msg});
|
||||||
@@ -743,7 +820,7 @@ function chat() {
|
|||||||
different, then this is a complete failure, something went
|
different, then this is a complete failure, something went
|
||||||
terribly wrong. */
|
terribly wrong. */
|
||||||
function login() {
|
function login() {
|
||||||
$("#username").html(userid()+"@"+window.location.hostname);
|
$("#username").html(userid()+"@"+hostname);
|
||||||
emit("login", {name: userid(),
|
emit("login", {name: userid(),
|
||||||
pubkey: localStorage.pubkey});
|
pubkey: localStorage.pubkey});
|
||||||
success("login sent to server");
|
success("login sent to server");
|
||||||
@@ -810,7 +887,7 @@ function init() {
|
|||||||
socket.on("message", message);
|
socket.on("message", message);
|
||||||
socket.on("messages", messages);
|
socket.on("messages", messages);
|
||||||
connectionstatus();
|
connectionstatus();
|
||||||
if (openpgp.initWorker("javascripts/openpgp.worker.js"))
|
if (openpgp.initWorker("openpgp.worker.min.js"))
|
||||||
console.log("asynchronous openpgp enabled");
|
console.log("asynchronous openpgp enabled");
|
||||||
else
|
else
|
||||||
console.log("asynchronous openpgp failed");
|
console.log("asynchronous openpgp failed");
|
||||||
|
@@ -1,22 +1,14 @@
|
|||||||
|
module.exports = function(app, package) {
|
||||||
|
|
||||||
/*
|
[
|
||||||
* GET home page.
|
'',
|
||||||
*/
|
'webrtc'
|
||||||
|
].forEach(function(p) {
|
||||||
var package = require(__dirname+"/../package.json");
|
app.get('/'+p, function(req, res) {
|
||||||
|
res.render(p?p:'index', {
|
||||||
exports.index = function(req, res) {
|
package: package
|
||||||
res.render(path, {
|
})
|
||||||
projecturl: package.documentation,
|
})
|
||||||
packagename: package.name,
|
|
||||||
packageversion: package.version
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
exports.webrtc = function(req, res) {
|
|
||||||
res.render('webrtc', {
|
|
||||||
projecturl: package.documentation,
|
|
||||||
packagename: package.name,
|
|
||||||
packageversion: package.version
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
var package = require(__dirname+'/package.json');
|
var package = require(__dirname+'/package.json');
|
||||||
var config = require(package.path.config);
|
var config = require(package.path.config);
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var routes = require(__dirname+'/routes');
|
|
||||||
var app = module.exports = express.createServer();
|
var app = module.exports = express.createServer();
|
||||||
|
var routes = require(__dirname+'/routes')(app, package);
|
||||||
var io = require('socket.io').listen(app);
|
var io = require('socket.io').listen(app);
|
||||||
var sql = require(__dirname+'/database')(config.mysql);
|
var sql = require(__dirname+'/database')(config.mysql);
|
||||||
var sockets = require(__dirname+'/sockets')(sql);
|
var sockets = require(__dirname+'/sockets')(sql);
|
||||||
@@ -34,11 +34,17 @@ app.configure(function() {
|
|||||||
app.use(app.router);
|
app.use(app.router);
|
||||||
app.use(express.static(__dirname + '/public'));
|
app.use(express.static(__dirname + '/public'));
|
||||||
[
|
[
|
||||||
'jquery/dist',
|
'jquery/dist/jquery.min.js',
|
||||||
'openpgp/dist'
|
'jquery/dist/jquery.js',
|
||||||
|
'openpgp/dist/openpgp.min.js',
|
||||||
|
'openpgp/dist/openpgp.js',
|
||||||
|
'openpgp/dist/openpgp.worker.min.js',
|
||||||
|
'openpgp/dist/openpgp.worker.js'
|
||||||
].forEach(function(file) {
|
].forEach(function(file) {
|
||||||
app.use('/'+file.replace(/\/.*/g, ''),
|
app.get('/'+file.replace(/.*\//g, ''),
|
||||||
express.static(__dirname + '/node_modules/'+file));
|
function(req, res) {
|
||||||
|
res.sendfile('/node_modules/'+file, {root: __dirname})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -54,11 +60,6 @@ app.configure('production', function(){
|
|||||||
|
|
||||||
io.sockets.on('connection', sockets.connection);
|
io.sockets.on('connection', sockets.connection);
|
||||||
|
|
||||||
// Routes
|
|
||||||
|
|
||||||
app.get('/', routes.index);
|
|
||||||
app.get('/webrtc', routes.webrtc);
|
|
||||||
|
|
||||||
app.listen(config.port, function(){
|
app.listen(config.port, function(){
|
||||||
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
|
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
|
||||||
});
|
});
|
||||||
|
@@ -56,6 +56,7 @@ module.exports = function(sql) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on("login", function(user) {
|
socket.on("login", function(user) {
|
||||||
|
console.log('-> signal: login('+user.name+')');
|
||||||
if (!user.name || !user.pubkey) return emit("fail", "wrong login format");
|
if (!user.name || !user.pubkey) return emit("fail", "wrong login format");
|
||||||
console.log("-> signal: login("+user.name+")");
|
console.log("-> signal: login("+user.name+")");
|
||||||
if (user.name=="safechat") return emit("fail", "user name safechat is reserved");
|
if (user.name=="safechat") return emit("fail", "user name safechat is reserved");
|
||||||
|
@@ -4,9 +4,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<meta name="viewport" content="width=device-width initial-scale=1" />
|
<meta name="viewport" content="width=device-width initial-scale=1" />
|
||||||
<link href="stylesheets/safechat.css" rel="stylesheet" type="text/css" />
|
<link href="stylesheets/safechat.css" rel="stylesheet" type="text/css" />
|
||||||
<script type="text/javascript" src="jquery/jquery.min.js"></script>
|
<script type="text/javascript" src="jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="openpgp/openpgp.min.js"></script>
|
<script type="text/javascript" src="openpgp.min.js"></script>
|
||||||
<script type="text/javascript" src="openpgp/openpgp.worker.min.js"></script>
|
|
||||||
<script type="text/javascript" src="socket.io/socket.io.js"></script>
|
<script type="text/javascript" src="socket.io/socket.io.js"></script>
|
||||||
<script type="text/javascript" src="javascripts/mediarecorder.js"></script>
|
<script type="text/javascript" src="javascripts/mediarecorder.js"></script>
|
||||||
<script type="text/javascript" src="javascripts/safechat.js"></script>
|
<script type="text/javascript" src="javascripts/safechat.js"></script>
|
||||||
@@ -18,7 +17,7 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="header" class="header">
|
<div id="header" class="header">
|
||||||
<h1>Safe Chat <%= packageversion %></h1>
|
<h1>Safe Chat <%= package.version %></h1>
|
||||||
<div id="togglemenu">
|
<div id="togglemenu">
|
||||||
<span id="username">[unknown]</span>
|
<span id="username">[unknown]</span>
|
||||||
<span id="connectionstatus">
|
<span id="connectionstatus">
|
||||||
@@ -35,7 +34,7 @@
|
|||||||
<li id="groups" onclick="groups()">Edit Groups</li>
|
<li id="groups" onclick="groups()">Edit Groups</li>
|
||||||
<li id="removeKey" style="display: none" onclick="removeKey()">Password Forgotten</li>
|
<li id="removeKey" style="display: none" onclick="removeKey()">Password Forgotten</li>
|
||||||
<li id="android-download" href="safechat.apk"><a href="safechat.apk">Download Android-App</a></li>
|
<li id="android-download" href="safechat.apk"><a href="safechat.apk">Download Android-App</a></li>
|
||||||
<li href="<%= projecturl %>" target="_blank"><a href="<%= projecturl %>" target="_blank">About Safe Chat</a></li>
|
<li href="<%= package.documentation %>" target="_blank"><a href="<%= package.documentation %>" target="_blank">About Safe Chat</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function() { // on load: without cordova, remove andoid-download
|
$(function() { // on load: without cordova, remove andoid-download
|
||||||
@@ -56,16 +55,14 @@
|
|||||||
<input placeholder="username" autocomplete="off" type="text" id="user"/>
|
<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="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)"/>
|
<input placeholder="repeat password" autocomplete="off" type="password" id="pwd2" oninput="checkpwd(document.getElementById('pwd').value, this.value)"/>
|
||||||
<input id="createuser" type="submit" disabled/>
|
<button id="createuser" disabled>register</button>
|
||||||
</form>
|
</form>
|
||||||
<script>
|
<script>
|
||||||
$("#user").on("input", function() {
|
$("#user").on("input", function() {
|
||||||
console.log("query user: "+$('#user').val());
|
queryuser($('#user').val());
|
||||||
socket.emit("user", $('#user').val());
|
|
||||||
});
|
});
|
||||||
$("#register").submit(function(event) {
|
$("#createuser").on("click", function(event) {
|
||||||
createkeypair(event.target.elements['user'].value,
|
createkeypair($('#user').val(), $('#pwd').val());
|
||||||
event.target.elements['pwd'].value);
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -193,7 +190,7 @@
|
|||||||
server. Your password and your secret key are fully under
|
server. Your password and your secret key are fully under
|
||||||
your control. That's why you must enable javascript and
|
your control. That's why you must enable javascript and
|
||||||
local storage for this application.</p>
|
local storage for this application.</p>
|
||||||
<p><a href="<%= projecturl %>" target="_blank">more information</a></p>
|
<p><a href="<%= package.documentation %>" target="_blank">more information</a></p>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
<!-- Error: Missing LocalStorage -->
|
<!-- Error: Missing LocalStorage -->
|
||||||
|
Reference in New Issue
Block a user