Some checks are pending
Check Python Version Consistency / Check Python Version (push) Waiting to run
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""
|
|
invite_store.py — Enkel Firestore-basert invite-token store.
|
|
Brukes av POST /onboard/invite og GET /onboard/invite/{token}.
|
|
"""
|
|
import secrets
|
|
import datetime
|
|
from typing import Optional
|
|
|
|
TOKEN_TTL_HOURS = 72
|
|
|
|
|
|
class InviteStore:
|
|
def __init__(self, db):
|
|
self.db = db
|
|
self._col = "onboard_invites"
|
|
|
|
def create(self, company: str, email: str, tier: str, created_by: str = "system") -> str:
|
|
token = secrets.token_urlsafe(32)
|
|
expires_at = datetime.datetime.utcnow() + datetime.timedelta(hours=TOKEN_TTL_HOURS)
|
|
self.db.collection(self._col).document(token).set({
|
|
"company": company,
|
|
"email": email,
|
|
"tier": tier,
|
|
"created_by": created_by,
|
|
"created_at": datetime.datetime.utcnow().isoformat(),
|
|
"expires_at": expires_at.isoformat(),
|
|
"used": False,
|
|
})
|
|
return token
|
|
|
|
def get(self, token: str) -> Optional[dict]:
|
|
doc = self.db.collection(self._col).document(token).get()
|
|
if not doc.exists:
|
|
return None
|
|
data = doc.to_dict()
|
|
if data.get("used"):
|
|
return None
|
|
expires_at = datetime.datetime.fromisoformat(data["expires_at"])
|
|
if datetime.datetime.utcnow() > expires_at:
|
|
return None
|
|
return data
|
|
|
|
def mark_used(self, token: str):
|
|
self.db.collection(self._col).document(token).update({"used": True})
|