bugfix: "Send Password" menu item visibility reversed, do not store password as None, UX fixes

This commit is contained in:
scgbckbone 2026-04-16 15:22:12 +02:00 committed by doc-hex
parent 44e7be3681
commit 2b5178bd63
3 changed files with 65 additions and 4 deletions

View File

@ -7,6 +7,9 @@ This lists the new changes that have not yet been published in a normal release.
- Bugfix: Delta Mode Trick PIN was never restored from backup
- Bugfix: Proper error message for incorrect 7z headers
- Bugfix: Exiting nickname entry with nickname already saved deleted previous nickname
- Bugfix: "Send Password" menu item inside Notes & Passwords visibility reversed
- Bugfix: Yikes when using "Send Password" on entry with password None field
- Bugfix: Do not show "Saving..." UX after failed Notes & Passwords import
# Mk Specific Changes

View File

@ -380,7 +380,7 @@ class PasswordContent(NoteContentBase):
# if self.misc: rv.append(MenuItem('↳ (notes)', f=self.view))
rv += [
MenuItem('View Password', f=self.view_pw),
MenuItem('Send Password', f=self.send_pw, predicate=lambda: settings.get('du', True)),
MenuItem('Send Password', f=self.send_pw, predicate=lambda: not settings.get('du', 0)),
]
if not readonly:
rv += [
@ -468,7 +468,8 @@ class PasswordContent(NoteContentBase):
if self.idx == -1:
# prompt for password only on new records.
self.password = await get_a_password(self.password)
# can be None if CANCEL is pressed - handle, Send Password requires string
self.password = await get_a_password(self.password) or ""
site = await ux_input_text(self.site, max_len=ONE_LINE, scan_ok=True, confirm_exit=False,
prompt='Website', placeholder='(optional)')
@ -664,8 +665,9 @@ async def import_from_other(menu, *a):
records = json.load(open(fn, 'rt'))
# We have some JSON, parsed now.
await import_from_json(records)
ok = await import_from_json(records)
if not ok: return
await ux_dramatic_pause('Saved.', 3)
menu.update_contents()
@ -683,6 +685,7 @@ async def import_from_json(records):
settings.set('notes', was)
settings.set('secnap', True)
settings.save()
return True
except Exception as e:
await ux_show_story(title="Failure", msg=str(e) + '\n\n' + problem_file_line(e))

View File

@ -672,6 +672,61 @@ def test_sign_note_body(msg, addr_fmt, acct, need_some_notes,
sign_msg_from_text(msg, addr_fmt, acct, False, 0, way)
def test_send_password_menu_item(need_some_passwords, goto_notes, cap_menu, pick_menu_item,
settings_set, settings_remove, press_cancel):
# covers regression where "Send Password" menu item was only shown when USB was disabled
need_some_passwords()
settings_set('du', 1)
goto_notes()
pick_menu_item('1: A')
time.sleep(.2)
m = cap_menu()
assert 'Send Password' not in m
press_cancel()
settings_set('du', 0)
goto_notes()
pick_menu_item('1: A')
time.sleep(.2)
m = cap_menu()
assert 'Send Password' in m
for _ in range(3):
press_cancel()
@pytest.mark.onetime
def test_password_cancel_stores_empty_not_none(goto_notes, need_keypress, press_select,
press_cancel, enter_text, settings_get,
settings_set, cap_screen, pick_menu_item):
# canceling the password field when creating a new password entry stored
# None instead of ''. EmulatedKeyboard.can_type(None) then raised
# TypeError: 'NoneType' object is not iterable when "Send Password" was selected.
#
settings_set('secnap', True)
settings_set('notes', [])
goto_notes('New Password')
enter_text('cancel-pw-test') # title
press_select() # skip username
press_cancel() # cancel password field - bug, stores None
press_select() # skip site
press_cancel() # exit misc
time.sleep(0.2)
goto_notes()
pick_menu_item('1: cancel-pw-test')
pick_menu_item('Send Password')
time.sleep(.5)
scr = cap_screen()
assert 'Traceback' not in scr
assert "Place mouse at" in scr
for _ in range(5):
press_cancel()
@pytest.mark.parametrize("chain", ["BTC", "XTN"])
@pytest.mark.parametrize("change", [True, False])
@pytest.mark.parametrize("idx", [None, 0, 9999])