auth_email_verify.test.ts (3710B)
1 import { 2 EMAIL_CHALLENGE_ATTEMPT_LIMIT, 3 EMAIL_CHALLENGE_TTL, 4 } from "#core/domain/constants.ts"; 5 import { assertAlmostEquals } from "$std/assert/assert_almost_equals.ts"; 6 import { assertEquals } from "$std/assert/assert_equals.ts"; 7 import { SECOND } from "$std/datetime/constants.ts"; 8 import { afterEach, beforeEach, describe, it } from "$std/testing/bdd.ts"; 9 import { FakeTime } from "$std/testing/time.ts"; 10 import { createAppForAcceptanceTest } from "./acceptance.ts"; 11 12 const uuid = "9272d511-a47f-4c91-8e41-d056ca797b42"; 13 const email = "doydy1@bfh.ch"; 14 const emailCode = "769262"; 15 // hash("password") 16 const passwordHash = 17 "$argon2id$v=19$m=65536,t=2,p=1$JqSklInU0x0uFDs/tj+dDQ$Z6vJ+4MlZqSwPocHobYwbeUt+I18a4T5k5m90wB/dpg"; 18 19 describe("given auth email challenge use case for acceptance test", () => { 20 let clock: FakeTime; 21 let app: ReturnType<typeof createAppForAcceptanceTest>; 22 23 beforeEach(() => { 24 clock = new FakeTime(new Date("2022-01-01T10:00:00").getTime()); 25 app = createAppForAcceptanceTest(); 26 app.authEntities.set(uuid, { 27 uuid, 28 email, 29 emailVerified: false, 30 emailCode, 31 emailCodeExpire: new Date(Date.now() + EMAIL_CHALLENGE_TTL), 32 emailChallengeRequest: 0, 33 emailChallengeRequestExpire: new Date(0), 34 emailChallengeAttempt: 0, 35 emailChallengeAttemptExpire: new Date(0), 36 passwordHash, 37 passwordAttempt: 0, 38 passwordAttemptExpire: new Date(0), 39 sessionToken: null, 40 sessionExpire: new Date(0), 41 version: 1, 42 }); 43 }); 44 45 afterEach(() => { 46 clock.restore(); 47 }); 48 49 describe("when verify email with valid code", () => { 50 const given = () => app.authVerifyEmail.execute({ uuid, code: emailCode }); 51 52 it("then should reject with invalid", async () => { 53 const act = await given(); 54 assertEquals(act.status, "verified"); 55 }); 56 57 it("then should be persisted", async () => { 58 await given(); 59 assertEquals(app.authEntities.get(uuid), { 60 uuid, 61 email, 62 emailVerified: true, 63 emailCode: null, 64 emailCodeExpire: new Date(0), 65 emailChallengeRequest: 0, 66 emailChallengeRequestExpire: new Date(0), 67 emailChallengeAttempt: 0, 68 emailChallengeAttemptExpire: new Date(0), 69 passwordHash, 70 passwordAttempt: 0, 71 passwordAttemptExpire: new Date(0), 72 sessionToken: null, 73 sessionExpire: new Date(0), 74 version: 2, 75 }); 76 }); 77 }); 78 79 describe("when verify email with invalid code", () => { 80 const given = () => app.authVerifyEmail.execute({ uuid, code: "whatever" }); 81 it("then should reject with invalid without counting as attempt", async () => { 82 for (let i = 0; i < EMAIL_CHALLENGE_ATTEMPT_LIMIT; i++) { 83 const act = await given(); 84 assertEquals(act, { status: "invalid", delay: 0 }); 85 } 86 }); 87 }); 88 89 describe("when verify email with wrong code", () => { 90 const given = () => app.authVerifyEmail.execute({ uuid, code: "878632" }); 91 it("then should reject with invalid", async () => { 92 const act = await given(); 93 assertEquals(act, { status: "invalid", delay: 0 }); 94 }); 95 }); 96 97 describe("when verify email with wrong code n times and reached attempt limit", () => { 98 const given = () => app.authVerifyEmail.execute({ uuid, code: "878632" }); 99 it("then should reject with invalid", async () => { 100 for (let i = 0; i < EMAIL_CHALLENGE_ATTEMPT_LIMIT; i++) { 101 await given(); 102 } 103 const act = await given(); 104 assertEquals(act.status, "invalid"); 105 assertAlmostEquals( 106 (act as { delay: number }).delay / SECOND, 107 EMAIL_CHALLENGE_TTL / SECOND, 108 ); 109 }); 110 }); 111 });