Merge pull request #260 from PR0M3TH3AN/beta

Beta
This commit is contained in:
thePR0M3TH3AN
2025-07-04 22:24:39 -04:00
committed by GitHub
8 changed files with 102 additions and 3 deletions

View File

@@ -78,6 +78,7 @@ bash -c "$(curl -sSL https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $scriptContent = (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/scripts/install.ps1'); & ([scriptblock]::create($scriptContent))
```
The Windows installer will attempt to install Git automatically if it is not already available.
*Install the beta branch:*
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $scriptContent = (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/scripts/install.ps1'); & ([scriptblock]::create($scriptContent)) -Branch beta

View File

@@ -32,7 +32,19 @@ function Write-Error {
# 1. Check for prerequisites
Write-Info "Installing SeedPass from branch: '$Branch'"
Write-Info "Checking for prerequisites..."
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Write-Error "Git is not installed. Please install it from https://git-scm.com/ and ensure it's in your PATH." }
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Warning "Git is not installed. Attempting to install..."
if (Get-Command winget -ErrorAction SilentlyContinue) {
try { winget install --id Git.Git -e --source winget -h } catch { Write-Error "Failed to install Git via winget. Error: $_" }
} elseif (Get-Command choco -ErrorAction SilentlyContinue) {
try { choco install git -y } catch { Write-Error "Failed to install Git via Chocolatey. Error: $_" }
} elseif (Get-Command scoop -ErrorAction SilentlyContinue) {
try { scoop install git } catch { Write-Error "Failed to install Git via Scoop. Error: $_" }
} else {
Write-Error "Git is not installed. Please install it from https://git-scm.com/ and ensure it's in your PATH."
}
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Write-Error "Git installation failed or git not found in PATH after installation." }
}
$pythonExe = Get-Command python -ErrorAction SilentlyContinue
if (-not $pythonExe) { Write-Error "Python 3 is not installed or not in your PATH. Please install it from https://www.python.org/" }

View File

@@ -57,7 +57,21 @@ main() {
# 2. Check for prerequisites
print_info "Checking for prerequisites (git, python3, pip)..."
if ! command -v git &> /dev/null; then print_error "Git is not installed. Please install it."; fi
if ! command -v git &> /dev/null; then
print_warning "Git is not installed. Attempting to install..."
if [ "$OS_NAME" = "Linux" ]; then
if command -v apt-get &> /dev/null; then sudo apt-get update && sudo apt-get install -y git;
elif command -v dnf &> /dev/null; then sudo dnf install -y git;
elif command -v pacman &> /dev/null; then sudo pacman -Syu --noconfirm git;
else print_error "Git is not installed and automatic installation is not supported on this system."; fi
elif [ "$OS_NAME" = "Darwin" ]; then
if command -v brew &> /dev/null; then brew install git;
else print_error "Git is not installed and Homebrew was not found. Please install Git manually."; fi
else
print_error "Git is not installed. Please install it."
fi
if ! command -v git &> /dev/null; then print_error "Git installation failed or git not found in PATH."; fi
fi
if ! command -v python3 &> /dev/null; then print_error "Python 3 is not installed. Please install it."; fi
if ! python3 -m ensurepip --default-pip &> /dev/null && ! command -v pip3 &> /dev/null; then print_error "pip for Python 3 is not available. Please install it."; fi
if ! python3 -c "import venv" &> /dev/null; then

View File

@@ -14,6 +14,7 @@ import json
import logging
import getpass
import os
import hashlib
from typing import Optional
import shutil
import time
@@ -2267,7 +2268,8 @@ class PasswordManager:
# Schema version and checksum status
stats["schema_version"] = data.get("schema_version")
current_checksum = json_checksum(data)
json_content = json.dumps(data, indent=4)
current_checksum = hashlib.sha256(json_content.encode("utf-8")).hexdigest()
chk_path = self.entry_manager.checksum_file
if chk_path.exists():
stored = chk_path.read_text().strip()

View File

@@ -4,6 +4,8 @@ from tempfile import TemporaryDirectory
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
from nostr.coincurve_keys import Keys
sys.path.append(str(Path(__file__).resolve().parents[1]))
from password_manager.entry_management import EntryManager
@@ -36,3 +38,11 @@ def test_nostr_key_determinism():
assert nsec1 == nsec2
assert npub1.startswith("npub")
assert nsec1.startswith("nsec")
priv_hex = Keys.bech32_to_hex(nsec1)
derived = Keys(priv_k=priv_hex)
encoded_npub = Keys.hex_to_bech32(derived.public_key_hex(), "npub")
assert encoded_npub == npub1
data = enc_mgr.load_json_data(entry_mgr.index_file)
assert data["entries"][str(idx)]["label"] == "main"

View File

@@ -25,3 +25,15 @@ def test_pgp_key_determinism():
assert fp1 == fp2
assert key1 == key2
# parse returned armored key and verify fingerprint
from pgpy import PGPKey
parsed_key, _ = PGPKey.from_blob(key1)
assert parsed_key.fingerprint == fp1
# ensure the index file stores key_type and user_id
data = enc_mgr.load_json_data(entry_mgr.index_file)
entry = data["entries"][str(idx)]
assert entry["key_type"] == "ed25519"
assert entry["user_id"] == "Test"

View File

@@ -3,6 +3,7 @@ from pathlib import Path
from tempfile import TemporaryDirectory
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
from mnemonic import Mnemonic
sys.path.append(str(Path(__file__).resolve().parents[1]))
@@ -30,6 +31,9 @@ def test_seed_phrase_determinism():
phrase24_a = entry_mgr.get_seed_phrase(idx_24, TEST_SEED)
phrase24_b = entry_mgr.get_seed_phrase(idx_24, TEST_SEED)
entry12 = entry_mgr.retrieve_entry(idx_12)
entry24 = entry_mgr.retrieve_entry(idx_24)
seed_bytes = Bip39SeedGenerator(TEST_SEED).Generate()
bip85 = BIP85(seed_bytes)
expected12 = derive_seed_phrase(bip85, idx_12, 12)
@@ -39,3 +43,7 @@ def test_seed_phrase_determinism():
assert phrase24_a == phrase24_b == expected24
assert len(phrase12_a.split()) == 12
assert len(phrase24_a.split()) == 24
assert Mnemonic("english").check(phrase12_a)
assert Mnemonic("english").check(phrase24_a)
assert entry12.get("words") == 12
assert entry24.get("words") == 24

View File

@@ -0,0 +1,40 @@
import sys
from pathlib import Path
from tempfile import TemporaryDirectory
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
sys.path.append(str(Path(__file__).resolve().parents[1]))
from password_manager.entry_management import EntryManager
from password_manager.backup import BackupManager
from password_manager.vault import Vault
from password_manager.config_manager import ConfigManager
from cryptography.hazmat.primitives import serialization
def test_ssh_private_key_corresponds_to_public():
with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir)
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
cfg_mgr = ConfigManager(vault, tmp_path)
backup_mgr = BackupManager(tmp_path, cfg_mgr)
entry_mgr = EntryManager(vault, backup_mgr)
idx = entry_mgr.add_ssh_key(TEST_SEED)
priv_pem, pub_pem = entry_mgr.get_ssh_key_pair(idx, TEST_SEED)
priv_key = serialization.load_pem_private_key(
priv_pem.encode(),
password=None,
)
derived_pub_pem = (
priv_key.public_key()
.public_bytes(
serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
)
.decode()
)
assert derived_pub_pem == pub_pem