diff options
| -rwxr-xr-x | installer/archangel | 58 | ||||
| -rw-r--r-- | installer/lib/common.sh | 37 | ||||
| -rw-r--r-- | tests/unit/test_common.bats | 29 |
3 files changed, 70 insertions, 54 deletions
diff --git a/installer/archangel b/installer/archangel index d1831cf..4dc6689 100755 --- a/installer/archangel +++ b/installer/archangel @@ -590,26 +590,8 @@ get_luks_passphrase() { echo "IMPORTANT: If you forget this passphrase, your data is UNRECOVERABLE!" echo "" - while true; do - prompt "Enter LUKS encryption passphrase:" - read -rs LUKS_PASSPHRASE - echo "" - - prompt "Confirm passphrase:" - read -rs confirm - echo "" - - if [[ "$LUKS_PASSPHRASE" == "$confirm" ]]; then - if [[ ${#LUKS_PASSPHRASE} -lt 8 ]]; then - warn "Passphrase should be at least 8 characters. Try again." - else - info "Passphrase confirmed." - break - fi - else - warn "Passphrases don't match. Try again." - fi - done + prompt_password LUKS_PASSPHRASE "LUKS encryption passphrase" 8 + info "Passphrase confirmed." } get_encryption_choice() { @@ -647,46 +629,14 @@ get_zfs_passphrase() { echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" - while true; do - prompt "Enter ZFS encryption passphrase:" - read -s -p "> " ZFS_PASSPHRASE - echo "" - - prompt "Confirm passphrase:" - read -s -p "> " confirm_pass - echo "" - - if [[ "$ZFS_PASSPHRASE" == "$confirm_pass" ]]; then - if [[ ${#ZFS_PASSPHRASE} -lt 8 ]]; then - warn "Passphrase should be at least 8 characters." - continue - fi - break - else - warn "Passphrases do not match. Try again." - fi - done + prompt_password ZFS_PASSPHRASE "ZFS encryption passphrase" 8 } get_root_password() { step "Root Password" echo "" - while true; do - prompt "Enter root password:" - read -s -p "> " ROOT_PASSWORD - echo "" - - prompt "Confirm root password:" - read -s -p "> " confirm_pass - echo "" - - if [[ "$ROOT_PASSWORD" == "$confirm_pass" ]]; then - break - else - warn "Passwords do not match. Try again." - fi - done + prompt_password ROOT_PASSWORD "root password" 0 } get_ssh_config() { diff --git a/installer/lib/common.sh b/installer/lib/common.sh index 4acd7b9..dcaf071 100644 --- a/installer/lib/common.sh +++ b/installer/lib/common.sh @@ -57,6 +57,43 @@ require_command() { } ############################# +# Password / Passphrase Input +############################# + +# Prompt for a secret, require confirmation, enforce min length, loop +# until valid. Sets the named variable by nameref so UI output stays +# on the terminal and the caller doesn't command-substitute. +# +# Usage: prompt_password VAR_NAME "label for prompts" MIN_LEN +# min_len of 0 disables the length check. +prompt_password() { + local -n _out="$1" + local label="$2" + local min_len="${3:-0}" + local confirm + + while true; do + prompt "Enter $label:" + read -rs _out + echo "" + + prompt "Confirm $label:" + read -rs confirm + echo "" + + if [[ "$_out" != "$confirm" ]]; then + warn "Passphrases do not match. Try again." + continue + fi + if [[ $min_len -gt 0 && ${#_out} -lt $min_len ]]; then + warn "Passphrase must be at least $min_len characters. Try again." + continue + fi + break + done +} + +############################# # FZF Prompts ############################# diff --git a/tests/unit/test_common.bats b/tests/unit/test_common.bats index 6b9c18f..f0e3e21 100644 --- a/tests/unit/test_common.bats +++ b/tests/unit/test_common.bats @@ -86,3 +86,32 @@ setup() { [ "$status" -eq 0 ] [ -z "$output" ] } + +############################# +# prompt_password +############################# + +@test "prompt_password accepts matching value meeting min length" { + prompt_password PASS "label" 4 < <(printf 'hello\nhello\n') >/dev/null + [ "$PASS" = "hello" ] +} + +@test "prompt_password enforces min length by looping until met" { + prompt_password PASS "label" 4 < <(printf 'ab\nab\nlongenough\nlongenough\n') >/dev/null + [ "$PASS" = "longenough" ] +} + +@test "prompt_password retries on mismatch" { + prompt_password PASS "label" 4 < <(printf 'aaaa\nbbbb\nfinal1234\nfinal1234\n') >/dev/null + [ "$PASS" = "final1234" ] +} + +@test "prompt_password with min_len=0 skips length check" { + prompt_password PASS "label" 0 < <(printf 'x\nx\n') >/dev/null + [ "$PASS" = "x" ] +} + +@test "prompt_password accepts empty passphrase when min_len=0" { + prompt_password PASS "label" 0 < <(printf '\n\n') >/dev/null + [ -z "$PASS" ] +} |
