diff --git a/CLAUDE.md b/CLAUDE.md index 35fe0e9..5cde555 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,7 +76,7 @@ Ce pattern (RLS pour l'accès à la ligne + trigger `BEFORE UPDATE` pour l'accè ## 4. Authentification -Email + mot de passe (Supabase Auth impose l'unicité de l'email). Confirmation d'email **activée** — nécessite un SMTP custom configuré côté Supabase (le service intégré est trop limité en volume, voir README). Le pseudo est un simple nom d'affichage stocké dans `profiles`, jamais l'email n'est montré aux autres membres. +**Sur invitation uniquement**, plus d'auto-inscription publique : "Allow new users to sign up" est désactivé côté Supabase. Un Archonte invite via Authentication → Users → Invite user ; le lien reçu établit une session directement sur `/signup`, qui sert alors à finaliser le compte (mot de passe, pseudo, photo) — sans session valide, la page affiche un message « invitation requise ». Le profil est créé dès l'invitation par le trigger `handle_new_user` (pseudo temporaire `"Nouveau membre"` jusqu'à finalisation). Nécessite un SMTP custom côté Supabase (le service intégré est trop limité en volume, voir README). Le pseudo est un simple nom d'affichage stocké dans `profiles`, jamais l'email n'est montré aux autres membres. --- diff --git a/README.md b/README.md index d9c2d20..5f00c8e 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,10 @@ npm install 1. Créez un nouveau projet sur [supabase.com](https://supabase.com/). 2. Dans **SQL Editor**, exécutez tout le contenu de [`supabase/schema.sql`](supabase/schema.sql) (tables `profiles`/`points_log`/`days`/`events`/`settings`, policies RLS, triggers, RPC, bucket `avatars`, Realtime). Le script est idempotent, vous pouvez le ré-exécuter sans risque après une mise à jour. 3. Récupérez l'URL du projet et la clé `anon` dans **Project Settings → API**. -4. Dans **Authentication → Providers → Email**, **activez "Confirm email"** (un vrai email par personne, condition d'unicité des comptes). -5. Dans **Authentication → Settings → SMTP Settings**, branchez un fournisseur SMTP custom (ex. Resend) — le service email par défaut de Supabase est bridé à quelques emails/heure. Voir [Email transactionnel](#email-transactionnel) ci-dessous. -6. Une fois votre propre compte créé et confirmé via `/signup`, désignez-vous Archonte (voir [Rôles & administration](#rôles--administration)). +4. Dans **Authentication → Providers → Email**, **désactivez "Allow new users to sign up"** — l'inscription publique est fermée, seules les invitations créent un compte (voir [Authentification](#authentification)). +5. Dans **Authentication → URL Configuration**, mettez **Site URL** sur `http://localhost:3000/signup` (puis votre domaine + `/signup` une fois déployé), et ajoutez la même valeur dans **Redirect URLs**. C'est la page où atterrit un lien d'invitation. +6. Dans **Authentication → Settings → SMTP Settings**, branchez un fournisseur SMTP custom (ex. Resend) — le service email par défaut de Supabase est bridé à quelques emails/heure. Voir [Email transactionnel](#email-transactionnel) ci-dessous. +7. Invitez-vous vous-même depuis **Authentication → Users → Invite user**, finalisez votre compte via le lien reçu, puis désignez-vous Archonte (voir [Rôles & administration](#rôles--administration)). ### 3. Variables d'environnement @@ -109,7 +110,7 @@ tribunal-app/ ├─ src/ │ ├─ app/ │ │ ├─ login/page.tsx # Connexion (email + mot de passe) -│ │ ├─ signup/page.tsx # Création de compte + photo recadrée +│ │ ├─ signup/page.tsx # Finalisation d'un compte invité (mot de passe, pseudo, photo) │ │ ├─ leaderboard/ │ │ │ ├─ page.tsx # Fetch initial + rôle de l'utilisateur │ │ │ └─ leaderboard-view.tsx # Realtime, podium, liste, contrôles juges @@ -139,9 +140,11 @@ tribunal-app/ ## Authentification -La connexion se fait par **email + mot de passe** ; Supabase impose l'unicité de l'email, ce qui empêche la création de comptes multiples. Le pseudo est purement un nom d'affichage (leaderboard, profil, journal) : l'email n'est jamais montré aux autres membres. La confirmation d'email est obligatoire (voir [SMTP](#email-transactionnel)). +**Sur invitation uniquement** : l'auto-inscription publique est désactivée côté Supabase (Authentication → Providers → Email → "Allow new users to sign up" décoché). Il n'y a plus de bouton « Créer un compte » sur `/login`. -Le profil (`public.profiles`) est créé automatiquement à l'inscription via un trigger sur `auth.users` (fonctionne même si l'email n'est pas encore confirmé). +Pour ajouter un membre : **Authentication → Users → Invite user** (email). Supabase lui envoie un email (via le SMTP configuré) contenant un lien d'invitation qui, une fois cliqué, établit directement une session sur `/signup` — c'est cette page qui sert alors à finaliser le compte (choix du mot de passe, du pseudo, upload de la photo). Sans session active (lien absent, invalide ou expiré), `/signup` affiche un message « invitation requise » plutôt qu'un formulaire d'inscription. + +Le profil (`public.profiles`) est créé automatiquement dès l'invitation via un trigger sur `auth.users` (pseudo temporaire `"Nouveau membre"` tant que la finalisation n'a pas eu lieu). Le pseudo est purement un nom d'affichage (leaderboard, profil, journal) : l'email n'est jamais montré aux autres membres. ### Verrou de pseudo diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index b487970..4b1b41d 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,9 +1,8 @@ "use client"; -import Link from "next/link"; import { useState, type FormEvent } from "react"; import { createClient } from "@/lib/supabase/client"; -import { LaurelWreath } from "@/components/laurel-wreath"; +import { AgoraLogo } from "@/components/agora-logo"; function mapSignInError(message: string): string { if (message.toLowerCase().includes("email not confirmed")) { @@ -43,7 +42,7 @@ export default function LoginPage() {
- Pas encore de compte ?{" "} - - Créer un compte - + L'inscription se fait uniquement sur invitation d'un Archonte.
- Vérifie ta boîte mail (et les spams) pour confirmer ton adresse, puis - connecte-toi. Tu pourras ajouter ta photo de profil ensuite depuis ton - profil. + La création de compte se fait uniquement sur invitation d'un + Archonte. Ce lien est invalide ou a expiré.
« Que ton nom soit gravé parmi les Citoyens. » @@ -138,21 +170,6 @@ export default function SignupPage() {