mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 07:57:32 +00:00
fix(notify): notify user in projection (#3889)
* start implement notify user in projection * fix(stmt): add copy to multi stmt * use projections for notify users * feat: notifications from projections * feat: notifications from projections * cleanup * pre-release * fix tests * fix types * fix command * fix queryNotifyUser * fix: build version * fix: HumanPasswordlessInitCodeSent Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
This commit is contained in:
@@ -20,18 +20,18 @@ var (
|
||||
", members.user_id" +
|
||||
", members.roles" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_machines.name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_machines.name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", COUNT(*) OVER () " +
|
||||
"FROM projections.instance_members as members " +
|
||||
"LEFT JOIN projections.users_humans " +
|
||||
"ON members.user_id = projections.users_humans.user_id " +
|
||||
"LEFT JOIN projections.users_machines " +
|
||||
"ON members.user_id = projections.users_machines.user_id " +
|
||||
"LEFT JOIN projections.users2_humans " +
|
||||
"ON members.user_id = projections.users2_humans.user_id " +
|
||||
"LEFT JOIN projections.users2_machines " +
|
||||
"ON members.user_id = projections.users2_machines.user_id " +
|
||||
"LEFT JOIN projections.login_names " +
|
||||
"ON members.user_id = projections.login_names.user_id " +
|
||||
"WHERE projections.login_names.is_primary = $1")
|
||||
|
@@ -20,18 +20,18 @@ var (
|
||||
", members.user_id" +
|
||||
", members.roles" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_machines.name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_machines.name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", COUNT(*) OVER () " +
|
||||
"FROM projections.org_members as members " +
|
||||
"LEFT JOIN projections.users_humans " +
|
||||
"ON members.user_id = projections.users_humans.user_id " +
|
||||
"LEFT JOIN projections.users_machines " +
|
||||
"ON members.user_id = projections.users_machines.user_id " +
|
||||
"LEFT JOIN projections.users2_humans " +
|
||||
"ON members.user_id = projections.users2_humans.user_id " +
|
||||
"LEFT JOIN projections.users2_machines " +
|
||||
"ON members.user_id = projections.users2_machines.user_id " +
|
||||
"LEFT JOIN projections.login_names " +
|
||||
"ON members.user_id = projections.login_names.user_id " +
|
||||
"WHERE projections.login_names.is_primary = $1")
|
||||
|
@@ -20,18 +20,18 @@ var (
|
||||
", members.user_id" +
|
||||
", members.roles" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_machines.name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_machines.name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", COUNT(*) OVER () " +
|
||||
"FROM projections.project_grant_members as members " +
|
||||
"LEFT JOIN projections.users_humans " +
|
||||
"ON members.user_id = projections.users_humans.user_id " +
|
||||
"LEFT JOIN projections.users_machines " +
|
||||
"ON members.user_id = projections.users_machines.user_id " +
|
||||
"LEFT JOIN projections.users2_humans " +
|
||||
"ON members.user_id = projections.users2_humans.user_id " +
|
||||
"LEFT JOIN projections.users2_machines " +
|
||||
"ON members.user_id = projections.users2_machines.user_id " +
|
||||
"LEFT JOIN projections.login_names " +
|
||||
"ON members.user_id = projections.login_names.user_id " +
|
||||
"LEFT JOIN projections.project_grants " +
|
||||
|
@@ -20,18 +20,18 @@ var (
|
||||
", members.user_id" +
|
||||
", members.roles" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_machines.name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_machines.name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", COUNT(*) OVER () " +
|
||||
"FROM projections.project_members as members " +
|
||||
"LEFT JOIN projections.users_humans " +
|
||||
"ON members.user_id = projections.users_humans.user_id " +
|
||||
"LEFT JOIN projections.users_machines " +
|
||||
"ON members.user_id = projections.users_machines.user_id " +
|
||||
"LEFT JOIN projections.users2_humans " +
|
||||
"ON members.user_id = projections.users2_humans.user_id " +
|
||||
"LEFT JOIN projections.users2_machines " +
|
||||
"ON members.user_id = projections.users2_machines.user_id " +
|
||||
"LEFT JOIN projections.login_names " +
|
||||
"ON members.user_id = projections.login_names.user_id " +
|
||||
"WHERE projections.login_names.is_primary = $1")
|
||||
|
@@ -358,6 +358,32 @@ func (p *labelPolicyProjection) reduceActivated(event eventstore.Event) (*handle
|
||||
handler.NewCol(LabelPolicyDarkLogoURLCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkIconURLCol, nil),
|
||||
},
|
||||
[]handler.Column{
|
||||
handler.NewCol(LabelPolicyChangeDateCol, nil),
|
||||
handler.NewCol(LabelPolicySequenceCol, nil),
|
||||
handler.NewCol(LabelPolicyStateCol, nil),
|
||||
handler.NewCol(LabelPolicyCreationDateCol, nil),
|
||||
handler.NewCol(LabelPolicyResourceOwnerCol, nil),
|
||||
handler.NewCol(LabelPolicyInstanceIDCol, nil),
|
||||
handler.NewCol(LabelPolicyIDCol, nil),
|
||||
handler.NewCol(LabelPolicyIsDefaultCol, nil),
|
||||
handler.NewCol(LabelPolicyHideLoginNameSuffixCol, nil),
|
||||
handler.NewCol(LabelPolicyFontURLCol, nil),
|
||||
handler.NewCol(LabelPolicyWatermarkDisabledCol, nil),
|
||||
handler.NewCol(LabelPolicyShouldErrorPopupCol, nil),
|
||||
handler.NewCol(LabelPolicyLightPrimaryColorCol, nil),
|
||||
handler.NewCol(LabelPolicyLightWarnColorCol, nil),
|
||||
handler.NewCol(LabelPolicyLightBackgroundColorCol, nil),
|
||||
handler.NewCol(LabelPolicyLightFontColorCol, nil),
|
||||
handler.NewCol(LabelPolicyLightLogoURLCol, nil),
|
||||
handler.NewCol(LabelPolicyLightIconURLCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkPrimaryColorCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkWarnColorCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkBackgroundColorCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkFontColorCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkLogoURLCol, nil),
|
||||
handler.NewCol(LabelPolicyDarkIconURLCol, nil),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(LabelPolicyIDCol, event.Aggregate().ID),
|
||||
handler.NewCond(LabelPolicyStateCol, domain.LabelPolicyStatePreview),
|
||||
|
@@ -18,6 +18,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
projectionConfig crdb.StatementHandlerConfig
|
||||
OrgProjection *orgProjection
|
||||
ActionProjection *actionProjection
|
||||
FlowProjection *flowProjection
|
||||
@@ -58,10 +59,11 @@ var (
|
||||
OIDCSettingsProjection *oidcSettingsProjection
|
||||
DebugNotificationProviderProjection *debugNotificationProviderProjection
|
||||
KeyProjection *keyProjection
|
||||
NotificationsProjection interface{}
|
||||
)
|
||||
|
||||
func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, config Config, keyEncryptionAlgorithm crypto.EncryptionAlgorithm) error {
|
||||
projectionConfig := crdb.StatementHandlerConfig{
|
||||
projectionConfig = crdb.StatementHandlerConfig{
|
||||
ProjectionHandlerConfig: handler.ProjectionHandlerConfig{
|
||||
HandlerConfig: handler.HandlerConfig{
|
||||
Eventstore: es,
|
||||
@@ -120,6 +122,11 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
|
||||
return nil
|
||||
}
|
||||
|
||||
func ApplyCustomConfig(customConfig CustomConfig) crdb.StatementHandlerConfig {
|
||||
return applyCustomConfig(projectionConfig, customConfig)
|
||||
|
||||
}
|
||||
|
||||
func applyCustomConfig(config crdb.StatementHandlerConfig, customConfig CustomConfig) crdb.StatementHandlerConfig {
|
||||
if customConfig.BulkLimit != nil {
|
||||
config.BulkLimit = *customConfig.BulkLimit
|
||||
|
@@ -17,9 +17,10 @@ type userProjection struct {
|
||||
}
|
||||
|
||||
const (
|
||||
UserTable = "projections.users"
|
||||
UserTable = "projections.users2"
|
||||
UserHumanTable = UserTable + "_" + UserHumanSuffix
|
||||
UserMachineTable = UserTable + "_" + UserMachineSuffix
|
||||
UserNotifyTable = UserTable + "_" + UserNotifySuffix
|
||||
|
||||
UserIDCol = "id"
|
||||
UserCreationDateCol = "creation_date"
|
||||
@@ -58,6 +59,16 @@ const (
|
||||
MachineUserInstanceIDCol = "instance_id"
|
||||
MachineNameCol = "name"
|
||||
MachineDescriptionCol = "description"
|
||||
|
||||
// notify
|
||||
UserNotifySuffix = "notifications"
|
||||
NotifyUserIDCol = "user_id"
|
||||
NotifyInstanceIDCol = "instance_id"
|
||||
NotifyLastEmailCol = "last_email"
|
||||
NotifyVerifiedEmailCol = "verified_email"
|
||||
NotifyLastPhoneCol = "last_phone"
|
||||
NotifyVerifiedPhoneCol = "verified_phone"
|
||||
NotifyPasswordSetCol = "password_set"
|
||||
)
|
||||
|
||||
func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig) *userProjection {
|
||||
@@ -110,6 +121,19 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
|
||||
UserMachineSuffix,
|
||||
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_machine_ref_user")),
|
||||
),
|
||||
crdb.NewSuffixedTable([]*crdb.Column{
|
||||
crdb.NewColumn(NotifyUserIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(NotifyInstanceIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(NotifyLastEmailCol, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
crdb.NewColumn(NotifyVerifiedEmailCol, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
crdb.NewColumn(NotifyLastPhoneCol, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
crdb.NewColumn(NotifyVerifiedPhoneCol, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
crdb.NewColumn(NotifyPasswordSetCol, crdb.ColumnTypeBool, crdb.Default(false)),
|
||||
},
|
||||
crdb.NewPrimaryKey(NotifyUserIDCol, NotifyInstanceIDCol),
|
||||
UserNotifySuffix,
|
||||
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_notify_ref_user")),
|
||||
),
|
||||
)
|
||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||
return p
|
||||
@@ -240,6 +264,10 @@ func (p *userProjection) reducers() []handler.AggregateReducer {
|
||||
Event: user.MachineChangedEventType,
|
||||
Reduce: p.reduceMachineChanged,
|
||||
},
|
||||
{
|
||||
Event: user.HumanPasswordChangedType,
|
||||
Reduce: p.reduceHumanPasswordChanged,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -280,6 +308,16 @@ func (p *userProjection) reduceHumanAdded(event eventstore.Event) (*handler.Stat
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCol(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
handler.NewCol(NotifyLastEmailCol, e.EmailAddress),
|
||||
handler.NewCol(NotifyLastPhoneCol, &sql.NullString{String: e.PhoneNumber, Valid: e.PhoneNumber != ""}),
|
||||
handler.NewCol(NotifyPasswordSetCol, e.Secret != nil),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -318,6 +356,16 @@ func (p *userProjection) reduceHumanRegistered(event eventstore.Event) (*handler
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCol(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
handler.NewCol(NotifyLastEmailCol, e.EmailAddress),
|
||||
handler.NewCol(NotifyLastPhoneCol, &sql.NullString{String: e.PhoneNumber, Valid: e.PhoneNumber != ""}),
|
||||
handler.NewCol(NotifyPasswordSetCol, e.Secret != nil),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -552,6 +600,16 @@ func (p *userProjection) reduceHumanPhoneChanged(event eventstore.Event) (*handl
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyLastPhoneCol, &sql.NullString{String: e.PhoneNumber, Valid: e.PhoneNumber != ""}),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -584,6 +642,17 @@ func (p *userProjection) reduceHumanPhoneRemoved(event eventstore.Event) (*handl
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyLastPhoneCol, nil),
|
||||
handler.NewCol(NotifyVerifiedPhoneCol, nil),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -615,6 +684,23 @@ func (p *userProjection) reduceHumanPhoneVerified(event eventstore.Event) (*hand
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddCopyStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, nil),
|
||||
handler.NewCol(NotifyInstanceIDCol, nil),
|
||||
handler.NewCol(NotifyLastPhoneCol, nil),
|
||||
},
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, nil),
|
||||
handler.NewCol(NotifyInstanceIDCol, nil),
|
||||
handler.NewCol(NotifyVerifiedPhoneCol, nil),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -647,6 +733,16 @@ func (p *userProjection) reduceHumanEmailChanged(event eventstore.Event) (*handl
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyLastEmailCol, &sql.NullString{String: e.EmailAddress, Valid: e.EmailAddress != ""}),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -678,6 +774,23 @@ func (p *userProjection) reduceHumanEmailVerified(event eventstore.Event) (*hand
|
||||
},
|
||||
crdb.WithTableSuffix(UserHumanSuffix),
|
||||
),
|
||||
crdb.AddCopyStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, nil),
|
||||
handler.NewCol(NotifyInstanceIDCol, nil),
|
||||
handler.NewCol(NotifyLastEmailCol, nil),
|
||||
},
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyUserIDCol, nil),
|
||||
handler.NewCol(NotifyInstanceIDCol, nil),
|
||||
handler.NewCol(NotifyVerifiedEmailCol, nil),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -743,6 +856,25 @@ func (p *userProjection) reduceHumanAvatarRemoved(event eventstore.Event) (*hand
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *userProjection) reduceHumanPasswordChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*user.HumanPasswordChangedEvent)
|
||||
if !ok {
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-jqXUY", "reduce.wrong.event.type %s", user.HumanPasswordChangedType)
|
||||
}
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
e,
|
||||
[]handler.Column{
|
||||
handler.NewCol(NotifyPasswordSetCol, true),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(NotifyUserIDCol, e.Aggregate().ID),
|
||||
handler.NewCond(NotifyInstanceIDCol, e.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(UserNotifySuffix),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *userProjection) reduceMachineAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*user.MachineAddedEvent)
|
||||
if !ok {
|
||||
|
@@ -50,7 +50,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -64,7 +64,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -78,6 +78,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -110,7 +120,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -124,7 +134,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -138,6 +148,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -165,7 +185,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -179,7 +199,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -193,6 +213,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "", Valid: false},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -225,7 +255,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -239,7 +269,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -253,6 +283,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -285,7 +325,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -299,7 +339,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -313,6 +353,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -340,7 +390,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -354,7 +404,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.users2_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -368,6 +418,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
&sql.NullString{},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users2_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
"email@zitadel.com",
|
||||
&sql.NullString{String: "", Valid: false},
|
||||
false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -390,7 +450,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.UserStateInitial,
|
||||
"agg-id",
|
||||
@@ -419,7 +479,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.UserStateInitial,
|
||||
"agg-id",
|
||||
@@ -448,7 +508,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.UserStateActive,
|
||||
"agg-id",
|
||||
@@ -477,7 +537,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.UserStateActive,
|
||||
"agg-id",
|
||||
@@ -506,7 +566,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
domain.UserStateLocked,
|
||||
@@ -537,7 +597,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
domain.UserStateActive,
|
||||
@@ -568,7 +628,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
domain.UserStateInactive,
|
||||
@@ -599,7 +659,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
domain.UserStateActive,
|
||||
@@ -630,7 +690,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.users WHERE (id = $1) AND (instance_id = $2)",
|
||||
expectedStmt: "DELETE FROM projections.users2 WHERE (id = $1) AND (instance_id = $2)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -660,7 +720,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
"username",
|
||||
@@ -698,7 +758,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -707,7 +767,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"first-name",
|
||||
"last-name",
|
||||
@@ -748,7 +808,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -757,7 +817,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"first-name",
|
||||
"last-name",
|
||||
@@ -793,7 +853,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -802,7 +862,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"+41 00 000 00 00",
|
||||
false,
|
||||
@@ -810,6 +870,14 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_phone) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -834,7 +902,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -843,7 +911,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"+41 00 000 00 00",
|
||||
false,
|
||||
@@ -851,6 +919,14 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_phone) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -873,7 +949,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -882,7 +958,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
nil,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
nil,
|
||||
@@ -912,7 +997,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -921,7 +1006,16 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
nil,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
nil,
|
||||
@@ -951,7 +1045,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -960,13 +1054,20 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
true,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPSERT INTO projections.users2_notifications (user_id, instance_id, verified_phone) SELECT user_id, instance_id, last_phone FROM projections.users2_notifications AS copy_table WHERE copy_table.user_id = $1 AND copy_table.instance_id = $2",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -989,7 +1090,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -998,13 +1099,20 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
true,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPSERT INTO projections.users2_notifications (user_id, instance_id, verified_phone) SELECT user_id, instance_id, last_phone FROM projections.users2_notifications AS copy_table WHERE copy_table.user_id = $1 AND copy_table.instance_id = $2",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1029,7 +1137,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1038,7 +1146,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"email@zitadel.com",
|
||||
false,
|
||||
@@ -1046,6 +1154,14 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_email) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
&sql.NullString{String: "email@zitadel.com", Valid: true},
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1070,7 +1186,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1079,7 +1195,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"email@zitadel.com",
|
||||
false,
|
||||
@@ -1087,6 +1203,14 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users2_notifications SET (last_email) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
&sql.NullString{String: "email@zitadel.com", Valid: true},
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1109,7 +1233,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1118,13 +1242,20 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
true,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPSERT INTO projections.users2_notifications (user_id, instance_id, verified_email) SELECT user_id, instance_id, last_email FROM projections.users2_notifications AS copy_table WHERE copy_table.user_id = $1 AND copy_table.instance_id = $2",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1147,7 +1278,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1156,13 +1287,20 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
true,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPSERT INTO projections.users2_notifications (user_id, instance_id, verified_email) SELECT user_id, instance_id, last_email FROM projections.users2_notifications AS copy_table WHERE copy_table.user_id = $1 AND copy_table.instance_id = $2",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1187,7 +1325,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1196,7 +1334,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
"users/agg-id/avatar",
|
||||
"agg-id",
|
||||
@@ -1225,7 +1363,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1234,7 +1372,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
"agg-id",
|
||||
@@ -1266,7 +1404,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -1280,7 +1418,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
|
||||
expectedStmt: "INSERT INTO projections.users2_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -1314,7 +1452,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.users2 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
@@ -1328,7 +1466,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.users_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
|
||||
expectedStmt: "INSERT INTO projections.users2_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -1361,7 +1499,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1370,7 +1508,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"machine-name",
|
||||
"description",
|
||||
@@ -1402,7 +1540,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1411,7 +1549,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_machines SET (name) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_machines SET (name) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
"machine-name",
|
||||
"agg-id",
|
||||
@@ -1442,7 +1580,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedStmt: "UPDATE projections.users2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
@@ -1451,7 +1589,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.users_machines SET (description) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedStmt: "UPDATE projections.users2_machines SET (description) = ($1) WHERE (user_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
"description",
|
||||
"agg-id",
|
||||
|
@@ -11,9 +11,7 @@ import (
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
)
|
||||
@@ -92,6 +90,31 @@ type Machine struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
type NotifyUser struct {
|
||||
ID string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
ResourceOwner string
|
||||
Sequence uint64
|
||||
State domain.UserState
|
||||
Type domain.UserType
|
||||
Username string
|
||||
LoginNames []string
|
||||
PreferredLoginName string
|
||||
FirstName string
|
||||
LastName string
|
||||
NickName string
|
||||
DisplayName string
|
||||
AvatarKey string
|
||||
PreferredLanguage language.Tag
|
||||
Gender domain.Gender
|
||||
LastEmail string
|
||||
VerifiedEmail string
|
||||
LastPhone string
|
||||
VerifiedPhone string
|
||||
PasswordSet bool
|
||||
}
|
||||
|
||||
type UserSearchQueries struct {
|
||||
SearchRequest
|
||||
Queries []SearchQuery
|
||||
@@ -237,6 +260,38 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
notifyTable = table{
|
||||
name: projection.UserNotifyTable,
|
||||
}
|
||||
NotifyUserIDCol = Column{
|
||||
name: projection.NotifyUserIDCol,
|
||||
table: notifyTable,
|
||||
}
|
||||
NotifyEmailCol = Column{
|
||||
name: projection.NotifyLastEmailCol,
|
||||
table: notifyTable,
|
||||
isOrderByLower: true,
|
||||
}
|
||||
NotifyVerifiedEmailCol = Column{
|
||||
name: projection.NotifyVerifiedEmailCol,
|
||||
table: notifyTable,
|
||||
isOrderByLower: true,
|
||||
}
|
||||
NotifyPhoneCol = Column{
|
||||
name: projection.NotifyLastPhoneCol,
|
||||
table: notifyTable,
|
||||
}
|
||||
NotifyVerifiedPhoneCol = Column{
|
||||
name: projection.NotifyVerifiedPhoneCol,
|
||||
table: notifyTable,
|
||||
}
|
||||
NotifyPasswordSetCol = Column{
|
||||
name: projection.NotifyPasswordSetCol,
|
||||
table: notifyTable,
|
||||
}
|
||||
)
|
||||
|
||||
func (q *Queries) GetUserByID(ctx context.Context, shouldTriggered bool, userID string, queries ...SearchQuery) (*User, error) {
|
||||
if shouldTriggered {
|
||||
projection.UserProjection.TriggerBulk(ctx)
|
||||
@@ -327,6 +382,28 @@ func (q *Queries) GetHumanPhone(ctx context.Context, userID string, queries ...S
|
||||
return scan(row)
|
||||
}
|
||||
|
||||
func (q *Queries) GeNotifyUser(ctx context.Context, shouldTriggered bool, userID string, queries ...SearchQuery) (*NotifyUser, error) {
|
||||
if shouldTriggered {
|
||||
projection.UserProjection.TriggerBulk(ctx)
|
||||
}
|
||||
|
||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||
query, scan := prepareNotifyUserQuery(instanceID)
|
||||
for _, q := range queries {
|
||||
query = q.toQuery(query)
|
||||
}
|
||||
stmt, args, err := query.Where(sq.Eq{
|
||||
UserIDCol.identifier(): userID,
|
||||
UserInstanceIDCol.identifier(): instanceID,
|
||||
}).ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "QUERY-Err3g", "Errors.Query.SQLStatment")
|
||||
}
|
||||
|
||||
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||||
return scan(row)
|
||||
}
|
||||
|
||||
func (q *Queries) SearchUsers(ctx context.Context, queries *UserSearchQueries) (*Users, error) {
|
||||
query, scan := prepareUsersQuery()
|
||||
stmt, args, err := queries.toQuery(query).
|
||||
@@ -748,6 +825,143 @@ func preparePhoneQuery() (sq.SelectBuilder, func(*sql.Row) (*Phone, error)) {
|
||||
}
|
||||
}
|
||||
|
||||
func prepareNotifyUserQuery(instanceID string) (sq.SelectBuilder, func(*sql.Row) (*NotifyUser, error)) {
|
||||
loginNamesQuery, loginNamesArgs, err := sq.Select(
|
||||
userLoginNamesUserIDCol.identifier(),
|
||||
"ARRAY_AGG("+userLoginNamesNameCol.identifier()+") as "+userLoginNamesListCol.name).
|
||||
From(userLoginNamesTable.identifier()).
|
||||
GroupBy(userLoginNamesUserIDCol.identifier()).
|
||||
Where(sq.Eq{
|
||||
userLoginNamesInstanceIDCol.identifier(): instanceID,
|
||||
}).ToSql()
|
||||
if err != nil {
|
||||
return sq.SelectBuilder{}, nil
|
||||
}
|
||||
preferredLoginNameQuery, preferredLoginNameArgs, err := sq.Select(
|
||||
userPreferredLoginNameUserIDCol.identifier(),
|
||||
userPreferredLoginNameCol.identifier()).
|
||||
From(userPreferredLoginNameTable.identifier()).
|
||||
Where(sq.Eq{
|
||||
userPreferredLoginNameIsPrimaryCol.identifier(): true,
|
||||
userPreferredLoginNameInstanceIDCol.identifier(): instanceID,
|
||||
}).ToSql()
|
||||
if err != nil {
|
||||
return sq.SelectBuilder{}, nil
|
||||
}
|
||||
return sq.Select(
|
||||
UserIDCol.identifier(),
|
||||
UserCreationDateCol.identifier(),
|
||||
UserChangeDateCol.identifier(),
|
||||
UserResourceOwnerCol.identifier(),
|
||||
UserSequenceCol.identifier(),
|
||||
UserStateCol.identifier(),
|
||||
UserTypeCol.identifier(),
|
||||
UserUsernameCol.identifier(),
|
||||
userLoginNamesListCol.identifier(),
|
||||
userPreferredLoginNameCol.identifier(),
|
||||
HumanUserIDCol.identifier(),
|
||||
HumanFirstNameCol.identifier(),
|
||||
HumanLastNameCol.identifier(),
|
||||
HumanNickNameCol.identifier(),
|
||||
HumanDisplayNameCol.identifier(),
|
||||
HumanPreferredLanguageCol.identifier(),
|
||||
HumanGenderCol.identifier(),
|
||||
HumanAvatarURLCol.identifier(),
|
||||
NotifyUserIDCol.identifier(),
|
||||
NotifyEmailCol.identifier(),
|
||||
NotifyVerifiedEmailCol.identifier(),
|
||||
NotifyPhoneCol.identifier(),
|
||||
NotifyVerifiedPhoneCol.identifier(),
|
||||
NotifyPasswordSetCol.identifier(),
|
||||
).
|
||||
From(userTable.identifier()).
|
||||
LeftJoin(join(HumanUserIDCol, UserIDCol)).
|
||||
LeftJoin(join(NotifyUserIDCol, UserIDCol)).
|
||||
LeftJoin("("+loginNamesQuery+") as "+userLoginNamesTable.alias+" on "+userLoginNamesUserIDCol.identifier()+" = "+UserIDCol.identifier(), loginNamesArgs...).
|
||||
LeftJoin("("+preferredLoginNameQuery+") as "+userPreferredLoginNameTable.alias+" on "+userPreferredLoginNameUserIDCol.identifier()+" = "+UserIDCol.identifier(), preferredLoginNameArgs...).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
func(row *sql.Row) (*NotifyUser, error) {
|
||||
u := new(NotifyUser)
|
||||
loginNames := pq.StringArray{}
|
||||
preferredLoginName := sql.NullString{}
|
||||
|
||||
humanID := sql.NullString{}
|
||||
firstName := sql.NullString{}
|
||||
lastName := sql.NullString{}
|
||||
nickName := sql.NullString{}
|
||||
displayName := sql.NullString{}
|
||||
preferredLanguage := sql.NullString{}
|
||||
gender := sql.NullInt32{}
|
||||
avatarKey := sql.NullString{}
|
||||
|
||||
notifyUserID := sql.NullString{}
|
||||
notifyEmail := sql.NullString{}
|
||||
notifyVerifiedEmail := sql.NullString{}
|
||||
notifyPhone := sql.NullString{}
|
||||
notifyVerifiedPhone := sql.NullString{}
|
||||
notifyPasswordSet := sql.NullBool{}
|
||||
|
||||
err := row.Scan(
|
||||
&u.ID,
|
||||
&u.CreationDate,
|
||||
&u.ChangeDate,
|
||||
&u.ResourceOwner,
|
||||
&u.Sequence,
|
||||
&u.State,
|
||||
&u.Type,
|
||||
&u.Username,
|
||||
&loginNames,
|
||||
&preferredLoginName,
|
||||
&humanID,
|
||||
&firstName,
|
||||
&lastName,
|
||||
&nickName,
|
||||
&displayName,
|
||||
&preferredLanguage,
|
||||
&gender,
|
||||
&avatarKey,
|
||||
¬ifyUserID,
|
||||
¬ifyEmail,
|
||||
¬ifyVerifiedEmail,
|
||||
¬ifyPhone,
|
||||
¬ifyVerifiedPhone,
|
||||
¬ifyPasswordSet,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if errs.Is(err, sql.ErrNoRows) {
|
||||
return nil, errors.ThrowNotFound(err, "QUERY-Dgqd2", "Errors.User.NotFound")
|
||||
}
|
||||
return nil, errors.ThrowInternal(err, "QUERY-Dbwsg", "Errors.Internal")
|
||||
}
|
||||
|
||||
if !notifyUserID.Valid {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "QUERY-Sfw3f", "Errors.User.NotFound")
|
||||
}
|
||||
|
||||
u.LoginNames = loginNames
|
||||
if preferredLoginName.Valid {
|
||||
u.PreferredLoginName = preferredLoginName.String
|
||||
}
|
||||
if humanID.Valid {
|
||||
u.FirstName = firstName.String
|
||||
u.LastName = lastName.String
|
||||
u.NickName = nickName.String
|
||||
u.DisplayName = displayName.String
|
||||
u.AvatarKey = avatarKey.String
|
||||
u.PreferredLanguage = language.Make(preferredLanguage.String)
|
||||
u.Gender = domain.Gender(gender.Int32)
|
||||
}
|
||||
u.LastEmail = notifyEmail.String
|
||||
u.VerifiedEmail = notifyVerifiedEmail.String
|
||||
u.LastPhone = notifyPhone.String
|
||||
u.VerifiedPhone = notifyVerifiedPhone.String
|
||||
u.PasswordSet = notifyPasswordSet.Bool
|
||||
|
||||
return u, nil
|
||||
}
|
||||
}
|
||||
|
||||
func prepareUserUniqueQuery() (sq.SelectBuilder, func(*sql.Row) (bool, error)) {
|
||||
return sq.Select(
|
||||
UserIDCol.identifier(),
|
||||
|
@@ -24,14 +24,14 @@ var (
|
||||
", projections.user_grants.roles" +
|
||||
", projections.user_grants.state" +
|
||||
", projections.user_grants.user_id" +
|
||||
", projections.users.username" +
|
||||
", projections.users.type" +
|
||||
", projections.users.resource_owner" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2.username" +
|
||||
", projections.users2.type" +
|
||||
", projections.users2.resource_owner" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.user_grants.resource_owner" +
|
||||
", projections.orgs.name" +
|
||||
@@ -39,8 +39,8 @@ var (
|
||||
", projections.user_grants.project_id" +
|
||||
", projections.projects.name" +
|
||||
" FROM projections.user_grants" +
|
||||
" LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" +
|
||||
" LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" +
|
||||
" LEFT JOIN projections.users2 ON projections.user_grants.user_id = projections.users2.id" +
|
||||
" LEFT JOIN projections.users2_humans ON projections.user_grants.user_id = projections.users2_humans.user_id" +
|
||||
" LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" +
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id" +
|
||||
" LEFT JOIN projections.login_names ON projections.user_grants.user_id = projections.login_names.user_id" +
|
||||
@@ -78,14 +78,14 @@ var (
|
||||
", projections.user_grants.roles" +
|
||||
", projections.user_grants.state" +
|
||||
", projections.user_grants.user_id" +
|
||||
", projections.users.username" +
|
||||
", projections.users.type" +
|
||||
", projections.users.resource_owner" +
|
||||
", projections.users_humans.first_name" +
|
||||
", projections.users_humans.last_name" +
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.users2.username" +
|
||||
", projections.users2.type" +
|
||||
", projections.users2.resource_owner" +
|
||||
", projections.users2_humans.first_name" +
|
||||
", projections.users2_humans.last_name" +
|
||||
", projections.users2_humans.email" +
|
||||
", projections.users2_humans.display_name" +
|
||||
", projections.users2_humans.avatar_key" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.user_grants.resource_owner" +
|
||||
", projections.orgs.name" +
|
||||
@@ -94,8 +94,8 @@ var (
|
||||
", projections.projects.name" +
|
||||
", COUNT(*) OVER ()" +
|
||||
" FROM projections.user_grants" +
|
||||
" LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" +
|
||||
" LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" +
|
||||
" LEFT JOIN projections.users2 ON projections.user_grants.user_id = projections.users2.id" +
|
||||
" LEFT JOIN projections.users2_humans ON projections.user_grants.user_id = projections.users2_humans.user_id" +
|
||||
" LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" +
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id" +
|
||||
" LEFT JOIN projections.login_names ON projections.user_grants.user_id = projections.login_names.user_id" +
|
||||
|
@@ -17,43 +17,43 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
userQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.creation_date,` +
|
||||
` projections.users.change_date,` +
|
||||
` projections.users.resource_owner,` +
|
||||
` projections.users.sequence,` +
|
||||
` projections.users.state,` +
|
||||
` projections.users.type,` +
|
||||
` projections.users.username,` +
|
||||
userQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2.state,` +
|
||||
` projections.users2.type,` +
|
||||
` projections.users2.username,` +
|
||||
` login_names.loginnames,` +
|
||||
` preferred_login_name.login_name,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.first_name,` +
|
||||
` projections.users_humans.last_name,` +
|
||||
` projections.users_humans.nick_name,` +
|
||||
` projections.users_humans.display_name,` +
|
||||
` projections.users_humans.preferred_language,` +
|
||||
` projections.users_humans.gender,` +
|
||||
` projections.users_humans.avatar_key,` +
|
||||
` projections.users_humans.email,` +
|
||||
` projections.users_humans.is_email_verified,` +
|
||||
` projections.users_humans.phone,` +
|
||||
` projections.users_humans.is_phone_verified,` +
|
||||
` projections.users_machines.user_id,` +
|
||||
` projections.users_machines.name,` +
|
||||
` projections.users_machines.description` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` +
|
||||
` LEFT JOIN projections.users_machines ON projections.users.id = projections.users_machines.user_id` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.first_name,` +
|
||||
` projections.users2_humans.last_name,` +
|
||||
` projections.users2_humans.nick_name,` +
|
||||
` projections.users2_humans.display_name,` +
|
||||
` projections.users2_humans.preferred_language,` +
|
||||
` projections.users2_humans.gender,` +
|
||||
` projections.users2_humans.avatar_key,` +
|
||||
` projections.users2_humans.email,` +
|
||||
` projections.users2_humans.is_email_verified,` +
|
||||
` projections.users2_humans.phone,` +
|
||||
` projections.users2_humans.is_phone_verified,` +
|
||||
` projections.users2_machines.user_id,` +
|
||||
` projections.users2_machines.name,` +
|
||||
` projections.users2_machines.description` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id` +
|
||||
` LEFT JOIN projections.users2_machines ON projections.users2.id = projections.users2_machines.user_id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as loginnames` +
|
||||
` FROM projections.login_names as login_names` +
|
||||
` WHERE login_names.instance_id = $1` +
|
||||
` GROUP BY login_names.user_id) as login_names` +
|
||||
` on login_names.user_id = projections.users.id` +
|
||||
` on login_names.user_id = projections.users2.id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.instance_id = $2 AND preferred_login_name.is_primary = $3) as preferred_login_name` +
|
||||
` on preferred_login_name.user_id = projections.users.id`
|
||||
` on preferred_login_name.user_id = projections.users2.id`
|
||||
userCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@@ -83,21 +83,21 @@ var (
|
||||
"name",
|
||||
"description",
|
||||
}
|
||||
profileQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.creation_date,` +
|
||||
` projections.users.change_date,` +
|
||||
` projections.users.resource_owner,` +
|
||||
` projections.users.sequence,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.first_name,` +
|
||||
` projections.users_humans.last_name,` +
|
||||
` projections.users_humans.nick_name,` +
|
||||
` projections.users_humans.display_name,` +
|
||||
` projections.users_humans.preferred_language,` +
|
||||
` projections.users_humans.gender,` +
|
||||
` projections.users_humans.avatar_key` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id`
|
||||
profileQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.first_name,` +
|
||||
` projections.users2_humans.last_name,` +
|
||||
` projections.users2_humans.nick_name,` +
|
||||
` projections.users2_humans.display_name,` +
|
||||
` projections.users2_humans.preferred_language,` +
|
||||
` projections.users2_humans.gender,` +
|
||||
` projections.users2_humans.avatar_key` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id`
|
||||
profileCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@@ -113,16 +113,16 @@ var (
|
||||
"gender",
|
||||
"avatar_key",
|
||||
}
|
||||
emailQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.creation_date,` +
|
||||
` projections.users.change_date,` +
|
||||
` projections.users.resource_owner,` +
|
||||
` projections.users.sequence,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.email,` +
|
||||
` projections.users_humans.is_email_verified` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id`
|
||||
emailQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.email,` +
|
||||
` projections.users2_humans.is_email_verified` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id`
|
||||
emailCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@@ -133,16 +133,16 @@ var (
|
||||
"email",
|
||||
"is_email_verified",
|
||||
}
|
||||
phoneQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.creation_date,` +
|
||||
` projections.users.change_date,` +
|
||||
` projections.users.resource_owner,` +
|
||||
` projections.users.sequence,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.phone,` +
|
||||
` projections.users_humans.is_phone_verified` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id`
|
||||
phoneQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.phone,` +
|
||||
` projections.users2_humans.is_phone_verified` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id`
|
||||
phoneCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@@ -153,15 +153,14 @@ var (
|
||||
"phone",
|
||||
"is_phone_verified",
|
||||
}
|
||||
|
||||
userUniqueQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.state,` +
|
||||
` projections.users.username,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.email,` +
|
||||
` projections.users_humans.is_email_verified` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id`
|
||||
userUniqueQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.state,` +
|
||||
` projections.users2.username,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.email,` +
|
||||
` projections.users2_humans.is_email_verified` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id`
|
||||
userUniqueCols = []string{
|
||||
"id",
|
||||
"state",
|
||||
@@ -170,43 +169,107 @@ var (
|
||||
"email",
|
||||
"is_email_verified",
|
||||
}
|
||||
usersQuery = `SELECT projections.users.id,` +
|
||||
` projections.users.creation_date,` +
|
||||
` projections.users.change_date,` +
|
||||
` projections.users.resource_owner,` +
|
||||
` projections.users.sequence,` +
|
||||
` projections.users.state,` +
|
||||
` projections.users.type,` +
|
||||
` projections.users.username,` +
|
||||
notifyUserQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2.state,` +
|
||||
` projections.users2.type,` +
|
||||
` projections.users2.username,` +
|
||||
` login_names.loginnames,` +
|
||||
` preferred_login_name.login_name,` +
|
||||
` projections.users_humans.user_id,` +
|
||||
` projections.users_humans.first_name,` +
|
||||
` projections.users_humans.last_name,` +
|
||||
` projections.users_humans.nick_name,` +
|
||||
` projections.users_humans.display_name,` +
|
||||
` projections.users_humans.preferred_language,` +
|
||||
` projections.users_humans.gender,` +
|
||||
` projections.users_humans.avatar_key,` +
|
||||
` projections.users_humans.email,` +
|
||||
` projections.users_humans.is_email_verified,` +
|
||||
` projections.users_humans.phone,` +
|
||||
` projections.users_humans.is_phone_verified,` +
|
||||
` projections.users_machines.user_id,` +
|
||||
` projections.users_machines.name,` +
|
||||
` projections.users_machines.description,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.first_name,` +
|
||||
` projections.users2_humans.last_name,` +
|
||||
` projections.users2_humans.nick_name,` +
|
||||
` projections.users2_humans.display_name,` +
|
||||
` projections.users2_humans.preferred_language,` +
|
||||
` projections.users2_humans.gender,` +
|
||||
` projections.users2_humans.avatar_key,` +
|
||||
` projections.users2_notifications.user_id,` +
|
||||
` projections.users2_notifications.last_email,` +
|
||||
` projections.users2_notifications.verified_email,` +
|
||||
` projections.users2_notifications.last_phone,` +
|
||||
` projections.users2_notifications.verified_phone,` +
|
||||
` projections.users2_notifications.password_set` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id` +
|
||||
` LEFT JOIN projections.users2_notifications ON projections.users2.id = projections.users2_notifications.user_id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as loginnames` +
|
||||
` FROM projections.login_names as login_names` +
|
||||
` WHERE login_names.instance_id = $1` +
|
||||
` GROUP BY login_names.user_id) as login_names` +
|
||||
` on login_names.user_id = projections.users2.id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.instance_id = $2 AND preferred_login_name.is_primary = $3) as preferred_login_name` +
|
||||
` on preferred_login_name.user_id = projections.users2.id`
|
||||
notifyUserCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
"change_date",
|
||||
"resource_owner",
|
||||
"sequence",
|
||||
"state",
|
||||
"type",
|
||||
"username",
|
||||
"loginnames",
|
||||
"login_name",
|
||||
//human
|
||||
"user_id",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"nick_name",
|
||||
"display_name",
|
||||
"preferred_language",
|
||||
"gender",
|
||||
"avatar_key",
|
||||
//machine
|
||||
"user_id",
|
||||
"last_email",
|
||||
"verified_email",
|
||||
"last_phone",
|
||||
"verified_phone",
|
||||
"password_set",
|
||||
}
|
||||
usersQuery = `SELECT projections.users2.id,` +
|
||||
` projections.users2.creation_date,` +
|
||||
` projections.users2.change_date,` +
|
||||
` projections.users2.resource_owner,` +
|
||||
` projections.users2.sequence,` +
|
||||
` projections.users2.state,` +
|
||||
` projections.users2.type,` +
|
||||
` projections.users2.username,` +
|
||||
` login_names.loginnames,` +
|
||||
` preferred_login_name.login_name,` +
|
||||
` projections.users2_humans.user_id,` +
|
||||
` projections.users2_humans.first_name,` +
|
||||
` projections.users2_humans.last_name,` +
|
||||
` projections.users2_humans.nick_name,` +
|
||||
` projections.users2_humans.display_name,` +
|
||||
` projections.users2_humans.preferred_language,` +
|
||||
` projections.users2_humans.gender,` +
|
||||
` projections.users2_humans.avatar_key,` +
|
||||
` projections.users2_humans.email,` +
|
||||
` projections.users2_humans.is_email_verified,` +
|
||||
` projections.users2_humans.phone,` +
|
||||
` projections.users2_humans.is_phone_verified,` +
|
||||
` projections.users2_machines.user_id,` +
|
||||
` projections.users2_machines.name,` +
|
||||
` projections.users2_machines.description,` +
|
||||
` COUNT(*) OVER ()` +
|
||||
` FROM projections.users` +
|
||||
` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` +
|
||||
` LEFT JOIN projections.users_machines ON projections.users.id = projections.users_machines.user_id` +
|
||||
` FROM projections.users2` +
|
||||
` LEFT JOIN projections.users2_humans ON projections.users2.id = projections.users2_humans.user_id` +
|
||||
` LEFT JOIN projections.users2_machines ON projections.users2.id = projections.users2_machines.user_id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as loginnames` +
|
||||
` FROM projections.login_names as login_names` +
|
||||
` GROUP BY login_names.user_id) as login_names` +
|
||||
` on login_names.user_id = projections.users.id` +
|
||||
` on login_names.user_id = projections.users2.id` +
|
||||
` LEFT JOIN` +
|
||||
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` +
|
||||
` on preferred_login_name.user_id = projections.users.id`
|
||||
` on preferred_login_name.user_id = projections.users2.id`
|
||||
usersCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@@ -760,6 +823,155 @@ func Test_UserPrepares(t *testing.T) {
|
||||
},
|
||||
object: nil,
|
||||
},
|
||||
{
|
||||
name: "prepareNotifyUserQuery no result",
|
||||
prepare: func() (sq.SelectBuilder, func(*sql.Row) (*NotifyUser, error)) {
|
||||
return prepareNotifyUserQuery("instanceID")
|
||||
},
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
regexp.QuoteMeta(notifyUserQuery),
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
err: func(err error) (error, bool) {
|
||||
if !errs.IsNotFound(err) {
|
||||
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||
}
|
||||
return nil, true
|
||||
},
|
||||
},
|
||||
object: (*NotifyUser)(nil),
|
||||
},
|
||||
{
|
||||
name: "prepareNotifyUserQuery notify found",
|
||||
prepare: func() (sq.SelectBuilder, func(*sql.Row) (*NotifyUser, error)) {
|
||||
return prepareNotifyUserQuery("instanceID")
|
||||
},
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
regexp.QuoteMeta(notifyUserQuery),
|
||||
notifyUserCols,
|
||||
[]driver.Value{
|
||||
"id",
|
||||
testNow,
|
||||
testNow,
|
||||
"resource_owner",
|
||||
uint64(20211108),
|
||||
domain.UserStateActive,
|
||||
domain.UserTypeHuman,
|
||||
"username",
|
||||
pq.StringArray{"login_name1", "login_name2"},
|
||||
"login_name1",
|
||||
//human
|
||||
"id",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"nick_name",
|
||||
"display_name",
|
||||
"de",
|
||||
domain.GenderUnspecified,
|
||||
"avatar_key",
|
||||
//notify
|
||||
"id",
|
||||
"lastEmail",
|
||||
"verifiedEmail",
|
||||
"lastPhone",
|
||||
"verifiedPhone",
|
||||
true,
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &NotifyUser{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
ResourceOwner: "resource_owner",
|
||||
Sequence: 20211108,
|
||||
State: domain.UserStateActive,
|
||||
Type: domain.UserTypeHuman,
|
||||
Username: "username",
|
||||
LoginNames: []string{"login_name1", "login_name2"},
|
||||
PreferredLoginName: "login_name1",
|
||||
FirstName: "first_name",
|
||||
LastName: "last_name",
|
||||
NickName: "nick_name",
|
||||
DisplayName: "display_name",
|
||||
AvatarKey: "avatar_key",
|
||||
PreferredLanguage: language.German,
|
||||
Gender: domain.GenderUnspecified,
|
||||
LastEmail: "lastEmail",
|
||||
VerifiedEmail: "verifiedEmail",
|
||||
LastPhone: "lastPhone",
|
||||
VerifiedPhone: "verifiedPhone",
|
||||
PasswordSet: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepareNotifyUserQuery not notify found (error)",
|
||||
prepare: func() (sq.SelectBuilder, func(*sql.Row) (*NotifyUser, error)) {
|
||||
return prepareNotifyUserQuery("instanceID")
|
||||
},
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
regexp.QuoteMeta(notifyUserQuery),
|
||||
notifyUserCols,
|
||||
[]driver.Value{
|
||||
"id",
|
||||
testNow,
|
||||
testNow,
|
||||
"resource_owner",
|
||||
uint64(20211108),
|
||||
domain.UserStateActive,
|
||||
domain.UserTypeHuman,
|
||||
"username",
|
||||
pq.StringArray{"login_name1", "login_name2"},
|
||||
"login_name1",
|
||||
//human
|
||||
"id",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"nick_name",
|
||||
"display_name",
|
||||
"de",
|
||||
domain.GenderUnspecified,
|
||||
"avatar_key",
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
),
|
||||
err: func(err error) (error, bool) {
|
||||
if !errs.IsPreconditionFailed(err) {
|
||||
return fmt.Errorf("err should be zitadel.PredconditionError got: %w", err), false
|
||||
}
|
||||
return nil, true
|
||||
},
|
||||
},
|
||||
object: (*NotifyUser)(nil),
|
||||
},
|
||||
{
|
||||
name: "prepareNotifyUserQuery sql err",
|
||||
prepare: func() (sq.SelectBuilder, func(*sql.Row) (*NotifyUser, error)) {
|
||||
return prepareNotifyUserQuery("instanceID")
|
||||
},
|
||||
want: want{
|
||||
sqlExpectations: mockQueryErr(
|
||||
regexp.QuoteMeta(notifyUserQuery),
|
||||
sql.ErrConnDone,
|
||||
),
|
||||
err: func(err error) (error, bool) {
|
||||
if !errors.Is(err, sql.ErrConnDone) {
|
||||
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
||||
}
|
||||
return nil, true
|
||||
},
|
||||
},
|
||||
object: nil,
|
||||
},
|
||||
{
|
||||
name: "prepareUsersQuery no result",
|
||||
prepare: prepareUsersQuery,
|
||||
|
Reference in New Issue
Block a user