From 0b285e6ef079605fa1f56f193cd546185c000f16 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Mon, 1 Sep 2025 18:40:05 -0600 Subject: [PATCH] Count registration also as a login. --- passkey/db/__init__.py | 1 + passkey/db/sql.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/passkey/db/__init__.py b/passkey/db/__init__.py index fbe17fa..358f3cb 100644 --- a/passkey/db/__init__.py +++ b/passkey/db/__init__.py @@ -337,6 +337,7 @@ class DatabaseInterface(ABC): 2. Optionally delete old session (e.g. reset token) if provided 3. Optionally update user's display name 4. Insert new session referencing the credential + 5. Update user's last_seen and increment visits (treat as a login) """ diff --git a/passkey/db/sql.py b/passkey/db/sql.py index 0074b0f..729697b 100644 --- a/passkey/db/sql.py +++ b/passkey/db/sql.py @@ -414,6 +414,11 @@ class DB(DatabaseInterface): ) -> None: """Atomic credential + (optional old session delete) + (optional rename) + new session.""" async with self.session() as session: + # Ensure credential has last_used / last_verified for immediate login semantics + if credential.last_used is None: + credential.last_used = credential.created_at + if credential.last_verified is None: + credential.last_verified = credential.last_used # Insert credential session.add( CredentialModel( @@ -450,6 +455,12 @@ class DB(DatabaseInterface): info=session_info, ) ) + # Login side-effects: update user analytics (last_seen + visits increment) + await session.execute( + update(UserModel) + .where(UserModel.uuid == user_uuid.bytes) + .values(last_seen=credential.last_used, visits=UserModel.visits + 1) + ) async def delete_credential(self, uuid: UUID, user_uuid: UUID) -> None: async with self.session() as session: