mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 18:17:35 +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:
@@ -17,6 +17,7 @@ const (
|
||||
DomainClaimedMessageType = "DomainClaimed"
|
||||
PasswordlessRegistrationMessageType = "PasswordlessRegistration"
|
||||
PasswordChangeMessageType = "PasswordChange"
|
||||
InviteUserMessageType = "InviteUser"
|
||||
MessageTitle = "Title"
|
||||
MessagePreHeader = "PreHeader"
|
||||
MessageSubject = "Subject"
|
||||
@@ -26,16 +27,6 @@ const (
|
||||
MessageFooterText = "Footer"
|
||||
)
|
||||
|
||||
type MessageTexts struct {
|
||||
InitCode CustomMessageText
|
||||
PasswordReset CustomMessageText
|
||||
VerifyEmail CustomMessageText
|
||||
VerifyPhone CustomMessageText
|
||||
DomainClaimed CustomMessageText
|
||||
PasswordlessRegistration CustomMessageText
|
||||
PasswordChange CustomMessageText
|
||||
}
|
||||
|
||||
type CustomMessageText struct {
|
||||
models.ObjectRoot
|
||||
|
||||
@@ -71,5 +62,6 @@ func IsMessageTextType(textType string) bool {
|
||||
textType == VerifyEmailOTPMessageType ||
|
||||
textType == DomainClaimedMessageType ||
|
||||
textType == PasswordlessRegistrationMessageType ||
|
||||
textType == PasswordChangeMessageType
|
||||
textType == PasswordChangeMessageType ||
|
||||
textType == InviteUserMessageType
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ const (
|
||||
NextStepProjectRequired
|
||||
NextStepRedirectToExternalIDP
|
||||
NextStepLoginSucceeded
|
||||
NextStepVerifyInvite
|
||||
)
|
||||
|
||||
type LoginStep struct{}
|
||||
@@ -191,3 +192,9 @@ type LoginSucceededStep struct{}
|
||||
func (s *LoginSucceededStep) Type() NextStepType {
|
||||
return NextStepLoginSucceeded
|
||||
}
|
||||
|
||||
type VerifyInviteStep struct{}
|
||||
|
||||
func (s *VerifyInviteStep) Type() NextStepType {
|
||||
return NextStepVerifyInvite
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ const (
|
||||
SecretGeneratorTypeAppSecret
|
||||
SecretGeneratorTypeOTPSMS
|
||||
SecretGeneratorTypeOTPEmail
|
||||
SecretGeneratorTypeInviteCode
|
||||
|
||||
secretGeneratorTypeCount
|
||||
)
|
||||
|
@@ -4,14 +4,11 @@ package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const _SecretGeneratorTypeName = "unspecifiedinit_codeverify_email_codeverify_phone_codeverify_domainpassword_reset_codepasswordless_init_codeapp_secretotpsmsotp_emailsecret_generator_type_count"
|
||||
const _SecretGeneratorTypeName = "unspecifiedinit_codeverify_email_codeverify_phone_codeverify_domainpassword_reset_codepasswordless_init_codeapp_secretotpsmsotp_emailinvite_codesecret_generator_type_count"
|
||||
|
||||
var _SecretGeneratorTypeIndex = [...]uint8{0, 11, 20, 37, 54, 67, 86, 108, 118, 124, 133, 160}
|
||||
|
||||
const _SecretGeneratorTypeLowerName = "unspecifiedinit_codeverify_email_codeverify_phone_codeverify_domainpassword_reset_codepasswordless_init_codeapp_secretotpsmsotp_emailsecret_generator_type_count"
|
||||
var _SecretGeneratorTypeIndex = [...]uint8{0, 11, 20, 37, 54, 67, 86, 108, 118, 124, 133, 144, 171}
|
||||
|
||||
func (i SecretGeneratorType) String() string {
|
||||
if i < 0 || i >= SecretGeneratorType(len(_SecretGeneratorTypeIndex)-1) {
|
||||
@@ -20,62 +17,21 @@ func (i SecretGeneratorType) String() string {
|
||||
return _SecretGeneratorTypeName[_SecretGeneratorTypeIndex[i]:_SecretGeneratorTypeIndex[i+1]]
|
||||
}
|
||||
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
func _SecretGeneratorTypeNoOp() {
|
||||
var x [1]struct{}
|
||||
_ = x[SecretGeneratorTypeUnspecified-(0)]
|
||||
_ = x[SecretGeneratorTypeInitCode-(1)]
|
||||
_ = x[SecretGeneratorTypeVerifyEmailCode-(2)]
|
||||
_ = x[SecretGeneratorTypeVerifyPhoneCode-(3)]
|
||||
_ = x[SecretGeneratorTypeVerifyDomain-(4)]
|
||||
_ = x[SecretGeneratorTypePasswordResetCode-(5)]
|
||||
_ = x[SecretGeneratorTypePasswordlessInitCode-(6)]
|
||||
_ = x[SecretGeneratorTypeAppSecret-(7)]
|
||||
_ = x[SecretGeneratorTypeOTPSMS-(8)]
|
||||
_ = x[SecretGeneratorTypeOTPEmail-(9)]
|
||||
_ = x[secretGeneratorTypeCount-(10)]
|
||||
}
|
||||
|
||||
var _SecretGeneratorTypeValues = []SecretGeneratorType{SecretGeneratorTypeUnspecified, SecretGeneratorTypeInitCode, SecretGeneratorTypeVerifyEmailCode, SecretGeneratorTypeVerifyPhoneCode, SecretGeneratorTypeVerifyDomain, SecretGeneratorTypePasswordResetCode, SecretGeneratorTypePasswordlessInitCode, SecretGeneratorTypeAppSecret, SecretGeneratorTypeOTPSMS, SecretGeneratorTypeOTPEmail, secretGeneratorTypeCount}
|
||||
var _SecretGeneratorTypeValues = []SecretGeneratorType{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
|
||||
var _SecretGeneratorTypeNameToValueMap = map[string]SecretGeneratorType{
|
||||
_SecretGeneratorTypeName[0:11]: SecretGeneratorTypeUnspecified,
|
||||
_SecretGeneratorTypeLowerName[0:11]: SecretGeneratorTypeUnspecified,
|
||||
_SecretGeneratorTypeName[11:20]: SecretGeneratorTypeInitCode,
|
||||
_SecretGeneratorTypeLowerName[11:20]: SecretGeneratorTypeInitCode,
|
||||
_SecretGeneratorTypeName[20:37]: SecretGeneratorTypeVerifyEmailCode,
|
||||
_SecretGeneratorTypeLowerName[20:37]: SecretGeneratorTypeVerifyEmailCode,
|
||||
_SecretGeneratorTypeName[37:54]: SecretGeneratorTypeVerifyPhoneCode,
|
||||
_SecretGeneratorTypeLowerName[37:54]: SecretGeneratorTypeVerifyPhoneCode,
|
||||
_SecretGeneratorTypeName[54:67]: SecretGeneratorTypeVerifyDomain,
|
||||
_SecretGeneratorTypeLowerName[54:67]: SecretGeneratorTypeVerifyDomain,
|
||||
_SecretGeneratorTypeName[67:86]: SecretGeneratorTypePasswordResetCode,
|
||||
_SecretGeneratorTypeLowerName[67:86]: SecretGeneratorTypePasswordResetCode,
|
||||
_SecretGeneratorTypeName[86:108]: SecretGeneratorTypePasswordlessInitCode,
|
||||
_SecretGeneratorTypeLowerName[86:108]: SecretGeneratorTypePasswordlessInitCode,
|
||||
_SecretGeneratorTypeName[108:118]: SecretGeneratorTypeAppSecret,
|
||||
_SecretGeneratorTypeLowerName[108:118]: SecretGeneratorTypeAppSecret,
|
||||
_SecretGeneratorTypeName[118:124]: SecretGeneratorTypeOTPSMS,
|
||||
_SecretGeneratorTypeLowerName[118:124]: SecretGeneratorTypeOTPSMS,
|
||||
_SecretGeneratorTypeName[124:133]: SecretGeneratorTypeOTPEmail,
|
||||
_SecretGeneratorTypeLowerName[124:133]: SecretGeneratorTypeOTPEmail,
|
||||
_SecretGeneratorTypeName[133:160]: secretGeneratorTypeCount,
|
||||
_SecretGeneratorTypeLowerName[133:160]: secretGeneratorTypeCount,
|
||||
}
|
||||
|
||||
var _SecretGeneratorTypeNames = []string{
|
||||
_SecretGeneratorTypeName[0:11],
|
||||
_SecretGeneratorTypeName[11:20],
|
||||
_SecretGeneratorTypeName[20:37],
|
||||
_SecretGeneratorTypeName[37:54],
|
||||
_SecretGeneratorTypeName[54:67],
|
||||
_SecretGeneratorTypeName[67:86],
|
||||
_SecretGeneratorTypeName[86:108],
|
||||
_SecretGeneratorTypeName[108:118],
|
||||
_SecretGeneratorTypeName[118:124],
|
||||
_SecretGeneratorTypeName[124:133],
|
||||
_SecretGeneratorTypeName[133:160],
|
||||
_SecretGeneratorTypeName[0:11]: 0,
|
||||
_SecretGeneratorTypeName[11:20]: 1,
|
||||
_SecretGeneratorTypeName[20:37]: 2,
|
||||
_SecretGeneratorTypeName[37:54]: 3,
|
||||
_SecretGeneratorTypeName[54:67]: 4,
|
||||
_SecretGeneratorTypeName[67:86]: 5,
|
||||
_SecretGeneratorTypeName[86:108]: 6,
|
||||
_SecretGeneratorTypeName[108:118]: 7,
|
||||
_SecretGeneratorTypeName[118:124]: 8,
|
||||
_SecretGeneratorTypeName[124:133]: 9,
|
||||
_SecretGeneratorTypeName[133:144]: 10,
|
||||
_SecretGeneratorTypeName[144:171]: 11,
|
||||
}
|
||||
|
||||
// SecretGeneratorTypeString retrieves an enum value from the enum constants string name.
|
||||
@@ -84,10 +40,6 @@ func SecretGeneratorTypeString(s string) (SecretGeneratorType, error) {
|
||||
if val, ok := _SecretGeneratorTypeNameToValueMap[s]; ok {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
if val, ok := _SecretGeneratorTypeNameToValueMap[strings.ToLower(s)]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return 0, fmt.Errorf("%s does not belong to SecretGeneratorType values", s)
|
||||
}
|
||||
|
||||
@@ -96,13 +48,6 @@ func SecretGeneratorTypeValues() []SecretGeneratorType {
|
||||
return _SecretGeneratorTypeValues
|
||||
}
|
||||
|
||||
// SecretGeneratorTypeStrings returns a slice of all String values of the enum
|
||||
func SecretGeneratorTypeStrings() []string {
|
||||
strs := make([]string, len(_SecretGeneratorTypeNames))
|
||||
copy(strs, _SecretGeneratorTypeNames)
|
||||
return strs
|
||||
}
|
||||
|
||||
// IsASecretGeneratorType returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i SecretGeneratorType) IsASecretGeneratorType() bool {
|
||||
for _, v := range _SecretGeneratorTypeValues {
|
||||
|
Reference in New Issue
Block a user