|
|
@ -1,3 +1,7 @@ |
|
|
|
|
|
|
|
import 'dart:convert'; |
|
|
|
|
|
|
|
import 'dart:typed_data'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import 'package:collection/collection.dart'; |
|
|
|
import 'package:kdbx/kdbx.dart'; |
|
|
|
import 'package:kdbx/kdbx.dart'; |
|
|
|
import 'package:kdbx/src/internal/extension_utils.dart'; |
|
|
|
import 'package:kdbx/src/internal/extension_utils.dart'; |
|
|
|
import 'package:kdbx/src/kdbx_binary.dart'; |
|
|
|
import 'package:kdbx/src/kdbx_binary.dart'; |
|
|
@ -17,6 +21,7 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext { |
|
|
|
String generator, |
|
|
|
String generator, |
|
|
|
}) : customData = KdbxCustomData.create(), |
|
|
|
}) : customData = KdbxCustomData.create(), |
|
|
|
binaries = [], |
|
|
|
binaries = [], |
|
|
|
|
|
|
|
_customIcons = {}, |
|
|
|
super.create('Meta') { |
|
|
|
super.create('Meta') { |
|
|
|
this.databaseName.set(databaseName); |
|
|
|
this.databaseName.set(databaseName); |
|
|
|
this.generator.set(generator ?? 'kdbx.dart'); |
|
|
|
this.generator.set(generator ?? 'kdbx.dart'); |
|
|
@ -39,6 +44,20 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext { |
|
|
|
yield KdbxBinary.readBinaryXml(binaryNode, isInline: false); |
|
|
|
yield KdbxBinary.readBinaryXml(binaryNode, isInline: false); |
|
|
|
} |
|
|
|
} |
|
|
|
})?.toList(), |
|
|
|
})?.toList(), |
|
|
|
|
|
|
|
_customIcons = node |
|
|
|
|
|
|
|
.singleElement(KdbxXml.NODE_CUSTOM_ICONS) |
|
|
|
|
|
|
|
?.let((el) sync* { |
|
|
|
|
|
|
|
for (final iconNode in el.findElements(KdbxXml.NODE_ICON)) { |
|
|
|
|
|
|
|
yield KdbxCustomIcon( |
|
|
|
|
|
|
|
uuid: KdbxUuid( |
|
|
|
|
|
|
|
iconNode.singleTextNode(KdbxXml.NODE_UUID)), |
|
|
|
|
|
|
|
data: base64.decode( |
|
|
|
|
|
|
|
iconNode.singleTextNode(KdbxXml.NODE_DATA))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
?.map((e) => MapEntry(e.uuid, e)) |
|
|
|
|
|
|
|
?.let((that) => Map.fromEntries(that)) ?? |
|
|
|
|
|
|
|
{}, |
|
|
|
super.read(node); |
|
|
|
super.read(node); |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
@ -49,6 +68,18 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext { |
|
|
|
/// only used in Kdbx 3 |
|
|
|
/// only used in Kdbx 3 |
|
|
|
final List<KdbxBinary> binaries; |
|
|
|
final List<KdbxBinary> binaries; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final Map<KdbxUuid, KdbxCustomIcon> _customIcons; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<KdbxUuid, KdbxCustomIcon> get customIcons => |
|
|
|
|
|
|
|
UnmodifiableMapView(_customIcons); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void addCustomIcon(KdbxCustomIcon customIcon) { |
|
|
|
|
|
|
|
if (_customIcons.containsKey(customIcon.uuid)) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
modify(() => _customIcons[customIcon.uuid] = customIcon); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
StringNode get generator => StringNode(this, 'Generator'); |
|
|
|
StringNode get generator => StringNode(this, 'Generator'); |
|
|
|
|
|
|
|
|
|
|
|
StringNode get databaseName => StringNode(this, 'DatabaseName'); |
|
|
|
StringNode get databaseName => StringNode(this, 'DatabaseName'); |
|
|
@ -62,6 +93,8 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext { |
|
|
|
DateTimeUtcNode get recycleBinChanged => |
|
|
|
DateTimeUtcNode get recycleBinChanged => |
|
|
|
DateTimeUtcNode(this, 'RecycleBinChanged'); |
|
|
|
DateTimeUtcNode(this, 'RecycleBinChanged'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// void addCustomIcon |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
xml.XmlElement toXml() { |
|
|
|
xml.XmlElement toXml() { |
|
|
|
final ret = super.toXml()..replaceSingle(customData.toXml()); |
|
|
|
final ret = super.toXml()..replaceSingle(customData.toXml()); |
|
|
@ -80,6 +113,26 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext { |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
XmlUtils.removeChildrenByName(ret, KdbxXml.NODE_CUSTOM_ICONS); |
|
|
|
|
|
|
|
ret.children.add( |
|
|
|
|
|
|
|
XmlElement(XmlName(KdbxXml.NODE_CUSTOM_ICONS)) |
|
|
|
|
|
|
|
..children.addAll(customIcons.values.map( |
|
|
|
|
|
|
|
(e) => XmlUtils.createNode(KdbxXml.NODE_ICON, [ |
|
|
|
|
|
|
|
XmlUtils.createTextNode(KdbxXml.NODE_UUID, e.uuid.uuid), |
|
|
|
|
|
|
|
XmlUtils.createTextNode(KdbxXml.NODE_DATA, base64.encode(e.data)) |
|
|
|
|
|
|
|
]), |
|
|
|
|
|
|
|
)), |
|
|
|
|
|
|
|
); |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class KdbxCustomIcon { |
|
|
|
|
|
|
|
KdbxCustomIcon({this.uuid, this.data}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// uuid of the icon, must be unique within each file. |
|
|
|
|
|
|
|
final KdbxUuid uuid; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Encoded png data of the image. will be base64 encoded into the kdbx file. |
|
|
|
|
|
|
|
final Uint8List data; |
|
|
|
|
|
|
|
} |
|
|
|