Change database name to (rp-id).paskiadb (previously paskia.jsonl). Validate the rp-id in passkey init.

This commit is contained in:
2026-02-09 16:42:12 +00:00
parent 6a217978d6
commit 25283eba9b
4 changed files with 23 additions and 8 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ dist/
*.lock
package-lock.json
paskia.sqlite
paskia.jsonl
*.paskiadb
/paskia/frontend-build
/paskia/_version.py
coverage-html/
+3 -5
View File
@@ -17,7 +17,6 @@ import uuid7
from paskia.config import SESSION_LIFETIME
from paskia.db.jsonl import (
DB_PATH_DEFAULT,
JsonlStore,
)
from paskia.db.structs import (
@@ -42,15 +41,14 @@ _db._store = _store
_initialized = False
async def init(*args, **kwargs):
async def init(rp_id: str = "localhost", *args, **kwargs):
"""Load database from JSONL file."""
global _db, _initialized
if _initialized:
_logger.debug("Database already initialized, skipping reload")
return
db_path = os.environ.get("PASKIA_DB", DB_PATH_DEFAULT)
if db_path.startswith("json:"):
db_path = db_path[5:]
default_path = f"{rp_id}.paskiadb"
db_path = os.environ.get("PASKIA_DB", default_path)
await _store.load(db_path)
_db = _store.db
_initialized = True
+2 -2
View File
@@ -42,7 +42,7 @@ async def init(
Database configuration:
Set PASKIA_DB environment variable to specify the JSONL database file path.
Default: paskia.jsonl
Default: {rp_id}.paskiadb
"""
# Initialize passkey instance with provided parameters
@@ -53,7 +53,7 @@ async def init(
)
# Initialize database
await db.init()
await db.init(rp_id=rp_id)
# Initialize remote auth manager
await remoteauth.init()
+17
View File
@@ -8,6 +8,7 @@ This module provides a unified interface for WebAuthn operations including:
"""
import json
import re
from urllib.parse import urlparse
from uuid import UUID
@@ -62,6 +63,7 @@ class Passkey:
ValueError: If any origin domain doesn't match or isn't a subdomain of rp_id.
"""
self.rp_id = rp_id
self._validate_rp_id(rp_id)
self.rp_name = rp_name or rp_id
self.allowed_origins: set[str] | None = None
if origins:
@@ -75,6 +77,21 @@ class Passkey:
COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_256,
]
def _validate_rp_id(self, rp_id: str) -> None:
"""Validate that rp_id is a valid domain name."""
if not rp_id:
raise ValueError("rp_id cannot be empty")
# Allow localhost, or domain-like strings
if rp_id == "localhost":
return
# Regex for valid domain: letters, digits, hyphens, dots, but not starting/ending with hyphen, etc.
# Simplified: alphanumeric, dots, hyphens
if not re.match(
r"^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$",
rp_id,
):
raise ValueError(f"rp_id '{rp_id}' is not a valid domain name")
def _validate_origin(self, origin: str, rp_id: str) -> None:
"""Validate an origin URL against the rp_id."""
hostname = urlparse(origin).hostname