diff --git a/package.json b/package.json index 358ace0..d5e480f 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,9 @@ "jquery-browserify": "*", "crypto-js": "3.1.2-3", "bitcoinjs-lib": "0.2.0", - "openpgp": "0.6.1" + "openpgp": "0.6.1", + "sjcl": "1.0.1", + "sanitizer" : "0.1.2", + "pretty-date" : "0.2.0" } } diff --git a/src/ninki-api.js b/src/ninki-api.js index 953f718..e0966cf 100644 --- a/src/ninki-api.js +++ b/src/ninki-api.js @@ -46,12 +46,10 @@ API.post = function (url, postData, callback) { function lpost(url, postData, callback) { - //https://ninkip2p.com - var sessionToken = $('#API-Token').val(); - + // $.ajax({ - url: "https://localhost:1111" + url, + url: "https://api.ninkip2p.com:443" + url, type: "POST", data: JSON.stringify(postData), contentType: "application/json; charset=utf-8", @@ -59,14 +57,10 @@ function lpost(url, postData, callback) { headers: { 'api-token': sessionToken }, success: function (data) { - data = sanitizer.sanitize(data); - var jdata = JSON.parse(data); - - if (jdata.error) { return callback(true, jdata.message); } @@ -76,6 +70,10 @@ function lpost(url, postData, callback) { return callback(false, JSON.stringify(jdata)); }, fail: function (data, textStatus) { + + data = sanitizer.sanitize(data); + textStatus = sanitizer.sanitize(textStatus); + return callback(true, { textStatus: textStatus, data: data @@ -83,34 +81,36 @@ function lpost(url, postData, callback) { }, error: function (data) { - console.log(data); + if (data.status == 403) { //session has been lost - } - else if (data.status == 401) { - - // if (!window.cordova) { - // if (chrome) { - // if (chrome.runtime) { - // if (chrome.runtime.reload) { - // chrome.runtime.reload() - // } else { - // location.reload(); - // } - // } else { - // location.reload(); - // } - // //return callback(true, data.statusText); - // } else { - // location.reload(); - // } - // } else { - // - // } + } else if (data.status == 401) { + + if (!window.cordova) { + if (chrome) { + if (chrome.runtime) { + if (chrome.runtime.reload) { + chrome.runtime.reload() + } else { + location.reload(); + } + } else { + location.reload(); + } + //return callback(true, data.statusText); + } else { + location.reload(); + } + } else { + + } } else { + + data.responseText = sanitizer.sanitize(data.responseText); + return callback(true, data.responseText); } @@ -316,6 +316,21 @@ API.getUnconfirmedBalance = function (guid, sharedid, callback) { }); } +//function for increased performance on login +API.getAccountData = function (guid, sharedid, callback) { + var postData = { guid: guid, sharedid: sharedid }; + return lpost("/api/1/u/getaccountdata", postData, function (err, dataStr) { + return callback(err, dataStr); + }); +} + +API.getUserData = function (guid, sharedid, callback) { + var postData = { guid: guid, sharedid: sharedid }; + return lpost("/api/1/u/getuserdata", postData, function (err, dataStr) { + return callback(err, dataStr); + }); +} + //gets the username associated with the wallet API.getNickname = function (guid, sharedid, callback) { @@ -345,9 +360,12 @@ API.getUnspentOutputs = function (guid, sharedid, callback) { var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getunspentoutputs", postData, function (err, response) { - var data1 = response; - var data2 = JSON.parse(data1); - return callback(err, data2.Message); + if (!err) { + var data = JSON.parse(response); + return callback(err, data.Message); + } else { + return callback(err, response); + } }); } @@ -356,17 +374,25 @@ API.getCoinProfile = function (guid, sharedid, callback) { var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getcoinprofile", postData, function (err, response) { - var data = JSON.parse(response); - return callback(err, data); + if (!err) { + var data = JSON.parse(response); + return callback(err, data); + } else { + return callback(err, response); + } }); } -API.getPrice = function (ccy, callback) { +API.getPrice = function (guid, ccy, callback) { - var postData = { ccy: ccy }; - return lpost("/api/1/u/getPrice", postData, function (err, response) { - var data = JSON.parse(response); - return callback(err, data); + var postData = { guid: guid, ccy: ccy }; + return lpost("/api/1/u/getprice", postData, function (err, response) { + if (!err) { + var data = JSON.parse(response); + return callback(err, data); + } else { + return callback(err, response); + } }); } @@ -375,9 +401,12 @@ API.getPendingUserRequests = function (guid, sharedid, callback) { //these are requests made by me to other people var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getpendinguserrequests", postData, function (err, data) { - var friends = JSON.parse(data); - - return callback(err, friends); + if (!err) { + var friends = JSON.parse(data); + return callback(err, friends); + } else { + return callback(err, data); + } }); } @@ -385,8 +414,12 @@ API.getFriendRequests = function (guid, sharedid, callback) { var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getfriendrequests", postData, function (err, dataStr) { - var jdata = JSON.parse(dataStr); - return callback(err, jdata); + if (!err) { + var jdata = JSON.parse(dataStr); + return callback(err, jdata); + } else { + return callback(err, dataStr); + } }); } @@ -394,25 +427,31 @@ API.getUserPacket = function (guid, sharedid, callback) { var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getuserpacket", postData, function (err, dataStr) { - - var jdata = JSON.parse(dataStr); - return callback(err, jdata); + if (!err) { + var jdata = JSON.parse(dataStr); + return callback(err, jdata); + } else { + return callback(err, dataStr); + } }); } API.isNetworkExist = function (guid, sharedid, username, callback) { var postData = { guid: guid, sharedid: sharedid, username: username }; lpost("/api/1/u/doesnetworkexist", postData, function (err, result) { - var exists = JSON.parse(result); - return callback(err, exists); - + if (!err) { + var exists = JSON.parse(result); + return callback(err, exists); + } else { + return callback(err, result); + } }); } API.rejectFriendRequest = function (guid, sharedid, username, callback) { var postData = { guid: guid, sharedid: sharedid, username: username }; - lpost("/api/1/u/rejectfriend", params, function (err, result) { + lpost("/api/1/u/rejectfriend", postData, function (err, result) { return callback(err, result); }); } @@ -423,9 +462,12 @@ API.getTransactionRecords = function (guid, sharedid, callback) { lpost("/api/1/u/gettransactionrecords", postData, function (err, transactions) { - var jtran = JSON.parse(transactions); - - return callback(err, jtran); + if (!err) { + var jtran = JSON.parse(transactions); + return callback(err, jtran); + } else { + return callback(err, transactions); + } }); @@ -437,9 +479,13 @@ API.getInvoiceList = function (guid, sharedid, callback) { lpost("/api/1/u/getinvoicestopay", postData, function (err, invoices) { - var jtran = JSON.parse(invoices); + if (!err) { + var jtran = JSON.parse(invoices); - return callback(err, jtran); + return callback(err, jtran); + } else { + return callback(err, invoices); + } }); @@ -451,9 +497,12 @@ API.getInvoiceByUserList = function (guid, sharedid, callback) { lpost("/api/1/u/getinvoicesbyuser", postData, function (err, invoices) { - var jtran = JSON.parse(invoices); - - return callback(err, jtran); + if (!err) { + var jtran = JSON.parse(invoices); + return callback(err, jtran); + } else { + return callback(err, invoices); + } }); @@ -483,7 +532,7 @@ API.registerDevice = function (guid, deviceName, deviceId, deviceModel, devicePI } API.getDeviceKey = function (guid, devicePIN, regToken, callback) { - var postData = { guid: guid, devicePIN: devicePIN, regToken: regToken}; + var postData = { guid: guid, devicePIN: devicePIN, regToken: regToken }; return lpost("/api/1/u/getdevicekey", postData, function (err, dataStr) { return callback(err, dataStr); }); @@ -516,8 +565,12 @@ API.createDevice = function (guid, sharedid, deviceName, callback) { API.getDevices = function (guid, sharedid, callback) { var postData = { guid: guid, sharedid: sharedid }; return lpost("/api/1/u/getdevices", postData, function (err, dataStr) { - var jdevs = JSON.parse(dataStr); - return callback(err, jdevs); + if (!err) { + var jdevs = JSON.parse(dataStr); + return callback(err, jdevs); + } else { + return callback(err, dataStr); + } }); } diff --git a/src/ninki-engine.js b/src/ninki-engine.js index 6c9258f..e7cba68 100644 --- a/src/ninki-engine.js +++ b/src/ninki-engine.js @@ -31,6 +31,7 @@ function Engine() { this.m_pubKey = ''; this.m_APIToken = ''; this.m_appInitialised = false; + this.m_watchOnly = false; m_this = this; @@ -205,7 +206,7 @@ function Engine() { }; }; - + this.pbkdf2 = pbkdf2; function pbkdf2(password, salt) { var passwordSalt = sjcl.codec.utf8String.toBits(salt); var derivedKey = sjcl.misc.pbkdf2(password, passwordSalt, 1000, 256, hmac); @@ -224,9 +225,90 @@ function Engine() { } + this.getEncHotHash = getEncHotHash; + function getEncHotHash(callback) { + + var isWeb = isBrowser(); + if (isChromeApp()) { + + chrome.storage.local.get("hk" + m_this.m_guid, function (result) { + + if (result["hk" + m_this.m_guid]) { + + var hk = result["hk" + m_this.m_guid]; + + chrome.storage.local.get("hkiv" + m_this.m_guid, function (resultiv) { + + if (resultiv["hkiv" + m_this.m_guid]) { + + var hkiv = resultiv["hkiv" + m_this.m_guid]; + + var data = "{\"enc\":\"" + hk + "\", \"iv\":\"" + hkiv + "\"}"; + return callback(false, data); + } else { + return callback(true, "ErrMissing"); + } + + }); + + } else { + return callback(true, "ErrMissing"); + } + + }); + + } else { + + return callback(true, "ErrInvalid"); + } + + + + } + + + this.restoreHotHash = restoreHotHash; + + function restoreHotHash(hothash, callback) { + + + + //validate against loaded hot public key + var validseed = true; + try { + var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash); + if (m_this.m_walletinfo.hotPub != bipHot.toString()) { + validseed = false; + } + } catch (error) { + + validseed = false; + } + + if (validseed) { + + saveHotHash(hothash, function (err, result) { + + if (!err) { + return callback(false, hothash); + } else { + return callback(err, result); + } + + }); + + } else { + + return callback(true, "ErrSeedInvalid"); + + } + + } + + this.getHotHash = getHotHash; function getHotHash(key, callback) { @@ -507,7 +589,7 @@ function Engine() { } else { - $('#textMessageCreate').html('stretching password...'); + $('#textMessageCreate').text('stretching password...'); setTimeout(function () { @@ -541,7 +623,7 @@ function Engine() { walletInformation.wallet.recPacketIV = recpacket.iv.toString(); //save the wallet to the server - $('#textMessageCreate').html('saving data...'); + $('#textMessageCreate').text('saving data...'); setTimeout(function () { @@ -579,7 +661,8 @@ function Engine() { //TODO add some more param checking //rename this function setTimeout(function () { - $('#textMessageCreate').html('creating account...'); + + $('#textMessageCreate').text('creating account...'); API.getMasterPublicKeyFromUpstreamServer(m_this.m_oguid, function (err, ninkiPubKey, userToken, secret) { if (err) { @@ -604,7 +687,7 @@ function Engine() { var network = "mainnet"; - $('#textMessageCreate').html('getting entropy...'); + $('#textMessageCreate').text('getting entropy...'); setTimeout(function () { //get some random data for the cold key @@ -631,7 +714,7 @@ function Engine() { //var seedtest = bip39.mnemonicToSeed(hotmnem, ''); - $('#textMessageCreate').html('creating cold keys...'); + $('#textMessageCreate').text('creating cold keys...'); setTimeout(function () { @@ -644,7 +727,7 @@ function Engine() { var coldPriv = coldWallet.toString(" "); var coldPub = coldWallet.toString(); - $('#textMessageCreate').html('creating hot keys...'); + $('#textMessageCreate').text('creating hot keys...'); setTimeout(function () { @@ -667,7 +750,7 @@ function Engine() { var hcbkey = Bitcoin.convert.hexToBytes(hckey); var hchkey = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(hcbkey)).toString(); - $('#textMessageCreate').html('creating pgp keys...'); + $('#textMessageCreate').text('creating pgp keys...'); setTimeout(function () { @@ -684,7 +767,7 @@ function Engine() { setTimeout(function () { - $('#textMessageCreate').html('encrypting data...'); + $('#textMessageCreate').text('encrypting data...'); //save the wallet keys and user token in an encrypted packet //AES256 using PBKDF2 on the password and a unique salt @@ -796,35 +879,22 @@ function Engine() { m_this.m_twoFactorOnLogin = true; - getPGPKeys(function (err, result) { - - if (!err) { - getSettings(function (err, result) { + getSettings(function (err, result) { - callback(err, result); + callback(err, result); - }); - } else { - callback(err, result); - } }); + } }); } else { - getPGPKeys(function (err, result) { + getSettings(function (err, result) { - if (!err) { - getSettings(function (err, result) { - - callback(err, result); + callback(err, result); - }); - } else { - callback(err, result); - } }); } @@ -832,10 +902,11 @@ function Engine() { } - this.openWallet2fa = openWallet2fa; - function openWallet2fa(twoFactCode, rememberTwoFactor, callback) { + this.migrateHotKeyFromPacket = migrateHotKeyFromPacket; + function migrateHotKeyFromPacket(twoFactCode, callback) { - API.getWalletFromServer(m_this.m_guid, m_this.m_secret, twoFactCode, rememberTwoFactor, function (err, wallet) { + + API.getWalletFromServer(m_this.m_guid, m_this.m_secret, twoFactCode, false, function (err, wallet) { if (err) { return callback(err, wallet); @@ -847,10 +918,14 @@ function Engine() { return callback(true, "Incorrect password"); } - //if any account still has a hotkey stored in their encrypted packet //then remove it and resave the packet + + // show a notice to the user that their hotkey has been migrated locally + // they should write this down as they will need t to setup their wallet + // on a new PC or if they uninstall the chrome app + if (walletInformation.hotHash != '') { var hotHash = walletInformation.hotHash; @@ -873,6 +948,7 @@ function Engine() { var postData = { twoFactorCode: twoFactCode, guid: m_this.m_guid, sharedid: walletInformation.userToken, accountPacket: packet.toString(), IVA: packet.iv.toString() }; API.post("/api/1/u/migratepacket", postData, function (err, dataStr) { + return callback(false, "ok"); }); @@ -887,6 +963,24 @@ function Engine() { } + }); + + } + + this.openWallet2fa = openWallet2fa; + function openWallet2fa(twoFactCode, rememberTwoFactor, callback) { + + API.getWalletFromServer(m_this.m_guid, m_this.m_secret, twoFactCode, rememberTwoFactor, function (err, wallet) { + + if (err) { + return callback(err, wallet); + } + + try { + var walletInformation = decrypt(wallet.Payload, m_this.m_password, wallet.IV); + } catch (err) { + return callback(true, "Incorrect password"); + } if (m_this.m_migrateBeta12fa) { @@ -928,20 +1022,14 @@ function Engine() { //save secret - getPGPKeys(function (err, result) { + getSettings(function (err, result) { if (!err) { - getSettings(function (err, result) { - if (!err) { - callback(err, wallet); - } else { - callback(err, result); - } - - }); + callback(err, wallet); } else { callback(err, result); } + }); } @@ -954,9 +1042,9 @@ function Engine() { //2. this is the standard login code execution //eventually only this block will be required - walletInformation.hotPriv = ''; - walletInformation.hotHash = ''; - walletInformation.hchkey = ''; + //walletInformation.hotPriv = ''; + //walletInformation.hotHash = ''; + //walletInformation.hchkey = ''; m_this.m_twoFactorOnLogin = wallet.TwoFactorOnLogin; m_this.m_walletinfo = walletInformation; @@ -974,22 +1062,16 @@ function Engine() { //save secret - getPGPKeys(function (err, result) { - + getSettings(function (err, result) { if (!err) { - getSettings(function (err, result) { - if (!err) { - callback(err, wallet); - } else { - callback(err, result); - } - - }); + callback(err, wallet); } else { callback(err, result); } + }); + } }); @@ -1089,26 +1171,20 @@ function Engine() { //alert and remind the user to write down their hotkeys - walletInformation.hotPriv = ''; - walletInformation.hotHash = ''; - walletInformation.hchkey = ''; + //walletInformation.hotPriv = ''; + //walletInformation.hotHash = ''; + //walletInformation.hchkey = ''; m_this.m_twoFactorOnLogin = wallet.TwoFactorOnLogin; m_this.m_walletinfo = walletInformation; m_this.m_sharedid = walletInformation.userToken; - getPGPKeys(function (err, result) { - if (!err) { - getSettings(function (err, result) { + getSettings(function (err, result) { - callback(err, result); + callback(err, result); - }); - } else { - callback(err, result); - } }); @@ -1179,19 +1255,14 @@ function Engine() { m_this.m_walletinfo = walletInformation; m_this.m_sharedid = walletInformation.userToken; - getPGPKeys(function (err, result) { - if (!err) { - getSettings(function (err, result) { + getSettings(function (err, result) { - callback(err, result); + callback(err, result); - }); - } else { - callback(err, result); - } }); + }); }); @@ -1245,52 +1316,56 @@ function Engine() { } - function getSettings(callback) { - //nickname in packet? - getNickname(function (err, nickname) { - m_this.m_nickname = nickname; + function getSettings(callback) { + //nickname in packet? + getUserData(function (err, data) { - getUserProfile(function (err, result) { + if (!err) { - var userProfile = JSON.parse(result); + data = JSON.parse(data); - m_this.m_profileImage = userProfile.ProfileImage; - m_this.m_statusText = userProfile.Status; - m_this.m_invoiceTax = userProfile.Tax; + m_this.m_nickname = data.Nickname; - getFingerPrint(function (err, fingerprint) { - //display the secret on a div + m_this.m_profileImage = data.ProfileImage; + m_this.m_statusText = data.Status; + m_this.m_invoiceTax = data.Tax; - var bip39 = new BIP39(); // 'en' is the default language - var fingermnem = bip39.entropyToMnemonic(fingerprint); - m_this.m_fingerprint = fingermnem; - getAccountSettings(function (err, response) { - if (err) { + //display the secret on a div + var rsaKeyPair = decrypt(data.Payload, m_this.m_password, data.IV); - } else { + var publicKeys = openpgp.key.readArmored(rsaKeyPair.RSAPub); + var privKeys = openpgp.key.readArmored(rsaKeyPair.RSAPriv); - var settingsObject = JSON.parse(response); - m_this.m_settings = settingsObject; - m_this.m_validate = !settingsObject.EmailVerified; - } + m_this.m_privKey = privKeys.keys[0]; + m_this.m_pubKey = publicKeys.keys[0]; - return callback(err, "ok"); + if (m_this.m_privKey.decrypt(m_this.m_sharedid)) { + var bip39 = new BIP39(); // 'en' is the default language + var fingermnem = bip39.entropyToMnemonic(m_this.m_pubKey.primaryKey.fingerprint); - }); + m_this.m_fingerprint = fingermnem; + m_this.m_settings = data.Settings; + m_this.m_validate = !data.Settings.EmailVerified; - }); + return callback(err, "ok"); + } else { + callback(true, 'failed'); + } + } else { - }); + return callback(err, data); + } }); } + function deriveChild(path, hdwallet) { var e = path.split('/'); @@ -1493,23 +1568,26 @@ function Engine() { //setup handles to report back progress var progressel = ''; var messel = ''; + var progresselnum = '' if (sendType == 'friend') { messel = '#textMessageSend'; progressel = '#sendfriendprogstatus'; + progresselnum = '#sendstdprognum'; } if (sendType == 'standard') { messel = '#textMessageSendStd'; progressel = '#sendstdprogstatus'; + progresselnum = '#sendstdprognum'; } if (sendType == 'invoice') { messel = '#textMessageSendInv'; progressel = '#sendinvprogstatus'; + progresselnum = '#sendstdprognum'; } - var minersFee = 10000; //?? amount = Math.round(amount); @@ -1540,313 +1618,365 @@ function Engine() { var pdata = { guid: m_this.m_guid, sharedid: m_this.m_sharedid }; - $(messel).html('Getting unspent outputs...'); + $(messel).text('Getting unspent outputs...'); API.post("/api/1/u/getunspentoutputs", pdata, function (err, outputs) { - var outputs = JSON.parse(outputs); - var outputsToSpend = []; - var amountsToSend = []; - var addressToSend = []; - var userHotPrivKeys = []; - var nodeLevels = []; - var publicKeys = []; - var packet = { addressToSend: addressToSend, amountsToSend: amountsToSend, outputsToSpend: outputsToSpend, userHotPrivKeys: userHotPrivKeys, guid: m_this.m_guid, paths: nodeLevels, publicKeys: publicKeys }; + if (!err) { - //get outputs to spend, calculate change amount minus miners fee + var outputs = JSON.parse(outputs); + var outputsToSpend = []; + var amountsToSend = []; + var addressToSend = []; + var userHotPrivKeys = []; - $(progressel).width('20%'); + var nodeLevels = []; + var publicKeys = []; + var packet = { addressToSend: addressToSend, amountsToSend: amountsToSend, outputsToSpend: outputsToSpend, userHotPrivKeys: userHotPrivKeys, guid: m_this.m_guid, paths: nodeLevels, publicKeys: publicKeys }; - //iterate the unspent outputs and select the first n that equal the amount to spend - //TO DO: do this before doing any key derivation - var amountSoFar = 0; - for (var i = 0; i < outputs.length; i++) { + //get outputs to spend, calculate change amount minus miners fee - var pitem = outputs[i]; - var pout = { transactionId: pitem.TransactionId, outputIndex: pitem.OutputIndex, amount: pitem.Amount, address: pitem.Address } + $(progressel).width('20%'); + if ($(progresselnum)) { + $(progresselnum).text('20%'); + } - nodeLevels.push(pitem.NodeLevel); + //iterate the unspent outputs and select the first n that equal the amount to spend + //TO DO: do this before doing any key derivation + var amountSoFar = 0; + for (var i = 0; i < outputs.length; i++) { - outputsToSpend.push(pout); + var pitem = outputs[i]; + var pout = { transactionId: pitem.TransactionId, outputIndex: pitem.OutputIndex, amount: pitem.Amount, address: pitem.Address } - //derive the private key to use for signing - userHotPrivKeys.push(deriveChild(pitem.NodeLevel, bipHot).priv); + nodeLevels.push(pitem.NodeLevel); - //derive the public keys to use for script generation - //this could be cached on the server as no privacy or hand-off issue that I can see + outputsToSpend.push(pout); - var dbipHotPub = ""; - var dbipColdPub = ""; - var dbipNinkiPub = ""; + //derive the private key to use for signing + userHotPrivKeys.push(deriveChild(pitem.NodeLevel, bipHot).priv); - if (pitem.PK1.length > 0) { + //derive the public keys to use for script generation + //this could be cached on the server as no privacy or hand-off issue that I can see - dbipHotPub = Bitcoin.convert.hexToBytes(pitem.PK1); - dbipColdPub = Bitcoin.convert.hexToBytes(pitem.PK2); - dbipNinkiPub = Bitcoin.convert.hexToBytes(pitem.PK3); + var dbipHotPub = ""; + var dbipColdPub = ""; + var dbipNinkiPub = ""; - } else { + if (pitem.PK1.length > 0) { + + dbipHotPub = Bitcoin.convert.hexToBytes(pitem.PK1); + dbipColdPub = Bitcoin.convert.hexToBytes(pitem.PK2); + dbipNinkiPub = Bitcoin.convert.hexToBytes(pitem.PK3); - dbipHotPub = deriveChild(pitem.NodeLevel, bipHotPub).pub.toBytes(); - dbipColdPub = deriveChild(pitem.NodeLevel, bipCold).pub.toBytes(); - dbipNinkiPub = deriveChild(pitem.NodeLevel, bipNinki).pub.toBytes(); + } else { + + dbipHotPub = deriveChild(pitem.NodeLevel, bipHotPub).pub.toBytes(); + dbipColdPub = deriveChild(pitem.NodeLevel, bipCold).pub.toBytes(); + dbipNinkiPub = deriveChild(pitem.NodeLevel, bipNinki).pub.toBytes(); + + } + + publicKeys.push([dbipHotPub, dbipColdPub, dbipNinkiPub]); + + //add the amount + amountSoFar += pitem.Amount; + + if ((amountSoFar - amount) >= minersFee) { + break; + } } - publicKeys.push([dbipHotPub, dbipColdPub, dbipNinkiPub]); + amountsToSend.push(amount); - //add the amount - amountSoFar += pitem.Amount; + //now create the change + //again move this before the key derivation + var changeAmount = amountSoFar - (amount + minersFee); - if ((amountSoFar - amount) >= minersFee) { - break; + if (changeAmount < 0) { + //this message needs to be handled carefully + //as the wallet will most likely have pending confirmations + //rather than insufficent funds + return callback(true, "ErrInsufficientFunds"); } - } + if (changeAmount > 0) { + amountsToSend.push(changeAmount); + } - amountsToSend.push(amount); + //create a new address for my change to be sent back to me - //now create the change - //again move this before the key derivation - var changeAmount = amountSoFar - (amount + minersFee); + //if we are sending money to a contact or paying an invoice + //we need to derive addresses on their behalf - if (changeAmount < 0) { - //this message needs to be handled carefully - //as the wallet will most likely have pending confirmations - //rather than insufficent funds - return callback(true, "ErrInsufficientFunds"); - } + if (sendType == 'friend' || sendType == 'invoice') { + var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, amount: amount }; - if (changeAmount > 0) { - amountsToSend.push(changeAmount); - } + //generate the address for the contact + //this must be done on the client + $(messel).text('Creating address...'); + createAddressForFriend(friendUserName, function (err, address) { - //create a new address for my change to be sent back to me + if (!err) { - //if we are sending money to a contact or paying an invoice - //we need to derive addresses on their behalf + $(progressel).width('40%'); + if ($(progresselnum)) { + $(progresselnum).text('40%'); + } - if (sendType == 'friend' || sendType == 'invoice') { - var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, amount: amount }; + addressToSend.push(address); - //generate the address for the contact - //this must be done on the client - $(messel).html('Creating address...'); - createAddressForFriend(friendUserName, function (err, address) { + //create the change address, this must be done on the client + $(messel).text('Creating change address...'); - if (!err) { + createAddress('m/0/1', changeAmount, function (err, changeaddress) { - $(progressel).width('40%'); - addressToSend.push(address); + if (!err) { + $(progressel).width('60%'); + if ($(progresselnum)) { + $(progresselnum).text('60%'); + } - //create the change address, this must be done on the client - $(messel).html('Creating change address...'); - createAddress('m/0/1', changeAmount, function (err, changeaddress) { + if (changeAmount > 0) { + addressToSend.push(changeaddress); + } + //now get the transaction data + $(messel).text('Creating transaction...'); + aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) { - if (!err) { - $(progressel).width('60%'); - if (changeAmount > 0) { - addressToSend.push(changeaddress); - } - //now get the transaction data - $(messel).html('Creating transaction...'); - aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) { + $(progressel).width('80%'); + if ($(progresselnum)) { + $(progresselnum).text('80%'); + } - $(progressel).width('80%'); - var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels } - var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: friendUserName }; - $(messel).html('Counter-signing transaction...'); - //send the transaction to the service for countersigning and broadcast to the network + var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels } + var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: friendUserName }; + $(messel).text('Counter-signing transaction...'); + //send the transaction to the service for countersigning and broadcast to the network - //requires 2 factor authentication - API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) { + //requires 2 factor authentication - if (!err) { - $(progressel).width('100%'); - $(messel).html('Transaction broadcast...'); - //error handling? - - //we have a transaction id so lets make a note of the transaction in the database - var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, transactionid: result, address: address, amount: amount }; - API.post("/api/1/u/createtransactionrecord", params, function (err, result) { - return callback(err, params.transactionid); - }); - } else { + API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) { - //handle error messages returned from the server - if (result == 'ErrSingleTransactionLimit') { + if (!err) { $(progressel).width('100%'); - $(messel).html('Transaction Failed: Single limit exceeded'); - return callback(err, result); - } + if ($(progresselnum)) { + $(progresselnum).text('100%'); + } - if (result == 'ErrDailyTransactionLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Daily limit exceeded'); - return callback(err, result); - } - if (result == 'ErrTransactionsPerDayLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Daily number limit exceeded'); - return callback(err, result); - } + $(messel).text('Transaction broadcast...'); + //error handling? - if (result == 'ErrTransactionsPerHourLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Hourly number limit exceeded'); - return callback(err, result); - } + //we have a transaction id so lets make a note of the transaction in the database + var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, transactionid: result, address: address, amount: amount }; + API.post("/api/1/u/createtransactionrecord", params, function (err, result) { + return callback(err, params.transactionid); + }); + } else { - if (result == 'ErrInvalidRequest') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Invalid request'); - return callback(err, result); - } + //handle error messages returned from the server + if (result == 'ErrSingleTransactionLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Single limit exceeded'); + return callback(err, result); + } - if (result == 'ErrLocked') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Account is unavailable'); - return callback(err, result); - } + if (result == 'ErrDailyTransactionLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Daily limit exceeded'); + return callback(err, result); + } + if (result == 'ErrTransactionsPerDayLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Daily number limit exceeded'); + return callback(err, result); + } - if (result == 'ErrBroadcastFailed') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Not accepted'); - return callback(err, result); - } + if (result == 'ErrTransactionsPerHourLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Hourly number limit exceeded'); + return callback(err, result); + } - if (result == "Invalid two factor code") { - $(progressel).width('100%'); - $(messel).html("Invalid two factor code"); - return callback(err, result); - } + if (result == 'ErrInvalidRequest') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Invalid request'); + return callback(err, result); + } - } + if (result == 'ErrLocked') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Account is unavailable'); + return callback(err, result); + } + + + if (result == 'ErrBroadcastFailed') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Not accepted'); + return callback(err, result); + } + + if (result == "Invalid two factor code") { + $(progressel).width('100%'); + $(messel).text("Invalid two factor code"); + return callback(err, result); + } + + } + }); }); - }); - } else { - //create address error - if (changeaddress == 'ErrInvalidRequest') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Invalid request'); - return callback(err, changeaddress); + } else { + //create address error + if (changeaddress == 'ErrInvalidRequest') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Invalid request'); + return callback(err, changeaddress); + } } + }); + } else { + + if (address == 'ErrInvalidRequest') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Invalid request'); + return callback(err, address); } - }); - } else { - if (address == 'ErrInvalidRequest') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Invalid request'); - return callback(err, address); } + }); + } else { - } - }); - } else { + $(messel).text('Creating address...'); - $(messel).html('Creating address...'); + addressToSend.push(addressTo); - addressToSend.push(addressTo); + //create the change address, this must be done on the client + createAddress('m/0/1', changeAmount, function (err, changeaddress) { - //create the change address, this must be done on the client - createAddress('m/0/1', changeAmount, function (err, changeaddress) { + if (!err) { - if (!err) { + $(progressel).width('40%'); - $(progressel).width('40%'); - if (changeAmount > 0) { - addressToSend.push(changeaddress); - } + if ($(progresselnum)) { + $(progresselnum).text('40%'); + } - //now get the transaction - $(messel).html('Creating transaction...'); - aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) { - $(progressel).width('60%'); - var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels } - var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: '' }; - $(messel).html('Counter-signing transaction...'); - API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) { + if (changeAmount > 0) { + addressToSend.push(changeaddress); + } - $(progressel).width('80%'); - if (!err) { - $(progressel).width('100%'); - $(messel).html('Transaction broadcast...'); + //now get the transaction + $(messel).text('Creating transaction...'); + aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) { + $(progressel).width('60%'); + if ($(progresselnum)) { + $(progresselnum).text('60%'); + } - //we have a transaction id so lets make a note of the transaction in the database - var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: 'External', transactionid: result, address: addressTo, amount: amount }; - API.post("/api/1/u/createtransactionrecord", params, function (err, result) { - return callback(err, result); - }); - } else { - if (result == 'ErrSingleTransactionLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Single limit exceeded'); - return callback(err, result); - } + var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels } + var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: '' }; + $(messel).text('Counter-signing transaction...'); + API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) { - if (result == 'ErrDailyTransactionLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Daily limit exceeded'); - return callback(err, result); - } + $(progressel).width('80%'); - if (result == 'ErrTransactionsPerDayLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Daily number limit exceeded'); - return callback(err, result); + if ($(progresselnum)) { + $(progresselnum).text('80%'); } - if (result == 'ErrTransactionsPerHourLimit') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Hourly number limit exceeded'); - return callback(err, result); - } - if (result == 'ErrInvalidRequest') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Invalid request'); - return callback(err, result); - } + if (!err) { - if (result == 'ErrBroadcastFailed') { + if ($(progresselnum)) { + $(progresselnum).text('100%'); + } $(progressel).width('100%'); - $(messel).html('Transaction Failed: Not accepted'); - return callback(err, result); - } + $(messel).text('Transaction broadcast...'); - if (result == "Invalid two factor code") { - $(progressel).width('100%'); - $(messel).html("Invalid two factor code"); - return callback(err, result); - } + //we have a transaction id so lets make a note of the transaction in the database + var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: 'External', transactionid: result, address: addressTo, amount: amount }; + API.post("/api/1/u/createtransactionrecord", params, function (err, result) { + return callback(err, result); + }); + } else { + if (result == 'ErrSingleTransactionLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Single limit exceeded'); + return callback(err, result); + } + + if (result == 'ErrDailyTransactionLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Daily limit exceeded'); + return callback(err, result); + } - } + if (result == 'ErrTransactionsPerDayLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Daily number limit exceeded'); + return callback(err, result); + } + + if (result == 'ErrTransactionsPerHourLimit') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Hourly number limit exceeded'); + return callback(err, result); + } + + if (result == 'ErrInvalidRequest') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Invalid request'); + return callback(err, result); + } + + + if (result == 'ErrBroadcastFailed') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Not accepted'); + return callback(err, result); + } + + if (result == "Invalid two factor code") { + $(progressel).width('100%'); + $(messel).text("Invalid two factor code"); + return callback(err, result); + } + + + } + }); }); - }); - } else { + } else { + + //create address error + if (changeaddress == 'ErrInvalidRequest') { + $(progressel).width('100%'); + $(messel).text('Transaction Failed: Invalid request'); + return callback(err, changeaddress); + } - //create address error - if (changeaddress == 'ErrInvalidRequest') { - $(progressel).width('100%'); - $(messel).html('Transaction Failed: Invalid request'); - return callback(err, changeaddress); } + }); + } + + } else { + + return callback(err, outputs); - } - }); } }); @@ -1926,62 +2056,70 @@ function Engine() { API.post("/api/1/u/getfriendpacket", postData, function (err, packet) { - //get the packet from friend containing the public key set to - //be used for address generation and decrypt - - var msg = openpgp.message.readArmored(packet); - var decrypted = openpgp.decryptAndVerifyMessage(m_this.m_privKey, [m_this.m_pubKey], msg); - - var pubkeys = JSON.parse(sanitizer.sanitize(decrypted.text)); - //var pubkeys = decrypt(packet, password, params.oguid); - //only allow address to be created if the packet has been validated - if (pubkeys.validated) { - //get the next leaf on the contacts address space node assigned to this user - API.post("/api/1/u/getnextleafforfriend", postData, function (err, leaf) { - - //derive the public keys - var path = 'm/' + leaf; - - var bipHot = Bitcoin.HDWallet.fromBase58(pubkeys.hotPub); - var bipCold = Bitcoin.HDWallet.fromBase58(pubkeys.coldPub); - var bipNinki = Bitcoin.HDWallet.fromBase58(pubkeys.ninkiPub); - - var hotKey = deriveChild(path, bipHot); - var coldKey = deriveChild(path, bipCold); - var ninkiKey = deriveChild(path, bipNinki); - - //now create the multisig address - var script = [0x52]; - script.push(33); - script = script.concat(hotKey.pub.toBytes()); - script.push(33); - script = script.concat(coldKey.pub.toBytes()); - script.push(33); - script = script.concat(ninkiKey.pub.toBytes()); - script.push(0x53); - script.push(0xae); - var address = multiSig(script); - - //register the address with the server - var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, address: address, leaf: leaf, pk1: hotKey.pub.toString(), pk2: coldKey.pub.toString(), pk3: ninkiKey.pub.toString() }; - API.post("/api/1/u/createaddressforfriend", postData, function (err, result) { + if (!err) { - if (!err) { - return callback(err, address); - } else { - return callback(err, result); - } + //get the packet from friend containing the public key set to + //be used for address generation and decrypt + + var msg = openpgp.message.readArmored(packet); + var decrypted = openpgp.decryptAndVerifyMessage(m_this.m_privKey, [m_this.m_pubKey], msg); + + var pubkeys = JSON.parse(sanitizer.sanitize(decrypted.text)); + //var pubkeys = decrypt(packet, password, params.oguid); + //only allow address to be created if the packet has been validated + if (pubkeys.validated) { + //get the next leaf on the contacts address space node assigned to this user + API.post("/api/1/u/getnextleafforfriend", postData, function (err, leaf) { + + //derive the public keys + var path = 'm/' + leaf; + + var bipHot = Bitcoin.HDWallet.fromBase58(pubkeys.hotPub); + var bipCold = Bitcoin.HDWallet.fromBase58(pubkeys.coldPub); + var bipNinki = Bitcoin.HDWallet.fromBase58(pubkeys.ninkiPub); + + var hotKey = deriveChild(path, bipHot); + var coldKey = deriveChild(path, bipCold); + var ninkiKey = deriveChild(path, bipNinki); + + //now create the multisig address + var script = [0x52]; + script.push(33); + script = script.concat(hotKey.pub.toBytes()); + script.push(33); + script = script.concat(coldKey.pub.toBytes()); + script.push(33); + script = script.concat(ninkiKey.pub.toBytes()); + script.push(0x53); + script.push(0xae); + var address = multiSig(script); + + //register the address with the server + var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, address: address, leaf: leaf, pk1: hotKey.pub.toString(), pk2: coldKey.pub.toString(), pk3: ninkiKey.pub.toString() }; + API.post("/api/1/u/createaddressforfriend", postData, function (err, result) { + + if (!err) { + return callback(err, address); + } else { + return callback(err, result); + } + + }); + + //now update the address to the server }); + } else { - //now update the address to the server + //something very bad has happened + //attempting to derive an address for a non validated contact + return callback(true, "ErrInvalid"); + } - }); } else { - //something very bad has happened - //attempting to derive an address for a non validated contact return callback(true, "ErrInvalid"); + } }); @@ -2067,8 +2205,12 @@ function Engine() { function getUserNetwork(callback) { var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid }; API.post("/api/1/u/getusernetwork", postData, function (err, data) { - var friends = JSON.parse(data); - return callback(err, friends); + if (!err) { + var friends = JSON.parse(data); + return callback(err, friends); + } else { + return callback(err, data); + } }); } @@ -2079,10 +2221,12 @@ function Engine() { var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username }; return API.post("/api/1/u/getfriend", postData, function (err, data) { - - var friend = JSON.parse(data); - - return callback(err, friend); + if (!err) { + var friend = JSON.parse(data); + return callback(err, friend); + } else { + return callback(err, data); + } }); } @@ -2096,7 +2240,7 @@ function Engine() { var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username }; if ($(uimessage)) { - $(uimessage).html('Assigning node...'); + $(uimessage).text('Assigning node...'); } API.post("/api/1/u/getnextnodeforfriend", postData, function (err, node) { @@ -2113,31 +2257,31 @@ function Engine() { var hotKey = deriveChild(node, bipHot).toString(); if ($(uimessage)) { - $(uimessage).html('Deriving address.'); + $(uimessage).text('Deriving address.'); } setTimeout(function () { var coldKey = deriveChild(node, bipCold).toString(); if ($(uimessage)) { - $(uimessage).html('Deriving address..'); + $(uimessage).text('Deriving address..'); } setTimeout(function () { var ninkiKey = deriveChild(node, bipNinki).toString(); if ($(uimessage)) { - $(uimessage).html('Deriving address...'); + $(uimessage).text('Deriving address...'); } //get the friends public RSA key var rsaKey = ''; - $(uimessage).html('Get PGP keys...'); + $(uimessage).text('Get PGP keys...'); API.post("/api/1/u/getrsakey", postData, function (err, rsaKey) { var publicKeys = openpgp.key.readArmored(rsaKey); if ($(uimessage)) { - $(uimessage).html('Encrypting data...'); + $(uimessage).text('Encrypting data...'); } var pubKey = publicKeys.keys[0]; @@ -2194,7 +2338,7 @@ function Engine() { var isValid = decrypted.signatures[0].valid; if (isValid) { - + var keys = sanitizer.sanitize(decrypted.text); var key1 = keys.substring(0, 111); @@ -2251,45 +2395,51 @@ function Engine() { //there was no easy way to change this password in the library so i opted to go with a fixed password //instead of a blank one + if (!err) { - var msg = openpgp.message.readArmored(packet); - var decrypted = openpgp.decryptAndVerifyMessage(m_this.m_privKey, [m_this.m_pubKey], msg); + var msg = openpgp.message.readArmored(packet); + var decrypted = openpgp.decryptAndVerifyMessage(m_this.m_privKey, [m_this.m_pubKey], msg); - var isValid = decrypted.signatures[0].valid; - if (isValid) { + var isValid = decrypted.signatures[0].valid; + if (isValid) { - var payload = JSON.parse(sanitizer.sanitize(decrypted.text)); + var payload = JSON.parse(sanitizer.sanitize(decrypted.text)); - var publicKeysUsed = openpgp.key.readArmored(payload.rsaKey); - var pubKeyUsed = publicKeysUsed.keys[0]; + var publicKeysUsed = openpgp.key.readArmored(payload.rsaKey); + var pubKeyUsed = publicKeysUsed.keys[0]; - if (code == pubKeyUsed.primaryKey.fingerprint) { + if (code == pubKeyUsed.primaryKey.fingerprint) { - var reencrypt = { - hotPub: payload.hotPub, - coldPub: payload.coldPub, - ninkiPub: payload.ninkiPub, - rsaKey: payload.rsaKey, - validated: true - }; + var reencrypt = { + hotPub: payload.hotPub, + coldPub: payload.coldPub, + ninkiPub: payload.ninkiPub, + rsaKey: payload.rsaKey, + validated: true + }; - var encryptedPayload = openpgp.signAndEncryptMessage([m_this.m_pubKey], m_this.m_privKey, JSON.stringify(reencrypt)); + var encryptedPayload = openpgp.signAndEncryptMessage([m_this.m_pubKey], m_this.m_privKey, JSON.stringify(reencrypt)); - postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, packet: encryptedPayload, validationHash: code }; + postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, packet: encryptedPayload, validationHash: code }; - API.post("/api/1/u/updatefriend", postData, function (err, result) { + API.post("/api/1/u/updatefriend", postData, function (err, result) { - return callback(err, result); + return callback(err, result); - }); + }); - return callback(err, true); - } else { - return callback(err, false); + } else { + + return callback(err, false); + + } } + } else { + + return callback(err, result); } @@ -2394,7 +2544,7 @@ function Engine() { var isValid = decrypted.signatures[0].valid; if (isValid) { - + var json = JSON.parse(sanitizer.sanitize(decrypted.text)); //remove any xss data @@ -2420,7 +2570,6 @@ function Engine() { var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, - twoFactorOnLogin: true, twoFactorCode: twoFactorCode, verifyToken: verifyToken }; @@ -2458,7 +2607,6 @@ function Engine() { var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, - twoFactorOnLogin: true, twoFactorCode: twoFactorCode, verifyToken: '' }; @@ -2540,7 +2688,7 @@ function Engine() { getHotHash("", function (err, hothash) { $(progbar).width('40%'); - $(progmess).html('Securing password...'); + $(progmess).text('Securing password...'); setTimeout(function () { //if password reset do not pbkdf the password @@ -2549,10 +2697,10 @@ function Engine() { //get the two packets $(progbar).width('40%'); - $(progmess).html('Getting packets...'); + $(progmess).text('Getting packets...'); // $("#chngpwdprogbar").width('50%'); - //$("#chngpwdprogmess").html('Decrypting account packet...'); + //$("#chngpwdprogmess").text('Decrypting account packet...'); //decrypt with the old password var decryptedWithOld = true; var decryptedPayload = ''; @@ -2565,7 +2713,7 @@ function Engine() { if (decryptedWithOld) { $(progbar).width('80%'); - $(progmess).html('Securing new password...'); + $(progmess).text('Securing new password...'); API.getUserPacket(m_this.m_guid, m_this.m_sharedid, function (err, encpacket) { var decryptedUsrWithOld = true; @@ -2587,151 +2735,159 @@ function Engine() { }, function (err, response) { - //decrypt packet - var decryptedVerWithOld = true; - var jpacket = JSON.parse(response); - var veripacket = ''; - try { - veripacket = decryptNp(jpacket.packet, m_this.m_password, jpacket.IV); - } - catch (verror) { - decryptedVerWithOld = false; - } + if (!err) { + //decrypt packet + var decryptedVerWithOld = true; + var jpacket = JSON.parse(response); + var veripacket = ''; + try { + veripacket = decryptNp(jpacket.packet, m_this.m_password, jpacket.IV); + } + catch (verror) { + decryptedVerWithOld = false; + } - if (decryptedVerWithOld) { - setTimeout(function () { + if (decryptedVerWithOld) { + setTimeout(function () { - newpassword = pbkdf2(newpassword, m_this.m_oguid); + newpassword = pbkdf2(newpassword, m_this.m_oguid); - $(progbar).width('80%'); - $(progmess).html('Encrypting account packet...'); - var newpayloadsuccess = true; - var newpayload = ''; - var newusrpayload = ''; - var newveripacket = ''; - var newpasspacket = ''; - var newAIV = ''; - var newUIV = ''; - var newRIV = ''; - var newPIV = '' - try { + $(progbar).width('80%'); + $(progmess).text('Encrypting account packet...'); - newpayload = encrypt(decryptedPayload, newpassword); - newusrpayload = encrypt(rsaKeyPair, newpassword); - newveripacket = encryptNp(veripacket, newpassword); + var newpayloadsuccess = true; + var newpayload = ''; + var newusrpayload = ''; + var newveripacket = ''; + var newpasspacket = ''; + var newAIV = ''; + var newUIV = ''; + var newRIV = ''; + var newPIV = '' + try { - if (decryptedPayload.hckey) { - newpasspacket = encryptNp(newpassword, decryptedPayload.hckey); - } + newpayload = encrypt(decryptedPayload, newpassword); + newusrpayload = encrypt(rsaKeyPair, newpassword); + newveripacket = encryptNp(veripacket, newpassword); + + if (decryptedPayload.hckey) { + newpasspacket = encryptNp(newpassword, decryptedPayload.hckey); + } - newAIV = newpayload.iv.toString(); - newUIV = newusrpayload.iv.toString(); - newRIV = newveripacket.iv.toString(); + newAIV = newpayload.iv.toString(); + newUIV = newusrpayload.iv.toString(); + newRIV = newveripacket.iv.toString(); - if (decryptedPayload.hckey) { - newPIV = newpasspacket.iv.toString(); + if (decryptedPayload.hckey) { + newPIV = newpasspacket.iv.toString(); + } + + } catch (err) { + newpayloadsuccess = false; } - } catch (err) { - newpayloadsuccess = false; - } + if (newpayloadsuccess) { - if (newpayloadsuccess) { + //$("#chngpwdprogbar").width('90%'); + //$("#chngpwdprogmess").text('Encrypting user packet...'); - //$("#chngpwdprogbar").width('90%'); - //$("#chngpwdprogmess").html('Encrypting user packet...'); + //test decryption - then update + var testpayload = ''; + var testnewusrpayload = ''; + var testveripacket = ''; + var testpasspacket = ''; + var testsuccess = true; + try { - //test decryption - then update - var testpayload = ''; - var testnewusrpayload = ''; - var testveripacket = ''; - var testpasspacket = ''; - var testsuccess = true; - try { + testpayload = decrypt(newpayload.toString(), newpassword, newAIV); + testnewusrpayload = decrypt(newusrpayload.toString(), newpassword, newUIV); + testveripacket = decryptNp(newveripacket.toString(), newpassword, newRIV); - testpayload = decrypt(newpayload.toString(), newpassword, newAIV); - testnewusrpayload = decrypt(newusrpayload.toString(), newpassword, newUIV); - testveripacket = decryptNp(newveripacket.toString(), newpassword, newRIV); + if (decryptedPayload.hckey) { + testpasspacket = decryptNp(newpasspacket.toString(), decryptedPayload.hckey, newPIV) + } - if (decryptedPayload.hckey) { - testpasspacket = decryptNp(newpasspacket.toString(), decryptedPayload.hckey, newPIV) + } catch (err) { + testsuccess = false; } - } catch (err) { - testsuccess = false; - } + if (testsuccess) { - if (testsuccess) { + //save to the server + $(progbar).width('95%'); + $(progmess).text('Saving...'); - //save to the server - $(progbar).width('95%'); - $(progmess).html('Saving...'); + //TO DO: + //add in the re-encryption of the verification + //packet - //TO DO: - //add in the re-encryption of the verification - //packet + //if reset password then provide signed message and call reset function - //if reset password then provide signed message and call reset function + //need to add two factor here + //so 1. add two factor + //2. add way to save only the main packet - //need to add two factor here - //so 1. add two factor - //2. add way to save only the main packet + var postData = { twoFactorCode: twoFactorCode, guid: m_this.m_guid, sharedid: m_this.m_sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV }; + API.post("/api/1/u/updatepackets", postData, function (err, dataStr) { + if (err) { + callback(true, "Error: Password not changed"); + } else { - var postData = { twoFactorCode: twoFactorCode, guid: m_this.m_guid, sharedid: m_this.m_sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV }; - API.post("/api/1/u/updatepackets", postData, function (err, dataStr) { - if (err) { - callback(true, "Error: Password not changed"); - } else { + if (dataStr == "ok") { - if (dataStr == "ok") { + m_this.m_password = newpassword; - m_this.m_password = newpassword; + //if something goes wrong here + //the worst case scenario is the + //user has to reenter their hot key - //if something goes wrong here - //the worst case scenario is the - //user has to reenter their hot key + saveHotHash(hothash, function (err, result) { - saveHotHash(hothash, function (err, result) { + callback(false, ''); - callback(false, ''); + }); - }); + } else { - } else { + callback(true, "Error: Password not changed"); + } - callback(true, "Error: Password not changed"); } + }); + - } - }); + } else { + callback(true, "Error: Password not changed"); + } } else { callback(true, "Error: Password not changed"); } - } else { + }, 500); - callback(true, "Error: Password not changed"); + } else { - } - }, 500); + callback(true, "Error: Password not changed"); + } } else { callback(true, "Error: Password not changed"); + } @@ -2818,7 +2974,7 @@ function Engine() { //verify that it matches the current one $(progbar).width('40%'); - $(progmess).html('Securing password...'); + $(progmess).text('Securing password...'); setTimeout(function () { //if password reset do not pbkdf the password @@ -2831,13 +2987,13 @@ function Engine() { //get the two packets $(progbar).width('40%'); - $(progmess).html('Getting packets...'); + $(progmess).text('Getting packets...'); // $("#chngpwdprogbar").width('50%'); - //$("#chngpwdprogmess").html('Decrypting account packet...'); + //$("#chngpwdprogmess").text('Decrypting account packet...'); //decrypt with the old password var decryptedWithOld = true; var decryptedPayload = ''; @@ -2850,7 +3006,7 @@ function Engine() { if (decryptedWithOld) { $(progbar).width('80%'); - $(progmess).html('Securing new password...'); + $(progmess).text('Securing new password...'); API.getUserPacket(guid, sharedid, function (err, encpacket) { var decryptedUsrWithOld = true; @@ -2872,128 +3028,136 @@ function Engine() { }, function (err, response) { - //decrypt packet - var decryptedVerWithOld = true; - var jpacket = JSON.parse(response); - var veripacket = ''; - try { - veripacket = decryptNp(jpacket.packet, resetKey, jpacket.IV); - } - catch (verror) { - decryptedVerWithOld = false; - } - - - if (decryptedVerWithOld) { - - setTimeout(function () { + if (!err) { + //decrypt packet + var decryptedVerWithOld = true; + var jpacket = JSON.parse(response); + var veripacket = ''; + try { + veripacket = decryptNp(jpacket.packet, resetKey, jpacket.IV); + } + catch (verror) { + decryptedVerWithOld = false; + } - newpassword = pbkdf2(newpassword, oguid); + if (decryptedVerWithOld) { - $(progbar).width('80%'); - $(progmess).html('Encrypting account packet...'); + setTimeout(function () { - var newpayloadsuccess = true; - var newpayload = ''; - var newusrpayload = ''; - var newveripacket = ''; - var newpasspacket = ''; - var newAIV = ''; - var newUIV = ''; - var newRIV = ''; - var newPIV = '' - try { - newpayload = encrypt(decryptedPayload, newpassword); - newusrpayload = encrypt(rsaKeyPair, newpassword); - newveripacket = encryptNp(veripacket, newpassword); - newpasspacket = encryptNp(newpassword, decryptedPayload.hckey); + newpassword = pbkdf2(newpassword, oguid); - //and encrypt the new password with the hotkey seed - newAIV = newpayload.iv.toString(); - newUIV = newusrpayload.iv.toString(); - newRIV = newveripacket.iv.toString(); - newPIV = newpasspacket.iv.toString(); + $(progbar).width('80%'); + $(progmess).text('Encrypting account packet...'); - } catch (err) { - newpayloadsuccess = false; - } + var newpayloadsuccess = true; + var newpayload = ''; + var newusrpayload = ''; + var newveripacket = ''; + var newpasspacket = ''; + var newAIV = ''; + var newUIV = ''; + var newRIV = ''; + var newPIV = '' + try { - if (newpayloadsuccess) { + newpayload = encrypt(decryptedPayload, newpassword); + newusrpayload = encrypt(rsaKeyPair, newpassword); + newveripacket = encryptNp(veripacket, newpassword); + newpasspacket = encryptNp(newpassword, decryptedPayload.hckey); - //$("#chngpwdprogbar").width('90%'); - //$("#chngpwdprogmess").html('Encrypting user packet...'); + //and encrypt the new password with the hotkey seed - //test decryption - then update - var testpayload = ''; - var testnewusrpayload = ''; - var testveripacket = ''; - var testpasspacket = ''; - var testsuccess = true; - try { - testpayload = decrypt(newpayload.toString(), newpassword, newAIV); - testnewusrpayload = decrypt(newusrpayload.toString(), newpassword, newUIV); - testveripacket = decryptNp(newveripacket.toString(), newpassword, newRIV); - testpasspacket = decryptNp(newpasspacket.toString(), decryptedPayload.hckey, newPIV); + newAIV = newpayload.iv.toString(); + newUIV = newusrpayload.iv.toString(); + newRIV = newveripacket.iv.toString(); + newPIV = newpasspacket.iv.toString(); } catch (err) { - testsuccess = false; + newpayloadsuccess = false; } - if (testsuccess) { + if (newpayloadsuccess) { + + //$("#chngpwdprogbar").width('90%'); + //$("#chngpwdprogmess").text('Encrypting user packet...'); + + //test decryption - then update + var testpayload = ''; + var testnewusrpayload = ''; + var testveripacket = ''; + var testpasspacket = ''; + var testsuccess = true; + try { + testpayload = decrypt(newpayload.toString(), newpassword, newAIV); + testnewusrpayload = decrypt(newusrpayload.toString(), newpassword, newUIV); + testveripacket = decryptNp(newveripacket.toString(), newpassword, newRIV); + testpasspacket = decryptNp(newpasspacket.toString(), decryptedPayload.hckey, newPIV); + + } catch (err) { + testsuccess = false; + } - //save to the server - $(progbar).width('95%'); - $(progmess).html('Saving...'); + if (testsuccess) { + //save to the server + $(progbar).width('95%'); + $(progmess).text('Saving...'); - //TO DO: - //add in the re-encryption of the verification - //packet + //TO DO: + //add in the re-encryption of the verification + //packet - //if reset password then provide signed message and call reset function - var postData = { guid: guid, sharedid: sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV }; - API.post("/api/1/u/updatepackets", postData, function (err, dataStr) { - if (err) { - callback(true, "Error: Password not changed"); - } else { + //if reset password then provide signed message and call reset function + + var postData = { guid: guid, sharedid: sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV }; + API.post("/api/1/u/updatepackets", postData, function (err, dataStr) { + if (err) { + callback(true, "Error: Password not changed"); + } else { - if (dataStr == "ok") { + if (dataStr == "ok") { - callback(false, newpassword); + callback(false, newpassword); - } else { + } else { + + callback(true, "Error: Password not changed"); + } - callback(true, "Error: Password not changed"); } + }); + - } - }); + } else { + callback(true, "Error: Password not changed"); + } } else { callback(true, "Error: Password not changed"); } - } else { + }, 500); - callback(true, "Error: Password not changed"); + } else { - } - }, 500); + callback(true, "Error: Password not changed"); + } } else { callback(true, "Error: Password not changed"); + } @@ -3036,8 +3200,7 @@ function Engine() { API.post("/api/1/getemailvalidationtwofactor", { guid: m_this.m_guid, - token: vtoken, - status: 1 + token: vtoken }, function (err, response) { if (!err) { @@ -3076,9 +3239,16 @@ function Engine() { getAccountSettings(function (err, res) { - var settingsObject = JSON.parse(res); - m_this.m_settings = settingsObject; - callback(err, response); + if (!err) { + + var settingsObject = JSON.parse(res); + m_this.m_settings = settingsObject; + callback(err, response); + } else { + + callback(err, res); + } + }); } else { @@ -3095,8 +3265,7 @@ function Engine() { var postData = { guid: m_this.m_guid, - sharedid: m_this.m_sharedid, - twoFactorOnLogin: true + sharedid: m_this.m_sharedid }; API.post("/api/1/gettwofactorimg", postData, function (err, twoFactorQrImgUrl) { @@ -3122,6 +3291,7 @@ function Engine() { var walletInformation = {}; try { + walletInformation = decrypt(wallet.Payload, m_this.m_password, wallet.IV); var result = {}; @@ -3129,12 +3299,18 @@ function Engine() { getHotHash("", function (err, hotHash) { + if (!err) { + + result.hotHash = hotHash; + } + else { - result.hotHash = hotHash; + result.hotHash = "Unavailable"; + } walletInformation = {}; - callback(err, result); + callback(false, result); }); @@ -3229,6 +3405,15 @@ function Engine() { API.getCoinProfile(m_this.m_guid, m_this.m_sharedid, callback); } + this.getAccountData = getAccountData; + function getAccountData(callback) { + API.getAccountData(m_this.m_guid, m_this.m_sharedid, callback); + } + + this.getUserData = getUserData; + function getUserData(callback) { + API.getUserData(m_this.m_guid, m_this.m_sharedid, callback); + } this.getNickname = getNickname; function getNickname(callback) { diff --git a/src/ninki-ui-mobile.js b/src/ninki-ui-mobile.js index 55f5fd2..5e242da 100644 --- a/src/ninki-ui-mobile.js +++ b/src/ninki-ui-mobile.js @@ -1,10 +1,9 @@ var Bitcoin = require('bitcoinjs-lib'); var BIP39 = require('./bip39'); - -function UI() { - +var prettydate = require("pretty-date"); +function UI() { var Engine = new Ninki.Engine(); @@ -21,10 +20,13 @@ function UI() { var FRIENDSLIST = {}; var COINUNIT = 'BTC'; + var price = 0; var SELECTEDFRIEND = ''; var noAlert = false; var norefresh = false; + var sendmode = "std"; + var trasactionFilterOn = false; var allTransactions = []; var filteredTransactions = []; @@ -76,7 +78,7 @@ function UI() { corners: 1, // Corner roundness (0..1) rotate: 0, // The rotation offset direction: 1, // 1: clockwise, -1: counterclockwise - color: '#000', // #rgb or #rrggbb or array of colors + color: '#c6d0e3', // #rgb or #rrggbb or array of colors speed: 1, // Rounds per second trail: 60, // Afterglow percentage shadow: false, // Whether to render a shadow @@ -87,7 +89,27 @@ function UI() { left: '50%' // Left position relative to parent }; + /* Parse bitcoin URL query keys. */ + function parseBitcoinURL(url) { + var r = /^bitcoin:([a-zA-Z0-9]{27,34})(?:\?(.*))?$/; + var match = r.exec(url); + if (!match) return null; + + var parsed = { url: url } + + if (match[2]) { + var queries = match[2].split('&'); + for (var i = 0; i < queries.length; i++) { + var query = queries[i].split('='); + if (query.length == 2) { + parsed[query[0]] = decodeURIComponent(query[1].replace(/\+/g, '%20')); + } + } + } + parsed.address = match[1]; + return parsed; + } function setCookie(cname, cvalue) { @@ -203,2804 +225,1823 @@ function UI() { } - var profilepagestate = ''; - var networkpagestate = ''; - var friendpagestate = ''; - var menustate = ''; - var cl = ''; + function loginPIN() { - jQuery(document).ready(function () { + var pin = $("#loginpinno").val(); - var $body = jQuery('body'); + $("#enterpinalert").hide(); - /* bind events */ - $(document).on('focus', 'input', function (e) { - $(".footer").hide(); - }); + if (pin.length == 4) { + getCookie("guid", function (guid) { - $(document).on('blur', 'input', function (e) { - $(".footer").show(); - }); - $("#dashsend").hide(); - $("#dashreceive").hide(); - $("#dashcontact").hide(); + if (!Engine.m_appInitialised) { + Engine.m_oguid = guid; - $("#addcontactmodal").hide(); + var bytes = []; + for (var i = 0; i < guid.length; ++i) { + bytes.push(guid.charCodeAt(i)); + } + Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); + } + Engine.getDeviceKey(pin, function (err, ekeyv) { - $('.num').bind('touchstart', function () { - $(this).removeClass('numtapoff'); + //decrypt the passcode - cl = 'b' + (Math.floor(Math.random() * 6) + 1) + ''; - //alert(cl); - $(this).addClass(cl); + if (!err) { - }) - $('.num').bind('touchend', function () { + if (Engine.m_appInitialised) { - var num = $(this); - var text = $.trim(num.find('.txt').clone().children().remove().end().text()); - var loginpinno = $('#loginpinno'); + $('.numdone').attr("style", "background-color:white"); - $(loginpinno).val(loginpinno.val() + text); + if (ekeyv.SessionToken) { + $("#API-Token").val(ekeyv.SessionToken); + } - if ($(loginpinno).val().length == 4) { - $("#pinscreen").hide(); + //check state and display correct headers - $("#btnLoginPIN").click(); - } + //set new session key + $("#paddel").hide(); + $('.numdone').attr("style", "background-color:white"); + $("#loginpin").hide(); + $("#nonlogin").show(); + $(".footer").show(); + $("#loginpinno").val(''); + //initialiseDashboard(); + setTimeout(updateUI(), 200); - var self = this; - setTimeout(function () { - //alert(cl); - $(self).removeClass('b1 b2 b3 b4 b5 b6'); - $(self).addClass('numtapoff'); - }, 100); + } else { - }) + $("#pinspinner").show(); + var target = document.getElementById('pinspinner'); + var spinner = new Spinner(spinneropts).spin(target); + getCookie("ninki_p", function (result) { + var enc = JSON.parse(result); + result = ''; + Engine.setStretchPass(Engine.decryptNp(enc.ct, ekeyv.DeviceKey, enc.iv)); + getCookie("ninki_rem", function (res) { - // $(".num").hammer({ - // drag: false, - // transform: false, - // hold: false, - // touch: false, - // tap: true, - // tapAlways: false, - // swipe: false, - // release: false, - // tapMaxTime: 1000 - // }).bind("tap", function (ev) { + if (res.length > 0) { + var enc = JSON.parse(res); + var fatoken = Engine.decryptNp(enc.ct, ekeyv.DeviceKey, enc.iv); - // $(this).addClass('numtap'); + //get the two factor token - // // var num = $(this); - // // var text = $.trim(num.find('.txt').clone().children().remove().end().text()); - // // var telNumber = $('#telNumber'); - // // $(telNumber).val(telNumber.val() + text); - // }); + //do we need to open wallet ? - // $(".num").click(function () { + Engine.openWallet(guid, fatoken, function (err, result) { - // $(this).addClass('numtap'); + if (!err) { - // // var num = $(this); - // // var text = $.trim(num.find('.txt').clone().children().remove().end().text()); - // // var telNumber = $('#telNumber'); - // // $(telNumber).val(telNumber.val() + text); - // }); + if (result.TwoFactorOnLogin) { + $("#pinspinner").hide(); + $("#loginpinno").val(''); + $("#enterpinalert").show(); + $("#enterpinalertmessage").text('Token has expired'); - $("#btnmenuprofile").hammer({ - drag: false, - transform: false, - hold: false, - touch: false, - tap: true, - tapAlways: false, - swipe: false, - release: false, - tapMaxTime: 1000 - }).bind("tap", function (ev) { - displayProfile(); + } else { + $("#pinspinner").hide(); + $('.numdone').attr("style", "background-color:white"); + $("#loginpin").hide(); + $("#loginpinno").val(''); + $("#paddel").hide(); - }); - $("#btnmenuprofile").hammer({ - drag: false, - transform: false, - hold: false, - touch: true, - tap: false, - tapAlways: false, - swipe: false, - release: false - }).bind("touch", function (ev) { + getCookie("currency", function (res) { - displayProfile(); + if (res) { + Engine.m_settings.LocalCurrency = res; - }); + } else { + setCookie("currency", Engine.m_settings.LocalCurrency); + } - $("#btnmenuprofile").hammer({ - drag: false, - transform: false, - hold: false, - touch: false, - tap: false, - tapAlways: false, - swipe: false, - release: true - }).bind("release", function (ev) { + var t = Engine.m_settings.LocalCurrency; + $('.sccy').filter(function () { + return $(this).text().trim() == t; + }).find("label").html(''); - displayProfile(); + getCookie("coinunit", function (res) { - }); + if (res) { - $("#btnmenuprofile").hammer({ - drag: false, - transform: false, - hold: true, - touch: false, - tap: false, - tapAlways: false, - swipe: false, - release: false - }).bind("hold", function (ev) { + Engine.m_settings.CoinUnit = res; - displayProfile(); + } else { + setCookie("coinunit", Engine.m_settings.CoinUnit); + } - }); - function displayProfile() { + var tc = Engine.m_settings.CoinUnit; + $('.scoinunit').filter(function () { + return $(this).text().trim() == tc; + }).find("label").html(''); + }); - if (menustate != 'profile') { - menustate = 'profile'; - $("#settings").hide(); - $("#network").hide(); - $("#dashboard").show(); - $("#networklist").hide(); - $("#invoices").hide(); - } else { - profilehome(); - } + }); - $("#btnmenusettings").attr('style', 'background-color:#ffffff'); - $("#btnmenunetwork").attr('style', 'background-color:#ffffff'); - $("#btnmenuprofile").attr('style', 'background-color:#eaeef1'); + initialiseDashboard(); + Engine.m_appInitialised = true; + } - } + } else { + $("#pinspinner").hide(); + $('.numdone').attr("style", "background-color:white"); - $("#btnmenunetwork").hammer({ - drag: false, - transform: false, - hold: false, - touch: false, - tap: true, - tapAlways: false, - swipe: false, - release: false, - tapMaxTime: 1000 - }).bind("tap", function (ev) { + } - displayNetwork(); + }); - }); + } - $("#btnmenunetwork").hammer({ - drag: false, - transform: false, - hold: false, - touch: true, - tap: false, - tapAlways: false, - swipe: false, - release: false - }).bind("touch", function (ev) { + }); - displayNetwork(); + }); - }); + } - $("#btnmenunetwork").hammer({ - drag: false, - transform: false, - hold: true, - touch: false, - tap: false, - tapAlways: false, - swipe: false, - release: true - }).bind("release", function (ev) { + } else { - displayNetwork(); + $("#pinspinner").hide(); - }); + if (ekeyv == "ErrDeviceDestroyed") { + deleteCookie("ninki_reg"); + deleteCookie("ninki_p"); + deleteCookie("ninki_rem"); + deleteCookie("guid"); + $("#loginpin").hide(); + $("#mainWallet").hide(); + $("#pairDevice").show(); - $("#btnmenunetwork").hammer({ - drag: false, - transform: false, - hold: true, - touch: false, - tap: false, - tapAlways: false, - swipe: false, - release: false - }).bind("hold", function (ev) { + location.reload(); + } - displayNetwork(); + $("#loginpinno").val(''); + $("#enterpinalert").show(); + $("#enterpinalertmessage").text(ekeyv); - }); + $('.numdone').attr("style", "background-color:white"); - function displayNetwork() { + } - if (menustate != "network") { - menustate = "network"; - $("#settings").hide(); - $("#network").show(); - $("#dashboard").hide(); - $("#networklist").show(); + }); + }); - if (networkpagestate == "invoice") { + } else { + $("#pinspinner").hide(); - $("#network").hide(); + } - $("#invoices").show(); - } + } - } else { - networkhome(); - } - $("#btnmenusettings").attr('style', 'background-color:#ffffff'); - $("#btnmenuprofile").attr('style', 'background-color:#ffffff'); - $("#btnmenunetwork").attr('style', 'background-color:#eaeef1'); - } + function closeSendNet() { + //$("#dashprofile").show(); + $("#dashsend").hide(); + $("#dashsendamt").hide(); + $("#mainWallet").show(); - $("#invformelink").hammer(null).bind("tap", function () { - $("#invformetab").show(); - $("#invbymetab").hide(); - $("#liby").removeClass('active'); - $("#lifor").addClass('active'); - }); + if (sendmode == "net") { + $("#friendheader").show(); + } - $("#invbymelink").hammer(null).bind("tap", function () { - $("#invbymetab").show(); - $("#invformetab").hide(); - $("#lifor").removeClass('active'); - $("#liby").addClass('active'); - }); + $(".footer").show(); - //tapsendfriend - //tapinvoicefriend - $("#tapsendfriend").hammer(null).bind("tap", function () { - $("#networksend").show(); - $("#pnlfriendinv").hide(); - networkpagestate = "friend"; - friendpagestate = "send"; - }); + $("#dashreceive").hide(); + $("#dashcontact").hide(); - $("#tapinvoicefriend").hammer(null).bind("tap", function () { - $("#pnlfriendinv").show(); - $("#networksend").hide(); - networkpagestate = "friend"; - friendpagestate = "invoice"; + $("#pinconfirm").hide(); - }); + $("#btnStdSndDone").hide(); - function networkhome() { - if (networkpagestate == "invoice") { - $('#network').show(); - $('#invoices').hide(); - networkpagestate = "friend"; - friendpagestate = "invoice"; + $('#toAddress').val(''); + $('#amount').text(''); - } else { - $("#pnlfriend").hide(); - $("#myfriends").show(); - $("#networklist").show(); - networkpagestate = ""; - } + updateStdAmount(); - } + } - function profilehome() { + function closeSendStd() { - $("#dashprofile").show(); - $("#dashsend").hide(); - $("#dashreceive").hide(); - $("#dashcontact").hide(); - $('#invoices').hide(); - $("#dashboard").show(); - profilepagestate = ""; + //$("#dashprofile").show(); + $("#dashsend").hide(); + $("#dashsendamt").hide(); + $("#dashheader").show(); + $("#mainWallet").show(); + $(".footer").show(); - } + $("#dashreceive").hide(); + $("#dashcontact").hide(); + $("#pinconfirm").hide(); - $("#btnmenusettings").hammer({ - drag: false, - transform: false, - hold: false, - touch: false, - tap: true, - tapAlways: false, - swipe: false, - release: false, - tapMaxTime: 1000 - }).bind("tap", function (ev) { + $("#addrfade").hide(); - menustate = "settings"; + $("#btnStdSndDone").hide(); - $("#settings").show(); - $("#network").hide(); - $("#networklist").hide(); - $("#dashboard").hide(); - $("#btnmenusettings").attr('style', 'background-color:#eaeef1'); - $("#btnmenuprofile").attr('style', 'background-color:#ffffff'); - $("#btnmenunetwork").attr('style', 'background-color:#ffffff'); - }); + //profilepagestate = "send"; + //menustate = "profile" - $("#tapsend").hammer(null).bind("tap", function () { - $("#dashprofile").hide(); - $("#dashsend").show(); - $("#dashreceive").hide(); - $("#dashcontact").hide(); - //$("#toAddress").focus(); - profilepagestate = "send"; - menustate = "profile" + $('#toAddress').val(''); + $('#amount').text(''); + updateStdAmount(); + } - }); + var stdAmountConvCoin = true; + var netAmountConvCoin = true; - $("#tapreceive").hammer(null).bind("tap", function () { - $("#dashprofile").hide(); - $("#dashsend").hide(); - $("#dashreceive").show(); - $("#dashcontact").hide(); - profilepagestate = "receive"; - menustate = "profile" + function convertToLocalCurrency(amount) { - }); + var conv = amount; + conv = conv * 1.0; - $("#taprequest").hammer(null).bind("tap", function () { - $("#dashprofile").hide(); - $("#dashsend").hide(); - $("#dashreceive").hide(); - $("#dashcontact").show(); - profilepagestate = "contact"; - menustate = "profile" + var sats = convertToSatoshis(conv, COINUNIT); + var btc = convertFromSatoshis(sats, "BTC"); - }); + var cbtc = btc * price; - $('#imgProfileContainer').show(); - $("#dropzone").hide(); - $("#btnSaveProfile").hide(); - $("#btnCancelProfile").hide(); - $("#statusedit").hide(); - $("#imgreset").hide(); + var loc = "en-US"; + var ires = cbtc; + if (Engine.m_settings.LocalCurrency == "JPY") { + ires = (cbtc * 1.0).toFixed(0) * 1.0; + } else { + ires = (cbtc * 1.0).toFixed(2) * 1.0; + } - $("#btnEditProfile").click(function () { - key = ''; + var cprc = ires.toLocaleString(loc, { style: "currency", currency: Engine.m_settings.LocalCurrency }); - $('#imgProfileContainer').hide(); - $("#dropzone").show(); - $("#btnSaveProfile").show(); - $("#btnCancelProfile").show(); - $("#btnEditProfile").hide(); - $("#statusedit").show(); - $("#profnmests").hide(); - $("#imgreset").show(); - $("#txtStatusText").val(Engine.m_statusText); + return cprc; - }); + } - $("#imgreset").click(function () { - Engine.m_profileImage = ""; - imgReset = true; + function convertFromLocalCurrency(amount) { - var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; + var conv = amount; + conv = conv * 1.0; - document.getElementById('imgProfile').src = imageSrc; - $('#imgProfileContainer').show(); - $('#dropzone').hide(); - $('progressNumber').html(''); - $("#imgreset").hide(); + //convert to bitcoin + if (price > 0) { + var cbtc = conv / price; - }); + var sats = convertToSatoshis(cbtc, "BTC"); + var btc = convertFromSatoshis(sats, COINUNIT); - var imgReset = false; - $("#btnSaveProfile").click(function () { + return btc; + } else { - //updateUserProfile + return 0; - var statusText = $("#txtStatusText").val(); + } - if (key == '' && !imgReset) { - key = Engine.m_profileImage; - } - Engine.updateUserProfile(key, statusText, Engine.m_invoiceTax, function (err, result) { + } - if (!err) { + function updateStdAmount() { - var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; - var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; + var asamt = $('#amount').text(); + if (asamt == '' || asamt == '.') { + asamt = 0; + } - if (key != '' && !imgReset) { - imageSrc = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; - imageSrcSmall = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0"; - } + if (stdAmountConvCoin) { + $('#ccystdamt').text(convertToLocalCurrency(asamt)); + $('#hdamount').val(asamt); + } + else { + var amt = convertFromLocalCurrency(asamt); + $('#hdamount').val(amt); + $('#ccystdamt').text(amt + ' ' + COINUNIT); + } - $("#imgProfile").attr("src", imageSrc); - $("#imgtoprightprofile").attr("src", imageSrcSmall); + } - $('#imgProfileContainer').show(); - $("#dropzone").hide(); - $("#btnSaveProfile").hide(); - $("#btnCancelProfile").hide(); - $("#btnEditProfile").show(); - $("#statusedit").hide(); - $("#mystatus").html(statusText); - $("#txtStatusText").val(statusText); - $("#profnmests").show(); - $("#imgreset").hide(); - imgReset = false; - $("#profileimgfile").val(''); - $("#progressNumber").val(''); - } + var profilepagestate = ''; + var networkpagestate = ''; + var friendpagestate = ''; + var menustate = ''; - }); + var cl = ''; - }); + jQuery(document).ready(function () { - $("#btnCancelProfile").click(function () { + var $body = jQuery('body'); - $('#imgProfileContainer').show(); - $("#dropzone").hide(); - $("#btnSaveProfile").hide(); - $("#btnCancelProfile").hide(); - $("#btnEditProfile").show(); - //reset profile image + //guid + //ninki_reg - var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; + //if device is paired then - if (Engine.m_profileImage != '') { - imageSrc = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; - } - $("#imgProfile").attr("src", imageSrc); + getCookie("ninki_reg", function (reg) { + + if (reg) { + $("#loginpin").show(); + } else { + $("#pairDevice").show(); + } - $("#statusedit").hide(); - $("#profnmests").show(); - $("#imgreset").hide(); }); - var obj = $("#dropzone"); - obj.click(function () { - $("#profileimgfile").click(); - }); + $("#mainWallet").hide(); + $("#dashreceive").hide(); + $("#dashcontact").hide(); - $("#profileimgfile").change(function (e) { - var control = document.getElementById("profileimgfile"); - var files = control.files; - //alert(files[0]); - //We need to send dropped files to Server - handleFileUpload(files, obj); + $("#addcontactmodal").hide(); - }); - obj.on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - $(this).css('border', '2px solid #0B85A1'); - }); + $('#stdselcu').click(function () { - obj.on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); + var amttarget = '#amount'; - obj.on('drop', function (e) { + $('#stdselunit').text(COINUNIT); + stdAmountConvCoin = true; + $(amttarget).text(''); + updateStdAmount(); - $(this).addClass("b-dashed"); - $(this).addClass("b-light"); - e.preventDefault(); - var files = e.originalEvent.dataTransfer.files; - //alert(files[0]); - //We need to send dropped files to Server - handleFileUpload(files, obj); }); + $('#stdsellc').click(function () { - $(document).on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - $(document).on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - obj.css('border', '2px dotted #0B85A1'); - }); + var amttarget = '#amount'; - $(document).on('drop', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); + $('#stdselunit').text(Engine.m_settings.LocalCurrency); + stdAmountConvCoin = false; + $(amttarget).text(''); + updateStdAmount(); - var key = ''; - function handleFileUpload(files, obj) { - if (files.length > 0) { - var file = files[0]; - var fd = new FormData(); + }); - key = "images\/" + Engine.m_nickname + '_' + (new Date).getTime() - Ninki.API.post("/api/1/u/createS3Policy", { test: 'test' }, function (err, result) { + // $('.numc').bind('touchstart', function () { + // $(this).removeClass('numtapoff'); - var policy = JSON.parse(result); + // cl = 'b' + (Math.floor(Math.random() * 6) + 1) + ''; + // //alert(cl); + // $(this).addClass(cl); - fd.append('key', key); - fd.append('acl', 'public-read'); - fd.append('Content-Type', file.type); - fd.append('bucket', 'ninkip2pimgstore'); - fd.append('AWSAccessKeyId', 'AKIAINOU56ATQFS3CLFQ'); - fd.append('policy', policy.s3Policy); - fd.append('signature', policy.s3Signature); - fd.append("file", file); - //fd.append("success_action_redirect", "https://localhost:1111/ok"); + // }); - var xhr = new XMLHttpRequest(); - xhr.upload.addEventListener("progress", uploadProgress, false); - xhr.addEventListener("load", uploadComplete, false); - xhr.addEventListener("error", uploadFailed, false); - xhr.addEventListener("abort", uploadCanceled, false); + $('.scoinunit').bind('click', function () { - xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND + $('.scoinunit').find("label").html(''); - xhr.send(fd); + $(this).find("label").html(''); - }); - } + var sel = $.trim($(this).text()); - } + setCookie("coinunit", sel); + Engine.m_settings.CoinUnit = sel; + COINUNIT = sel; - function uploadProgress(evt) { - if (evt.lengthComputable) { - var percentComplete = Math.round(evt.loaded * 100 / evt.total); - document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; - } - else { - document.getElementById('progressNumber').innerHTML = 'unable to compute'; - } - } + updateUI(); - function uploadComplete(evt) { - /* This event is raised when the server send back a response */ - //alert("Done - " + evt.target.responseText); - document.getElementById('imgProfile').src = 'https://ninkip2p.imgix.net/' + key + "?fit=crop&crop=faces&h=128&w=128&mask=ellipse&border=1,d0d0d0"; - $('#imgProfileContainer').show(); - $('#dropzone').hide(); - $('progressNumber').html(''); - $("#imgreset").hide(); + }); - } - function uploadFailed(evt) { - alert("There was an error attempting to upload the file." + evt); - } - function uploadCanceled(evt) { - alert("The upload has been canceled by the user or the browser dropped the connection."); - } - var options = {}; - options.ui = { - container: "#pwd-container", - showVerdictsInsideProgressBar: true, - showPopover: true, - showErrors: true, - viewports: { - progress: ".pwstrength_viewport_progress" - } - }; - options.common = { - debug: true, - onLoad: function () { - $('#messages').text('Start typing password'); - }, - onKeyUp: function () { - $("#createwalletalert").fadeOut(100); - } - }; + $('.sccy').bind('click', function () { - $('#createWalletStart #cpassword').pwstrength(options); + $('.sccy').find("label").html(''); + $(this).find("label").html(''); - var optionschng = {}; - optionschng.ui = { - container: "#newpwd-container", - showVerdictsInsideProgressBar: true, - showPopover: true, - showErrors: true, - viewports: { - progress: ".newpwstrength_viewport_progress" - } - }; - optionschng.common = { - debug: true, - onLoad: function () { - $('#messages').text('Start typing password'); - }, - onKeyUp: function () { - $("#createwalletalert").fadeOut(100); - } - }; + var sel = $.trim($(this).text()); - $('#newpassword1').pwstrength(optionschng); + setCookie("currency", sel); - }); + Engine.m_settings.LocalCurrency = sel; + updateUI(); + }); - $('#btnPassphraseLogin').keydown(function (e) { - if (e.keyCode == 13) { - e.preventDefault(); - return false; - } - }); - $('#frmSaveTwoFactor').keydown(function (e) { - if (e.keyCode == 13) { - e.preventDefault(); - return false; - } - }); + $('.numc').bind('touchend', function () { - $('#phrase2fa').keydown(function (e) { - if (e.keyCode == 13) { - e.preventDefault(); - return false; - } - }); + var num = $(this); + var text = $.trim(num.find('.txt').clone().children().remove().end().text()); + var amttarget = '#amount'; - $(document).on("keydown", function (e) { - if (e.which === 8 && !$(e.target).is("input, textarea")) { - e.preventDefault(); - } - }); + var amt = $(amttarget).text(); + if (!(amt.indexOf(".") > -1 && text == '.')) { - $(document).ready(function () { + var prev = amt.substring(0, amt.length - 1); + + if (text.length > 0) { + $(amttarget).text($(amttarget).text() + text); + } else { + $(amttarget).text(prev); + } + updateStdAmount(); - $('body').on('click', function (e) { - //did not click a popover toggle or popover - if ($(e.target).data('toggle') !== 'popover' - && $(e.target).parents('.popover.in').length === 0) { - $('[data-toggle="popover"]').popover('hide'); } + + }); + var pintaps = 0; + var prevpin = ''; + //touchend + $('#loginpin .num').bind('touchstart', function () { + var num = $(this); + var text = $.trim(num.find('.txt').clone().children().remove().end().text()); - getCookie('guid', function (res) { - if (res.length == 0) { + if (text.length > 0) { - var betafrom = 'December 12, 2009 12:00 pm GMT'; - var betato = 'December 12, 2009 01:00 pm GMT'; + pintaps++; - betafrom = getLocalTime(betafrom); - betato = getLocalTime(betato); + if (pintaps == 1) { - $('#betafrom').html(betafrom); - $('#betato').html(betato); + $('#loginpin #pin1').attr("style", "background-color:Gray"); - $('#basicModal').modal('show'); + } - $("#btnDeclineBeta").click(function () { - window.location.href = '/' - }); + if (pintaps == 2) { - } - }); + $('#loginpin #pin2').attr("style", "background-color:Gray"); + } + if (pintaps == 3) { - $("#btnAcceptBeta").click(function () { - $("#openWalletStart #password").focus(); - }); + $('#loginpin #pin3').attr("style", "background-color:Gray"); + } + if (pintaps == 4) { + $('#loginpin #pin4').attr("style", "background-color:Gray"); + } - $("#btncreatewallet").click(function () { - showCreateWalletStart(); - }); + } - $("#pairdeviceblob").change(function () { - $("#loginpin").hide(); - $("#pairstep1").hide(); - $("#pairstep2").show(); + var loginpinno = $('#loginpinno'); + var lpin = loginpinno.val(); + prevpin = lpin.substring(0, lpin.length - 1) - }); + if (text.length > 0) { + $('#paddel').show(); - $("#btnUnpair").click(function () { - getCookie("guid", function (guid) { - Engine.m_oguid = guid; + $(loginpinno).val(loginpinno.val() + text); - var bytes = []; - for (var i = 0; i < guid.length; ++i) { - bytes.push(guid.charCodeAt(i)); - } + if (pintaps == 4) { - Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); + pintaps = 0; - Engine.destroyDevice(function (err, res) { + loginPIN(); - deleteCookie("ninki_rem"); - deleteCookie("ninki_p"); - deleteCookie("ninki_reg"); - deleteCookie("ninki_h"); + //only if fail - //call to server - location.reload(); + } - }); - }); + } else { - }); + if (pintaps == 1) { - $("#btnPairDevice").click(function () { + $('#loginpin #pin1').attr("style", "background-color:White"); + $('#loginpin #paddel').hide(); - var deviceid = "DEVICE123456789"; + } - if (window.cordova) { - deviceid = window.device.uuid; - } + if (pintaps == 2) { - var blob = $('#pairdeviceblob').val(); - var pin = $('#pairdevicepinnumber').val(); - var pwd = $('#pairpwd').val(); + $('#loginpin #pin2').attr("style", "background-color:White"); + } + if (pintaps == 3) { - var splitBlob = blob.split('|'); + $('#loginpin #pin3').attr("style", "background-color:White"); - var enck = splitBlob[0]; - var iv = splitBlob[1]; - var guid = splitBlob[2]; - var deviceName = splitBlob[3]; - var regToken = splitBlob[4]; + } + if (pintaps == 4) { - Engine.setPass(pwd, guid); + $('#loginpin #pin4').attr("style", "background-color:White"); - pwd = Engine.m_password; + } + + $(loginpinno).val(prevpin); + + if (pintaps > 0) { + pintaps--; + } - var bytes = []; - for (var i = 0; i < guid.length; ++i) { - bytes.push(guid.charCodeAt(i)); } - var hashguid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); + }); - Engine.m_guid = hashguid; - Engine.m_oguid = guid; - //first validate the password with the secret - Engine.getRecoveryPacket(function (err, response) { + $('#pinconfirm .num').bind('touchend', function () { - if (err) { + var num = $(this); + var text = $.trim(num.find('.txt').clone().children().remove().end().text()); + var loginpinno = $('#sendstdpin'); + var lpin = loginpinno.val(); + prevpin = lpin.substring(0, lpin.length - 1) - $('#pairdevicealertmessage').html(response); + if (text.length > 0) { - } else { + $('#paddelconf').show(); - //decrypt packet + pintaps++; - var jpacket = JSON.parse(response); + if (pintaps == 1) { - var secret = Engine.decryptNp(jpacket.packet, pwd, jpacket.IV); + $('#pinconfirm #cpin1').attr("style", "background-color:Gray"); - Engine.validateSecret(secret, function (err, secvalid) { + } - if (!err) { + if (pintaps == 2) { + $('#pinconfirm #cpin2').attr("style", "background-color:Gray"); - //hash the pin and device id + } - var pinhash = deviceid + pin; - bytes = []; - for (var i = 0; i < pinhash.length; ++i) { - bytes.push(pinhash.charCodeAt(i)); - } + if (pintaps == 3) { - pinhash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); + $('#pinconfirm #cpin3').attr("style", "background-color:Gray"); + } - //new register device + if (pintaps == 4) { + $('#pinconfirm #cpin4').attr("style", "background-color:Gray"); - //enter password - //stretch - //get validate - //if valid - //choose a PIN - //register + } - var devplatform = "platform"; - var devmodel = "model"; + $(loginpinno).val(loginpinno.val() + text); - if (window.cordova) { - devplatform = window.device.platform; - devmodel = window.device.model; - } + if (pintaps == 4) { - Engine.registerDevice(hashguid, deviceName, devplatform, devmodel, pinhash, regToken, secret, function (err, result) { + pintaps = 0; - if (!err) { + if (sendmode == 'std') { - var dk = JSON.parse(result); + sendMoneyStd(); - if (dk.DeviceKey.length > 0) { + } else if (sendmode == 'net') { - var decblob = Engine.decryptNp(enck, dk.DeviceKey, iv); + sendMoney(SELECTEDFRIEND, 0); - //slice it up - //64 64 64 - var hk = decblob.substring(0, 64); - var fatoken = decblob.substring(64, 128); + } else if (sendmode == 'inv') { - var encp = Engine.encryptNp(pwd, dk.DeviceKey); - result = ''; + payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId); - var ptok = {}; - ptok.ct = encp.toString(); - ptok.iv = encp.iv.toString(); - var ptoken = JSON.stringify(ptok); + } - var enc = Engine.encryptNp(fatoken, dk.DeviceKey); - var ctok = {}; - ctok.ct = enc.toString(); - ctok.iv = enc.iv.toString(); - var ctoken = JSON.stringify(ctok); + //only if fail + } - var ench = Engine.encryptNp(hk, dk.DeviceKey); - var htok = {}; - htok.ct = ench.toString(); - htok.iv = ench.iv.toString(); - var hkey = JSON.stringify(htok); + } else { - dk.DeviceKey = ''; - //login using the credentials - //get a session - //then call register PIN - //this will return the encryption key - //encrypt the password and store in local storage - setCookie("guid", guid); + if (pintaps == 1) { - Engine.openWallet(guid, fatoken, function (err, result) { + $('#pinconfirm #cpin1').attr("style", "background-color:White"); + $('#pinconfirm #paddelconf').hide(); - if (!err) { + } - if (!result.TwoFactorOnLogin) { + if (pintaps == 2) { - setCookie("ninki_rem", ctoken); - setCookie("ninki_p", ptoken); - setCookie("ninki_reg", regToken); - setCookie("ninki_h", hkey); + $('#pinconfirm #cpin2').attr("style", "background-color:White"); - $('#pairDevice').hide(); + } - initialiseUI(); + if (pintaps == 3) { - } else { + $('#pinconfirm #cpin3').attr("style", "background-color:White"); + } - $('#pairdevicealertmessage').html("could not pair"); - $('#pairdevicealert').show(); - } + if (pintaps == 4) { + $('#pinconfirm #cpin4').attr("style", "background-color:White"); - } else { + } - $('#pairdevicealertmessage').html(result); - $('#pairdevicealert').show(); - } + $(loginpinno).val(prevpin); - }); - } else { + if (pintaps > 0) { + pintaps--; + } - $('#pairdevicealertmessage').html("The pairing token has expired"); - $('#pairdevicealert').show(); - } + } - } else { + }); - $('#pairdevicealertmessage').html(result); - $('#pairdevicealert').show(); - } + $("#btnmenuprofile").bind('touchstart', function () { - }); + displayProfile(); - } else { + }); - $('#pairdevicealertmessage').html(secvalid); - $('#pairdevicealert').show(); - } - }); + function displayProfile() { - } - }); + if (menustate != 'profile') { + menustate = 'profile'; + $("#settings").hide(); + $("#settingsheader").hide(); - }); + $("#network").hide(); + $("#networklistheader").hide(); + $("#friendheader").hide(); + $("#dashboard").show(); - $("#btnLoginPIN").click(function () { + $('#dashheader').show(); + //$("#invoices").hide(); - var pin = $("#loginpinno").val(); + } else { + profilehome(); + } - $("#enterpinalert").hide(); + $("#btnmenusettings").attr('style', 'background-color:#ffffff'); + $("#btnmenunetwork").attr('style', 'background-color:#ffffff'); + $("#btnmenuprofile").attr('style', 'background-color:#eaeef1'); - if (pin.length == 4) { + } - getCookie("guid", function (guid) { - Engine.m_oguid = guid; + var hastouched = false; + $("#btnmenunetwork").bind('touchstart', function () { - var bytes = []; - for (var i = 0; i < guid.length; ++i) { - bytes.push(guid.charCodeAt(i)); - } + if (!hastouched) { - Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); + hastouched = true; + var target = document.getElementById('myfrndspin'); + var spinner = new Spinner(spinneropts).spin(target); + $("#myfrndspin").show(); + updateFriends(function (err, res) { - Engine.getDeviceKey(pin, function (err, ekeyv) { + $("#myfrndspin").hide(); - //decrypt the passcode + }); - if (!err) { + loadInvoices(); - getCookie("ninki_p", function (result) { + } - var enc = JSON.parse(result); - result = ''; - Engine.setStretchPass(Engine.decryptNp(enc.ct, ekeyv.DeviceKey, enc.iv)); + displayNetwork(); - getCookie("ninki_rem", function (res) { - if (res.length > 0) { - var enc = JSON.parse(res); - var fatoken = Engine.decryptNp(enc.ct, ekeyv.DeviceKey, enc.iv); + }); - //get the two factor token - //do we need to open wallet ? - if (!Engine.m_appInitialised) { - Engine.openWallet(guid, fatoken, function (err, result) { + function displayNetwork() { - if (!err) { + if (menustate != "network") { - if (result.TwoFactorOnLogin) { + menustate = "network"; + $("#settings").hide(); + $("#settingsheader").hide(); + $("#dashboard").hide(); + $('#dashheader').hide(); + //$("#pnlfriend").hide(); + $("#network").show(); - $("#loginpinno").val(''); - $("#enterpinalert").show(); - $("#enterpinalertmessage").html('Token has expired'); - } else { + if ($("#networklist").is(':visible')) { + $("#networklistheader").show(); + } - $("#loginpin").hide(); - $("#loginpinno").val(''); + if ($("#pnlfriend").is(':visible')) { + $("#friendheader").show(); + } - initialiseUI(); - Engine.m_appInitialised = true; - } + //$("#networklist").show(); - } else { + if (networkpagestate == "invoice") { - } - }); + //$("#invoices").show(); + } - } else { + } else { - if (ekeyv.SessionToken) { - $("#API-Token").val(ekeyv.SessionToken); - } - //set new session key + networkhome(); + } - $("#loginpin").hide(); - $("#loginpinno").val(''); + $("#btnmenusettings").attr('style', 'background-color:#ffffff'); + $("#btnmenuprofile").attr('style', 'background-color:#ffffff'); + $("#btnmenunetwork").attr('style', 'background-color:#eaeef1'); + } - initialiseUI(); - } + $("#invformelink").hammer(null).bind("tap", function () { - } + sendmode = "inv"; + $("#invformetab").show(); + $("#invbymetab").hide(); + $("#liby").removeClass('active'); + $("#lifor").addClass('active'); + }); - }); + $("#invbymelink").hammer(null).bind("tap", function () { + $("#invbymetab").show(); + $("#invformetab").hide(); + $("#lifor").removeClass('active'); + $("#liby").addClass('active'); + }); - }); + //tapsendfriend + //tapinvoicefriend - } else { + //tapnetpayments - if (ekeyv == "ErrDeviceDestroyed") { + $("#tapnetpayments").hammer(null).bind("tap", function () { + $("#pnlfriendinv").hide(); + $("#networkpayments").show(); + $("#networksend").hide(); + networkpagestate = "friend"; + friendpagestate = "payments"; - deleteCookie("ninki_reg"); - deleteCookie("ninki_p"); - deleteCookie("ninki_rem"); - deleteCookie("guid"); + }); - location.reload(); - } - $("#loginpinno").val(''); - $("#enterpinalert").show(); - $("#enterpinalertmessage").html(ekeyv); + $("#tapinvoicefriend").hammer(null).bind("tap", function () { - } + $("#pnlfriendinv").show(); + $("#networkpayments").hide(); + $("#networksend").hide(); + networkpagestate = "friend"; + friendpagestate = "invoice"; - }); + }); - }); + function networkhome() { + if (networkpagestate == "invoice") { - } + $('#network').show(); + $("#pnlfriend").show(); + $("#friendheader").show(); + $('#invoices').hide(); + networkpagestate = "friend"; + friendpagestate = "invoice"; - }); - $("#btnLogin").click(function () { + } else { - if (!ensureOpenWalletGuidAndPasswordValid()) return; + $("#pnlfriend").hide(); + $("#friendheader").hide(); + $("#network").show(); + $("#networklist").show(); + $("#networklistheader").show(); - $("#imgopenwaiting").show(); - $("#btnLogin").prop('disabled', true); - $("#btnLogin").addClass('disabled'); - var target = document.getElementById('imgopenwaiting'); - var spinner = new Spinner(spinneropts).spin(target); + networkpagestate = ""; + } + } - setTimeout(function () { + function profilehome() { - var guid = $('#openWalletStart input#guid').val(); - var password = $('#openWalletStart input#password').val(); - var twoFactorCode = $('#openWalletStart input#twoFactorCode').val(); - //decrypt the password using the key sent back from the server + $("#dashprofile").show(); + $("#dashsend").hide(); + $("#dashreceive").hide(); + $("#dashcontact").hide(); + $('#invoices').hide(); + $("#dashboard").show(); + $('#dashheader').show(); + $("#network").hide(); + profilepagestate = ""; + } - Engine.setPass(password, guid); - getCookie("ninki_rem", function (res) { + $("#btnmenusettings").bind('touchstart', function () { - if (res.length > 0) { - var enc = JSON.parse(res); - twoFactorCode = Engine.decryptNp(enc.ct, Engine.m_password, enc.iv); - } + menustate = "settings"; - setCookie('guid', guid); + $("#settings").show(); + $("#settingsheader").show(); + $("#network").hide(); + $("#dashboard").hide(); + $('#dashheader').hide(); + $('#friendheader').hide(); + $('#networklistheader').hide(); - Engine.openWallet(guid, twoFactorCode, function (err, result) { + $("#btnmenusettings").attr('style', 'background-color:#eaeef1'); + $("#btnmenuprofile").attr('style', 'background-color:#ffffff'); + $("#btnmenunetwork").attr('style', 'background-color:#ffffff'); + }); - $("#imgopenwaiting").hide(); - $("#btnLogin").prop('disabled', false); - $("#btnLogin").removeClass('disabled'); - if (!err) { + $('#toAddress').change(function () { - $("#imgopenwaiting").hide(); - $("#openwalletalert").hide(); + //if a valid bitcoin address then + //next stage + var addr = $('#toAddress').val(); - if (result.TwoFactorOnLogin) { + var paddr = parseBitcoinURL(addr); - //delete any old 2 factor tokens + if (addr.length > 25) { + if (Engine.isAddressValid(paddr.address)) { - deleteCookie("ninki_rem"); + //next stage - if (!result.Beta12fa) { + //if amount is included in the URL set the amount and go straight to the + //pay screen + $('#toAddress').val(paddr.address) - $('#openWalletStart input#password').val(''); + $("#dashsend").hide(); + $("#addrfade").hide(); + $("#dashsendamt").show(); - if (result.TwoFactorOnLogin) { - $("#siguid").hide(); - $("#silguid").hide(); - $("#sipwd").hide(); - $("#si2fa").show(); - $("#sib1").hide(); - $("#sib2").show(); - $('#openWalletStart input#twoFactorCode').focus(); - } - } else { + } + } + }); - //for beta1 migrations - $("#siguid").hide(); - $("#silguid").hide(); - $("#sipwd").hide(); - $("#si2fa").show(); - $("#sib1").hide(); - $("#sib2").show(); - $('#openWalletStart input#twoFactorCode').focus(); - } + $("#btnCloseContact").bind('touchstart', function () { - } else { + //closeSendStd(); + $("#dashcontact").hide(); + $("#mainWallet").show(); + $("#networklistheader").show(); + $(".footer").show(); + }); - //initiate 2fa setup modal - if (!m_this.m_twoFactorOnLogin) { - $("#twofactorsettings").show(); - $("#2famodal").modal('show'); + $("#btnAddContactDone").bind('touchstart', function () { - $("#twofactorsettings").show(); - $("#btnSetupTwoFactor").hide(); - $("#savetwofactorerror").hide(); - $("#setup2faemail").hide(); - $("#setup2faqr").show(); + $("#addcontactmodal").hide(); + $("#dashcontact").show(); - showSettingsTwoFactorQr(); - } else { + }); - initialiseUI(); + $("#btnCloseStdSndAmt").bind('touchstart', function () { - } + closeSendNet(); - } + }); - $("#unlockaccount").hide(); + $("#btnCloseStdSndPIN").bind('touchstart', function () { - } else { - $("#imgopenwaiting").hide(); - $("#openwalletalert").show(); + if (sendmode == "std") { + closeSendStd(); + } else { + closeSendNet(); + } - if (result == "ErrAccount") { - $("#openwalletalertmessage").html("Incorrect password"); - } + }); - if (result == "ErrLocked") { - $("#openwalletalertmessage").html("Your account has been locked."); - $("#unlockaccount").show(); - } else { - $("#unlockaccount").hide(); - } - } + $("#btnCloseStdSnd").bind('touchstart', function () { - }); + closeSendStd(); - }); - }, 100); }); + $("#btnCloseRec").bind('touchstart', function () { - $("#btn2faLogin").click(function () { + closeSendStd(); + }); - $("#img2faopenwaiting").show(); - $("#btn2faLogin").prop('disabled', true); - $("#btn2faLogin").addClass('disabled'); - var target = document.getElementById('img2faopenwaiting'); - var spinner = new Spinner(spinneropts).spin(target); - setTimeout(function () { + $("#btnStdSndDone").bind('touchstart', function () { - var twoFactorCode = $('#openWalletStart input#twoFactorCode').val(); - var rememberTwoFactor = $('#twofactorremember')[0].checked; + $('#sendprogress').hide(); - Engine.openWallet2fa(twoFactorCode, rememberTwoFactor, function (err, result) { - if (err) { + if (sendmode == "std") { + closeSendStd(); + } else { + closeSendNet(); + } + + }); - $("#img2faopenwaiting").hide(); - $("#openwalletalert").show(); - $("#openwalletalertmessage").html(result); - $("#btn2faLogin").prop('disabled', false); - $("#btn2faLogin").removeClass('disabled'); - } else { + //$("#btnStdSndDone") - if (result.CookieToken) { + $("#btnsendmoneystd").bind('touchstart', function () { - setCookie("ninki_rem", result.CookieToken); - } + if (sendmode == 'std') { + $("#sendstds2add").text($('#toAddress').val()); + } else if (sendmode == 'net') { + $("#sendstds2add").text(SELECTEDFRIEND); + } + $("#sendstds2amt").text($("#hdamount").val() + ' ' + COINUNIT); - initialiseUI(); - } - }); + $("#dashsend").hide(); + $("#dashsendamt").hide(); + $("#pinconfirm").show(); - }, 100); + //sendMoneyStd(); }); - $("#btnEmailGuid").click(function () { - - var userName = $("#txtlostguidusername").val(); - Engine.emailGUID(userName, function (err, response) { + $("#btnCloseValidate").bind('touchstart', function () { - showOpenWalletStart(); - }); + $("#friendheader").show(); + $("#mainWallet").show(); + $(".footer").show(); + $("#networkvalidate").hide(); }); - $("#btnaddfriend").click(function () { + $("#tapvalidatefriend").bind('touchstart', function () { - addFriend($('input#friend').val()); + $("#friendheader").hide(); + $("#mainWallet").hide(); + $(".footer").hide(); + $("#networkvalidate").show(); }); - $("#btngenaddr").click(function () { + $("#tapsendfriend").bind('touchstart', function () { - generateAddressClient(); + sendmode = "net"; - }); - - - $("#showopenwallet").click(function () { - - showOpenWalletStart(); - - }); - - $("#btnopenwalletrec").click(function () { - - showOpenWalletStart(); + $("#sendsubheading").text("send to " + SELECTEDFRIEND); - }); - - - $("#showopenwalletcr").click(function () { - - showOpenWalletStart(); + $("#btnStdSndDone").hide(); + $("#dashsend").hide(); + $("#addrfade").hide(); - }); + $("#friendheader").hide(); + $("#dashsendamt").show(); + $("#mainWallet").hide(); + $(".footer").hide(); - $("#btnsendmoneystd").hammer(null).bind("tap", function () { - sendMoneyStd(); + networkpagestate = "friend"; + friendpagestate = "send"; }); + $("#tapsend").bind('touchstart', function () { - $("#btnCreate").click(function () { - - if ($("#frmcreate").parsley('validate')) { - - //check password strength - if (($(".password-verdict").html() == 'Strong' || $(".password-verdict").html() == 'Very Strong')) { - - //can we remove this check? - if (ensureCreateWalletGuidNicknameAndPasswordValid()) { - - $("#imgcreatewaiting").show(); - $("#btnCreate").prop('disabled', true); - $("#btnCreate").addClass('disabled'); - $("#lnkOpenWallet").hide(); - - var target = document.getElementById('imgcreatewaiting'); - var spinner = new Spinner(spinneropts).spin(target); - - //error handling here? - - var guid = $('#createWalletStart input#guid').val(); - var username = $("#createWalletStart input#nickname").val(); - var password = $('#createWalletStart input#cpassword').val(); - var emailAddress = $('#createWalletStart input#emailaddress').val(); - - - Engine.createWallet(guid, password, username, emailAddress, function (err, result) { - - //move error handling and ui elements to here - $("#createWalletStart input#nickname").css("border-color", "#ccc"); - if (err) { - if (result == "ErrUserExists") { - - $("#createWalletStart input#nickname").css("border-color", "#ffaaaa"); - $("#imgcreatewaiting").hide(); - - $("#createwalletalert").show(); - $("#createwalletalertmessage").html("The username already exists"); - - $("#btnCreate").prop('disabled', false); - $("#btnCreate").removeClass('disabled'); - $("#lnkOpenWallet").show(); - } - if (result == "ErrEmailExists") { + sendmode = "std" - $("#createWalletStart input#emailaddress").css("border-color", "#ffaaaa"); - $("#imgcreatewaiting").hide(); - - $("#createwalletalert").show(); - $("#createwalletalertmessage").html("The email address is already in use"); - - $("#btnCreate").prop('disabled', false); - $("#btnCreate").removeClass('disabled'); - $("#lnkOpenWallet").show(); - } - - if (result == "ErrCreateAccount") { - - $("#imgcreatewaiting").hide(); - $("#btnCreate").prop('disabled', false); - $("#btnCreate").removeClass('disabled'); - $("#lnkOpenWallet").show(); - - } + $("#dashheader").hide(); + $("#dashprofile").hide(); + $("#dashsend").show(); - } else { - //set variables for the session - $("#createWalletStart").hide(); - $('#createWalletStart input#cpassword').val(''); - $('#createWalletStart input#password1').val(''); + setTimeout(function () { + $("#addrfade").fadeIn(500); - $("#hotWalletPhrase").text(result.hotWalletPhrase); - $("#coldWalletPhrase").text(result.coldWalletPhrase); - //$("#ninkiWalletPhrase").text(result.ninkiWalletPhrase); + }, 500); - $("#walletGuid").text($('input#guid').val()); - $("#showPhrases").show(); - $("#securitywizard").show(); - if ($('#createWalletStart input#showQrCheckbox')[0].checked) { - //create two factor setting in databse and display qr code - $("#no2famessage").hide(); - showTwoFactorQr(); - } else { - $("#no2famessage").show(); - } - } - }); - } + $("#dashsendamt").hide(); + $("#mainWallet").hide(); + $(".footer").hide(); - } else { + $("#dashreceive").hide(); + $("#dashcontact").hide(); + $("#toAddress").blur(); + $("#qr").focus(); + $("#btnStdSndDone").hide(); - //password not strong - $("#createwalletalert").show(); - $("#createwalletalertmessage").html("Password must be Strong- ideally Very Strong"); - } + profilepagestate = "send"; + menustate = "profile" - } }); - $("#btnPassphraseLogin").click(function () { + $("#tapreceive").bind('touchstart', function () { - var isvalid = true; - - if ($('#createWalletStart input#showQrCheckbox')[0].checked) { - isvalid = $("#phrase2fa").parsley('validate'); - } - - if (isvalid) { - - var twoFactorCodeChk = $('#twoFactorCodeCheck').val(); - - var target = document.getElementById('imgphrasewaiting'); - var spinner = new Spinner(spinneropts).spin(target); - - $("#imgphrasewaiting").show(); - setCookie('guid', Engine.m_oguid); - - Engine.openWalletAfterCreate(twoFactorCodeChk, function (err, result) { - - if (err) { - - $("#imgphrasewaiting").hide(); - $("#phraseloginerror").show(); - $("#phraseloginerrormessage").html(result); - - } else { - - - initialiseUI(); - $("#imgphrasewaiting").hide(); - $("#phraseloginerror").hide(); - $("#validateemail").show(); - $("#step4").show(); - $("#step3").hide(); - $("#listep3").removeClass("active"); - $("#listep4").addClass("active"); - $("#prgsecwiz").width('100%'); - $(".next").hide(); - $(".previous").hide(); - } - - - }); - } + //dashreceive + $("#dashheader").hide(); + $("#dashprofile").hide(); + $("#dashsend").hide(); + $("#mainWallet").hide(); + $("#dashreceive").show(); + $(".footer").hide(); + $("#dashcontact").hide(); + profilepagestate = "receive"; + menustate = "profile" }); + $("#taprequest").bind('touchstart', function () { + //$("#dashprofile").hide(); + //$("#dashsend").hide(); + //$("#dashreceive").hide(); + $("#mainWallet").hide(); + $("#networklistheader").hide(); + $("#dashcontact").show(); + $(".footer").hide(); - $("#btnEmailValidate").click(function () { - - var token = $("#txtEmailToken").val(); - - Engine.getEmailValidation(token, function (err, response) { - - if (err) { - - } else { - - if (response != "Valid") { - $("#valemailerror").show(); - - if (response == "Expired") { - $("#valemailerrormessage").html('Your token has expired'); - } - if (response == "Invalid") { - $("#valemailerrormessage").html('Your token is not valid'); - } - - - - } else { - - if ($('#createWalletStart input#showQrCheckbox')[0].checked) { - //TWOFACTORONLOGIN = true; - } - - //initialiseUI(); - Engine.m_validate = false; - - //readAccountSettingsFromServerAndPopulateForm(); - $("#securitywizard").hide(); - $("#validateemail").hide(); - $("#mainWallet").show(); - $("#valemailerror").hide(); - } - } - - }); - - - //call to verify token + //checkAndValidateTimer = setInterval(function () { checkAndValidateFriendRequests() }, 2000); + //profilepagestate = "contact"; + //menustate = "profile" }); - //wallet security wizard - var step = 1; - $("#step1").show(); - $("#prgsecwiz").width('25%'); - $(".previous").hide(); - $(".next").click(function () { - - if (step == 2) { - $("#step3").show(); - $("#step2").hide(); - $("#listep2").removeClass("active"); - $("#listep3").addClass("active"); - $("#prgsecwiz").width('75%'); - $(".next").hide(); - $(".previous").show(); - step++; - } - - if (step == 1) { - $("#step2").show(); - $("#step1").hide(); - $("#listep1").removeClass("active"); - $("#listep2").addClass("active"); - $("#prgsecwiz").width('50%'); - $(".previous").show(); - - step++; - } + $('#imgProfileContainer').show(); + $("#dropzone").hide(); + $("#btnSaveProfile").hide(); + $("#btnCancelProfile").hide(); + $("#statusedit").hide(); + $("#imgreset").hide(); - }); - $(".previous").click(function () { - - if (step == 2) { - $("#step1").show(); - $("#step2").hide(); - $("#listep2").removeClass("active"); - $("#listep1").addClass("active"); - $("#prgsecwiz").width('25%'); - $(".previous").hide(); - $(".next").show(); - step--; - } + $("#btnEditProfile").bind('touchstart', function () { - if (step == 3) { - $("#step2").show(); - $("#step3").hide(); - $("#listep3").removeClass("active"); - $("#listep2").addClass("active"); - $("#prgsecwiz").width('50%'); - $(".previous").show(); - $(".next").show(); - step--; - } + key = ''; - if (step == 4) { - $("#step3").show(); - $("#step4").hide(); - $("#listep4").removeClass("active"); - $("#listep3").addClass("active"); - $("#prgsecwiz").width('75%'); - $(".previous").show(); - $(".next").hide(); - step--; - } + $('#imgProfileContainer').hide(); + $("#dropzone").show(); + $("#btnSaveProfile").show(); + $("#btnCancelProfile").show(); + $("#btnEditProfile").hide(); + $("#statusedit").show(); + $("#profnmests").hide(); + $("#imgreset").show(); + $("#txtStatusText").val(Engine.m_statusText); }); + $("#imgreset").bind('touchstart', function () { + Engine.m_profileImage = ""; + imgReset = true; + var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; + document.getElementById('imgProfile').src = imageSrc; + $('#imgProfileContainer').show(); + $('#dropzone').hide(); + $('progressNumber').text(''); + $("#imgreset").hide(); - - - - $("#btnReset2fa").click(function () { - - //stretch password - //download the recovery packet - //decrypt - //return shared secret - //no feedback apart from, please check your email - var fguid = $("#txtreset2faguid").val(); - var fusername = $("#txtreset2fausername").val(); - var fpwd = $("#txtreset2fapassword").val(); - - $("#reset2faerror").hide(); - $("#reset2fasuccess").hide(); - - Engine.ResetTwoFactor(fguid, fusername, fpwd, function (err, results) { - - if (err) { - $("#reset2faerror").show(); - $("#reset2faerrormessage").html('There was an error'); - } else { - $("#validate2fareset").show(); - $("#reset2fa").hide(); - } - }); - - }); - - - $("#btnhidekeys").click(function () { - $("#secdisphrase").hide(); - $("#secdisninki").hide(); - $("#btnhidekeys").hide(); - $("#btndisplaykeys").show(); }); - $("#btndisplaykeys").click(function () { - - //get the wallet packet - //secdisphrase - - var ninkiPub = Engine.m_walletinfo.ninkiPubKey; - var phrase = Engine.m_walletinfo.hotHash; - - var bip39 = new BIP39(); // 'en' is the default language - var hotmnem = bip39.entropyToMnemonic(phrase); + var imgReset = false; + $("#btnSaveProfile").bind('touchstart', function () { - $("#secdisphrase").html(hotmnem); - $("#secdisninki").html(ninkiPub); - $("#secdisphrase").show(); - $("#secdisninki").show(); - $("#btnhidekeys").show(); - $("#btndisplaykeys").hide(); + //updateUserProfile - }); + var statusText = $("#txtStatusText").val(); + if (key == '' && !imgReset) { + key = Engine.m_profileImage; + } - //depreciated - $("#btn2faResetValidate").click(function () { + Engine.updateUserProfile(key, statusText, Engine.m_invoiceTax, function (err, result) { - var vtoken = $("#txt2faResetToken").val(); + if (!err) { - Engine.EmailValidationForTwoFactor(vtoken, 0, function (err, response) { - if (err) { + var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; + var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; - } else { + if (key != '' && !imgReset) { + imageSrc = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; + imageSrcSmall = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0"; + } - if (response != "Valid") { - $("#val2fatokenerror").show(); + $("#imgProfile").attr("src", imageSrc); + $("#imgtoprightprofile").attr("src", imageSrcSmall); - if (response == "Expired") { - $("#val2fatokenerrormessage").html('Your token has expired'); - } - if (response == "Invalid") { - $("#val2fatokenerrormessage").html('Your token is not valid'); - } + $('#imgProfileContainer').show(); + $("#dropzone").hide(); + $("#btnSaveProfile").hide(); + $("#btnCancelProfile").hide(); + $("#btnEditProfile").show(); + $("#statusedit").hide(); + $("#mystatus").text(statusText); + $("#txtStatusText").val(statusText); + $("#profnmests").show(); + $("#imgreset").hide(); + imgReset = false; + $("#profileimgfile").val(''); + $("#progressNumber").val(''); - } else { - $("#val2fatoken").hide(); - $("#val2fatokenerror").hide(); - location.reload(); - } } }); }); + $("#btnCancelProfile").bind('touchstart', function () { - //transaction filters - - $("#optDay").click(function () { - trasactionFilterOn = true; - currentTransactionFilter = 'Day'; - lastNoOfTrans = -1; - updateTransactions(); - }); - - $("#optWeek").click(function () { - trasactionFilterOn = true; - currentTransactionFilter = 'Week'; - lastNoOfTrans = -1; - updateTransactions(); - }); - - $("#optMonth").click(function () { - trasactionFilterOn = true; - currentTransactionFilter = 'Month'; - lastNoOfTrans = -1; - updateTransactions(); - }); - - $('#btntransearch').click(function () { - trasactionFilterOn = true; - currentTransactionFilter = 'Search'; - lastNoOfTrans = -1; - updateTransactions(); - }); - - $('#btntranclear').click(function () { - trasactionFilterOn = false; - currentTransactionFilter = ''; - lastNoOfTrans = -1; - updateTransactions(); - $("#optDay").removeClass('active'); - $("#optWeek").removeClass('active'); - $("#optMonth").removeClass('active'); - $("#txttransearch").val(''); - - }); - - - $('#thtrandate').click(function () { - - //reset contact widget - if (currentTransactionSort == 'ContactDesc') { - $('#thtrancontact').toggleClass('active'); - } - - if (currentTransactionSort == 'DateDesc') { - currentTransactionSort = 'DateAsc'; - } else { - currentTransactionSort = 'DateDesc'; - } - - trasactionSortOn = true; - lastNoOfTrans = -1; - updateTransactions(); - }); + $('#imgProfileContainer').show(); + $("#dropzone").hide(); + $("#btnSaveProfile").hide(); + $("#btnCancelProfile").hide(); + $("#btnEditProfile").show(); - $('#thtrancontact').click(function () { + //reset profile image - //reset date widget - if (currentTransactionSort == 'DateDesc') { - $('#thtrandate').toggleClass('active'); - } + var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png"; - if (currentTransactionSort == 'ContactAsc') { - currentTransactionSort = 'ContactDesc'; - } else { - currentTransactionSort = 'ContactAsc'; + if (Engine.m_profileImage != '') { + imageSrc = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; } - trasactionSortOn = true; - lastNoOfTrans = -1; - updateTransactions(); - }); + $("#imgProfile").attr("src", imageSrc); - $('#tpagfirst').click(function () { - currentPageIndex = 0; - lastNoOfTrans = -1; - updateTransactions(); + $("#statusedit").hide(); + $("#profnmests").show(); + $("#imgreset").hide(); }); - $('#tpaglast').click(function () { - currentPageIndex = Math.floor((filteredTransactions.length / transactionsPerPage)); - lastNoOfTrans = -1; - updateTransactions(); - - }); + var obj = $("#dropzone"); - $('#tpagnext').click(function () { - if (currentPageIndex < Math.floor((filteredTransactions.length / transactionsPerPage))) { - currentPageIndex = currentPageIndex + 1; - lastNoOfTrans = -1; - updateTransactions(); - } + obj.click(function () { + $("#profileimgfile").click(); }); - $('#tpagprev').click(function () { - if (currentPageIndex > 0) { - currentPageIndex = currentPageIndex - 1; - lastNoOfTrans = -1; - updateTransactions(); - } - }); + $("#profileimgfile").change(function (e) { + var control = document.getElementById("profileimgfile"); + var files = control.files; + //alert(files[0]); + //We need to send dropped files to Server + handleFileUpload(files, obj); - //invoice filters - //for me - $("#optPending").click(function () { - invoiceFilterOn = true; - currentInvoiceFilter = 'Pending'; - lastInvoiceToPayCount = -1; - showInvoiceList(); }); - $("#optPaid").click(function () { - invoiceFilterOn = true; - currentInvoiceFilter = 'Paid'; - lastInvoiceToPayCount = -1; - showInvoiceList(); + obj.on('dragenter', function (e) { + e.stopPropagation(); + e.preventDefault(); + $(this).css('border', '2px solid #0B85A1'); }); - $("#optRejected").click(function () { - invoiceFilterOn = true; - currentInvoiceFilter = 'Rejected'; - lastInvoiceToPayCount = -1; - showInvoiceList(); + obj.on('dragover', function (e) { + e.stopPropagation(); + e.preventDefault(); }); - $("#optClearInvoice").click(function () { - invoiceFilterOn = false; - currentInvoiceFilter = ''; - lastInvoiceToPayCount = -1; - showInvoiceList(); - }); + obj.on('drop', function (e) { - $('#btnSearchInvForMe').click(function () { - currentForMeInvoicePageIndex = 0; - invoiceFilterOn = true; - currentInvoiceFilter = 'Search'; - lastInvoiceToPayCount = -1; - showInvoiceList(); + $(this).addClass("b-dashed"); + $(this).addClass("b-light"); + e.preventDefault(); + var files = e.originalEvent.dataTransfer.files; + //alert(files[0]); + //We need to send dropped files to Server + handleFileUpload(files, obj); }); - - - - //by me - //invoice filters - $("#optByMePending").click(function () { - invoiceByMeFilterOn = true; - currentByMeInvoiceFilter = 'Pending'; - lastInvoiceByUserCount = -1; - showInvoiceByUserList(); + $(document).on('dragenter', function (e) { + e.stopPropagation(); + e.preventDefault(); }); - $("#optByMePaid").click(function () { - invoiceByMeFilterOn = true; - currentByMeInvoiceFilter = 'Paid'; - lastInvoiceByUserCount = -1; - showInvoiceByUserList(); + $(document).on('dragover', function (e) { + e.stopPropagation(); + e.preventDefault(); + obj.css('border', '2px dotted #0B85A1'); }); - $("#optByMeRejected").click(function () { - invoiceByMeFilterOn = true; - currentByMeInvoiceFilter = 'Rejected'; - lastInvoiceByUserCount = -1; - showInvoiceByUserList(); + $(document).on('drop', function (e) { + e.stopPropagation(); + e.preventDefault(); }); - $("#optByMeClear").click(function () { - invoiceByMeFilterOn = false; - currentByMeInvoiceFilter = ''; - lastInvoiceByUserCount = -1; - showInvoiceByUserList(); - }); + var key = ''; + function handleFileUpload(files, obj) { - $('#btnSearchInvByMe').click(function () { - currentByMeInvoicePageIndex = 0; - invoiceByMeFilterOn = true; - currentByMeInvoiceFilter = 'Search'; - lastInvoiceByUserCount = -1; - showInvoiceByUserList(); - }); + if (files.length > 0) { + var file = files[0]; + var fd = new FormData(); - $('#ibmpagfirst').click(function () { - currentByMeInvoicePageIndex = 0; - lastInvoiceByMeNetCount = -1; - showInvoiceByUserList(); - }); + key = "images\/" + Engine.m_nickname + '_' + (new Date).getTime() - $('#ibmpaglast').click(function () { - currentByMeInvoicePageIndex = Math.floor((filteredByMeInvoices.length / invoicesByMePerPage)); - lastInvoiceByMeNetCount = -1; - showInvoiceByUserList(); - }); + Ninki.API.post("/api/1/u/createS3Policy", { test: 'test' }, function (err, result) { - $('#ibmpagnext').click(function () { - if (currentByMeInvoicePageIndex < Math.floor((filteredByMeInvoices.length / invoicesByMePerPage))) { - currentByMeInvoicePageIndex = currentByMeInvoicePageIndex + 1; - lastInvoiceByMeNetCount = -1; - showInvoiceByUserList(); - } - }); + var policy = JSON.parse(result); - $('#ibmpagprev').click(function () { - if (currentByMeInvoicePageIndex > 0) { - currentByMeInvoicePageIndex = currentByMeInvoicePageIndex - 1; - lastInvoiceByMeNetCount = -1; - showInvoiceByUserList(); - } - }); + fd.append('key', key); + fd.append('acl', 'public-read'); + fd.append('Content-Type', file.type); + fd.append('bucket', 'ninkip2pimgstore'); + fd.append('AWSAccessKeyId', 'AKIAINOU56ATQFS3CLFQ'); + fd.append('policy', policy.s3Policy); + fd.append('signature', policy.s3Signature); + fd.append("file", file); + //fd.append("success_action_redirect", "https://localhost:1111/ok"); - //for me + var xhr = new XMLHttpRequest(); - $('#ifmpagfirst').click(function () { - currentForMeInvoicePageIndex = 0; - lastInvoiceToPayCount = -1; - showInvoiceList(); - }); + xhr.upload.addEventListener("progress", uploadProgress, false); + xhr.addEventListener("load", uploadComplete, false); + xhr.addEventListener("error", uploadFailed, false); + xhr.addEventListener("abort", uploadCanceled, false); - $('#ifmpaglast').click(function () { - currentForMeInvoicePageIndex = Math.floor((filteredForMeInvoices.length / invoicesForMePerPage)); - lastInvoiceToPayCount = -1; - showInvoiceList(); - }); + xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND - $('#ifmpagnext').click(function () { - if (currentForMeInvoicePageIndex < Math.floor((filteredForMeInvoices.length / invoicesForMePerPage))) { - currentForMeInvoicePageIndex = currentForMeInvoicePageIndex + 1; - lastInvoiceToPayCount = -1; - showInvoiceList(); - } - }); + xhr.send(fd); - $('#ifmpagprev').click(function () { - if (currentForMeInvoicePageIndex > 0) { - currentForMeInvoicePageIndex = currentForMeInvoicePageIndex - 1; - lastInvoiceToPayCount = -1; - showInvoiceList(); + }); } - }); - - - - getCookie('ninki_reg', function (res) { - if (res.length > 0) { - - showOpenWalletStart(); - - } else { - - showCreateWalletStart(); - } - }) + } - $("#password").keypress(function (e) { - if (e.which == 13) { - $("#btnLogin").click(); - } - }); - $("#twoFactorCode").keypress(function (e) { - if (e.which == 13) { - $("#btn2faLogin").click(); + function uploadProgress(evt) { + if (evt.lengthComputable) { + var percentComplete = Math.round(evt.loaded * 100 / evt.total); + document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; } - }); - - $("#password1").keypress(function (e) { - if (e.which == 13) { - $("#btnCreate").click(); + else { + document.getElementById('progressNumber').innerHTML = 'unable to compute'; } - }); - - - $("#cpassword").blur(function () { - $(".popover.fade.bottom.in").hide(); - }); - - $("#cpassword").focus(function () { - $(".popover.fade.bottom.in").show(); - }); - - $("#newpassword1").blur(function () { - $(".popover.fade.bottom.in").hide(); - }); - - $("#newpassword1").focus(function () { - $(".popover.fade.bottom.in").show(); - }); - - //$("#balance").html("... BTC"); - - $("#mainWallet").hide(); - $('#message').hide(); - $("#openwalletalert").hide(); - $("#createwalletalert").hide(); - $("#imgopenwaiting").hide(); - $("#imgcreatewaiting").hide(); - $("#showPhrases").hide(); - $("#twoFactorQr").hide(); - $("#2factor1").hide(); - $("#securitywizard").hide(); - $("#secdisphrase").hide(); - $("#secdisninki").hide(); - $("#btnhidekeys").hide(); - - $("#btnSendToFriend").hammer(null).bind("tap", function () { - - - sendMoney(SELECTEDFRIEND, 0); - - - }); - $("#sendfriendprog").hide(); - - $("#hforgotguid").click(function () { - - $("#createWalletStart").hide(); - $("#openWalletStart").hide(); - $("#lostguid").show(); - $("#reset2fa").hide(); - }); - - - $("#hlost2fa").click(function () { - - $("#createWalletStart").hide(); - $("#openWalletStart").hide(); - $("#lostguid").hide(); - $("#reset2fa").show(); - - }); - - - $("#emailresend").click(function () { - - Engine.sendWelcomeDetails(function (err, result) { - - if (!err) { - - $("#emailresendmessage").show(); - $("#emailresend").hide(); - //email has been resent, please check your email - } - - }); - - }); - - - $("#cpassword").on('change keyup', function () { - - $("#password1").parsley("validate"); - - }); - - - $("#twoFactorCodeCheck").on('change keyup', function () { - - $("#phraseloginerror").fadeOut(100); - - }); - - - $("#btnChangePassword").click(function () { - - $("#chngpwssuc").hide(); - $("#chngpwerr").hide(); - $("#chngpwdprog").hide(); - $("#chngpwdprogbar").width('0%'); - - var newpassword = $("#newpassword1").val(); - var oldpassword = $("#oldpwd").val(); - var twoFactorCode = $("#txtTwoFactorCodeForChangePwd").val(); - - if ($("#frmpwdchange").parsley('validate')) { - - $("#chngpwdprog").show(); - $("#chngpwdprogmess").show(); - $("#chngpwdprogbar").width('10%'); - $("#chngpwdprogmess").html('Getting packet...'); - - - if (oldpassword != newpassword) { - - //check password strength - if (($(".newpwstrength_viewport_progress .password-verdict").html() == 'Strong' || $(".newpwstrength_viewport_progress .password-verdict").html() == 'Very Strong')) { + } - //stretch old password - //verify that it matches the current one - $("#chngpwdprogbar").width('20%'); - $("#chngpwdprogmess").html('Getting details...'); + function uploadComplete(evt) { + /* This event is raised when the server send back a response */ + //alert("Done - " + evt.target.responseText); + document.getElementById('imgProfile').src = 'https://ninkip2p.imgix.net/' + key + "?fit=crop&crop=faces&h=128&w=128&mask=ellipse&border=1,d0d0d0"; + $('#imgProfileContainer').show(); + $('#dropzone').hide(); + $('progressNumber').text(''); + $("#imgreset").hide(); - setTimeout(function () { + } - Engine.ChangePassword(twoFactorCode, oldpassword, newpassword, "#chngpwdprogbar", "#chngpwdprogmess", function (err, results) { + function uploadFailed(evt) { + alert("There was an error attempting to upload the file." + evt); + } - if (err) { - $("#chngpwerr").show(); - $("#chngpwerrmess").html(results); - $("#chngpwdprogmess").hide(); - $("#chngpwdprog").hide(); + function uploadCanceled(evt) { + alert("The upload has been canceled by the user or the browser dropped the connection."); + } - } else { + }); - password = results; - $("#chngpwerr").hide(); - $("#chngpwdprogbar").width('100%'); - $("#chngpwdprog").hide(); - $("#chngpwdprogmess").hide(); - $("#chngpwdprogbar").hide(); - $("#chngpwssuc").show(); - $("#newpassword1").val(''); - $("#newpassword2").val(''); - $("#oldpwd").val(''); - $("#txtTwoFactorCodeForChangePwd").val(''); - } + $(document).ready(function () { - }); + $("#pairdeviceblob").change(function () { - }, 500); - } + $("#loginpin").hide(); + $("#pairstep1").hide(); + $("#pairstep2").show(); - } else { - $("#chngpwerr").show(); - $("#chngpwerrmess").html("Passwords are the same. Password not updated"); - $("#chngpwdprogmess").hide(); - $("#chngpwdprog").hide(); - } - } }); - $("#btnVerify").click(function () { - - var code = $("#txtCode").val(); - - $("#txtCode").css("border-color", "#ccc"); - $("#validatefail").hide(); - $("#validatesuccess").hide(); - - var bip39 = new BIP39(); - code = bip39.mnemonicToHex(code); - - if (code.length != 40) { - $("#txtCode").css("border-color", "#ffaaaa"); - return; - } - - //get the hash to validate against - //this will confirm that my friend has the same keys - //i orginally packaged for him - - Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { - - if (result) { - $("#validateform").hide(); - $("#validatesuccess").show(); - $("#txtCode").val(''); - selectedFriend.validated = true; - FRIENDSLIST[selectedFriend.userName].validated = true; - updateSelectedFriend(); - - //update list also + $("#btnUnpair").click(function () { - //find friend in list and update the validated icon - $("#myfriends #seltarget" + selectedFriend.userName).html('
'); + //return; + getCookie("guid", function (guid) { + Engine.m_oguid = guid; - } else { - $("#validatefail").show(); + var bytes = []; + for (var i = 0; i < guid.length; ++i) { + bytes.push(guid.charCodeAt(i)); } - }); - }); - - - $("#btnSetupTwoFactor").click(function () { - - $("#twofactorsettings").show(); - $("#btnSetupTwoFactor").hide(); - $("#savetwofactorerror").hide(); - $("#setup2faemail").hide(); - $("#setup2faqr").show(); - showSettingsTwoFactorQr(); - - }); - - - $("#btnSaveTwoFactor").click(function () { + Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); - //validate authenticator code - //switch on two factor on login - //setting changes always require two factor - if ($("#frmSaveTwoFactor").parsley('validate')) { + Engine.destroyDevice(function (err, res) { - var twoFactorCode = $("#txtsettings2fa").val(); - var verifyToken = $("#txt2faVerifyToken").val(); + deleteCookie("ninki_rem"); + deleteCookie("ninki_p"); + deleteCookie("ninki_reg"); + deleteCookie("ninki_h"); - Engine.SaveTwoFactor(twoFactorCode, verifyToken, function (err, result) { + //call to server + location.reload(); - if (!err) { - //ok - $("#setup2faemail").show(); - $("#setup2faqr").hide(); - readAccountSettingsFromServerAndPopulateForm(); - } else { - //error - $("#savetwofactorerror").show(); - $("#savetwofactorerrormessage").show(); - $("#savetwofactorerrormessage").html(result); - } }); - } - }); - - $("#btn2faVerifyEmail").click(function () { - - - var vtoken = $("#txt2faVerifyToken").val(); - - Engine.EmailValidationForTwoFactor(vtoken, 1, function (err, response) { - - if (!err) { - - - //TWOFACTORONLOGIN = true; - //refresh settings panel - - readAccountSettingsFromServerAndPopulateForm(); - - $("#twofactorsettings").hide(); - $("#btnSetupTwoFactor").hide(); - $("#savetwofactorerror").hide(); - $("#savetwofactorerrormessage").hide(); - $("#setup2faemail").hide(); - $("#setup2faqr").hide(); - - - } else { - - //TO DO: - //report error here - - } - - }); }); - $("#hsettings").click(function () { - readAccountSettingsFromServerAndPopulateForm(); - }); + $("#btnPairDevice").bind('click', function () { - $("#savesettingsbutton").click(function () { - if ($("#frmsettings").parsley('validate')) { - saveAccountSettingsToServer(); + var deviceid = "DEVICE123456789"; + if (window.cordova) { + deviceid = window.device.uuid; } - }); - Engine.fillElementWithGuid($("#createWalletStart input#guid")); + var blob = $('#pairdeviceblob').val(); + var pin = $('#pairdevicepinnumber').val(); + var pwd = $('#pairpwd').val(); + - //INVOICE STUFF START------------------------------------------ + var splitBlob = blob.split('|'); - $("#friendselector").hide(); - $("#invoice").hide(); - $("#invoicedisplay").hide(); + var enck = splitBlob[0]; + var iv = splitBlob[1]; + var guid = splitBlob[2]; + var deviceName = splitBlob[3]; + var regToken = splitBlob[4]; - $("#btnpayinvoice").hammer(null).bind("tap", function () { - payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId); + Engine.setPass(pwd, guid); - }); + pwd = Engine.m_password; - $("#btnrejectinvoice").hammer(null).bind("tap", function () { + var bytes = []; + for (var i = 0; i < guid.length; ++i) { + bytes.push(guid.charCodeAt(i)); + } - Engine.updateInvoice(selectedInvoiceUserName, selectedInvoiceId, '', 2, function (err, result) { + var hashguid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); - lastInvoiceToPayCount = 0; - showInvoiceList(); - showInvoiceListNetwork(); - $("#invoicedisplay").hide(); - $("#invoicestopay").show(); - $("#createinv").show(); + Engine.m_guid = hashguid; + Engine.m_oguid = guid; - if (uiInvoiceReturnToNetwork) { - updateSelectedFriend(); - } - }); + //first validate the password with the secret + Engine.getRecoveryPacket(function (err, response) { - }); + if (err) { - $("#payinvoicecancel").hammer(null).bind("tap", function () { + $('#pairdevicealertmessage').text(response); + } else { - $("#invoices").hide(); - $("#network").show(); + //decrypt packet - //if (uiInvoiceReturnToNetwork) { - //$("#hnetwork").click(); - //uiInvoiceReturnToNetwork = false; - //} + var jpacket = JSON.parse(response); + var secret = Engine.decryptNp(jpacket.packet, pwd, jpacket.IV); - }); + Engine.validateSecret(secret, function (err, secvalid) { + if (!err) { - $("#invoicecancel").click(function () { - $("#invoicestopay").show(); - $("#createinv").show(); - }); - $("#sendinvoicecancel").click(function () { + //hash the pin and device id - $("#invoicedisplay").hide(); - $("#invoice").hide(); - $("#invoicestopay").show(); - $("#hnetwork").click(); - }); + var pinhash = deviceid + pin; + bytes = []; + for (var i = 0; i < pinhash.length; ++i) { + bytes.push(pinhash.charCodeAt(i)); + } + pinhash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString(); - $("#sendinvoice").click(function () { - calcInvoiceTotals(); + //new register device - var subtotal = $("#tblinvoice tfoot th #subtotal").html(); - var tax = $("#tblinvoice tfoot th #tax").html(); - var total = $("#tblinvoice tfoot th #total").html(); - if (subtotal > 0) { + //enter password + //stretch + //get validate + //if valid + //choose a PIN + //register - if (validateInvoice()) { - //parse the table and generate objects - var invoicelines = []; - $("#tblinvoice tbody tr").each(function () { - var tmpVals = []; - $(this).find('input').each(function () { - tmpVals.push($(this).val()); - }); - if (tmpVals[0] != null) { - invoicelines.push({ - description: tmpVals[0], - quantity: tmpVals[1], - amount: convertToSatoshis(tmpVals[2], COINUNIT) - }); - } - }); + var devplatform = "platform"; + var devmodel = "model"; + if (window.cordova) { + devplatform = window.device.platform; + devmodel = window.device.model; + } - var summary = { - subtotal: convertToSatoshis(subtotal, COINUNIT), - tax: convertToSatoshis(tax, COINUNIT), - total: convertToSatoshis(total, COINUNIT) - }; - var invoice = { - summary: summary, - invoicelines: invoicelines - }; - createNewInvoice(invoiceSelectedUser, invoice, function (err, invoices) { + Engine.registerDevice(hashguid, deviceName, devplatform, devmodel, pinhash, regToken, secret, function (err, result) { - $("#invoicestopay").show(); - $("#createinv").show(); - $("#invoice").hide(); + if (!err) { + var dk = JSON.parse(result); - $("#hnetwork").click(); - lastInvoiceByUserCount = -1; - lastInvoiceByMeNetCount = -1; + if (dk.DeviceKey.length > 0) { - showInvoiceByUserList(function (err, result) { + var decblob = Engine.decryptNp(enck, dk.DeviceKey, iv); - showInvoiceByMeListNetwork(function (err, result) { + //slice it up + //64 64 64 + var hk = decblob.substring(0, 64); + var fatoken = decblob.substring(64, 128); + var encp = Engine.encryptNp(pwd, dk.DeviceKey); + result = ''; - }); + var ptok = {}; + ptok.ct = encp.toString(); + ptok.iv = encp.iv.toString(); + var ptoken = JSON.stringify(ptok); - }); + var enc = Engine.encryptNp(fatoken, dk.DeviceKey); + var ctok = {}; + ctok.ct = enc.toString(); + ctok.iv = enc.iv.toString(); - //updateSelectedFriend(); + var ctoken = JSON.stringify(ctok); - }); - } - } - }); + var ench = Engine.encryptNp(hk, dk.DeviceKey); + var htok = {}; + htok.ct = ench.toString(); + htok.iv = ench.iv.toString(); + var hkey = JSON.stringify(htok); - $("#btnCreateInvFriend").click(function () { + dk.DeviceKey = ''; - $("#invoicestopay").hide(); - $("#invoicedisplay").hide(); - uiInvoiceReturnToNetwork = true; - invoiceSelectedUser = SELECTEDFRIEND; - lineCount = 0 - $("#createinvoiceforlabel").html('Create an Invoice for ' + SELECTEDFRIEND); - $("#tblinvoice tbody").empty(); + //login using the credentials + //get a session + //then call register PIN + //this will return the encryption key + //encrypt the password and store in local storage - $("#friendselector").hide(); - $("#invoice").show(); - //write a new one - $("#addline").click(); - $("#hinvoices").click(); + setCookie("guid", guid); - }); + Engine.openWallet(guid, fatoken, function (err, result) { + if (!err) { + if (!result.TwoFactorOnLogin) { - $("#lineAmount").keypress(function (e) { - if (e.which == 13) { + setCookie("ninki_rem", ctoken); + setCookie("ninki_p", ptoken); + setCookie("ninki_reg", regToken); + setCookie("ninki_h", hkey); - $("#addline").click(); + $('#pairDevice').hide(); - } - }); + initialiseDashboard(); - $("#addline").click(function () { + } else { - if (validateInvoice()) { - //recalc everything - lineCount++; + $('#pairdevicealertmessage').text("could not pair"); + $('#pairdevicealert').show(); + } - $('#tblinvoice tbody').append(getRowTempate()); - $('#line' + lineCount + 'desc').focus(); - $('#addline' + lineCount).click({ - line: lineCount - }, function (event) { - $('#tblinvoice #row' + event.data.line).remove(); - validateInvoice(); - }); + } else { - $('#line' + lineCount + 'Amount').blur({ - line: lineCount - }, function (event) { - if (validateInvoice()) { - $('#lineTotal' + (event.data.line)).html(($('#line' + (event.data.line) + 'Amount').val() * $('#line' + (event.data.line) + 'Quantity').val()).toFixed(4)); - calcInvoiceTotals(); - } else { - //$('#line' + (event.data.line) + 'Amount'). - } - }); + $('#pairdevicealertmessage').text(result); + $('#pairdevicealert').show(); + } + }); + } else { - $('#line' + lineCount + 'Quantity').blur({ - line: lineCount - }, function (event) { - if (validateInvoice()) { - $('#lineTotal' + (event.data.line)).html(($('#line' + (event.data.line) + 'Amount').val() * $('#line' + (event.data.line) + 'Quantity').val()).toFixed(4)); - calcInvoiceTotals(); - } else { - //$('#line' + (event.data.line) + 'Amount'). - } - }); + $('#pairdevicealertmessage').text("The pairing token has expired"); + $('#pairdevicealert').show(); + } - $('#line' + lineCount + 'desc').blur(function (event) { - validateInvoice(); - }); + } else { - $('#line' + lineCount + 'Amount').keypress({ - line: lineCount - }, function (e) { - if (e.which == 13) { - $('#line' + lineCount + 'Amount').blur(); - $("#addline").click(); + $('#pairdevicealertmessage').text(result); + $('#pairdevicealert').show(); - } - }); + } - $('#line' + lineCount + 'desc').keydown({ - line: lineCount - }, function (e) { - if (e.which == 8) { - if ($('#line' + lineCount + 'desc').val() == '' && $('#line' + lineCount + 'Amount').val() == '' && $('#line' + lineCount + 'Quantity').val() == '') { - $('#tblinvoice #row' + e.data.line).remove(); - } - } - }); + }); - } - //write a new one + } else { - }); + $('#pairdevicealertmessage').text(secvalid); + $('#pairdevicealert').show(); + } - //openWallet(); - $("#openWalletStart #password").focus(); - }); + }); + } - function calcInvoiceTotals() { - var subTotal = 0; - $('#tblinvoice .lineTotal').each(function () { + }); - subTotal += ($(this).html() * 1); }); - $("#subtotal").html(subTotal.toFixed(4)); - $("#tax").html((subTotal * 0.10).toFixed(4)); - $("#total").html((subTotal + (subTotal * 0.10)).toFixed(4)); - - }; - function validateInvoice() { - var subTotal = 0; + $("#btnaddfriend").bind('touchstart', function () { - var isValid = true; + addFriend($('input#friend').val()); - $('#tblinvoice .amount').each(function () { + }); - var vval = $(this).val(); - var visValid = true; - if ($.isNumeric(vval)) { + $("#btngenaddr").bind('touchstart', function () { - if ((vval * 1) <= 0) { - //not valid - //highlight - isValid = false; - visValid = false; - } + generateAddressClient(); - } else { + }); - isValid = false; - visValid = false; - } - if (!visValid) { - $(this).css("border-color", "#ff0000"); - } else { - $(this).css("border-color", "#cbd5dd"); - } + //wallet security wizard - }); + //$("#balance").text("... BTC"); - $('#tblinvoice .quantity').each(function () { + $("#btnSendToFriend").bind('touchstart', function () { - var vval = $(this).val(); - var visValid = true; - if ($.isNumeric(vval)) { - if ((vval * 1) <= 0) { - //not valid - //highlight - isValid = false; - visValid = false; - } + sendMoney(SELECTEDFRIEND, 0); - } else { - isValid = false; - visValid = false; - } + }); - if (!visValid) { - $(this).css("border-color", "#ff0000"); - } else { - $(this).css("border-color", "#cbd5dd"); - } + $("#sendfriendprog").hide(); - }); + $("#hdvalcontact").change(function () { - $('#tblinvoice .desc').each(function () { + console.log('caught event...'); + var res = $("#hdvalcontact").val(); + var sres = res.split(','); + var phrase = sres[0]; + var username = sres[1]; - var vval = $(this).val(); - var visValid = true; - if (vval.length == 0) { - visValid = false; - isValid = false; - } + $("#netvalidprognum").text('30%'); + $("#netvalidprogmess").text('Validating contact...'); + $("#netvalidprog").width('30%'); - if (!visValid) { - $(this).css("border-color", "#ff0000"); - } else { - $(this).css("border-color", "#cbd5dd"); - } + setTimeout(function () { + var bip39 = new BIP39(); + code = bip39.mnemonicToHex(phrase); - }); + console.log(code); - if (isValid) { - calcInvoiceTotals(); + if (code.length != 40) { - //if (subTotal > 0) { - //$("#subtotal").html(subTotal.toFixed(4)); - //$("#tax").html((subTotal * 0.10).toFixed(4)); - //$("#total").html((subTotal + (subTotal * 0.10)).toFixed(4)); - //} else { - // isValid = false; - //} - } + return; + } - return isValid; - }; + //console.log(SELECTEDFRIEND); + //console.log(username); + if (SELECTEDFRIEND == username) { - var lineCount = 0; - function getRowTempate() { - var template = '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - ''; + $("#netvalidp2").show(); + $("#netvalidp1").hide(); + $("#netvalidprognum").text('50%'); + $("#netvalidprogmess").text('Validating contact...'); + $("#netvalidprog").width('50%'); + setTimeout(function () { + Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { - return template; - } + console.log(result); - var cachedInvoices = []; - var lastInvoiceToPayCount = 0; - function showInvoiceList(callback) { - //get back the list of invoices to pay + if (result) { - Engine.getInvoiceList(function (err, invoices) { + $("#netvalidprognum").text('100%'); + $("#netvalidprogmess").text('Contact validated'); + $("#netvalidprog").width('100%'); + //$("#validateform").hide(); + //$("#validatesuccess").show(); + $("#txtCode").val(''); + selectedFriend.validated = true; + FRIENDSLIST[selectedFriend.userName].validated = true; + updateSelectedFriend(); + $("#networkvalidate").hide(); + $("#friendheader").show(); + $("#mainWallet").show(); + $(".footer").show(); - if (lastInvoiceToPayCount < invoices.length) { + $("#netvalidp2").hide(); + $("#netvalidp1").show(); + //update list also - } else { + //find friend in list and update the validated icon + $("#myfriends #seltarget" + selectedFriend.userName).html('
'); - return callback(false, "done"); - } + } else { - for (var i = 0; i < invoices.length; i++) { - var d1 = new Date(invoices[i].InvoiceDate); - invoices[i].JsDate = d1; - } + $("#netvalidp2").hide(); + $("#netvalidp1").show(); + $("#validatefail").show(); + } - invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; }); + }); - filteredForMeInvoices = invoices; + }, 100); + } - //perform all filters then set back to invoices + }, 100); - if (currentInvoiceFilter == "Pending") { + }); - filteredForMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 0; }); - } + $("#btnVerify").bind('touchstart', function () { - if (currentInvoiceFilter == "Paid") { + var code = $("#txtCode").val(); - filteredForMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 1; }); - } + $("#txtCode").css("border-color", "#ccc"); + $("#validatefail").hide(); + $("#validatesuccess").hide(); - if (currentInvoiceFilter == "Rejected") { + var bip39 = new BIP39(); + code = bip39.mnemonicToHex(code); - filteredForMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 2; }); + if (code.length != 40) { + $("#txtCode").css("border-color", "#ffaaaa"); + return; } + //get the hash to validate against + //this will confirm that my friend has the same keys + //i orginally packaged for him - if (currentInvoiceFilter == "Search") { - var search = $('#txtSearchInvForMe').val(); - filteredForMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceFrom.search(search) > -1; }); - } + Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { + if (result) { - var noofpages = Math.floor((filteredForMeInvoices.length / invoicesForMePerPage)); + $("#txtCode").val(''); + selectedFriend.validated = true; + FRIENDSLIST[selectedFriend.userName].validated = true; + updateSelectedFriend(); + $("#networkvalidate").hide(); + $("#friendheader").show(); + $("#mainWallet").show(); + $(".footer").show(); + //update list also - var indexFrom = currentForMeInvoicePageIndex * invoicesForMePerPage; - var indexTo = indexFrom + invoicesForMePerPage; + //find friend in list and update the validated icon + $("#myfriends #seltarget" + selectedFriend.userName).html('
'); - if (indexTo > filteredForMeInvoices.length) { - indexTo = filteredForMeInvoices.length; - } - $('#invbmpaglabel').html('Showing ' + (indexFrom + 1) + ' to ' + (indexTo) + ' of ' + filteredForMeInvoices.length); + } else { + $("#validatefail").show(); + } + }); + }); - invoices = filteredForMeInvoices; - if (lastInvoiceToPayCount < invoices.length) { + //INVOICE STUFF START------------------------------------------ + $("#friendselector").hide(); + $("#invoice").hide(); + $("#invoicedisplay").hide(); - pagedForMeInvoices = filteredForMeInvoices.slice(indexFrom, indexTo); + $("#btnpayinvoice").bind('touchstart', function () { - invoices = pagedForMeInvoices; - cachedInvoices = []; + $(".footer").hide(); - lastInvoiceToPayCount = invoices.length; + $("#sendstds2add").text(SELECTEDFRIEND); - var s = ''; - $('#tblinvoicepay tbody').empty(); - for (var i = 0; i < invoices.length; i++) { + $("#sendstds2amt").text(convertFromSatoshis(selectedInvoiceAmount, COINUNIT) + ' ' + COINUNIT); - var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1).toLocaleString(); + sendmode = 'inv'; - var invpaydate = ''; - if (invoices[i].InvoicePaidDate) { - invpaydate = new Date(invoices[i].InvoicePaidDate.match(/\d+/)[0] * 1).toLocaleString(); - } + $("#mainWallet").hide(); + $("#pinconfirm").show(); - cachedInvoices.push(invoices[i]); - var statusbox = ''; - if (invoices[i].InvoiceStatus == 0) { - statusbox = ' Pending'; - } - else if (invoices[i].InvoiceStatus == 1) { - statusbox = ' Paid'; - } - else if (invoices[i].InvoiceStatus == 2) { - statusbox = ' Rejected'; - } + }); + $("#btnrejectinvoice").bind('touchstart', function () { - var length = invoices[i].InvoiceFrom.length; - if (length > 20) { - length = 20; - } + Engine.updateInvoice(selectedInvoiceUserName, selectedInvoiceId, '', 2, function (err, result) { - var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(length) + ".png"; + loadInvoices(function (err, res) { + lastInvoiceToPayCount = 0; - if (FRIENDSLIST[invoices[i].InvoiceFrom].profileImage != '') { - imageSrcSmall = "https://ninkip2p.imgix.net/" + FRIENDSLIST[invoices[i].InvoiceFrom].profileImage + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0"; - } + showInvoiceListNetwork(); - s += "" + invdate + ""; + $("#invoicedisplay").hide(); + $("#invoicestopay").show(); + $("#createinv").show(); - s += "\"\" "; + updateSelectedFriend(); - s += invoices[i].InvoiceFrom + ""; - s += "" + statusbox + "" + invpaydate + ""; - } + }); + }); - $('#tblinvoicepay tbody').append(s); + }); - for (var i = 0; i < invoices.length; i++) { + $("#payinvoicecancel").bind('touchstart', function () { - $("#tblinvoicepay #viewinvoice" + i).click({ - index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom - }, function (event) { - displayInvoice(event.data.index, event.data.username, 'forme', function (err, res) { - uiInvoiceReturnToNetwork = false; - //$('#hinvoices').click(); - }); - }); - } - } + $("#invoices").hide(); + $("#network").show(); + $("#pnlfriend").show(); + $("#friendheader").show(); + //if (uiInvoiceReturnToNetwork) { + //$("#hnetwork").click(); + //uiInvoiceReturnToNetwork = false; + //} - callback(); }); - } + }); var lastInvoiceToPayNetCount = 0; var uiInvoiceReturnToNetwork = false; + + var cachedInvoices = []; + var cachedInvoicesByUser = []; + function showInvoiceListNetwork() { var invoices = _.filter(cachedInvoices, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; }); @@ -3012,62 +2053,65 @@ function UI() { } - if (lastInvoiceToPayNetCount < invoices.length) { + //if (lastInvoiceToPayNetCount < invoices.length) { - lastInvoiceToPayNetCount = invoices.length; + lastInvoiceToPayNetCount = invoices.length; - var s = ''; - $('#invfornet').empty(); + var s = ''; + $('#invfornet').empty(); - for (var i = 0; i < invoices.length; i++) { + for (var i = 0; i < invoices.length; i++) { - var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1).toLocaleString(); + var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1); - var statusbox = ''; - if (invoices[i].InvoiceStatus == 0) { - statusbox = ' Pending'; - } - else if (invoices[i].InvoiceStatus == 1) { - statusbox = ' Paid'; - } - else if (invoices[i].InvoiceStatus == 2) { - statusbox = ' Rejected'; - } + var timeLabel = prettydate.format(invdate); - s += "
" + invdate + "
" + - "
" + statusbox + "
"; + var statusbox = ''; + if (invoices[i].InvoiceStatus == 0) { + statusbox = ' Pending'; + } + else if (invoices[i].InvoiceStatus == 1) { + statusbox = ' Paid'; } + else if (invoices[i].InvoiceStatus == 2) { + statusbox = ' Rejected'; + } + + s += "
" + _.escape(timeLabel) + "
" + + "
" + statusbox + "
"; + } - $('#invfornet').append(s); + $('#invfornet').append(s); - for (var i = 0; i < invoices.length; i++) { + for (var i = 0; i < invoices.length; i++) { - $("#invfornet #viewinvoicenetfrom" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", { - index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom - }, function (event) { + $("#invfornet #viewinvoicenetfrom" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", { + index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom + }, function (event) { - $("#invtapspinner").show(); - var target = document.getElementById('invtapspinner'); - var spinner = new Spinner(spinneropts).spin(target); + $("#invtapspinner").show(); + var target = document.getElementById('invtapspinner'); + var spinner = new Spinner(spinneropts).spin(target); - displayInvoice(event.data.index, event.data.username, 'forme', function (err, res) { - uiInvoiceReturnToNetwork = true; + displayInvoice(event.data.index, event.data.username, 'forme', function (err, res) { + uiInvoiceReturnToNetwork = true; - networkpagestate = "invoice"; - friendpagestate = "invoice"; + networkpagestate = "invoice"; + friendpagestate = "invoice"; - $("#invtapspinner").hide(); - $('#network').hide(); - $('#invoices').show(); + $("#invtapspinner").hide(); + $('#pnlfriend').hide(); + $("#friendheader").hide(); + $('#invoices').show(); - }); }); - } + }); + } - $('#invfornet').show(); + $('#invfornet').show(); - } + //} // $('#pnlfriendinv').show(); @@ -3079,8 +2123,6 @@ function UI() { var invoices = _.filter(cachedInvoicesByUser, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; }); - - if (invoices.length == 0) { $('#invbynet').empty(); $('#invbynet').hide(); @@ -3096,7 +2138,10 @@ function UI() { for (var i = 0; i < invoices.length; i++) { - var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1).toLocaleString(); + var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1); + + var timeLabel = prettydate.format(invdate); + var statusbox = ''; if (invoices[i].InvoiceStatus == 0) { @@ -3109,7 +2154,7 @@ function UI() { statusbox = ' Rejected'; } - s += "
" + invdate + "
" + + s += "
" + _.escape(timeLabel) + "
" + "
" + statusbox + "
"; } @@ -3132,7 +2177,8 @@ function UI() { friendpagestate = "invoice"; $("#invtapspinner").hide(); - $('#network').hide(); + $('#pnlfriend').hide(); + $("#friendheader").hide(); $('#invoices').show(); }); @@ -3149,166 +2195,6 @@ function UI() { } - var cachedInvoicesByUser = []; - var lastInvoiceByUserCount = 0; - function showInvoiceByUserList(callback) { - //get back the list of invoices to pay - - - Engine.getInvoiceByUserList(function (err, invoices) { - - for (var i = 0; i < invoices.length; i++) { - var d1 = new Date(invoices[i].InvoiceDate); - invoices[i].JsDate = d1; - } - - invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; }); - - filteredByMeInvoices = invoices; - - //perform all filters then set back to invoices - - if (currentByMeInvoiceFilter == "Pending") { - - filteredByMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 0; }); - } - - if (currentByMeInvoiceFilter == "Paid") { - - filteredByMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 1; }); - } - - if (currentByMeInvoiceFilter == "Rejected") { - - filteredByMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceStatus == 2; }); - } - - if (currentByMeInvoiceFilter == "Search") { - var search = $('#txtSearchInvByMe').val(); - filteredByMeInvoices = _.filter(invoices, function (inv) { return inv.InvoiceFrom.search(search) > -1; }); - } - - var noofpages = Math.floor((filteredByMeInvoices.length / invoicesByMePerPage)); - - var indexFrom = currentByMeInvoicePageIndex * invoicesByMePerPage; - var indexTo = indexFrom + invoicesByMePerPage; - - if (indexTo > filteredByMeInvoices.length) { - indexTo = filteredByMeInvoices.length; - } - - $('#invbmpaglabel').html('Showing ' + (indexFrom + 1) + ' to ' + (indexTo) + ' of ' + filteredByMeInvoices.length); - - invoices = filteredByMeInvoices; - - - if (lastInvoiceByUserCount < invoices.length) { - - - pagedByMeInvoices = filteredByMeInvoices.slice(indexFrom, indexTo); - - invoices = pagedByMeInvoices; - - cachedInvoicesByUser = []; - - lastInvoiceByUserCount = invoices.length; - - var s = ''; - $('#tblinvoicebyme tbody').empty(); - for (var i = 0; i < invoices.length; i++) { - - - var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1).toLocaleString(); - var invpaydate = ''; - if (invoices[i].InvoicePaidDate) { - invpaydate = new Date(invoices[i].InvoicePaidDate.match(/\d+/)[0] * 1).toLocaleString(); - } - - cachedInvoicesByUser.push(invoices[i]); - - var statusbox = ''; - if (invoices[i].InvoiceStatus == 0) { - statusbox = ' Pending'; - } - else if (invoices[i].InvoiceStatus == 1) { - statusbox = ' Paid'; - } - else if (invoices[i].InvoiceStatus == 2) { - statusbox = ' Rejected'; - } - - - var length = invoices[i].InvoiceFrom.length; - if (length > 20) { - length = 20; - } - - s += "" + invdate + "\"\" " + - invoices[i].InvoiceFrom + "" + statusbox + "" + invpaydate + ""; - } - - $('#tblinvoicebyme tbody').append(s); - - for (var i = 0; i < invoices.length; i++) { - - $("#tblinvoicebyme #viewinvoicebyuser" + i).click({ - index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom - }, function (event) { - displayInvoiceByUser(event.data.index, event.data.username, 'byme', function (err, res) { - - - }); - }); - } - - if (callback) { - callback(false, "ok"); - } - - } else { - - //no new invoices, but lets check for invoices with changed status - cachedInvoicesByUser = invoices; - - $('#tblinvoicebyme tbody tr .active').each(function (index, elem) { - var statusbox = ''; - if (cachedInvoicesByUser[index].InvoiceStatus == 0) { - statusbox = ' Pending'; - } - else if (cachedInvoicesByUser[index].InvoiceStatus == 1) { - statusbox = ' Paid'; - } - else if (cachedInvoicesByUser[index].InvoiceStatus == 2) { - statusbox = ' Rejected'; - } - //$(elem).html(''); - $(elem).html(statusbox); - }); - - $('#tblinvoicebyme tbody tr .paid').each(function (index, elem) { - - if (cachedInvoicesByUser[index].InvoiceStatus == 1 || cachedInvoicesByUser[index].InvoiceStatus == 1) { - - var invpaydate = ''; - if (cachedInvoicesByUser[index].InvoicePaidDate) { - invpaydate = new Date(cachedInvoicesByUser[index].InvoicePaidDate.match(/\d+/)[0] * 1).toLocaleString(); - } - - - $(elem).html(invpaydate); - } - - }); - - } - - if (callback) { - callback(false, "ok"); - } - - }); - } - var selectedInvoiceAmount = 0; @@ -3327,22 +2213,22 @@ function UI() { $('#tblinvdisplay tbody').empty(); var s = ''; for (var i = 0; i < json.invoicelines.length; i++) { - s += "" + json.invoicelines[i].description + "" + json.invoicelines[i].quantity + "" + convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) + "" + (convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) * json.invoicelines[i].quantity) + ""; + s += "" + _.escape(json.invoicelines[i].description) + "" + _.escape(json.invoicelines[i].quantity) + "" + _.escape(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT)) + "" + _.escape(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) * json.invoicelines[i].quantity) + ""; } $('#tblinvdisplay tbody').append(s); if (invtype == 'forme') { - $("#dinvusername").html('Invoice from ' + invoice.InvoiceFrom); + $("#dinvusername").text('Invoice from ' + invoice.InvoiceFrom); } else { - $("#dinvusername").html('Invoice to ' + invoice.InvoiceFrom); + $("#dinvusername").text('Invoice to ' + invoice.InvoiceFrom); } - $("#dinvdate").html(invdate); + $("#dinvdate").text(invdate); - $("#tblinvdisplay tfoot th #dsubtotal").html(convertFromSatoshis(json.summary.subtotal, COINUNIT)); - $("#tblinvdisplay tfoot th #dtax").html(convertFromSatoshis(json.summary.tax, COINUNIT)); - $("#tblinvdisplay tfoot th #dtotal").html(convertFromSatoshis(json.summary.total, COINUNIT)); + $("#tblinvdisplay tfoot th #dsubtotal").text(convertFromSatoshis(json.summary.subtotal, COINUNIT)); + $("#tblinvdisplay tfoot th #dtax").text(convertFromSatoshis(json.summary.tax, COINUNIT)); + $("#tblinvdisplay tfoot th #dtotal").text(convertFromSatoshis(json.summary.total, COINUNIT)); selectedInvoiceAmount = convertFromSatoshis(json.summary.total); selectedInvoiceId = invoice.InvoiceId; @@ -3361,7 +2247,7 @@ function UI() { if (!FRIENDSLIST[invoice.InvoiceFrom].validated) { $("#btnpayinvoice").addClass("disabled"); - $("#invvalt").html(invoice.InvoiceFrom); + $("#invvalt").text(invoice.InvoiceFrom); $("#invvalmess").show(); } else { $("#btnpayinvoice").removeClass("disabled"); @@ -3395,7 +2281,7 @@ function UI() { } $("#invdisstatus").html(statusbox); - $("#invdisid").html(invoice.InvoiceFrom.toUpperCase() + invoice.InvoiceId); + $("#invdisid").text(invoice.InvoiceFrom.toUpperCase() + invoice.InvoiceId); $("#invoicedisplay").show(); @@ -3448,33 +2334,30 @@ function UI() { } - function createNewInvoice(userName, invoice, callback) { + function payInvoice(friend, amount, invoiceNumber) { - Engine.createInvoice(userName, invoice, function (err, invoiceNo) { - return callback(err, invoiceNo); + var pin = $('#sendstdpin').val(); - }); + Engine.getDeviceKey(pin, function (err, ekey) { - } + if (!err) { - function payInvoice(friend, amount, invoiceNumber) { + $('#sendprogress').show(); + $('#pinconfirm').hide(); - $('#textMessageSendInv').removeClass('alert alert-danger'); - $('#textMessageSendInv').html('Creating transaction...'); - $('#textMessageSendInv').show(); - $('#sendinvprogstatus').width('3%') - $('#sendinvprog').show(); - $('#sendinvprogstatus').width('10%'); - var pin = $('#sendinvpin').val(); + $('#textMessageSendStd').text('Creating transaction...'); + $('#textMessageSendStd').show(); + $('#sendstdprogstatus').width('3%') + $('#sendstdprog').show(); + $('#sendstdprogstatus').width('10%'); - Engine.getDeviceKey(pin, function (err, ekey) { + $('#sendstdprognum').text('10%'); - if (!err) { - Engine.sendTransaction('invoice', friend, '', amount, ekey, function (err, transactionid) { + Engine.sendTransaction('invoice', friend, '', amount, ekey.DeviceKey, function (err, transactionid) { if (!err) { @@ -3482,17 +2365,21 @@ function UI() { if (!err) { - $('#textMessageSendInv').html('You paid invoice: ' + friend.toUpperCase() + invoiceNumber); - $('#textMessageSendInv').fadeOut(5000); - $('#sendinvprog').fadeOut(5000); + $('#textMessageSend').text('You paid invoice: ' + friend.toUpperCase() + invoiceNumber); + $('input#amount').text(''); + + updateStdAmount(); + + setTimeout(function () { + $("#btnStdSndDone").show(); + }, 100); + + $("#sendstdpin").val(''); + $('.numdone').attr("style", "background-color:white"); - //$("#invoicedisplay").hide(); - //$("#invoicestopay").show(); - //$("#createinv").show(); updateBalance(); - lastInvoiceToPayCount = 0; - showInvoiceList(); + //change status var statusbox = ' Paid'; @@ -3503,13 +2390,6 @@ function UI() { $("#payinvoicecancel").hide(); $("#btnpayinvoice").hide(); $("#btnrejectinvoice").hide(); - - //show ok - $("#btnokinvoice").show(); - - if (uiInvoiceReturnToNetwork) { - updateSelectedFriend(); - } } }); @@ -3517,11 +2397,11 @@ function UI() { } else { - $('#textMessageSendInv').addClass('alert alert-danger'); - $('#sendinvprogstatus').width('0%') + $('#textMessageSend').addClass('alert alert-danger'); + $('#sendstdprogstatus').width('0%') if (transactionid == "ErrInsufficientFunds") { - $('#textMessageSendInv').html('Transaction Failed: Waiting for funds to clear'); + $('#textMessageSend').text('Transaction Failed: Waiting for funds to clear'); } } @@ -3530,9 +2410,11 @@ function UI() { } else { - $('#textMessageSendInv').addClass('alert alert-danger'); - $('#sendinvprogstatus').width('0%') - $('#textMessageSendInv').html(ekey); + //display pin error + $('.numdone').attr("style", "background-color:white"); + $("#sendstdpin").val(''); + $('#confpinalert').show(); + $('#confpinalertmess').text(ekey); } @@ -3544,60 +2426,18 @@ function UI() { //INVOICE FUNCTIONS END------------------------------------------ - //OPEN/CREATE WALLET FUNCTIONS--------------------------------------------- - - //event handlers - - - - //wrapper functions - - function openWallet(guid, password, twoFactorCode, callback) { - - setCookie('guid', guid); - - Engine.openWallet(guid, twoFactorCode, function (err, result) { - - if (err) { - - return callback(err, result); - - } else { - - if (result.Beta12fa) { - - - //if we are migrating a beta1 account that uses 2fa - //request the 2fa code - - $("#si2fa").show(); - return callback(err, result); - - } else { - - if (result.TwoFactorOnLogin) { - return callback(err, result); - } else { - initialiseUI(); - } - } - - } - }); - - } - - function initialiseUI() { + function initialiseDashboard() { - $("#dashprofile").show(); $("#dashsend").hide(); $("#dashreceive").hide(); $("#dashcontact").hide(); $('#invoices').hide(); $('#network').hide(); $('#networklist').hide(); + $("#networklistheader").hide(); $('#settings').hide(); + $("#settingsheader").hide(); var length = Engine.m_nickname.length; if (length > 20) { @@ -3606,9 +2446,9 @@ function UI() { COINUNIT = Engine.m_settings.CoinUnit; - $("#mynickname").html(Engine.m_nickname); - $("#usernameProfile").html(Engine.m_nickname); - $("#mystatus").html(Engine.m_statusText); + $("#mynickname").text(Engine.m_nickname); + $("#usernameProfile").text(Engine.m_nickname); + $("#mystatus").text(Engine.m_statusText); var imageSrc = "images/avatar/128px/Avatar-" + pad(length) + ".png"; @@ -3623,97 +2463,116 @@ function UI() { $("#imgProfile").attr("src", imageSrc); $("#imgtoprightprofile").attr("src", imageSrcSmall); - //$("#codeForFriend").html(Engine.m_fingerprint); + $("#codeForFriend").text(Engine.m_fingerprint); - var data = Engine.m_fingerprint + ',' + Engine.m_nickname; - var options = { text: data, width: 172, height: 172 }; + Engine.getUserNetwork(function (err, friends) { - $('#fingerprintqr').html(''); - $('#fingerprintqr').qrcode(options); + FRIENDSLIST = {}; + for (var i = 0; i < friends.length; i++) { + FRIENDSLIST[friends[i].userName] = friends[i]; + } - Engine.getusernetworkcategory(function (err, categories) { + //prep the network tab + $("#networklist").show(); + //$("#networklistheader").show(); - var catOptions = ''; + var data = Engine.m_fingerprint + ',' + Engine.m_nickname; + var options = { text: data, width: 172, height: 172 }; - $("#netcatoptions").html(catOptions); - $("#nselnetcat").change(function () { + $('#fingerprintqr').text(''); + $('#fingerprintqr').qrcode(options); - $("#nselnetcat option:selected").each(function () { - //update selected friend category - Engine.updateusernetworkcategory(SELECTEDFRIEND, $(this).text(), function (err, result) { - //refresh friend list - if (!err) { - lastNoOfFriends = 0; - updateFriends(); - } + setInterval(function () { + + updateUI(); + + }, 10000); - }); - }); }); + }); + - if (!err) { + } - setInterval(function () { + function loadInvoices(callback) { - updateUI(); + //load the invoices into the cache + cachedInvoices = []; - }, 10000); + Engine.getInvoiceList(function (err, invoices) { - updateUI(); + for (var i = 0; i < invoices.length; i++) { + var d1 = new Date(invoices[i].InvoiceDate); + invoices[i].JsDate = d1; + } + invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; }); + for (var i = 0; i < invoices.length; i++) { - $('#showPhrases').hide(); - $("#openWalletStart").hide(); - $("#createWalletStart").hide(); + cachedInvoices.push(invoices[i]); - if (Engine.m_validate) { + } - $("#securitywizard").show(); - $("#step4").show(); - $("#step1").hide(); - $("#step2").hide(); - $("#step3").hide(); - $("#listep1").removeClass("active"); - $("#listep2").removeClass("active"); - $("#listep3").removeClass("active"); - $("#listep4").addClass("active"); - $("#prgsecwiz").width('100%'); - $(".next").hide(); - $(".previous").hide(); - $("#validateemail").show(); - $("#mainWallet").hide(); + cachedInvoicesByUser = []; - } else { + Engine.getInvoiceByUserList(function (err, invoices) { - $("#securitywizard").hide(); - $("#mainWallet").show(); - $("#validateemail").hide(); + for (var i = 0; i < invoices.length; i++) { + var d1 = new Date(invoices[i].InvoiceDate); + invoices[i].JsDate = d1; } - setAwayTimeout(600000); + invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; }); - } + for (var i = 0; i < invoices.length; i++) { + cachedInvoicesByUser.push(invoices[i]); + } + if (callback) { + return callback(false, "ok"); + } + + }); }); } + + function initialiseUI() { + + + //updateFriends(function (err, res) { + + + + //}); + + } + + + + + + + //OPEN/CREATE WALLET FUNCTIONS END--------------------------------------------- function pad(n) { @@ -3728,222 +2587,123 @@ function UI() { updateUI(); } - function updateUI() { - $(".coinunit").html(COINUNIT); - $("#stdsendcunit").html(COINUNIT); - $("#amount").attr("placeholder", "Enter amount in units of " + COINUNIT); - $("#friendAmount").attr("placeholder", "Enter amount in units of " + COINUNIT); - $("#fndsendcunit").html(COINUNIT); + var prevBlock = 0; - updateBalance(function (err, res) { + function updateUI(callback) { - updateFriends(function (err, res) { - showTransactionFeed(function (err, res) { - - updateFriendRequests(function (err, res) { + //All background UI activity controlled from here + //The focus is on minimizing any activity + //get version + //checks all infra + //if error we have a problem - updateTransactions(function (err, res) { + var newBlock = false; - showInvoiceList(function (err, res) { + Engine.getVersion(function (err, res) { - showInvoiceByUserList(function (err, res) { + if (!err) { - if (!norefresh) { - refreshSelectedFriend(function (err, res) { + var stats = JSON.parse(res); - console.log('completed refresh'); + if (prevBlock != stats.BlockNumber) { + newBlock = true; + } - }); - } - }); + prevBlock = stats.BlockNumber; - }); + //Always - }); - }); - }); - }); - }); - } + updateBalance(function (err, hasChanged) { - function showCreateWalletStart() { - $("#createWalletStart").hide(); - $("#openWalletStart").hide(); - $("#lostguid").hide(); - $("#reset2fa").hide(); - $("#validateemail").hide(); - $("#pairDevice").show(); - } + //do we need to update transactions + //1. is our balance different from the last request? + //if it is immediately update transactions - function showOpenWalletStart() { - $("#openWalletStart").hide(); - $("#createWalletStart").hide(); - $("#lostguid").hide(); - $("#reset2fa").hide(); - $("#validateemail").hide(); - $("#loginpin").show(); + //2. do we have a new block? + //if so then call updatetransactions - } + //if (hasChanged || newBlock) { - function showTwoFactorQr() { + //update transactions? - $("#twoFactorQr").show(); - $("#2factor1").show(); + showTransactionFeed(function (err, result) { - Engine.getTwoFactorImg(function (err, twoFASecret) { + loadInvoices(function (err, result) { - var nickname = $("#createWalletStart input#nickname").val(); - var data = "otpauth://totp/Ninki:" + nickname + "?secret=" + twoFASecret + "&issuer=Ninki"; - var options = { text: data, width: 172, height: 172 }; + updateSelectedFriend(); - $('#twoFactorQrImg').html(''); - $('#twoFactorQrImg').qrcode(options); + }); - $("#twoFactorQrImg").attr("src", twoFactorQrImgUrl); - }); - } - function showSettingsTwoFactorQr() { + }); - $("#setup2faqr").show(); - $("#setting2fa").show(); - $("#settings2fa").show(); - $("#btnSetupTwoFactor").hide(); + updateFriendRequests(function (err, res) { - Engine.getTwoFactorImg(function (err, twoFASecret) { - var data = "otpauth://totp/Ninki:" + Engine.m_nickname + "?secret=" + twoFASecret + "&issuer=Ninki"; - var options = { text: data, width: 172, height: 172 }; + }); - $('#imgsettings2fa').html(''); - $('#imgsettings2fa').qrcode(options); - }); + updateFriends(function (err, res) { - } - //Download settings from server and populate input boxes - function readAccountSettingsFromServerAndPopulateForm() { - $("#savesettingserror").hide(); - $("#savesettingssuccess").hide(); + }); - if (Engine.m_twoFactorOnLogin) { - $("#settings2faok").show(); - $("#TwoFactorCodeForSettings").show(); - $("#TwoFactorCodeForChangePwd").show(); - $("#DailyTransactionLimit").prop('disabled', false); - $("#SingleTransactionLimit").prop('disabled', false); - $("#NoOfTransactionsPerDay").prop('disabled', false); - $("#NoOfTransactionsPerHour").prop('disabled', false); - $("#btnSetupTwoFactor").hide(); - } else { - $("#settings2faok").hide(); - $("#TwoFactorCodeForSettings").hide(); - $("#TwoFactorCodeForChangePwd").hide(); - $("#DailyTransactionLimit").prop('disabled', true); - $("#SingleTransactionLimit").prop('disabled', true); - $("#NoOfTransactionsPerDay").prop('disabled', true); - $("#NoOfTransactionsPerHour").prop('disabled', true); - } - Engine.getAccountSettings(function (err, response) { - if (err) { + //update selected friend transactions also + //} - } else { + }); - var settingsObject = JSON.parse(response); - $('#DailyTransactionLimit').val(convertFromSatoshis(settingsObject['DailyTransactionLimit'], COINUNIT)); - $('#SingleTransactionLimit').val(convertFromSatoshis(settingsObject['SingleTransactionLimit'], COINUNIT)); - $('#NoOfTransactionsPerDay').val(settingsObject['NoOfTransactionsPerDay']); - $('#NoOfTransactionsPerHour').val(settingsObject['NoOfTransactionsPerHour']); - $('#Inactivity').val(settingsObject['Inactivity']); - $('#MinersFee').val(convertFromSatoshis(settingsObject['MinersFee'], COINUNIT)); - $('#CoinUnit').val(settingsObject['CoinUnit']); - $('#Email').val(settingsObject['Email']); - $('#EmailNotification').prop('checked', settingsObject['EmailNotification']); - if (settingsObject['CoinUnit'] == 'BTC') { - $('#cuSelected').html('BTC'); - $('#cuBTC').prop('checked', true); - } - if (settingsObject['CoinUnit'] == 'mBTC') { - $('#cuSelected').html('mBTC'); - $('#cumBTC').prop('checked', true); - } - if (settingsObject['CoinUnit'] == 'uBTC') { - $('#cuSelected').html('μBTC'); - $('#cuuBTC').prop('checked', true); - } - if (settingsObject['CoinUnit'] == 'Bits') { - $('#cuSelected').html('Bits'); - $('#cuuBits').prop('checked', true); - } + //Always + Ninki.API.getPrice(Engine.m_guid, Engine.m_settings.LocalCurrency, function (err, result) { - } - }); - } + result = _.escape(result); + price = result * 1.0; + var loc = "en-US"; + var cprc = ""; + if (Engine.m_settings.LocalCurrency == "JPY" || Engine.m_settings.LocalCurrency == "CNY") { + cprc = accounting.formatMoney(result, "¥", 0); + } else if (Engine.m_settings.LocalCurrency == "GBP") { + cprc = accounting.formatMoney(result, "£", 2); + } else if (Engine.m_settings.LocalCurrency == "EUR") { + cprc = accounting.formatMoney(result, "€", 2); + } else if (Engine.m_settings.LocalCurrency == "USD") { + cprc = accounting.formatMoney(result, "$", 2); + } else if (Engine.m_settings.LocalCurrency == "CNY") { + cprc = accounting.formatMoney(result, "¥", 2); + } - function saveAccountSettingsToServer() { - var jsonPacket = { - guid: Engine.m_guid - }; - - jsonPacket['DailyTransactionLimit'] = convertToSatoshis($('#DailyTransactionLimit').val(), COINUNIT); - jsonPacket['SingleTransactionLimit'] = convertToSatoshis($('#SingleTransactionLimit').val(), COINUNIT); - jsonPacket['NoOfTransactionsPerDay'] = $('#NoOfTransactionsPerDay').val(); - jsonPacket['NoOfTransactionsPerHour'] = $('#NoOfTransactionsPerHour').val(); - jsonPacket['Inactivity'] = $('#Inactivity').val(); - jsonPacket['MinersFee'] = convertToSatoshis($('#MinersFee').val(), COINUNIT); - - if ($('#cuSelected').html() == 'BTC') { - jsonPacket['CoinUnit'] = 'BTC'; - } else if ($('#cuSelected').html() == 'mBTC') { - jsonPacket['CoinUnit'] = 'mBTC'; - } else if ($('#cuSelected').html() == 'Bits') { - jsonPacket['CoinUnit'] = 'Bits'; - } else { - jsonPacket['CoinUnit'] = 'uBTC'; - } - jsonPacket['Email'] = $('#Email').val(); - jsonPacket['EmailNotification'] = $('#EmailNotification')[0].checked; - Engine.updateAccountSettings(jsonPacket, $("#txtTwoFactorCodeForSettings").val(), function (err, response) { - if (err) { - $("#savesettingserror").show(); - $("#savesettingssuccess").hide(); - $("#savesettingserrormessage").html(response); - } else { + $('#homeprice').html(cprc); - if (jsonPacket['CoinUnit'] != COINUNIT) { - COINUNIT = jsonPacket['CoinUnit']; - lastNoOfTrans = -1; - updateUI(); - readAccountSettingsFromServerAndPopulateForm(); - } + // + ' / BTC' - $("#savesettingssuccess").show(); - $("#savesettingserror").hide(); - $("#savesettingssuccessmessage").html("Settings saved successfully"); + }); - //alert(response.body); } + }); + + + + } function convertFromSatoshis(amount, toUnit) { @@ -3967,7 +2727,7 @@ function UI() { return amount; } - + function convertToSatoshis(amount, fromUnit) { if (fromUnit == 'BTC') { @@ -3990,44 +2750,73 @@ function UI() { return amount; } + + var previousBalance = 0; + function updateBalance(callback) { Engine.getBalance(function (err, result) { - //get in BTC units - var balance = convertFromSatoshis(result.TotalBalance, COINUNIT); + if (!err) { - // var xhr = new XMLHttpRequest(); - // xhr.open('GET', "https://api.bitcoinaverage.com/ticker/global/USD/last", false); - // xhr.send(); + //get in BTC units + var balance = convertFromSatoshis(result.TotalBalance, COINUNIT); - // var xccy = xhr.responseText / 100000000; - // var xccy = (result.TotalBalance * xccy).toFixed(2); + $("#homebalance").text(balance); + $("#homecoinunit").text(COINUNIT); + $("#calcbalance").text(balance); + $("#calccoinunit").text(COINUNIT); - //$("#balance").html(balance); - $("#balanceTop").html(balance + " " + COINUNIT); - //$("#balanceTop").html(balance + " " + COINUNIT + " ($" + (xccy) + ")"); - //$("#dashcoinunit").html(COINUNIT); - var template = ''; - if (result.UnconfirmedBalance > 0) { - template += ''; - } else { - template += ''; - } + var template = ''; + if (result.UnconfirmedBalance > 0) { + template += ''; + } else { + template += ''; + } - $("#balancetimer").html(template); + var templatecalc = ''; + if (result.UnconfirmedBalance > 0) { + templatecalc += ''; + } else { + templatecalc += ''; + } - if (callback) { - callback(); - } + $("#hometimer").html(template); + $("#calctimer").html(templatecalc); + + + if (previousBalance != result.TotalBalance || result.UnconfirmedBalance > 0) { + + previousBalance = result.TotalBalance; + + if (callback) { + callback(err, true); + } + + } else { + + if (result.UnconfirmedBalance == 0) { + if (callback) { + callback(err, false); + } + } else { + if (callback) { + callback(err, true); + } + } + + } + } else { + + callback(true, "Error"); + } }); - //$("#balance").html(Math.floor((Math.random() * 100) + 1) + " BTC"); - //$("#message").fadeToggle(3000); + } @@ -4049,7 +2838,7 @@ function UI() { if (friends.length != previousReqByMe) { previousReqByMe = friends.length; - $("#requestssent").html(''); + $("#requestssent").text(''); for (var i = 0; i < friends.length; i++) { var length = friends[i].userName.length; @@ -4106,7 +2895,7 @@ function UI() { Engine.getUserNetwork(function (err, friends) { - //$("#nfriends").html(friends.length); + //$("#nfriends").text(friends.length); if (friends.length > lastNoOfFriends) { @@ -4121,25 +2910,25 @@ function UI() { //if selected friend is not isend and isreceive //then find in list and update - if (selectedFriend != null) { + // if (selectedFriend != null) { - if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) { - selectedFriend = FRIENDSLIST[selectedFriend.userName]; - updateSelectedFriend(); - } + // if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) { + // selectedFriend = FRIENDSLIST[selectedFriend.userName]; + // updateSelectedFriend(); + // } - } + // } - $("#nfriends").html(friends.length); - $("#myfriends").html(''); + $("#nfriends").text(friends.length); + $("#myfriends").text(''); var grouptemplate = ''; var friendsgroup = _.groupBy(friends, function (item) { return item.category; }) - grouptemplate += '
'; + grouptemplate += '
'; var k = 0; var g = 1; @@ -4148,9 +2937,9 @@ function UI() { friends = friendsgroup[key]; grouptemplate += '
'; - grouptemplate += '
'; - grouptemplate += ''; - grouptemplate += key; + grouptemplate += ''; grouptemplate += '
'; @@ -4169,13 +2958,13 @@ function UI() { var imageSrc = "images/avatar/64px/Avatar-" + pad(length) + ".png"; if (frnd.profileImage != '') { - imageSrc = "https://ninkip2p.imgix.net/" + frnd.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; - imageSrcSmall = "https://ninkip2p.imgix.net/" + frnd.profileImage + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0"; + imageSrc = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; + imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0"; } var template = '
' + - '
'; + '
'; if (frnd.validated) { template += '
' + @@ -4184,8 +2973,8 @@ function UI() { } template += '
' + - '
' + friends[i].userName + '
' + - '' + frnd.status + '' + + '
' + _.escape(friends[i].userName) + '
' + + '' + _.escape(frnd.status) + '' + '
' + '
'; @@ -4208,6 +2997,20 @@ function UI() { $("#myfriends").html(grouptemplate); + + $('#myfriends #accordion2').on('touchstart.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this); + + $this.click(); + + //href, target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) //strip for ie7 + //, + //option = $(target).data('collapse') ? 'show' : $this.data() + //$(target).collapse(option) + }); + + + var k = 0; var g = 1; for (var key in friendsgroup) { @@ -4225,24 +3028,27 @@ function UI() { SELECTEDFRIEND = ev.data.userName; selectedFriend = FRIENDSLIST[ev.data.userName]; - + prevNetworkTransCount = 0; networkpagestate = "friend"; friendpagestate = "send" + $("#networklistheader").hide(); + $("#friendheader").show(); + $("#pnlfriend").show(); - $('#myfriends').hide(); + $('#netpayfeed').html(''); + $("#networkpayments").show(); $("#networklist").hide(); + $("#pnlfriendinv").hide(); window.scrollTo(0, 0); - //depreciate - - updateSelectedFriend(); + }); - console.log("added click " + k + " for " + friends[i].userName); + //console.log("added click " + k + " for " + friends[i].userName); k++; } @@ -4250,8 +3056,9 @@ function UI() { } } - - return callback(false, "done"); + if (callback) { + return callback(false, "done"); + } }); } @@ -4291,28 +3098,13 @@ function UI() { imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; } if (selectedFriend.status != '') { - $("#friendSelectedStatus").html(selectedFriend.status); + $("#friendSelectedStatus").text(selectedFriend.status); } $("#imgSelectedFriend").attr("src", imageSrc); - if (selectedFriend.validated) { - $("#validateform").hide(); - $("#isvalidated").show(); - $("#networkvalidate").hide(); - $("#btnSendToFriend").prop('disabled', false); - $("#btnSendToFriend").removeClass('disabled'); - $("#friendvalreq").hide(); - } else { - $("#validateform").show(); - $("#isvalidated").hide(); - $("#networkvalidate").show(); - $("#btnSendToFriend").prop('disabled', true); - $("#btnSendToFriend").addClass('disabled'); - $("#friendvalreq").show(); - } callback(err, friend); @@ -4346,81 +3138,69 @@ function UI() { length = 20; } - $("#nselnetcat").val(selectedFriend.category); + //$("#nselnetcat").val(selectedFriend.category); $('#friendempty').hide(); - $('#textMessageSend').removeClass('alert alert-danger'); + //$('#textMessageSend').removeClass('alert alert-danger'); $('#textMessageSend').hide(); $('#sendfriendprog').hide(); - $("#networkvalidate").show(); - $("#friendSelectedName").html(selectedFriend.userName); - $("#friendSelectedNameTo").html(selectedFriend.userName); - $("#validateusername2").html(selectedFriend.userName); - $("#validateusername3").html(selectedFriend.userName); - $("#validateusername4").html(selectedFriend.userName); - $("#validateusername5").html(selectedFriend.userName); + + $("#friendSelectedName").text(selectedFriend.userName); + $("#friendSelectedNameTo").text(selectedFriend.userName); + $("#validateusername2").text(selectedFriend.userName); + $("#validateusername3").text(selectedFriend.userName); + $("#validateusername4").text(selectedFriend.userName); + $("#validateusername5").text(selectedFriend.userName); $("#validatesuccess").hide(); $("#validatefail").hide(); - if (selectedFriend.ICanSend) { - $("#issend").show(); - $("#networksend").show(); - } else { - $("#issend").hide(); - $("#networksend").hide(); - } - if (selectedFriend.ICanReceive) { - $("#isreceive").show(); - } else { - $("#isreceive").hide(); - } var imageSrc = "images/avatar/256px/Avatar-" + pad(length) + ".png"; if (selectedFriend.profileImage != '') { imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0"; } - $("#friendSelectedStatus").html(''); + $("#friendSelectedStatus").text(''); if (selectedFriend.status != '') { - $("#friendSelectedStatus").html(selectedFriend.status); + $("#friendSelectedStatus").text(selectedFriend.status); } $("#imgSelectedFriend").attr("src", imageSrc); if (selectedFriend.validated) { - $("#validateform").hide(); - $("#isvalidated").show(); - $("#networkvalidate").hide(); - $("#btnSendToFriend").prop('disabled', false); - $("#btnSendToFriend").removeClass('disabled'); - $("#friendvalreq").hide(); - } else { - $("#validateform").show(); - $("#isvalidated").hide(); - $("#networkvalidate").show(); - $("#btnSendToFriend").prop('disabled', true); - $("#btnSendToFriend").addClass('disabled'); - $("#friendvalreq").show(); - } + $("#tapvalidatefriend").hide(); + $("#tapsendfriend").show(); + } else { + $("#tapvalidatefriend").show(); + $("#tapsendfriend").hide(); + } $('#tblnetinvbyme tbody').empty(); $('#tblnetinvforme tbody').empty(); + + + lastInvoiceToPayNetCount = 0; lastInvoiceByMeNetCount = 0; + showInvoiceListNetwork(); showInvoiceByMeListNetwork(); - $("#pnlfriend").show(); + showTransactionNetwork(); + + //$("#pnlfriend").show(); + //$("#friendheader").show(); + } @@ -4436,7 +3216,13 @@ function UI() { } + + + + + var lastNoOfFriendsReq = 0; + var selectedFriendRequest = ''; function updateFriendRequests(callback) { @@ -4457,7 +3243,7 @@ function UI() { for (var i = 0; i < ofriends.length; i++) { if (contactPhraseCache[ofriends[i].userName]) { - acceptAndValidateFriend(ofriends[i].userName); + //acceptAndValidateFriend(ofriends[i].userName); } else { friends.push(ofriends[i]); } @@ -4472,9 +3258,9 @@ function UI() { $("#dashrequests").hide(); } - $("#notifications").html(friends.length); - $("#notificationsright").html(friends.length); - //$("#nfriendreq").html(friends.length); + //$("#notifications").text(friends.length); + //$("#notificationsright").text(friends.length); + //$("#nfriendreq").text(friends.length); @@ -4488,8 +3274,8 @@ function UI() { } else { $("#notifications").attr("class", "badge pull-right"); } - $("#nfriendreq").html(friends.length); - $("#friendreq").html(''); + $("#nfriendreq").text(friends.length); + $("#friendreq").text(''); for (var i = 0; i < friends.length; i++) { var length = friends[i].userName.length; @@ -4497,38 +3283,35 @@ function UI() { length = 20; } - var template = '
  • ' + + var template = '
  • ' + 'John said' + '' + '
  • '; $("#friendreq").append(template); - $("#btnaccept" + i).button(); - - } for (var i = 0; i < friends.length; i++) { + $("#friendreq #tapfriendreq" + i).hammer(null).bind("tap", { userName: friends[i].userName }, function (ev) { - $("#friendreq #btnaccept" + i).click({ - userName: friends[i].userName - }, function (event) { - acceptAndValidateFriend(event.data.userName, function (err, result) { + selectedFriendRequest = ev.data.userName; + $("#friendrequestusername").text(selectedFriendRequest); - }); - }); - + $("#mainWallet").hide(); + $("#networklistheader").hide(); + $(".footer").hide(); + $("#contactrequest").show(); - } + }); + } } if (callback) { @@ -4538,10 +3321,60 @@ function UI() { } - function acceptAndValidateFriend(username, callback) { - acceptFriend(username, function (err, res) { + + $('#btnContactRequestClose').bind('touchstart', function () { + + $("#contactrequest").hide(); + $("#mainWallet").show(); + $("#networklistheader").show(); + $(".footer").show(); + $("friendrequestp1").show(); + $("friendrequestp2").hide(); + + }); + + + $('#btnAcceptContactDone').bind('touchstart', function () { + + $("#contactrequest").hide(); + $("#mainWallet").show(); + $("#networklistheader").show(); + $(".footer").show(); + $("friendrequestp1").show(); + $("friendrequestp2").hide(); + + }); + + + $('#btnContactReject').bind('touchstart', function () { + + rejectFriend(event.data.userName, function (err, res) { + + if (!err) { + + selectedFriendRequest = ''; + updateFriendRequests(); + + $("#friendrequestusername").text(''); + $("#contactrequest").hide(); + $("#mainWallet").show(); + $("#networklistheader").show(); + $(".footer").show(); + } + + }); + + }); + + function acceptAndValidateFriend(username, message, callback) { + + if ($(message)) { + $(message).text('Accepting friend request...'); + } + + acceptFriend(username, message, function (err, res) { //handle here instead @@ -4553,13 +3386,21 @@ function UI() { if (!err) { + console.log('accepted request'); + lastNoOfFriendsReq = 0; updateFriendRequests(); - $("#imgrequestwaiting").hide(); + //$("#imgrequestwaiting").hide(); if (contactPhraseCache[username]) { + if ($(message)) { + $(message).text('Validating contact...'); + } + + console.log('found phrase'); + console.log('found phrase'); console.log(contactPhraseCache[username]) @@ -4573,18 +3414,29 @@ function UI() { if (result) { + if ($(message)) { + $(message).text('Validated...'); + } + console.log('verified'); console.log(result); lastNoOfFriends = 0; updateFriends(); + + if (callback) { + + callback(false, "ok"); + + } + //updateSelectedFriend(); //update list also //find friend in list and update the validated icon - //$("#myfriends #seltarget" + selectedFriend.userName).html('
    '); + //$("#myfriends #seltarget" + selectedFriend.userName).text('
    '); } @@ -4597,6 +3449,14 @@ function UI() { //i orginally packaged for him + } else { + + if (callback) { + + callback(false, "ok"); + + } + } } @@ -4606,38 +3466,34 @@ function UI() { } var prevtransfeed = -1; + var transactionCache = []; + function showTransactionFeed(callback) { Engine.getTransactionRecords(function (err, transactions) { + allTransactions = transactions; + transactionCache = transactions; + if (transactions.length != prevtransfeed) { - prevtransfeed = transactions.length; + for (var i = 0; i < allTransactions.length; i++) { + var d1 = new Date(allTransactions[i].TransDateTime); + allTransactions[i].JsDate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1); + transactionIndex[allTransactions[i].TransactionId] = i; + } - var template = ''; - $('#transfeed').empty(); - for (var i = 0; i < transactions.length && i < 5; i++) { + prevtransfeed = transactions.length; - var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1).toLocaleString(); + $('#transfeed').empty(); - var dirTemplate = ""; - if (transactions[i].TransType == 'S') { - dirTemplate = convertFromSatoshis(transactions[i].Amount, COINUNIT) + ' ' + COINUNIT + '
    Sent
    '; - } - if (transactions[i].TransType == 'R') { - dirTemplate = convertFromSatoshis(transactions[i].Amount, COINUNIT) + ' ' + COINUNIT + '
    Received
    '; - } + var template = ''; - if (transactions[i].Confirmations < 6) { - dirTemplate += ''; - } else { - dirTemplate += ''; - } - dirTemplate += ""; + for (var i = 0; i < transactions.length && i < 11; i++) { var length = transactions[i].UserName.length; if (length > 20) { @@ -4647,273 +3503,213 @@ function UI() { var imageSrcSmall = "images/avatar/32px/Avatar-" + pad(length) + ".png"; if (transactions[i].UserName != 'External') { - if (FRIENDSLIST[transactions[i].UserName].profileImage != '') { - imageSrcSmall = "https://ninkip2p.imgix.net/" + FRIENDSLIST[transactions[i].UserName].profileImage + "?crop=faces&fit=crop&h=32&w=32&mask=ellipse&border=1,d0d0d0"; + if (FRIENDSLIST[transactions[i].UserName]) { + if (FRIENDSLIST[transactions[i].UserName].profileImage != '') { + imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(FRIENDSLIST[transactions[i].UserName].profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0"; + } } } - var tref = transactions[i].UserName; - - if (transactions[i].UserName == 'External') { - tref = transactions[i].Address.substring(0, 7) + '...'; - } - - template += '
    ' + - dirTemplate + '
    ' + trdate + '
    John said ' + - tref + '
    '; - - } - - $('#transfeed').html(template); - - } else { - - $('#transfeed .pull-right').each(function (index, elem) { + var amountLabel = ""; + var friendLabel = ""; - var tran = allTransactions[transactionIndex[transactions[index].TransactionId]]; - - var dirTemplate = ""; - if (tran.TransType == 'S') { - dirTemplate = convertFromSatoshis(tran.Amount, COINUNIT) + ' ' + COINUNIT + '
    Sent
    '; - } - if (tran.TransType == 'R') { - dirTemplate = convertFromSatoshis(tran.Amount, COINUNIT) + ' ' + COINUNIT + '
    Received
    '; + if (transactions[i].TransType == 'S') { + amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT); + friendLabel = "to " + _.escape(transactions[i].UserName); } - if (tran.Confirmations < 6) { - dirTemplate += ' ' + tran.Confirmations + ''; - } else { - dirTemplate += ''; + if (transactions[i].TransType == 'R') { + amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT); + friendLabel = "from " + _.escape(transactions[i].UserName); } - $(elem).html(dirTemplate); - - - }); - } - - return callback(err, "ok"); - - }); - - } - + var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1); + var timeLabel = prettydate.format(trdate); - var lastNoOfTrans = 0; + template += ''; + template += ''; + template += '...'; - function updateTransactions(callback) { - - //if there are any new friends - //fade in the button + template += ''; + template += ''; + template += ''; + template += amountLabel; + template += ''; + template += ''; + template += '
    ' + template += timeLabel; + template += '
    '; + template += '
    '; - Engine.getTransactionRecords(function (err, transactions) { + template += ''; + template += '
    '; + if (transactions[i].Confirmations < 6) { + template += ''; + template += transactions[i].Confirmations; + template += ''; + } + template += '
    '; + template += ''; + template += friendLabel; + template += ''; + template += '
    '; + template += '
    '; - allTransactions = transactions; + } - if (allTransactions.length != lastNoOfTrans) { + $('#transfeed').html(template); } else { - transactions = pagedTransactions; - - //we ony need to update the confirmations + //optimise - $('#tbltran tbody tr .bcconf').each(function (index, elem) { + $('#transfeed .conf').each(function (index, elem) { var tran = allTransactions[transactionIndex[transactions[index].TransactionId]]; + var template = '' if (tran.Confirmations < 6) { - $(elem).html('
    ' + tran.Confirmations + '
    '); - } else { - $(elem).html('
    '); + template += ''; + template += _.escape(tran.Confirmations); + template += ''; } - }); + $(elem).html(template); - return callback(false, "ok"); - } + }); + $('#transfeed .trntime').each(function (index, elem) { - for (var i = 0; i < allTransactions.length; i++) { - var d1 = new Date(allTransactions[i].TransDateTime); - allTransactions[i].JsDate = d1; - transactionIndex[allTransactions[i].TransactionId] = i; - } - //first convert to javascript dates + var tran = allTransactions[transactionIndex[transactions[index].TransactionId]]; - filteredTransactions = allTransactions; - //apply current filter currentTransactionFilter + var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1); - if (currentTransactionFilter == "Day") { - var lastDay = new Date(); - lastDay = lastDay.setDate(lastDay.getDate() - 1); - filteredTransactions = _.filter(allTransactions, function (trans) { return trans.JsDate > lastDay; }); - } + var timeLabel = prettydate.format(trdate); - if (currentTransactionFilter == "Week") { - var lastWeek = new Date(); - lastWeek = lastWeek.setDate(lastWeek.getDate() - 7); - filteredTransactions = _.filter(allTransactions, function (trans) { return trans.JsDate > lastWeek; }); - } + $(elem).html(timeLabel); - if (currentTransactionFilter == "Month") { - var lastMonth = new Date(); - lastMonth = lastMonth.setDate(lastMonth.getDate() - 31); - filteredTransactions = _.filter(allTransactions, function (trans) { return trans.JsDate > lastMonth; }); - } + }); - if (currentTransactionFilter == "Search") { - var search = $('#txttransearch').val(); - filteredTransactions = _.filter(allTransactions, function (trans) { return trans.UserName.search(search) > -1; }); } - if (currentTransactionSort == 'DateDesc') { - filteredTransactions = _.sortBy(filteredTransactions, function (trans) { return -trans.JsDate; }); - } + return callback(err, "ok"); - if (currentTransactionSort == 'DateAsc') { - filteredTransactions = _.sortBy(filteredTransactions, function (trans) { return trans.JsDate; }); - } + }); - if (currentTransactionSort == 'ContactAsc') { - filteredTransactions = _.sortBy(filteredTransactions, function (trans) { return trans.UserName; }); - } + } - if (currentTransactionSort == 'ContactDesc') { - filteredTransactions = _.sortBy(filteredTransactions, function (trans) { return trans.UserName; }); - filteredTransactions.reverse(); - } - var noofpages = Math.floor((filteredTransactions.length / transactionsPerPage)); - var indexFrom = currentPageIndex * transactionsPerPage; - var indexTo = indexFrom + transactionsPerPage; + // - if (indexTo > filteredTransactions.length) { - indexTo = filteredTransactions.length; - } + var prevNetworkTransCount = 0; - $('#tranpaglabel').html('Showing ' + (indexFrom + 1) + ' to ' + (indexTo) + ' of ' + filteredTransactions.length); + function showTransactionNetwork(callback) { - transactions = filteredTransactions; + var transactions = _.filter(transactionCache, function (tran) { return tran.UserName == SELECTEDFRIEND; }); - if (allTransactions.length != lastNoOfTrans) { + if (prevNetworkTransCount < transactions.length) { - pagedTransactions = filteredTransactions.slice(indexFrom, indexTo); + prevNetworkTransCount = transactions.length; - transactions = pagedTransactions; + var template = ''; - lastNoOfTrans = allTransactions.length; + for (var i = 0; i < transactions.length; i++) { - var template = ''; - $('#tbltran tbody').empty(); - for (var i = 0; i < transactions.length; i++) { + var amountLabel = ""; + var friendLabel = ""; - var dirTemplate = ""; - if (transactions[i].TransType == 'S') { - dirTemplate = '' + convertFromSatoshis(transactions[i].Amount, COINUNIT) + ' ' + COINUNIT + ''; - } - if (transactions[i].TransType == 'R') { - dirTemplate = '' + convertFromSatoshis(transactions[i].Amount, COINUNIT) + ' ' + COINUNIT + ''; - } + if (transactions[i].TransType == 'S') { + amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT); + friendLabel = "to " + _.escape(transactions[i].UserName); + } - var length = transactions[i].UserName.length; - if (length > 20) { - length = 20; - } + if (transactions[i].TransType == 'R') { + amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT); + friendLabel = "from " + _.escape(transactions[i].UserName); + } + var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1); + var timeLabel = prettydate.format(trdate); - var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(length) + ".png"; + template += ''; + template += ''; - if (transactions[i].UserName != 'External') { - if (FRIENDSLIST[transactions[i].UserName].profileImage != '') { - imageSrcSmall = "https://ninkip2p.imgix.net/" + FRIENDSLIST[transactions[i].UserName].profileImage + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0"; - } - } + template += ''; + template += amountLabel; + template += ''; - var tref = transactions[i].UserName; + template += ''; + template += '
    ' + template += timeLabel; + template += '
    '; + template += '
    '; - if (transactions[i].UserName == 'External') { - tref = transactions[i].Address.substring(0, 7) + '...'; - } + template += ''; + template += '
    '; + if (transactions[i].Confirmations < 6) { + template += ''; + template += transactions[i].Confirmations; + template += ''; + } + template += '
    '; + template += ''; + template += friendLabel; + template += ''; + template += '
    '; + template += '
    '; + } - var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1).toLocaleString(); + $('#netpayfeed').html(template); + } else { - template += '' + - '' + - '' + trdate + '' + - '' + - 'John said ' + - tref + '' + - dirTemplate + - ''; - if (transactions[i].Confirmations < 6) { - template += '
    ' + transactions[i].Confirmations + '
    '; - } else { - template += '
    '; - } - template += ''; - template += '
    '; + $('#netpayfeed .conf').each(function (index, elem) { - template += ''; + var tran = allTransactions[transactionIndex[transactions[index].TransactionId]]; + var template = '' + if (tran.Confirmations < 6) { + template += ''; + template += _.escape(tran.Confirmations); + template += ''; } - $('#tbltran tbody').append(template); + $(elem).html(template); - for (var i = 0; i < transactions.length; i++) { + console.log('updating 1'); + }); - var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1).toLocaleString(); + $('#netpayfeed .trntime').each(function (index, elem) { - var popcontent = ''; + var tran = allTransactions[transactionIndex[transactions[index].TransactionId]]; - popcontent += '

    Date: '; - popcontent += trdate; - popcontent += '

    '; + var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1); - popcontent += '

    TransactionId

    '; - popcontent += '

    '; - popcontent += transactions[i].TransactionId; - popcontent += '

    '; + var timeLabel = prettydate.format(trdate); - popcontent += '

    Address: '; - popcontent += transactions[i].Address; - popcontent += '

    '; + $(elem).html(timeLabel); - popcontent += '

    Amount: '; - popcontent += convertFromSatoshis(transactions[i].Amount, COINUNIT) + ' '; - popcontent += COINUNIT + '

    '; + console.log('updating 2'); - popcontent += '

    Send/Receive: '; - popcontent += transactions[i].TransType; - popcontent += '

    '; + }); - $("#btnpop" + i).popover({ - placement: 'left', // top, bottom, left or right - title: 'Transaction Details', - html: 'true', - content: '
    ' + popcontent + '
    ' - }); - } + } - } - callback(); - }); } - - function generateAddressClient() { $("#newaddrspinner").show(); @@ -4924,12 +3720,12 @@ function UI() { var options = { text: newAddress, width: 172, height: 172 }; - $('#requestaddressqr').html(''); + $('#requestaddressqr').text(''); $('#requestaddressqr').qrcode(options); - $('#requestaddresstxt').html(newAddress); + $('#requestaddresstxt').text(newAddress); - //$('#requestaddress').html(tempate); + //$('#requestaddress').text(tempate); $("#newaddrspinner").hide(); $('#requestaddress').show(); @@ -4942,45 +3738,60 @@ function UI() { function sendMoney(friend, index) { $('#textMessageSend').removeClass('alert alert-danger'); + if (friend == null) { return; } - var amount = $('input#friendAmount').val(); + var pin = $('#sendstdpin').val(); + var amount = $('#amount').text(); amount = convertToSatoshis(amount, COINUNIT); + if (amount > 0) { + - var pin = $('#sendfriendpin').val(); + Engine.getDeviceKey(pin, function (err, ekey) { - if (amount > 0) { + if (!err) { - $('input#friendAmount').css("border-color", "#ccc"); - $('#textMessageSend').html('Creating transaction...'); - $('#textMessageSend').show(); - $('#sendfriendprogstatus').width('3%') - $('#sendfriendprog').show(); - $('#sendfriendprogstatus').width('10%'); + $('#sendprogress').show(); + $('#pinconfirm').hide(); - Engine.getDeviceKey(pin, function (err, ekey) { + $('#textMessageSendStd').text('Creating transaction...'); + $('#textMessageSendStd').show(); + $('#sendstdprogstatus').width('3%') + $('#sendstdprog').show(); + $('#sendstdprogstatus').width('10%'); + + $('#sendstdprognum').text('10%'); + - if (!err) { - Engine.sendTransaction('friend', friend, "", amount, ekey, function (err, transactionid) { + Engine.sendTransaction('friend', friend, "", amount, ekey.DeviceKey, function (err, transactionid) { if (!err) { - updateBalance(); - $('#textMessageSend').html('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend); - $('input#friendAmount').val(''); - $('#textMessageSend').fadeOut(5000); - $('#sendfriendprog').fadeOut(5000); + + $('#textMessageSend').text('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend); + $('input#amount').text(''); + + updateUI(); + updateStdAmount(); + + setTimeout(function () { + $("#btnStdSndDone").show(); + }, 100); + + $("#sendstdpin").val(''); + $('.numdone').attr("style", "background-color:white"); + } else { $('#textMessageSend').addClass('alert alert-danger'); $('#sendfriendprogstatus').width('0%') if (transactionid == "ErrInsufficientFunds") { - $('#textMessageSend').html('Transaction Failed: Waiting for funds to clear'); + $('#textMessageSend').text('Transaction Failed: Waiting for funds to clear'); } } @@ -4989,9 +3800,10 @@ function UI() { } else { - $('#textMessageSend').addClass('alert alert-danger'); - $('#sendfriendprogstatus').width('0%') - $('#textMessageSend').html(ekey); + $('.numdone').attr("style", "background-color:white"); + $("#sendstdpin").val(''); + $('#confpinalert').show(); + $('#confpinalertmess').text(ekey) } @@ -5012,7 +3824,7 @@ function UI() { //get device key //pass the device key as the 2fa code - var amount = $('input#amount').val(); + var amount = $('#amount').text(); amount = convertToSatoshis(amount, COINUNIT); var address = $('input#toAddress').val(); @@ -5028,9 +3840,9 @@ function UI() { allok = false; } if (amount > 0) { - $('input#amount').css("border-color", "#ccc"); + $('#amount').css("border-color", "#ccc"); } else { - $('input#amount').css("border-color", "#ffaaaa"); + $('#amount').css("border-color", "#ffaaaa"); allok = false; } @@ -5042,30 +3854,47 @@ function UI() { if (!err) { - $('#textMessageSendStd').html('Creating transaction...'); + + + $('#sendprogress').show(); + $('#pinconfirm').hide(); + + + $('#textMessageSendStd').text('Creating transaction...'); $('#textMessageSendStd').show(); $('#sendstdprogstatus').width('3%') $('#sendstdprog').show(); $('#sendstdprogstatus').width('10%'); + $('#sendstdprognum').text('10%'); + - Engine.sendTransaction('standard', '', address, amount, ekey, function (err, transactionid) { + Engine.sendTransaction('standard', '', address, amount, ekey.DeviceKey, function (err, transactionid) { if (!err) { - $('#textMessageSendStd').html('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + address + ''); - $('input#amount').val(''); - $('#textMessageSendStd').fadeOut(5000); - $('#sendstdprog').fadeOut(5000); + $('#textMessageSendStd').html('You sent ' + _.escape(convertFromSatoshis(amount, COINUNIT)) + ' ' + _.escape(COINUNIT) + ' to ' + address + ''); + $('input#amount').text(''); + + updateUI(); + updateStdAmount(); + + setTimeout(function () { + $("#btnStdSndDone").show(); + }, 100); + + $("#sendstdpin").val(''); + $('.numdone').attr("style", "background-color:white"); } else { if (transactionid == "ErrInsufficientFunds") { - $('#textMessageSendStd').html('Transaction Failed: Waiting for funds to clear'); + $('#textMessageSendStd').text('Transaction Failed: Waiting for funds to clear'); } $('#sendstdprogstatus').width('0%') $('#textMessageSendStd').addClass('alert alert-danger'); + $("#sendstdpin").val(''); } }); @@ -5073,9 +3902,12 @@ function UI() { } else { - $('#sendstdprogstatus').width('0%') - $('#textMessageSendStd').addClass('alert alert-danger'); - $('#textMessageSendStd').html(ekey); + + //display pin error + $('.numdone').attr("style", "background-color:white"); + $("#sendstdpin").val(''); + $('#confpinalert').show(); + $('#confpinalertmess').text(ekey); } @@ -5085,6 +3917,86 @@ function UI() { } + + var checkAndValidateTimer = null; + + + function clearCheckAndValidateTimer() { + clearInterval(checkAndValidateTimer); + } + + + function checkAndValidateFriendRequests() { + Engine.getFriendRequests(function (err, ofriends) { + + var friends = []; + for (var i = 0; i < ofriends.length; i++) { + + if (contactPhraseCache[ofriends[i].userName]) { + + clearCheckAndValidateTimer(); + + console.log('found request...accepting and validating'); + acceptAndValidateFriend(ofriends[i].userName); + + return; + } + } + }); + } + + + $('#btnContactAccept').bind('touchstart', function () { + + $("#btnAcceptContactDone").hide(); + $("#friendrequestp1").hide(); + $("#friendrequestp2").show(); + $("#acceptcontactprognum").text('10%'); + $("#acceptcontactprog").width('10%'); + + + acceptAndValidateFriend(selectedFriendRequest, "#acceptcontactprogmess", function (err, result) { + + if (!err) { + + + + $("#acceptcontactprognum").text('70%'); + $("#acceptcontactprog").width('70%'); + + updateFriendRequests(function (err, result) { + + $("#acceptcontactprognum").text('80%'); + $("#acceptcontactprog").width('80%'); + + updateFriends(function (err, result) { + + $("#friendrequestusername").text(''); + $("#btnAcceptContactDone").show(); + $("#acceptcontactprogmess").text("You accepted the contact request from " + selectedFriendRequest); + $("#acceptcontactprognum").text('100%'); + $("#acceptcontactprog").width('100%'); + + selectedFriendRequest = ''; + + }); + + + }); + + } else { + + $("#friendrequestp1").show(); + $("#friendrequestp2").hide(); + + } + + }); + + }); + + + //function when connecting from main add contact screen $("#hdqrcontact").change(function () { console.log('event triggered'); @@ -5101,15 +4013,25 @@ function UI() { contactPhraseCache[username] = phrase; $("#addcontactmodal").show(); + $("#dashcontact").hide(); - $("#imgaddcontactwaiting").show(); - var target = document.getElementById('imgaddcontactwaiting'); - var spinner = new Spinner(spinneropts).spin(target); + //$("#imgaddcontactwaiting").show(); + + //var target = document.getElementById('imgaddcontactwaiting'); + //var spinner = new Spinner(spinneropts).spin(target); - $("#qrcontactupd").show(); - $("#qrcontactmess").html('Verifying user...'); + + //$("#qrcontactupd").show(); + + $("#textAddContact").text('Verifying user...'); + + + $("#addcontactprog").show(); + + $("#addcontactprognum").text("10%"); + $("#addcontactprogstatus").width("10%"); Engine.doesUsernameExist(username, function (err, usernameExistsOnServer) { @@ -5118,76 +4040,166 @@ function UI() { if (usernameExistsOnServer) { - $("#qrcontactmess").html('Verifying network...'); - Engine.isNetworkExist(username, function (err, result) { + console.log('username exists'); - if (!result) { + $("#addcontactprognum").text("30%"); + $("#addcontactprogstatus").width("30%"); - $("#qrcontactmess").html('Deriving addresses...'); + $("#textAddContact").text('Verifying network...'); - Engine.createFriend(username, "#qrcontactmess", function (err, result) { - if (err) { + //if no friendrequest- create one and wait + //if it exists, then accept and validate + //if alread accepted then just validate - $("#addcontactmodal").hide(); - $("#imgaddcontactwaiting").hide(); - $("#qrcontactalert").show(); - $("#qrcontactalertmessage").html("Error adding contact"); + Engine.getFriendRequests(function (err, ofriends) { + var friends = _.filter(ofriends, function (frn) { return frn.UserName == username; }); - } else { - $("#imgaddcontactwaiting").hide(); - $("#addcontactmodal").hide(); - $("#qrcontactsuccess").show(); - $("#qrcontactsuccessmessage").html("Successfully added " + username + " as a contact"); - $("#qrcontactsuccess").fadeOut(5000); + if (friends.length == 0) { - } - }); + console.log('network not exists'); - } else { - //validate using the fingerprint + //if network doesnt exist create friend + + Engine.isNetworkExist(username, function (err, result) { + + if (!err) { - if (contactPhraseCache[username]) { + if (!result) { - console.log('found phrase'); - console.log(contactPhraseCache[username]) - var code = contactPhraseCache[username]; - var bip39 = new BIP39(); - code = bip39.mnemonicToHex(code); + $("#textAddContact").text('Deriving addresses...'); - if (code.length == 40) { - $("#qrcontactmess").html('Verifying user...'); - Engine.verifyFriendData(username, code, function (err, result) { + $("#addcontactprognum").text("60%"); + $("#addcontactprogstatus").width("60%"); - if (result) { - $("#qrcontactmess").html('Verfied...'); - console.log('verified'); - console.log(result); - $("#imgaddcontactwaiting").hide(); - $("#addcontactmodal").hide(); - $("#qrcontactsuccess").show(); - $("#qrcontactsuccessmessage").html("You verfied " + username + " as a contact"); - $("#qrcontactsuccess").fadeOut(5000); - lastNoOfFriends = 0; - updateFriends(); + Engine.createFriend(username, "#qrcontactmess", function (err, result) { + + console.log('create friend ' + result); + + if (err) { + + //$("#addcontactmodal").hide(); + //$("#imgaddcontactwaiting").hide(); + //$("#qrcontactalert").show(); + $("#textAddContact").text("Error adding contact"); + + + } else { + + console.log('added timer for check and validate'); + //here we go to - now you friend should scan this code + checkAndValidateTimer = setInterval(function () { checkAndValidateFriendRequests() }, 2000); + + //listen for 2 minutes + setTimeout(clearCheckAndValidateTimer(), 120000); + + $("#addcontactprognum").text("100%"); + $("#addcontactprogstatus").width("100%"); + + //$("#imgaddcontactwaiting").hide(); + //$("#addcontactmodal").hide(); + $("#textAddContact").text("Successfully added " + username + " as a contact"); + } + }); + } else { + + + $("#textAddContact").text('validating...'); + + $("#addcontactprognum").text("80%"); + $("#addcontactprogstatus").width("80%"); + + + //if already accepted validate only + + var needToAccept = false; + if (FRIENDSLIST[username]) { + + if (!FRIENDSLIST[username].ICanSend) { + needToAccept = true; + } + + } else { + needToAccept = true; } - }); + + if (needToAccept) { + + acceptAndValidateFriend(username, "", function (err, result) { + + + if (!err) { + + $("#addcontactprognum").text("100%"); + $("#addcontactprogstatus").width("100%"); + + $("#textAddContact").text("Successfully added " + username + " as a contact"); + } + + + }); + + + } else { + + console.log('caught event...'); + + var bip39 = new BIP39(); + code = bip39.mnemonicToHex(phrase); + + console.log(code); + + + if (code.length != 40) { + + return; + } + + Engine.verifyFriendData(username, code, function (err, result) { + + + $("#addcontactprognum").text("100%"); + $("#addcontactprogstatus").width("100%"); + + $("#textAddContact").text("Successfully verified " + username + " as a contact"); + + //update contact list + updateFriends(); + + }); + + + } + + } } - //get the hash to validate against - //this will confirm that my friend has the same keys - //i orginally packaged for him + }); + } else if (friends.length == 1) { - } + + //validate using the fingerprint + acceptAndValidateFriend(username, "#textAddContact", function (err, result) { + + if (!err) { + + $("#addcontactprognum").text("100%"); + $("#addcontactprogstatus").width("100%"); + + $("#textAddContact").text("Successfully added " + username + " as a contact"); + } + + + }); } @@ -5217,19 +4229,7 @@ function UI() { return; } - $("#addcontactmodal").show(); - - $("#imgaddcontactwaiting").show(); - var target = document.getElementById('imgaddcontactwaiting'); - var spinner = new Spinner(spinneropts).spin(target); - - //verify input and if username exists - $("#addcontactalert").hide(); - - - $("#qrcontactupd").show(); - $("#qrcontactmess").html('Verifying user...'); //merge these functions @@ -5239,32 +4239,62 @@ function UI() { if (usernameExistsOnServer) { - $("#qrcontactmess").html('Verifying network...'); + + $("#addcontactprognum").text("20%"); + $("#addcontactprogstatus").width("20%"); + $("#textAddContact").text('Verifying network...'); + + Engine.isNetworkExist(username, function (err, result) { if (!result) { + $("#addcontactmodal").show(); + $("#dashcontact").hide(); + + + //$("#imgaddcontactwaiting").show(); + //var target = document.getElementById('imgaddcontactwaiting'); + //var spinner = new Spinner(spinneropts).spin(target); + + + //verify input and if username exists + $("#addcontactalert").hide(); + + + //$("#qrcontactupd").show(); + $("#textAddContact").text('Verifying user...'); + + $("#addcontactprognum").text("20%"); + $("#addcontactprogstatus").width("20%"); + $("#friend").css("border-color", "#ccc"); - $("#qrcontactmess").html('Deriving addresses...'); + $("#textAddContact").text('Deriving addresses...'); + - Engine.createFriend(username, "#qrcontactmess", function (err, result) { + Engine.createFriend(username, "#textAddContact", function (err, result) { if (err) { - $("#friend").css("border-color", "#ffaaaa"); - $("#addcontactalert").show(); - $("#addcontactalertmessage").html("Error adding contact"); - $("#imgaddcontactwaiting").hide(); + //$("#friend").css("border-color", "#ffaaaa"); + + //$("#addcontactalert").show(); + //$("#addcontactalertmessage").text("Error adding contact"); + //$("#imgaddcontactwaiting").hide(); } else { - $("#addcontactmodal").hide(); + + $("#addcontactprognum").text("100%"); + $("#addcontactprogstatus").width("100%"); + + //$("#addcontactmodal").hide(); $("#friend").val(''); - $("#imgaddcontactwaiting").hide(); - $("#addcontactsuccess").show(); - $("#addcontactsuccessmessage").html("You requested " + username + " as a contact"); - $("#addcontactsuccess").fadeOut(5000); + //$("#imgaddcontactwaiting").hide(); + //$("#addcontactsuccess").show(); + $("#textAddContact").text("You requested " + username + " as a contact"); + //$("#addcontactsuccess").fadeOut(5000); //updateRequestsMadeByMe(); } @@ -5274,8 +4304,8 @@ function UI() { $("#friend").css("border-color", "#ffaaaa"); $("#addcontactalert").show(); - $("#addcontactalertmessage").html("You have already requested " + username + " as a contact"); - $("#imgaddcontactwaiting").hide(); + $("#textAddContact").text("You have already requested " + username + " as a contact"); + //$("#imgaddcontactwaiting").hide(); } }); @@ -5284,8 +4314,8 @@ function UI() { $("#friend").css("border-color", "#ffaaaa"); $("#addcontactalert").show(); - $("#addcontactalertmessage").html("The username could not be found"); - $("#imgaddcontactwaiting").hide(); + $("#addcontactalertmessage").text("The username could not be found"); + //$("#imgaddcontactwaiting").hide(); } }); @@ -5303,14 +4333,14 @@ function UI() { }); } - function acceptFriend(username, callback) { + function acceptFriend(username, message, callback) { console.log('calling accept acceptFriend'); - $("#imgrequestwaiting").show(); - var target = document.getElementById('imgrequestwaiting'); - var spinner = new Spinner(spinneropts).spin(target); + // $("#imgrequestwaiting").show(); + //var target = document.getElementById('imgrequestwaiting'); + // var spinner = new Spinner(spinneropts).spin(target); //$('#friendreq').fadeOut(1000); Engine.acceptFriendRequest(username, function (err, secret) { @@ -5322,7 +4352,7 @@ function UI() { if (!result) { - Engine.createFriend(username, "", function (err, result) { + Engine.createFriend(username, message, function (err, result) { if (err) { @@ -5347,73 +4377,5 @@ function UI() { } - function ensureOpenWalletGuidAndPasswordValid() { - - if (Engine.isRealGuid($("#openWalletStart input#guid").val())) { - $("#openWalletStart input#guid").css("border-color", "#ccc"); - } else { - $("#openWalletStart input#guid").css("border-color", "#ffaaaa"); - } - - if ($("#openWalletStart input#password").val().length == 0) { - $("#openWalletStart input#password").css("border-color", "#ffaaaa"); - } else { - $("#openWalletStart input#password").css("border-color", "#ccc"); - } - - if (!Engine.isRealGuid($("#openWalletStart input#guid").val()) || - $("#openWalletStart input#password").val().length == 0) { - - return false; - } - - return true; - } - - function ensureCreateWalletGuidNicknameAndPasswordValid() { - - if (Engine.isRealGuid($("#createWalletStart input#guid").val())) { - $("#createWalletStart input#guid").css("border-color", "#ccc"); - } else { - $("#createWalletStart input#guid").css("border-color", "#ffaaaa"); - } - - //TODO Check nickname does not already exist - if ($("#createWalletStart input#nickname").val().length == 0 || $("#createWalletStart input#nickname").val().length > 20) { - $("#createWalletStart input#nickname").css("border-color", "#ffaaaa"); - } else { - $("#createWalletStart input#nickname").css("border-color", "#ccc"); - } - - if (!Engine.isRealGuid($("#createWalletStart input#guid").val()) || - $("#createWalletStart input#cpassword").val().length == 0 || - $("#createWalletStart input#nickname").val().length == 0 || - $("#createWalletStart input#nickname").val().length > 20) { - - return false; - } else { - return true; - } - - } - - function validate() { - - if (Engine.isRealGuid($("input#guid").val())) { - $("input#guid").css("background-color", "#ffffff"); - } else { - $("input#guid").css("background-color", "#ffaaaa"); - } - - if (!Engine.isRealGuid($("input#guid").val()) || - $("input#password").val().length == 0) { - - return false; - } - - return true; - } - } - -module.exports = UI; +module.exports = UI; \ No newline at end of file diff --git a/src/ninki-ui.js b/src/ninki-ui.js index ca064b1..9a5a5e6 100644 --- a/src/ninki-ui.js +++ b/src/ninki-ui.js @@ -86,7 +86,7 @@ function UI() { - function setCookie(cname, cvalue, exdays) { + function setCookie(cname, cvalue) { if (isChromeApp()) { @@ -197,9 +197,51 @@ function UI() { } + + function backupHotKey(errtarget) { + + Engine.getEncHotHash(function (err, data) { + + if (!err) { + + var d = new Date(); + var fdate = "" + (d.getDate()) + (d.getMonth() + 1) + (d.getFullYear()); + var sugName = "ninki_backup_" + _.escape(Engine.m_nickname) + "_" + fdate + ".json"; + + chrome.fileSystem.chooseEntry({ type: 'saveFile', suggestedName: sugName }, function (writableFileEntry) { + writableFileEntry.createWriter(function (writer) { + writer.onerror = function (e) { + //console.log('write complete'); + $(errtarget).text('Error'); + }; + writer.onwriteend = function (e) { + //console.log('write complete'); + //$(errtarget).text('Success'); + }; + writer.write(new Blob([data], { type: 'text/plain' })); + }); + }); + + } + + }); + + } + + + jQuery(document).ready(function () { + $("#btnBackupBeta").click(function () { + + backupHotKey('#errbackupbeta'); + + }); + + + $('#openWalletStart input#password').focus(); + var fatokk = getCookie("ninki_rem", function (res) { if (res.length > 0) { @@ -208,6 +250,99 @@ function UI() { }); + var tmpContent = {}; + $("#btnBrowseRestore").click(function () { + + chrome.fileSystem.chooseEntry({ type: 'openFile', accepts: [{ extensions: ['json']}] }, function (readOnlyEntry) { + + readOnlyEntry.file(function (file) { + var reader = new FileReader(); + + //reader.onerror = errorHandler; + reader.onloadend = function (e) { + + try { + + if (e.target.result) { + var json = JSON.parse(e.target.result); + tmpContent = json; + restoreFromFile(m_this.m_password, json); + } else { + $("#restoreerror").text('The file was empty'); + } + + } catch (error) { + $("#restoreerror").text('Invalid file'); + } + + }; + + reader.readAsText(file); + }); + }); + + }); + + + $("#btnRestore").click(function () { + + $("#restorepwd").hide(); + + var respwd = $("#restorePassword").val(); + respwd = Engine.pbkdf2(respwd, Engine.m_oguid); + + restoreFromFile(respwd, tmpContent); + + }); + + + function restoreFromFile(pwd, data) { + + var json = data; + + var hothash = ''; + var iserror = false; + try { + hothash = Engine.decryptNp(json.enc, pwd, json.iv); + } catch (error) { + iserror = true; + } + + if (!iserror) { + + Engine.restoreHotHash(hothash, function (err, result) { + + //login + if (!err) { + + tmpContent = {}; + $("#hotkeymodal").modal('hide'); + $("#hotkeyenter").hide(); + + } else { + + if (result == "ErrSeedInvalid") { + $('#restorepwd').show(); + } else { + + $('#hotkeyentererror').show(); + $('#hotkeyentererrormessage').text(result); + } + + } + + }); + + } else { + + $('#hotkeyentererror').show(); + $('#hotkeyentererrormessage').text("Invalid file"); + + } + + } + + $("#btnSaveHotKey").click(function () { @@ -237,8 +372,11 @@ function UI() { $("#btnWatchOnly").click(function () { + Engine.m_watchOnly = true; $("#hotkeymodal").modal('hide'); $("#hotkeyenter").hide(); + $("#btnSaveBackup").prop('disabled', true); + $("#btnSaveBackupP").prop('disabled', true); }); @@ -257,6 +395,7 @@ function UI() { }); + $("#logout").click(function () { logout(); @@ -490,27 +629,31 @@ function UI() { Engine.createS3Policy(function (err, result) { - var policy = JSON.parse(result); - fd.append('key', key); - fd.append('acl', 'public-read'); - fd.append('Content-Type', file.type); - fd.append('bucket', 'ninkip2pimgstore'); - fd.append('AWSAccessKeyId', 'AKIAINOU56ATQFS3CLFQ'); - fd.append('policy', policy.s3Policy); - fd.append('signature', policy.s3Signature); - fd.append("file", file); + if (!err) { + + var policy = JSON.parse(result); - var xhr = new XMLHttpRequest(); + fd.append('key', key); + fd.append('acl', 'public-read'); + fd.append('Content-Type', file.type); + fd.append('bucket', 'ninkip2pimgstore'); + fd.append('AWSAccessKeyId', 'AKIAINOU56ATQFS3CLFQ'); + fd.append('policy', policy.s3Policy); + fd.append('signature', policy.s3Signature); + fd.append("file", file); - xhr.upload.addEventListener("progress", uploadProgress, false); - xhr.addEventListener("load", uploadComplete, false); - xhr.addEventListener("error", uploadFailed, false); - xhr.addEventListener("abort", uploadCanceled, false); + var xhr = new XMLHttpRequest(); - xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND + xhr.upload.addEventListener("progress", uploadProgress, false); + xhr.addEventListener("load", uploadComplete, false); + xhr.addEventListener("error", uploadFailed, false); + xhr.addEventListener("abort", uploadCanceled, false); - xhr.send(fd); + xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND + + xhr.send(fd); + } }); } @@ -800,43 +943,10 @@ function UI() { }); - - getCookie('guid', function (res) { - if (res.length == 0) { - - var betafrom = 'December 12, 2009 12:00 pm GMT'; - var betato = 'December 12, 2009 01:00 pm GMT'; - - betafrom = getLocalTime(betafrom); - betato = getLocalTime(betato); - - $('#betafrom').text(betafrom); - $('#betato').text(betato); - - $('#basicModal').modal('show'); - - $("#btnDeclineBeta").click(function () { - window.location.href = '/' - }); - - } - }); - - - - $("#btnAcceptBeta").click(function () { - $("#openWalletStart #password").focus(); - }); - - $("#btncreatewallet").click(function () { showCreateWalletStart(); }); - - - - $("#btnAddDevice").click(function () { @@ -898,6 +1008,9 @@ function UI() { var twoFactorCode = $("#pairTwoFactorCode").val(); + $('#pairerror').hide(); + $('#pairerrormess').text(''); + if (twoFactorCode.length == 6) { @@ -927,7 +1040,7 @@ function UI() { var options = { text: data, width: 256, height: 256 }; - //$('#qrdevice').text(data); + $('#qrdevice').text(data); $('#qrdevice').qrcode(options); $('#pairqr2fa').hide(); @@ -975,6 +1088,11 @@ function UI() { } + } else { + + $('#pairerror').show(); + $('#pairerrormess').text("Invalid two factor code"); + } @@ -1020,19 +1138,23 @@ function UI() { twoFactorCode = Engine.decryptNp(enc.ct, Engine.m_password, enc.iv); } - setCookie('guid', guid, 30); + setCookie('guid', guid); + + Engine.openWallet(guid, twoFactorCode, function (err, result) { - $("#imgopenwaiting").hide(); - $("#btnLogin").prop('disabled', false); - $("#btnLogin").removeClass('disabled'); + //$("#imgopenwaiting").hide(); + if (!err) { - $("#imgopenwaiting").hide(); + //$("#imgopenwaiting").hide(); + $("#openwalletalert").hide(); + + if (result.TwoFactorOnLogin) { //delete any old 2 factor tokens @@ -1044,15 +1166,24 @@ function UI() { $('#openWalletStart input#password').val(''); if (result.TwoFactorOnLogin) { + $("#siguid").hide(); $("#silguid").hide(); $("#sipwd").hide(); $("#si2fa").show(); $("#sib1").hide(); $("#sib2").show(); + $("#signdiff").hide(); + $("#crwallet").hide(); + + $('#openWalletStart input#twoFactorCode').focus(); + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); + $("#imgopenwaiting").hide(); } + } else { //for beta1 migrations @@ -1063,7 +1194,9 @@ function UI() { $("#sib1").hide(); $("#sib2").show(); $('#openWalletStart input#twoFactorCode').focus(); - + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); + $("#imgopenwaiting").hide(); } } else { @@ -1072,6 +1205,7 @@ function UI() { //initiate 2fa setup modal if (!m_this.m_twoFactorOnLogin) { + $("#twofactorsettings").show(); $("#2famodal").modal('show'); @@ -1080,12 +1214,57 @@ function UI() { $("#savetwofactorerror").hide(); $("#setup2faemail").hide(); $("#setup2faqr").show(); + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); + $("#imgopenwaiting").hide(); showSettingsTwoFactorQr(); } else { - initialiseUI(); + + if (Engine.m_walletinfo.hotHash == '') { + + initialiseUI(function (err, result) { + + setCookie("user", Engine.m_nickname); + setCookie("userimg", Engine.m_profileImage); + + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); + $("#imgopenwaiting").hide(); + + + }); + + + } else { + + //display a screen advising the user to write down their hot key + //checkbox->ok + //then migrate the packet + //initialise ui + + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); + $("#imgopenwaiting").hide(); + + + + if (Engine.m_walletinfo.hotHash != '') { + Engine.saveHotHash(Engine.m_walletinfo.hotHash, function (err, result) { + + $("#mighotdisp").text(Engine.encodeKey(Engine.m_walletinfo.hotHash)); + + $("#openWalletStart").hide(); + $("#hotmigmodal").modal('show'); + $("#hotmigenter").show(); + + }); + } + + + } } @@ -1094,7 +1273,11 @@ function UI() { $("#unlockaccount").hide(); } else { + + $("#btnLogin").prop('disabled', false); + $("#btnLogin").removeClass('disabled'); $("#imgopenwaiting").hide(); + $("#openwalletalert").show(); if (result == "ErrAccount") { @@ -1116,12 +1299,50 @@ function UI() { }); + + + $("#btnMigHotKey").click(function () { + + $("#mighoterr").hide(); + + var twoFactorCode = $('#hotmig2fa').val(); + + if (twoFactorCode.length == 6) { + + Engine.migrateHotKeyFromPacket(twoFactorCode, function (err, result) { + + if (err) { + + $("#mighoterrmess").text(result); + $("#mighoterr").show(); + + } else { + + $("#hotmigmodal").modal('hide'); + $("#hotmigenter").hide(); + initialiseUI(); + + } + + }); + + } else { + + $("#mighoterrmess").text("Invalid two factor code"); + $("#mighoterr").show(); + + } + + }); + $("#btn2faLogin").click(function () { + $("#img2faopenwaiting").show(); $("#btn2faLogin").prop('disabled', true); $("#btn2faLogin").addClass('disabled'); + var target = document.getElementById('img2faopenwaiting'); var spinner = new Spinner(spinneropts).spin(target); @@ -1131,25 +1352,59 @@ function UI() { var twoFactorCode = $('#openWalletStart input#twoFactorCode').val(); var rememberTwoFactor = $('#twofactorremember')[0].checked; - Engine.openWallet2fa(twoFactorCode, rememberTwoFactor, function (err, result) { - if (err) { + if (twoFactorCode.length == 6) { - $("#img2faopenwaiting").hide(); - $("#openwalletalert").show(); - $("#openwalletalertmessage").text(result); - $("#btn2faLogin").prop('disabled', false); - $("#btn2faLogin").removeClass('disabled'); - } else { + Engine.openWallet2fa(twoFactorCode, rememberTwoFactor, function (err, result) { + + if (err) { + + $("#img2faopenwaiting").hide(); + $("#openwalletalert").show(); + $("#openwalletalertmessage").text(result); + $("#btn2faLogin").prop('disabled', false); + $("#btn2faLogin").removeClass('disabled'); + } else { + + if (result.CookieToken) { - if (result.CookieToken) { + setCookie("ninki_rem", result.CookieToken); + } + + if (Engine.m_walletinfo.hotHash == '') { + + initialiseUI(function (err, result) { + + setCookie("user", Engine.m_nickname); + setCookie("userimg", Engine.m_profileImage); - setCookie("ninki_rem", result.CookieToken); + }); + + + } else { + + //display a screen advising the user to write down their hot key + //checkbox->ok + //then migrate the packet + //initialise ui + $("#mighotdisp").text(Engine.encodeKey(Engine.m_walletinfo.hotHash)); + + $("#openWalletStart").hide(); + $("#hotmigmodal").modal('show'); + $("#hotmigenter").show(); + + + } } + }); + } else { - initialiseUI(); - } - }); + $("#img2faopenwaiting").hide(); + $("#openwalletalert").show(); + $("#openwalletalertmessage").text("Invalid two factor code"); + $("#btn2faLogin").prop('disabled', false); + $("#btn2faLogin").removeClass('disabled'); + } }, 100); @@ -1168,11 +1423,7 @@ function UI() { }); - $("#btnaddfriend").click(function () { - addFriend(); - - }); $("#btngenaddr").click(function () { @@ -1328,12 +1579,13 @@ function UI() { }); + $("#btnCreate").click(function () { if ($("#frmcreate").parsley('validate')) { //check password strength - if (($(".password-verdict").text() == 'Strong' || $(".password-verdict").text() == 'Very Strong')) { + if (($(".password-verdict").html() == 'Strong' || $(".password-verdict").html() == 'Very Strong')) { //can we remove this check? if (ensureCreateWalletGuidNicknameAndPasswordValid()) { @@ -1354,6 +1606,8 @@ function UI() { var emailAddress = $('#createWalletStart input#emailaddress').val(); + Engine.m_nickname = username; + Engine.createWallet(guid, password, username, emailAddress, function (err, result) { //move error handling and ui elements to here @@ -1391,6 +1645,9 @@ function UI() { $("#btnCreate").removeClass('disabled'); $("#lnkOpenWallet").show(); + $("#createwalletalert").show(); + $("#createwalletalertmessage").text("Error"); + } } else { @@ -1404,12 +1661,14 @@ function UI() { $("#hotWalletPhrase").text(result.hotWalletPhrase); $("#coldWalletPhrase").text(result.coldWalletPhrase); - //$("#ninkiWalletPhrase").text(result.ninkiWalletPhrase); + $("#coldWalletPhrasePrintText").text(result.coldWalletPhrase); + $("#walletGuid").text($('input#guid').val()); $("#showPhrases").show(); $("#securitywizard").show(); + $(".next").hide(); $("#no2famessage").hide(); showTwoFactorQr(); @@ -1429,6 +1688,32 @@ function UI() { }); + $("#coldconf").change(function () { + if (this.checked) { + $(".next").show(); + } else { + $(".next").hide(); + } + }); + + $("#hotconf").change(function () { + if (this.checked) { + $(".next").show(); + } else { + $(".next").hide(); + } + }); + + + $("#chkhotmig").change(function () { + if (this.checked) { + $("#hotmigcont").show(); + } else { + $("#hotmigcont").hide(); + } + }); + + $("#btnPassphraseLogin").click(function () { @@ -1436,6 +1721,8 @@ function UI() { if (isvalid) { + $("#btnPassphraseLogin").prop('disabled', true); + var twoFactorCodeChk = $('#twoFactorCodeCheck').val(); var target = document.getElementById('imgphrasewaiting'); @@ -1443,7 +1730,7 @@ function UI() { $("#imgphrasewaiting").show(); - setCookie('guid', Engine.m_oguid, 30); + setCookie('guid', Engine.m_oguid); Engine.openWalletAfterCreate(twoFactorCodeChk, function (err, result) { @@ -1452,10 +1739,12 @@ function UI() { $("#imgphrasewaiting").hide(); $("#phraseloginerror").show(); $("#phraseloginerrormessage").text(result); + $("#btnPassphraseLogin").prop('disabled', false); } else { initialiseUI(); + $("#btnPassphraseLogin").prop('disabled', false); $("#imgphrasewaiting").hide(); $("#phraseloginerror").hide(); $("#validateemail").show(); @@ -1466,6 +1755,10 @@ function UI() { $("#prgsecwiz").width('100%'); $(".next").hide(); $(".previous").hide(); + + setCookie("user", Engine.m_nickname); + setCookie("userimg", Engine.m_profileImage); + } @@ -1479,10 +1772,12 @@ function UI() { var token = $("#txtEmailToken").val(); + $("#btnEmailValidate").prop('disabled', true); + Engine.getEmailValidation(token, function (err, response) { if (err) { - + $("#btnEmailValidate").prop('disabled', false); } else { if (response != "Valid") { @@ -1495,7 +1790,7 @@ function UI() { $("#valemailerrormessage").text('Your token is not valid'); } - + $("#btnEmailValidate").prop('disabled', false); } else { @@ -1503,11 +1798,12 @@ function UI() { //initialiseUI(); Engine.m_validate = false; - //readAccountSettingsFromServerAndPopulateForm(); + $("#securitywizard").hide(); $("#validateemail").hide(); $("#mainWallet").show(); $("#valemailerror").hide(); + $("#btnEmailValidate").prop('disabled', false); } } @@ -1533,7 +1829,11 @@ function UI() { $("#listep2").removeClass("active"); $("#listep3").addClass("active"); $("#prgsecwiz").width('75%'); + + $(".next").hide(); + + $(".previous").show(); step++; } @@ -1546,6 +1846,12 @@ function UI() { $("#prgsecwiz").width('50%'); $(".previous").show(); + if ($("#hotconf")[0].checked) { + $(".next").show(); + } else { + $(".next").hide(); + } + step++; } @@ -1649,12 +1955,15 @@ function UI() { var ninkiPub = result.ninkiPubKey; var phrase = result.hotHash; - var bip39 = new BIP39(); // 'en' is the default language - var hotmnem = bip39.entropyToMnemonic(phrase); + if (phrase != "Unavailable") { + var bip39 = new BIP39(); // 'en' is the default language + var hotmnem = bip39.entropyToMnemonic(phrase); + $("#secdisphrase").text(hotmnem); + $("#secdisphrase").show(); + } - $("#secdisphrase").text(hotmnem); $("#secdisninki").text(ninkiPub); - $("#secdisphrase").show(); + $("#secdisninki").show(); $("#btnhidekeys").show(); $("#btndisplaykeys").hide(); @@ -1964,15 +2273,93 @@ function UI() { if (res.length > 0) { + $("#guidsec").hide(); + + + if (isChromeApp()) { + + getCookie('user', function (uname) { + + //console.write(res); + $("#loginuser").text(uname); + + getCookie('userimg', function (res) { + + var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(uname.length) + ".png"; + + if (res != '') { + imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(res) + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0"; + } + + var xhrsm = new XMLHttpRequest(); + xhrsm.open('GET', imageSrcSmall, true); + xhrsm.responseType = 'blob'; + + xhrsm.onload = function (e) { + $("#loginimg").attr("src", window.URL.createObjectURL(this.response)); + }; + + xhrsm.send(); + + $("#password").focus(); + + }); + + + + }); + + } + showOpenWalletStart(); + } else { - showCreateWalletStart(); + $("#introduction").show(); + + } + }); + + $("#btnsigndiff").click(function () { + + $("#guidsec").show(); + $("#userlogin").hide(); + + }); + + + + + $("#printCold").click(function () { + // $("#coldWalletPhrase").printElement(); + chrome.app.window.create('printwindow.html', { 'bounds': { + 'width': Math.round(window.screen.availWidth * 0.8), + 'height': Math.round(window.screen.availHeight * 0.8) } - }) + }, + function (createdWindow) { + var win = createdWindow.contentWindow; + win.onload = function () { + win.document.querySelector('#content').innerHTML = $("#coldWalletPhrasePrintText").text(); + win.print(); + } + } + ); + + }); + + + $("#btnCreateInit").click(function () { + $("#introduction").hide(); + showCreateWalletStart(); + }); + $("#btnLoginInit").click(function () { + $("#introduction").hide(); + showOpenWalletStart(); + }); $("#password").keypress(function (e) { @@ -2125,6 +2512,26 @@ function UI() { password = results; + + // Engine.getEncHotHash(function (err, data) { + + // var bb = new Blob([data], { type: 'text/plain' }); + + // var a = document.getElementById('btnSaveBackupP'); + + // var d = new Date(); + // var fdate = "" + (d.getDate()) + (d.getMonth() + 1) + (d.getFullYear()); + + // a.download = "ninki_backup_" + _.escape(Engine.m_nickname) + "_" + fdate + ".json"; + // a.href = window.URL.createObjectURL(bb); + + // a.dataset.downloadurl = ['text/plain', a.download, a.href].join(':'); + + // }); + + + $("#pwdchangemain").hide(); + $("#chngpwerr").hide(); $("#chngpwdprogbar").width('100%'); $("#chngpwdprog").hide(); @@ -2158,6 +2565,14 @@ function UI() { $("#btnVerify").click(function () { + + $(this).prop('disabled', true); + + var target = document.getElementById('verifyspinner'); + var spinner = new Spinner(spinneropts).spin(target); + + $("#verifyspinner").show(); + var code = $("#txtCode").val(); $("#txtCode").css("border-color", "#ccc"); @@ -2169,34 +2584,83 @@ function UI() { if (code.length != 40) { $("#txtCode").css("border-color", "#ffaaaa"); + $("#verifyspinner").hide(); + $(this).prop('disabled', false); return; } - //get the hash to validate against - //this will confirm that my friend has the same keys - //i orginally packaged for him + var isAccepted = false; - Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { + if (FRIENDSLIST[selectedFriend.userName].IsSend) { + isAccepted = true; + } - if (result) { - $("#validateform").hide(); - $("#validatesuccess").show(); - $("#txtCode").val(''); - selectedFriend.validated = true; - FRIENDSLIST[selectedFriend.userName].validated = true; - updateSelectedFriend(); - //update list also + if (isAccepted) { - //find friend in list and update the validated icon - $("#myfriends #seltarget" + selectedFriend.userName).html('
    '); + Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { + if (result) { - } else { - $("#validatefail").show(); - } + $("#validateform").hide(); + $("#validatesuccess").show(); + $("#txtCode").val(''); + selectedFriend.validated = true; + FRIENDSLIST[selectedFriend.userName].validated = true; + updateSelectedFriend(); - }); + //update list also + + //find friend in list and update the validated icon + $("#myfriends #seltarget" + selectedFriend.userName).html('
    '); + + + } else { + + $("#validatefail").show(); + + } + + $("#verifyspinner").hide(); + $("#btnVerify").prop('disabled', false); + }); + + } else { + + Engine.acceptFriendRequest(SELECTEDFRIEND, function (err, res) { + + + //get the hash to validate against + //this will confirm that my friend has the same keys + //i orginally packaged for him + + Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) { + + if (result) { + $("#validateform").hide(); + $("#validatesuccess").show(); + $("#txtCode").val(''); + selectedFriend.validated = true; + FRIENDSLIST[selectedFriend.userName].validated = true; + updateSelectedFriend(); + + //update list also + + //find friend in list and update the validated icon + $("#myfriends #seltarget" + selectedFriend.userName).html('
    '); + + + } else { + $("#validatefail").show(); + } + + $("#verifyspinner").hide(); + $("#btnVerify").prop('disabled', false); + }); + + }); + + } }); @@ -2254,7 +2718,7 @@ function UI() { //TWOFACTORONLOGIN = true; //refresh settings panel - readAccountSettingsFromServerAndPopulateForm(); + readAccountSettings(); $("#twofactorsettings").hide(); $("#btnSetupTwoFactor").hide(); @@ -2279,9 +2743,34 @@ function UI() { $("#hsettings").click(function () { - readAccountSettingsFromServerAndPopulateForm(); + + }); + + + + $("#btnSaveBackup").click(function () { + + //errbackup + backupHotKey('#errbackup'); + + }); + + $("#btnSaveBackupP").click(function () { + + //errbackupp + backupHotKey('#errbackupp'); + }); + $("#backupHot").click(function () { + + //errbackuphot + backupHotKey('#errbackuphot'); + + }); + + + $("#savesettingsbutton").click(function () { if ($("#frmsettings").parsley('validate')) { saveAccountSettingsToServer(); @@ -2600,9 +3089,6 @@ function UI() { }); - - - $("#openWalletStart #password").focus(); }); $('#txtTax').blur(function () { @@ -3513,7 +3999,7 @@ function UI() { - function initialiseUI() { + function initialiseUI(callback) { //check if hot key is available //if not prompt the user to enter their hot key @@ -3521,7 +4007,7 @@ function UI() { Engine.appHasLoaded(); - Engine.getHotHash("",function (err, result) { + Engine.getHotHash("", function (err, result) { if (err) { @@ -3599,6 +4085,7 @@ function UI() { catOptions += ''; $("#netcatoptions").html(catOptions); + $("#nselnetcat").change(function () { $("#nselnetcat option:selected").each(function () { @@ -3621,15 +4108,17 @@ function UI() { document.onAway = function () { logout(); } + setInterval(function () { updateUI(); }, 10000); - + setInterval(function () { + refreshSelectedFriend(); + }, 30000); - updateUI(); + - updateRequestsMadeByMe(); $('#showPhrases').hide(); $("#openWalletStart").hide(); @@ -3659,11 +4148,23 @@ function UI() { $("#validateemail").hide(); } + updateUI(); + + updateRequestsMadeByMe(); + + readAccountSettings(); + + setAwayTimeout(600000); $('#stdselcu').click(); $('#netselcu').click(); + if (callback) { + + return callback(false, "ok"); + + } } @@ -3703,10 +4204,14 @@ function UI() { updateUI(); } + + + + function updateUI() { - Ninki.API.getPrice(Engine.m_settings.LocalCurrency, function (err, result) { + Ninki.API.getPrice(Engine.m_guid, Engine.m_settings.LocalCurrency, function (err, result) { price = result * 1.0; @@ -3761,13 +4266,6 @@ function UI() { showInvoiceListNetwork(function (err, res) { - if (!norefresh) { - refreshSelectedFriend(function (err, res) { - - console.log('completed refresh'); - - }); - } }); @@ -3796,6 +4294,10 @@ function UI() { $("#lostguid").hide(); $("#reset2fa").hide(); $("#validateemail").hide(); + $("#password").focus(); + $("#signdiff").show(); + $("#crwallet").show(); + } function showTwoFactorQr() { @@ -3838,7 +4340,7 @@ function UI() { } //Download settings from server and populate input boxes - function readAccountSettingsFromServerAndPopulateForm() { + function readAccountSettings() { $("#savesettingserror").hide(); $("#savesettingssuccess").hide(); @@ -3981,7 +4483,7 @@ function UI() { if (jsonPacket['CoinUnit'] != COINUNIT) { COINUNIT = jsonPacket['CoinUnit']; lastNoOfTrans = -1; - readAccountSettingsFromServerAndPopulateForm(); + readAccountSettings(); $("#stdsendcunit").text(COINUNIT); $("#amount").val(''); $("#friendAmount").val(''); @@ -4104,28 +4606,40 @@ function UI() { Engine.getBalance(function (err, result) { - //get in BTC units - var balance = convertFromSatoshis(result.TotalBalance, COINUNIT); + if (!err) { + //get in BTC units + var balance = convertFromSatoshis(result.TotalBalance, COINUNIT); - $("#balance").text(balance); - $("#balanceTop").text(balance + " " + COINUNIT); - //$("#balanceTop").text(balance + " " + COINUNIT + " ($" + (xccy) + ")"); - $("#dashcoinunit").text(COINUNIT); - var template = ''; - if (result.UnconfirmedBalance > 0) { - template += '
    '; - } else { - template += '
    '; - } + if (COINUNIT == 'BTC') { + $("#balance").text(balance); + $("#balanceTop").text(balance + " " + COINUNIT); + } else { + $("#balance").text(balance.toLocaleString()); + $("#balanceTop").text(balance.toLocaleString() + " " + COINUNIT); + } - $("#balancetimer").html(template); - if (callback) { - callback(); - } + //$("#balanceTop").text(balance + " " + COINUNIT + " ($" + (xccy) + ")"); + $("#dashcoinunit").text(COINUNIT); + var template = ''; + if (result.UnconfirmedBalance > 0) { + template += '
    '; + } else { + template += '
    '; + } + $("#balancetimer").html(template); + + if (callback) { + callback(); + } + } else { + $("#balance").text("connecting..."); + $("#balanceTop").text("connecting..."); + + } }); @@ -4502,11 +5016,11 @@ function UI() { } function refreshSelectedFriend(callback) { + if (!norefresh) { + if (SELECTEDFRIEND.length > 0) { - if (SELECTEDFRIEND.length > 0) { + Engine.getFriend(SELECTEDFRIEND, function (err, friend) { - Engine.getFriend(SELECTEDFRIEND, function (err, friend) { - if (!norefresh) { if (SELECTEDFRIEND == friend.userName) { selectedFriend = friend; FRIENDSLIST[SELECTEDFRIEND] = friend; @@ -4570,15 +5084,19 @@ function UI() { $("#friendvalreq").show(); } - callback(err, friend); + if (callback) { + callback(err, friend); + } //updateSelectedFriend(function (err, res) { // selFriendBkgUpdate = false; // callback(err, res); //}); } - } - }); + + }); + + } } @@ -4647,7 +5165,7 @@ function UI() { } //if (selectedFriend.status != '') { - $("#friendSelectedStatus").text(selectedFriend.status); + $("#friendSelectedStatus").text(selectedFriend.status); //} if (isChromeApp()) { @@ -4749,7 +5267,7 @@ function UI() { '
    ' + '' + _.escape(friends[i].userName) + '' + 'has requested you as a contact' + - '
    Accept Reject' + + '
    ' + '
    '; $("#friendreq").append(template); @@ -4761,10 +5279,51 @@ function UI() { $("#friendreq #btnaccept" + i).click({ - userName: friends[i].userName + userName: friends[i].userName, index: i }, function (event) { + + $(this).prop('disabled', true); + $("#friendreq #btnreject" + event.data.index).prop('disabled', true); + + $("#imgrequestwaiting").show(); + var target = document.getElementById('imgrequestwaiting'); + var spinner = new Spinner(spinneropts).spin(target); + + var that = $(this); + var thatrej = $("#friendreq #btnreject" + event.data.index); + acceptFriend(event.data.userName, function (err, res) { + if (!err) { + lastNoOfFriendsReq = 0; + updateFriendRequests(); + } + + $("#imgrequestwaiting").hide(); + $(that).prop('disabled', false); + $(thatrej).prop('disabled', false); + + }); + }); + + + $("#friendreq #btnreject" + i).click({ + userName: friends[i].userName, index: i + }, function (event) { + + $(this).prop('disabled', true); + $("#friendreq #btnaccept" + event.data.index).prop('disabled', true); + + var that = $(this); + var thatacc = $("#friendreq #btnaccept" + event.data.index); + rejectFriend(event.data.userName, function (err, res) { + + if (!err) { + updateFriendRequests(); + } + + $(that).prop('disabled', false); + $(thatacc).prop('disabled', false); //handle here instead }); @@ -4815,7 +5374,11 @@ function UI() { }); - return callback(false, "ok"); + if (callback) { + + return callback(false, "ok"); + + } } @@ -5188,16 +5751,18 @@ function UI() { - function addFriend() { + $("#btnaddfriend").click(function () { var username = $('input#friend').val(); if (username.length == 0 || Engine.m_nickname == username) { $("#friend").css("border-color", "#ffaaaa"); + return; } - + $("#btnaddfriend").prop('disabled', true); $("#imgaddcontactwaiting").show(); + var target = document.getElementById('imgaddcontactwaiting'); var spinner = new Spinner(spinneropts).spin(target); @@ -5212,43 +5777,71 @@ function UI() { //also check if friend already - if (usernameExistsOnServer) { + if (!err) { - Engine.isNetworkExist(username, function (err, result) { + if (usernameExistsOnServer) { - if (!result) { + Engine.isNetworkExist(username, function (err, result) { - $("#friend").css("border-color", "#ccc"); - Engine.createFriend(username, '', function (err, result) { - if (err) { - $("#friend").css("border-color", "#ffaaaa"); - $("#addcontactalert").show(); - $("#addcontactalertmessage").text(result); - $("#imgaddcontactwaiting").hide(); + if (!err) { + + if (!result) { + + $("#friend").css("border-color", "#ccc"); + + Engine.createFriend(username, '', function (err, result) { + if (err) { + $("#friend").css("border-color", "#ffaaaa"); + $("#addcontactalert").show(); + $("#addcontactalertmessage").text(result); + $("#imgaddcontactwaiting").hide(); + + } else { + + $("#friend").val(''); + $("#imgaddcontactwaiting").hide(); + $("#addcontactsuccess").show(); + $("#addcontactsuccessmessage").text("You requested " + username + " as a contact"); + $("#addcontactsuccess").fadeOut(5000); + + updateRequestsMadeByMe(); + } + + $("#btnaddfriend").prop('disabled', false); + + }); + } else { - $("#friend").val(''); + $("#friend").css("border-color", "#ffaaaa"); + $("#addcontactalert").show(); + $("#addcontactalertmessage").text("You have already requested " + username + " as a contact"); $("#imgaddcontactwaiting").hide(); - $("#addcontactsuccess").show(); - $("#addcontactsuccessmessage").text("You requested " + username + " as a contact"); - $("#addcontactsuccess").fadeOut(5000); - updateRequestsMadeByMe(); + $("#btnaddfriend").prop('disabled', false); } - }); - } else { + } else { - $("#friend").css("border-color", "#ffaaaa"); - $("#addcontactalert").show(); - $("#addcontactalertmessage").text("You have already requested " + username + " as a contact"); - $("#imgaddcontactwaiting").hide(); + $("#friend").css("border-color", "#ffaaaa"); + $("#addcontactalert").show(); + $("#addcontactalertmessage").text(result); + $("#imgaddcontactwaiting").hide(); + $("#btnaddfriend").prop('disabled', false); - } - }); + } + }); + } else { + $("#friend").css("border-color", "#ffaaaa"); + $("#addcontactalert").show(); + $("#addcontactalertmessage").text("The username could not be found"); + $("#imgaddcontactwaiting").hide(); + $("#btnaddfriend").prop('disabled', false); + + } } else { @@ -5256,57 +5849,56 @@ function UI() { $("#addcontactalert").show(); $("#addcontactalertmessage").text("The username could not be found"); $("#imgaddcontactwaiting").hide(); + $("#btnaddfriend").prop('disabled', false); } }); - } + }); - function rejectFriend(username) { + function rejectFriend(username, callback) { Engine.rejectFriendRequest(username, function (err, result) { - updateFriendRequests(); + return callback(err, result); }); } - function acceptFriend(username) { + function acceptFriend(username, callback) { //need to add error handling and messages here - $("#imgrequestwaiting").show(); - var target = document.getElementById('imgrequestwaiting'); - var spinner = new Spinner(spinneropts).spin(target); - - //$('#friendreq').fadeOut(1000); Engine.acceptFriendRequest(username, function (err, secret) { + if (err) { - //alert("Wallet could not be opened.\n\n" + err); + return callback(err, secret); + } else { Engine.isNetworkExist(username, function (err, result) { if (!result) { - Engine.createFriend(username, '', '', function (err, result) { + Engine.createFriend(username, '', function (err, result) { if (err) { + return callback(err, result); } else { - $("#imgrequestwaiting").hide(); + + return callback(err, result); } }); - } - - lastNoOfFriendsReq = 0; + } else { - updateFriendRequests(); + return callback(err, result); + } }); }