Skip to content

Commit

Permalink
Let user resolve conflicts when importing mpsites
Browse files Browse the repository at this point in the history
(Issue #28)
  • Loading branch information
ttyridal committed Aug 8, 2016
1 parent 705e147 commit 88176d6
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 43 deletions.
138 changes: 107 additions & 31 deletions ext/data/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,22 @@ function save_sites_to_backend() {
document.documentElement.dispatchEvent(event);
}

function stored_sites_table_append(domain, site, type, loginname, count, ver) {
function passtype_to_str(type) {
switch(type) {
case 'x': type="Maximum"; break;
case 'l': type="Long"; break;
case 'm': type="Medium"; break;
case 'b': type="Basic"; break;
case 's': type="Short"; break;
case 'i': type="Pin"; break;
case 'n': type="Name"; break;
case 'p': type="Phrase"; break;
case 'x': return "Maximum";
case 'l': return "Long";
case 'm': return "Medium";
case 'b': return "Basic";
case 's': return "Short";
case 'i': return "Pin";
case 'n': return "Name";
case 'p': return "Phrase";
default: throw new Error("Unknown password type");
}
}

function stored_sites_table_append(domain, site, type, loginname, count, ver) {
type = passtype_to_str(type);
$('#stored_sites > tbody').append('<tr><td>'+site+'<td><input class="domainvalue" type="text" data-old="'+
domain+'" value="'+domain+'"><td>'+loginname+'<td>'+count+'<td>'+type+'<td>'+ver+
'<td><img class="delete" src="delete.png">');
Expand Down Expand Up @@ -123,6 +127,51 @@ $('#stored_sites').on('click','.delete',function(e){
save_sites_to_backend();
});


function get_sitesearch(sitename) {
let y = sitename.split("@");
if (y.length > 1)
return y[y.length-1];
else
return sitename;
}

function resolveConflict(site) {
return new Promise(function(resolve, reject){
var div = document.createElement('div');
div.style.cssText = "position:fixed;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,0.7);z-index:500";
div.innerHTML = [
'<div style="border:2px black inset;position:fixed;top:5em;left:5em;width:50%;background:white;padding: 1em"><h2>Conflicting ',
site.sitename,
' (<small>',site.sitesearch,'</small>)',
'</h2><h3>existing</h3>',
'type: ', passtype_to_str(stored_sites[site.sitesearch][site.sitename].type),
' count: ', stored_sites[site.sitesearch][site.sitename].generation,
' username: ', stored_sites[site.sitesearch][site.sitename].username,
'<h3>importing</h3>',
'type: ', passtype_to_str(site.passtype),
' count: ', site.passcnt,
' username: ', site.loginname,
'<div style="padding-top:1em"><button id="existing">Keep existing</button> <button id="imported">Replace with imported</button></div>',
'</div>'].join('');
div.addEventListener('click', function(ev){
switch (ev.target.id) {
case 'existing':
resolve(stored_sites[site.sitesearch][site.sitename]);
break;
case 'imported':
resolve({'generation': site.passcnt, 'type': site.passtype, 'username': site.loginname});
break;
default:
return;

}
div.parentNode.removeChild(div);
});
document.querySelector('body').appendChild(div);
});
}

$(document).on('drop', function(e){
e.originalEvent.dataTransfer.dropEffect='move';
e.preventDefault();
Expand All @@ -146,32 +195,59 @@ $(document).on('drop', function(e){
else throw e;
}

for (let site of x) {
let y = site.sitename.split("@");
if (y.length > 1)
site.sitesearch = y[y.length-1];
else
site.sitesearch = site.sitename;
var done = new Promise(function(all_done){
function popsite() {
if (! x.length) return false;

if (site.passalgo < 2 && !string_is_plain_ascii(site.sitename))
has_ver1_mb_sites = true;
var p, site = x.shift();

if (! (site.sitesearch in stored_sites)) stored_sites[site.sitesearch] = {};
stored_sites[site.sitesearch][site.sitename] = {
'generation': site.passcnt,
'type': site.passtype,
'username': site.loginname
};
}
stored_sites_table_update(stored_sites);
site.sitesearch = get_sitesearch(site.sitename);
if (site.passalgo < 2 && !string_is_plain_ascii(site.sitename))
has_ver1_mb_sites = true;

if (! (site.sitesearch in stored_sites)) stored_sites[site.sitesearch] = {};
if (site.sitename in stored_sites[site.sitesearch] &&
(stored_sites[site.sitesearch][site.sitename].generation !== site.passcnt ||
stored_sites[site.sitesearch][site.sitename].type !== site.passtype ||
stored_sites[site.sitesearch][site.sitename].username !== site.loginname)) {

p = resolveConflict(site);
} else {
p = Promise.resolve({'generation': site.passcnt, 'type': site.passtype, 'username': site.loginname}, undefined);
}

p.then(function(cfg, nextanswer){
stored_sites[site.sitesearch][site.sitename] = cfg;
if (!popsite())
all_done();
})
.catch(function(reason){
console.error("popsite failed", reason);
});

if (has_ver1_mb_sites)
alert("Version mismatch\n\nYour file contains site names with non ascii characters from "+
"an old masterpassword version. This addon can not reproduce these passwords");
else
console.debug('Import successful');
return true;
}

if (!popsite())
all_done();
});


done.then(function(){
stored_sites_table_update(stored_sites);

if (has_ver1_mb_sites)
alert("Version mismatch\n\nYour file contains site names with non ascii characters from "+
"an old masterpassword version. This addon can not reproduce these passwords");
else
console.debug('Import successful');

save_sites_to_backend();
})
.catch(function(err){
console.error(err);
});

save_sites_to_backend();
};
fr.readAsText(e.originalEvent.dataTransfer.files[0]);

Expand Down
29 changes: 17 additions & 12 deletions ext/test/test-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ function mpsites_upload_jquery() {
});
}
},
append: function(){}
append: function(){},
empty: function(){}
};
}

