/** * Convex Auth configuration with Zitadel OIDC. * * GDPR Compliance: No user profile data (name, email, image) is stored. * User details must be fetched from Zitadel userinfo endpoint when needed. */ import Zitadel from "@auth/core/providers/zitadel"; import { convexAuth } from "@convex-dev/auth/server"; export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({ providers: [ Zitadel({ issuer: process.env.AUTH_ZITADEL_ISSUER, clientId: process.env.AUTH_ZITADEL_ID, clientSecret: process.env.AUTH_ZITADEL_SECRET, // Strip all profile data - return only the subject ID profile(zitadelProfile) { return { id: zitadelProfile.sub, // Intentionally omit: name, email, image // These must be fetched from Zitadel userinfo endpoint }; }, }), ], callbacks: { // Validate redirect URIs for React Native async redirect({ redirectTo }) { const allowedPrefixes = [ "scry://", // App custom scheme "app://", // Default Expo scheme "exp://", // Expo Go "http://localhost", "https://localhost", ]; const isAllowed = allowedPrefixes.some((prefix) => redirectTo.startsWith(prefix) ); if (!isAllowed) { throw new Error(`Invalid redirectTo URI: ${redirectTo}`); } return redirectTo; }, }, });