package onboarding import ( "github.com/google/uuid" "testing" "time" ) func TestSMSCaptchaRequiredBeforeDelivery(t *testing.T) { f := newLoginFixture(t) input := SMSSendInput{Phone: f.phone, Purpose: "LOGIN"} send := func(id string) int { w, _ := f.request("POST", "/api/v1/web/login/sms/send", input, f.cookie, f.csrf, id) return w.Code } if send("") != 401 || f.sender.calls != 0 { t.Fatal("missing image challenge sent SMS") } input = f.smsInput() input.CaptchaCode = "000000" if send("") != 401 || f.sender.calls != 0 { t.Fatal("wrong image answer sent SMS") } input.CaptchaCode = "654321" if send("") != 401 { t.Fatal("failed image answer was reusable") } input.CaptchaID = f.knownCaptchaFor("another-browser") if send("") != 401 { t.Fatal("foreign browser image accepted") } input = f.smsInput() must(t, f.s.redis.Expire(f.ctx, f.s.captchaKey(digest([]byte(f.cookie.Value))), -time.Second).Err()) if send("") != 401 { t.Fatal("expired image accepted") } input = f.smsInput() id := uuid.NewString() if send(id) != 200 || f.sender.calls != 1 { t.Fatal("valid image did not send SMS") } if send(id) != 200 || f.sender.calls != 1 { t.Fatal("exact retry delivered twice") } if send("") != 401 || f.sender.calls != 1 { t.Fatal("image replay delivered again") } } func TestSetupSMSCaptchaIsBoundToSetupSession(t *testing.T) { f := newLoginFixture(t) image, err := f.s.webCaptcha(f.ctx, f.web) must(t, err) if image["image"] == nil { t.Fatal("missing setup captcha") } in := SMSSendInput{Phone: f.phone, Purpose: "LOGIN"} if _, err = f.s.SendSMS(f.ctx, f.web, uuid.NewString(), in); err == nil || f.sender.calls != 0 { t.Fatal("setup SMS bypassed image") } in.CaptchaID, in.CaptchaCode = f.knownCaptcha(), "654321" if _, err = f.s.SendSMS(f.ctx, f.web, uuid.NewString(), in); err == nil { t.Fatal("login captcha crossed into setup") } in.CaptchaID = f.knownCaptchaFor(f.web.Hash) if _, err = f.s.SendSMS(f.ctx, f.web, uuid.NewString(), in); err != nil || f.sender.calls != 1 { t.Fatal("setup captcha rejected", err) } }