mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:17:32 +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:
@@ -19,6 +19,7 @@ type Commands interface {
|
||||
HumanPasswordlessInitCodeSent(ctx context.Context, userID, resourceOwner, codeID string) error
|
||||
PasswordChangeSent(ctx context.Context, orgID, userID string) error
|
||||
HumanPhoneVerificationCodeSent(ctx context.Context, orgID, userID string) error
|
||||
InviteCodeSent(ctx context.Context, orgID, userID string) error
|
||||
UsageNotificationSent(ctx context.Context, dueEvent *quota.NotificationDueEvent) error
|
||||
MilestonePushed(ctx context.Context, msType milestone.Type, endpoints []string, primaryDomain string) error
|
||||
}
|
||||
|
@@ -18,30 +18,30 @@ import (
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockCommands is a mock of Commands interface.
|
||||
// MockCommands is a mock of Commands interface
|
||||
type MockCommands struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCommandsMockRecorder
|
||||
}
|
||||
|
||||
// MockCommandsMockRecorder is the mock recorder for MockCommands.
|
||||
// MockCommandsMockRecorder is the mock recorder for MockCommands
|
||||
type MockCommandsMockRecorder struct {
|
||||
mock *MockCommands
|
||||
}
|
||||
|
||||
// NewMockCommands creates a new mock instance.
|
||||
// NewMockCommands creates a new mock instance
|
||||
func NewMockCommands(ctrl *gomock.Controller) *MockCommands {
|
||||
mock := &MockCommands{ctrl: ctrl}
|
||||
mock.recorder = &MockCommandsMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockCommands) EXPECT() *MockCommandsMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// HumanEmailVerificationCodeSent mocks base method.
|
||||
// HumanEmailVerificationCodeSent mocks base method
|
||||
func (m *MockCommands) HumanEmailVerificationCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanEmailVerificationCodeSent", arg0, arg1, arg2)
|
||||
@@ -49,13 +49,13 @@ func (m *MockCommands) HumanEmailVerificationCodeSent(arg0 context.Context, arg1
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanEmailVerificationCodeSent indicates an expected call of HumanEmailVerificationCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanEmailVerificationCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// HumanEmailVerificationCodeSent indicates an expected call of HumanEmailVerificationCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanEmailVerificationCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanEmailVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanEmailVerificationCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// HumanInitCodeSent mocks base method.
|
||||
// HumanInitCodeSent mocks base method
|
||||
func (m *MockCommands) HumanInitCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanInitCodeSent", arg0, arg1, arg2)
|
||||
@@ -63,13 +63,13 @@ func (m *MockCommands) HumanInitCodeSent(arg0 context.Context, arg1, arg2 string
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanInitCodeSent indicates an expected call of HumanInitCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanInitCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// HumanInitCodeSent indicates an expected call of HumanInitCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanInitCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanInitCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// HumanOTPEmailCodeSent mocks base method.
|
||||
// HumanOTPEmailCodeSent mocks base method
|
||||
func (m *MockCommands) HumanOTPEmailCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanOTPEmailCodeSent", arg0, arg1, arg2)
|
||||
@@ -77,13 +77,13 @@ func (m *MockCommands) HumanOTPEmailCodeSent(arg0 context.Context, arg1, arg2 st
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanOTPEmailCodeSent indicates an expected call of HumanOTPEmailCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanOTPEmailCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// HumanOTPEmailCodeSent indicates an expected call of HumanOTPEmailCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanOTPEmailCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPEmailCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPEmailCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// HumanOTPSMSCodeSent mocks base method.
|
||||
// HumanOTPSMSCodeSent mocks base method
|
||||
func (m *MockCommands) HumanOTPSMSCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanOTPSMSCodeSent", arg0, arg1, arg2)
|
||||
@@ -91,13 +91,13 @@ func (m *MockCommands) HumanOTPSMSCodeSent(arg0 context.Context, arg1, arg2 stri
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanOTPSMSCodeSent indicates an expected call of HumanOTPSMSCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanOTPSMSCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// HumanOTPSMSCodeSent indicates an expected call of HumanOTPSMSCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanOTPSMSCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPSMSCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPSMSCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// HumanPasswordlessInitCodeSent mocks base method.
|
||||
// HumanPasswordlessInitCodeSent mocks base method
|
||||
func (m *MockCommands) HumanPasswordlessInitCodeSent(arg0 context.Context, arg1, arg2, arg3 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanPasswordlessInitCodeSent", arg0, arg1, arg2, arg3)
|
||||
@@ -105,13 +105,13 @@ func (m *MockCommands) HumanPasswordlessInitCodeSent(arg0 context.Context, arg1,
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanPasswordlessInitCodeSent indicates an expected call of HumanPasswordlessInitCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanPasswordlessInitCodeSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
// HumanPasswordlessInitCodeSent indicates an expected call of HumanPasswordlessInitCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanPasswordlessInitCodeSent(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPasswordlessInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPasswordlessInitCodeSent), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// HumanPhoneVerificationCodeSent mocks base method.
|
||||
// HumanPhoneVerificationCodeSent mocks base method
|
||||
func (m *MockCommands) HumanPhoneVerificationCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HumanPhoneVerificationCodeSent", arg0, arg1, arg2)
|
||||
@@ -119,13 +119,27 @@ func (m *MockCommands) HumanPhoneVerificationCodeSent(arg0 context.Context, arg1
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HumanPhoneVerificationCodeSent indicates an expected call of HumanPhoneVerificationCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) HumanPhoneVerificationCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// HumanPhoneVerificationCodeSent indicates an expected call of HumanPhoneVerificationCodeSent
|
||||
func (mr *MockCommandsMockRecorder) HumanPhoneVerificationCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPhoneVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPhoneVerificationCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// MilestonePushed mocks base method.
|
||||
// InviteCodeSent mocks base method
|
||||
func (m *MockCommands) InviteCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InviteCodeSent", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// InviteCodeSent indicates an expected call of InviteCodeSent
|
||||
func (mr *MockCommandsMockRecorder) InviteCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InviteCodeSent", reflect.TypeOf((*MockCommands)(nil).InviteCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// MilestonePushed mocks base method
|
||||
func (m *MockCommands) MilestonePushed(arg0 context.Context, arg1 milestone.Type, arg2 []string, arg3 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MilestonePushed", arg0, arg1, arg2, arg3)
|
||||
@@ -133,13 +147,13 @@ func (m *MockCommands) MilestonePushed(arg0 context.Context, arg1 milestone.Type
|
||||
return ret0
|
||||
}
|
||||
|
||||
// MilestonePushed indicates an expected call of MilestonePushed.
|
||||
func (mr *MockCommandsMockRecorder) MilestonePushed(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
// MilestonePushed indicates an expected call of MilestonePushed
|
||||
func (mr *MockCommandsMockRecorder) MilestonePushed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MilestonePushed", reflect.TypeOf((*MockCommands)(nil).MilestonePushed), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// OTPEmailSent mocks base method.
|
||||
// OTPEmailSent mocks base method
|
||||
func (m *MockCommands) OTPEmailSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "OTPEmailSent", arg0, arg1, arg2)
|
||||
@@ -147,13 +161,13 @@ func (m *MockCommands) OTPEmailSent(arg0 context.Context, arg1, arg2 string) err
|
||||
return ret0
|
||||
}
|
||||
|
||||
// OTPEmailSent indicates an expected call of OTPEmailSent.
|
||||
func (mr *MockCommandsMockRecorder) OTPEmailSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// OTPEmailSent indicates an expected call of OTPEmailSent
|
||||
func (mr *MockCommandsMockRecorder) OTPEmailSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPEmailSent", reflect.TypeOf((*MockCommands)(nil).OTPEmailSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// OTPSMSSent mocks base method.
|
||||
// OTPSMSSent mocks base method
|
||||
func (m *MockCommands) OTPSMSSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "OTPSMSSent", arg0, arg1, arg2)
|
||||
@@ -161,13 +175,13 @@ func (m *MockCommands) OTPSMSSent(arg0 context.Context, arg1, arg2 string) error
|
||||
return ret0
|
||||
}
|
||||
|
||||
// OTPSMSSent indicates an expected call of OTPSMSSent.
|
||||
func (mr *MockCommandsMockRecorder) OTPSMSSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// OTPSMSSent indicates an expected call of OTPSMSSent
|
||||
func (mr *MockCommandsMockRecorder) OTPSMSSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPSMSSent", reflect.TypeOf((*MockCommands)(nil).OTPSMSSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// PasswordChangeSent mocks base method.
|
||||
// PasswordChangeSent mocks base method
|
||||
func (m *MockCommands) PasswordChangeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PasswordChangeSent", arg0, arg1, arg2)
|
||||
@@ -175,13 +189,13 @@ func (m *MockCommands) PasswordChangeSent(arg0 context.Context, arg1, arg2 strin
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PasswordChangeSent indicates an expected call of PasswordChangeSent.
|
||||
func (mr *MockCommandsMockRecorder) PasswordChangeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// PasswordChangeSent indicates an expected call of PasswordChangeSent
|
||||
func (mr *MockCommandsMockRecorder) PasswordChangeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordChangeSent", reflect.TypeOf((*MockCommands)(nil).PasswordChangeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// PasswordCodeSent mocks base method.
|
||||
// PasswordCodeSent mocks base method
|
||||
func (m *MockCommands) PasswordCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PasswordCodeSent", arg0, arg1, arg2)
|
||||
@@ -189,13 +203,13 @@ func (m *MockCommands) PasswordCodeSent(arg0 context.Context, arg1, arg2 string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PasswordCodeSent indicates an expected call of PasswordCodeSent.
|
||||
func (mr *MockCommandsMockRecorder) PasswordCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// PasswordCodeSent indicates an expected call of PasswordCodeSent
|
||||
func (mr *MockCommandsMockRecorder) PasswordCodeSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordCodeSent", reflect.TypeOf((*MockCommands)(nil).PasswordCodeSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// UsageNotificationSent mocks base method.
|
||||
// UsageNotificationSent mocks base method
|
||||
func (m *MockCommands) UsageNotificationSent(arg0 context.Context, arg1 *quota.NotificationDueEvent) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UsageNotificationSent", arg0, arg1)
|
||||
@@ -203,13 +217,13 @@ func (m *MockCommands) UsageNotificationSent(arg0 context.Context, arg1 *quota.N
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UsageNotificationSent indicates an expected call of UsageNotificationSent.
|
||||
func (mr *MockCommandsMockRecorder) UsageNotificationSent(arg0, arg1 any) *gomock.Call {
|
||||
// UsageNotificationSent indicates an expected call of UsageNotificationSent
|
||||
func (mr *MockCommandsMockRecorder) UsageNotificationSent(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UsageNotificationSent", reflect.TypeOf((*MockCommands)(nil).UsageNotificationSent), arg0, arg1)
|
||||
}
|
||||
|
||||
// UserDomainClaimedSent mocks base method.
|
||||
// UserDomainClaimedSent mocks base method
|
||||
func (m *MockCommands) UserDomainClaimedSent(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UserDomainClaimedSent", arg0, arg1, arg2)
|
||||
@@ -217,8 +231,8 @@ func (m *MockCommands) UserDomainClaimedSent(arg0 context.Context, arg1, arg2 st
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UserDomainClaimedSent indicates an expected call of UserDomainClaimedSent.
|
||||
func (mr *MockCommandsMockRecorder) UserDomainClaimedSent(arg0, arg1, arg2 any) *gomock.Call {
|
||||
// UserDomainClaimedSent indicates an expected call of UserDomainClaimedSent
|
||||
func (mr *MockCommandsMockRecorder) UserDomainClaimedSent(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UserDomainClaimedSent", reflect.TypeOf((*MockCommands)(nil).UserDomainClaimedSent), arg0, arg1, arg2)
|
||||
}
|
||||
|
@@ -106,6 +106,10 @@ func (u *userNotifier) Reducers() []handler.AggregateReducer {
|
||||
Event: user.HumanOTPEmailCodeAddedType,
|
||||
Reduce: u.reduceOTPEmailCodeAdded,
|
||||
},
|
||||
{
|
||||
Event: user.HumanInviteCodeAddedType,
|
||||
Reduce: u.reduceInviteCodeAdded,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -718,6 +722,61 @@ func (u *userNotifier) reducePhoneCodeAdded(event eventstore.Event) (*handler.St
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceInviteCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*user.HumanInviteCodeAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Eeg3s", "reduce.wrong.event.type %s", user.HumanInviteCodeAddedType)
|
||||
}
|
||||
if e.CodeReturned {
|
||||
return handler.NewNoOpStatement(e), nil
|
||||
}
|
||||
|
||||
return handler.NewStatement(event, func(ex handler.Executer, projectionName string) error {
|
||||
ctx := HandlerContext(event.Aggregate())
|
||||
alreadyHandled, err := u.checkIfCodeAlreadyHandledOrExpired(ctx, event, e.Expiry, nil,
|
||||
user.HumanInviteCodeAddedType, user.HumanInviteCodeSentType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if alreadyHandled {
|
||||
return nil
|
||||
}
|
||||
code, err := crypto.DecryptString(e.Code, u.queries.UserDataCrypto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
colors, err := u.queries.ActiveLabelPolicyByOrg(ctx, e.Aggregate().ResourceOwner, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template, err := u.queries.MailTemplateByOrg(ctx, e.Aggregate().ResourceOwner, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notifyUser, err := u.queries.GetNotifyUserByID(ctx, true, e.Aggregate().ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
translator, err := u.queries.GetTranslatorWithOrgTexts(ctx, notifyUser.ResourceOwner, domain.InviteUserMessageType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, err = u.queries.Origin(ctx, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
notify := types.SendEmail(ctx, u.channels, string(template.Template), translator, notifyUser, colors, e)
|
||||
err = notify.SendInviteCode(ctx, notifyUser, code, e.ApplicationName, e.URLTemplate, e.AuthRequestID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return u.commands.InviteCodeSent(ctx, e.Aggregate().ID, e.Aggregate().ResourceOwner)
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) checkIfCodeAlreadyHandledOrExpired(ctx context.Context, event eventstore.Event, expiry time.Duration, data map[string]interface{}, eventTypes ...eventstore.EventType) (bool, error) {
|
||||
if event.CreatedAt().Add(expiry).Before(time.Now().UTC()) {
|
||||
return true, nil
|
||||
|
Reference in New Issue
Block a user