fix: corriger le flux de réinitialisation par e-mail
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m22s
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m22s
This commit is contained in:
66
server/__tests__/passwordResetTokenContract.test.ts
Normal file
66
server/__tests__/passwordResetTokenContract.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getDb, createPasswordResetToken, getPasswordResetToken, markTokenAsUsed } from "../db";
|
||||
import { passwordResetTokens, users } from "../../drizzle/schema";
|
||||
|
||||
const schema = readFileSync(
|
||||
new URL("../../drizzle/schema.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const databaseHelpers = readFileSync(
|
||||
new URL("../db.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const router = readFileSync(
|
||||
new URL("../routers.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const passwordResetTokenSchema = schema.match(
|
||||
/export const passwordResetTokens = mysqlTable\([\s\S]*?\n\}\);/,
|
||||
)?.[0];
|
||||
|
||||
describe("contrat des tokens de réinitialisation", () => {
|
||||
it("référence un utilisateur et non une colonne email absente de la table déployée", () => {
|
||||
expect(passwordResetTokenSchema).toContain('userId: int("userId").notNull()');
|
||||
expect(passwordResetTokenSchema).not.toContain('email: varchar("email", { length: 320 }).notNull()');
|
||||
expect(databaseHelpers).toContain(
|
||||
"createPasswordResetToken(userId: number, token: string)",
|
||||
);
|
||||
expect(databaseHelpers).toContain("userId,");
|
||||
});
|
||||
|
||||
it("utilise l’identifiant utilisateur dans les parcours public et administrateur", () => {
|
||||
expect(router).toContain("db.createPasswordResetToken(utilisateur.id, token)");
|
||||
expect(router).toContain("db.createPasswordResetToken(user.id, token)");
|
||||
expect(router).toContain("db.getUserById(resetToken.userId)");
|
||||
});
|
||||
|
||||
it("ne génère plus de lien de réinitialisation sur un domaine fictif", () => {
|
||||
expect(router).not.toContain("https://votre-domaine.com/reset-password");
|
||||
});
|
||||
|
||||
it("insère et consomme un token lié à un utilisateur sans dépendre d’un e-mail", async () => {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Base de test indisponible");
|
||||
|
||||
const [user] = await db.select({ id: users.id }).from(users).limit(1);
|
||||
if (!user) throw new Error("Utilisateur de test introuvable");
|
||||
|
||||
const token = `test-${randomUUID()}`;
|
||||
try {
|
||||
await createPasswordResetToken(user.id, token);
|
||||
|
||||
const created = await getPasswordResetToken(token);
|
||||
expect(created?.userId).toBe(user.id);
|
||||
expect(created?.used).toBe(false);
|
||||
|
||||
await markTokenAsUsed(created!.id);
|
||||
const consumed = await getPasswordResetToken(token);
|
||||
expect(consumed?.used).toBe(true);
|
||||
} finally {
|
||||
await db.delete(passwordResetTokens).where(eq(passwordResetTokens.token, token));
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user