diff --git a/docs/docs/apis/openidoauth/endpoints.md b/docs/docs/apis/openidoauth/endpoints.md index f05cd78f80..fef1027ab3 100644 --- a/docs/docs/apis/openidoauth/endpoints.md +++ b/docs/docs/apis/openidoauth/endpoints.md @@ -39,7 +39,7 @@ Optional parameters | login_hint | A valid logon name of a user. Will be used for username inputs or preselecting a user on `select_account` | | max_age | Seconds since the last active successful authentication of the user | | nonce | Random string value to associate the client session with the ID Token and for replay attacks mitigation. | -| prompt | If the Auth Server prompts the user for (re)authentication.
no prompt: the user will have to choose a session if more than one session exists
`none`: user must be authenticated without interaction, an error is returned otherwise
`login`: user must reauthenticate / provide a user name
`select_account`: user is prompted to select one of the existing sessions or create a new one | +| prompt | If the Auth Server prompts the user for (re)authentication.
no prompt: the user will have to choose a session if more than one session exists
`none`: user must be authenticated without interaction, an error is returned otherwise
`login`: user must reauthenticate / provide a user name
`select_account`: user is prompted to select one of the existing sessions or create a new one
`create`: the registration form will be displayed to the user directly | | state | Opaque value used to maintain state between the request and the callback. Used for Cross-Site Request Forgery (CSRF) mitigation as well. | Successful Code Response diff --git a/docs/docs/apis/proto/management.md b/docs/docs/apis/proto/management.md index c25c665218..f75bc29ce3 100644 --- a/docs/docs/apis/proto/management.md +++ b/docs/docs/apis/proto/management.md @@ -1794,7 +1794,7 @@ The Following Variables can be used: > **rpc** ResetCustomPasswordResetMessageTextToDefault([ResetCustomPasswordResetMessageTextToDefaultRequest](#resetcustompasswordresetmessagetexttodefaultrequest)) [ResetCustomPasswordResetMessageTextToDefaultResponse](#resetcustompasswordresetmessagetexttodefaultresponse) -Removes the custom init message text of the organisation +Removes the custom password reset message text of the organisation The default text of the IAM will trigger after @@ -1838,7 +1838,7 @@ The Following Variables can be used: > **rpc** ResetCustomVerifyEmailMessageTextToDefault([ResetCustomVerifyEmailMessageTextToDefaultRequest](#resetcustomverifyemailmessagetexttodefaultrequest)) [ResetCustomVerifyEmailMessageTextToDefaultResponse](#resetcustomverifyemailmessagetexttodefaultresponse) -Removes the custom init message text of the organisation +Removes the custom verify email message text of the organisation The default text of the IAM will trigger after @@ -1882,7 +1882,7 @@ The Following Variables can be used: > **rpc** ResetCustomVerifyPhoneMessageTextToDefault([ResetCustomVerifyPhoneMessageTextToDefaultRequest](#resetcustomverifyphonemessagetexttodefaultrequest)) [ResetCustomVerifyPhoneMessageTextToDefaultResponse](#resetcustomverifyphonemessagetexttodefaultresponse) -Removes the custom init message text of the organisation +Removes the custom verify phone text of the organisation The default text of the IAM will trigger after diff --git a/internal/api/oidc/auth_request_converter.go b/internal/api/oidc/auth_request_converter.go index 73756500b2..66b548e202 100644 --- a/internal/api/oidc/auth_request_converter.go +++ b/internal/api/oidc/auth_request_converter.go @@ -171,6 +171,8 @@ func PromptToBusiness(prompt oidc.Prompt) domain.Prompt { return domain.PromptConsent case oidc.PromptSelectAccount: return domain.PromptSelectAccount + case "create": //this prompt is not final yet, so not implemented in oidc lib + return domain.PromptCreate default: return domain.PromptUnspecified } diff --git a/internal/auth/repository/eventsourcing/eventstore/auth_request.go b/internal/auth/repository/eventsourcing/eventstore/auth_request.go index dd13381140..3899208944 100644 --- a/internal/auth/repository/eventsourcing/eventstore/auth_request.go +++ b/internal/auth/repository/eventsourcing/eventstore/auth_request.go @@ -532,6 +532,9 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *domain.Auth return steps, nil } steps = append(steps, new(domain.LoginStep)) + if request.Prompt == domain.PromptCreate { + return append(steps, &domain.RegistrationStep{}), nil + } if request.Prompt == domain.PromptSelectAccount || request.Prompt == domain.PromptUnspecified { users, err := repo.usersForUserSelection(request) if err != nil { diff --git a/internal/domain/auth_request.go b/internal/domain/auth_request.go index b57448850c..8aa9d9a62e 100644 --- a/internal/domain/auth_request.go +++ b/internal/domain/auth_request.go @@ -72,6 +72,7 @@ const ( PromptLogin PromptConsent PromptSelectAccount + PromptCreate ) type LevelOfAssurance int diff --git a/internal/domain/next_step.go b/internal/domain/next_step.go index 50b62de6ba..6e812e7ac6 100644 --- a/internal/domain/next_step.go +++ b/internal/domain/next_step.go @@ -24,6 +24,7 @@ const ( NextStepExternalLogin NextStepGrantRequired NextStepPasswordless + NextStepRegistration ) type LoginStep struct{} @@ -32,6 +33,12 @@ func (s *LoginStep) Type() NextStepType { return NextStepLogin } +type RegistrationStep struct{} + +func (s *RegistrationStep) Type() NextStepType { + return NextStepRegistration +} + type SelectUserStep struct { Users []UserSelection } diff --git a/internal/ui/login/handler/register_handler.go b/internal/ui/login/handler/register_handler.go index a686aceedd..ba7d98bdd8 100644 --- a/internal/ui/login/handler/register_handler.go +++ b/internal/ui/login/handler/register_handler.go @@ -3,10 +3,10 @@ package handler import ( "net/http" - "github.com/caos/zitadel/internal/domain" - "golang.org/x/text/language" + http_mw "github.com/caos/zitadel/internal/api/http/middleware" + "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" ) @@ -82,7 +82,12 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, l.zitadelURL, http.StatusFound) return } - authRequest.LoginName = user.PreferredLoginName + userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) + err = l.authRepo.SelectUser(r.Context(), authRequest.ID, user.AggregateID, userAgentID) + if err != nil { + l.renderRegister(w, r, authRequest, data, err) + return + } l.renderNextStep(w, r, authRequest) } diff --git a/internal/ui/login/handler/renderer.go b/internal/ui/login/handler/renderer.go index 98559036ca..1db5a1e513 100644 --- a/internal/ui/login/handler/renderer.go +++ b/internal/ui/login/handler/renderer.go @@ -8,18 +8,17 @@ import ( "path" "strings" - "github.com/caos/zitadel/internal/domain" - "github.com/caos/zitadel/internal/static" - "github.com/caos/logging" "github.com/gorilla/csrf" "golang.org/x/text/language" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/auth_request/model" + "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/renderer" + "github.com/caos/zitadel/internal/static" ) const ( @@ -238,6 +237,8 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq * return } l.renderLogin(w, r, authReq, err) + case *domain.RegistrationStep: + l.renderRegisterOption(w, r, authReq, nil) case *domain.SelectUserStep: l.renderUserSelection(w, r, authReq, step) case *domain.InitPasswordStep: diff --git a/internal/ui/login/static/templates/register_option.html b/internal/ui/login/static/templates/register_option.html index 2dcaef10a4..700f50a8b5 100644 --- a/internal/ui/login/static/templates/register_option.html +++ b/internal/ui/login/static/templates/register_option.html @@ -22,9 +22,8 @@ formnovalidate>{{t "RegisterOption.RegisterUsernamePassword"}} {{end}} -

{{t "Registration.ExternalLogin"}}

- - {{if .LoginPolicy.AllowExternalIDP}} + {{if hasExternalLogin}} +

{{t "Registration.ExternalLogin"}}

{{ $reqid := .AuthReqID}} {{range $provider := .IDPProviders}}