is $entry->username, 'bar', 'username is set correctly as the UserName string';
cmp_deeply $entry, noclass({
- auto_type => {},
+ auto_type => {
+ associations => [],
+ data_transfer_obfuscation => 0,
+ default_sequence => "{USERNAME}{TAB}{PASSWORD}{ENTER}",
+ enabled => bool(1),
+ },
background_color => "",
binaries => {},
custom_data => {},
my $entry = File::KDBX::Entry->new;
$entry->creation_time('2022-02-02 12:34:56');
- cmp_ok $entry->creation_time, '==', 1643805296, 'Creation time coerced into a Time::Piece (epoch)';
+ cmp_ok $entry->creation_time->epoch, '==', 1643805296, 'Creation time coerced into a Time::Piece (epoch)';
is $entry->creation_time->datetime, '2022-02-02T12:34:56', 'Creation time coerced into a Time::Piece';
+
+ $entry->username('foo');
+ cmp_deeply $entry->strings->{UserName}, {
+ value => 'foo',
+ }, 'Username setter works';
+
+ $entry->password('bar');
+ cmp_deeply $entry->strings->{Password}, {
+ value => 'bar',
+ protect => bool(1),
+ }, 'Password setter works';
};
subtest 'Custom icons' => sub {
my $entry2 = $kdbx->add_entry(label => 'Bar');
$entry2->url(sprintf('{REF:T@I:%s} {REF:T@I:%s}', $entry1->id, lc($entry1->id)));
- is $entry2->expanded_url, 'Foo Foo', 'Field reference expands'
+ is $entry2->expand_url, 'Foo Foo', 'Field reference expands'
or diag explain $entry2->url;
$entry1->uuid("\1" x 16);
is $entry2->url, '{REF:T@I:01010101010101010101010101010101} {REF:T@I:01010101010101010101010101010101}',
'Replace field references when an entry UUID is changed';
- is $entry2->expanded_url, 'Foo Foo', 'Field reference expands after UUID is changed'
+ is $entry2->expand_url, 'Foo Foo', 'Field reference expands after UUID is changed'
or diag explain $entry2->url;
};
+subtest 'Auto-type' => sub {
+ my $kdbx = File::KDBX->new;
+
+ my $entry = $kdbx->add_entry(title => 'Meh');
+ $entry->add_auto_type_association({
+ window => 'Boring Store',
+ keystroke_sequence => 'yeesh',
+ });
+ $entry->add_auto_type_association({
+ window => 'Friendly Bank',
+ keystroke_sequence => 'blah',
+ });
+
+ my $window_title = 'Friendly';
+ my $entries = $kdbx->entries(auto_type => 1)
+ ->filter(sub {
+ my ($ata) = grep { $_->{window} =~ /\Q$window_title\E/i } @{$_->auto_type_associations};
+ return [$_, $ata->{keystroke_sequence} || $_->auto_type_default_sequence] if $ata;
+ });
+ cmp_ok $entries->count, '==', 1, 'Find auto-type window association';
+
+ (undef, my $keys) = @{$entries->next};
+ is $keys, 'blah', 'Select the correct association';
+};
+
+subtest 'Memory protection' => sub {
+ my $kdbx = File::KDBX->new;
+
+ is exception { $kdbx->lock }, undef, 'Can lock empty database';
+ $kdbx->unlock; # should be no-op since nothing was locked
+
+ my $entry = $kdbx->root->add_entry(
+ title => 'My Bank',
+ username => 'mreynolds',
+ password => 's3cr3t',
+ );
+ $entry->string(Custom => 'foo', protect => 1);
+ $entry->binary(Binary => 'bar', protect => 1);
+ $entry->binary(UnprotectedBinary => 'baz');
+
+ is exception { $kdbx->lock }, undef, 'Can lock new database';
+ is $entry->username, 'mreynolds', 'UserName does not get locked';
+ is $entry->password, undef, 'Password is lockable';
+ is $entry->string_value('Custom'), undef, 'Custom is lockable';
+ is $entry->binary_value('Binary'), undef, 'Binary is lockable';
+ is $entry->binary_value('UnprotectedBinary'), 'baz', 'Unprotected binary does not get locked';
+
+ $kdbx->unlock;
+ is $entry->password, 's3cr3t', 'Password is unlockable';
+ is $entry->string_value('Custom'), 'foo', 'Custom is unlockable';
+ is $entry->binary_value('Binary'), 'bar', 'Binary is unlockable';
+};
+
done_testing;