feat: username login support - recherche par username OU email
This commit is contained in:
@@ -17,6 +17,11 @@ import {
|
||||
createLocalUser,
|
||||
updateLocalUser,
|
||||
deleteLocalUser,
|
||||
createIdea,
|
||||
getAllIdeas,
|
||||
getIdeasByUser,
|
||||
repondreIdea,
|
||||
updateIdeaStatut,
|
||||
} from "./db";
|
||||
import { importVeille, importAAP, runFullImport, getImportConfig } from "./importer";
|
||||
import { loginLocalUser, hashPassword, ensureAdminExists } from "./localAuth";
|
||||
@@ -190,7 +195,8 @@ export const appRouter = router({
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string().min(2).max(255),
|
||||
email: z.string().email(),
|
||||
username: z.string().min(2).max(128).optional(),
|
||||
email: z.string().email().optional(),
|
||||
password: z.string().min(8),
|
||||
role: z.enum(["admin", "user", "readonly"]).default("user"),
|
||||
})
|
||||
@@ -199,7 +205,8 @@ export const appRouter = router({
|
||||
const passwordHash = await hashPassword(input.password);
|
||||
await createLocalUser({
|
||||
name: input.name,
|
||||
email: input.email.toLowerCase(),
|
||||
username: input.username ?? null,
|
||||
email: input.email ? input.email.toLowerCase() : null,
|
||||
passwordHash,
|
||||
role: input.role,
|
||||
isActive: true,
|
||||
@@ -212,6 +219,7 @@ export const appRouter = router({
|
||||
z.object({
|
||||
id: z.number().int().positive(),
|
||||
name: z.string().min(2).max(255).optional(),
|
||||
username: z.string().min(2).max(128).optional(),
|
||||
email: z.string().email().optional(),
|
||||
password: z.string().min(8).optional(),
|
||||
role: z.enum(["admin", "user", "readonly"]).optional(),
|
||||
@@ -238,6 +246,67 @@ export const appRouter = router({
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
|
||||
// ─── Boîte à idées ───────────────────────────────────────────────────────────
|
||||
ideas: router({
|
||||
// Créer une nouvelle idée / question
|
||||
create: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
titre: z.string().min(3).max(512),
|
||||
message: z.string().min(10),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
await createIdea({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? ctx.user.email ?? "Utilisateur",
|
||||
titre: input.titre,
|
||||
message: input.message,
|
||||
});
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
// Lister toutes les idées (admin) ou les siennes (user)
|
||||
list: protectedProcedure.query(async ({ ctx }) => {
|
||||
if (ctx.user.role === "admin") {
|
||||
return getAllIdeas();
|
||||
}
|
||||
return getIdeasByUser(ctx.user.id);
|
||||
}),
|
||||
|
||||
// Répondre à une idée (admin uniquement)
|
||||
repondre: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
id: z.number().int().positive(),
|
||||
reponseAdmin: z.string().min(1),
|
||||
statut: z.enum(["ouvert", "en_cours", "resolu", "ferme"]),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
await repondreIdea(
|
||||
input.id,
|
||||
input.reponseAdmin,
|
||||
ctx.user.name ?? ctx.user.email ?? "Admin",
|
||||
input.statut
|
||||
);
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
// Changer le statut (admin uniquement)
|
||||
updateStatut: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
id: z.number().int().positive(),
|
||||
statut: z.enum(["ouvert", "en_cours", "resolu", "ferme"]),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
await updateIdeaStatut(input.id, input.statut);
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
||||
Reference in New Issue
Block a user