Add local Pinscope multi-user auth for shared projects.

Self-host email/password accounts enable the existing collaborator
invite flow without Clerk; first admin inherits users/local projects.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-11 14:31:37 +02:00
co-authored by Cursor
parent c5b260b404
commit 5a69b380da
22 changed files with 1045 additions and 116 deletions
+18 -2
View File
@@ -119,11 +119,18 @@ class Settings(BaseSettings):
# GCS (if set, use GCSStorageBackend; otherwise LocalStorageBackend)
gcs_bucket: str = ""
# Clerk authentication
# Clerk authentication (cloud). When set, takes priority over local auth.
clerk_secret_key: str = ""
clerk_publishable_key: str = ""
clerk_jwks_url: str = ""
# Local Pinscope auth (self-host). Set AUTH_JWT_SECRET to enable email/password
# accounts and multi-user project collaborators without Clerk.
auth_jwt_secret: str = ""
# Comma-separated emails that become admin on register (in addition to the
# first account, which is always admin).
auth_admin_emails: str = ""
# DigiKey API (optional — enables auto-fetch datasheets)
digikey_client_id: str = ""
digikey_client_secret: str = ""
@@ -212,9 +219,18 @@ class Settings(BaseSettings):
return bool(self.gcs_bucket)
@property
def use_auth(self) -> bool:
def use_clerk(self) -> bool:
return bool(self.clerk_secret_key and self.clerk_jwks_url)
@property
def use_local_auth(self) -> bool:
"""Self-host email/password auth when JWT secret is set and Clerk is not."""
return bool(self.auth_jwt_secret) and not self.use_clerk
@property
def use_auth(self) -> bool:
return self.use_clerk or self.use_local_auth
@property
def use_email(self) -> bool:
return bool(self.email_sender and self.email_frontend_url)