npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

passbolt-kdbxweb

v2.1.1

Published

Kdbx KeePass database reader for web (temporary passbolt fork)

Downloads

385

Readme

KdbxWeb CI Checks Coverage Status

KdbxWeb is a high-performance javascript library for reading/writing KeePass v2 databases (kdbx) in node.js or browser.

Features

  • runs in browser or node.js
  • no native addons
  • fast encryption with WebCrypto
  • total ≈130kB with dependencies
  • full support of Kdbx features
  • protected values are stored in memory XOR'ed
  • conflict-free merge support
  • high code coverage
  • strict TypeScript

Browser support

  • modern browsers: Chrome, Firefox, Safari, Opera, Edge
  • node.js

Compatibility

Supported formats are Kdbx3 and Kdbx4, current KeePass file format. Old kdb files (for KeePass v1) are out of scope of this library.

Kdbx4

Kdbx4 has introduced Argon2, a new hashing function. Due to complex calculations, you have to implement it manually and export to kdbxweb, if you want to support such files. Here's how:

kdbxweb.CryptoEngine.setArgon2Impl((password, salt,
    memory, iterations, length, parallelism, type, version
) => {
    // your implementation makes hash (Uint8Array, 'length' bytes)
    return Promise.resolve(hash);
});

You can find an implementation example in tests.

It's not compiled into the library because there's no universal way to provide a fast implementation, so it's up to you, to choose the best one.

Usage

Loading
let credentials = new kdbxweb.Credentials(kdbxweb.ProtectedValue.fromString('demo'),
    keyFileArrayBuffer, challengeResponseFunction);
const db1 = await kdbxweb.Kdbx.load(dataAsArrayBuffer, credentials);
const db2 = await kdbxweb.Kdbx.loadXml(dataAsString, credentials);
Saving
const dataAsArrayBuffer = await db.save();
const xmlAsString = await db.saveXml();

You can also pretty-print XML:

const prettyPrintedXml = await db.saveXml(true);
File info
db.header
db.meta

See the corresponding type fields inside, they should be obvious.

Changing credentials
const db = await kdbxweb.Kdbx.load(data, credentials);
db.credentials.setPassword(kdbxweb.ProtectedValue.fromString('newPass'));
const randomKeyFile = await kdbxweb.Credentials.createRandomKeyFile();
db.credentials.setKeyFile(randomKeyFile);
await db.save();
Creation
let newDb = kdbxweb.Kdbx.create(credentials, 'My new db');
let group = newDb.createGroup(newDb.getDefaultGroup(), 'subgroup');
let entry = newDb.createEntry(group);
Maintenance
db.cleanup({
    historyRules: true,
    customIcons: true,
    binaries: true
});

// upgrade the db to latest version (currently KDBX4)
db.upgrade();

// downgrade to KDBX3
db.setVersion(3);

// set KDF to AES
db.setKdf(kdbxweb.Consts.KdfId.Aes);
Merge

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.

let db = await kdbxweb.Kdbx.load(data, credentials); // load local db
// work with db
db.save(); // save local db
let 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
let remoteDb = await kdbxweb.Kdbx.load(remoteData, credentials); // load remote db
db.merge(remoteDb); // merge remote into local
delete remoteDb; // don't use remoteDb anymore
let saved = await db.save(); // save local db
editStateBeforeSave = db.getLocalEditState(); // save local editing state again
let pushedOk = pushToUpstream(saved); // push db to upstream
if (pushedOk) {
    db.removeLocalEditState(); // clear local editing state
    editStateBeforeSave = null; // and discard it
}
Groups
let defaultGroup = db.getDefaultGroup();
let anotherGroup = db.getGroup(uuid);
let deepGroup = defaultGroup.groups[1].groups[2];
Group creation
let group = db.createGroup(db.getDefaultGroup(), 'New group');
let anotherGroup = db.createGroup(group, 'Subgroup');
Group deletion
db.remove(group);
Group move
db.move(group, toGroup);
db.move(group, toGroup, atIndex);
Recycle Bin
let recycleBin = db.getGroup(db.meta.recycleBinUuid);
if (!recycleBin) {
    db.createRecycleBin();
}
Recursive traverse
for (const entry of group.allEntries()) { /* ... */ }
for (const group of group.allGroups()) { /* ... */ }
for (const entryOrGroup of group.allGroupsAndEntries()) { /* ... */ }
Entries
let entry = db.getDefaultGroup().entries[0];
entry.fields.AccountNumber = '1234 5678';
entry.fields.Pin = kdbxweb.ProtectedValue.fromString('4321');
Entry creation
let entry = db.createEntry(group);
Entry modification
// 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.

Entry deletion
db.remove(entry);
Entry move
db.move(entry, toGroup);

If you're moving an entry from another file, this is called import:

db.importEntry(entry, toGroup, sourceFile);
ProtectedValue

Used for passwords and custom fields, stored the value in memory XOR'ed

let value = new kdbxweb.ProtectedValue(xoredByted, saltBytes);
let valueFromString = kdbxweb.ProtectedValue.fromString('str');
let valueFromBinary = kdbxweb.ProtectedValue.fromBinary(data);
let textString = value.getText();
let binaryData = value.getBinary();
let includesSubString = value.includes('foo');
Errors
try {
    await kdbxweb.Kdbx.load(data, credentials);
} catch (e) {
    if (e instanceof kdbxweb.KdbxError && e.code === kdbxweb.Consts.ErrorCodes.BadSignature) {
        /* ... */
    }
}
Consts

Consts definition

kdbxweb.Consts.ErrorCodes // all thrown errors have code property
kdbxweb.Consts.Defaults // default db settings
kdbxweb.Consts.Icons // icons map
Random
let randomArray = kdbxweb.Crypto.random(/* desired length */ 100);
ByteUtils
kdbxweb.ByteUtils.bytesToString(bytes);
kdbxweb.ByteUtils.stringToBytes(str);
kdbxweb.ByteUtils.bytesToBase64(bytes);
kdbxweb.ByteUtils.base64ToBytes(str);
kdbxweb.ByteUtils.bytesToHex(bytes);
kdbxweb.ByteUtils.hexToBytes(str);

Building

Use npm to build this project:

npm run build

To run tests:

npm test

3rd party libs

kdbxweb includes these 3rd party libraries:

Tools

The library provides a number of scripts to work with KDBX files:

Dump the binary header:

npm run script:dump-header my-db.kdbx

Print detailed size information about internal objects:

npm run script:kdbx-size-profiler my-db.kdbx password

Dump the internal XML:

npm run script:kdbx-to-xml my-db.kdbx password

Generate big files for load testing:

npm run script:make-big-files

See it in action

This library is used in KeeWeb

Extras

We also provide a template for HexFiend to explore the contents of KDBX files, you can find it here.

License

MIT