From f8ab262dfb293477289cd6db8b2daa05804884b6 Mon Sep 17 00:00:00 2001 From: andyexeter Date: Thu, 25 Jun 2026 17:05:02 +0100 Subject: [PATCH] Send notetype so secure notes aren't classified as logins The redesigned LastPass web vault decides whether an item is a secure note from a plaintext "notetype" param, not the legacy url=http://sn marker. lpass never sends it, so notes created or edited via the CLI show up as password/login items in the web vault. Capture the notetype the server already sends (previously discarded in the account parser) and echo it back unchanged on update, so existing structured notes keep their type. New secure notes that have none default to "Generic". --- blob.c | 3 ++- blob.h | 1 + cmd-duplicate.c | 2 ++ endpoints.c | 13 +++++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/blob.c b/blob.c index 404c44e1..e19e06b7 100644 --- a/blob.c +++ b/blob.c @@ -102,6 +102,7 @@ void account_free_contents(struct account *account) free(account->username); free(account->password); free(account->note); + free(account->notetype); free(account->name_encrypted); free(account->group_encrypted); free(account->url_encrypted); @@ -393,7 +394,7 @@ static struct account *account_parse(struct chunk *chunk, const unsigned char ke entry_plain(attachkey_encrypted); entry_boolean(attachpresent); skip(individualshare); - skip(notetype); + entry_plain(notetype); skip(noalert); entry_plain(last_modified_gmt); skip(hasbeenshared); diff --git a/blob.h b/blob.h index 60a0d9cb..03b8babb 100644 --- a/blob.h +++ b/blob.h @@ -64,6 +64,7 @@ struct account { char *username, *username_encrypted; char *password, *password_encrypted; char *note, *note_encrypted; + char *notetype; char *last_touch, *last_modified_gmt; bool pwprotect; bool fav; diff --git a/cmd-duplicate.c b/cmd-duplicate.c index d507dfa9..77fdc4ec 100644 --- a/cmd-duplicate.c +++ b/cmd-duplicate.c @@ -97,6 +97,8 @@ int cmd_duplicate(int argc, char **argv) new->fullname = xstrdup(found->fullname); account_set_url(new, xstrdup(found->url), key, &session->feature_flag); new->pwprotect = found->pwprotect; + if (found->notetype) + new->notetype = xstrdup(found->notetype); list_for_each_entry(field, &found->field_head, list) { copy_field = new0(struct field, 1); diff --git a/endpoints.c b/endpoints.c index 273965ad..cd06dbec 100644 --- a/endpoints.c +++ b/endpoints.c @@ -229,6 +229,19 @@ void lastpass_update_account(enum blobsync sync, unsigned const char key[KDF_HAS http_post_add_params(¶ms, "url", url, NULL); } + /* + * The redesigned web vault classifies an item as a secure note via a + * plaintext "notetype" param, not the legacy url=http://sn marker. + * Without it, CLI-created notes render as logins. Echo back the type the + * server gave us (preserving structured types on edit), defaulting to a + * generic note for newly created notes that have none yet. + */ + if (account_is_secure_note(account)) { + const char *notetype = (account->notetype && *account->notetype) + ? account->notetype : "Generic"; + http_post_add_params(¶ms, "notetype", notetype, NULL); + } + if (strlen(fields)) { http_post_add_params(¶ms, "save_all", "1",