From 5aad1c1e6cc92f72af56511dacb9812edb600813 Mon Sep 17 00:00:00 2001 From: Jonas Hungershausen Date: Tue, 26 Mar 2024 11:11:22 +0100 Subject: [PATCH] fix: execute verification & verification_ui properly in login flows (#3847) --- go.mod | 15 +- go.sum | 27 ++-- internal/client-go/go.sum | 1 - selfservice/flow/login/flow.go | 7 + selfservice/flow/login/hook.go | 3 + selfservice/flow/registration/flow.go | 4 + selfservice/hook/show_verification_ui.go | 26 ++- selfservice/hook/show_verification_ui_test.go | 152 ++++++++++++------ selfservice/hook/verification.go | 2 +- spec/api.json | 2 + spec/swagger.json | 2 + 11 files changed, 167 insertions(+), 74 deletions(-) diff --git a/go.mod b/go.mod index 9d0ec28c0544..655a07bbf9e2 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( github.com/ory/jsonschema/v3 v3.0.8 github.com/ory/mail/v3 v3.0.0 github.com/ory/nosurf v1.2.7 - github.com/ory/x v0.0.619 + github.com/ory/x v0.0.623 github.com/peterhellberg/link v1.2.0 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/errors v0.9.1 @@ -207,13 +207,13 @@ require ( github.com/ian-kent/linkio v0.0.0-20170807205755-97566b872887 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.13.0 // indirect + github.com/jackc/pgconn v1.14.3 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.1 // indirect - github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.12.0 // indirect - github.com/jackc/pgx/v4 v4.17.2 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgtype v1.14.0 // indirect + github.com/jackc/pgx/v4 v4.18.2 // indirect github.com/jandelgado/gcov2lcov v1.0.5 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect @@ -316,7 +316,7 @@ require ( google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -335,7 +335,6 @@ require ( ) require ( - github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect github.com/jackc/puddle/v2 v2.1.2 // indirect github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/segmentio/asm v1.2.0 // indirect diff --git a/go.sum b/go.sum index fc067a3bd5e3..f344856176b4 100644 --- a/go.sum +++ b/go.sum @@ -199,8 +199,6 @@ github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= -github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/go-crypt/crypt v0.2.9 h1:5gWWTId2Qyqs9ROIsegt5pnqo9wUSRLbhpkR6JSftjg= github.com/go-crypt/crypt v0.2.9/go.mod h1:JjzdTYE2mArb6nBoIvvpF7o46/rK/1pfmlArCRMTFUk= github.com/go-crypt/x v0.2.1 h1:OGw78Bswme9lffCOX6tyuC280ouU5391glsvThMtM5U= @@ -555,8 +553,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -572,22 +571,26 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/pgx/v4 v4.18.2 h1:xVpYkNR5pk5bMCZGfClbO962UIqVABcAGt7ha1s/FeU= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -824,10 +827,8 @@ github.com/ory/nosurf v1.2.7 h1:YrHrbSensQyU6r6HT/V5+HPdVEgrOTMJiLoJABSBOp4= github.com/ory/nosurf v1.2.7/go.mod h1:d4L3ZBa7Amv55bqxCBtCs63wSlyaiCkWVl4vKf3OUxA= github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 h1:zm6sDvHy/U9XrGpixwHiuAwpp0Ock6khSVHkrv6lQQU= github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/ory/x v0.0.616 h1:iaojp7MvFW1cdirSZFK/XeuJvyhUEVXQdY61bmIOkzk= -github.com/ory/x v0.0.616/go.mod h1:Fqxxc1Ks6a4vZuqWwr6TYAeUDh2SAvxXyrk9N7Hidbo= -github.com/ory/x v0.0.619 h1:eeK6BVeko0MBg7HERrPOu1B0YRUOu/wLBkWqEdHxYF0= -github.com/ory/x v0.0.619/go.mod h1:Fqxxc1Ks6a4vZuqWwr6TYAeUDh2SAvxXyrk9N7Hidbo= +github.com/ory/x v0.0.623 h1:sFJiw2i/itTkBRJbhGXtrso9NcdscnjFlHBFitCzf8A= +github.com/ory/x v0.0.623/go.mod h1:CUw8/O3X8lUMheyV0iH+6LQ0tePrH+FBsW39MccCHgw= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1545,8 +1546,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= diff --git a/internal/client-go/go.sum b/internal/client-go/go.sum index 6cc3f5911d11..c966c8ddfd0d 100644 --- a/internal/client-go/go.sum +++ b/internal/client-go/go.sum @@ -4,7 +4,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/selfservice/flow/login/flow.go b/selfservice/flow/login/flow.go index 8b1578e912f5..a01d449a2751 100644 --- a/selfservice/flow/login/flow.go +++ b/selfservice/flow/login/flow.go @@ -152,6 +152,9 @@ type Flow struct { // It can, for example, contain a reference to the verification flow, created as part of the user's // registration. ContinueWithItems []flow.ContinueWith `json:"-" db:"-" faker:"-" ` + + // ReturnToVerification contains the redirect URL for the verification flow. + ReturnToVerification string `json:"-" db:"-"` } var _ flow.Flow = new(Flow) @@ -320,3 +323,7 @@ func (f *Flow) AddContinueWith(c flow.ContinueWith) { func (f *Flow) ContinueWith() []flow.ContinueWith { return f.ContinueWithItems } + +func (f *Flow) SetReturnToVerification(to string) { + f.ReturnToVerification = to +} diff --git a/selfservice/flow/login/hook.go b/selfservice/flow/login/hook.go index 595fdbff7936..f0e06ccfc934 100644 --- a/selfservice/flow/login/hook.go +++ b/selfservice/flow/login/hook.go @@ -320,6 +320,9 @@ func (e *HookExecutor) PostLoginHook( } finalReturnTo = rt span.SetAttributes(attribute.String("return_to", rt), attribute.String("redirect_reason", "oauth2 login challenge")) + } else if f.ReturnToVerification != "" { + finalReturnTo = f.ReturnToVerification + span.SetAttributes(attribute.String("redirect_reason", "verification requested")) } x.ContentNegotiationRedirection(w, r, s, e.d.Writer(), finalReturnTo) diff --git a/selfservice/flow/registration/flow.go b/selfservice/flow/registration/flow.go index 2786a03fdc79..17ad0c6d720a 100644 --- a/selfservice/flow/registration/flow.go +++ b/selfservice/flow/registration/flow.go @@ -275,3 +275,7 @@ func (f *Flow) SetState(state State) { func (t *Flow) GetTransientPayload() json.RawMessage { return t.TransientPayload } + +func (f *Flow) SetReturnToVerification(to string) { + f.ReturnToVerification = to +} diff --git a/selfservice/hook/show_verification_ui.go b/selfservice/hook/show_verification_ui.go index 51f29a2aa6ce..566546a028da 100644 --- a/selfservice/hook/show_verification_ui.go +++ b/selfservice/hook/show_verification_ui.go @@ -9,13 +9,18 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/selfservice/flow" + "github.com/ory/kratos/selfservice/flow/login" "github.com/ory/kratos/selfservice/flow/registration" "github.com/ory/kratos/session" + "github.com/ory/kratos/ui/node" "github.com/ory/kratos/x" "github.com/ory/x/otelx" ) -var _ registration.PostHookPostPersistExecutor = new(ShowVerificationUIHook) +var ( + _ registration.PostHookPostPersistExecutor = new(ShowVerificationUIHook) + _ login.PostHookExecutor = new(ShowVerificationUIHook) +) type ( showVerificationUIDependencies interface { @@ -45,7 +50,20 @@ func (e *ShowVerificationUIHook) ExecutePostRegistrationPostPersistHook(_ http.R }) } -func (e *ShowVerificationUIHook) execute(r *http.Request, f *registration.Flow) error { +// ExecutePostRegistrationPostPersistHook adds redirect headers and status code if the request is a browser request. +// If the request is not a browser request, this hook does nothing. +func (e *ShowVerificationUIHook) ExecuteLoginPostHook(_ http.ResponseWriter, r *http.Request, _ node.UiNodeGroup, f *login.Flow, _ *session.Session) error { + return otelx.WithSpan(r.Context(), "selfservice.hook.ShowVerificationUIHook.ExecutePostRegistrationPostPersistHook", func(ctx context.Context) error { + return e.execute(r.WithContext(ctx), f) + }) +} + +type loginOrRegistrationFlow interface { + ContinueWith() []flow.ContinueWith + SetReturnToVerification(string) +} + +func (e *ShowVerificationUIHook) execute(r *http.Request, f loginOrRegistrationFlow) error { if !x.IsBrowserRequest(r) { // this hook is only intended to be used by browsers, as it redirects to the verification ui // JSON API clients should use the `continue_with` field to continue the flow @@ -53,7 +71,7 @@ func (e *ShowVerificationUIHook) execute(r *http.Request, f *registration.Flow) } var vf *flow.ContinueWithVerificationUI - for _, c := range f.ContinueWithItems { + for _, c := range f.ContinueWith() { if item, ok := c.(*flow.ContinueWithVerificationUI); ok { vf = item } @@ -62,7 +80,7 @@ func (e *ShowVerificationUIHook) execute(r *http.Request, f *registration.Flow) ctx := r.Context() if vf != nil { redirURL := e.d.Config().SelfServiceFlowVerificationUI(ctx) - f.ReturnToVerification = vf.AppendTo(redirURL).String() + f.SetReturnToVerification(vf.AppendTo(redirURL).String()) } return nil diff --git a/selfservice/hook/show_verification_ui_test.go b/selfservice/hook/show_verification_ui_test.go index 70e14af11711..22171f0c345b 100644 --- a/selfservice/hook/show_verification_ui_test.go +++ b/selfservice/hook/show_verification_ui_test.go @@ -15,62 +15,120 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/internal" "github.com/ory/kratos/selfservice/flow" + "github.com/ory/kratos/selfservice/flow/login" "github.com/ory/kratos/selfservice/flow/registration" "github.com/ory/kratos/selfservice/flow/verification" "github.com/ory/kratos/selfservice/hook" ) func TestExecutePostRegistrationPostPersistHook(t *testing.T) { - t.Run("case=no continue with items returns 200 OK", func(t *testing.T) { - _, reg := internal.NewVeryFastRegistryWithoutDB(t) - h := hook.NewShowVerificationUIHook(reg) - browserRequest := httptest.NewRequest("GET", "/", nil) - f := ®istration.Flow{} - rec := httptest.NewRecorder() - require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, f, nil)) - require.Equal(t, 200, rec.Code) - }) + t.Run("flow=registration", func(t *testing.T) { + t.Run("case=no continue with items returns 200 OK", func(t *testing.T) { + _, reg := internal.NewVeryFastRegistryWithoutDB(t) + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + f := ®istration.Flow{} + rec := httptest.NewRecorder() + require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, f, nil)) + require.Equal(t, 200, rec.Code) + }) - t.Run("case=not a browser request returns 200 OK", func(t *testing.T) { - _, reg := internal.NewVeryFastRegistryWithoutDB(t) - h := hook.NewShowVerificationUIHook(reg) - browserRequest := httptest.NewRequest("GET", "/", nil) - browserRequest.Header.Add("Accept", "application/json") - f := ®istration.Flow{} - rec := httptest.NewRecorder() - require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, f, nil)) - require.Equal(t, 200, rec.Code) - }) + t.Run("case=not a browser request returns 200 OK", func(t *testing.T) { + _, reg := internal.NewVeryFastRegistryWithoutDB(t) + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + browserRequest.Header.Add("Accept", "application/json") + f := ®istration.Flow{} + rec := httptest.NewRecorder() + require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, f, nil)) + require.Equal(t, 200, rec.Code) + }) + + t.Run("case=verification ui in continue with item returns redirect", func(t *testing.T) { + conf, reg := internal.NewVeryFastRegistryWithoutDB(t) + conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + vf := &verification.Flow{ + ID: uuid.Must(uuid.NewV4()), + } + rf := ®istration.Flow{} + rf.ContinueWithItems = []flow.ContinueWith{ + flow.NewContinueWithVerificationUI(vf, "some@ory.sh", ""), + } + rec := httptest.NewRecorder() + require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, rf, nil)) + assert.Equal(t, 200, rec.Code) + assert.Equal(t, "/verification?flow="+vf.ID.String(), rf.ReturnToVerification) + }) - t.Run("case=verification ui in continue with item returns redirect", func(t *testing.T) { - conf, reg := internal.NewVeryFastRegistryWithoutDB(t) - conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") - h := hook.NewShowVerificationUIHook(reg) - browserRequest := httptest.NewRequest("GET", "/", nil) - vf := &verification.Flow{ - ID: uuid.Must(uuid.NewV4()), - } - rf := ®istration.Flow{} - rf.ContinueWithItems = []flow.ContinueWith{ - flow.NewContinueWithVerificationUI(vf, "some@ory.sh", ""), - } - rec := httptest.NewRecorder() - require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, rf, nil)) - assert.Equal(t, 200, rec.Code) - assert.Equal(t, "/verification?flow="+vf.ID.String(), rf.ReturnToVerification) + t.Run("case=no verification ui in continue with item returns 200 OK", func(t *testing.T) { + conf, reg := internal.NewVeryFastRegistryWithoutDB(t) + conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + rf := ®istration.Flow{} + rf.ContinueWithItems = []flow.ContinueWith{ + flow.NewContinueWithSetToken("token"), + } + rec := httptest.NewRecorder() + require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, rf, nil)) + assert.Equal(t, 200, rec.Code) + }) }) - t.Run("case=no verification ui in continue with item returns 200 OK", func(t *testing.T) { - conf, reg := internal.NewVeryFastRegistryWithoutDB(t) - conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") - h := hook.NewShowVerificationUIHook(reg) - browserRequest := httptest.NewRequest("GET", "/", nil) - rf := ®istration.Flow{} - rf.ContinueWithItems = []flow.ContinueWith{ - flow.NewContinueWithSetToken("token"), - } - rec := httptest.NewRecorder() - require.NoError(t, h.ExecutePostRegistrationPostPersistHook(rec, browserRequest, rf, nil)) - assert.Equal(t, 200, rec.Code) + t.Run("flow=login", func(t *testing.T) { + t.Run("case=no continue with items returns 200 OK", func(t *testing.T) { + _, reg := internal.NewVeryFastRegistryWithoutDB(t) + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + f := &login.Flow{} + rec := httptest.NewRecorder() + require.NoError(t, h.ExecuteLoginPostHook(rec, browserRequest, "", f, nil)) + require.Equal(t, 200, rec.Code) + }) + + t.Run("case=not a browser request returns 200 OK", func(t *testing.T) { + _, reg := internal.NewVeryFastRegistryWithoutDB(t) + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + browserRequest.Header.Add("Accept", "application/json") + f := &login.Flow{} + rec := httptest.NewRecorder() + require.NoError(t, h.ExecuteLoginPostHook(rec, browserRequest, "", f, nil)) + require.Equal(t, 200, rec.Code) + }) + + t.Run("case=verification ui in continue with item returns redirect", func(t *testing.T) { + conf, reg := internal.NewVeryFastRegistryWithoutDB(t) + conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + vf := &verification.Flow{ + ID: uuid.Must(uuid.NewV4()), + } + rf := &login.Flow{} + rf.ContinueWithItems = []flow.ContinueWith{ + flow.NewContinueWithVerificationUI(vf, "some@ory.sh", ""), + } + rec := httptest.NewRecorder() + require.NoError(t, h.ExecuteLoginPostHook(rec, browserRequest, "", rf, nil)) + assert.Equal(t, 200, rec.Code) + assert.Equal(t, "/verification?flow="+vf.ID.String(), rf.ReturnToVerification) + }) + + t.Run("case=no verification ui in continue with item returns 200 OK", func(t *testing.T) { + conf, reg := internal.NewVeryFastRegistryWithoutDB(t) + conf.Set(context.Background(), config.ViperKeySelfServiceVerificationUI, "/verification") + h := hook.NewShowVerificationUIHook(reg) + browserRequest := httptest.NewRequest("GET", "/", nil) + rf := &login.Flow{} + rf.ContinueWithItems = []flow.ContinueWith{ + flow.NewContinueWithSetToken("token"), + } + rec := httptest.NewRecorder() + require.NoError(t, h.ExecuteLoginPostHook(rec, browserRequest, "", rf, nil)) + assert.Equal(t, 200, rec.Code) + }) }) } diff --git a/selfservice/hook/verification.go b/selfservice/hook/verification.go index ef4bf2e3f16a..6fdd039c146f 100644 --- a/selfservice/hook/verification.go +++ b/selfservice/hook/verification.go @@ -94,7 +94,7 @@ func (e *Verifier) do( } isBrowserFlow := f.GetType() == flow.TypeBrowser - isRegistrationOrLoginFlow := f.GetFlowName() == flow.RegistrationFlow + isRegistrationOrLoginFlow := f.GetFlowName() == flow.RegistrationFlow || f.GetFlowName() == flow.LoginFlow for k := range i.VerifiableAddresses { address := &i.VerifiableAddresses[k] diff --git a/spec/api.json b/spec/api.json index 84202310f0a4..76036e26595f 100644 --- a/spec/api.json +++ b/spec/api.json @@ -879,6 +879,7 @@ "type": "object" } }, + "title": "The not ready status of the service.", "type": "object" }, "healthStatus": { @@ -888,6 +889,7 @@ "type": "string" } }, + "title": "The health status of the service.", "type": "object" }, "identity": { diff --git a/spec/swagger.json b/spec/swagger.json index 37a79fc4f6bb..7da943e9f0a8 100755 --- a/spec/swagger.json +++ b/spec/swagger.json @@ -3991,6 +3991,7 @@ }, "healthNotReadyStatus": { "type": "object", + "title": "The not ready status of the service.", "properties": { "errors": { "description": "Errors contains a list of errors that caused the not ready status.", @@ -4003,6 +4004,7 @@ }, "healthStatus": { "type": "object", + "title": "The health status of the service.", "properties": { "status": { "description": "Status always contains \"ok\".",