mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 23:38:49 +00:00
Merge pull request #436 from PR0M3TH3AN/codex/add-checksum-commands-and-api-endpoints
Add checksum CLI/API commands
This commit is contained in:
@@ -106,6 +106,8 @@ Miscellaneous helper commands.
|
|||||||
| Action | Command | Examples |
|
| Action | Command | Examples |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| Generate a password | `util generate-password` | `seedpass util generate-password --length 24` |
|
| Generate a password | `util generate-password` | `seedpass util generate-password --length 24` |
|
||||||
|
| Verify script checksum | `util verify-checksum` | `seedpass util verify-checksum` |
|
||||||
|
| Update script checksum | `util update-checksum` | `seedpass util update-checksum` |
|
||||||
|
|
||||||
### API Commands
|
### API Commands
|
||||||
|
|
||||||
@@ -170,6 +172,8 @@ Code: 123456
|
|||||||
### `util` Commands
|
### `util` Commands
|
||||||
|
|
||||||
- **`seedpass util generate-password`** – Generate a strong password of the requested length.
|
- **`seedpass util generate-password`** – Generate a strong password of the requested length.
|
||||||
|
- **`seedpass util verify-checksum`** – Verify the SeedPass script checksum.
|
||||||
|
- **`seedpass util update-checksum`** – Regenerate the script checksum file.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -28,6 +28,8 @@ Keep this token secret. Every request must include it in the `Authorization` hea
|
|||||||
- `DELETE /api/v1/fingerprint/{fp}` – Remove a fingerprint.
|
- `DELETE /api/v1/fingerprint/{fp}` – Remove a fingerprint.
|
||||||
- `POST /api/v1/fingerprint/select` – Switch the active fingerprint.
|
- `POST /api/v1/fingerprint/select` – Switch the active fingerprint.
|
||||||
- `GET /api/v1/nostr/pubkey` – Fetch the Nostr public key for the active seed.
|
- `GET /api/v1/nostr/pubkey` – Fetch the Nostr public key for the active seed.
|
||||||
|
- `POST /api/v1/checksum/verify` – Verify the checksum of the running script.
|
||||||
|
- `POST /api/v1/checksum/update` – Update the stored script checksum.
|
||||||
- `POST /api/v1/change-password` – Change the master password for the active profile.
|
- `POST /api/v1/change-password` – Change the master password for the active profile.
|
||||||
- `POST /api/v1/shutdown` – Stop the server gracefully.
|
- `POST /api/v1/shutdown` – Stop the server gracefully.
|
||||||
|
|
||||||
|
@@ -311,6 +311,24 @@ def get_nostr_pubkey(authorization: str | None = Header(None)) -> Any:
|
|||||||
return {"npub": _pm.nostr_client.key_manager.get_npub()}
|
return {"npub": _pm.nostr_client.key_manager.get_npub()}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/v1/checksum/verify")
|
||||||
|
def verify_checksum(authorization: str | None = Header(None)) -> dict[str, str]:
|
||||||
|
"""Verify the SeedPass script checksum."""
|
||||||
|
_check_token(authorization)
|
||||||
|
assert _pm is not None
|
||||||
|
_pm.handle_verify_checksum()
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/v1/checksum/update")
|
||||||
|
def update_checksum(authorization: str | None = Header(None)) -> dict[str, str]:
|
||||||
|
"""Regenerate the script checksum file."""
|
||||||
|
_check_token(authorization)
|
||||||
|
assert _pm is not None
|
||||||
|
_pm.handle_update_script_checksum()
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/api/v1/change-password")
|
@app.post("/api/v1/change-password")
|
||||||
def change_password(authorization: str | None = Header(None)) -> dict[str, str]:
|
def change_password(authorization: str | None = Header(None)) -> dict[str, str]:
|
||||||
"""Change the master password for the active profile."""
|
"""Change the master password for the active profile."""
|
||||||
|
@@ -430,6 +430,20 @@ def generate_password(ctx: typer.Context, length: int = 24) -> None:
|
|||||||
typer.echo(password)
|
typer.echo(password)
|
||||||
|
|
||||||
|
|
||||||
|
@util_app.command("verify-checksum")
|
||||||
|
def verify_checksum(ctx: typer.Context) -> None:
|
||||||
|
"""Verify the SeedPass script checksum."""
|
||||||
|
pm = _get_pm(ctx)
|
||||||
|
pm.handle_verify_checksum()
|
||||||
|
|
||||||
|
|
||||||
|
@util_app.command("update-checksum")
|
||||||
|
def update_checksum(ctx: typer.Context) -> None:
|
||||||
|
"""Regenerate the script checksum file."""
|
||||||
|
pm = _get_pm(ctx)
|
||||||
|
pm.handle_update_script_checksum()
|
||||||
|
|
||||||
|
|
||||||
@api_app.command("start")
|
@api_app.command("start")
|
||||||
def api_start(ctx: typer.Context, host: str = "127.0.0.1", port: int = 8000) -> None:
|
def api_start(ctx: typer.Context, host: str = "127.0.0.1", port: int = 8000) -> None:
|
||||||
"""Start the SeedPass API server."""
|
"""Start the SeedPass API server."""
|
||||||
|
@@ -141,3 +141,23 @@ def test_fingerprint_endpoints(client):
|
|||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert res.json() == {"status": "ok"}
|
assert res.json() == {"status": "ok"}
|
||||||
assert calls.get("select") == "xyz"
|
assert calls.get("select") == "xyz"
|
||||||
|
|
||||||
|
|
||||||
|
def test_checksum_endpoints(client):
|
||||||
|
cl, token = client
|
||||||
|
calls = {}
|
||||||
|
|
||||||
|
api._pm.handle_verify_checksum = lambda: calls.setdefault("verify", True)
|
||||||
|
api._pm.handle_update_script_checksum = lambda: calls.setdefault("update", True)
|
||||||
|
|
||||||
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
res = cl.post("/api/v1/checksum/verify", headers=headers)
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert res.json() == {"status": "ok"}
|
||||||
|
assert calls.get("verify") is True
|
||||||
|
|
||||||
|
res = cl.post("/api/v1/checksum/update", headers=headers)
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert res.json() == {"status": "ok"}
|
||||||
|
assert calls.get("update") is True
|
||||||
|
@@ -334,3 +334,31 @@ def test_entry_unarchive(monkeypatch):
|
|||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "4" in result.stdout
|
assert "4" in result.stdout
|
||||||
assert called["id"] == 4
|
assert called["id"] == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_verify_checksum_command(monkeypatch):
|
||||||
|
called = {}
|
||||||
|
|
||||||
|
pm = SimpleNamespace(
|
||||||
|
handle_verify_checksum=lambda: called.setdefault("called", True),
|
||||||
|
handle_update_script_checksum=lambda: None,
|
||||||
|
select_fingerprint=lambda fp: None,
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
|
result = runner.invoke(app, ["util", "verify-checksum"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert called.get("called") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_checksum_command(monkeypatch):
|
||||||
|
called = {}
|
||||||
|
|
||||||
|
pm = SimpleNamespace(
|
||||||
|
handle_verify_checksum=lambda: None,
|
||||||
|
handle_update_script_checksum=lambda: called.setdefault("called", True),
|
||||||
|
select_fingerprint=lambda fp: None,
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
|
result = runner.invoke(app, ["util", "update-checksum"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert called.get("called") is True
|
||||||
|
Reference in New Issue
Block a user