auth_email_challenge.test.ts (4196B)
1 import { 2 EMAIL_CHALLENGE_REQUEST_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 { assertNotEquals } from "$std/assert/assert_not_equals.ts"; 8 import { SECOND } from "$std/datetime/constants.ts"; 9 import { afterEach, beforeEach, describe, it } from "$std/testing/bdd.ts"; 10 import { FakeTime } from "$std/testing/time.ts"; 11 import { createAppForAcceptanceTest } from "./acceptance.ts"; 12 13 const uuid = "9272d511-a47f-4c91-8e41-d056ca797b42"; 14 const email = "doydy1@bfh.ch"; 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 app: ReturnType<typeof createAppForAcceptanceTest>; 21 let clock: FakeTime; 22 23 beforeEach(() => { 24 app = createAppForAcceptanceTest(); 25 clock = new FakeTime(new Date("2022-01-01T10:00:00").getTime()); 26 app.authEntities.set(uuid, { 27 uuid, 28 email, 29 emailVerified: false, 30 emailCode: null, 31 emailCodeExpire: new Date(0), 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 it("then auth should be unverified", () => { 50 const act = app.userSearch.execute({ email }); 51 assertEquals((act as { emailVerified: boolean }).emailVerified, false); 52 }); 53 54 describe("when request email challenge with invalid uuid", () => { 55 const given = () => 56 app.authEmailChallenge.execute({ uuid: "invalid uuid" }); 57 58 it("then should reject with invalid", async () => { 59 const act = await given(); 60 assertEquals(act.status, "invalid"); 61 }); 62 }); 63 64 describe("when request email challenge with already verified email", () => { 65 const given = () => { 66 app.authEntities.set(uuid, { 67 uuid, 68 email, 69 emailVerified: true, 70 emailCode: null, 71 emailCodeExpire: new Date(0), 72 emailChallengeRequest: 0, 73 emailChallengeRequestExpire: new Date(0), 74 emailChallengeAttempt: 0, 75 emailChallengeAttemptExpire: new Date(0), 76 passwordHash, 77 passwordAttempt: 0, 78 passwordAttemptExpire: new Date(0), 79 sessionToken: null, 80 sessionExpire: new Date(0), 81 version: 2, 82 }); 83 return app.authEmailChallenge.execute({ uuid }); 84 }; 85 86 it("then should be rejected with invalid", async () => { 87 const act = await given(); 88 assertEquals(act.status, "invalid"); 89 }); 90 }); 91 92 describe("when request email challenge", () => { 93 const given = () => app.authEmailChallenge.execute({ uuid }); 94 95 it("then should sent and delay 0", async () => { 96 const act = await given(); 97 assertEquals(act.status, "sent"); 98 assertEquals((act as { delay: number }).delay, 0); 99 }); 100 101 it("then code should be sent", async () => { 102 app.authEmailChallengeMailer.lastEmail = null; 103 app.authEmailChallengeMailer.lastCode = null; 104 await given(); 105 assertEquals(app.authEmailChallengeMailer.lastEmail, email); 106 assertNotEquals(app.authEmailChallengeMailer.lastCode, null); 107 }); 108 }); 109 110 describe("and request email challenge", () => { 111 beforeEach(async () => { 112 for (let i = 1; i < EMAIL_CHALLENGE_REQUEST_LIMIT; i++) { 113 await app.authEmailChallenge.execute({ uuid: uuid }); 114 } 115 }); 116 117 describe("when request email challenge", () => { 118 const given = () => app.authEmailChallenge.execute({ uuid: uuid }); 119 120 it("then should be send and delay 5min", async () => { 121 const act = await given(); 122 assertEquals(act.status, "sent"); 123 assertAlmostEquals( 124 (act as { delay: number }).delay / SECOND, 125 EMAIL_CHALLENGE_TTL / SECOND, 126 ); 127 }); 128 }); 129 }); 130 });