fix #10: use webcrypto for keyfile encryption if it's available

This commit is contained in:
Antelle 2015-11-04 00:59:57 +03:00
parent 73b51c2dae
commit 3b0c0f9f89
3 changed files with 87 additions and 69 deletions

View File

@ -51,13 +51,18 @@ var FileModel = Backbone.Model.extend({
password = new kdbxweb.ProtectedValue(value.buffer.slice(0, byteLength), salt.buffer.slice(0, byteLength));
try {
var credentials = new kdbxweb.Credentials(password, keyFileData);
this.db = kdbxweb.Kdbx.load(fileData, credentials);
kdbxweb.Kdbx.load(fileData, credentials, (function(db, err) {
if (err) {
this.set({error: true, opening: false});
} else {
this.db = db;
this.readModel(this.get('name'));
this.setOpenFile({ passwordLength: len });
}
}).bind(this));
} catch (e) {
this.set({ error: true, opening: false });
return;
}
this.readModel(this.get('name'));
this.setOpenFile({ passwordLength: len });
},
create: function(name) {
@ -72,9 +77,11 @@ var FileModel = Backbone.Model.extend({
var password = kdbxweb.ProtectedValue.fromString('demo');
var credentials = new kdbxweb.Credentials(password);
var demoFile = kdbxweb.ByteUtils.arrayToBuffer(kdbxweb.ByteUtils.base64ToBytes(demoFileData));
this.db = kdbxweb.Kdbx.load(demoFile, credentials);
this.readModel();
this.setOpenFile({ passwordLength: 4, demo: true, name: 'Demo' });
kdbxweb.Kdbx.load(demoFile, credentials, (function(db) {
this.db = db;
this.readModel();
this.setOpenFile({passwordLength: 4, demo: true, name: 'Demo'});
}).bind(this));
},
setOpenFile: function(props) {
@ -164,27 +171,31 @@ var FileModel = Backbone.Model.extend({
this.set('syncing', true);
switch (this.get('storage')) {
case 'file':
Launcher.writeFile(this.get('path'), this.getData());
this.saved(this.get('path'), this.get('storage'));
this.getData(function(data) {
Launcher.writeFile(this.get('path'), data);
this.saved(this.get('path'), this.get('storage'));
});
break;
case 'dropbox':
DropboxLink.saveFile(this.get('path'), this.getData(), true, (function(err) {
if (!err) {
this.saved(this.get('path'), this.get('storage'));
}
}).bind(this));
this.getData(function(data) {
DropboxLink.saveFile(this.get('path'), data, true, (function (err) {
if (!err) {
this.saved(this.get('path'), this.get('storage'));
}
}).bind(this));
});
break;
default:
throw 'Unknown storage; cannot auto save';
}
},
getData: function() {
return this.db.save();
getData: function(cb) {
return this.db.save(cb);
},
getXml: function() {
return this.db.saveXml();
getXml: function(cb) {
this.db.saveXml(cb);
},
saved: function(path, storage) {

View File

@ -98,26 +98,28 @@ var SettingsAboutView = Backbone.View.extend({
if (!this.validate()) {
return;
}
var data = this.model.getData();
var fileName = this.model.get('name') + '.kdbx';
if (Launcher) {
if (this.model.get('path')) {
this.saveToFileWithPath(this.model.get('path'), data);
var that = this;
this.model.getData(function(data) {
var fileName = that.model.get('name') + '.kdbx';
if (Launcher) {
if (that.model.get('path')) {
that.saveToFileWithPath(that.model.get('path'), data);
} else {
Launcher.getSaveFileName(fileName, function (path) {
if (path) {
that.saveToFileWithPath(path, data);
}
});
}
} else {
Launcher.getSaveFileName(fileName, (function (path) {
if (path) {
this.saveToFileWithPath(path, data);
}
}).bind(this));
var blob = new Blob([data], {type: 'application/octet-stream'});
FileSaver.saveAs(blob, fileName);
that.passwordChanged = false;
if (that.model.get('storage') !== 'dropbox') {
that.model.saved();
}
}
} else {
var blob = new Blob([data], {type: 'application/octet-stream'});
FileSaver.saveAs(blob, fileName);
this.passwordChanged = false;
if (this.model.get('storage') !== 'dropbox') {
this.model.saved();
}
}
});
},
saveToFileWithPath: function(path, data) {
@ -140,9 +142,10 @@ var SettingsAboutView = Backbone.View.extend({
if (!this.validate()) {
return;
}
var data = this.model.getXml();
var blob = new Blob([data], {type: 'text/xml'});
FileSaver.saveAs(blob, this.model.get('name') + '.xml');
this.model.getXml((function(xml) {
var blob = new Blob([xml], {type: 'text/xml'});
FileSaver.saveAs(blob, this.model.get('name') + '.xml');
}).bind(this));
},
saveToDropboxClick: function() {
@ -155,37 +158,41 @@ var SettingsAboutView = Backbone.View.extend({
if (this.model.get('syncing') || !this.validate()) {
return;
}
var data = this.model.getData();
var fileName = this.model.get('name') + '.kdbx';
this.model.set('syncing', true);
this.render();
DropboxLink.saveFile(fileName, data, overwrite, (function(err) {
if (err) {
this.model.set('syncing', false);
if (err.exists) {
Alerts.alert({
header: 'Already exists',
body: 'File ' + fileName + ' already exists in your Dropbox.',
icon: 'question',
buttons: [{result: 'yes', title: 'Overwrite it'}, {result: '', title: 'I\'ll choose another name'}],
esc: '',
click: '',
enter: 'yes',
success: this.saveToDropbox.bind(this, true),
cancel: (function() { this.$el.find('#settings__file-name').focus(); }).bind(this)
});
var that = this;
this.model.getData(function(data) {
var fileName = that.model.get('name') + '.kdbx';
that.model.set('syncing', true);
that.render();
DropboxLink.saveFile(fileName, data, overwrite, function (err) {
if (err) {
that.model.set('syncing', false);
if (err.exists) {
Alerts.alert({
header: 'Already exists',
body: 'File ' + fileName + ' already exists in your Dropbox.',
icon: 'question',
buttons: [{result: 'yes', title: 'Overwrite it'}, {result: '', title: 'I\'ll choose another name'}],
esc: '',
click: '',
enter: 'yes',
success: that.saveToDropbox.bind(that, true),
cancel: function () {
that.$el.find('#settings__file-name').focus();
}
});
} else {
Alerts.error({
header: 'Save error',
body: 'Error saving to Dropbox: \n' + err
});
}
} else {
Alerts.error({
header: 'Save error',
body: 'Error saving to Dropbox: \n' + err
});
that.passwordChanged = false;
that.model.saved(fileName, 'dropbox');
that.render();
}
} else {
this.passwordChanged = false;
this.model.saved(fileName, 'dropbox');
this.render();
}
}).bind(this));
});
});
},
keyFileChange: function(e) {

View File

@ -29,7 +29,7 @@
"dropbox": "antelle/dropbox-js#0.10.4",
"font-awesome": "~4.4.0",
"install": "~1.0.4",
"kdbxweb": "~0.1.12",
"kdbxweb": "~0.2.0",
"normalize.css": "~3.0.3",
"pikaday": "~1.3.3",
"zepto": "~1.1.6",