Skip to content

Stream to buffer #44

Open
Open
@mmajcica

Description

@mmajcica

Hi,

we are having some small issues with using the library, maybe it is not directly connected to the library itself but may be an improvement point.

Loading the library expects to receive an ArrayBuffer. However, we are dealing with streams because we are downloading our kbdx file.

Initially, we were doing the following, downloading the file to the disk, then reading it to the buffer. It works well. Following the code used:

    async getDatabase(url: string): Promise<string> {
        const sampleFilePath = Path.join(
            tmpdir(),
            `keepass.${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.kdbx`,
        );

        const file: NodeJS.WritableStream = fs.createWriteStream(sampleFilePath);
        const response = await this.httpClient.get(url);
        const stream = response.message.pipe(file);

        const promise = new Promise((resolve, reject) => {
            stream.on('finish', () => {
                resolve(true);
            });
            stream.on('error', reject);
        });

        await promise;

        return sampleFilePath;
    }

const dbPath = await this.getDatabase(argv.url);
const keepassDb = fs.readFileSync(dbPath).buffer;
const db = await kdbxweb.Kdbx.load(keepassDb, credentials);

Now we are not allowed anymore to persist things on a disk and we need to manage all of the things in memory. That is not a big issue as our DB file is only around 200kb and it will not grow.

We changed the code to the following:

    async getDatabase(url: string): Promise<Buffer> {
        const response: IHttpClientResponse = await this.httpClient.get(url);

        return new Promise<Buffer>(async (resolve, reject) => {
            const chunks = [];
            response.message
                .on('data', function (data: Buffer) {
                    chunks.push(data);
                })
                .on('end', async function () {
                    const buffer: Buffer = Buffer.concat(chunks);

                    resolve(buffer);
                })
                .on('error', function (err) {
                    reject(err);
                });
        });
    }

const dbBuffer = await this.getDatabase(argv.url);
const db = await kdbxweb.Kdbx.load(dbBuffer, credentials);

However, this does not work, we do get an exception saying KdbxError: Error InvalidArg: data.

Do you have any idea why this may not work? Is there an example of how to get a stream into the buffer that will be accepted by kdbxweb?

Would it be possible to have a possibility to load a DB direclty from a stream?

Thank you in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions