Files
safechat/html/safechat.js

359 lines
12 KiB
JavaScript
Raw Normal View History

2015-07-01 00:07:33 +00:00
var password = null; // password, only stored temporary, until reload
var username = null; // username, only used during registration
var filecontent = new Array(); // temporary storage for attachments
2015-06-28 20:58:51 +00:00
function error(data, stay) {
$("#status").fadeOut("slow", function() {
2015-06-29 13:19:06 +00:00
$("#status").addClass("error")
$("#status").removeClass("notice")
$("#status").removeClass("success")
2015-06-28 20:58:51 +00:00
if (data) {
if (typeof data == 'string') {
2015-06-29 13:19:06 +00:00
$("#status").html(data);
2015-06-28 20:58:51 +00:00
console.log("error: "+data);
} else {
2015-07-01 00:07:33 +00:00
$("#status").html('error');
2015-06-28 20:58:51 +00:00
console.log("error: "+JSON.stringify(data));
}
} else {
2015-06-29 13:19:06 +00:00
$("#status").html('error');
2015-06-28 20:58:51 +00:00
console.log("error");
}
$("#status").fadeIn("slow");
if (!stay) setTimeout(start, 5000);
});
}
function notice(text) {
$("#status").fadeOut("slow", function() {
2015-06-29 13:19:06 +00:00
$("#status").addClass("notice")
$("#status").removeClass("error")
$("#status").removeClass("success")
2015-06-28 20:58:51 +00:00
if (text) {
2015-06-29 13:19:06 +00:00
$("#status").html(text);
2015-06-28 20:58:51 +00:00
console.log("notice: "+text);
} else {
$("#status").html('');
console.log("notice");
}
$("#status").fadeIn("slow");
});
}
function success(text) {
$("#status").fadeOut("slow", function() {
2015-06-29 13:19:06 +00:00
$("#status").addClass("success")
$("#status").removeClass("error")
$("#status").removeClass("notice")
2015-06-28 20:58:51 +00:00
if (text) {
2015-06-29 13:19:06 +00:00
$("#status").html(text);
2015-06-28 20:58:51 +00:00
console.log("success: "+text);
} else {
$("#status").html('');
console.log("success");
}
$("#status").fadeIn("slow");
});
}
function status(text, msg) {
$("#main").fadeOut("slow", function() {
$("#main").html(text);
success(msg);
2015-06-29 22:34:37 +00:00
$("#main").fadeIn("slow", function() {
$("form input:first-child").focus();
})
2015-06-28 20:58:51 +00:00
});
}
function checkuser(user) {
$("#register").submit(function(event) {
return false;
});
$.post("checknewuser.php", {user: user})
.done(function(res) {
username=JSON.parse(res);
if (!username||username.length<1) username=null;
$("#createuser").prop("disabled", !(username && password));
if (username) {
if (password) success("user is ready to be created");
else notice("user name is available, please set password");
} else notice("user name is not available");
}).fail(function(res) {
username=null;
$("#createuser").prop("disabled", !(username && password));
error(res);
});
}
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 notice("passwords don't match");
}
function checkpartner(user) {
$("#chat").submit(function(event) {
return false;
});
$.post("checknewuser.php", {user: user})
.done(function(res) {
if (JSON.parse(res)) {
notice("receiver does not exist");
$("#send").prop("disabled", true);
return;
}
$("#send").prop("disabled", false);
success("receiver exists");
}).fail(function(res) {
notice("cannot connect to server: "+res);
$("#send").prop("disabled", true);
});
}
function createNewUser(user, pwd) {
status("generate keys");
openpgp.generateKeyPair({
numBits: 1024,
userId: user,
passphrase: pwd
}).then(function(keyPair) {
success("keys generated");
localStorage.pubKey = keyPair.publicKeyArmored;
localStorage.privKey = keyPair.privateKeyArmored;
login();
}).catch(function(e) {
error(e);
});
}
function publicKey() {
if (typeof localStorage.pubKey == 'undefined') return null;
return openpgp.key.readArmored(localStorage.pubKey);
}
function privateKey() {
if (typeof localStorage.privKey == 'undefined') return null;
return openpgp.key.readArmored(localStorage.privKey);
}
function userid() {
if (!publicKey() ||
publicKey().keys.length < 1 ||
publicKey().keys[0].getUserIds().length < 1) return null
return publicKey().keys[0].getUserIds()[0];
}
2015-07-01 00:07:33 +00:00
function clearmessage() {
filecontent = new Array();
$('#preview').empty();
$("#msg").val("");
notice("message cleared");
}
function attachments(files, id) {
if (files) files.forEach(function(file) {
//if (file.content.length<1000000) {
var img = document.createElement('img');
img.src = 'data:'+file.type+';base64,' + file.content;
$(id).append(img);
//}
});
}
2015-06-30 14:09:05 +00:00
function fileupload(evt) {
if (!window.FileReader)
return error("your browser dows not support file upload", true);
2015-07-01 00:07:33 +00:00
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 ...");
var base64 = btoa(evt.target.result);
filecontent.push({type: file.type, content: base64});
if (file.type.match('^image/')) {
var img = document.createElement('img');
img.src = 'data:'+file.type+';base64,' + base64;
$("#preview").append(img);
success('image of type '+file.type+' is ready to be sent');
} else {
success('file of type '+file.type+' is ready to be sent');
}
}
reader.readAsBinaryString(file);
2015-06-30 14:09:05 +00:00
}
}
2015-06-28 20:58:51 +00:00
function setreceiver(name) {
$("#recv").val(name);
checkpartner(name);
$("#msg").focus();
}
2015-07-01 00:07:33 +00:00
var startmsg = 0; // number of last downloaded message
2015-06-28 20:58:51 +00:00
function get() {
2015-06-29 13:19:06 +00:00
var beeped = false;
2015-06-28 20:58:51 +00:00
$.post("get.php", {start: startmsg}).done(function(res) {
var msgs = JSON.parse(res);
if (msgs) {
msgs.forEach(function(e) {
2015-07-01 00:07:33 +00:00
if (startmsg<Number(e.id)) startmsg = Number(e.id);
$.post("pubkey.php", {user: e.user}).done(function(pk) {
2015-06-28 20:58:51 +00:00
var res=JSON.parse(pk);
var key=openpgp.key.readArmored(res);
if (!res||key.err) {
2015-07-01 00:07:33 +00:00
setTimeout(get, 10000);
return error("key of receiver not found", true);
2015-06-28 20:58:51 +00:00
}
2015-07-01 00:07:33 +00:00
var message = openpgp.message.readArmored(e.msg);
var privkey = privateKey().keys[0];
if (privkey.decrypt(password))
openpgp.decryptAndVerifyMessage(privkey, key.keys, message)
.then(function(msg) {
var message = JSON.parse(msg.text);
$("#msgs") // todo: check msg.signatures[0].valid
.prepend('<div id="id'+(e.id)+'" class="msg '+
(e.user==userid()?"me":"other")+
'"><div class="header">'+
'<span class="date">'+
(new Date(1000*Number(e.time))).toLocaleString()+
'</span><span class="sender">'+
'<a href="javascript:void(0)" onclick="setreceiver(this.innerHTML)">'+
e.user+
'</a></span></div>'+
'<div class="text">'+
message.text+
'</div></div><div class="clear"/>');
attachments(message.files, '#id'+e.id+' .text');
$('#id'+e.id).emoticonize();
if (!beeped)
(new Audio("A-Tone-His_Self-1266414414.mp3"))
.play();
beeped = true;
})
.catch(function(e) {
// not for me
});
2015-06-28 20:58:51 +00:00
}).fail(function(e) {
error("get sender's key from server failed", true);
});
});
}
2015-07-01 00:07:33 +00:00
}).fail(function(e) {
error("get messages failed")
});
setTimeout(get, 10000);
2015-06-28 20:58:51 +00:00
}
function sendmessage(recv, txt) {
2015-07-01 00:07:33 +00:00
notice("1/3 preparing message ...");
$("#message").fadeOut("slow");
2015-06-28 20:58:51 +00:00
$.post("pubkey.php", {user: recv}).done(function(pk) {
var res=JSON.parse(pk);
var key=openpgp.key.readArmored(res);
if (!res||key.err) {
2015-07-01 00:07:33 +00:00
$("#message").fadeIn("slow");
2015-06-28 20:58:51 +00:00
error("key of receiver not found", true);
return;
}
var privkey = privateKey().keys[0];
privkey.decrypt(password);
2015-07-01 00:07:33 +00:00
var message = JSON.stringify({text: txt, files: filecontent});
notice("2/3 encrypting message ...");
openpgp.signAndEncryptMessage(key.keys.concat(publicKey().keys), privkey, message)
2015-06-28 20:58:51 +00:00
.then(function(msg) {
2015-07-01 00:07:33 +00:00
notice("3/3 sending message ...");
2015-06-28 20:58:51 +00:00
$.post("send.php", {user: userid(), msg: msg})
.done(function(res) {
if (JSON.parse(res)) {
2015-07-01 00:07:33 +00:00
$("#message").fadeIn("slow");
clearmessage();
2015-06-28 20:58:51 +00:00
success("message sent");
2015-07-01 00:07:33 +00:00
} else {
$("#message").fadeIn("slow");
error("error sending message", true);
}
2015-06-28 20:58:51 +00:00
})
.fail(error);
})
.catch(function(e) {
2015-07-01 00:07:33 +00:00
$("#message").fadeIn("slow");
2015-06-28 20:58:51 +00:00
error("encryption of message failed", true);
});
}).fail(function(e) {
2015-07-01 00:07:33 +00:00
$("#message").fadeIn("slow");
2015-06-28 20:58:51 +00:00
error("get receiver's key from server failed", true);
});
2015-07-01 00:07:33 +00:00
$("#message").fadeIn("slow");
2015-06-28 20:58:51 +00:00
}
function setpw(pwd) {
if (privateKey().keys[0].decrypt(pwd)) {
password = pwd;
chat();
}
}
function getpwd() {
status('<form>'+
2015-06-29 22:34:37 +00:00
' <input placeholder="password for '+userid()+
'" id="pwd" oninput="setpw(this.value)" type="password" />'+
2015-06-28 20:58:51 +00:00
'</form>');
}
function chat() {
if (!password) return getpwd();
$.ajax({url: "chat.html", success: function(res) {
status(res);
setTimeout(get, 2000);
}}).fail(error);
}
function login() {
status("login ...");
$.post("login.php", {user: userid(),
pubkey: localStorage.pubKey},
function(res) {
if (JSON.parse(res)) {
status("logged in ...", "successfully logged in");
chat();
} else {
error("login failed");
}
}).fail(function(e) {
error(e);
});
}
function newuser() {
status("new user ...");
$.ajax({url: "newuser.html", success: function(res) {
status(res);
}}).fail(error);
}
function start() {
try {
status("Starting up ...");
if (!userid()) {
newuser();
} else {
login();
}
} catch (m) {
error(m);
}
}
$(start);