var password = null ;
var username = null ;
function error ( data , stay ) {
$ ( "#status" ) . fadeOut ( "slow" , function ( ) {
$ ( "#status" ) . addClass ( "error" )
$ ( "#status" ) . removeClass ( "notice" )
$ ( "#status" ) . removeClass ( "success" )
if ( data ) {
if ( typeof data == 'string' ) {
$ ( "#status" ) . html ( data ) ;
console . log ( "error: " + data ) ;
} else {
$ ( "#status" ) . html ( '<pre>' + JSON . stringify ( data ) + '</pre>' ) ;
console . log ( "error: " + JSON . stringify ( data ) ) ;
}
} else {
$ ( "#status" ) . html ( 'error' ) ;
console . log ( "error" ) ;
}
$ ( "#status" ) . fadeIn ( "slow" ) ;
if ( ! stay ) setTimeout ( start , 5000 ) ;
} ) ;
}
function notice ( text ) {
$ ( "#status" ) . fadeOut ( "slow" , function ( ) {
$ ( "#status" ) . addClass ( "notice" )
$ ( "#status" ) . removeClass ( "error" )
$ ( "#status" ) . removeClass ( "success" )
if ( text ) {
$ ( "#status" ) . html ( text ) ;
console . log ( "notice: " + text ) ;
} else {
$ ( "#status" ) . html ( '' ) ;
console . log ( "notice" ) ;
}
$ ( "#status" ) . fadeIn ( "slow" ) ;
} ) ;
}
function success ( text ) {
$ ( "#status" ) . fadeOut ( "slow" , function ( ) {
$ ( "#status" ) . addClass ( "success" )
$ ( "#status" ) . removeClass ( "error" )
$ ( "#status" ) . removeClass ( "notice" )
if ( text ) {
$ ( "#status" ) . html ( text ) ;
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 ) ;
$ ( "#main" ) . fadeIn ( "slow" ) ;
} ) ;
}
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 ] ;
}
function setreceiver ( name ) {
$ ( "#recv" ) . val ( name ) ;
checkpartner ( name ) ;
$ ( "#msg" ) . focus ( ) ;
}
var startmsg = 0 ;
function get ( ) {
var beeped = false ;
$ . post ( "get.php" , { start : startmsg } ) . done ( function ( res ) {
var msgs = JSON . parse ( res ) ;
if ( msgs ) {
msgs . forEach ( function ( e ) {
if ( startmsg < Number ( e [ "id" ] ) ) startmsg = Number ( e [ "id" ] ) ;
$ . post ( "pubkey.php" , { user : e [ "user" ] } ) . done ( function ( pk ) {
var res = JSON . parse ( pk ) ;
var key = openpgp . key . readArmored ( res ) ;
if ( ! res || key . err ) {
error ( "key of receiver not found" , true ) ;
} else {
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 ) {
$ ( "#msgs" )
. prepend ( "<tr><td>"
+ e [ "id" ]
+ "</td><td>"
+ ( new Date ( 1000 * Number ( e [ "time" ] ) ) ) . toLocaleString ( )
+ '</td><td><a href="javascript:void(0)" onclick="setreceiver(this.innerHTML)">'
+ e [ "user" ]
+ "</a></td><td>"
+ ( msg . signatures [ 0 ] . valid ? "✔" : "✘" )
+ '</td><td class="msg">'
+ msg . text
+ "</td></tr>" ) ;
if ( ! beeped )
( new Audio ( "A-Tone-His_Self-1266414414.mp3" ) )
. play ( ) ;
beeped = true ;
} ) ;
// .catch(function(e) {
// error("decryption of message failed", true);
// });
}
} ) . fail ( function ( e ) {
error ( "get sender's key from server failed" , true ) ;
} ) ;
} ) ;
}
if ( beeped ) $ ( ".msg" ) . emoticonize ( ) ; // only if new messages added
setTimeout ( get , 10000 ) ;
} ) . fail ( error ) ;
}
function sendmessage ( recv , txt ) {
$ . post ( "pubkey.php" , { user : recv } ) . done ( function ( pk ) {
var res = JSON . parse ( pk ) ;
var key = openpgp . key . readArmored ( res ) ;
if ( ! res || key . err ) {
error ( "key of receiver not found" , true ) ;
return ;
}
var privkey = privateKey ( ) . keys [ 0 ] ;
privkey . decrypt ( password ) ;
openpgp . signAndEncryptMessage ( key . keys . concat ( publicKey ( ) . keys ) , privkey , txt )
. then ( function ( msg ) {
$ . post ( "send.php" , { user : userid ( ) , msg : msg } )
. done ( function ( res ) {
if ( JSON . parse ( res ) ) {
$ ( "#msg" ) . val ( "" ) ;
success ( "message sent" ) ;
} else error ( "error sending message" , true ) ;
} )
. fail ( error ) ;
} )
. catch ( function ( e ) {
error ( "encryption of message failed" , true ) ;
} ) ;
} ) . fail ( function ( e ) {
error ( "get receiver's key from server failed" , true ) ;
} ) ;
}
function setpw ( pwd ) {
if ( privateKey ( ) . keys [ 0 ] . decrypt ( pwd ) ) {
password = pwd ;
chat ( ) ;
}
}
function getpwd ( ) {
status ( '<form>' +
' <label for="pwd">password for ' + userid ( ) + ':</label>' +
' <input id="pwd" oninput="setpw(this.value)" type="password" autofocus/>' +
'</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 ) ;