@hazae41/kdbx
Version:
Rust-like KeePass (KDBX 4) file format for TypeScript
581 lines (577 loc) • 22.6 kB
JavaScript
'use strict';
var index = require('../data/index.cjs');
class KeePassFile {
document;
constructor(document) {
this.document = document;
}
getMetaOrThrow() {
const element = this.document.querySelector(":scope > Meta");
if (element == null)
throw new Error();
return new KeePassFile.Meta(element);
}
getRootOrThrow() {
const element = this.document.querySelector(":scope > Root");
if (element == null)
throw new Error();
return new KeePassFile.Root(element);
}
}
(function (KeePassFile) {
class Meta {
element;
constructor(element) {
this.element = element;
}
getDatabaseNameOrThrow() {
const element = this.element.querySelector(":scope > DatabaseName");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getDatabaseNameChangedOrThrow() {
const element = this.element.querySelector(":scope > DatabaseNameChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getGeneratorOrThrow() {
const element = this.element.querySelector(":scope > Generator");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getHistoryMaxItemsOrThrow() {
const element = this.element.querySelector(":scope > HistoryMaxItems");
if (element == null)
throw new Error();
return new index.Data.AsInteger(element);
}
getHistoryMaxSizeOrThrow() {
const element = this.element.querySelector(":scope > HistoryMaxSize");
if (element == null)
throw new Error();
return new index.Data.AsInteger(element);
}
getRecycleBinEnabledOrThrow() {
const element = this.element.querySelector(":scope > RecycleBinEnabled");
if (element == null)
throw new Error();
return new index.Data.AsBoolean(element);
}
getRecycleBinUuidOrThrow() {
const element = this.element.querySelector(":scope > RecycleBinUUID");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getRecycleBinChangedOrThrow() {
const element = this.element.querySelector(":scope > RecycleBinChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getSettingsChangedOrThrow() {
const element = this.element.querySelector(":scope > SettingsChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getDatabaseDescriptionOrThrow() {
const element = this.element.querySelector(":scope > DatabaseDescription");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getDatabaseDescriptionChangedOrThrow() {
const element = this.element.querySelector(":scope > DatabaseDescriptionChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getDefaultUserNameOrThrow() {
const element = this.element.querySelector(":scope > DefaultUserName");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getDefaultUserNameChangedOrThrow() {
const element = this.element.querySelector(":scope > DefaultUserNameChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getColorOrThrow() {
const element = this.element.querySelector(":scope > Color");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getDirectEntryTemplatesGroupOrThrow() {
const element = this.element.querySelector(":scope > EntryTemplatesGroup");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getDirectEntryTemplatesGroupChangedOrThrow() {
const element = this.element.querySelector(":scope > EntryTemplatesGroupChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
}
KeePassFile.Meta = Meta;
class Root {
element;
constructor(element) {
this.element = element;
}
*getGroups() {
const elements = this.element.querySelectorAll(`Group`);
for (const element of elements)
yield new Group(element);
return;
}
getGroupByUuidOrThrow(uuid) {
const elements = this.element.querySelectorAll(`Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
throw new Error();
}
getGroupByUuidOrNull(uuid) {
const elements = this.element.querySelectorAll(`Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
return;
}
*getDirectGroups() {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements)
yield new Group(element);
return;
}
getDirectGroupByIndexOrThrow(index) {
const element = this.element.querySelector(`:scope > Group:nth-of-type(${index + 1})`);
if (element == null)
throw new Error();
return new Group(element);
}
getDirectGroupByIndexOrNull(index) {
const element = this.element.querySelector(`:scope > Group:nth-of-type(${index + 1})`);
if (element == null)
return;
return new Group(element);
}
getDirectGroupByUuidOrThrow(uuid) {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
throw new Error();
}
getDirectGroupByUuidOrNull(uuid) {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
return;
}
}
KeePassFile.Root = Root;
class Group {
element;
constructor(element) {
this.element = element;
}
moveOrThrow(group) {
if (this.element.parentNode === group.element)
return;
this.element.parentNode?.removeChild(this.element);
group.element.appendChild(this.element);
this.getTimesOrThrow().getLocationChangedOrThrow().setOrThrow(new Date());
group.getTimesOrThrow().getLastModificationTimeOrThrow().setOrThrow(new Date());
}
getNameOrThrow() {
const element = this.element.querySelector(":scope > Name");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getUuidOrThrow() {
const element = this.element.querySelector(":scope > UUID");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getTimesOrThrow() {
const element = this.element.querySelector(":scope > Times");
if (element == null)
throw new Error();
return new Times(element);
}
getIconIdOrThrow() {
const element = this.element.querySelector(":scope > IconID");
if (element == null)
throw new Error();
return new index.Data.AsInteger(element);
}
getEnableAutoTypeOrThrow() {
const element = this.element.querySelector(":scope > EnableAutoType");
if (element == null)
throw new Error();
return new index.Data.AsBoolean(element);
}
getEnableSearchingOrThrow() {
const element = this.element.querySelector(":scope > EnableSearching");
if (element == null)
throw new Error();
return new index.Data.AsBoolean(element);
}
*getDirectGroups() {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements)
yield new Group(element);
return;
}
getDirectGroupByIndexOrThrow(index) {
const element = this.element.querySelector(`:scope > Group:nth-of-type(${index + 1})`);
if (element == null)
throw new Error();
return new Group(element);
}
getDirectGroupByIndexOrNull(index) {
const element = this.element.querySelector(`:scope > Group:nth-of-type(${index + 1})`);
if (element == null)
return;
return new Group(element);
}
getDirectGroupByUuidOrThrow(uuid) {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
throw new Error();
}
getDirectGroupByUuidOrNull(uuid) {
const elements = this.element.querySelectorAll(`:scope > Group`);
for (const element of elements) {
const group = new Group(element);
if (group.getUuidOrThrow().get() === uuid)
return group;
continue;
}
return;
}
*getDirectEntries() {
const elements = this.element.querySelectorAll(`:scope > Entry`);
for (const element of elements)
yield new Entry(element);
return;
}
getDirectEntryByIndexOrThrow(index) {
const element = this.element.querySelector(`:scope > Entry:nth-of-type(${index + 1})`);
if (element == null)
throw new Error();
return new Entry(element);
}
getDirectEntryByIndexOrNull(index) {
const element = this.element.querySelector(`:scope > Entry:nth-of-type(${index + 1})`);
if (element == null)
return;
return new Entry(element);
}
getDirectEntryByUuidOrThrow(uuid) {
const elements = this.element.querySelectorAll(`:scope > Entry`);
for (const element of elements) {
const entry = new Entry(element);
if (entry.getUuidOrThrow().get() === uuid)
return entry;
continue;
}
throw new Error();
}
getDirectEntryByUuidOrNull(uuid) {
const elements = this.element.querySelectorAll(`:scope > Entry`);
for (const element of elements) {
const entry = new Entry(element);
if (entry.getUuidOrThrow().get() === uuid)
return entry;
continue;
}
return;
}
}
KeePassFile.Group = Group;
class Times {
element;
constructor(element) {
this.element = element;
}
getLastModificationTimeOrThrow() {
const element = this.element.querySelector(":scope > LastModificationTime");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getCreationTimeOrThrow() {
const element = this.element.querySelector(":scope > CreationTime");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getLastAccessTimeOrThrow() {
const element = this.element.querySelector(":scope > LastAccessTime");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
getExpiresOrThrow() {
const element = this.element.querySelector(":scope > Expires");
if (element == null)
throw new Error();
return new index.Data.AsBoolean(element);
}
getUsageCountOrThrow() {
const element = this.element.querySelector(":scope > UsageCount");
if (element == null)
throw new Error();
return new index.Data.AsInteger(element);
}
getLocationChangedOrThrow() {
const element = this.element.querySelector(":scope > LocationChanged");
if (element == null)
throw new Error();
return new index.Data.AsDate(element);
}
}
KeePassFile.Times = Times;
class Entry {
element;
constructor(element) {
this.element = element;
}
moveOrThrow(group) {
if (this.element.parentNode === group.element)
return;
this.element.parentNode?.removeChild(this.element);
group.element.appendChild(this.element);
this.getTimesOrThrow().getLocationChangedOrThrow().setOrThrow(new Date());
group.getTimesOrThrow().getLastModificationTimeOrThrow().setOrThrow(new Date());
}
moveToTrashOrThrow() {
const file = new KeePassFile(this.element.ownerDocument);
const meta = file.getMetaOrThrow();
const root = file.getRootOrThrow();
const recybleBinEnabled = meta.getRecycleBinEnabledOrThrow().get();
if (!recybleBinEnabled)
throw new Error("Recycle bin is not enabled");
const recycleBinUuid = meta.getRecycleBinUuidOrThrow().get();
const recycleBinGroup = root.getGroupByUuidOrThrow(recycleBinUuid);
this.moveOrThrow(recycleBinGroup);
meta.getRecycleBinChangedOrThrow().setOrThrow(new Date());
}
cloneToHistoryOrThrow() {
return this.getHistoryOrNew().insertAndCleanOrThrow(this);
}
createStringOrThrow(key, value) {
const { ownerDocument } = this.element;
const $string = ownerDocument.createElement("String");
this.element.appendChild($string);
const $key = ownerDocument.createElement("Key");
$key.innerHTML = key;
$string.appendChild($key);
const $value = ownerDocument.createElement("Value");
$value.innerHTML = value;
$string.appendChild($value);
this.getTimesOrThrow().getLastModificationTimeOrThrow().setOrThrow(new Date());
return new String($string);
}
getUuidOrThrow() {
const element = this.element.querySelector(":scope > UUID");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getTimesOrThrow() {
const element = this.element.querySelector(":scope > Times");
if (element == null)
throw new Error();
return new Times(element);
}
getHistoryOrThrow() {
const element = this.element.querySelector(":scope > History");
if (element == null)
throw new Error();
return new History(element);
}
getHistoryOrNull() {
const element = this.element.querySelector(":scope > History");
if (element == null)
return;
return new History(element);
}
getHistoryOrNew() {
const { ownerDocument } = this.element;
const previous = this.element.querySelector(":scope > History");
if (previous != null)
return new History(previous);
const created = ownerDocument.createElement("History");
this.element.appendChild(created);
return new History(created);
}
*getDirectStrings() {
const elements = this.element.querySelectorAll(`:scope > String`);
for (const element of elements)
yield new String(element);
return;
}
getDirectStringByIndexOrThrow(index) {
const element = this.element.querySelector(`:scope > String:nth-of-type(${index + 1})`);
if (element == null)
throw new Error();
return new String(element);
}
getDirectStringByIndexOrNull(index) {
const element = this.element.querySelector(`:scope > String:nth-of-type(${index + 1})`);
if (element == null)
return;
return new String(element);
}
getDirectStringByKeyOrThrow(key) {
const elements = this.element.querySelectorAll(`:scope > String`);
for (const element of elements) {
const string = new String(element);
if (string.getKeyOrThrow().get() === key)
return string;
continue;
}
throw new Error();
}
getDirectStringByKeyOrNull(key) {
const elements = this.element.querySelectorAll(`:scope > String`);
for (const element of elements) {
const string = new String(element);
if (string.getKeyOrThrow().get() === key)
return string;
continue;
}
return;
}
}
KeePassFile.Entry = Entry;
class String {
element;
constructor(element) {
this.element = element;
}
getKeyOrThrow() {
const element = this.element.querySelector(":scope > Key");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
getValueOrThrow() {
const element = this.element.querySelector(":scope > Value");
if (element == null)
throw new Error();
return new index.Data.AsString(element);
}
}
KeePassFile.String = String;
class Value {
element;
constructor(element) {
this.element = element;
}
get() {
return this.element.innerHTML;
}
set(value) {
this.element.innerHTML = value;
}
get protected() {
return this.element.getAttribute("Protected");
}
set protected(value) {
if (value == null)
this.element.removeAttribute("Protected");
else
this.element.setAttribute("Protected", value);
}
}
KeePassFile.Value = Value;
class History {
element;
constructor(element) {
this.element = element;
}
insertAndCleanOrThrow(entry) {
const clone = new Entry(entry.element.cloneNode(true));
const history = clone.getHistoryOrNull();
if (history != null)
clone.element.removeChild(history.element);
this.element.prepend(clone.element);
this.cleanOrThrow();
return clone;
}
cleanOrThrow() {
const file = new KeePassFile(this.element.ownerDocument);
const meta = file.getMetaOrThrow();
const historyMaxItems = meta.getHistoryMaxItemsOrThrow().getOrThrow();
if (this.element.children.length > historyMaxItems) {
while (this.element.children.length > historyMaxItems) {
const last = this.element.lastElementChild;
if (last == null)
throw new Error();
this.element.removeChild(last);
}
}
const historyMaxSize = meta.getHistoryMaxSizeOrThrow().getOrThrow();
for (let bytes = new TextEncoder().encode(new XMLSerializer().serializeToString(this.element)); bytes.length > historyMaxSize; bytes = new TextEncoder().encode(new XMLSerializer().serializeToString(this.element))) {
const last = this.element.lastElementChild;
if (last == null)
throw new Error();
this.element.removeChild(last);
}
}
*getDirectEntries() {
const elements = this.element.querySelectorAll(`:scope > Entry`);
for (const element of elements)
yield new Entry(element);
return;
}
getDirectEntryByIndexOrThrow(index) {
const element = this.element.querySelector(`:scope > Entry:nth-of-type(${index + 1})`);
if (element == null)
throw new Error();
return new Entry(element);
}
getDirectEntryByIndexOrNull(index) {
const element = this.element.querySelector(`:scope > Entry:nth-of-type(${index + 1})`);
if (element == null)
return;
return new Entry(element);
}
}
KeePassFile.History = History;
})(KeePassFile || (KeePassFile = {}));
exports.KeePassFile = KeePassFile;
//# sourceMappingURL=index.cjs.map