Auth
Cette application exécute son propre Better Auth à
/api/auth/*, en fédérant via le courtier d'authentification Grok partagé (auth.grok.me)
grâce au plugin genericOAuth. Ce modèle câble Google et X.
Méthodes de connexion prises en charge — utilisez UNIQUEMENT ces trois méthodes ; rien d'autre n'est pris en charge :
Google, X et email/mot de passe. Aucun autre fournisseur social/OAuth (GitHub, Apple, Discord, …), aucun lien magique, passkey, OTP, téléphone/SMS, ni connexion anonyme. N'ajoutez pas d'entrées à GROK_PROVIDERS. Détail des méthodes et le basculement email/mot de passe (modifiez uniquement src/lib/auth/email-password.ts) : references/sign-in-methods.md.
Exception — les visiteurs de la page d'accueil sont déjà connectés ; n'affichez JAMAIS de boutons de connexion/ré-authentification pour eux. Applications connecteur / données d'application : UNIQUEMENT le bouton "Continuer avec Grok" sur la page d'accueil, pas de boutons Google/X : references/grok-identity.md.
La connexion est DÉSACTIVÉE par défaut — le modèle fournit .grok/app-env.json avec
{"VITE_AUTH_ENABLED": "false"}, donc n'ajoutez des comptes que lorsque la demande l'exige
(AGENTS.md §0.5). L'activer consiste à "Activer la connexion" ci-dessous.
Une fois activée, la connexion est RÉELLE — y compris dans l'aperçu en direct du bac à sable. Ne créez PAS d'utilisateurs de démonstration/mock/statiques. Aperçu : popup + client d'aperçu intégré ; déployé : client par application + DATABASE_URL + connexion sans clic pour les visiteurs de la page d'accueil
(references/prewired-and-env.md).
Lorsqu'elle est DÉSACTIVÉE (VITE_AUTH_ENABLED=false), un utilisateur de développement est renvoyé afin
qu'une application sans authentification s'affiche sans visiteur connecté — développement et aperçu uniquement.
Déployé, le flag est celui de la plateforme (toujours "true"), donc requireUserId rejette
tout visiteur — les applications sans authentification ne l'utilisent ni elle ni authMiddleware.
Tout est préinstallé et pré-câblé dans src/lib/auth/ — n'exécutez pas
npm install quoi que ce soit ; better-auth est le seul package d'authentification (jamais
@neondatabase/*, @stackframe/* ou @clerk/*). Ne modifiez ni ne réécrivez aucun
fichier sous src/lib/auth/ — surtout server.ts — sauf
email-password.ts pour son unique flag. Carte des fichiers :
references/prewired-and-env.md.
/auth/popup est déjà géré par le plugin Vite du modèle
(vite.config.ts → popup.server.ts) : il n'affiche jamais l'application React. Ne créez PAS
src/routes/auth/popup.tsx (ni aucune page React / OAuth client à ce
chemin) — cela affiche l'application complète dans la popup, le mode de défaillance courant.
N'écrivez jamais de fichier .env / .env.local / .env.example dans ce bac à sable :
l'aperçu en direct n'a besoin d'aucune configuration d'environnement et une application déployée reçoit ses variables
injectées par la plateforme. Les seuls réglages existants se trouvent dans
references/prewired-and-env.md — n'exposez jamais une variable non VITE_ au client.
migrations/auth/0001_auth.sql est le schéma de Better Auth — ne le modifiez pas. Il
se trouve en dehors du répertoire globé migrations/ (aucun applicateur ne descend), donc
il n'est pas appliqué aux applications sans connexion ; "Activer la connexion" le copie vers le haut.
Activer la connexion
Faites tout cela — les routes seules affichent la branche désactivée :
- Flag : supprimez la clé
VITE_AUTH_ENABLEDde.grok/app-env.jsonet redémarrez le serveur de développement. Vite lit l'environnement au démarrage, donc HMR ne le prendra pas en compte.npm run dev,npm run buildetnpm run previewlisent tous ce fichier viascripts/with-app-env.mjs, donc l'aperçu et la sortie compilée basculent ensemble — ne démarrez jamais Vite directement. - Schéma :
cp migrations/auth/0001_auth.sql migrations/0001_auth.sql, puis redémarrez pour qu'il s'applique. Il est suivi par le nom de base dans_migrations, donc une base de données qui l'a déjà ne l'exécutera pas à nouveau. - Routes : ajoutez
src/routes/api/auth/$.ts+src/routes/login.tsx— copiez les deux depuisreferences/wiring.md(la route API générique est ce qui rend/api/auth/*et le rappel du courtier fonctionnels). - Déconnexion : une connexion sans moyen de sortie n'est pas terminée — affichez
<UserButton />depuis@/lib/auth/gates(il câblesignOut(); cache la déconnexion pour les sessions de page d'accueil). - Données existantes : enveloppez les fonctions serveur de l'application dans
authMiddleware(une application sans authentification ne doit pas l'avoir utilisée — voir la compétenceneon). Les lignes d'avant l'existence de la connexion sont des données de développement : supprimez-les et recréez-les sauf si l'utilisateur dit le contraire — ne les remettez pas à celui qui se connecte en premier.
Construire dessus une fois activée
- Connexion / Déconnexion :
signIn(providerId)etsignOut()depuis@/lib/auth/client;GROK_PROVIDERSaffiche les boutons. La popup, le transfert de jeton porteur et l'attachement de la requête sont internes — ne les touchez pas. Préférez<UserButton />(il gère les états en attente et d'échec) ;signOut()échoue en déploiement si le serveur ne confirme jamais — interceptez-le. Ne faites jamaisauthClient.signOut(): cela laisse le jeton porteur de l'aperçu attaché à chaque requête ultérieure, donc le visiteur reste connecté. - Lire l'utilisateur :
useCurrentUser()est réservé à l'affichage (nullsignifie chargement OU déconnecté, donc ne redirigez jamais uniquement sur lui) ; utilisez plutôtuseCurrentUserState()mais uniquement pour son étatisPending. Les portes (SignedIn,SignedOut,SignInGate,RedirectToSignIn,UserButton) se trouvent dans@/lib/auth/gates. Règles strictes pour les appels à l'action, squelette et cookie-SSR sans flash :references/session-ui.md. - Données par utilisateur (obligatoire) : toute fonction serveur qui touche à des données par utilisateur
doit utiliser le
authMiddlewarepré-câblé et limiter chaque lecture et écriture àcontext.userId— un pilote Postgres a un accès complet à la base de données, donc rien d'autre ne limite la requête. Gardez les colonnesuser_idenTEXT; ne faites jamais confiance à un identifiant utilisateur fourni par le client ; une fois déconnecté, le middleware lèveUnauthorizedError(401). Code et sémantique en mode désactivé :references/per-user-data.md. - Modèle de sécurité : courtier sans tête, cookies
__Host-+trustedOrigins, et l'isolation des frères Fetch-Metadata sont déjà câblés — ne les affaiblissez jamais pour faire disparaître une erreur (references/sign-in-methods.mdcouvre le modèle et le correctif "Origine invalide").