keeweb/app/scripts/comp/kdbx-to-html.js

112 lines
3.3 KiB
JavaScript
Raw Normal View History

2019-09-08 20:28:02 +02:00
const Format = require('../util/format');
const Locale = require('../util/locale');
const Links = require('../const/links');
const RuntimeInfo = require('./runtime-info');
const kdbxweb = require('kdbxweb');
const Templates = {
db: require('templates/export/db.hbs'),
entry: require('templates/export/entry.hbs')
};
const FieldMapping = [
{ name: 'UserName', locStr: 'user' },
2019-09-08 20:29:07 +02:00
{ name: 'Password', locStr: 'password', protect: true },
2019-09-08 20:28:02 +02:00
{ name: 'URL', locStr: 'website' },
{ name: 'Notes', locStr: 'notes' }
];
const KnownFields = { 'Title': true };
for (const { name } of FieldMapping) {
KnownFields[name] = true;
}
function walkGroup(db, group, parents) {
parents = [...parents, group];
if (
group.uuid.equals(db.meta.recycleBinUuid) ||
group.uuid.equals(db.meta.entryTemplatesGroup)
) {
return '';
}
const self = group.entries.map(entry => walkEntry(db, entry, parents)).join('\n');
const children = group.groups.map(childGroup => walkGroup(db, childGroup, parents)).join('\n');
return self + children;
}
function walkEntry(db, entry, parents) {
const path = parents.map(group => group.name).join(' / ');
const fields = [];
for (const field of FieldMapping) {
const value = entryField(entry, field.name);
if (value) {
fields.push({
title: Format.capFirst(Locale[field.locStr]),
value,
protect: field.protect
});
}
}
for (const fieldName of Object.keys(entry.fields)) {
if (!KnownFields[fieldName]) {
const value = entryField(entry, fieldName);
if (value) {
fields.push({
title: fieldName,
value,
protect: entry.fields[fieldName].isProtected
});
}
}
}
const title = entryField(entry, 'Title');
let expires;
if (entry.times.expires && entry.times.expiryTime) {
expires = Format.dtStr(entry.times.expiryTime);
}
const attachments = Object.entries(entry.binaries)
.map(([name, data]) => {
if (data && data.ref) {
data = data.value;
}
if (data) {
const base64 = kdbxweb.ByteUtils.bytesToBase64(data);
data = 'data:application/octet-stream;base64,' + base64;
}
return { name, data };
})
.filter(att => att.name && att.data);
return Templates.entry({
path,
title,
fields,
tags: entry.tags.join(', '),
created: Format.dtStr(entry.times.creationTime),
modified: Format.dtStr(entry.times.lastModTime),
expires,
attachments
});
}
function entryField(entry, fieldName) {
const value = entry.fields[fieldName];
return (value && value.isProtected && value.getText()) || value || '';
}
const KdbxToHtml = {
convert(db, options) {
const content = db.groups.map(group => walkGroup(db, group, [])).join('\n');
return Templates.db({
name: options.name,
date: Format.dtStr(Date.now()),
appLink: Links.Homepage,
appVersion: RuntimeInfo.version,
content
});
}
};
module.exports = KdbxToHtml;