keeweb/app/scripts/models/entry-model.js

272 lines
8.1 KiB
JavaScript
Raw Normal View History

2015-10-17 23:49:24 +02:00
'use strict';
var Backbone = require('backbone'),
AttachmentModel = require('./attachment-model'),
IconMap = require('../const/icon-map'),
Color = require('../util/color'),
2015-11-21 21:14:21 +01:00
IconUrl = require('../util/icon-url'),
2015-10-17 23:49:24 +02:00
kdbxweb = require('kdbxweb');
var EntryModel = Backbone.Model.extend({
defaults: {},
buildInFields: ['Title', 'Password', 'Notes', 'URL', 'UserName'],
initialize: function() {
},
setEntry: function(entry, group, file) {
this.set({ id: entry.uuid.id }, {silent: true});
this.entry = entry;
this.group = group;
this.file = file;
this._fillByEntry();
},
_fillByEntry: function() {
var entry = this.entry;
this.fileName = this.file.db.meta.name;
this.title = entry.fields.Title || '';
2015-10-31 20:27:31 +01:00
this.password = entry.fields.Password || kdbxweb.ProtectedValue.fromString('');
2015-10-17 23:49:24 +02:00
this.notes = entry.fields.Notes || '';
this.url = entry.fields.URL || '';
this.user = entry.fields.UserName || '';
this.iconId = entry.icon;
this.icon = this._iconFromId(entry.icon);
this.tags = entry.tags;
this.color = this._colorToModel(entry.bgColor) || this._colorToModel(entry.fgColor);
this.fields = this._fieldsToModel(entry.fields);
this.attachments = this._attachmentsToModel(entry.binaries);
this.created = entry.times.creationTime;
this.updated = entry.times.lastModTime;
this.expires = entry.times.expires ? entry.times.expiryTime : undefined;
this.expired = entry.times.expires && entry.times.expiryTime <= new Date();
this.historyLength = entry.history.length;
2015-11-12 22:52:28 +01:00
this._buildCustomIcon();
2015-10-17 23:49:24 +02:00
this._buildSearchText();
this._buildSearchTags();
this._buildSearchColor();
},
_buildSearchText: function() {
var text = '';
_.forEach(this.entry.fields, function(value) {
if (typeof value === 'string') {
text += value.toLowerCase() + '\n';
}
});
this.entry.tags.forEach(function(tag) {
text += tag.toLowerCase() + '\n';
});
this.attachments.forEach(function(att) {
text += att.title.toLowerCase() + '\n';
});
this.searchText = text;
},
2015-11-12 22:52:28 +01:00
_buildCustomIcon: function() {
this.customIcon = null;
2015-11-21 23:15:51 +01:00
this.customIconId = null;
2015-11-12 22:52:28 +01:00
if (this.entry.customIcon) {
2015-11-21 21:14:21 +01:00
this.customIcon = IconUrl.toDataUrl(this.file.db.meta.customIcons[this.entry.customIcon]);
2015-11-21 23:15:51 +01:00
this.customIconId = this.entry.customIcon.toString();
2015-11-12 22:52:28 +01:00
}
},
2015-10-17 23:49:24 +02:00
_buildSearchTags: function() {
this.searchTags = this.entry.tags.map(function(tag) { return tag.toLowerCase(); });
},
_buildSearchColor: function() {
this.searchColor = this.color;
},
_iconFromId: function(id) {
return IconMap[id];
},
_colorToModel: function(color) {
return color ? Color.getNearest(color) : null;
},
_fieldsToModel: function(fields) {
return _.omit(fields, this.buildInFields);
},
_attachmentsToModel: function(binaries) {
var att = [];
_.forEach(binaries, function(data, title) {
att.push(AttachmentModel.fromAttachment({ data: data, title: title }));
}, this);
return att;
},
_entryModified: function() {
if (!this.unsaved) {
this.unsaved = true;
this.entry.pushHistory();
this.file.setModified();
}
2015-10-27 22:07:48 +01:00
if (this.isJustCreated) {
this.isJustCreated = false;
2015-10-27 20:40:34 +01:00
}
2015-10-17 23:49:24 +02:00
this.entry.times.update();
},
matches: function(filter) {
return (!filter.tagLower || this.searchTags.indexOf(filter.tagLower) >= 0) &&
(!filter.textLower || this.searchText.indexOf(filter.textLower) >= 0) &&
(!filter.color || filter.color === true && this.searchColor || this.searchColor === filter.color);
},
setColor: function(color) {
this._entryModified();
this.entry.bgColor = Color.getKnownBgColor(color);
this._fillByEntry();
},
setIcon: function(iconId) {
this._entryModified();
this.entry.icon = iconId;
2015-11-21 23:15:51 +01:00
this.entry.customIcon = undefined;
this._fillByEntry();
},
setCustomIcon: function(customIconId) {
this._entryModified();
this.entry.customIcon = new kdbxweb.KdbxUuid(customIconId);
2015-10-17 23:49:24 +02:00
this._fillByEntry();
},
setExpires: function(dt) {
this._entryModified();
this.entry.times.expiryTime = dt instanceof Date ? dt : undefined;
this.entry.times.expires = !!dt;
this._fillByEntry();
},
setTags: function(tags) {
this._entryModified();
this.entry.tags = tags;
this._fillByEntry();
},
setField: function(field, val) {
this._entryModified();
2015-11-10 18:23:50 +01:00
var hasValue = val && (typeof val === 'string' || val instanceof kdbxweb.ProtectedValue && val.byteLength);
if (hasValue || this.buildInFields.indexOf(field) >= 0) {
2015-10-17 23:49:24 +02:00
this.entry.fields[field] = val;
} else {
delete this.entry.fields[field];
}
this._fillByEntry();
},
hasField: function(field) {
return this.entry.fields.hasOwnProperty(field);
},
addAttachment: function(name, data) {
this._entryModified();
this.entry.binaries[name] = kdbxweb.ProtectedValue.fromBinary(data);
this._fillByEntry();
},
removeAttachment: function(name) {
this._entryModified();
delete this.entry.binaries[name];
this._fillByEntry();
},
getHistory: function() {
var history = this.entry.history.map(function(rec) {
return EntryModel.fromEntry(rec, this.group, this.file);
}, this);
history.push(this);
history.sort(function(x, y) { return x.updated - y.updated; });
return history;
},
deleteHistory: function(historyEntry) {
var ix = this.entry.history.indexOf(historyEntry);
if (ix >= 0) {
this.entry.history.splice(ix, 1);
}
this._fillByEntry();
},
revertToHistoryState: function(historyEntry) {
var ix = this.entry.history.indexOf(historyEntry);
if (ix < 0) {
return;
}
this.entry.pushHistory();
this.unsaved = true;
this.file.setModified();
this.entry.fields = {};
this.entry.binaries = {};
this.entry.copyFrom(historyEntry);
this._entryModified();
this._fillByEntry();
},
discardUnsaved: function() {
if (this.unsaved) {
this.unsaved = false;
var historyEntry = this.entry.history.pop();
this.entry.fields = {};
this.entry.binaries = {};
this.entry.copyFrom(historyEntry);
this._fillByEntry();
}
},
moveToTrash: function() {
2015-11-19 06:55:45 +01:00
this.file.setModified();
if (this.isJustCreated) {
this.isJustCreated = false;
}
2015-11-04 09:06:49 +01:00
this.file.db.remove(this.entry);
2015-10-17 23:49:24 +02:00
this.group.removeEntry(this);
var trashGroup = this.file.getTrashGroup();
if (trashGroup) {
trashGroup.addEntry(this);
this.group = trashGroup;
}
2015-10-27 20:40:34 +01:00
},
2015-11-09 19:15:39 +01:00
deleteFromTrash: function() {
2015-11-19 06:55:45 +01:00
this.file.setModified();
2015-11-09 19:15:39 +01:00
this.file.db.move(this.entry, null);
this.group.removeEntry(this);
},
2015-10-27 20:40:34 +01:00
removeWithoutHistory: function() {
var ix = this.group.group.entries.indexOf(this.entry);
if (ix >= 0) {
this.group.group.entries.splice(ix, 1);
}
this.group.removeEntry(this);
2015-10-17 23:49:24 +02:00
}
});
EntryModel.fromEntry = function(entry, group, file) {
var model = new EntryModel();
model.setEntry(entry, group, file);
return model;
};
EntryModel.newEntry = function(group, file) {
var model = new EntryModel();
var entry = file.db.createEntry(group.group);
model.setEntry(entry, group, file);
model.entry.times.update();
model.unsaved = true;
2015-10-27 22:07:48 +01:00
model.isJustCreated = true;
2015-10-27 20:40:34 +01:00
group.addEntry(model);
2015-10-17 23:49:24 +02:00
file.setModified();
return model;
};
module.exports = EntryModel;