Change master password if it's expired

This commit is contained in:
antelle 2016-07-03 19:46:43 +03:00
parent f7da41db3e
commit f0139c93e2
No known key found for this signature in database
GPG Key ID: 26C38FADD3BDF3CA
9 changed files with 86 additions and 22 deletions

View File

@ -438,8 +438,8 @@ var AppModel = Backbone.Model.extend({
that.setFileOpts(file, params.opts);
that.addToLastOpenFiles(file, rev);
that.addFile(file);
that.fileOpened(file);
callback(null, file);
that.fileOpened(file);
});
},
@ -511,6 +511,9 @@ var AppModel = Backbone.Model.extend({
that.syncFile(file);
}, Timeouts.FileChangeSync));
}
if (file.isKeyChangePending(true)) {
Backbone.trigger('key-change-pending', { file: file });
}
},
fileClosed: function(file) {

View File

@ -30,6 +30,7 @@ var FileModel = Backbone.Model.extend({
oldKeyFileName: '',
passwordChanged: false,
keyFileChanged: false,
keyChangeForce: -1,
syncing: false,
syncError: null,
syncDate: null
@ -142,7 +143,8 @@ var FileModel = Backbone.Model.extend({
recycleBinEnabled: this.db.meta.recycleBinEnabled,
historyMaxItems: this.db.meta.historyMaxItems,
historyMaxSize: this.db.meta.historyMaxSize,
keyEncryptionRounds: this.db.header.keyEncryptionRounds
keyEncryptionRounds: this.db.header.keyEncryptionRounds,
keyChangeForce: this.db.meta.keyChangeForce
}, { silent: true });
this.db.groups.forEach(function(group) {
var groupModel = this.getGroup(this.subId(group.uuid.id));
@ -394,6 +396,28 @@ var FileModel = Backbone.Model.extend({
this.setModified();
},
isKeyChangePending: function(force) {
if (!this.db.meta.keyChanged) {
return false;
}
var expiryDays = force ? this.db.meta.keyChangeForce : this.db.meta.keyChangeRec;
if (!expiryDays || expiryDays < 0 || isNaN(expiryDays)) {
return false;
}
var daysDiff = (Date.now() - this.db.meta.keyChanged) / 1000 / 3600 / 24;
return daysDiff > expiryDays;
},
setKeyChange: function(force, days) {
if (isNaN(days) || !days || days < 0) {
days = -1;
}
var prop = force ? 'keyChangeForce' : 'keyChangeRec';
this.db.meta[prop] = days;
this.set(prop, days);
this.setModified();
},
setName: function(name) {
this.db.meta.name = name;
this.db.meta.nameChanged = new Date();

View File

@ -88,8 +88,10 @@ var Locale = {
tagBadName: 'Bad name',
tagBadNameBody: 'Tag name can not contain characters `,`, `;`, `:`. Please remove them.',
keyChangeTitle: 'Master Key Changed',
keyChangeMessage: 'Master key was changed for this database. Please enter a new key',
keyChangeTitleRemote: 'Master Key Changed',
keyChangeMessageRemote: 'Master key was changed for this database. Please enter a new key',
keyChangeTitleExpired: 'Master Key Expired',
keyChangeMessageExpired: 'Master key for this database is expired. Please enter a new key',
iconFavTitle: 'Download and use website favicon',
iconSelCustom: 'Select custom icon',
@ -364,6 +366,7 @@ var Locale = {
setFileHistSize: 'History size, total MB per file',
setFileAdvanced: 'Advanced',
setFileRounds: 'Key encryption rounds',
setFileKeyChangeForce: 'Ask to change key after (days)',
setFileUseKeyFile: 'Use key file',
setFileUseGenKeyFile: 'Use generated key file',
setFileUseOldKeyFile: 'Use old key file',

View File

@ -65,6 +65,7 @@ var AppView = Backbone.View.extend({
this.listenTo(Backbone, 'open-file', this.toggleOpenFile);
this.listenTo(Backbone, 'save-all', this.saveAll);
this.listenTo(Backbone, 'remote-key-changed', this.remoteKeyChanged);
this.listenTo(Backbone, 'key-change-pending', this.keyChangePending);
this.listenTo(Backbone, 'toggle-settings', this.toggleSettings);
this.listenTo(Backbone, 'toggle-menu', this.toggleMenu);
this.listenTo(Backbone, 'toggle-details', this.toggleDetails);
@ -219,8 +220,11 @@ var AppView = Backbone.View.extend({
this.views.tag.show();
},
showKeyChange: function(file) {
if (this.views.keyChange || Alerts.alertDisplayed) {
showKeyChange: function(file, viewConfig) {
if (Alerts.alertDisplayed) {
return;
}
if (this.views.keyChange && this.views.keyChange.model.remote) {
return;
}
this.hideSettings();
@ -231,7 +235,9 @@ var AppView = Backbone.View.extend({
this.views.details.hide();
this.views.grp.hide();
this.views.tag.hide();
this.views.keyChange = new KeyChangeView({ model: file });
this.views.keyChange = new KeyChangeView({
model: { file: file, expired: viewConfig.expired, remote: viewConfig.remote }
});
this.views.keyChange.setElement(this.$el.find('.app__body')).render();
this.views.keyChange.on('accept', this.keyChangeAccept.bind(this));
this.views.keyChange.on('cancel', this.showEntries.bind(this));
@ -464,18 +470,31 @@ var AppView = Backbone.View.extend({
},
remoteKeyChanged: function(e) {
this.showKeyChange(e.file);
this.showKeyChange(e.file, { remote: true });
},
keyChangePending: function(e) {
this.showKeyChange(e.file, { expired: true });
},
keyChangeAccept: function(e) {
this.showEntries();
this.model.syncFile(e.file, {
remoteKey: {
password: e.password,
keyFileName: e.keyFileName,
keyFileData: e.keyFileData
if (e.expired) {
e.file.setPassword(e.password);
if (e.keyFileData && e.keyFileName) {
e.file.setKeyFile(e.keyFileData, e.keyFileName);
} else {
e.file.removeKeyFile();
}
});
} else {
this.model.syncFile(e.file, {
remoteKey: {
password: e.password,
keyFileName: e.keyFileName,
keyFileData: e.keyFileData
}
});
}
},
toggleSettings: function(page) {

View File

@ -25,11 +25,13 @@ var KeyChangeView = Backbone.View.extend({
},
render: function() {
this.keyFileName = this.model.get('keyFileName') || null;
this.keyFileName = this.model.file.get('keyFileName') || null;
this.keyFileData = null;
this.renderTemplate({
fileName: this.model.get('name'),
keyFileName: this.model.get('keyFileName')
fileName: this.model.file.get('name'),
keyFileName: this.model.file.get('keyFileName'),
title: this.model.expired ? Locale.keyChangeTitleExpired : Locale.keyChangeTitleRemote,
message: this.model.expired ? Locale.keyChangeMessageExpired : Locale.keyChangeMessageRemote
});
this.$el.find('.key-change__keyfile-name').text(this.keyFileName ? ': ' + this.keyFileName : '');
this.inputEl = this.$el.find('.key-change__pass');
@ -81,7 +83,8 @@ var KeyChangeView = Backbone.View.extend({
accept: function() {
this.trigger('accept', {
file: this.model,
file: this.model.file,
expired: this.model.expired,
password: this.passwordInput.value,
keyFileName: this.keyFileName,
keyFileData: this.keyFileData

View File

@ -34,7 +34,8 @@ var SettingsFileView = Backbone.View.extend({
'change #settings__file-trash': 'changeTrash',
'input #settings__file-hist-len': 'changeHistoryLength',
'input #settings__file-hist-size': 'changeHistorySize',
'input #settings__file-key-rounds': 'changeKeyRounds'
'input #settings__file-key-rounds': 'changeKeyRounds',
'input #settings__file-key-change-force': 'changeKeyChangeForce'
},
appModel: null,
@ -69,6 +70,7 @@ var SettingsFileView = Backbone.View.extend({
historyMaxItems: this.model.get('historyMaxItems'),
historyMaxSize: Math.round(this.model.get('historyMaxSize') / 1024 / 1024),
keyEncryptionRounds: this.model.get('keyEncryptionRounds'),
keyChangeForce: this.model.get('keyChangeForce') > 0 ? this.model.get('keyChangeForce') : null,
storageProviders: storageProviders
});
if (!this.model.get('created')) {
@ -383,6 +385,14 @@ var SettingsFileView = Backbone.View.extend({
return;
}
this.model.setKeyEncryptionRounds(value);
},
changeKeyChangeForce: function(e) {
var value = Math.round(e.target.value);
if (isNaN(value) || value <= 0) {
value = -1;
}
this.model.setKeyChange(true, value);
}
});

View File

@ -20,7 +20,6 @@
text-align: center;
}
&__body {
@include flex(0);
@include display(flex);
@include align-items(flex-start);
@include flex-direction(column);

View File

@ -1,8 +1,8 @@
<div class="key-change">
<i class="key-change__icon fa fa-lock"></i>
<div class="key-change__header">{{fileName}}: {{res 'keyChangeTitle'}}</div>
<div class="key-change__header">{{fileName}}: {{title}}</div>
<div class="key-change__body">
<div class="key-change__message">{{res 'keyChangeMessage'}}:</div>
<div class="key-change__message">{{message}}:</div>
<div class="key-change__input">
<input class="key-change__file hide-by-pos" type="file" />
<input class="key-change__pass" type="password" size="30" autocomplete="off" maxlength="1024" autofocus />

View File

@ -73,4 +73,7 @@
<h2>{{res 'setFileAdvanced'}}</h2>
<label for="settings__file-key-rounds">{{res 'setFileRounds'}}:</label>
<input type="text" pattern="\d+" required class="settings__input input-base" id="settings__file-key-rounds" value="{{keyEncryptionRounds}}" />
<label for="settings__file-key-rounds">{{res 'setFileKeyChangeForce'}}:</label>
<input type="text" pattern="\d*" class="settings__input input-base" id="settings__file-key-change-force" value="{{keyChangeForce}}" />
</div>