import 'package:collection/collection.dart'; import 'package:kdbx/src/crypto/protected_value.dart'; import 'package:kdbx/src/kdbx_consts.dart'; import 'package:kdbx/src/kdbx_format.dart'; import 'package:kdbx/src/kdbx_group.dart'; import 'package:kdbx/src/kdbx_object.dart'; import 'package:xml/xml.dart'; /// Represents a case insensitive (but case preserving) key. class KdbxKey { KdbxKey(this.key) : _canonicalKey = key.toLowerCase(); final String key; final String _canonicalKey; @override bool operator ==(Object other) => other is KdbxKey && _canonicalKey == other._canonicalKey; @override int get hashCode => _canonicalKey.hashCode; } class KdbxEntry extends KdbxObject { KdbxEntry.create(this.parent) : super.create('Entry') { icon.set(KdbxIcon.Key); } KdbxEntry.read(this.parent, XmlElement node) : super.read(node) { _strings.addEntries(node.findElements('String').map((el) { final key = KdbxKey(el.findElements('Key').single.text); final valueNode = el.findElements('Value').single; if (valueNode.getAttribute('Protected')?.toLowerCase() == 'true') { return MapEntry(key, KdbxFile.protectedValueForNode(valueNode)); } else { return MapEntry(key, PlainValue(valueNode.text)); } })); } XmlElement toXml() { final el = node.copy() as XmlElement; el.children.removeWhere((e) => e is XmlElement && e.name.local == 'String'); el.children.addAll(strings.entries.map((stringEntry) { final value = XmlElement(XmlName('Value')); if (stringEntry.value is ProtectedValue) { value.attributes.add(XmlAttribute(XmlName('Protected'), 'true')); KdbxFile.setProtectedValueForNode( value, stringEntry.value as ProtectedValue); } else { value.children.add(XmlText(stringEntry.value.getText())); } return XmlElement(XmlName('String')) ..children.addAll([ XmlElement(XmlName('Key')) ..children.add(XmlText(stringEntry.key.key)), value, ]); })); return el; } KdbxGroup parent; final Map _strings = {}; Map get strings => UnmodifiableMapView(_strings); void setString(KdbxKey key, StringValue value) { _strings[key] = value; } String _plainValue(KdbxKey key) { final value = _strings[key]; if (value is PlainValue) { return value.getText(); } return value?.toString(); } String get label => _plainValue(KdbxKey('Title')); }