Authentification
Better Auth, magic links, sessions, rôles
L'auth est gérée par Better Auth avec l'adapter Drizzle. Deux méthodes de connexion : magic link (onboarding) et email/password (quotidien).
Architecture
flowchart LR
Client -->|credentials| BetterAuth[Better Auth]
BetterAuth -->|session cookie| Client
BetterAuth -->|vérifie| DB[(PostgreSQL)]
Client -->|cookie httpOnly| API[tRPC API]
API -->|getSession| BetterAuthMéthodes de connexion
Magic link (onboarding)
- Admin Wcare crée un établissement → un user est créé
- Better Auth génère un magic link (token one-time, validité 24h)
- Email envoyé via Resend
- Clic → session créée → redirect vers
/dashboard
// Envoi du magic link via Better Auth
await auth.api.sendMagicLink({
email: establishment.email,
callbackURL: "/dashboard",
});Email / Password
Disponible après la première connexion. L'établissement peut définir un mot de passe depuis ses paramètres.
// Sign in classique
await authClient.signIn.email({
email: "hotel@example.com",
password: "********",
});Rôles et permissions
| Rôle | Accès | Création |
|---|---|---|
super_admin | Tout | Seed initial |
establishment_admin | Son établissement | Par le super_admin |
establishment_member | Lecture seule + alertes | Par l'establishment_admin |
Middleware de rôle (tRPC)
const requireRole = (...roles: UserRole[]) =>
protectedProcedure.use(({ ctx, next }) => {
if (!roles.includes(ctx.session.user.role)) {
throw new TRPCError({ code: "FORBIDDEN" });
}
return next({ ctx });
});
const adminOnly = requireRole("super_admin");
const establishmentOnly = requireRole("establishment_admin", "super_admin");Configuration Better Auth
betterAuth({
database: drizzleAdapter(db, { provider: "pg", schema }),
trustedOrigins: [env.CORS_ORIGIN],
emailAndPassword: { enabled: true },
magicLink: { enabled: true },
secret: env.BETTER_AUTH_SECRET,
baseURL: env.BETTER_AUTH_URL,
advanced: {
defaultCookieAttributes: {
sameSite: "none",
secure: true,
httpOnly: true,
},
},
});Sessions
- Durée : 30 jours (configurable)
- Stockage : Table
sessionen PostgreSQL - Transport : Cookie
httpOnly,secure,sameSite: none - Refresh : Automatique par Better Auth