mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 15:58:48 +00:00
Remove insecure parent seed endpoint
This commit is contained in:
@@ -430,25 +430,6 @@ def get_notifications(authorization: str | None = Header(None)) -> List[dict]:
|
||||
return notes
|
||||
|
||||
|
||||
@app.get("/api/v1/parent-seed")
|
||||
def get_parent_seed(
|
||||
authorization: str | None = Header(None),
|
||||
file: str | None = None,
|
||||
password: str | None = Header(None, alias="X-SeedPass-Password"),
|
||||
) -> dict:
|
||||
"""Return the parent seed or save it as an encrypted backup."""
|
||||
_check_token(authorization)
|
||||
_require_password(password)
|
||||
assert _pm is not None
|
||||
if file:
|
||||
path = Path(file)
|
||||
_pm.encryption_manager.encrypt_and_save_file(
|
||||
_pm.parent_seed.encode("utf-8"), path
|
||||
)
|
||||
return {"status": "saved", "path": str(path)}
|
||||
return {"seed": _pm.parent_seed}
|
||||
|
||||
|
||||
@app.get("/api/v1/nostr/pubkey")
|
||||
def get_nostr_pubkey(authorization: str | None = Header(None)) -> Any:
|
||||
_check_token(authorization)
|
||||
@@ -581,18 +562,24 @@ async def import_vault(
|
||||
|
||||
@app.post("/api/v1/vault/backup-parent-seed")
|
||||
def backup_parent_seed(
|
||||
data: dict | None = None, authorization: str | None = Header(None)
|
||||
data: dict,
|
||||
authorization: str | None = Header(None),
|
||||
password: str | None = Header(None, alias="X-SeedPass-Password"),
|
||||
) -> dict[str, str]:
|
||||
"""Backup and reveal the parent seed."""
|
||||
"""Create an encrypted backup of the parent seed after confirmation."""
|
||||
_check_token(authorization)
|
||||
_require_password(password)
|
||||
assert _pm is not None
|
||||
path = None
|
||||
if data is not None:
|
||||
p = data.get("path")
|
||||
if p:
|
||||
path = Path(p)
|
||||
_pm.handle_backup_reveal_parent_seed(path)
|
||||
return {"status": "ok"}
|
||||
|
||||
if not data.get("confirm"):
|
||||
raise HTTPException(status_code=400, detail="Confirmation required")
|
||||
|
||||
path_str = data.get("path")
|
||||
if not path_str:
|
||||
raise HTTPException(status_code=400, detail="Missing path")
|
||||
path = Path(path_str)
|
||||
_pm.encryption_manager.encrypt_and_save_file(_pm.parent_seed.encode("utf-8"), path)
|
||||
return {"status": "saved", "path": str(path)}
|
||||
|
||||
|
||||
@app.post("/api/v1/change-password")
|
||||
|
@@ -155,30 +155,10 @@ def test_totp_codes_endpoint(client):
|
||||
}
|
||||
|
||||
|
||||
def test_parent_seed_endpoint(client, tmp_path):
|
||||
def test_parent_seed_endpoint_removed(client):
|
||||
cl, token = client
|
||||
api._pm.parent_seed = "seed"
|
||||
called = {}
|
||||
api._pm.encryption_manager = SimpleNamespace(
|
||||
encrypt_and_save_file=lambda data, path: called.setdefault("path", path)
|
||||
)
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"X-SeedPass-Password": "pw",
|
||||
}
|
||||
|
||||
res = cl.get("/api/v1/parent-seed", headers=headers)
|
||||
assert res.status_code == 200
|
||||
assert res.json() == {"seed": "seed"}
|
||||
|
||||
out = tmp_path / "bk.enc"
|
||||
res = cl.get("/api/v1/parent-seed", params={"file": str(out)}, headers=headers)
|
||||
assert res.status_code == 200
|
||||
assert res.json() == {"status": "saved", "path": str(out)}
|
||||
assert called["path"] == out
|
||||
|
||||
res = cl.get("/api/v1/parent-seed", headers={"Authorization": f"Bearer {token}"})
|
||||
assert res.status_code == 401
|
||||
assert res.status_code == 404
|
||||
|
||||
|
||||
def test_fingerprint_endpoints(client):
|
||||
@@ -350,22 +330,31 @@ def test_vault_export_endpoint(client, tmp_path):
|
||||
|
||||
def test_backup_parent_seed_endpoint(client, tmp_path):
|
||||
cl, token = client
|
||||
api._pm.parent_seed = "seed"
|
||||
called = {}
|
||||
|
||||
def backup(path=None):
|
||||
called["path"] = path
|
||||
|
||||
api._pm.handle_backup_reveal_parent_seed = backup
|
||||
api._pm.encryption_manager = SimpleNamespace(
|
||||
encrypt_and_save_file=lambda data, path: called.setdefault("path", path)
|
||||
)
|
||||
path = tmp_path / "seed.enc"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"X-SeedPass-Password": "pw",
|
||||
}
|
||||
res = cl.post(
|
||||
"/api/v1/vault/backup-parent-seed",
|
||||
json={"path": str(path), "confirm": True},
|
||||
headers=headers,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.json() == {"status": "saved", "path": str(path)}
|
||||
assert called["path"] == path
|
||||
|
||||
res = cl.post(
|
||||
"/api/v1/vault/backup-parent-seed",
|
||||
json={"path": str(path)},
|
||||
headers=headers,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.json() == {"status": "ok"}
|
||||
assert called["path"] == path
|
||||
assert res.status_code == 400
|
||||
|
||||
|
||||
def test_relay_management_endpoints(client, dummy_nostr_client, monkeypatch):
|
||||
|
Reference in New Issue
Block a user