fix: tos on external registration (#2164)

* faet: add tos checkbox to external login

* fix: add tos to external not found option

* fix: add tos to external not found option

* fix: show register external user overview

* fix: no init user mail on external register

* fix: custom login text

* add missing custom text tests on org

* add missing custom text tests on iam

* fix: custom login text external registration overview tests

* fix: back button on registration overview

* fix: add texts, change register form

* fix: external not found html

* fix: remove form validation

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi 2021-08-11 13:50:03 +02:00 committed by GitHub
parent 87fa6e58fb
commit b104011418
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 3412 additions and 164 deletions

View File

@ -2437,6 +2437,7 @@ This is an empty request
| passwordless_prompt_text | zitadel.text.v1.PasswordlessPromptScreenText | - | |
| passwordless_registration_text | zitadel.text.v1.PasswordlessRegistrationScreenText | - | |
| passwordless_registration_done_text | zitadel.text.v1.PasswordlessRegistrationDoneScreenText | - | |
| external_registration_user_overview_text | zitadel.text.v1.ExternalRegistrationUserOverviewScreenText | - | |

View File

@ -6756,6 +6756,7 @@ This is an empty request
| passwordless_prompt_text | zitadel.text.v1.PasswordlessPromptScreenText | - | |
| passwordless_registration_text | zitadel.text.v1.PasswordlessRegistrationScreenText | - | |
| passwordless_registration_done_text | zitadel.text.v1.PasswordlessRegistrationDoneScreenText | - | |
| external_registration_user_overview_text | zitadel.text.v1.ExternalRegistrationUserOverviewScreenText | - | |

View File

@ -131,6 +131,7 @@ func SetLoginTextToDomain(req *admin_pb.SetCustomLoginTextsRequest) *domain.Cust
result.PasswordResetDone = text.PasswordResetDoneScreenTextPbToDomain(req.PasswordResetDoneText)
result.RegisterOption = text.RegistrationOptionScreenTextPbToDomain(req.RegistrationOptionText)
result.RegistrationUser = text.RegistrationUserScreenTextPbToDomain(req.RegistrationUserText)
result.ExternalRegistrationUserOverview = text.ExternalRegistrationUserOverviewScreenTextPbToDomain(req.ExternalRegistrationUserOverviewText)
result.RegistrationOrg = text.RegistrationOrgScreenTextPbToDomain(req.RegistrationOrgText)
result.LinkingUsersDone = text.LinkingUserDoneScreenTextPbToDomain(req.LinkingUserDoneText)
result.ExternalNotFoundOption = text.ExternalUserNotFoundScreenTextPbToDomain(req.ExternalUserNotFoundText)

View File

@ -129,6 +129,7 @@ func SetLoginCustomTextToDomain(req *mgmt_pb.SetCustomLoginTextsRequest) *domain
result.PasswordResetDone = text.PasswordResetDoneScreenTextPbToDomain(req.PasswordResetDoneText)
result.RegisterOption = text.RegistrationOptionScreenTextPbToDomain(req.RegistrationOptionText)
result.RegistrationUser = text.RegistrationUserScreenTextPbToDomain(req.RegistrationUserText)
result.ExternalRegistrationUserOverview = text.ExternalRegistrationUserOverviewScreenTextPbToDomain(req.ExternalRegistrationUserOverviewText)
result.RegistrationOrg = text.RegistrationOrgScreenTextPbToDomain(req.RegistrationOrgText)
result.LinkingUsersDone = text.LinkingUserDoneScreenTextPbToDomain(req.LinkingUserDoneText)
result.ExternalNotFoundOption = text.ExternalUserNotFoundScreenTextPbToDomain(req.ExternalUserNotFoundText)

View File

@ -32,39 +32,40 @@ func CustomLoginTextToPb(text *domain.CustomLoginText) *text_pb.LoginCustomText
text.ChangeDate,
text.AggregateID,
),
SelectAccountText: SelectAccountScreenToPb(text.SelectAccount),
LoginText: LoginScreenTextToPb(text.Login),
PasswordText: PasswordScreenTextToPb(text.Password),
UsernameChangeText: UsernameChangeScreenTextToPb(text.UsernameChange),
UsernameChangeDoneText: UsernameChangeDoneScreenTextToPb(text.UsernameChangeDone),
InitPasswordText: InitPasswordScreenTextToPb(text.InitPassword),
InitPasswordDoneText: InitPasswordDoneScreenTextToPb(text.InitPasswordDone),
EmailVerificationText: EmailVerificationScreenTextToPb(text.EmailVerification),
EmailVerificationDoneText: EmailVerificationDoneScreenTextToPb(text.EmailVerificationDone),
InitializeUserText: InitializeUserScreenTextToPb(text.InitUser),
InitializeDoneText: InitializeUserDoneScreenTextToPb(text.InitUserDone),
InitMfaPromptText: InitMFAPromptScreenTextToPb(text.InitMFAPrompt),
InitMfaOtpText: InitMFAOTPScreenTextToPb(text.InitMFAOTP),
InitMfaU2FText: InitMFAU2FScreenTextToPb(text.InitMFAU2F),
InitMfaDoneText: InitMFADoneScreenTextToPb(text.InitMFADone),
MfaProvidersText: MFAProvidersTextToPb(text.MFAProvider),
VerifyMfaOtpText: VerifyMFAOTPScreenTextToPb(text.VerifyMFAOTP),
VerifyMfaU2FText: VerifyMFAU2FScreenTextToPb(text.VerifyMFAU2F),
PasswordlessText: PasswordlessScreenTextToPb(text.Passwordless),
PasswordlessPromptText: PasswordlessPromptScreenTextToPb(text.PasswordlessPrompt),
PasswordlessRegistrationText: PasswordlessRegistrationScreenTextToPb(text.PasswordlessRegistration),
PasswordlessRegistrationDoneText: PasswordlessRegistrationDoneScreenTextToPb(text.PasswordlessRegistrationDone),
PasswordChangeText: PasswordChangeScreenTextToPb(text.PasswordChange),
PasswordChangeDoneText: PasswordChangeDoneScreenTextToPb(text.PasswordChangeDone),
PasswordResetDoneText: PasswordResetDoneScreenTextToPb(text.PasswordResetDone),
RegistrationOptionText: RegistrationOptionScreenTextToPb(text.RegisterOption),
RegistrationUserText: RegistrationUserScreenTextToPb(text.RegistrationUser),
RegistrationOrgText: RegistrationOrgScreenTextToPb(text.RegistrationOrg),
LinkingUserDoneText: LinkingUserDoneScreenTextToPb(text.LinkingUsersDone),
ExternalUserNotFoundText: ExternalUserNotFoundScreenTextToPb(text.ExternalNotFoundOption),
SuccessLoginText: SuccessLoginScreenTextToPb(text.LoginSuccess),
LogoutText: LogoutDoneScreenTextToPb(text.LogoutDone),
FooterText: FooterTextToPb(text.Footer),
SelectAccountText: SelectAccountScreenToPb(text.SelectAccount),
LoginText: LoginScreenTextToPb(text.Login),
PasswordText: PasswordScreenTextToPb(text.Password),
UsernameChangeText: UsernameChangeScreenTextToPb(text.UsernameChange),
UsernameChangeDoneText: UsernameChangeDoneScreenTextToPb(text.UsernameChangeDone),
InitPasswordText: InitPasswordScreenTextToPb(text.InitPassword),
InitPasswordDoneText: InitPasswordDoneScreenTextToPb(text.InitPasswordDone),
EmailVerificationText: EmailVerificationScreenTextToPb(text.EmailVerification),
EmailVerificationDoneText: EmailVerificationDoneScreenTextToPb(text.EmailVerificationDone),
InitializeUserText: InitializeUserScreenTextToPb(text.InitUser),
InitializeDoneText: InitializeUserDoneScreenTextToPb(text.InitUserDone),
InitMfaPromptText: InitMFAPromptScreenTextToPb(text.InitMFAPrompt),
InitMfaOtpText: InitMFAOTPScreenTextToPb(text.InitMFAOTP),
InitMfaU2FText: InitMFAU2FScreenTextToPb(text.InitMFAU2F),
InitMfaDoneText: InitMFADoneScreenTextToPb(text.InitMFADone),
MfaProvidersText: MFAProvidersTextToPb(text.MFAProvider),
VerifyMfaOtpText: VerifyMFAOTPScreenTextToPb(text.VerifyMFAOTP),
VerifyMfaU2FText: VerifyMFAU2FScreenTextToPb(text.VerifyMFAU2F),
PasswordlessText: PasswordlessScreenTextToPb(text.Passwordless),
PasswordlessPromptText: PasswordlessPromptScreenTextToPb(text.PasswordlessPrompt),
PasswordlessRegistrationText: PasswordlessRegistrationScreenTextToPb(text.PasswordlessRegistration),
PasswordlessRegistrationDoneText: PasswordlessRegistrationDoneScreenTextToPb(text.PasswordlessRegistrationDone),
PasswordChangeText: PasswordChangeScreenTextToPb(text.PasswordChange),
PasswordChangeDoneText: PasswordChangeDoneScreenTextToPb(text.PasswordChangeDone),
PasswordResetDoneText: PasswordResetDoneScreenTextToPb(text.PasswordResetDone),
RegistrationOptionText: RegistrationOptionScreenTextToPb(text.RegisterOption),
RegistrationUserText: RegistrationUserScreenTextToPb(text.RegistrationUser),
ExternalRegistrationUserOverviewText: ExternalRegistrationUserOverviewScreenTextToPb(text.ExternalRegistrationUserOverview),
RegistrationOrgText: RegistrationOrgScreenTextToPb(text.RegistrationOrg),
LinkingUserDoneText: LinkingUserDoneScreenTextToPb(text.LinkingUsersDone),
ExternalUserNotFoundText: ExternalUserNotFoundScreenTextToPb(text.ExternalNotFoundOption),
SuccessLoginText: SuccessLoginScreenTextToPb(text.LoginSuccess),
LogoutText: LogoutDoneScreenTextToPb(text.LogoutDone),
FooterText: FooterTextToPb(text.Footer),
}
}
@ -299,9 +300,10 @@ func PasswordlessRegistrationScreenTextToPb(text domain.PasswordlessRegistration
func PasswordlessRegistrationDoneScreenTextToPb(text domain.PasswordlessRegistrationDoneScreenText) *text_pb.PasswordlessRegistrationDoneScreenText {
return &text_pb.PasswordlessRegistrationDoneScreenText{
Title: text.Title,
Description: text.Description,
NextButtonText: text.NextButtonText,
Title: text.Title,
Description: text.Description,
NextButtonText: text.NextButtonText,
CancelButtonText: text.CancelButtonText,
}
}
@ -365,6 +367,27 @@ func RegistrationUserScreenTextToPb(text domain.RegistrationUserScreenText) *tex
}
}
func ExternalRegistrationUserOverviewScreenTextToPb(text domain.ExternalRegistrationUserOverviewScreenText) *text_pb.ExternalRegistrationUserOverviewScreenText {
return &text_pb.ExternalRegistrationUserOverviewScreenText{
Title: text.Title,
Description: text.Description,
EmailLabel: text.EmailLabel,
UsernameLabel: text.UsernameLabel,
FirstnameLabel: text.FirstnameLabel,
LastnameLabel: text.LastnameLabel,
NicknameLabel: text.NicknameLabel,
LanguageLabel: text.LanguageLabel,
PhoneLabel: text.PhoneLabel,
TosAndPrivacyLabel: text.TOSAndPrivacyLabel,
TosConfirm: text.TOSConfirm,
TosLinkText: text.TOSLinkText,
TosConfirmAnd: text.TOSConfirmAnd,
PrivacyLinkText: text.PrivacyLinkText,
NextButtonText: text.NextButtonText,
BackButtonText: text.BackButtonText,
}
}
func RegistrationOrgScreenTextToPb(text domain.RegistrationOrgScreenText) *text_pb.RegistrationOrgScreenText {
return &text_pb.RegistrationOrgScreenText{
Title: text.Title,
@ -400,6 +423,11 @@ func ExternalUserNotFoundScreenTextToPb(text domain.ExternalUserNotFoundScreenTe
Description: text.Description,
LinkButtonText: text.LinkButtonText,
AutoRegisterButtonText: text.AutoRegisterButtonText,
TosAndPrivacyLabel: text.TOSAndPrivacyLabel,
TosConfirm: text.TOSConfirm,
TosLinkText: text.PrivacyLinkText,
TosConfirmAnd: text.TOSConfirmAnd,
PrivacyLinkText: text.PrivacyLinkText,
}
}
@ -807,6 +835,30 @@ func RegistrationUserScreenTextPbToDomain(text *text_pb.RegistrationUserScreenTe
}
}
func ExternalRegistrationUserOverviewScreenTextPbToDomain(text *text_pb.ExternalRegistrationUserOverviewScreenText) domain.ExternalRegistrationUserOverviewScreenText {
if text == nil {
return domain.ExternalRegistrationUserOverviewScreenText{}
}
return domain.ExternalRegistrationUserOverviewScreenText{
Title: text.Title,
Description: text.Description,
EmailLabel: text.EmailLabel,
UsernameLabel: text.UsernameLabel,
FirstnameLabel: text.FirstnameLabel,
LastnameLabel: text.LastnameLabel,
NicknameLabel: text.NicknameLabel,
LanguageLabel: text.LanguageLabel,
PhoneLabel: text.PhoneLabel,
TOSAndPrivacyLabel: text.TosAndPrivacyLabel,
TOSConfirm: text.TosConfirm,
TOSLinkText: text.TosLinkText,
TOSConfirmAnd: text.TosConfirmAnd,
PrivacyLinkText: text.PrivacyLinkText,
NextButtonText: text.NextButtonText,
BackButtonText: text.BackButtonText,
}
}
func RegistrationOrgScreenTextPbToDomain(text *text_pb.RegistrationOrgScreenText) domain.RegistrationOrgScreenText {
if text == nil {
return domain.RegistrationOrgScreenText{}
@ -851,6 +903,11 @@ func ExternalUserNotFoundScreenTextPbToDomain(text *text_pb.ExternalUserNotFound
Description: text.Description,
LinkButtonText: text.LinkButtonText,
AutoRegisterButtonText: text.AutoRegisterButtonText,
TOSAndPrivacyLabel: text.TosAndPrivacyLabel,
TOSConfirm: text.TosConfirm,
TOSLinkText: text.PrivacyLinkText,
TOSConfirmAnd: text.TosConfirmAnd,
PrivacyLinkText: text.PrivacyLinkText,
}
}

View File

@ -15,6 +15,7 @@ type AuthRequestRepository interface {
CheckLoginName(ctx context.Context, id, loginName, userAgentID string) error
CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser, info *domain.BrowserInfo) error
SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser) error
SelectUser(ctx context.Context, id, userID, userAgentID string) error
SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID string) error
VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID string, info *domain.BrowserInfo) error

