#!/bin/bash . $(dirname $0)/include.sh function test_login { login || return 1 assertz $? } function test_login_wrong_pw_should_fail { LPASS_ASKPASS=./askpass-wrong.sh login local ret=$? rm .askpass.lock 2>/dev/null assert $ret } function test_add_account { login || return 1 local name="test-add-account" local url="https://example.com" local username="user27" local password="999999999" cat<<__EOM__ | lpass add --sync=no --non-interactive $name Name: $name URL: $url Username: $username Password: $password __EOM__ assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --password $name)" "$password" } function test_add_site_note { login || return 1 local name="test-add-site-note" local url="https://example.com" local username="user27" local password="999999999" local notes="here are some notes!!" cat<<__EOM__ | lpass add --sync=no --non-interactive $name Name: $name URL: $url Username: $username Password: $password Notes: $notes __EOM__ assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --note $name)" "$notes" } function test_add_note { login || return 1 local name="test-add-note" cat<<__EOM__ | lpass add --sync=no --note-type=ssn --non-interactive $name Name: $name Number: 000-00-0000 NoteType: Social Security __EOM__ assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --field=Number $name)" "000-00-0000" } function test_add_note_with_field { login || return 1 local name="test-add-note-with-notes" cat<<__EOM__ | lpass add --sync=no --note-type=ssn --non-interactive $name Name: $name Number: 000-00-0000 Field: This is my SSN NoteType: Social Security __EOM__ assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --field=Number $name)" "000-00-0000" } function test_add_ssn_name { login || return 1 local name="test-add-note" local person_name="John Doe" cat<<__EOM__ | lpass add --sync=no --note-type=ssn --non-interactive $name Name: $name Name: $person_name Number: 000-00-0000 NoteType: Social Security __EOM__ assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --field=Name $name)" "$person_name" } function test_add_ssh_key { login || return 1 local name="test-add-ssh-key" read -r -d '' privkey <<__EOM__ -----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,5D91CAD2A62C0E3EDCCB853FCB21054D V/HhFCirRljWoJnjOwwhoFqdRnpWbXQsrppky/uT/Ttb9k5YmC9SLhEZyf8fAReJ KGiE8MvnnXKvDMj5eqeWge/YleHsNvyR+8qPqfPha9X/vYCUeR/ZoGg/CKzMVBN3 bnghFVqB3npQykkkbiBEKLDwosTkR/0JO4I8PRzo34k= -----END EC PRIVATE KEY----- __EOM__ read -r -d '' pubkey <<__EOM__ ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHiavhPDPg2OH2YjJWDpF9JHpKfnVGB0xc7cSojMXMJftgH4UvgUr8fVJhfp1ix/I8a/a8C0RiCo/Q/A6z3o+7U= blah __EOM__ cat <<__EOM__ | lpass add --sync=no --note-type=ssh-key --non-interactive $name Name: $name Hostname: foobar Private Key: $privkey Public Key: $pubkey __EOM__ assert_str_eq "$(lpass show --sync=no --field='Private Key' $name)" "$privkey" || return 1 assert_str_eq "$(lpass show --sync=no --field='Public Key' $name)" "$pubkey" } function test_edit_ssh_key { login || return 1 local name="test-edit-ssh-key" read -r -d '' privkey <<__EOM__ -----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,5D91CAD2A62C0E3EDCCB853FCB21054D V/HhFCirRljWoJnjOwwhoFqdRnpWbXQsrppky/uT/Ttb9k5YmC9SLhEZyf8fAReJ KGiE8MvnnXKvDMj5eqeWge/YleHsNvyR+8qPqfPha9X/vYCUeR/ZoGg/CKzMVBN3 bnghFVqB3npQykkkbiBEKLDwosTkR/0JO4I8PRzo34k= -----END EC PRIVATE KEY----- __EOM__ read -r -d '' pubkey <<__EOM__ ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHiavhPDPg2OH2YjJWDpF9JHpKfnVGB0xc7cSojMXMJftgH4UvgUr8fVJhfp1ix/I8a/a8C0RiCo/Q/A6z3o+7U= blah __EOM__ cat <<__EOM__ | lpass add --sync=no --note-type=ssh-key --non-interactive $name Name: $name Hostname: foobar __EOM__ echo "$privkey" | lpass edit --sync=no --field='Private Key' --non-interactive $name echo "$pubkey" | lpass edit --sync=no --field='Public Key' --non-interactive $name assert_str_eq "$(lpass show --sync=no --field='Private Key' $name)" "$privkey" || return 1 assert_str_eq "$(lpass show --sync=no --field='Public Key' $name)" "$pubkey" } function test_edit_username { login || return 1 local username="new-test-user" echo $username | lpass edit --username --non-interactive test-account assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --username test-account)" $username } function test_edit_field { login || return 1 local hostname="quux.bar.com" echo $hostname | lpass edit --field=Hostname --non-interactive test-note assertz $? || return 1 assert_str_eq "$(lpass show --sync=no --field=Hostname test-note)" $hostname } function test_edit_reprompt { login || return 1 echo "Reprompt: No" | lpass edit --non-interactive test-reprompt-account assertz $? || return 1 assert_str_eq "$(lpass show --sync=no test-reprompt-account | grep Reprompt)" "" echo "Reprompt: Yes" | lpass edit --non-interactive test-reprompt-account assertz $? || return 1 assert_str_eq "$(lpass show --sync=no test-reprompt-account | grep Reprompt)" "Reprompt: Yes" } function test_edit_reprompt_note { login || return 1 echo "Reprompt: No" | lpass edit --non-interactive test-reprompt-note assertz $? || return 1 assert_str_eq "$(lpass show --sync=no test-reprompt-note | grep Reprompt)" "" || return 1 echo "Reprompt: Yes" | lpass edit --non-interactive test-reprompt-note assertz $? || return 1 assert_str_eq "$(lpass show --sync=no test-reprompt-note | grep Reprompt)" "Reprompt: Yes" } function test_duplicate { login || return 1 lpass duplicate --sync=no test-account || return 1 local numaccts=$(lpass ls --sync=no | grep test-account | wc -l) assert_eq $numaccts 2 } function test_generate { login || return 1 lpass generate --sync=no test-generate 30 >/dev/null || return 1 local newpw=$(lpass show --sync=no --password test-generate) assert_eq ${#newpw} 30 } function test_show { login || return 1 read -r -d '' expected <<__EOM__ test-group/test-account [id: 0001] Username: xyz@example.com Password: test-account-password URL: https://test-url.example.com/ __EOM__ local out=$(lpass show --sync=no test-account) assert_str_eq "$expected" "$out" } function test_show_json { login || return 1 read -r -d '' expected <<__EOM__ [ { "id": "0001", "name": "test-account", "fullname": "test-group/test-account", "username": "xyz@example.com", "password": "test-account-password", "last_modified_gmt": "skipped", "last_touch": "skipped", "group": "test-group", "url": "https://test-url.example.com/", "note": "" } ] __EOM__ local out=$(lpass show --sync=no --json test-account) assert_str_eq "$expected" "$out" } function test_show_note { login || return 1 # note the extra space here because mock server includes one # normally note fields are trimmed when saved read -r -d '' expected <<__EOM__ test-group/test-note [id: 0002] Username: test-note-user Password: test-note-password Hostname: foo.example.com NoteType: Server __EOM__ local out=$(lpass show --sync=no test-note) assert_str_eq "$expected" "$out" } function test_show_reprompt { login || return 1 read -r -d '' expected <<__EOM__ test-group/test-reprompt-account [id: 0003] Username: xyz@example.com Password: test-account-password URL: https://test-url.example.com/ Reprompt: Yes __EOM__ local out=$(lpass show --sync=no test-reprompt-account) assert_str_eq "$expected" "$out" } function test_ls { login || return 1 read -r -d '' expected <<__EOM__ test-group/test-account [id: 0001] test-group/test-note [id: 0002] test-group/test-reprompt-account [id: 0003] test-group/test-reprompt-note [id: 0004] __EOM__ local out=$(lpass ls --sync=no) assert_str_eq "$expected" "$out" } function test_export { login || return 1 read -r -d '' expected <<__EOM__ url,username,password,extra,name,grouping,fav http://sn,,,"NoteType: Server Hostname: foo.example.com Username: test-note-user Password: test-note-password",test-reprompt-note,test-group,0 https://test-url.example.com/,xyz@example.com,test-account-password,,test-reprompt-account,test-group,0 http://sn,,,"NoteType: Server Hostname: foo.example.com Username: test-note-user Password: test-note-password",test-note,test-group,0 https://test-url.example.com/,xyz@example.com,test-account-password,,test-account,test-group,0 __EOM__ local out=$(lpass export --sync=no | tr -d '\r') assert_str_eq "$expected" "$out" } function test_export_extended { login || return 1 read -r -d '' expected <<__EOM__ grouping,url,username,password,extra,name,fav,id,group,fullname,last_touch,last_modified_gmt,unknown,attachpresent test-group,http://sn,,,"NoteType: Server Hostname: foo.example.com Username: test-note-user Password: test-note-password",test-reprompt-note,0,0004,test-group,test-group/test-reprompt-note,skipped,skipped,,0 test-group,https://test-url.example.com/,xyz@example.com,test-account-password,,test-reprompt-account,0,0003,test-group,test-group/test-reprompt-account,skipped,skipped,,0 test-group,http://sn,,,"NoteType: Server Hostname: foo.example.com Username: test-note-user Password: test-note-password",test-note,0,0002,test-group,test-group/test-note,skipped,skipped,,0 test-group,https://test-url.example.com/,xyz@example.com,test-account-password,,test-account,0,0001,test-group,test-group/test-account,skipped,skipped,,0 __EOM__ local out=$(lpass export --sync=no --fields=grouping,url,username,password,extra,name,fav,id,group,fullname,last_touch,last_modified_gmt,unknown,attachpresent | tr -d '\r') assert_str_eq "$expected" "$out" } runtests "$@"