KdbxWeb is a high-performance javascript library for reading/writing KeePass v2 databases (kdbx) in node.js or browser.
- runs in browser or node.js
- no native addons
- fast encryption with WebCrypto, open time is comparable to native app
- total ≈150kB with dependencies
- full support of Kdbx features
- protected values are stored in memory XOR'ed
- conflict-free merge support
- modern browsers: IE10+, Firefox, Chrome, Safari 7+, Opera
- node.js
var credentials = new kdbxweb.Credentials(kdbxweb.ProtectedValue.fromString('demo'), keyFileArrayBuffer);
kdbxweb.Kdbx.load(dataAsArrayBuffer, credentials, function(db) { });
kdbxweb.Kdbx.loadXml(dataAsString, credentials, function(db) { });
db.save(function(dataAsArrayBuffer) { });
db.saveXml(function(xmlAsString) { });
Header object fields
Meta object fields
db.header
db.meta
var db = kdbxweb.Kdbx.load(data, credentials);
db.credentials.setPassword(kdbxweb.ProtectedValue.fromString('newPass'));
var randomKeyFile = kdbxweb.Credentials.createRandomKeyFile();
db.credentials.setKeyFile(randomKeyFile);
db.save();
var newDb = kdbxweb.Kdbx.create(credentials, 'My new db');
var group = newDb.createGroup(newDb.getDefaultGroup(), 'subgroup');
var entry = newDb.createEntry(group);
db.cleanup({
historyRules: true,
customIcons: true,
binaries: true
});
Entries, groups and meta are consistent against merging in any direction with any state.
Due to format limitations, p2p entry history merging and some non-critical fields in meta can produce phantom records or deletions,
so correct entry history merging is supported only with one central replica. Items order is not guaranteed but the algorithm tries to preserve it.
var db = kdbxweb.Kdbx.load(data, credentials); // load local db
// work with db
db.save(); // save local db
var editStateBeforeSave = db.getLocalEditState(); // save local editing state (serializable to JSON)
db.close(); // close local db
db = kdbxweb.Kdbx.load(data, credentials); // reopen it again
db.setLocalEditState(editStateBeforeSave); // assign edit state obtained before save
// work with db
var remoteDb = kdbxweb.Kdbx.load(remoteData, credentials); // load remote db
db.merge(remoteDb); // merge remote into local
delete remoteDb; // don't use remoteDb anymore
var saved = db.save(); // save local db
editStateBeforeSave = db.getLocalEditState(); // save local editing state again
var pushedOk = pushToUpstream(saved); { // push db to upstream
if (pushedOk) {
db.removeLocalEditState(); // clear local editing state
editStateBeforeSave = null; // and discard it
}
var defaultGroup = db.getDefaultGroup();
var anotherGroup = db.getGroup(uuid);
var deepGroup = defaultGroup.groups[1].groups[2];
var group = db.createGroup(db.getDefaultGroup(), 'New group');
var anotherGroup = db.createGroup(group, 'Subgroup');
db.remove(group);
db.move(group, toGroup);
var recycleBin = db.getGroup(db.meta.recycleBinUuid);
if (!recycleBin) {
db.createRecycleBin();
}
group.forEach(function(entry, group) { /* will be called for each entry or group */ });
Entry object fields
Entry.times fields
var entry = db.getDefaultGroup().entries[0];
entry.fields.AccountNumber = '1234 5678';
entry.fields.Pin = kdbxweb.ProtectedValue.fromString('4321');
var entry = db.createEntry(group);
// push current state to history stack
entry.pushHistory();
// change something
entry.fgColor = '#ff0000';
// update entry modification and access time
entry.times.update();
// remove states from entry history
entry.removeHistory(index, count);
Important: don't modify history states directly, this will break merge.
db.remove(entry);
db.move(entry, toGroup);
Used for passwords and custom fields, stored the value in memory XOR'ed
var value = new kdbxweb.ProtectedValue(xoredByted, saltBytes);
var valueFromString = kdbxweb.ProtectedValue.fromString('str');
var valueFromBinary = kdbxweb.ProtectedValue.fromBinary(data);
var textString = value.getText();
var binaryData = value.getBinary();
var includesSubString = value.includes('foo');
try {
kdbxweb.Kdbx.load(data, credentials);
} catch (e) {
if (e.code === kdbxweb.Consts.ErrorCodes.BadSignature) { /* ... */ }
}
kdbxweb.Consts.ErrorCodes // all thrown errors have code property
kdbxweb.Consts.Defaults // default db settings
kdbxweb.Consts.Icons // icons map
var randomArray = kdbxweb.Random.getBytes(/* desired length */ 100);
kdbxweb.ByteUtils.bytesToString(bytes);
kdbxweb.ByteUtils.stringToBytes(str);
kdbxweb.ByteUtils.bytesToBase64(bytes)
kdbxweb.ByteUtils.base64ToBytes(str);;
Use npm to build this project:
> npm run build
> npm run build:debug
To run tests:
> npm test
Areas which need more attention for now:
- unit tests, especially for complex functions (like moving entry with binaries)
- testing in general
MIT