@hazae41/kdbx
Version:
Rust-like KeePass (KDBX 4) file format for TypeScript
137 lines (133 loc) • 4.53 kB
JavaScript
;
var binary = require('@hazae41/binary');
var index$1 = require('../../vector/index.cjs');
var index$2 = require('./cipher/index.cjs');
var index = require('./markup/index.cjs');
class HeadersAndContentWithBytes {
headers;
content;
constructor(headers, content) {
this.headers = headers;
this.content = content;
}
static computeOrThrow(headers, content) {
const contentWithBytes = ContentWithBytes.computeOrThrow(content);
return new HeadersAndContentWithBytes(headers, contentWithBytes);
}
async rotateOrThrow() {
return new HeadersAndContentWithBytes(await this.headers.rotateOrThrow(), this.content);
}
sizeOrThrow() {
return this.headers.sizeOrThrow() + this.content.sizeOrThrow();
}
writeOrThrow(cursor) {
this.headers.writeOrThrow(cursor);
this.content.writeOrThrow(cursor);
}
recomputeOrThrow() {
return HeadersAndContentWithBytes.computeOrThrow(this.headers, this.content.value);
}
}
class ContentWithBytes {
bytes;
value;
constructor(bytes, value) {
this.bytes = bytes;
this.value = value;
}
static computeOrThrow(content) {
const string = new XMLSerializer().serializeToString(content.document);
const opaque = new binary.Opaque(new TextEncoder().encode(string));
return new ContentWithBytes(opaque, content);
}
sizeOrThrow() {
return this.bytes.sizeOrThrow();
}
writeOrThrow(cursor) {
this.bytes.writeOrThrow(cursor);
}
recomputeOrThrow() {
return ContentWithBytes.computeOrThrow(this.value);
}
}
(function (ContentWithBytes) {
function readOrThrow(cursor) {
const bytes = new binary.Opaque(cursor.readOrThrow(cursor.remaining));
const raw = new TextDecoder().decode(bytes.bytes);
const xml = new DOMParser().parseFromString(raw, "text/xml");
return new ContentWithBytes(bytes, new index.KeePassFile(xml));
}
ContentWithBytes.readOrThrow = readOrThrow;
})(ContentWithBytes || (ContentWithBytes = {}));
(function (HeadersAndContentWithBytes) {
function readOrThrow(cursor) {
const headers = Headers.readOrThrow(cursor);
const content = ContentWithBytes.readOrThrow(cursor);
return new HeadersAndContentWithBytes(headers, content);
}
HeadersAndContentWithBytes.readOrThrow = readOrThrow;
})(HeadersAndContentWithBytes || (HeadersAndContentWithBytes = {}));
class Headers {
value;
constructor(value) {
this.value = value;
}
get cipher() {
return this.value.value[1][0];
}
get key() {
return this.value.value[2][0];
}
get binary() {
return this.value.value[3];
}
sizeOrThrow() {
return this.value.sizeOrThrow();
}
writeOrThrow(cursor) {
this.value.writeOrThrow(cursor);
}
cloneOrThrow() {
return binary.Readable.readFromBytesOrThrow(Headers, binary.Writable.writeToBytesOrThrow(this));
}
async rotateOrThrow() {
const { cipher, binary: binary$1 } = this;
const key = new binary.Opaque(new Uint8Array(crypto.getRandomValues(new Uint8Array(32))));
return Headers.initOrThrow({ cipher, key, binary: binary$1 });
}
async getCipherOrThrow() {
return await this.cipher.initOrThrow(this.key.bytes);
}
}
(function (Headers) {
function initOrThrow(init) {
const { cipher, key, binary } = init;
const indexed = {
1: [cipher],
2: [key],
3: binary
};
return new Headers(index$1.Vector.initOrThrow(indexed));
}
Headers.initOrThrow = initOrThrow;
function readOrThrow(cursor) {
const vector = index$1.Vector.readOrThrow(cursor);
if (vector.value[1].length !== 1)
throw new Error();
if (vector.value[2].length !== 1)
throw new Error();
if (vector.value[3].length === 0)
throw new Error();
const indexed = {
1: [vector.value[1][0].readIntoOrThrow(index$2.Cipher)],
2: [vector.value[2][0]],
3: vector.value[3]
};
return new Headers(new index$1.Vector(vector.bytes, indexed));
}
Headers.readOrThrow = readOrThrow;
})(Headers || (Headers = {}));
exports.ContentWithBytes = ContentWithBytes;
exports.Headers = Headers;
exports.HeadersAndContentWithBytes = HeadersAndContentWithBytes;
//# sourceMappingURL=index.cjs.map