mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
fix: allow invite codes for users with verified mails (#9962)
# Which Problems Are Solved Users who started the invitation code verification, but haven't set up any authentication method, need to be able to do so. This might require a new invitation code, which was currently not possible since creation was prevented for users with verified emails. # How the Problems Are Solved - Allow creation of invitation emails for users with verified emails. - Merged the creation and resend into a single method, defaulting the urlTemplate, applicatioName and authRequestID from the previous code (if one exists). On the user service API, the `ResendInviteCode` endpoint has been deprecated in favor of the `CreateInviteCode` # Additional Changes None # Additional Context - Noticed while investigating something internally. - requires backport to 2.x and 3.x
This commit is contained in:
@@ -19,14 +19,34 @@ type CreateUserInvite struct {
|
||||
URLTemplate string
|
||||
ReturnCode bool
|
||||
ApplicationName string
|
||||
AuthRequestID string
|
||||
}
|
||||
|
||||
func (c *Commands) CreateInviteCode(ctx context.Context, invite *CreateUserInvite) (details *domain.ObjectDetails, returnCode *string, err error) {
|
||||
return c.sendInviteCode(ctx, invite, "", false)
|
||||
}
|
||||
|
||||
// ResendInviteCode resends the invite mail with a new code and an optional authRequestID.
|
||||
// It will reuse the applicationName from the previous code.
|
||||
func (c *Commands) ResendInviteCode(ctx context.Context, userID, resourceOwner, authRequestID string) (objectDetails *domain.ObjectDetails, err error) {
|
||||
details, _, err := c.sendInviteCode(
|
||||
ctx,
|
||||
&CreateUserInvite{
|
||||
UserID: userID,
|
||||
AuthRequestID: authRequestID,
|
||||
},
|
||||
resourceOwner,
|
||||
true,
|
||||
)
|
||||
return details, err
|
||||
}
|
||||
|
||||
func (c *Commands) sendInviteCode(ctx context.Context, invite *CreateUserInvite, resourceOwner string, requireExisting bool) (details *domain.ObjectDetails, returnCode *string, err error) {
|
||||
invite.UserID = strings.TrimSpace(invite.UserID)
|
||||
if invite.UserID == "" {
|
||||
return nil, nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-4jio3", "Errors.User.UserIDMissing")
|
||||
}
|
||||
wm, err := c.userInviteCodeWriteModel(ctx, invite.UserID, "")
|
||||
wm, err := c.userInviteCodeWriteModel(ctx, invite.UserID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -39,10 +59,22 @@ func (c *Commands) CreateInviteCode(ctx context.Context, invite *CreateUserInvit
|
||||
if !wm.CreationAllowed() {
|
||||
return nil, nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-EF34g", "Errors.User.AlreadyInitialised")
|
||||
}
|
||||
if requireExisting && wm.InviteCode == nil || wm.CodeReturned {
|
||||
return nil, nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Wr3gq", "Errors.User.Code.NotFound")
|
||||
}
|
||||
code, err := c.newUserInviteCode(ctx, c.eventstore.Filter, c.userEncryption) //nolint
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if invite.URLTemplate == "" {
|
||||
invite.URLTemplate = wm.URLTemplate
|
||||
}
|
||||
if invite.ApplicationName == "" {
|
||||
invite.ApplicationName = wm.ApplicationName
|
||||
}
|
||||
if invite.AuthRequestID == "" {
|
||||
invite.AuthRequestID = wm.AuthRequestID
|
||||
}
|
||||
err = c.pushAppendAndReduce(ctx, wm, user.NewHumanInviteCodeAddedEvent(
|
||||
ctx,
|
||||
UserAggregateFromWriteModelCtx(ctx, &wm.WriteModel),
|
||||
@@ -51,7 +83,7 @@ func (c *Commands) CreateInviteCode(ctx context.Context, invite *CreateUserInvit
|
||||
invite.URLTemplate,
|
||||
invite.ReturnCode,
|
||||
invite.ApplicationName,
|
||||
"",
|
||||
invite.AuthRequestID,
|
||||
))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -62,53 +94,6 @@ func (c *Commands) CreateInviteCode(ctx context.Context, invite *CreateUserInvit
|
||||
return writeModelToObjectDetails(&wm.WriteModel), returnCode, nil
|
||||
}
|
||||
|
||||
// ResendInviteCode resends the invite mail with a new code and an optional authRequestID.
|
||||
// It will reuse the applicationName from the previous code.
|
||||
func (c *Commands) ResendInviteCode(ctx context.Context, userID, resourceOwner, authRequestID string) (objectDetails *domain.ObjectDetails, err error) {
|
||||
if userID == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-2n8vs", "Errors.User.UserIDMissing")
|
||||
}
|
||||
|
||||
existingCode, err := c.userInviteCodeWriteModel(ctx, userID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingCode.UserState.Exists() {
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-H3b2a", "Errors.User.NotFound")
|
||||
}
|
||||
if err := c.checkPermissionUpdateUser(ctx, existingCode.ResourceOwner, userID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingCode.CreationAllowed() {
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Gg42s", "Errors.User.AlreadyInitialised")
|
||||
}
|
||||
if existingCode.InviteCode == nil || existingCode.CodeReturned {
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Wr3gq", "Errors.User.Code.NotFound")
|
||||
}
|
||||
code, err := c.newUserInviteCode(ctx, c.eventstore.Filter, c.userEncryption) //nolint
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if authRequestID == "" {
|
||||
authRequestID = existingCode.AuthRequestID
|
||||
}
|
||||
err = c.pushAppendAndReduce(ctx, existingCode,
|
||||
user.NewHumanInviteCodeAddedEvent(
|
||||
ctx,
|
||||
UserAggregateFromWriteModelCtx(ctx, &existingCode.WriteModel),
|
||||
code.Crypted,
|
||||
code.Expiry,
|
||||
existingCode.URLTemplate,
|
||||
false,
|
||||
existingCode.ApplicationName,
|
||||
authRequestID,
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&existingCode.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) InviteCodeSent(ctx context.Context, userID, orgID string) (err error) {
|
||||
if userID == "" {
|
||||
return zerrors.ThrowInvalidArgument(nil, "COMMAND-Sgf31", "Errors.User.UserIDMissing")
|
||||
|
Reference in New Issue
Block a user