package factorhttp import ( "net/http" "net/http/httptest" "strings" "testing" sresponse "git.sendico.io/tech/sxchnge/product/auth/response" customer "git.sendico.io/tech/sxchnge/product/customers/model" api "git.sendico.io/tech/sxchnge/shared/http" mservice "git.sendico.io/tech/sxchnge/shared/service" "github.com/stretchr/testify/require" "go.uber.org/zap" ) type accountRoutes map[string]sresponse.AccountHandlerFunc func (r accountRoutes) AccountHandler(_ mservice.Type, path string, _ api.HTTPMethod, h sresponse.AccountHandlerFunc) { r[path] = h } func TestSettingsTransportRejectsCallerOwnedScopeAndDestinationOverrides(t *testing.T) { routes := accountRoutes{} Install(routes, nil, zap.NewNop()) // Every route is registered through the authenticated-account contract. require.Len(t, routes, 6) for _, tc := range []struct{ path, body string }{ {"/two-factor/enroll", `{"channel":"email","address":"a@example.com","subject":"other-account"}`}, {"/two-factor/enroll/verify", `{"challengeId":"id","code":"123456","purpose":"login"}`}, {"/two-factor/preference", `{"factorId":"id","address":"arbitrary@example.com"}`}, {"/two-factor/preference/verify", `{"factorId":"id","code":"123456","verified":true}`}, {"/two-factor/resend", `{"challengeId":"id","target":"arbitrary@example.com"}`}, {"/two-factor/enroll", `{"channel":"email"} {"channel":"sms"}`}, } { t.Run(tc.path+tc.body, func(t *testing.T) { req := httptest.NewRequest(http.MethodPost, tc.path, strings.NewReader(tc.body)) w := httptest.NewRecorder() routes[tc.path](req, &customer.Account{}, nil).ServeHTTP(w, req) require.Equal(t, http.StatusBadRequest, w.Code, w.Body.String()) require.Equal(t, "no-store", w.Header().Get("Cache-Control")) require.NotContains(t, w.Body.String(), "arbitrary@example.com") }) } }