diff --git a/index.html b/index.html
index 4acac0961..31992f889 100644
--- a/index.html
+++ b/index.html
@@ -85,7 +85,7 @@
Share this secret with your other copayers for them to join your wallet
- {{$root.wallet.getMyCopayerId()}}
+ {{$root.wallet.getSecret()}}
diff --git a/js/controllers/signin.js b/js/controllers/signin.js
index f1e8b2fe4..052179478 100644
--- a/js/controllers/signin.js
+++ b/js/controllers/signin.js
@@ -18,24 +18,26 @@ angular.module('copay.signin').controller('SigninController',
};
$scope.join = function(secret) {
- if (!secret || secret.length !==66 || !secret.match(/^[0-9a-f]*$/) ) {
- $rootScope.flashMessage = { message: 'Bad secret secret string', type: 'error'};
- return;
- }
$scope.loading = true;
- walletFactory.network.on('joinError', function() {
- controllerUtils.onErrorDigest($scope);
+ walletFactory.network.on('badSecret', function() {
});
- walletFactory.joinCreateSession(secret, function(w) {
- if (w) {
- controllerUtils.startNetwork(w);
- }
- else {
- $scope.loading = false;
- controllerUtils.onErrorDigest();
+ walletFactory.joinCreateSession(secret, function(err,w) {
+ $scope.loading = false;
+console.log('[signin.js.27:err:]',err,w); //TODO
+
+ if (err || !w) {
+ if (err === 'joinError')
+ $rootScope.flashMessage = { message: 'Can not find peer'};
+ else if (err === 'badSecret')
+ $rootScope.flashMessage = { message: 'Bad secret secret string', type: 'error'};
+ else
+ $rootScope.flashMessage = { message: 'Unknown error', type: 'error'};
+ controllerUtils.onErrorDigest();
}
+ else
+ controllerUtils.startNetwork(w);
});
};
});
diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js
index 02646d3c9..1a9898993 100644
--- a/js/models/core/Wallet.js
+++ b/js/models/core/Wallet.js
@@ -9,6 +9,8 @@ var Builder = bitcore.TransactionBuilder;
var http = require('http');
var EventEmitter = imports.EventEmitter || require('events').EventEmitter;
var copay = copay || require('../../../copay');
+var SecureRandom = bitcore.SecureRandom;
+var Base58Check = bitcore.Base58.base58Check;
function Wallet(opts) {
var self = this;
@@ -26,6 +28,8 @@ function Wallet(opts) {
this.id = opts.id || Wallet.getRandomId();
this.name = opts.name;
+ this.netKey = opts.netKey || SecureRandom.getRandomBuffer(8).toString('base64');
+
this.verbose = opts.verbose;
this.publicKeyRing.walletId = this.id;
this.txProposals.walletId = this.id;
@@ -124,6 +128,7 @@ Wallet.prototype._optsToObj = function() {
requiredCopayers: this.requiredCopayers,
totalCopayers: this.totalCopayers,
name: this.name,
+ netKey: this.netKey,
};
return obj;
@@ -139,6 +144,26 @@ Wallet.prototype.getMyCopayerId = function() {
return this.getCopayerId(0);
};
+
+Wallet.prototype.getSecret = function() {
+ var i = new Buffer(this.getMyCopayerId(),'hex');
+ var k = new Buffer(this.netKey,'base64');
+ var b = Buffer.concat([i,k]);
+ var str = Base58Check.encode(b);
+ return str;
+};
+
+
+Wallet.decodeSecret = function(secretB) {
+ var secret = Base58Check.decode(secretB);
+ var netKeyBuf = secret.slice(-8);
+ var pubKeyBuf = secret.slice(0,33);
+ return {
+ pubKey: pubKeyBuf.toString('hex'),
+ netKey: netKeyBuf.toString('base64'),
+ }
+};
+
Wallet.prototype._lockIncomming = function() {
this.network.lockIncommingConnections(this.publicKeyRing.getAllCopayerIds());
};
@@ -162,6 +187,7 @@ Wallet.prototype.netStart = function() {
var startOpts = {
copayerId: myId,
maxPeers: self.totalCopayers,
+ netKey: this.netKey,
};
if (this.publicKeyRing.isComplete()) {
diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js
index a8dd80f84..cb6974120 100644
--- a/js/models/core/WalletFactory.js
+++ b/js/models/core/WalletFactory.js
@@ -149,27 +149,35 @@ WalletFactory.prototype.remove = function(walletId) {
};
-WalletFactory.prototype.joinCreateSession = function(copayerId, cb) {
+WalletFactory.prototype.joinCreateSession = function(secret, cb) {
var self = this;
+ var s;
+ try {
+ s=Wallet.decodeSecret(secret);
+ } catch (e) {
+ return cb('badSecret');
+ }
+
//Create our PrivateK
var privateKey = new PrivateKey({ networkName: this.networkName });
this.log('\t### PrivateKey Initialized');
var opts = {
copayerId: privateKey.getId(),
+ netKey: s.netKey,
};
self.network.cleanUp();
self.network.start(opts, function() {
- self.network.connectTo(copayerId);
+ self.network.connectTo(s.pubKey);
self.network.on('onlyYou', function(sender, data) {
- return cb();
+ return cb('joinError');
});
self.network.on('data', function(sender, data) {
if (data.type ==='walletId') {
data.opts.privateKey = privateKey;
var w = self.open(data.walletId, data.opts);
- w.firstCopayerId = copayerId;
- return cb(w);
+ w.firstCopayerId = s.pubKey;
+ return cb(null, w);
}
});
});
diff --git a/js/models/network/WebRTC.js b/js/models/network/WebRTC.js
index f45eaa1f4..d45b5aae6 100644
--- a/js/models/network/WebRTC.js
+++ b/js/models/network/WebRTC.js
@@ -3,7 +3,6 @@ var imports = require('soop').imports();
var EventEmitter= imports.EventEmitter || require('events').EventEmitter;
var bitcore = require('bitcore');
var util = bitcore.util;
-var Key = bitcore.Key;
/*
* Emits
* 'networkChange'
@@ -18,12 +17,11 @@ var Key = bitcore.Key;
*/
function Network(opts) {
- var self = this;
+ var self = this;
opts = opts || {};
this.apiKey = opts.apiKey || 'lwjd5qra8257b9';
this.debug = opts.debug || 3;
this.maxPeers = opts.maxPeers || 10;
- this.opts = { key: opts.key };
this.sjclParams = opts.sjclParams || {
salt: 'f28bfb49ef70573c',
iter:500,
@@ -31,8 +29,10 @@ function Network(opts) {
ts:parseInt(64),
};
+
// For using your own peerJs server
- ['port', 'host', 'path', 'debug'].forEach(function(k) {
+ self.opts = {};
+ ['port', 'host', 'path', 'debug', 'key'].forEach(function(k) {
if (opts[k]) self.opts[k] = opts[k];
});
this.cleanUp();
@@ -44,6 +44,7 @@ Network.prototype.cleanUp = function() {
this.started = false;
this.connectedPeers = [];
this.peerId = null;
+ this.netKey = null;
this.copayerId = null;
this.signingKey = null;
this.allowedCopayerIds=null;
@@ -338,6 +339,7 @@ Network.prototype.start = function(opts, openCallback) {
if (this.started) return openCallback();
+ this.netKey = opts.netKey;
this.maxPeers = opts.maxPeers || this.maxPeers;
if (!this.copayerId)
@@ -363,22 +365,10 @@ Network.prototype.getPeer = function() {
return this.peer;
};
-
-Network.prototype._keyForCopayerId = function(copayerId) {
- var key=this.keyCache[copayerId];
- if (key) return key;
-
- var cBuf = new Buffer(copayerId,'hex');
- var key = bitcore.util.sha256(cBuf).toString('base64');
- this.keyCache[copayerId] = key;
- return key;
-};
-
-Network.prototype._encryptFor = function(copayerId, payloadStr) {
- var key = this._keyForCopayerId(copayerId);
+Network.prototype._encrypt = function(payloadStr) {
var plainText = sjcl.codec.utf8String.toBits(payloadStr);
- var p = this.sjclParams; // auth strength
- ct = sjcl.encrypt(key, plainText, p);//,p, rp);
+ var p = this.sjclParams;
+ ct = sjcl.encrypt(this.netKey, plainText, p);//,p, rp);
var c = JSON.parse(ct);
var toSend = {
iv: c.iv,
@@ -394,8 +384,7 @@ Network.prototype._decrypt = function(encStr) {
i[k] = this.sjclParams[k];
}
var str= JSON.stringify(i);
- var key= this._keyForCopayerId(this.copayerId);
- var pt = sjcl.decrypt(key, str);
+ var pt = sjcl.decrypt(this.netKey, str);
return pt;
};
@@ -404,7 +393,7 @@ Network.prototype._sendToOne = function(copayerId, payloadStr, sig, cb) {
if (peerId !== this.peerId) {
var dataConn = this.connections[peerId];
if (dataConn) {
- dataConn.send(this._encryptFor(copayerId, payloadStr));
+ dataConn.send(this._encrypt(payloadStr));
}
else {
console.log('[WebRTC.js.255] WARN: NO CONNECTION TO:', peerId); //TODO
diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js
index bfdc3909e..2690e2cbc 100644
--- a/js/services/controllerUtils.js
+++ b/js/services/controllerUtils.js
@@ -29,11 +29,6 @@ angular.module('copay.controllerUtils')
root.onError = function(scope) {
if (scope) scope.loading = false;
- $rootScope.flashMessage = {
- type: 'error',
- message: 'Could not connect to peer: ' +
- scope
- };
root.logout();
}
diff --git a/js/services/video.js b/js/services/video.js
index 367296934..3902a04bc 100644
--- a/js/services/video.js
+++ b/js/services/video.js
@@ -7,7 +7,7 @@ var Video = function() {
this.mediaConnections = {};
this.localStream = null;
- this.onlineSound = new Audio('../../sound/online.wav');
+ this.onlineSound = new Audio('sound/online.wav');
};
Video.prototype.setOwnPeer = function(peer, wallet, cb) {
@@ -72,11 +72,13 @@ Video.prototype._addCall = function(mediaConnection, cb) {
}
Video.prototype.close = function() {
- this.localStream.stop();
- this.localStream.mozSrcObject = null;
- this.localStream.src = "";
- this.localStream.src = null;
- this.localStream = null;
+ if (this.localStream){
+ this.localStream.stop();
+ this.localStream.mozSrcObject = null;
+ this.localStream.src = "";
+ this.localStream.src = null;
+ this.localStream = null;
+ }
for (var i = 0; this.mediaConnections.length; i++) {
this.mediaConnections[i].close();
}
diff --git a/test/test.Wallet.js b/test/test.Wallet.js
index bc34c0690..2d6fbfef1 100644
--- a/test/test.Wallet.js
+++ b/test/test.Wallet.js
@@ -31,9 +31,10 @@ describe('Wallet model', function() {
(function(){new Wallet(config)}).should.throw();
});
- var createW = function () {
+ var createW = function (netKey) {
var c = JSON.parse(JSON.stringify(config));
-
+
+ if (netKey) c.netKey = netKey;
c.privateKey = new copay.PrivateKey({ networkName: c.networkName });
c.publicKeyRing = new copay.PublicKeyRing({
@@ -66,6 +67,9 @@ describe('Wallet model', function() {
should.exist(w.publicKeyRing);
should.exist(w.privateKey);
should.exist(w.txProposals);
+ should.exist(w.netKey);
+ var b = new Buffer(w.netKey,'base64');
+ b.toString('hex').length.should.equal(16);
});
it('should provide some basic features', function () {
@@ -88,7 +92,8 @@ describe('Wallet model', function() {
];
var createW2 = function (privateKeys) {
- var w = createW();
+ var netKey = 'T0FbU2JLby0=';
+ var w = createW(netKey);
should.exist(w);
var pkr = w.publicKeyRing;
@@ -188,4 +193,21 @@ describe('Wallet model', function() {
should.exist(w2.privateKey.toObj);
});
+ it('#getSecret decodeSecret', function () {
+ var w = createW2();
+ var id = w.getMyCopayerId();
+ var nk = w.netKey;
+
+ var sb= w.getSecret();
+ should.exist(sb);
+ var s = Wallet.decodeSecret(sb);
+ s.pubKey.should.equal(id);
+ s.netKey.should.equal(nk);
+
+ });
+ it('decodeSecret check', function () {
+ (function(){Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoKM');}).should.not.throw();
+ (function(){Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoK');}).should.throw();
+ (function(){Wallet.decodeSecret('12345');}).should.throw();
+ });
});