mirror of https://github.com/keeweb/keeweb
kdbxweb v2
parent
a845a42d0d
commit
0cbdd6281a
|
@ -48,7 +48,6 @@
|
|||
"import/no-webpack-loader-syntax": "off",
|
||||
"import/no-relative-parent-imports": "error",
|
||||
"import/first": "error",
|
||||
"import/no-namespace": "error",
|
||||
"import/no-default-export": "error",
|
||||
"babel/no-unused-expressions": "error",
|
||||
"node/no-callback-literal": "off"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Logger } from 'util/logger';
|
||||
|
||||
const logger = new Logger('online-password-checker');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Events } from 'framework/events';
|
||||
import { RuntimeInfo } from 'const/runtime-info';
|
||||
import { Transport } from 'comp/browser/transport';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
|
||||
const SecureInput = function () {
|
||||
this.el = null;
|
||||
|
@ -79,7 +79,7 @@ Object.defineProperty(SecureInput.prototype, 'value', {
|
|||
const len = pseudoValue.length;
|
||||
let byteLength = 0;
|
||||
const valueBytes = new Uint8Array(len * 4);
|
||||
const saltBytes = kdbxweb.Random.getBytes(len * 4);
|
||||
const saltBytes = kdbxweb.CryptoEngine.random(len * 4);
|
||||
let ch;
|
||||
let bytes;
|
||||
for (let i = 0; i < len; i++) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Events } from 'framework/events';
|
||||
import { Launcher } from 'comp/launcher';
|
||||
import { box as tweetnaclBox } from 'tweetnacl';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable import/no-commonjs */
|
||||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { RuntimeInfo } from 'const/runtime-info';
|
||||
import { Links } from 'const/links';
|
||||
import { DateFormat } from 'comp/i18n/date-format';
|
||||
|
@ -51,14 +51,14 @@ function walkEntry(db, entry, parents) {
|
|||
});
|
||||
}
|
||||
}
|
||||
for (const fieldName of Object.keys(entry.fields)) {
|
||||
for (const [fieldName, fieldValue] of entry.fields) {
|
||||
if (!KnownFields[fieldName]) {
|
||||
const value = entryField(entry, fieldName);
|
||||
if (value) {
|
||||
fields.push({
|
||||
title: fieldName,
|
||||
value,
|
||||
protect: entry.fields[fieldName].isProtected
|
||||
protect: fieldValue.isProtected
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ function walkEntry(db, entry, parents) {
|
|||
expires = DateFormat.dtStr(entry.times.expiryTime);
|
||||
}
|
||||
|
||||
const attachments = Object.entries(entry.binaries)
|
||||
const attachments = [...entry.binaries]
|
||||
.map(([name, data]) => {
|
||||
if (data && data.ref) {
|
||||
data = data.value;
|
||||
|
@ -95,7 +95,7 @@ function walkEntry(db, entry, parents) {
|
|||
}
|
||||
|
||||
function entryField(entry, fieldName) {
|
||||
const value = entry.fields[fieldName];
|
||||
const value = entry.fields.get(fieldName);
|
||||
return (value && value.isProtected && value.getText()) || value || '';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Events } from 'framework/events';
|
||||
import { Logger } from 'util/logger';
|
||||
import { Launcher } from 'comp/launcher';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Model } from 'framework/model';
|
||||
import { AppSettingsModel } from 'models/app-settings-model';
|
||||
import { KdbxToHtml } from 'comp/format/kdbx-to-html';
|
||||
|
@ -52,7 +52,7 @@ class EntryModel extends Model {
|
|||
this.icon = this._iconFromId(entry.icon);
|
||||
this.tags = entry.tags;
|
||||
this.color = this._colorToModel(entry.bgColor) || this._colorToModel(entry.fgColor);
|
||||
this.fields = this._fieldsToModel(entry.fields);
|
||||
this.fields = this._fieldsToModel();
|
||||
this.attachments = this._attachmentsToModel(entry.binaries);
|
||||
this.created = entry.times.creationTime;
|
||||
this.updated = entry.times.lastModTime;
|
||||
|
@ -71,7 +71,7 @@ class EntryModel extends Model {
|
|||
}
|
||||
|
||||
_getPassword() {
|
||||
const password = this.entry.fields.Password || kdbxweb.ProtectedValue.fromString('');
|
||||
const password = this.entry.fields.get('Password') || kdbxweb.ProtectedValue.fromString('');
|
||||
if (!password.isProtected) {
|
||||
return kdbxweb.ProtectedValue.fromString(password);
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ class EntryModel extends Model {
|
|||
}
|
||||
|
||||
_getFieldString(field) {
|
||||
const val = this.entry.fields[field];
|
||||
const val = this.entry.fields.get(field);
|
||||
if (!val) {
|
||||
return '';
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ class EntryModel extends Model {
|
|||
|
||||
_buildSearchText() {
|
||||
let text = '';
|
||||
for (const value of Object.values(this.entry.fields)) {
|
||||
for (const value of this.entry.fields.values()) {
|
||||
if (typeof value === 'string') {
|
||||
text += value.toLowerCase() + '\n';
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class EntryModel extends Model {
|
|||
this.customIconId = null;
|
||||
if (this.entry.customIcon) {
|
||||
this.customIcon = IconUrlFormat.toDataUrl(
|
||||
this.file.db.meta.customIcons[this.entry.customIcon]
|
||||
this.file.db.meta.customIcons.get(this.entry.customIcon.id)?.data
|
||||
);
|
||||
this.customIconId = this.entry.customIcon.toString();
|
||||
}
|
||||
|
@ -164,13 +164,13 @@ class EntryModel extends Model {
|
|||
return color ? Color.getNearest(color) : null;
|
||||
}
|
||||
|
||||
_fieldsToModel(fields) {
|
||||
return omit(fields, BuiltInFields);
|
||||
_fieldsToModel() {
|
||||
return omit(this.getAllFields(), BuiltInFields);
|
||||
}
|
||||
|
||||
_attachmentsToModel(binaries) {
|
||||
const att = [];
|
||||
for (let [title, data] of Object.entries(binaries)) {
|
||||
for (let [title, data] of binaries) {
|
||||
if (data && data.ref) {
|
||||
data = data.value;
|
||||
}
|
||||
|
@ -210,7 +210,11 @@ class EntryModel extends Model {
|
|||
}
|
||||
|
||||
getAllFields() {
|
||||
return this.entry.fields;
|
||||
const fields = {};
|
||||
for (const [key, value] of this.entry.fields) {
|
||||
fields[key] = value;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
getHistoryEntriesForSearch() {
|
||||
|
@ -232,7 +236,7 @@ class EntryModel extends Model {
|
|||
getFieldValue(field) {
|
||||
field = field.toLowerCase();
|
||||
let resolvedField;
|
||||
Object.keys(this.entry.fields).some((entryField) => {
|
||||
[...this.entry.fields.keys()].some((entryField) => {
|
||||
if (entryField.toLowerCase() === field) {
|
||||
resolvedField = entryField;
|
||||
return true;
|
||||
|
@ -240,7 +244,7 @@ class EntryModel extends Model {
|
|||
return false;
|
||||
});
|
||||
if (resolvedField) {
|
||||
let fieldValue = this.entry.fields[resolvedField];
|
||||
let fieldValue = this.entry.fields.get(resolvedField);
|
||||
const refValue = this._resolveFieldReference(fieldValue);
|
||||
if (refValue !== undefined) {
|
||||
fieldValue = refValue;
|
||||
|
@ -276,7 +280,7 @@ class EntryModel extends Model {
|
|||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
return entry.entry.fields[FieldRefIds[fieldRefId]];
|
||||
return entry.entry.fields.get(FieldRefIds[fieldRefId]);
|
||||
}
|
||||
|
||||
setColor(color) {
|
||||
|
@ -329,10 +333,10 @@ class EntryModel extends Model {
|
|||
if (hasValue || allowEmpty || BuiltInFields.indexOf(field) >= 0) {
|
||||
this._entryModified();
|
||||
val = this.sanitizeFieldValue(val);
|
||||
this.entry.fields[field] = val;
|
||||
} else if (Object.prototype.hasOwnProperty.call(this.entry.fields, field)) {
|
||||
this.entry.fields.set(field, val);
|
||||
} else if (this.entry.fields.has(field)) {
|
||||
this._entryModified();
|
||||
delete this.entry.fields[field];
|
||||
this.entry.fields.delete(field);
|
||||
}
|
||||
this._fillByEntry();
|
||||
}
|
||||
|
@ -347,7 +351,7 @@ class EntryModel extends Model {
|
|||
}
|
||||
|
||||
hasField(field) {
|
||||
return Object.prototype.hasOwnProperty.call(this.entry.fields, field);
|
||||
return this.entry.fields.has(field);
|
||||
}
|
||||
|
||||
addAttachment(name, data) {
|
||||
|
@ -360,7 +364,7 @@ class EntryModel extends Model {
|
|||
|
||||
removeAttachment(name) {
|
||||
this._entryModified();
|
||||
delete this.entry.binaries[name];
|
||||
this.entry.binaries.delete(name);
|
||||
this._fillByEntry();
|
||||
}
|
||||
|
||||
|
@ -390,8 +394,8 @@ class EntryModel extends Model {
|
|||
this.entry.pushHistory();
|
||||
this.unsaved = true;
|
||||
this.file.setModified();
|
||||
this.entry.fields = {};
|
||||
this.entry.binaries = {};
|
||||
this.entry.fields = new Map();
|
||||
this.entry.binaries = new Map();
|
||||
this.entry.copyFrom(historyEntry);
|
||||
this._entryModified();
|
||||
this._fillByEntry();
|
||||
|
@ -402,8 +406,8 @@ class EntryModel extends Model {
|
|||
this.unsaved = false;
|
||||
const historyEntry = this.entry.history[this.entry.history.length - 1];
|
||||
this.entry.removeHistory(this.entry.history.length - 1);
|
||||
this.entry.fields = {};
|
||||
this.entry.binaries = {};
|
||||
this.entry.fields = new Map();
|
||||
this.entry.binaries = new Map();
|
||||
this.entry.copyFrom(historyEntry);
|
||||
this._fillByEntry();
|
||||
}
|
||||
|
@ -476,14 +480,14 @@ class EntryModel extends Model {
|
|||
otpUrl = Otp.makeUrl(args.key, args.step, args.size);
|
||||
}
|
||||
}
|
||||
} else if (this.entry.fields['TOTP Seed']) {
|
||||
} else if (this.entry.fields.get('TOTP Seed')) {
|
||||
// TrayTOTP plugin format
|
||||
let secret = this.entry.fields['TOTP Seed'];
|
||||
let secret = this.entry.fields.get('TOTP Seed');
|
||||
if (secret.isProtected) {
|
||||
secret = secret.getText();
|
||||
}
|
||||
if (secret) {
|
||||
let settings = this.entry.fields['TOTP Settings'];
|
||||
let settings = this.entry.fields.get('TOTP Settings');
|
||||
if (settings && settings.isProtected) {
|
||||
settings = settings.getText();
|
||||
}
|
||||
|
@ -522,8 +526,8 @@ class EntryModel extends Model {
|
|||
|
||||
setOtpUrl(url) {
|
||||
this.setField('otp', url ? kdbxweb.ProtectedValue.fromString(url) : undefined);
|
||||
delete this.entry.fields['TOTP Seed'];
|
||||
delete this.entry.fields['TOTP Settings'];
|
||||
this.entry.fields.delete('TOTP Seed');
|
||||
this.entry.fields.delete('TOTP Settings');
|
||||
}
|
||||
|
||||
getEffectiveEnableAutoType() {
|
||||
|
@ -574,7 +578,7 @@ class EntryModel extends Model {
|
|||
newEntry.entry.uuid = uuid;
|
||||
newEntry.entry.times.update();
|
||||
newEntry.entry.times.creationTime = newEntry.entry.times.lastModTime;
|
||||
newEntry.entry.fields.Title = this.title + nameSuffix;
|
||||
newEntry.entry.fields.set('Title', this.title + nameSuffix);
|
||||
newEntry._fillByEntry();
|
||||
this.file.reload();
|
||||
return newEntry;
|
||||
|
@ -586,7 +590,7 @@ class EntryModel extends Model {
|
|||
this.entry.uuid = uuid;
|
||||
this.entry.times.update();
|
||||
this.entry.times.creationTime = this.entry.times.lastModTime;
|
||||
this.entry.fields.Title = '';
|
||||
this.entry.fields.set('Title', '');
|
||||
this._fillByEntry();
|
||||
}
|
||||
|
||||
|
@ -612,7 +616,7 @@ class EntryModel extends Model {
|
|||
const allFields = Object.keys(fieldWeights).concat(Object.keys(this.fields));
|
||||
|
||||
return allFields.reduce((rank, fieldName) => {
|
||||
const val = this.entry.fields[fieldName];
|
||||
const val = this.entry.fields.get(fieldName);
|
||||
if (!val) {
|
||||
return rank;
|
||||
}
|
||||
|
@ -630,20 +634,20 @@ class EntryModel extends Model {
|
|||
}
|
||||
|
||||
canCheckPasswordIssues() {
|
||||
return !this.entry.customData?.IgnorePwIssues;
|
||||
return !this.entry.customData?.has('IgnorePwIssues');
|
||||
}
|
||||
|
||||
setIgnorePasswordIssues() {
|
||||
if (!this.entry.customData) {
|
||||
this.entry.customData = {};
|
||||
this.entry.customData = new Map();
|
||||
}
|
||||
this.entry.customData.IgnorePwIssues = '1';
|
||||
this.entry.customData.set('IgnorePwIssues', '1');
|
||||
this._entryModified();
|
||||
}
|
||||
|
||||
getNextUrlFieldName() {
|
||||
const takenFields = new Set(
|
||||
Object.keys(this.entry.fields).filter((f) => f.startsWith(ExtraUrlFieldName))
|
||||
[...this.entry.fields.keys()].filter((f) => f.startsWith(ExtraUrlFieldName))
|
||||
);
|
||||
for (let i = 0; ; i++) {
|
||||
const fieldName = i ? `${ExtraUrlFieldName}_${i}` : ExtraUrlFieldName;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import demoFileData from 'demo.kdbx';
|
||||
import { Model } from 'framework/model';
|
||||
import { Events } from 'framework/events';
|
||||
|
@ -669,16 +669,19 @@ class FileModel extends Model {
|
|||
}
|
||||
|
||||
getCustomIcons() {
|
||||
return mapObject(this.db.meta.customIcons, (customIcon) =>
|
||||
IconUrlFormat.toDataUrl(customIcon)
|
||||
);
|
||||
const customIcons = {};
|
||||
for (const [id, icon] of this.db.meta.customIcons) {
|
||||
customIcons[id] = IconUrlFormat.toDataUrl(icon.data);
|
||||
}
|
||||
return customIcons;
|
||||
}
|
||||
|
||||
addCustomIcon(iconData) {
|
||||
const uuid = kdbxweb.KdbxUuid.random();
|
||||
this.db.meta.customIcons[uuid] = kdbxweb.ByteUtils.arrayToBuffer(
|
||||
kdbxweb.ByteUtils.base64ToBytes(iconData)
|
||||
);
|
||||
this.db.meta.customIcons[uuid] = {
|
||||
data: kdbxweb.ByteUtils.arrayToBuffer(kdbxweb.ByteUtils.base64ToBytes(iconData)),
|
||||
lastModified: new Date()
|
||||
};
|
||||
return uuid.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { IconMap } from 'const/icon-map';
|
||||
import { EntryModel } from 'models/entry-model';
|
||||
import { MenuItemModel } from 'models/menu/menu-item-model';
|
||||
|
@ -86,7 +86,9 @@ class GroupModel extends MenuItemModel {
|
|||
_buildCustomIcon() {
|
||||
this.customIcon = null;
|
||||
if (this.group.customIcon) {
|
||||
return IconUrlFormat.toDataUrl(this.file.db.meta.customIcons[this.group.customIcon]);
|
||||
return IconUrlFormat.toDataUrl(
|
||||
this.file.db.meta.customIcons.get(this.group.customIcon.id)?.data
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Events } from 'framework/events';
|
||||
import { SettingsStore } from 'comp/settings/settings-store';
|
||||
import { Links } from 'const/links';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import BaseLocale from 'locales/base.json';
|
||||
import { Model } from 'framework/model';
|
||||
import { RuntimeInfo } from 'const/runtime-info';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { StorageBase } from 'storage/storage-base';
|
||||
import { Locale } from 'util/locale';
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
|
||||
let newOAuthSession;
|
||||
|
||||
function createOAuthSession() {
|
||||
const session = newOAuthSession;
|
||||
|
||||
const state = kdbxweb.ByteUtils.bytesToHex(kdbxweb.Random.getBytes(64));
|
||||
const codeVerifier = kdbxweb.ByteUtils.bytesToHex(kdbxweb.Random.getBytes(50));
|
||||
const state = kdbxweb.ByteUtils.bytesToHex(kdbxweb.CryptoEngine.random(64));
|
||||
const codeVerifier = kdbxweb.ByteUtils.bytesToHex(kdbxweb.CryptoEngine.random(50));
|
||||
|
||||
const codeVerifierBytes = kdbxweb.ByteUtils.arrayToBuffer(
|
||||
kdbxweb.ByteUtils.stringToBytes(codeVerifier)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Logger } from 'util/logger';
|
||||
import publicKeyData from 'public-key.pem';
|
||||
import publicKeyDataNew from 'public-key-new.pem';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
|
||||
const IconUrlFormat = {
|
||||
toDataUrl(iconData) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { phonetic } from 'util/generators/phonetic';
|
||||
import { shuffle } from 'util/fn';
|
||||
|
||||
|
@ -54,8 +54,8 @@ const PasswordGenerator = {
|
|||
}
|
||||
}
|
||||
|
||||
const rangeIxRandomBytes = kdbxweb.Random.getBytes(countDefaultChars);
|
||||
const rangeCharRandomBytes = kdbxweb.Random.getBytes(countDefaultChars);
|
||||
const rangeIxRandomBytes = kdbxweb.CryptoEngine.random(countDefaultChars);
|
||||
const rangeCharRandomBytes = kdbxweb.CryptoEngine.random(countDefaultChars);
|
||||
const defaultRangeGeneratedChars = [];
|
||||
for (let i = 0; i < countDefaultChars; i++) {
|
||||
const rangeIx = i < ranges.length ? i : rangeIxRandomBytes[i] % ranges.length;
|
||||
|
@ -65,7 +65,7 @@ const PasswordGenerator = {
|
|||
}
|
||||
shuffle(defaultRangeGeneratedChars);
|
||||
|
||||
const randomBytes = kdbxweb.Random.getBytes(opts.length);
|
||||
const randomBytes = kdbxweb.CryptoEngine.random(opts.length);
|
||||
const chars = [];
|
||||
for (let i = 0; i < opts.length; i++) {
|
||||
const rand = Math.round(Math.random() * 1000) + randomBytes[i];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Logger } from 'util/logger';
|
||||
import { Features } from 'util/features';
|
||||
import { NativeModules } from 'comp/launcher/native-modules';
|
||||
|
@ -7,7 +7,7 @@ const logger = new Logger('argon2');
|
|||
|
||||
const KdbxwebInit = {
|
||||
init() {
|
||||
kdbxweb.CryptoEngine.argon2 = (...args) => this.argon2(...args);
|
||||
kdbxweb.CryptoEngine.setArgon2Impl((...args) => this.argon2(...args));
|
||||
},
|
||||
|
||||
argon2(password, salt, memory, iterations, length, parallelism, type, version) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
|
||||
const ExpectedFieldRefChars = '{REF:0@I:00000000000000000000000000000000}'.split('');
|
||||
const ExpectedFieldRefByteLength = ExpectedFieldRefChars.length;
|
||||
|
@ -175,7 +175,7 @@ kdbxweb.ProtectedValue.prototype.isFieldReference = function () {
|
|||
return true;
|
||||
};
|
||||
|
||||
const RandomSalt = kdbxweb.Random.getBytes(128);
|
||||
const RandomSalt = kdbxweb.CryptoEngine.random(128);
|
||||
|
||||
kdbxweb.ProtectedValue.prototype.saltedValue = function () {
|
||||
if (!this.byteLength) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { View } from 'framework/views/view';
|
||||
import { Events } from 'framework/events';
|
||||
import { AutoType } from 'auto-type';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Keys } from 'const/keys';
|
||||
import { Locale } from 'util/locale';
|
||||
import { Tip } from 'util/ui/tip';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { Events } from 'framework/events';
|
||||
import { KeyHandler } from 'comp/browser/key-handler';
|
||||
import { Keys } from 'const/keys';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { View } from 'framework/views/view';
|
||||
import { Events } from 'framework/events';
|
||||
import { CopyPaste } from 'comp/browser/copy-paste';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { View } from 'framework/views/view';
|
||||
import { Scrollable } from 'framework/views/scrollable';
|
||||
import template from 'templates/import-csv.hbs';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { View } from 'framework/views/view';
|
||||
import { Events } from 'framework/events';
|
||||
import { Storage } from 'storage';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import * as kdbxweb from 'kdbxweb';
|
||||
import { View } from 'framework/views/view';
|
||||
import { Storage } from 'storage';
|
||||
import { Shortcuts } from 'comp/app/shortcuts';
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
"jquery": "3.6.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"jsqrcode": "github:antelle/jsqrcode#0.1.3",
|
||||
"kdbxweb": "^1.14.4",
|
||||
"kdbxweb": "^2.0.0",
|
||||
"load-grunt-tasks": "5.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^2.0.3",
|
||||
|
@ -11706,13 +11706,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/kdbxweb": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/kdbxweb/-/kdbxweb-1.14.4.tgz",
|
||||
"integrity": "sha512-QhLQ6lU12Atba33/D0h/3UNLGYqmHXwjzcfgnFQ91A1PIXLS99/UpWHg1GvBniZrpXzfi8TnTEXD4wgLTK3ktw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kdbxweb/-/kdbxweb-2.0.0.tgz",
|
||||
"integrity": "sha512-oomAWfJRkgWU+1Bi20N2SXJbHLT2wnCibIsdXQm5HNQ8ot2wRa6weAMxvfekYWKbo3/mLKwLV8mq4cNhjXwhTw==",
|
||||
"dependencies": {
|
||||
"pako": "github:keeweb/pako#653c0b00d8941c89d09ed4546d2179001ec44efc",
|
||||
"text-encoding": "github:keeweb/text-encoding#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb",
|
||||
"xmldom": "github:keeweb/xmldom#ec8f61f723e2f403adaf7a1bbf55ced4ff1ea0c6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/antelle"
|
||||
}
|
||||
},
|
||||
"node_modules/kdbxweb/node_modules/xmldom": {
|
||||
|
@ -18398,9 +18401,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/text-encoding": {
|
||||
"resolved": "git+https://git@github.com/keeweb/text-encoding.git#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb"
|
||||
},
|
||||
"node_modules/text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
|
@ -29846,12 +29846,11 @@
|
|||
}
|
||||
},
|
||||
"kdbxweb": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/kdbxweb/-/kdbxweb-1.14.4.tgz",
|
||||
"integrity": "sha512-QhLQ6lU12Atba33/D0h/3UNLGYqmHXwjzcfgnFQ91A1PIXLS99/UpWHg1GvBniZrpXzfi8TnTEXD4wgLTK3ktw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kdbxweb/-/kdbxweb-2.0.0.tgz",
|
||||
"integrity": "sha512-oomAWfJRkgWU+1Bi20N2SXJbHLT2wnCibIsdXQm5HNQ8ot2wRa6weAMxvfekYWKbo3/mLKwLV8mq4cNhjXwhTw==",
|
||||
"requires": {
|
||||
"pako": "github:keeweb/pako#653c0b00d8941c89d09ed4546d2179001ec44efc",
|
||||
"text-encoding": "github:keeweb/text-encoding#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb",
|
||||
"xmldom": "github:keeweb/xmldom#ec8f61f723e2f403adaf7a1bbf55ced4ff1ea0c6"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -35131,10 +35130,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"text-encoding": {
|
||||
"version": "git+https://git@github.com/keeweb/text-encoding.git#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb",
|
||||
"from": "text-encoding@github:keeweb/text-encoding#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb"
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"jquery": "3.6.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"jsqrcode": "github:antelle/jsqrcode#0.1.3",
|
||||
"kdbxweb": "^1.14.4",
|
||||
"kdbxweb": "^2.0.0",
|
||||
"load-grunt-tasks": "5.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^2.0.3",
|
||||
|
|
|
@ -4,6 +4,7 @@ Release notes
|
|||
`+` browser extension "KeeWeb Connect"
|
||||
`+` support for KeePassXC-Browser
|
||||
`+` optimized memory consumption for large files
|
||||
`+` KDBX4.1 support
|
||||
`+` option to use short-lived tokens in cloud storages
|
||||
`+` opening XML and CSV files using the Open button
|
||||
`*` password generator now includes all selected character ranges
|
||||
|
|
Loading…
Reference in New Issue