cadrumo.entrypoints.tui.secret.passphrase module

Passphrase change: re-wrap one profile’s key under a new password.

This screen collects the current passphrase (proof), the replacement, and its confirmation, then hands all three to the injected rotation door. It decides nothing about whether a new password is acceptable or whether a confirmation mismatch refuses the change – both are re-checked inside rotate_profile_passphrase() regardless of what this screen already validated, per that door’s own stated contract (“a caller reaching this function directly must not be able to skip the check”).

See also

rotate_profile_passphrase()

The application door this screen drives.

RegistrationScreen

The sibling credential surface this one borrows its live strength feedback and attempt shape from.

class PassphraseChangeRefusal(message_key, context=())[source]

Bases: object

Secret-free localized refusal retained as data until rendering.

Parameters:
message_key: str
context: tuple[tuple[str, object], ...]
render(*, locale=None)[source]

Resolve the refusal under the screen’s active language.

Return type:

str

Parameters:

locale (str | None)

class PassphraseChangeAttempt(outcome=None, expected_refusal=None)[source]

Bases: object

The outcome of asking the application to rotate a profile’s passphrase.

Same shape as RegistrationAttempt: a refusal arrives as text the screen displays, not as an exception it has to recognise, keeping refusal classification with the layer that owns the rotation rules.

Parameters:
outcome: ProfilePassphraseRotationOutcome | None
expected_refusal: PassphraseChangeRefusal | None
property refusal: str | None

Render expected refusal data only at the presentation boundary.

class PassphraseScreen(*, assess, rotate)[source]

Bases: CredentialScreen[ProfilePassphraseRotationOutcome]

Full-screen credential entry that re-wraps one profile’s password.

Parameters:
SCOPED_CSS: ClassVar[bool]

Should default css be limited to the widget type?

DEFAULT_CSS: ClassVar[str]

Default TCSS.

ATTEMPT_NAME: ClassVar[str]
compose()[source]

Yield the banner, the three credential fields, and the footer.

Return type:

Iterable[Widget]

on_mount()[source]

Install the theme, render copy, and focus the current-password field.

Return type:

None

on_input_changed(event)[source]

Re-render the advisory strength line as the new password is typed.

Return type:

None

Parameters:

event (Changed)

on_button_pressed(event)[source]

Route a change or cancellation button intent.

Return type:

None

Parameters:

event (Pressed)

on_input_submitted(event)[source]

Enter advances to the next field, and submits from the last one.

Return type:

None

Parameters:

event (Submitted)

action_change()[source]

Validate the form locally, then rotate the passphrase and exit.

Local checks only catch what the screen can see – a blank current password, an unacceptable new one, a mismatched confirmation. Everything else (a wrong current passphrase, a storage refusal) is the application door’s decision, surfaced here as its translated message rather than re-derived.

Return type:

None

resolve_attempt_refusal(attempt)[source]

Render structured rotation refusals under this screen’s locale.

Return type:

str | None

Parameters:

attempt (CredentialAttempt[ProfilePassphraseRotationOutcome])

default_refusal()[source]

Text shown when a refusal carries no message.

Return type:

str

progress_message()[source]

Operator-facing description of the subclass’s in-flight attempt.

Return type:

str

refuse(message)[source]

Show refusal and return the keyboard to the form.

The rotation door refuses while the fields are disabled, so re-enabling them leaves nothing focused. The local checks focus the field they name immediately after calling this; the current-password field is the landing place for a refusal that named none, which in practice is the door rejecting the current password.

Return type:

None

Parameters:

message (str)

set_busy(*, busy)[source]

Render change progress and freeze inputs while storage mutates.

Return type:

None

Parameters:

busy (bool)

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

build_profile_passphrase_change_door(profile_id, *, profile_decode_context)[source]

Bind the canonical rotation door to one already-authenticated profile.

The identity is closed over here so the screen never carries it, and the returned door mutates nothing until the operator submits. Expected refusals stay data: the application owns which failures are expected and supplies their localized key, and no passphrase reaches the result.

Return type:

Callable[[str, str, str], PassphraseChangeAttempt]

Parameters: