@@ -20,28 +20,28 @@ import (
2020 "github.com/supabase/auth/internal/api/apierrors"
2121 "github.com/supabase/auth/internal/conf"
2222 "github.com/supabase/auth/internal/sbff"
23+ "github.com/supabase/auth/internal/security"
2324 "github.com/supabase/auth/internal/storage"
2425)
2526
26- const (
27- HCaptchaSecret string = "0x0000000000000000000000000000000000000000"
28- CaptchaResponse string = "10000000-aaaa-bbbb-cccc-000000000001"
29- TurnstileCaptchaSecret string = "1x0000000000000000000000000000000AA"
30- )
27+ const captchaResponse string = "10000000-aaaa-bbbb-cccc-000000000001"
3128
3229type MiddlewareTestSuite struct {
3330 suite.Suite
34- API * API
35- Config * conf.GlobalConfiguration
31+ API * API
32+ Config * conf.GlobalConfiguration
33+ CaptchaVerifier * MockCaptchaVerifier
3634}
3735
3836func TestMiddlewareFunctions (t * testing.T ) {
39- api , config , err := setupAPIForTest ()
37+ mockCaptcha := & MockCaptchaVerifier {}
38+ api , config , err := setupAPIForTest (WithCaptchaVerifier (mockCaptcha ))
4039 require .NoError (t , err )
4140
4241 ts := & MiddlewareTestSuite {
43- API : api ,
44- Config : config ,
42+ API : api ,
43+ Config : config ,
44+ CaptchaVerifier : mockCaptcha ,
4545 }
4646 defer api .db .Close ()
4747
@@ -50,50 +50,41 @@ func TestMiddlewareFunctions(t *testing.T) {
5050
5151func (ts * MiddlewareTestSuite ) TestVerifyCaptchaValid () {
5252 ts .Config .Security .Captcha .Enabled = true
53+ ts .Config .Security .Captcha .Provider = "hcaptcha"
54+ ts .Config .Security .Captcha .Secret = "test-secret"
55+
56+ // Configure mock to return success
57+ ts .CaptchaVerifier .Result = & security.VerificationResponse {Success : true }
58+ ts .CaptchaVerifier .Err = nil
5359
5460 adminClaims := & AccessTokenClaims {
5561 Role : "supabase_admin" ,
5662 }
5763 adminJwt , err := jwt .NewWithClaims (jwt .SigningMethodHS256 , adminClaims ).SignedString ([]byte (ts .Config .JWT .Secret ))
5864 require .NoError (ts .T (), err )
5965 cases := []struct {
60- desc string
61- adminJwt string
62- captcha_token string
63- captcha_provider string
66+ desc string
67+ adminJwt string
68+ captcha_token string
69+ expectVerify bool
6470 }{
6571 {
6672 "Valid captcha response" ,
6773 "" ,
68- CaptchaResponse ,
69- "hcaptcha" ,
70- },
71- {
72- "Valid captcha response" ,
73- "" ,
74- CaptchaResponse ,
75- "turnstile" ,
76- },
77- {
78- "Ignore captcha if admin role is present" ,
79- adminJwt ,
80- "" ,
81- "hcaptcha" ,
74+ captchaResponse ,
75+ true ,
8276 },
8377 {
8478 "Ignore captcha if admin role is present" ,
8579 adminJwt ,
8680 "" ,
87- "turnstile" ,
81+ false ,
8882 },
8983 }
9084 for _ , c := range cases {
91- ts .Config .Security .Captcha .Provider = c .captcha_provider
92- if c .captcha_provider == "turnstile" {
93- ts .Config .Security .Captcha .Secret = TurnstileCaptchaSecret
94- } else if c .captcha_provider == "hcaptcha" {
95- ts .Config .Security .Captcha .Secret = HCaptchaSecret
96- }
85+ // Reset mock state between cases
86+ ts .CaptchaVerifier .LastToken = ""
87+ ts .CaptchaVerifier .LastClientIP = ""
9788
9889 var buffer bytes.Buffer
9990 require .NoError (ts .T (), json .NewEncoder (& buffer ).Encode (map [string ]interface {}{
@@ -117,6 +108,12 @@ func (ts *MiddlewareTestSuite) TestVerifyCaptchaValid() {
117108 afterCtx , err := ts .API .verifyCaptcha (w , req )
118109 require .NoError (ts .T (), err )
119110
111+ if c .expectVerify {
112+ require .Equal (ts .T (), c .captcha_token , ts .CaptchaVerifier .LastToken )
113+ } else {
114+ require .Empty (ts .T (), ts .CaptchaVerifier .LastToken )
115+ }
116+
120117 body , err := io .ReadAll (req .Body )
121118 require .NoError (ts .T (), err )
122119
@@ -138,40 +135,41 @@ func (ts *MiddlewareTestSuite) TestVerifyCaptchaValid() {
138135func (ts * MiddlewareTestSuite ) TestVerifyCaptchaInvalid () {
139136 cases := []struct {
140137 desc string
141- captchaConf * conf. CaptchaConfiguration
138+ errorCodes [] string
142139 expectedCode int
143140 expectedMsg string
144141 }{
145142 {
146143 "Captcha validation failed" ,
147- & conf.CaptchaConfiguration {
148- Enabled : true ,
149- Provider : "hcaptcha" ,
150- Secret : "test" ,
151- },
144+ []string {"not-using-dummy-secret" },
152145 http .StatusBadRequest ,
153146 "captcha protection: request disallowed (not-using-dummy-secret)" ,
154147 },
155148 {
156149 "Captcha validation failed" ,
157- & conf.CaptchaConfiguration {
158- Enabled : true ,
159- Provider : "turnstile" ,
160- Secret : "anothertest" ,
161- },
150+ []string {"invalid-input-secret" },
162151 http .StatusBadRequest ,
163152 "captcha protection: request disallowed (invalid-input-secret)" ,
164153 },
165154 }
166155 for _ , c := range cases {
167156 ts .Run (c .desc , func () {
168- ts .Config .Security .Captcha = * c .captchaConf
157+ ts .Config .Security .Captcha .Enabled = true
158+ ts .Config .Security .Captcha .Provider = "hcaptcha"
159+ ts .Config .Security .Captcha .Secret = "test-secret"
160+
161+ ts .CaptchaVerifier .Result = & security.VerificationResponse {
162+ Success : false ,
163+ ErrorCodes : c .errorCodes ,
164+ }
165+ ts .CaptchaVerifier .Err = nil
166+
169167 var buffer bytes.Buffer
170168 require .NoError (ts .T (), json .NewEncoder (& buffer ).Encode (map [string ]interface {}{
171169 "email" : "test@example.com" ,
172170 "password" : "secret" ,
173171 "gotrue_meta_security" : map [string ]interface {}{
174- "captcha_token" : CaptchaResponse ,
172+ "captcha_token" : captchaResponse ,
175173 },
176174 }))
177175 req := httptest .NewRequest (http .MethodPost , "http://localhost" , & buffer )
0 commit comments