Expand Down Expand Up @@ -54,7 +55,7 @@ exports["test mpsites upload invalid"] = function(assert) {
assert.ok(got_alert_not_mpsites);
};

exports["test mpsites upload valid"] = function(assert) {
exports["test mpsites upload valid"] = function(assert, async_test_done) {
var self = require("sdk/self");
const { sandbox, evaluate, load } = require("sdk/loader/sandbox");

Expand All @@ -71,14 +72,25 @@ exports["test mpsites upload valid"] = function(assert) {
].join('\n');

var version_mismatch_received = false;
var event_received;
var scope = sandbox();
scope.window = {
'addEventListener': function(){}
};
scope.document = {
createEvent:function(){return{initCustomEvent:function(){ this.sites = arguments[3];}};},
documentElement:{dispatchEvent: function(e){event_received=e;}}
createEvent:function(){return{initCustomEvent:function(){this.type = arguments[0]; this.sites = arguments[3];}};},
documentElement:{
dispatchEvent: function(event_received){
assert.equal(event_received.type, "masterpassword-siteupdate");
assert.ok(version_mismatch_received);
assert.ok('asite' in event_received.sites);
assert.ok('åsite' in event_received.sites);
assert.equal(event_received.sites.asite.asite.generation, 6);
assert.equal(event_received.sites.asite.asite.type, 'x');
assert.equal(event_received.sites['åsite']['åsite'].generation, 4);
assert.equal(event_received.sites['åsite']['åsite'].type, 'm');
async_test_done();
}
}
};
scope.console = console;
scope.confirm = function(m){return true;};
Expand All @@ -90,13 +102,6 @@ exports["test mpsites upload valid"] = function(assert) {
};
load(scope, self.data.url('mpw-utils.js'));
load(scope, self.data.url('config.js'));
assert.ok(version_mismatch_received);
assert.ok('asite' in event_received.sites);
assert.ok('åsite' in event_received.sites);
assert.equal(event_received.sites.asite.asite.generation, 6);
assert.equal(event_received.sites.asite.asite.type, 'x');
assert.equal(event_received.sites['åsite']['åsite'].generation, 4);
assert.equal(event_received.sites['åsite']['åsite'].type, 'm');
};

exports["test main handlers"] = function(assert, async_test_done) {
Expand Down

0 comments on commit 88176d6

Please sign in to comment.