From 2099573be9ec1400c6b6120464e367610efd8ce9 Mon Sep 17 00:00:00 2001 From: kszafran Date: Wed, 23 Mar 2022 18:02:18 +0100 Subject: [PATCH] fix: accept recovery link from authenticated users (#2195) When a recovery link is opened while the user already has a session cookie (possibly for another account), the endpoint will now correctly complete the recovery process and issue new cookies. BREAKING CHANGES: Calling /self-service/recovery without flow ID or with an invalid flow ID while authenticated will now respond with an error instead of redirecting to the default page. Closes https://github.com/ory-corp/cloud/issues/2173 Co-authored-by: aeneasr <3372410+aeneasr@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- internal/testhelpers/handler_mock.go | 26 ++++- internal/testhelpers/server.go | 1 + internal/testhelpers/session.go | 34 +++++- selfservice/flow/nosurf_test.go | 56 ++++++++++ selfservice/flow/recovery/handler.go | 4 +- .../strategy/link/strategy_recovery.go | 11 +- .../strategy/link/strategy_recovery_test.go | 100 ++++++++++++++++-- .../recovery/recovery/success.spec.ts | 36 +++++++ test/e2e/hydra-login-consent/go.mod | 2 + test/e2e/hydra-login-consent/go.sum | 52 +-------- test/e2e/run.sh | 4 +- 13 files changed, 257 insertions(+), 75 deletions(-) create mode 100644 selfservice/flow/nosurf_test.go diff --git a/go.mod b/go.mod index be8dc27c7ca2..524080efb0f1 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ replace ( // official SDK, allowing for the Ory CLI to consume Ory Kratos' CLI commands. github.com/ory/kratos-client-go => ./internal/httpclient go.mongodb.org/mongo-driver => go.mongodb.org/mongo-driver v1.4.6 - golang.org/x/sys => golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac + golang.org/x/sys => golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 gopkg.in/DataDog/dd-trace-go.v1 => gopkg.in/DataDog/dd-trace-go.v1 v1.27.1-0.20201005154917-54b73b3e126a ) diff --git a/go.sum b/go.sum index 890575b254ad..8b6aefd4ad08 100644 --- a/go.sum +++ b/go.sum @@ -2118,8 +2118,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/internal/testhelpers/handler_mock.go b/internal/testhelpers/handler_mock.go index da3e59e8f701..c65abdb40b10 100644 --- a/internal/testhelpers/handler_mock.go +++ b/internal/testhelpers/handler_mock.go @@ -29,10 +29,16 @@ type mockDeps interface { } func MockSetSession(t *testing.T, reg mockDeps, conf *config.Config) httprouter.Handle { - return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { i := identity.NewIdentity(config.DefaultIdentityTraitsSchemaID) require.NoError(t, reg.PrivilegedIdentityPool().CreateIdentity(context.Background(), i)) + MockSetSessionWithIdentity(t, reg, conf, i)(w, r, ps) + } +} + +func MockSetSessionWithIdentity(t *testing.T, reg mockDeps, conf *config.Config, i *identity.Identity) httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { activeSession, _ := session.NewActiveSession(i, conf, time.Now().UTC(), identity.CredentialsTypePassword, identity.AuthenticatorAssuranceLevel1) if aal := r.URL.Query().Get("set_aal"); len(aal) > 0 { activeSession.AuthenticatorAssuranceLevel = identity.AuthenticatorAssuranceLevel(aal) @@ -56,10 +62,21 @@ func MockGetSession(t *testing.T, reg mockDeps) httprouter.Handle { } func MockMakeAuthenticatedRequest(t *testing.T, reg mockDeps, conf *config.Config, router *httprouter.Router, req *http.Request) ([]byte, *http.Response) { + return MockMakeAuthenticatedRequestWithClient(t, reg, conf, router, req, NewClientWithCookies(t)) +} + +func MockMakeAuthenticatedRequestWithClient(t *testing.T, reg mockDeps, conf *config.Config, router *httprouter.Router, req *http.Request, client *http.Client) ([]byte, *http.Response) { + return MockMakeAuthenticatedRequestWithClientAndID(t, reg, conf, router, req, client, nil) +} + +func MockMakeAuthenticatedRequestWithClientAndID(t *testing.T, reg mockDeps, conf *config.Config, router *httprouter.Router, req *http.Request, client *http.Client, id *identity.Identity) ([]byte, *http.Response) { set := "/" + uuid.New().String() + "/set" - router.GET(set, MockSetSession(t, reg, conf)) + if id == nil { + router.GET(set, MockSetSession(t, reg, conf)) + } else { + router.GET(set, MockSetSessionWithIdentity(t, reg, conf, id)) + } - client := NewClientWithCookies(t) MockHydrateCookieClient(t, client, "http://"+req.URL.Host+set+"?"+req.URL.Query().Encode()) res, err := client.Do(req) @@ -94,6 +111,7 @@ func MockHydrateCookieClient(t *testing.T, c *http.Client, u string) { res, err := c.Get(u) require.NoError(t, err) defer res.Body.Close() + body := x.MustReadAll(res.Body) assert.EqualValues(t, http.StatusOK, res.StatusCode) var found bool @@ -102,7 +120,7 @@ func MockHydrateCookieClient(t *testing.T, c *http.Client, u string) { found = true } } - require.True(t, found) + require.True(t, found, "got body: %s\ngot url: %s", body, res.Request.URL.String()) } func MockSessionCreateHandlerWithIdentity(t *testing.T, reg mockDeps, i *identity.Identity) (httprouter.Handle, *session.Session) { diff --git a/internal/testhelpers/server.go b/internal/testhelpers/server.go index 3eb2c541201a..6b072434fc03 100644 --- a/internal/testhelpers/server.go +++ b/internal/testhelpers/server.go @@ -76,6 +76,7 @@ func NewKratosServers(t *testing.T) (public, admin *httptest.Server) { public = httptest.NewServer(x.NewRouterPublic()) admin = httptest.NewServer(x.NewRouterAdmin()) + public.URL = strings.Replace(public.URL, "127.0.0.1", "localhost", -1) t.Cleanup(public.Close) t.Cleanup(admin.Close) return diff --git a/internal/testhelpers/session.go b/internal/testhelpers/session.go index 2e550388c8ca..5174067fc556 100644 --- a/internal/testhelpers/session.go +++ b/internal/testhelpers/session.go @@ -3,9 +3,12 @@ package testhelpers import ( "context" "net/http" + "strings" "testing" "time" + "github.com/ory/nosurf" + "github.com/stretchr/testify/assert" "github.com/tidwall/gjson" @@ -52,14 +55,39 @@ func maybePersistSession(t *testing.T, reg *driver.RegistryDefault, sess *sessio func NewHTTPClientWithSessionCookie(t *testing.T, reg *driver.RegistryDefault, sess *session.Session) *http.Client { maybePersistSession(t, reg, sess) - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.NoError(t, reg.SessionManager().IssueCookie(context.Background(), w, r, sess)) - })) + }) + + if _, ok := reg.CSRFHandler().(*nosurf.CSRFHandler); ok { + handler = nosurf.New(handler) + } + + ts := httptest.NewServer(handler) + defer ts.Close() + + c := NewClientWithCookies(t) + MockHydrateCookieClient(t, c, ts.URL) + return c +} + +func NewHTTPClientWithSessionCookieLocalhost(t *testing.T, reg *driver.RegistryDefault, sess *session.Session) *http.Client { + maybePersistSession(t, reg, sess) + + var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.NoError(t, reg.SessionManager().IssueCookie(context.Background(), w, r, sess)) + }) + + if _, ok := reg.CSRFHandler().(*nosurf.CSRFHandler); ok { + handler = nosurf.New(handler) + } + + ts := httptest.NewServer(handler) defer ts.Close() c := NewClientWithCookies(t) - // This should work for other test servers as well because cookies ignore ports. + ts.URL = strings.Replace(ts.URL, "127.0.0.1", "localhost", 1) MockHydrateCookieClient(t, c, ts.URL) return c } diff --git a/selfservice/flow/nosurf_test.go b/selfservice/flow/nosurf_test.go new file mode 100644 index 000000000000..31d2d7af99ee --- /dev/null +++ b/selfservice/flow/nosurf_test.go @@ -0,0 +1,56 @@ +package flow + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ory/nosurf" +) + +func TestGetCSRFToken(t *testing.T) { + noToken := &mockReg{ + presentToken: "", + regeneratedToken: "regenerated", + } + + tokenPresent := &mockReg{ + presentToken: "existing", + regeneratedToken: "regenerated", + } + + t.Run("case=no token, browser flow", func(t *testing.T) { + assert.Equal(t, "regenerated", GetCSRFToken(noToken, nil, nil, TypeBrowser)) + }) + + t.Run("case=token present, browser flow", func(t *testing.T) { + assert.Equal(t, "existing", GetCSRFToken(tokenPresent, nil, nil, TypeBrowser)) + }) + + t.Run("case=no token, api flow", func(t *testing.T) { + assert.Equal(t, "", GetCSRFToken(noToken, nil, nil, TypeAPI)) + }) + + t.Run("case=token present, api flow", func(t *testing.T) { + assert.Equal(t, "existing", GetCSRFToken(tokenPresent, nil, nil, TypeAPI)) + }) +} + +type mockReg struct { + presentToken, regeneratedToken string + + nosurf.Handler +} + +func (m *mockReg) GenerateCSRFToken(*http.Request) string { + return m.presentToken +} + +func (m *mockReg) CSRFHandler() nosurf.Handler { + return m +} + +func (m *mockReg) RegenerateToken(http.ResponseWriter, *http.Request) string { + return m.regeneratedToken +} diff --git a/selfservice/flow/recovery/handler.go b/selfservice/flow/recovery/handler.go index ae7893b30968..6a2ee80b2ce2 100644 --- a/selfservice/flow/recovery/handler.go +++ b/selfservice/flow/recovery/handler.go @@ -79,8 +79,8 @@ func (h *Handler) RegisterPublicRoutes(public *x.RouterPublic) { public.GET(RouteGetFlow, h.fetch) - public.GET(RouteSubmitFlow, h.d.SessionHandler().IsNotAuthenticated(h.submitFlow, redirect)) - public.POST(RouteSubmitFlow, h.d.SessionHandler().IsNotAuthenticated(h.submitFlow, redirect)) + public.GET(RouteSubmitFlow, h.submitFlow) + public.POST(RouteSubmitFlow, h.submitFlow) } func (h *Handler) RegisterAdminRoutes(admin *x.RouterAdmin) { diff --git a/selfservice/strategy/link/strategy_recovery.go b/selfservice/strategy/link/strategy_recovery.go index 1cd71eb94bb8..1965ba17d2ef 100644 --- a/selfservice/strategy/link/strategy_recovery.go +++ b/selfservice/strategy/link/strategy_recovery.go @@ -225,6 +225,15 @@ func (s *Strategy) Recover(w http.ResponseWriter, r *http.Request, f *recovery.F return s.recoveryUseToken(w, r, body) } + if _, err := s.d.SessionManager().FetchFromRequest(r.Context(), r); err == nil { + if x.IsJSONRequest(r) { + session.RespondWithJSONErrorOnAuthenticated(s.d.Writer(), recovery.ErrAlreadyLoggedIn)(w, r, nil) + } else { + session.RedirectOnAuthenticated(s.d)(w, r, nil) + } + return errors.WithStack(flow.ErrCompletedByStrategy) + } + if err := flow.MethodEnabledAndAllowed(r.Context(), s.RecoveryStrategyID(), body.Method, s.d); err != nil { return s.HandleRecoveryError(w, r, nil, body, err) } @@ -254,7 +263,7 @@ func (s *Strategy) Recover(w http.ResponseWriter, r *http.Request, f *recovery.F func (s *Strategy) recoveryIssueSession(w http.ResponseWriter, r *http.Request, f *recovery.Flow, id *identity.Identity) error { f.UI.Messages.Clear() f.State = recovery.StatePassedChallenge - f.SetCSRFToken(flow.GetCSRFToken(s.d, w, r, f.Type)) + f.SetCSRFToken(s.d.CSRFHandler().RegenerateToken(w, r)) f.RecoveredIdentityID = uuid.NullUUID{ UUID: id.ID, Valid: true, diff --git a/selfservice/strategy/link/strategy_recovery_test.go b/selfservice/strategy/link/strategy_recovery_test.go index 488356e654ca..5763bde40ca1 100644 --- a/selfservice/strategy/link/strategy_recovery_test.go +++ b/selfservice/strategy/link/strategy_recovery_test.go @@ -193,7 +193,7 @@ func TestRecovery(t *testing.T) { _ = testhelpers.NewSettingsUIFlowEchoServer(t, reg) _ = testhelpers.NewErrorTestServer(t, reg) - public, _ := testhelpers.NewKratosServerWithCSRF(t, reg) + public, _, publicRouter, _ := testhelpers.NewKratosServerWithCSRFAndRouters(t, reg) var createIdentityToRecover = func(email string) *identity.Identity { var id = &identity.Identity{ @@ -298,7 +298,59 @@ func TestRecovery(t *testing.T) { check(t, expectValidationError(t, nil, true, false, values), email) }) } + }) + t.Run("description=should try to submit the form while authenticated", func(t *testing.T) { + run := func(t *testing.T, flow string) { + isAPI := flow == "api" + isSPA := flow == "spa" + hc := testhelpers.NewDebugClient(t) + if !isAPI { + hc = testhelpers.NewClientWithCookies(t) + hc.Transport = testhelpers.NewTransportWithLogger(http.DefaultTransport, t).RoundTripper + } + + var f *kratos.SelfServiceRecoveryFlow + if isAPI { + f = testhelpers.InitializeRecoveryFlowViaAPI(t, hc, public) + } else { + f = testhelpers.InitializeRecoveryFlowViaBrowser(t, hc, isSPA, public, nil) + } + + v := testhelpers.SDKFormFieldsToURLValues(f.Ui.Nodes) + v.Set("email", "some-email@example.org") + v.Set("method", "link") + + authClient := testhelpers.NewHTTPClientWithArbitrarySessionToken(t, reg) + if isAPI { + s, err := session.NewActiveSession( + &identity.Identity{ID: x.NewUUID(), State: identity.StateActive}, + testhelpers.NewSessionLifespanProvider(time.Hour), + time.Now(), + identity.CredentialsTypePassword, + identity.AuthenticatorAssuranceLevel1, + ) + require.NoError(t, err) + authClient = testhelpers.NewHTTPClientWithSessionCookieLocalhost(t, reg, s) + } + + body, res := testhelpers.RecoveryMakeRequest(t, isAPI || isSPA, f, authClient, testhelpers.EncodeFormAsJSON(t, isAPI || isSPA, v)) + + if isAPI || isSPA { + assert.EqualValues(t, http.StatusBadRequest, res.StatusCode, "%s", body) + assert.Contains(t, res.Request.URL.String(), recovery.RouteSubmitFlow, "%+v\n\t%s", res.Request, body) + assertx.EqualAsJSONExcept(t, recovery.ErrAlreadyLoggedIn, json.RawMessage(gjson.Get(body, "error").Raw), nil) + } else { + assert.EqualValues(t, http.StatusOK, res.StatusCode, "%s", body) + assert.Contains(t, res.Request.URL.String(), conf.SelfServiceBrowserDefaultReturnTo().String(), "%+v\n\t%s", res.Request, body) + } + } + + for _, f := range []string{"browser", "spa", "api"} { + t.Run("type="+f, func(t *testing.T) { + run(t, f) + }) + } }) t.Run("description=should try to recover an email that does not exist", func(t *testing.T) { @@ -480,17 +532,14 @@ func TestRecovery(t *testing.T) { }) t.Run("description=should recover an account and set the csrf cookies", func(t *testing.T) { - recoveryEmail := "recoverme1@ory.sh" - - var check = func(t *testing.T, actual string) { + var check = func(t *testing.T, actual, recoveryEmail string, cl *http.Client, do func(*http.Client, *http.Request) (*http.Response, error)) { message := testhelpers.CourierExpectMessage(t, reg, recoveryEmail, "Recover access to your account") recoveryLink := testhelpers.CourierExpectLinkInMessage(t, message, 1) - cl := testhelpers.NewClientWithCookies(t) cl.CheckRedirect = func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse } - res, err := cl.Get(recoveryLink) + res, err := do(cl, x.NewTestHTTPRequest(t, "GET", recoveryLink, nil)) require.NoError(t, err) require.NoError(t, res.Body.Close()) assert.Equal(t, http.StatusSeeOther, res.StatusCode) @@ -498,6 +547,9 @@ func TestRecovery(t *testing.T) { cookies := spew.Sdump(cl.Jar.Cookies(urlx.ParseOrPanic(public.URL))) assert.Contains(t, cookies, x.CSRFTokenName) assert.Contains(t, cookies, "ory_kratos_session") + returnTo, err := res.Location() + require.NoError(t, err) + assert.Contains(t, returnTo.String(), conf.SelfServiceFlowSettingsUI().String(), "we end up at the settings screen") rl := urlx.ParseOrPanic(recoveryLink) actualRes, err := cl.Get(public.URL + recovery.RouteGetFlow + "?id=" + rl.Query().Get("flow")) @@ -505,13 +557,41 @@ func TestRecovery(t *testing.T) { body := x.MustReadAll(actualRes.Body) require.NoError(t, actualRes.Body.Close()) assert.Equal(t, http.StatusOK, actualRes.StatusCode, "%s", body) + assert.Equal(t, string(recovery.StatePassedChallenge), gjson.GetBytes(body, "state").String(), "%s", body) } - var values = func(v url.Values) { - v.Set("email", recoveryEmail) - } + email := x.NewUUID().String() + "@ory.sh" + id := createIdentityToRecover(email) - check(t, expectSuccess(t, nil, false, false, values)) + t.Run("case=unauthenticated", func(t *testing.T) { + var values = func(v url.Values) { + v.Set("email", email) + } + check(t, expectSuccess(t, nil, false, false, values), email, testhelpers.NewClientWithCookies(t), (*http.Client).Do) + }) + + t.Run("case=already logged into another account", func(t *testing.T) { + var values = func(v url.Values) { + v.Set("email", email) + } + + check(t, expectSuccess(t, nil, false, false, values), email, testhelpers.NewClientWithCookies(t), func(cl *http.Client, req *http.Request) (*http.Response, error) { + _, res := testhelpers.MockMakeAuthenticatedRequestWithClient(t, reg, conf, publicRouter.Router, req, cl) + return res, nil + }) + }) + + t.Run("case=already logged into the account", func(t *testing.T) { + var values = func(v url.Values) { + v.Set("email", email) + } + + cl := testhelpers.NewHTTPClientWithIdentitySessionCookie(t, reg, id) + check(t, expectSuccess(t, nil, false, false, values), email, cl, func(_ *http.Client, req *http.Request) (*http.Response, error) { + _, res := testhelpers.MockMakeAuthenticatedRequestWithClientAndID(t, reg, conf, publicRouter.Router, req, cl, id) + return res, nil + }) + }) }) t.Run("description=should recover and invalidate all other sessions if hook is set", func(t *testing.T) { diff --git a/test/e2e/cypress/integration/profiles/recovery/recovery/success.spec.ts b/test/e2e/cypress/integration/profiles/recovery/recovery/success.spec.ts index bbfa92603406..15fd59aed50c 100644 --- a/test/e2e/cypress/integration/profiles/recovery/recovery/success.spec.ts +++ b/test/e2e/cypress/integration/profiles/recovery/recovery/success.spec.ts @@ -98,4 +98,40 @@ context('Account Recovery Success', () => { cy.get('button[value="password"]').click() cy.url().should('eq', 'https://www.ory.sh/') }) + + it('should recover even if already logged into another account', () => { + const app = 'express' as 'express' + + cy.deleteMail() + cy.useConfigProfile('recovery') + cy.proxy(app) + + cy.deleteMail() + cy.disableVerification() + + const identity1 = gen.identityWithWebsite() + cy.registerApi(identity1) + const identity2 = gen.identityWithWebsite() + cy.registerApi(identity2) + + cy.recoverApi({ email: identity2.email }) + + // first log in as identity1 + + cy.visit(express.login) + + cy.get(appPrefix(app) + 'input[name="identifier"]').type(identity1.email) + cy.get('input[name="password"]').type(identity1.password) + cy.get('button[value="password"]').click() + + cy.location('pathname').should('not.contain', '/login') + + // then recover identity2, while still logged in as identity1 + + cy.recoverEmail({ expect: identity2 }) + + cy.getSession() + cy.location('pathname').should('eq', '/settings') + cy.get('input[name="traits.email"]').should('have.value', identity2.email) + }) }) diff --git a/test/e2e/hydra-login-consent/go.mod b/test/e2e/hydra-login-consent/go.mod index fd65ddcf4817..e1008dbd4242 100644 --- a/test/e2e/hydra-login-consent/go.mod +++ b/test/e2e/hydra-login-consent/go.mod @@ -4,6 +4,8 @@ go 1.16 replace github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 +replace golang.org/x/sys => golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 + require ( github.com/julienschmidt/httprouter v1.3.0 github.com/ory/hydra-client-go v1.7.4 diff --git a/test/e2e/hydra-login-consent/go.sum b/test/e2e/hydra-login-consent/go.sum index a573aaf06c78..0890641be4aa 100644 --- a/test/e2e/hydra-login-consent/go.sum +++ b/test/e2e/hydra-login-consent/go.sum @@ -896,56 +896,8 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180927150500-dad3d9fb7b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181011152604-fa43e7bc11ba/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181022134430-8a28ead16f52/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181024145615-5cd93ef61a7c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026064943-731415f00dce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181106135930-3a76605856fd/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= diff --git a/test/e2e/run.sh b/test/e2e/run.sh index ca0d753742ac..6ca202b1966a 100755 --- a/test/e2e/run.sh +++ b/test/e2e/run.sh @@ -189,8 +189,8 @@ prepare() { ( cd test/e2e/hydra-login-consent - go build . && - PORT=4446 HYDRA_ADMIN_URL=http://localhost:4445 ./hydra-login-consent >"${base}/test/e2e/hydra-ui.e2e.log" 2>&1 & + go build . + PORT=4446 HYDRA_ADMIN_URL=http://localhost:4445 ./hydra-login-consent >"${base}/test/e2e/hydra-ui.e2e.log" 2>&1 & ) }