mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 07:27:33 +00:00
feat: invite user link (#8578)
# Which Problems Are Solved As an administrator I want to be able to invite users to my application with the API V2, some user data I will already prefil, the user should add the authentication method themself (password, passkey, sso). # How the Problems Are Solved - A user can now be created with a email explicitly set to false. - If a user has no verified email and no authentication method, an `InviteCode` can be created through the User V2 API. - the code can be returned or sent through email - additionally `URLTemplate` and an `ApplicatioName` can provided for the email - The code can be resent and verified through the User V2 API - The V1 login allows users to verify and resend the code and set a password (analog user initialization) - The message text for the user invitation can be customized # Additional Changes - `verifyUserPasskeyCode` directly uses `crypto.VerifyCode` (instead of `verifyEncryptedCode`) - `verifyEncryptedCode` is removed (unnecessarily queried for the code generator) # Additional Context - closes #8310 - TODO: login V2 will have to implement invite flow: https://github.com/zitadel/typescript/issues/166
This commit is contained in:
@@ -106,6 +106,7 @@ type idpUserLinksProvider interface {
|
||||
type userEventProvider interface {
|
||||
UserEventsByID(ctx context.Context, id string, changeDate time.Time, eventTypes []eventstore.EventType) ([]eventstore.Event, error)
|
||||
PasswordCodeExists(ctx context.Context, userID string) (exists bool, err error)
|
||||
InviteCodeExists(ctx context.Context, userID string) (exists bool, err error)
|
||||
}
|
||||
|
||||
type userCommandProvider interface {
|
||||
@@ -1254,8 +1255,18 @@ func (repo *AuthRequestRepo) firstFactorChecked(ctx context.Context, request *do
|
||||
|
||||
if user.PasswordInitRequired {
|
||||
if !user.IsEmailVerified {
|
||||
// If the user was created through the user resource API,
|
||||
// they can either have an invite code...
|
||||
exists, err := repo.UserEventProvider.InviteCodeExists(ctx, user.ID)
|
||||
logging.WithFields("userID", user.ID).OnError(err).Error("unable to check if invite code exists")
|
||||
if err == nil && exists {
|
||||
return &domain.VerifyInviteStep{}
|
||||
}
|
||||
// or were created with an explicit email verification mail
|
||||
return &domain.VerifyEMailStep{InitPassword: true}
|
||||
}
|
||||
// If they were created with a verified mail, they might have never received mail to set their password,
|
||||
// e.g. when created through a user resource API. In this case we'll just create and send one now.
|
||||
exists, err := repo.UserEventProvider.PasswordCodeExists(ctx, user.ID)
|
||||
logging.WithFields("userID", user.ID).OnError(err).Error("unable to check if password code exists")
|
||||
if err == nil && !exists {
|
||||
|
Reference in New Issue
Block a user