from repositories.pocketbase_client import pb_client from repositories.tenant_repository import tenant_repository from repositories.seat_repository import seat_repository def get_tenant_id_from_request(request): """ Resolves the tenant_id for a dashboard request from its `Authorization: Bearer {jwt}` header. The JWT itself is issued and verified by PocketBase (the dashboard authenticates directly against PocketBase) — this backend doesn't hold the JWT signing secret, so it validates the token by asking PocketBase to refresh it, then resolves the returned email to a tenant via the existing seat record. Data flow: request.headers['Authorization'] → strip "Bearer " prefix → PocketBase POST /api/collections/users/auth-refresh → { record: { email } } → seat lookup by email across known tenants (via domain) → tenant_id returned, or None if unresolvable """ auth_header = request.headers.get('Authorization', '') if not auth_header.startswith('Bearer '): return None token = auth_header[len('Bearer '):] record = pb_client.auth_refresh(token) if not record or not record.get('email'): return None email = record['email'] domain = email.split('@', 1)[1].lower() if '@' in email else None if not domain: return None tenant = tenant_repository.get_by_domain(domain) if not tenant: return None # Confirm this email actually holds an active seat on the tenant — # a verified PocketBase login alone isn't sufficient authorization, # the email must also be a registered, active seat. seat = seat_repository.get_active(tenant['id'], email) if not seat: return None return tenant['id']