mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 20:37:31 +00:00
support reset pw
This commit is contained in:
@@ -523,6 +523,221 @@ func Test_userNotifier_reducePasswordChanged(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_userNotifier_reducePasswordCodeAdded(t *testing.T) {
|
||||||
|
expectMailSubject := "Reset password"
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
test func(*gomock.Controller, *mock.MockQueries, *mock.MockCommands) (fields, args, want)
|
||||||
|
}{{
|
||||||
|
name: "asset url with event trigger url",
|
||||||
|
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) {
|
||||||
|
givenTemplate := "{{.LogoURL}}"
|
||||||
|
expectContent := fmt.Sprintf("%s%s/%s/%s", eventOrigin, assetsPath, policyID, logoURL)
|
||||||
|
w.message = messages.Email{
|
||||||
|
Recipients: []string{lastEmail},
|
||||||
|
Subject: expectMailSubject,
|
||||||
|
Content: expectContent,
|
||||||
|
}
|
||||||
|
codeAlg, code := cryptoValue(t, ctrl, "testcode")
|
||||||
|
expectTemplateQueries(queries, givenTemplate)
|
||||||
|
commands.EXPECT().PasswordCodeSent(gomock.Any(), orgID, userID).Return(nil)
|
||||||
|
return fields{
|
||||||
|
queries: queries,
|
||||||
|
commands: commands,
|
||||||
|
es: eventstore.NewEventstore(eventstore.TestConfig(
|
||||||
|
es_repo_mock.NewRepo(t).ExpectFilterEvents(),
|
||||||
|
)),
|
||||||
|
userDataCrypto: codeAlg,
|
||||||
|
}, args{
|
||||||
|
event: &user.HumanPasswordCodeAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: sql.NullString{String: orgID},
|
||||||
|
CreationDate: time.Now().UTC(),
|
||||||
|
}),
|
||||||
|
Code: code,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
URLTemplate: "",
|
||||||
|
CodeReturned: false,
|
||||||
|
TriggeredAtOrigin: eventOrigin,
|
||||||
|
},
|
||||||
|
}, w
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "asset url without event trigger url",
|
||||||
|
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) {
|
||||||
|
givenTemplate := "{{.LogoURL}}"
|
||||||
|
expectContent := fmt.Sprintf("%s://%s:%d%s/%s/%s", externalProtocol, instancePrimaryDomain, externalPort, assetsPath, policyID, logoURL)
|
||||||
|
w.message = messages.Email{
|
||||||
|
Recipients: []string{lastEmail},
|
||||||
|
Subject: expectMailSubject,
|
||||||
|
Content: expectContent,
|
||||||
|
}
|
||||||
|
codeAlg, code := cryptoValue(t, ctrl, "testcode")
|
||||||
|
queries.EXPECT().SearchInstanceDomains(gomock.Any(), gomock.Any()).Return(&query.InstanceDomains{
|
||||||
|
Domains: []*query.InstanceDomain{{
|
||||||
|
Domain: instancePrimaryDomain,
|
||||||
|
IsPrimary: true,
|
||||||
|
}},
|
||||||
|
}, nil)
|
||||||
|
expectTemplateQueries(queries, givenTemplate)
|
||||||
|
commands.EXPECT().PasswordCodeSent(gomock.Any(), orgID, userID).Return(nil)
|
||||||
|
return fields{
|
||||||
|
queries: queries,
|
||||||
|
commands: commands,
|
||||||
|
es: eventstore.NewEventstore(eventstore.TestConfig(
|
||||||
|
es_repo_mock.NewRepo(t).ExpectFilterEvents(),
|
||||||
|
)),
|
||||||
|
userDataCrypto: codeAlg,
|
||||||
|
}, args{
|
||||||
|
event: &user.HumanPasswordCodeAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: sql.NullString{String: orgID},
|
||||||
|
CreationDate: time.Now().UTC(),
|
||||||
|
}),
|
||||||
|
Code: code,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
URLTemplate: "",
|
||||||
|
CodeReturned: false,
|
||||||
|
},
|
||||||
|
}, w
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "button url with event trigger url",
|
||||||
|
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) {
|
||||||
|
givenTemplate := "{{.URL}}"
|
||||||
|
testCode := "testcode"
|
||||||
|
expectContent := fmt.Sprintf("%s/ui/login/password/init?userID=%s&code=%s&orgID=%s", eventOrigin, userID, testCode, orgID)
|
||||||
|
w.message = messages.Email{
|
||||||
|
Recipients: []string{lastEmail},
|
||||||
|
Subject: expectMailSubject,
|
||||||
|
Content: expectContent,
|
||||||
|
}
|
||||||
|
codeAlg, code := cryptoValue(t, ctrl, testCode)
|
||||||
|
expectTemplateQueries(queries, givenTemplate)
|
||||||
|
commands.EXPECT().PasswordCodeSent(gomock.Any(), orgID, userID).Return(nil)
|
||||||
|
return fields{
|
||||||
|
queries: queries,
|
||||||
|
commands: commands,
|
||||||
|
es: eventstore.NewEventstore(eventstore.TestConfig(
|
||||||
|
es_repo_mock.NewRepo(t).ExpectFilterEvents(),
|
||||||
|
)),
|
||||||
|
userDataCrypto: codeAlg,
|
||||||
|
SMSTokenCrypto: nil,
|
||||||
|
}, args{
|
||||||
|
event: &user.HumanPasswordCodeAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: sql.NullString{String: orgID},
|
||||||
|
CreationDate: time.Now().UTC(),
|
||||||
|
}),
|
||||||
|
Code: code,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
URLTemplate: "",
|
||||||
|
CodeReturned: false,
|
||||||
|
TriggeredAtOrigin: eventOrigin,
|
||||||
|
},
|
||||||
|
}, w
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "button url without event trigger url",
|
||||||
|
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) {
|
||||||
|
givenTemplate := "{{.URL}}"
|
||||||
|
testCode := "testcode"
|
||||||
|
expectContent := fmt.Sprintf("%s://%s:%d/ui/login/password/init?userID=%s&code=%s&orgID=%s", externalProtocol, instancePrimaryDomain, externalPort, userID, testCode, orgID)
|
||||||
|
w.message = messages.Email{
|
||||||
|
Recipients: []string{lastEmail},
|
||||||
|
Subject: expectMailSubject,
|
||||||
|
Content: expectContent,
|
||||||
|
}
|
||||||
|
codeAlg, code := cryptoValue(t, ctrl, testCode)
|
||||||
|
queries.EXPECT().SearchInstanceDomains(gomock.Any(), gomock.Any()).Return(&query.InstanceDomains{
|
||||||
|
Domains: []*query.InstanceDomain{{
|
||||||
|
Domain: instancePrimaryDomain,
|
||||||
|
IsPrimary: true,
|
||||||
|
}},
|
||||||
|
}, nil)
|
||||||
|
expectTemplateQueries(queries, givenTemplate)
|
||||||
|
commands.EXPECT().PasswordCodeSent(gomock.Any(), orgID, userID).Return(nil)
|
||||||
|
return fields{
|
||||||
|
queries: queries,
|
||||||
|
commands: commands,
|
||||||
|
es: eventstore.NewEventstore(eventstore.TestConfig(
|
||||||
|
es_repo_mock.NewRepo(t).ExpectFilterEvents(),
|
||||||
|
)),
|
||||||
|
userDataCrypto: codeAlg,
|
||||||
|
}, args{
|
||||||
|
event: &user.HumanPasswordCodeAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: sql.NullString{String: orgID},
|
||||||
|
CreationDate: time.Now().UTC(),
|
||||||
|
}),
|
||||||
|
Code: code,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
URLTemplate: "",
|
||||||
|
CodeReturned: false,
|
||||||
|
},
|
||||||
|
}, w
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "button url with url template and event trigger url",
|
||||||
|
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) {
|
||||||
|
givenTemplate := "{{.URL}}"
|
||||||
|
urlTemplate := "https://my.custom.url/org/{{.OrgID}}/user/{{.UserID}}/verify/{{.Code}}"
|
||||||
|
testCode := "testcode"
|
||||||
|
expectContent := fmt.Sprintf("https://my.custom.url/org/%s/user/%s/verify/%s", orgID, userID, testCode)
|
||||||
|
w.message = messages.Email{
|
||||||
|
Recipients: []string{lastEmail},
|
||||||
|
Subject: expectMailSubject,
|
||||||
|
Content: expectContent,
|
||||||
|
}
|
||||||
|
codeAlg, code := cryptoValue(t, ctrl, testCode)
|
||||||
|
expectTemplateQueries(queries, givenTemplate)
|
||||||
|
commands.EXPECT().PasswordCodeSent(gomock.Any(), orgID, userID).Return(nil)
|
||||||
|
return fields{
|
||||||
|
queries: queries,
|
||||||
|
commands: commands,
|
||||||
|
es: eventstore.NewEventstore(eventstore.TestConfig(
|
||||||
|
es_repo_mock.NewRepo(t).ExpectFilterEvents(),
|
||||||
|
)),
|
||||||
|
userDataCrypto: codeAlg,
|
||||||
|
SMSTokenCrypto: nil,
|
||||||
|
}, args{
|
||||||
|
event: &user.HumanPasswordCodeAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: sql.NullString{String: orgID},
|
||||||
|
CreationDate: time.Now().UTC(),
|
||||||
|
}),
|
||||||
|
Code: code,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
URLTemplate: urlTemplate,
|
||||||
|
CodeReturned: false,
|
||||||
|
TriggeredAtOrigin: eventOrigin,
|
||||||
|
},
|
||||||
|
}, w
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
fs, err := statik_fs.NewWithNamespace("notification")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
queries := mock.NewMockQueries(ctrl)
|
||||||
|
commands := mock.NewMockCommands(ctrl)
|
||||||
|
f, a, w := tt.test(ctrl, queries, commands)
|
||||||
|
_, err = newUserNotifier(t, ctrl, queries, fs, f, a, w).reducePasswordCodeAdded(a.event)
|
||||||
|
if w.err != nil {
|
||||||
|
w.err(t, err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type fields struct {
|
type fields struct {
|
||||||
queries *mock.MockQueries
|
queries *mock.MockQueries
|
||||||
commands *mock.MockCommands
|
commands *mock.MockCommands
|
||||||
|
@@ -82,11 +82,12 @@ func HumanPasswordChangedEventMapper(event *repository.Event) (eventstore.Event,
|
|||||||
type HumanPasswordCodeAddedEvent struct {
|
type HumanPasswordCodeAddedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
Code *crypto.CryptoValue `json:"code,omitempty"`
|
Code *crypto.CryptoValue `json:"code,omitempty"`
|
||||||
Expiry time.Duration `json:"expiry,omitempty"`
|
Expiry time.Duration `json:"expiry,omitempty"`
|
||||||
NotificationType domain.NotificationType `json:"notificationType,omitempty"`
|
NotificationType domain.NotificationType `json:"notificationType,omitempty"`
|
||||||
URLTemplate string `json:"url_template,omitempty"`
|
URLTemplate string `json:"url_template,omitempty"`
|
||||||
CodeReturned bool `json:"code_returned,omitempty"`
|
CodeReturned bool `json:"code_returned,omitempty"`
|
||||||
|
TriggeredAtOrigin string `json:"base_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HumanPasswordCodeAddedEvent) Data() interface{} {
|
func (e *HumanPasswordCodeAddedEvent) Data() interface{} {
|
||||||
@@ -97,6 +98,10 @@ func (e *HumanPasswordCodeAddedEvent) UniqueConstraints() []*eventstore.EventUni
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *HumanPasswordCodeAddedEvent) TriggerOrigin() string {
|
||||||
|
return e.TriggeredAtOrigin
|
||||||
|
}
|
||||||
|
|
||||||
func NewHumanPasswordCodeAddedEvent(
|
func NewHumanPasswordCodeAddedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
|
Reference in New Issue
Block a user