View File

@ -233,6 +233,21 @@ func (repo *AuthRequestRepo) CheckExternalUserLogin(ctx context.Context, authReq
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
}
func (repo *AuthRequestRepo) SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, externalUser *domain.ExternalUser) (err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
request, err := repo.getAuthRequest(ctx, authReqID, userAgentID)
if err != nil {
return err
}
err = repo.setLinkingUser(ctx, request, externalUser)
if err != nil {
return err
}
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
}
func (repo *AuthRequestRepo) setLinkingUser(ctx context.Context, request *domain.AuthRequest, externalUser *domain.ExternalUser) error {
request.LinkingUsers = append(request.LinkingUsers, externalUser)
return repo.AuthRequests.UpdateAuthRequest(ctx, request)

View File

@ -40,6 +40,7 @@ func (c *Commands) createAllLoginTextEvents(ctx context.Context, agg *eventstore
events = append(events, c.createPasswordResetDoneEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createRegistrationOptionEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createRegistrationUserEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createExternalRegistrationUserOverviewEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createRegistrationOrgEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createLinkingUserEvents(ctx, agg, existingText, text, defaultText)...)
events = append(events, c.createExternalUserNotFoundEvents(ctx, agg, existingText, text, defaultText)...)
@ -664,6 +665,10 @@ func (c *Commands) createPasswordlessRegistrationDoneEvents(ctx context.Context,
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyPasswordlessRegistrationDoneCancelButtonText, existingText.PasswordlessRegistrationDoneCancelButtonText, text.PasswordlessRegistrationDone.CancelButtonText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
return events
}
@ -832,6 +837,75 @@ func (c *Commands) createRegistrationUserEvents(ctx context.Context, agg *events
return events
}
func (c *Commands) createExternalRegistrationUserOverviewEvents(ctx context.Context, agg *eventstore.Aggregate, existingText *CustomLoginTextReadModel, text *domain.CustomLoginText, defaultText bool) []eventstore.EventPusher {
events := make([]eventstore.EventPusher, 0)
event := c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewTitle, existingText.ExternalRegistrationUserOverviewTitle, text.ExternalRegistrationUserOverview.Title, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewDescription, existingText.ExternalRegistrationUserOverviewDescription, text.ExternalRegistrationUserOverview.Description, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewEmailLabel, existingText.ExternalRegistrationUserOverviewEmailLabel, text.ExternalRegistrationUserOverview.EmailLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewUsernameLabel, existingText.ExternalRegistrationUserOverviewUsernameLabel, text.ExternalRegistrationUserOverview.UsernameLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewFirstnameLabel, existingText.ExternalRegistrationUserOverviewFirstnameLabel, text.ExternalRegistrationUserOverview.FirstnameLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewLastnameLabel, existingText.ExternalRegistrationUserOverviewLastnameLabel, text.ExternalRegistrationUserOverview.LastnameLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewNicknameLabel, existingText.ExternalRegistrationUserOverviewNicknameLabel, text.ExternalRegistrationUserOverview.NicknameLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewLanguageLabel, existingText.ExternalRegistrationUserOverviewLanguageLabel, text.ExternalRegistrationUserOverview.LanguageLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewPhoneLabel, existingText.ExternalRegistrationUserOverviewPhoneLabel, text.ExternalRegistrationUserOverview.PhoneLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewTOSAndPrivacyLabel, existingText.ExternalRegistrationUserOverviewTOSAndPrivacyLabel, text.ExternalRegistrationUserOverview.TOSAndPrivacyLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewTOSConfirm, existingText.ExternalRegistrationUserOverviewTOSConfirm, text.ExternalRegistrationUserOverview.TOSConfirm, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewTOSLinkText, existingText.ExternalRegistrationUserOverviewTOSLinkText, text.ExternalRegistrationUserOverview.TOSLinkText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewTOSConfirmAnd, existingText.ExternalRegistrationUserOverviewTOSConfirmAnd, text.ExternalRegistrationUserOverview.TOSConfirmAnd, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewPrivacyLinkText, existingText.ExternalRegistrationUserOverviewPrivacyLinkText, text.ExternalRegistrationUserOverview.PrivacyLinkText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewBackButtonText, existingText.ExternalRegistrationUserOverviewBackButtonText, text.ExternalRegistrationUserOverview.BackButtonText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalRegistrationUserOverviewNextButtonText, existingText.ExternalRegistrationUserOverviewNextButtonText, text.ExternalRegistrationUserOverview.NextButtonText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
return events
}
func (c *Commands) createRegistrationOrgEvents(ctx context.Context, agg *eventstore.Aggregate, existingText *CustomLoginTextReadModel, text *domain.CustomLoginText, defaultText bool) []eventstore.EventPusher {
events := make([]eventstore.EventPusher, 0)
event := c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyRegisterOrgTitle, existingText.RegisterOrgTitle, text.RegistrationOrg.Title, text.Language, defaultText)
@ -936,6 +1010,26 @@ func (c *Commands) createExternalUserNotFoundEvents(ctx context.Context, agg *ev
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalNotFoundTOSAndPrivacyLabel, existingText.ExternalUserNotFoundTOSAndPrivacyLabel, text.ExternalNotFoundOption.TOSAndPrivacyLabel, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalNotFoundTOSConfirm, existingText.ExternalUserNotFoundTOSConfirm, text.ExternalNotFoundOption.TOSConfirm, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalNotFoundTOSLinkText, existingText.ExternalUserNotFoundTOSLinkText, text.ExternalNotFoundOption.TOSLinkText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalNotFoundTOSConfirmAnd, existingText.ExternalUserNotFoundTOSConfirmAnd, text.ExternalNotFoundOption.TOSConfirmAnd, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyExternalNotFoundPrivacyLinkText, existingText.ExternalUserNotFoundPrivacyLinkText, text.ExternalNotFoundOption.PrivacyLinkText, text.Language, defaultText)
if event != nil {
events = append(events, event)
}
return events
}

View File

@ -161,9 +161,10 @@ type CustomLoginTextReadModel struct {
PasswordlessRegistrationNotSupported string
PasswordlessRegistrationErrorRetry string
PasswordlessRegistrationDoneTitle string
PasswordlessRegistrationDoneDescription string
PasswordlessRegistrationDoneNextButtonText string
PasswordlessRegistrationDoneTitle string
PasswordlessRegistrationDoneDescription string
PasswordlessRegistrationDoneNextButtonText string
PasswordlessRegistrationDoneCancelButtonText string
PasswordChangeTitle string
PasswordChangeDescription string
@ -207,6 +208,25 @@ type CustomLoginTextReadModel struct {
RegistrationUserNextButtonText string
RegistrationUserBackButtonText string
ExternalRegistrationUserOverviewTitle string
ExternalRegistrationUserOverviewDescription string
ExternalRegistrationUserOverviewEmailLabel string
ExternalRegistrationUserOverviewUsernameLabel string
ExternalRegistrationUserOverviewFirstnameLabel string
ExternalRegistrationUserOverviewLastnameLabel string
ExternalRegistrationUserOverviewNicknameLabel string
ExternalRegistrationUserOverviewLanguageLabel string
ExternalRegistrationUserOverviewPhoneLabel string
ExternalRegistrationUserOverviewTOSAndPrivacyLabel string
ExternalRegistrationUserOverviewTOSConfirm string
ExternalRegistrationUserOverviewTOSLink string
ExternalRegistrationUserOverviewTOSLinkText string
ExternalRegistrationUserOverviewTOSConfirmAnd string
ExternalRegistrationUserOverviewPrivacyLink string
ExternalRegistrationUserOverviewPrivacyLinkText string
ExternalRegistrationUserOverviewBackButtonText string
ExternalRegistrationUserOverviewNextButtonText string
RegisterOrgTitle string
RegisterOrgDescription string
RegisterOrgOrgNameLabel string
@ -232,6 +252,11 @@ type CustomLoginTextReadModel struct {
ExternalUserNotFoundDescription string
ExternalUserNotFoundLinkButtonText string
ExternalUserNotFoundAutoRegisterButtonText string
ExternalUserNotFoundTOSAndPrivacyLabel string
ExternalUserNotFoundTOSConfirm string
ExternalUserNotFoundTOSLinkText string
ExternalUserNotFoundTOSConfirmAnd string
ExternalUserNotFoundPrivacyLinkText string
SuccessLoginTitle string
SuccessLoginAutoRedirectDescription string
@ -364,6 +389,10 @@ func (wm *CustomLoginTextReadModel) Reduce() error {
wm.handleRegistrationUserScreenSetEvent(e)
continue
}
if strings.HasPrefix(e.Key, domain.LoginKeyExternalRegistrationUserOverview) {
wm.handleExternalRegistrationUserOverviewScreenSetEvent(e)
continue
}
if strings.HasPrefix(e.Key, domain.LoginKeyRegistrationOrg) {
wm.handleRegistrationOrgScreenSetEvent(e)
continue
@ -500,6 +529,10 @@ func (wm *CustomLoginTextReadModel) Reduce() error {
wm.handleRegistrationUserScreenRemoveEvent(e)
continue
}
if strings.HasPrefix(e.Key, domain.LoginKeyExternalRegistrationUserOverview) {
wm.handleExternalRegistrationUserOverviewScreenRemoveEvent(e)
continue
}
if strings.HasPrefix(e.Key, domain.LoginKeyRegistrationOrg) {
wm.handleRegistrationOrgScreenRemoveEvent(e)
continue
@ -1652,6 +1685,10 @@ func (wm *CustomLoginTextReadModel) handlePasswordlessRegistrationDoneScreenSetE
wm.PasswordlessRegistrationDoneNextButtonText = e.Text
return
}
if e.Key == domain.LoginKeyPasswordlessRegistrationDoneCancelButtonText {
wm.PasswordlessRegistrationDoneCancelButtonText = e.Text
return
}
}
func (wm *CustomLoginTextReadModel) handlePasswordlessRegistrationDoneScreenRemoveEvent(e *policy.CustomTextRemovedEvent) {
@ -1667,6 +1704,10 @@ func (wm *CustomLoginTextReadModel) handlePasswordlessRegistrationDoneScreenRemo
wm.PasswordlessRegistrationDoneNextButtonText = ""
return
}
if e.Key == domain.LoginKeyPasswordlessRegistrationDoneCancelButtonText {
wm.PasswordlessRegistrationDoneCancelButtonText = ""
return
}
}
func (wm *CustomLoginTextReadModel) handlePasswordChangeScreenSetEvent(e *policy.CustomTextSetEvent) {
@ -1904,6 +1945,73 @@ func (wm *CustomLoginTextReadModel) handleRegistrationUserScreenSetEvent(e *poli
}
}
func (wm *CustomLoginTextReadModel) handleExternalRegistrationUserOverviewScreenSetEvent(e *policy.CustomTextSetEvent) {
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTitle {
wm.ExternalRegistrationUserOverviewTitle = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewDescription {
wm.ExternalRegistrationUserOverviewDescription = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewEmailLabel {
wm.ExternalRegistrationUserOverviewEmailLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewUsernameLabel {
wm.ExternalRegistrationUserOverviewUsernameLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewFirstnameLabel {
wm.ExternalRegistrationUserOverviewFirstnameLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewLastnameLabel {
wm.ExternalRegistrationUserOverviewLastnameLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewNicknameLabel {
wm.ExternalRegistrationUserOverviewNicknameLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewLanguageLabel {
wm.ExternalRegistrationUserOverviewLanguageLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewPhoneLabel {
wm.ExternalRegistrationUserOverviewPhoneLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSAndPrivacyLabel {
wm.ExternalRegistrationUserOverviewTOSAndPrivacyLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSConfirm {
wm.ExternalRegistrationUserOverviewTOSConfirm = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSLinkText {
wm.ExternalRegistrationUserOverviewTOSLinkText = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSConfirmAnd {
wm.ExternalRegistrationUserOverviewTOSConfirmAnd = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewPrivacyLinkText {
wm.ExternalRegistrationUserOverviewPrivacyLinkText = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewBackButtonText {
wm.ExternalRegistrationUserOverviewBackButtonText = e.Text
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewNextButtonText {
wm.ExternalRegistrationUserOverviewNextButtonText = e.Text
return
}
}
func (wm *CustomLoginTextReadModel) handleRegistrationUserScreenRemoveEvent(e *policy.CustomTextRemovedEvent) {
if e.Key == domain.LoginKeyRegistrationUserTitle {
wm.RegistrationUserTitle = ""
@ -1979,6 +2087,73 @@ func (wm *CustomLoginTextReadModel) handleRegistrationUserScreenRemoveEvent(e *p
}
}
func (wm *CustomLoginTextReadModel) handleExternalRegistrationUserOverviewScreenRemoveEvent(e *policy.CustomTextRemovedEvent) {
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTitle {
wm.ExternalRegistrationUserOverviewTitle = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewDescription {
wm.ExternalRegistrationUserOverviewDescription = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewEmailLabel {
wm.ExternalRegistrationUserOverviewEmailLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewUsernameLabel {
wm.ExternalRegistrationUserOverviewUsernameLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewFirstnameLabel {
wm.ExternalRegistrationUserOverviewFirstnameLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewLastnameLabel {
wm.ExternalRegistrationUserOverviewLastnameLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewNicknameLabel {
wm.ExternalRegistrationUserOverviewNicknameLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewLanguageLabel {
wm.ExternalRegistrationUserOverviewLanguageLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewPhoneLabel {
wm.ExternalRegistrationUserOverviewPhoneLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSAndPrivacyLabel {
wm.ExternalRegistrationUserOverviewTOSAndPrivacyLabel = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSConfirm {
wm.ExternalRegistrationUserOverviewTOSConfirm = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSLinkText {
wm.ExternalRegistrationUserOverviewTOSLinkText = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewTOSConfirmAnd {
wm.ExternalRegistrationUserOverviewTOSConfirmAnd = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewPrivacyLinkText {
wm.ExternalRegistrationUserOverviewPrivacyLinkText = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewBackButtonText {
wm.ExternalRegistrationUserOverviewBackButtonText = ""
return
}
if e.Key == domain.LoginKeyExternalRegistrationUserOverviewNextButtonText {
wm.ExternalRegistrationUserOverviewNextButtonText = ""
return
}
}
func (wm *CustomLoginTextReadModel) handleRegistrationOrgScreenSetEvent(e *policy.CustomTextSetEvent) {
if e.Key == domain.LoginKeyRegisterOrgTitle {
wm.RegisterOrgTitle = e.Text
@ -2160,6 +2335,26 @@ func (wm *CustomLoginTextReadModel) handleExternalUserNotFoundScreenSetEvent(e *
wm.ExternalUserNotFoundAutoRegisterButtonText = e.Text
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSAndPrivacyLabel {
wm.ExternalUserNotFoundTOSAndPrivacyLabel = e.Text
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSConfirm {
wm.ExternalUserNotFoundTOSConfirm = e.Text
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSLinkText {
wm.ExternalUserNotFoundTOSLinkText = e.Text
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSConfirmAnd {
wm.ExternalUserNotFoundTOSConfirmAnd = e.Text
return
}
if e.Key == domain.LoginKeyExternalNotFoundPrivacyLinkText {
wm.ExternalUserNotFoundPrivacyLinkText = e.Text
return
}
}
func (wm *CustomLoginTextReadModel) handleExternalUserNotFoundScreenRemoveEvent(e *policy.CustomTextRemovedEvent) {
@ -2179,6 +2374,26 @@ func (wm *CustomLoginTextReadModel) handleExternalUserNotFoundScreenRemoveEvent(
wm.ExternalUserNotFoundAutoRegisterButtonText = ""
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSAndPrivacyLabel {
wm.ExternalUserNotFoundTOSAndPrivacyLabel = ""
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSLinkText {
wm.ExternalUserNotFoundTOSLinkText = ""
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSConfirm {
wm.ExternalUserNotFoundTOSConfirm = ""
return
}
if e.Key == domain.LoginKeyExternalNotFoundTOSConfirmAnd {
wm.ExternalUserNotFoundTOSConfirmAnd = ""
return
}
if e.Key == domain.LoginKeyExternalNotFoundPrivacyLinkText {
wm.ExternalUserNotFoundPrivacyLinkText = ""
return
}
}
func (wm *CustomLoginTextReadModel) handleSuccessLoginScreenSetEvent(e *policy.CustomTextSetEvent) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -206,7 +206,7 @@ func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.
events = append(events, event)
}
if human.IsInitialState(passwordless) {
if human.IsInitialState(passwordless, externalIDP != nil) {
initCode, err := domain.NewInitUserCode(c.initializeUserCode)
if err != nil {
return nil, nil, err

View File

@ -175,10 +175,11 @@ const (
LoginKeyPasswordlessRegistrationNotSupported = LoginKeyPasswordlessRegistration + "NotSupported"
LoginKeyPasswordlessRegistrationErrorRetry = LoginKeyPasswordlessRegistration + "ErrorRetry"
LoginKeyPasswordlessRegistrationDone = "PasswordlessRegistrationDone."
LoginKeyPasswordlessRegistrationDoneTitle = LoginKeyPasswordlessRegistrationDone + "Title"
LoginKeyPasswordlessRegistrationDoneDescription = LoginKeyPasswordlessRegistrationDone + "Description"
LoginKeyPasswordlessRegistrationDoneNextButtonText = LoginKeyPasswordlessRegistrationDone + "NextButtonText"
LoginKeyPasswordlessRegistrationDone = "PasswordlessRegistrationDone."
LoginKeyPasswordlessRegistrationDoneTitle = LoginKeyPasswordlessRegistrationDone + "Title"
LoginKeyPasswordlessRegistrationDoneDescription = LoginKeyPasswordlessRegistrationDone + "Description"
LoginKeyPasswordlessRegistrationDoneNextButtonText = LoginKeyPasswordlessRegistrationDone + "NextButtonText"
LoginKeyPasswordlessRegistrationDoneCancelButtonText = LoginKeyPasswordlessRegistrationDone + "CancelButtonText"
LoginKeyPasswordChange = "PasswordChange."
LoginKeyPasswordChangeTitle = LoginKeyPasswordChange + "Title"
@ -225,6 +226,24 @@ const (
LoginKeyRegistrationUserNextButtonText = LoginKeyRegistrationUser + "NextButtonText"
LoginKeyRegistrationUserBackButtonText = LoginKeyRegistrationUser + "BackButtonText"
LoginKeyExternalRegistrationUserOverview = "ExternalRegistrationUserOverview."
LoginKeyExternalRegistrationUserOverviewTitle = LoginKeyExternalRegistrationUserOverview + "Title"
LoginKeyExternalRegistrationUserOverviewDescription = LoginKeyExternalRegistrationUserOverview + "Description"
LoginKeyExternalRegistrationUserOverviewEmailLabel = LoginKeyExternalRegistrationUserOverview + "EmailLabel"
LoginKeyExternalRegistrationUserOverviewUsernameLabel = LoginKeyExternalRegistrationUserOverview + "UsernameLabel"
LoginKeyExternalRegistrationUserOverviewFirstnameLabel = LoginKeyExternalRegistrationUserOverview + "FirstnameLabel"
LoginKeyExternalRegistrationUserOverviewLastnameLabel = LoginKeyExternalRegistrationUserOverview + "LastnameLabel"
LoginKeyExternalRegistrationUserOverviewNicknameLabel = LoginKeyExternalRegistrationUserOverview + "NicknameLabel"
LoginKeyExternalRegistrationUserOverviewPhoneLabel = LoginKeyExternalRegistrationUserOverview + "PhoneLabel"
LoginKeyExternalRegistrationUserOverviewLanguageLabel = LoginKeyExternalRegistrationUserOverview + "LanguageLabel"
LoginKeyExternalRegistrationUserOverviewTOSAndPrivacyLabel = LoginKeyExternalRegistrationUserOverview + "TosAndPrivacyLabel"
LoginKeyExternalRegistrationUserOverviewTOSConfirm = LoginKeyExternalRegistrationUserOverview + "TosConfirm"
LoginKeyExternalRegistrationUserOverviewTOSLinkText = LoginKeyExternalRegistrationUserOverview + "TosLinkText"
LoginKeyExternalRegistrationUserOverviewTOSConfirmAnd = LoginKeyExternalRegistrationUserOverview + "TosConfirmAnd"
LoginKeyExternalRegistrationUserOverviewPrivacyLinkText = LoginKeyExternalRegistrationUserOverview + "PrivacyLinkText"
LoginKeyExternalRegistrationUserOverviewBackButtonText = LoginKeyExternalRegistrationUserOverview + "BackButtonText"
LoginKeyExternalRegistrationUserOverviewNextButtonText = LoginKeyExternalRegistrationUserOverview + "NextButtonText"
LoginKeyRegistrationOrg = "RegistrationOrg."
LoginKeyRegisterOrgTitle = LoginKeyRegistrationOrg + "Title"
LoginKeyRegisterOrgDescription = LoginKeyRegistrationOrg + "Description"
@ -253,6 +272,11 @@ const (
LoginKeyExternalNotFoundDescription = LoginKeyExternalNotFound + "Description"
LoginKeyExternalNotFoundLinkButtonText = LoginKeyExternalNotFound + "LinkButtonText"
LoginKeyExternalNotFoundAutoRegisterButtonText = LoginKeyExternalNotFound + "AutoRegisterButtonText"
LoginKeyExternalNotFoundTOSAndPrivacyLabel = LoginKeyExternalNotFound + "TosAndPrivacyLabel"
LoginKeyExternalNotFoundTOSConfirm = LoginKeyExternalNotFound + "TosConfirm"
LoginKeyExternalNotFoundTOSLinkText = LoginKeyExternalNotFound + "TosLinkText"
LoginKeyExternalNotFoundTOSConfirmAnd = LoginKeyExternalNotFound + "TosConfirmAnd"
LoginKeyExternalNotFoundPrivacyLinkText = LoginKeyExternalNotFound + "PrivacyLinkText"
LoginKeySuccessLogin = "LoginSuccess."
LoginKeySuccessLoginTitle = LoginKeySuccessLogin + "Title"
@ -279,39 +303,40 @@ type CustomLoginText struct {
Default bool
Language language.Tag
SelectAccount SelectAccountScreenText
Login LoginScreenText
Password PasswordScreenText
UsernameChange UsernameChangeScreenText
UsernameChangeDone UsernameChangeDoneScreenText
InitPassword InitPasswordScreenText
InitPasswordDone InitPasswordDoneScreenText
EmailVerification EmailVerificationScreenText
EmailVerificationDone EmailVerificationDoneScreenText
InitUser InitializeUserScreenText
InitUserDone InitializeUserDoneScreenText
InitMFAPrompt InitMFAPromptScreenText
InitMFAOTP InitMFAOTPScreenText
InitMFAU2F InitMFAU2FScreenText
InitMFADone InitMFADoneScreenText
MFAProvider MFAProvidersText
VerifyMFAOTP VerifyMFAOTPScreenText
VerifyMFAU2F VerifyMFAU2FScreenText
Passwordless PasswordlessScreenText
PasswordlessPrompt PasswordlessPromptScreenText
PasswordlessRegistration PasswordlessRegistrationScreenText
PasswordlessRegistrationDone PasswordlessRegistrationDoneScreenText
PasswordChange PasswordChangeScreenText
PasswordChangeDone PasswordChangeDoneScreenText
PasswordResetDone PasswordResetDoneScreenText
RegisterOption RegistrationOptionScreenText
RegistrationUser RegistrationUserScreenText
RegistrationOrg RegistrationOrgScreenText
LinkingUsersDone LinkingUserDoneScreenText
ExternalNotFoundOption ExternalUserNotFoundScreenText
LoginSuccess SuccessLoginScreenText
LogoutDone LogoutDoneScreenText
Footer FooterText
SelectAccount SelectAccountScreenText
Login LoginScreenText
Password PasswordScreenText
UsernameChange UsernameChangeScreenText
UsernameChangeDone UsernameChangeDoneScreenText
InitPassword InitPasswordScreenText
InitPasswordDone InitPasswordDoneScreenText
EmailVerification EmailVerificationScreenText
EmailVerificationDone EmailVerificationDoneScreenText
InitUser InitializeUserScreenText
InitUserDone InitializeUserDoneScreenText
InitMFAPrompt InitMFAPromptScreenText
InitMFAOTP InitMFAOTPScreenText
InitMFAU2F InitMFAU2FScreenText
InitMFADone InitMFADoneScreenText
MFAProvider MFAProvidersText
VerifyMFAOTP VerifyMFAOTPScreenText
VerifyMFAU2F VerifyMFAU2FScreenText
Passwordless PasswordlessScreenText
PasswordlessPrompt PasswordlessPromptScreenText
PasswordlessRegistration PasswordlessRegistrationScreenText
PasswordlessRegistrationDone PasswordlessRegistrationDoneScreenText
PasswordChange PasswordChangeScreenText
PasswordChangeDone PasswordChangeDoneScreenText
PasswordResetDone PasswordResetDoneScreenText
RegisterOption RegistrationOptionScreenText
RegistrationUser RegistrationUserScreenText
ExternalRegistrationUserOverview ExternalRegistrationUserOverviewScreenText
RegistrationOrg RegistrationOrgScreenText
LinkingUsersDone LinkingUserDoneScreenText
ExternalNotFoundOption ExternalUserNotFoundScreenText
LoginSuccess SuccessLoginScreenText
LogoutDone LogoutDoneScreenText
Footer FooterText
}
func (m *CustomLoginText) IsValid() bool {
@ -537,6 +562,25 @@ type RegistrationUserScreenText struct {
BackButtonText string
}
type ExternalRegistrationUserOverviewScreenText struct {
Title string
Description string
EmailLabel string
UsernameLabel string
FirstnameLabel string
LastnameLabel string
NicknameLabel string
LanguageLabel string
PhoneLabel string
TOSAndPrivacyLabel string
TOSConfirm string
TOSLinkText string
TOSConfirmAnd string
PrivacyLinkText string
BackButtonText string
NextButtonText string
}
type RegistrationOrgScreenText struct {
Title string
Description string
@ -567,6 +611,11 @@ type ExternalUserNotFoundScreenText struct {
Description string
LinkButtonText string
AutoRegisterButtonText string
TOSAndPrivacyLabel string
TOSConfirm string
TOSLinkText string
TOSConfirmAnd string
PrivacyLinkText string
}
type SuccessLoginScreenText struct {
@ -608,7 +657,8 @@ type PasswordlessRegistrationScreenText struct {
}
type PasswordlessRegistrationDoneScreenText struct {
Title string
Description string
NextButtonText string
Title string
Description string
NextButtonText string
CancelButtonText string
}

View File

@ -18,7 +18,6 @@ type Human struct {
*Email
*Phone
*Address
ExternalIDPs []*ExternalIDP
}
func (h Human) GetUsername() string {
@ -79,8 +78,8 @@ func (u *Human) HashPasswordIfExisting(policy *PasswordComplexityPolicy, passwor
return nil
}
func (u *Human) IsInitialState(passwordless bool) bool {
return u.Email == nil || !u.IsEmailVerified || (u.ExternalIDPs == nil || len(u.ExternalIDPs) == 0) && !passwordless && (u.Password == nil || u.SecretString == "")
func (u *Human) IsInitialState(passwordless, externalIDPs bool) bool {
return u.Email == nil || !u.IsEmailVerified || !externalIDPs && !passwordless && (u.Password == nil || u.SecretString == "")
}
func NewInitUserCode(generator crypto.Generator) (*InitUserCode, error) {

View File

@ -700,6 +700,9 @@ func passwordlessRegistrationDoneKeyToDomain(text *CustomTextView, result *domai
if text.Key == domain.LoginKeyPasswordlessRegistrationDoneNextButtonText {
result.PasswordlessRegistrationDone.NextButtonText = text.Text
}
if text.Key == domain.LoginKeyPasswordlessRegistrationDoneCancelButtonText {
result.PasswordlessRegistrationDone.CancelButtonText = text.Text
}
}
func passwordChangeKeyToDomain(text *CustomTextView, result *domain.CustomLoginText) {
@ -898,6 +901,21 @@ func externalUserNotFoundKeyToDomain(text *CustomTextView, result *domain.Custom
if text.Key == domain.LoginKeyExternalNotFoundAutoRegisterButtonText {
result.ExternalNotFoundOption.AutoRegisterButtonText = text.Text
}
if text.Key == domain.LoginKeyExternalNotFoundTOSAndPrivacyLabel {
result.ExternalNotFoundOption.TOSAndPrivacyLabel = text.Text
}
if text.Key == domain.LoginKeyExternalNotFoundTOSConfirm {
result.ExternalNotFoundOption.TOSConfirm = text.Text
}
if text.Key == domain.LoginKeyExternalNotFoundTOSLinkText {
result.ExternalNotFoundOption.TOSLinkText = text.Text
}
if text.Key == domain.LoginKeyExternalNotFoundTOSConfirmAnd {
result.ExternalNotFoundOption.TOSConfirmAnd = text.Text
}
if text.Key == domain.LoginKeyExternalNotFoundPrivacyLinkText {
result.ExternalNotFoundOption.PrivacyLinkText = text.Text
}
}
func successLoginKeyToDomain(text *CustomTextView, result *domain.CustomLoginText) {

View File

@ -1,6 +1,10 @@
package handler
import (
"net/http"
"strings"
"time"
"github.com/caos/oidc/pkg/client/rp"
"github.com/caos/oidc/pkg/oidc"
"golang.org/x/oauth2"
@ -11,9 +15,6 @@ import (
"github.com/caos/zitadel/internal/errors"
caos_errors "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"net/http"
"strings"
"time"
)
const (
@ -34,6 +35,7 @@ type externalNotFoundOptionFormData struct {
Link bool `schema:"link"`
AutoRegister bool `schema:"autoregister"`
ResetLinking bool `schema:"resetlinking"`
TermsConfirm bool `schema:"terms-confirm"`
}
type externalNotFoundOptionData struct {

View File

@ -6,6 +6,7 @@ import (
"github.com/caos/oidc/pkg/client/rp"
"github.com/caos/oidc/pkg/oidc"
"golang.org/x/text/language"
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
"github.com/caos/zitadel/internal/domain"
@ -13,6 +14,42 @@ import (
iam_model "github.com/caos/zitadel/internal/iam/model"
)
const (
tmplExternalRegisterOverview = "externalregisteroverview"
)
type externalRegisterFormData struct {
ExternalIDPConfigID string `schema:"external-idp-config-id"`
ExternalIDPExtUserID string `schema:"external-idp-ext-user-id"`
ExternalIDPDisplayName string `schema:"external-idp-display-name"`
ExternalEmail string `schema:"external-email"`
ExternalEmailVerified bool `schema:"external-email-verified"`
Email string `schema:"email"`
Username string `schema:"username"`
Firstname string `schema:"firstname"`
Lastname string `schema:"lastname"`
Nickname string `schema:"nickname"`
ExternalPhone string `schema:"external-phone"`
ExternalPhoneVerified bool `schema:"external-phone-verified"`
Phone string `schema:"phone"`
Language string `schema:"language"`
TermsConfirm bool `schema:"terms-confirm"`
}
type externalRegisterData struct {
baseData
externalRegisterFormData
ExternalIDPID string
ExternalIDPUserID string
ExternalIDPUserDisplayName string
ShowUsername bool
OrgRegister bool
ExternalEmail string
ExternalEmailVerified bool
ExternalPhone string
ExternalPhoneVerified bool
}
func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) {
data := new(externalIDPData)
authReq, err := l.getAuthRequestAndParseData(r, data)
@ -76,18 +113,77 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques
return
}
resourceOwner := iam.GlobalOrgID
memberRoles := []string{domain.RoleOrgProjectCreator}
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
memberRoles = nil
resourceOwner = authReq.RequestedOrgID
}
orgIamPolicy, err := l.getOrgIamPolicy(r, resourceOwner)
if err != nil {
l.renderRegisterOption(w, r, authReq, err)
return
}
user, externalIDP := l.mapTokenToLoginHumanAndExternalIDP(orgIamPolicy, tokens, idpConfig)
l.renderExternalRegisterOverview(w, r, authReq, orgIamPolicy, user, externalIDP, nil)
}
func (l *Login) renderExternalRegisterOverview(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, orgIAMPolicy *iam_model.OrgIAMPolicyView, human *domain.Human, idp *domain.ExternalIDP, err error) {
var errID, errMessage string
if err != nil {
errID, errMessage = l.getErrorMessage(r, err)
}
data := externalRegisterData{
baseData: l.getBaseData(r, authReq, "ExternalRegisterOverview", errID, errMessage),
externalRegisterFormData: externalRegisterFormData{
Email: human.EmailAddress,
Username: human.PreferredLoginName,
Firstname: human.FirstName,
Lastname: human.LastName,
Nickname: human.NickName,
Language: human.PreferredLanguage.String(),
},
ExternalIDPID: idp.IDPConfigID,
ExternalIDPUserID: idp.ExternalUserID,
ExternalIDPUserDisplayName: idp.DisplayName,
ExternalEmail: human.EmailAddress,
ExternalEmailVerified: human.IsEmailVerified,
ShowUsername: orgIAMPolicy.UserLoginMustBeDomain,
OrgRegister: orgIAMPolicy.UserLoginMustBeDomain,
}
if human.Phone != nil {
data.Phone = human.PhoneNumber
data.ExternalPhone = human.PhoneNumber
data.ExternalPhoneVerified = human.IsPhoneVerified
}
translator := l.getTranslator(authReq)
l.renderer.RenderTemplate(w, r, translator, l.renderer.Templates[tmplExternalRegisterOverview], data, nil)
}
func (l *Login) handleExternalRegisterCheck(w http.ResponseWriter, r *http.Request) {
data := new(externalRegisterFormData)
authReq, err := l.getAuthRequestAndParseData(r, data)
if err != nil {
l.renderError(w, r, authReq, err)
return
}
iam, err := l.authRepo.GetIAM(r.Context())
if err != nil {
l.renderRegisterOption(w, r, authReq, err)
return
}
resourceOwner := iam.GlobalOrgID
memberRoles := []string{domain.RoleOrgProjectCreator}
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
memberRoles = nil
resourceOwner = authReq.RequestedOrgID
}
externalIDP, err := l.getExternalIDP(data)
if externalIDP == nil {
l.renderRegisterOption(w, r, authReq, err)
return
}
user, err := l.mapExternalRegisterDataToUser(r, data)
if err != nil {
l.renderRegisterOption(w, r, authReq, err)
return
}
_, err = l.command.RegisterHuman(setContext(r.Context(), resourceOwner), resourceOwner, user, externalIDP, memberRoles)
if err != nil {
l.renderRegisterOption(w, r, authReq, err)
@ -140,6 +236,9 @@ func (l *Login) mapTokenToLoginHumanAndExternalIDP(orgIamPolicy *iam_model.OrgIA
displayName = tokens.IDTokenClaims.GetEmail()
}
}
if displayName == "" {
displayName = tokens.IDTokenClaims.GetEmail()
}
externalIDP := &domain.ExternalIDP{
IDPConfigID: idpConfig.IDPConfigID,
@ -148,3 +247,43 @@ func (l *Login) mapTokenToLoginHumanAndExternalIDP(orgIamPolicy *iam_model.OrgIA
}
return human, externalIDP
}
func (l *Login) mapExternalRegisterDataToUser(r *http.Request, data *externalRegisterFormData) (*domain.Human, error) {
human := &domain.Human{
Username: data.Username,
Profile: &domain.Profile{
FirstName: data.Firstname,
LastName: data.Lastname,
PreferredLanguage: language.Make(data.Language),
NickName: data.Nickname,
},
Email: &domain.Email{
EmailAddress: data.Email,
},
}
if data.ExternalEmail != data.Email {
human.IsEmailVerified = false
} else {
human.IsEmailVerified = data.ExternalEmailVerified
}
if data.ExternalPhone == "" {
return human, nil
}
human.Phone = &domain.Phone{
PhoneNumber: data.Phone,
}
if data.ExternalPhone != data.Phone {
human.IsPhoneVerified = false
} else {
human.IsPhoneVerified = data.ExternalPhoneVerified
}
return human, nil
}
func (l *Login) getExternalIDP(data *externalRegisterFormData) (*domain.ExternalIDP, error) {
return &domain.ExternalIDP{
IDPConfigID: data.ExternalIDPConfigID,
ExternalUserID: data.ExternalIDPExtUserID,
DisplayName: data.ExternalIDPDisplayName,
}, nil
}

View File

@ -62,6 +62,7 @@ func CreateRenderer(pathPrefix string, staticDir http.FileSystem, staticStorage
tmplChangePasswordDone: "change_password_done.html",
tmplRegisterOption: "register_option.html",
tmplRegister: "register.html",
tmplExternalRegisterOverview: "external_register_overview.html",
tmplLogoutDone: "logout_done.html",
tmplRegisterOrg: "register_org.html",
tmplChangeUsername: "change_username.html",
@ -181,6 +182,9 @@ func CreateRenderer(pathPrefix string, staticDir http.FileSystem, staticStorage
"orgRegistrationUrl": func() string {
return path.Join(r.pathPrefix, EndpointRegisterOrg)
},
"externalRegistrationUrl": func() string {
return path.Join(r.pathPrefix, EndpointExternalRegister)
},
"changeUsernameUrl": func() string {
return path.Join(r.pathPrefix, EndpointChangeUsername)
},

View File

@ -82,6 +82,7 @@ func CreateRouter(login *Login, staticDir http.FileSystem, interceptors ...mux.M
router.HandleFunc(EndpointRegister, login.handleRegister).Methods(http.MethodGet)
router.HandleFunc(EndpointRegister, login.handleRegisterCheck).Methods(http.MethodPost)
router.HandleFunc(EndpointExternalRegister, login.handleExternalRegister).Methods(http.MethodGet)
router.HandleFunc(EndpointExternalRegister, login.handleExternalRegisterCheck).Methods(http.MethodPost)
router.HandleFunc(EndpointExternalRegisterCallback, login.handleExternalRegisterCallback).Methods(http.MethodGet)
router.HandleFunc(EndpointLogoutDone, login.handleLogoutDone).Methods(http.MethodGet)
router.HandleFunc(EndpointDynamicResources, login.handleDynamicResources).Methods(http.MethodGet)

View File

@ -221,6 +221,26 @@ RegistrationUser:
BackButtonText: zurück
NextButtonText: weiter
ExternalRegistrationUserOverview:
Title: Externer Benutzer Registration
Description: Deine Benutzerangaben werden vom ausgewählten Provider übernommen. Du kannst sie hier ändern und ergänzen, bevor dein Benutzer angelegt wird.
EmailLabel: E-Mail
UsernameLabel: Benutzername
FirstnameLabel: Vorname
LastnameLabel: Nachname
NicknameLabel: Nachname
PhoneLabel: Telefonnummer
LanguageLabel: Sprache
German: Deutsch
English: English
TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz
TosConfirm: Ich akzeptiere die
TosLinkText: AGBs
TosConfirmAnd: und die
PrivacyLinkText: Datenschutzerklärung
BackButtonText: zurück
NextButtonText: speichern
RegistrationOrg:
Title: Organisations Registration
Description: Gib deinen Organisationsnamen und deine Benutzerangaben an.
@ -260,6 +280,11 @@ ExternalNotFoundOption:
Description: Externer Benutzer konnte nicht gefunden werden. Willst du deinen Benutzer mit einem bestehenden verlinken oder diesen als neuen Benutzer registrieren.
LinkButtonText: Verlinken
AutoRegisterButtonText: Automatisches registrieren
TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz
TosConfirm: Ich akzeptiere die
TosLinkText: AGBs
TosConfirmAnd: und die
PrivacyLinkText: Datenschutzerklärung
Footer:
PoweredBy: Powered By
@ -305,6 +330,8 @@ Errors:
GeneratorAlgNotSupported: Generator Algorithums wird nicht unterstützt
EmailVerify:
UserIDEmpty: UserID ist leer
ExternalData:
CouldNotRead: Externe Daten konnten nicht korrekt gelesen werden
MFA:
NoProviders: Es stehen keine Multifaktorprovider zur Verfügung
OTP:
@ -318,6 +345,9 @@ Errors:
ExternalIDP:
IDPTypeNotImplemented: IDP Typ ist nicht implementiert
NotAllowed: Externer Login Provider ist nicht erlaubt
IDPConfigIDEmpty: Identity Provider ID ist leer
ExternalUserIDEmpty: Externe User ID ist leer
UserDisplayNameEmpty: Benutzer Anzeige Name ist leer
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
IdentityProvider:
InvalidConfig: Identitäts Provider Konfiguration ist ungültig

View File

@ -221,6 +221,27 @@ RegistrationUser:
BackButtonText: back
NextButtonText: next
ExternalRegistrationUserOverview:
Title: External User Registration
Description: We have taken your user details from the selected provider. You can now change or complete them.
EmailLabel: E-Mail
UsernameLabel: Username
FirstnameLabel: Firstname
LastnameLabel: Lastname
NicknameLabel: Nickname
PhoneLabel: Phonenumber
LanguageLabel: Language
German: Deutsch
English: English
TosAndPrivacyLabel: Terms and conditions
TosConfirm: I accept the
TosLinkText: TOS
TosConfirmAnd: and the
PrivacyLinkText: privacy policy
ExternalLogin: or register with an external user
BackButtonText: back
NextButtonText: save
RegistrationOrg:
Title: Organisation Registration
Description: Enter your organisationname and userdata.
@ -260,6 +281,11 @@ ExternalNotFoundOption:
Description: External user not found. Do you want to link your user or auto register a new one.
LinkButtonText: Link
AutoRegisterButtonText: Auto register
TosAndPrivacyLabel: Terms and conditions
TosConfirm: I accept the
TosLinkText: TOS
TosConfirmAnd: and the
PrivacyLinkText: privacy policy
Footer:
PoweredBy: Powered By
@ -305,6 +331,8 @@ Errors:
GeneratorAlgNotSupported: Unsupported generator algorithm
EmailVerify:
UserIDEmpty: UserID is empty
ExternalData:
CouldNotRead: External data could not be read correctly
MFA:
NoProviders: No available multifactor providers
OTP:
@ -318,6 +346,9 @@ Errors:
ExternalIDP:
IDPTypeNotImplemented: IDP Type is not implemented
NotAllowed: External Login Provider not allowed
IDPConfigIDEmpty: Identity Provider ID is empty
ExternalUserIDEmpty: External User ID is empty
UserDisplayNameEmpty: User Display Name is empty
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
IdentityProvider:
InvalidConfig: Identity Provider configuration is invalid

View File

@ -0,0 +1,5 @@
let button1 = document.getElementById("link-button");
disableSubmit(undefined, button1);
let button2 = document.getElementById("auto-register-button");
disableSubmit(undefined, button2);

View File

@ -3,32 +3,65 @@
<div class="lgn-head">
<h1>{{t "ExternalNotFoundOption.Title"}}</h1>
<p>{{t "ExternalNotFoundOption.Description"}}</p>
</div>
<form action="{{ externalNotFoundOptionUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="lgn-register">
{{ if or .TOSLink .PrivacyLink }}
<div class="lgn-field">
<label class="lgn-label">{{t "ExternalNotFoundOption.TosAndPrivacyLabel"}}</label>
<div class="lgn-checkbox">
<input type="checkbox" id="register-term-confirmation"
name="register-term-confirmation" required>
<label for="register-term-confirmation">
{{t "ExternalNotFoundOption.TosConfirm"}}
{{ if .TOSLink }}
<a class="tos-link" target="_blank" href="{{ .TOSLink }}" rel="noopener noreferrer">
{{t "ExternalNotFoundOption.TosLinkText"}}
</a>
{{end}}
{{ if and .TOSLink .PrivacyLink }}
{{t "ExternalNotFoundOption.TosConfirmAnd"}}
{{ end }}
{{ if .PrivacyLink }}
<a class="tos-link" target="_blank" href="{{ .PrivacyLink}}" rel="noopener noreferrer">
{{t "ExternalNotFoundOption.PrivacyLinkText"}}
</a>
{{end}}
</label>
</div>
</div>
{{ end }}
</div>
{{template "error-message" .}}
<div class="lgn-actions">
<button class="lgn-icon-button lgn-left-action" name="resetlinking" value="true"
formnovalidate>
formnovalidate>
<i class="lgn-icon-arrow-left-solid"></i>
</button>
<button class="lgn-raised-button lgn-primary" name="link" value="true"
formnovalidate>{{t "ExternalNotFoundOption.LinkButtonText"}}</button>
<span class="fill-space"></span>
<button class="lgn-raised-button lgn-primary" name="autoregister" value="true"
formnovalidate>{{t "ExternalNotFoundOption.AutoRegisterButtonText"}}</button>
<button class="lgn-raised-button lgn-primary" name="link" value="true">
{{t "ExternalNotFoundOption.LinkButtonText"}}
</button>
<span class="fill-space"></span>
<button class="lgn-raised-button lgn-primary" name="autoregister" value="true">
{{t "ExternalNotFoundOption.AutoRegisterButtonText"}}
</button>
</div>
{{template "error-message" .}}
</form>
<script src="{{ resourceUrl "scripts/form_submit.js" }}"></script>
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
<script src="{{ resourceUrl "scripts/external_not_found_check.js" }}"></script>
{{template "main-bottom" .}}

View File

@ -0,0 +1,114 @@
{{template "main-top" .}}
<div class="lgn-head">
<h1>{{t "ExternalRegistrationUserOverview.Title"}}</h1>
<p>{{t "ExternalRegistrationUserOverview.Description"}}</p>
</div>
<form action="{{ externalRegistrationUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" id="external-idp-config-id" name="external-idp-config-id" value="{{ .ExternalIDPID }}" />
<input type="hidden" id="external-idp-ext-user-id" name="external-idp-ext-user-id" value="{{ .ExternalIDPUserID }}" />
<input type="hidden" id="external-idp-display-name" name="external-idp-display-name" value="{{ .ExternalIDPUserDisplayName }}" />
<input type="hidden" id="external-email" name="external-email" value="{{ .ExternalEmail }}" />
<input type="hidden" id="external-email-verified" name="external-email-verified" value="{{ .ExternalEmailVerified }}" />
<input type="hidden" id="external-phone" name="external-phone" value="{{ .ExternalPhone }}" />
<input type="hidden" id="external-phone-verified" name="external-phone-verified" value="{{ .ExternalPhoneVerified }}" />
<div class="lgn-register">
<div class="double-col">
<div class="lgn-field">
<label class="lgn-label" for="firstname">{{t "ExternalRegistrationUserOverview.FirstnameLabel"}}</label>
<input class="lgn-input" type="text" id="firstname" name="firstname" autocomplete="given-name"
value="{{ .Firstname }}" autofocus required>
</div>
<div class="lgn-field">
<label class="lgn-label" for="lastname">{{t "ExternalRegistrationUserOverview.LastnameLabel"}}</label>
<input class="lgn-input" type="text" id="lastname" name="lastname" autocomplete="family-name"
value="{{ .Lastname }}" required>
</div>
</div>
<div class="lgn-field double">
<label class="lgn-label" for="email">{{t "ExternalRegistrationUserOverview.EmailLabel"}}</label>
<input class="lgn-input" type="text" id="email" name="email" autocomplete="email" value="{{ .Email }}" required>
</div>
<div class="lgn-field double">
<label class="lgn-label" for="phone">{{t "ExternalRegistrationUserOverview.PhoneLabel"}}</label>
<input class="lgn-input" type="text" id="phone" name="phone" autocomplete="tel" value="{{ .Phone }}">
</div>
{{if .ShowUsername}}
<div class="lgn-field double">
<label class="lgn-label" for="username">{{t "ExternalRegistrationUserOverview.UsernameLabel"}}</label>
<div class="lgn-suffix-wrapper">
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username" autocomplete="email" value="{{ .Email }}" required>
{{if .DisplayLoginNameSuffix}}
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
{{end}}
</div>
</div>
{{end}}
<div class="double-col">
<div class="lgn-field">
<label class="lgn-label" for="languages">{{t "ExternalRegistrationUserOverview.LanguageLabel"}}</label>
<select id="languages" name="language">
<option value=""></option>
<option value="de" id="de" {{if (selectedLanguage "de")}} selected {{end}}>{{t "ExternalRegistrationUserOverview.German"}}
</option>
<option value="en" id="en" {{if (selectedLanguage "en")}} selected {{end}}>{{t "ExternalRegistrationUserOverview.English"}}
</option>
</select>
</div>
</div>
{{ if or .TOSLink .PrivacyLink }}
<div class="lgn-field">
<label class="lgn-label">{{t "ExternalRegistrationUserOverview.TosAndPrivacyLabel"}}</label>
<div class="lgn-checkbox">
<input type="checkbox" id="register-term-confirmation"
name="register-term-confirmation" required>
<label for="register-term-confirmation">
{{t "ExternalRegistrationUserOverview.TosConfirm"}}
{{ if .TOSLink }}
<a class="tos-link" target="_blank" href="{{ .TOSLink }}" rel="noopener noreferrer">
{{t "ExternalRegistrationUserOverview.TosLinkText"}}
</a>
{{end}}
{{ if and .TOSLink .PrivacyLink }}
{{t "ExternalRegistrationUserOverview.TosConfirmAnd"}}
{{ end }}
{{ if .PrivacyLink }}
<a class="tos-link" target="_blank" href="{{ .PrivacyLink}}" rel="noopener noreferrer">
{{t "ExternalRegistrationUserOverview.PrivacyLinkText"}}
</a>
{{end}}
</label>
</div>
</div>
{{ end }}
</div>
{{template "error-message" .}}
<div class="lgn-actions">
<a class="lgn-stroked-button lgn-primary" href="{{ registerOptionUrl }}">
{{t "ExternalRegistrationUserOverview.BackButtonText"}}
</a>
<span class="fill-space"></span>
<button class="lgn-raised-button lgn-primary" id="submit-button" type="submit">{{t "ExternalRegistrationUserOverview.NextButtonText"}}</button>
</div>
</form>
<script src="{{ resourceUrl "scripts/input_suffix_offset.js" }}"></script>
<script src="{{ resourceUrl "scripts/form_submit.js" }}"></script>
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
{{template "main-bottom" .}}

View File

@ -39,7 +39,7 @@
{{if .ShowUsername}}
<div class="lgn-field double">
<label class="lgn-label" for="email">{{t "RegistrationUser.UsernameLabel"}}</label>
<label class="lgn-label" for="username">{{t "RegistrationUser.UsernameLabel"}}</label>
<div class="lgn-suffix-wrapper">
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username" autocomplete="email" value="{{ .Email }}" required>
{{if .DisplayLoginNameSuffix}}

View File

@ -3393,6 +3393,7 @@ message SetCustomLoginTextsRequest {
zitadel.text.v1.PasswordlessPromptScreenText passwordless_prompt_text = 32;
zitadel.text.v1.PasswordlessRegistrationScreenText passwordless_registration_text = 33;
zitadel.text.v1.PasswordlessRegistrationDoneScreenText passwordless_registration_done_text = 34;
zitadel.text.v1.ExternalRegistrationUserOverviewScreenText external_registration_user_overview_text = 35;
}
message SetCustomLoginTextsResponse {

View File

@ -4561,6 +4561,7 @@ message SetCustomLoginTextsRequest {
zitadel.text.v1.PasswordlessPromptScreenText passwordless_prompt_text = 32;
zitadel.text.v1.PasswordlessRegistrationScreenText passwordless_registration_text = 33;
zitadel.text.v1.PasswordlessRegistrationDoneScreenText passwordless_registration_done_text = 34;
zitadel.text.v1.ExternalRegistrationUserOverviewScreenText external_registration_user_overview_text = 35;
}
message SetCustomLoginTextsResponse {

View File

@ -82,6 +82,7 @@ message LoginCustomText {
PasswordlessPromptScreenText passwordless_prompt_text = 32;
PasswordlessRegistrationScreenText passwordless_registration_text = 33;
PasswordlessRegistrationDoneScreenText passwordless_registration_done_text = 34;
ExternalRegistrationUserOverviewScreenText external_registration_user_overview_text = 35;
}
message SelectAccountScreenText {
@ -305,6 +306,25 @@ message RegistrationUserScreenText {
string tos_confirm_and = 22 [(validate.rules).string = {max_len: 200}];
}
message ExternalRegistrationUserOverviewScreenText {
string title = 1 [(validate.rules).string = {max_len: 200}];
string description = 2 [(validate.rules).string = {max_len: 500}];
string email_label = 3 [(validate.rules).string = {max_len: 200}];
string username_label = 4 [(validate.rules).string = {max_len: 200}];
string firstname_label = 5 [(validate.rules).string = {max_len: 200}];
string lastname_label = 6 [(validate.rules).string = {max_len: 200}];
string nickname_label = 7 [(validate.rules).string = {max_len: 200}];
string language_label = 8 [(validate.rules).string = {max_len: 200}];
string phone_label = 9 [(validate.rules).string = {max_len: 200}];
string tos_and_privacy_label = 10 [(validate.rules).string = {max_len: 200}];
string tos_confirm = 11 [(validate.rules).string = {max_len: 200}];
string tos_link_text = 12 [(validate.rules).string = {max_len: 200}];
string tos_confirm_and = 13 [(validate.rules).string = {max_len: 200}];
string privacy_link_text = 14 [(validate.rules).string = {max_len: 200}];
string back_button_text = 15 [(validate.rules).string = {max_len: 200}];
string next_button_text = 16 [(validate.rules).string = {max_len: 200}];
}
message RegistrationOrgScreenText {
reserved 13, 15, 16, 18;
reserved "tos_link", "privacy_confirm", "privacy_link", "external_login_description";
@ -337,6 +357,11 @@ message ExternalUserNotFoundScreenText {
string description = 2 [(validate.rules).string = {max_len: 500}];
string link_button_text = 3 [(validate.rules).string = {max_len: 100}];
string auto_register_button_text = 4 [(validate.rules).string = {max_len: 100}];
string tos_and_privacy_label = 5 [(validate.rules).string = {max_len: 200}];
string tos_confirm = 6 [(validate.rules).string = {max_len: 200}];
string tos_link_text = 7 [(validate.rules).string = {max_len: 200}];
string privacy_link_text = 8 [(validate.rules).string = {max_len: 200}];
string tos_confirm_and = 9 [(validate.rules).string = {max_len: 200}];
}
message SuccessLoginScreenText {
@ -385,4 +410,5 @@ message PasswordlessRegistrationDoneScreenText {
string title = 1 [(validate.rules).string = {max_len: 200}];
string description = 2 [(validate.rules).string = {max_len: 500}];
string next_button_text = 3 [(validate.rules).string = {max_len: 100}];
string cancel_button_text = 4 [(validate.rules).string = {max_len: 100}];
}