From 6cef9064c36bc8bf1e67f56f907531e308b54e86 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 11 Jul 2023 14:48:37 +0530 Subject: [PATCH 01/37] Update provider template for sms verification --- server/db/models/model.go | 34 +++++++++---------- server/db/models/sms_verification_requests.go | 12 +++---- .../arangodb/sms_verification_requests.go | 15 ++++---- .../cassandradb/sms_verification_requests.go | 15 ++++---- .../couchbase/sms_verification_requests.go | 15 ++++---- .../dynamodb/sms_verification_requests.go | 15 ++++---- .../mongodb/sms_verification_requests.go | 26 +++++++------- .../sms_verification_requests.go | 22 ++++++++++++ server/db/providers/providers.go | 6 ++-- .../sql/sms_verification_requests.go | 12 +++---- 10 files changed, 94 insertions(+), 78 deletions(-) create mode 100644 server/db/providers/provider_template/sms_verification_requests.go diff --git a/server/db/models/model.go b/server/db/models/model.go index a0d5763..5061c41 100644 --- a/server/db/models/model.go +++ b/server/db/models/model.go @@ -2,14 +2,14 @@ package models // Collections / Tables available for authorizer in the database type CollectionList struct { - User string - VerificationRequest string - Session string - Env string - Webhook string - WebhookLog string - EmailTemplate string - OTP string + User string + VerificationRequest string + Session string + Env string + Webhook string + WebhookLog string + EmailTemplate string + OTP string SMSVerificationRequest string } @@ -18,14 +18,14 @@ var ( Prefix = "authorizer_" // Collections / Tables available for authorizer in the database (used for dbs other than gorm) Collections = CollectionList{ - User: Prefix + "users", - VerificationRequest: Prefix + "verification_requests", - Session: Prefix + "sessions", - Env: Prefix + "env", - Webhook: Prefix + "webhooks", - WebhookLog: Prefix + "webhook_logs", - EmailTemplate: Prefix + "email_templates", - OTP: Prefix + "otps", - SMSVerificationRequest: Prefix + "sms_verification_requests", + User: Prefix + "users", + VerificationRequest: Prefix + "verification_requests", + Session: Prefix + "sessions", + Env: Prefix + "env", + Webhook: Prefix + "webhooks", + WebhookLog: Prefix + "webhook_logs", + EmailTemplate: Prefix + "email_templates", + OTP: Prefix + "otps", + SMSVerificationRequest: Prefix + "sms_verification_requests", } ) diff --git a/server/db/models/sms_verification_requests.go b/server/db/models/sms_verification_requests.go index 2a70d5e..a938298 100644 --- a/server/db/models/sms_verification_requests.go +++ b/server/db/models/sms_verification_requests.go @@ -2,10 +2,10 @@ package models // SMS verification requests model for database type SMSVerificationRequest struct { - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` - PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` - Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` - CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"` - CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` - UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` + ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` + PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` + CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"` + CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` + UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` } diff --git a/server/db/providers/arangodb/sms_verification_requests.go b/server/db/providers/arangodb/sms_verification_requests.go index 4dee5bd..6eb97b8 100644 --- a/server/db/providers/arangodb/sms_verification_requests.go +++ b/server/db/providers/arangodb/sms_verification_requests.go @@ -4,20 +4,19 @@ import ( "context" "github.com/authorizerdev/authorizer/server/db/models" - ) -// SMS verification Request -func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return sms_code, nil +// UpsertSMSRequest adds/updates SMS verification request +func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { + return nil, nil } +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - return &sms_verification_request, nil + return nil, nil } -func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { return nil } diff --git a/server/db/providers/cassandradb/sms_verification_requests.go b/server/db/providers/cassandradb/sms_verification_requests.go index 3c67c1b..ddead30 100644 --- a/server/db/providers/cassandradb/sms_verification_requests.go +++ b/server/db/providers/cassandradb/sms_verification_requests.go @@ -4,20 +4,19 @@ import ( "context" "github.com/authorizerdev/authorizer/server/db/models" - ) -// SMS verification Request -func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return sms_code, nil +// UpsertSMSRequest adds/updates SMS verification request +func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { + return nil, nil } +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - return &sms_verification_request, nil + return nil, nil } -func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { return nil } diff --git a/server/db/providers/couchbase/sms_verification_requests.go b/server/db/providers/couchbase/sms_verification_requests.go index 9201d73..0639179 100644 --- a/server/db/providers/couchbase/sms_verification_requests.go +++ b/server/db/providers/couchbase/sms_verification_requests.go @@ -4,20 +4,19 @@ import ( "context" "github.com/authorizerdev/authorizer/server/db/models" - ) -// SMS verification Request -func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return sms_code, nil +// UpsertSMSRequest adds/updates SMS verification request +func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { + return nil, nil } +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - return &sms_verification_request, nil + return nil, nil } -func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { return nil } diff --git a/server/db/providers/dynamodb/sms_verification_requests.go b/server/db/providers/dynamodb/sms_verification_requests.go index bd47bce..6569a54 100644 --- a/server/db/providers/dynamodb/sms_verification_requests.go +++ b/server/db/providers/dynamodb/sms_verification_requests.go @@ -4,20 +4,19 @@ import ( "context" "github.com/authorizerdev/authorizer/server/db/models" - ) -// SMS verification Request -func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return sms_code, nil +// UpsertSMSRequest adds/updates SMS verification request +func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { + return nil, nil } +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - return &sms_verification_request, nil + return nil, nil } -func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { return nil } diff --git a/server/db/providers/mongodb/sms_verification_requests.go b/server/db/providers/mongodb/sms_verification_requests.go index b2d3a13..1183df1 100644 --- a/server/db/providers/mongodb/sms_verification_requests.go +++ b/server/db/providers/mongodb/sms_verification_requests.go @@ -10,41 +10,40 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -// SMS verification Request +// UpsertSMSRequest adds/updates SMS verification request func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) + smsVerificationRequest, err := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) + if err != nil { + return nil, err + } + // Boolean to check if we should create a new record or update the existing one shouldCreate := false - if smsVerificationRequest == nil { id := uuid.NewString() - smsVerificationRequest = &models.SMSVerificationRequest{ - ID: id, - CreatedAt: time.Now().Unix(), - Code: smsRequest.Code, - PhoneNumber: smsRequest.PhoneNumber, + ID: id, + CreatedAt: time.Now().Unix(), + Code: smsRequest.Code, + PhoneNumber: smsRequest.PhoneNumber, CodeExpiresAt: smsRequest.CodeExpiresAt, } shouldCreate = true } - + smsVerificationRequest.UpdatedAt = time.Now().Unix() smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - - var err error if shouldCreate { _, err = smsRequestCollection.InsertOne(ctx, smsVerificationRequest) } else { _, err = smsRequestCollection.UpdateOne(ctx, bson.M{"phone_number": bson.M{"$eq": smsRequest.PhoneNumber}}, bson.M{"$set": smsVerificationRequest}, options.MergeUpdateOptions()) } - if err != nil { return nil, err } - return smsVerificationRequest, nil } +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { var smsVerificationRequest models.SMSVerificationRequest @@ -58,6 +57,7 @@ func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*mod return &smsVerificationRequest, nil } +// DeleteSMSRequest to delete SMS verification request func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { smsVerificationRequests := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) _, err := smsVerificationRequests.DeleteOne(nil, bson.M{"_id": smsRequest.ID}, options.Delete()) diff --git a/server/db/providers/provider_template/sms_verification_requests.go b/server/db/providers/provider_template/sms_verification_requests.go new file mode 100644 index 0000000..d238a80 --- /dev/null +++ b/server/db/providers/provider_template/sms_verification_requests.go @@ -0,0 +1,22 @@ +package provider_template + +import ( + "context" + + "github.com/authorizerdev/authorizer/server/db/models" +) + +// UpsertSMSRequest adds/updates SMS verification request +func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { + return nil, nil +} + +// GetCodeByPhone to get code for a given phone number +func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { + return nil, nil +} + +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { + return nil +} diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index 28fbf78..31c021c 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -85,10 +85,10 @@ type Provider interface { // DeleteOTP to delete otp DeleteOTP(ctx context.Context, otp *models.OTP) error - // Upsert SMS code request + // UpsertSMSRequest adds/updates SMS verification request UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) - // Get sms code by phone number + // GetCodeByPhone to get code for a given phone number GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) - // Delete sms + // DeleteSMSRequest to delete SMS verification request DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error } diff --git a/server/db/providers/sql/sms_verification_requests.go b/server/db/providers/sql/sms_verification_requests.go index 5035c54..387b5eb 100644 --- a/server/db/providers/sql/sms_verification_requests.go +++ b/server/db/providers/sql/sms_verification_requests.go @@ -9,27 +9,24 @@ import ( "gorm.io/gorm/clause" ) -// SMS verification Request +// UpsertSMSRequest adds/updates SMS verification request func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { if smsRequest.ID == "" { smsRequest.ID = uuid.New().String() } - smsRequest.CreatedAt = time.Now().Unix() smsRequest.UpdatedAt = time.Now().Unix() - res := p.db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "phone_number"}}, - DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at"}), + DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at", "updated_at"}), }).Create(smsRequest) if res.Error != nil { return nil, res.Error } - return smsRequest, nil } -// GetOTPByEmail to get otp for a given email address +// GetCodeByPhone to get code for a given phone number func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { var sms_verification_request models.SMSVerificationRequest @@ -40,7 +37,8 @@ func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*mod return &sms_verification_request, nil } -func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { +// DeleteSMSRequest to delete SMS verification request +func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { result := p.db.Delete(&models.SMSVerificationRequest{ ID: smsRequest.ID, }) From 07f71e883b598113ec575985785042b68076e548 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 11 Jul 2023 14:49:16 +0530 Subject: [PATCH 02/37] Add comments for twillio --- server/constants/env.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/constants/env.go b/server/constants/env.go index d8382fb..0f26ede 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -181,8 +181,13 @@ const ( EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" // Twilio env variables + + // EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY EnvKeyTwilioAPIKey = "TWILIO_API_KEY" + // EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET EnvKeyTwilioAPISecret = "TWILIO_API_SECRET" + // EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID" + // EnvKeyTwilioSenderFrom key for env variable TWILIO_SENDER_FROM EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM" ) From abe809ca68ef0f730573d1c9ce0c717ee24bd3b6 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Wed, 12 Jul 2023 11:24:13 +0530 Subject: [PATCH 03/37] [draft] Move sms verificaiton to otp models --- server/db/models/otp.go | 22 +++++++++++------ server/db/models/sms_verification_requests.go | 3 ++- server/db/providers/arangodb/provider.go | 19 ++++++++++++++- server/db/providers/couchbase/shared.go | 5 ---- server/db/providers/mongodb/otp.go | 13 ++++++++++ server/db/providers/mongodb/provider.go | 6 +++++ .../mongodb/sms_verification_requests.go | 7 ++---- server/db/providers/providers.go | 2 ++ server/db/providers/sql/otp.go | 24 +++++++++++++++---- 9 files changed, 78 insertions(+), 23 deletions(-) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index ac9732b..b0e02ee 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -1,14 +1,22 @@ package models +const ( + // FieldName email is the field name for email + FieldNameEmail = "email" + // FieldNamePhoneNumber is the field name for phone number + FieldNamePhoneNumber = "phone_number" +) + // OTP model for database type OTP struct { - Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` - Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` - ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` - CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` - UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` + Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb + ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` + Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` + PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` + ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` + CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` + UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` } type Paging struct { diff --git a/server/db/models/sms_verification_requests.go b/server/db/models/sms_verification_requests.go index a938298..e14da4c 100644 --- a/server/db/models/sms_verification_requests.go +++ b/server/db/models/sms_verification_requests.go @@ -1,7 +1,8 @@ package models -// SMS verification requests model for database +// SMSVerificationRequest is SMS verification requests model for database type SMSVerificationRequest struct { + Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 5488428..88fc6e4 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -225,7 +225,6 @@ func NewProvider() (*provider, error) { return nil, err } } - otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP) if err != nil { return nil, err @@ -235,6 +234,24 @@ func NewProvider() (*provider, error) { Sparse: true, }) + smsVerificationCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.SMSVerificationRequest) + if err != nil { + return nil, err + } + if !smsVerificationCollectionExists { + _, err = arangodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, nil) + if err != nil { + return nil, err + } + } + smsVerificationCollection, err := arangodb.Collection(ctx, models.Collections.SMSVerificationRequest) + if err != nil { + return nil, err + } + smsVerificationCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + Unique: true, + Sparse: true, + }) return &provider{ db: arangodb, }, err diff --git a/server/db/providers/couchbase/shared.go b/server/db/providers/couchbase/shared.go index 104ad02..d640f68 100644 --- a/server/db/providers/couchbase/shared.go +++ b/server/db/providers/couchbase/shared.go @@ -11,24 +11,19 @@ import ( func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) { params := make(map[string]interface{}, 1) - updateFields := "" - for key, value := range webhookMap { if key == "_id" { continue } - if key == "_key" { continue } - if value == nil { updateFields += fmt.Sprintf("%s=$%s,", key, key) params[key] = "null" continue } - valueType := reflect.TypeOf(value) if valueType.Name() == "string" { updateFields += fmt.Sprintf("%s = $%s, ", key, key) diff --git a/server/db/providers/mongodb/otp.go b/server/db/providers/mongodb/otp.go index d6ff2df..8726f5a 100644 --- a/server/db/providers/mongodb/otp.go +++ b/server/db/providers/mongodb/otp.go @@ -2,6 +2,7 @@ package mongodb import ( "context" + "errors" "time" "github.com/authorizerdev/authorizer/server/db/models" @@ -12,6 +13,18 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otp.Email == "" && otp.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) shouldCreate := false if otp == nil { diff --git a/server/db/providers/mongodb/provider.go b/server/db/providers/mongodb/provider.go index fd4a0b2..1922b0e 100644 --- a/server/db/providers/mongodb/provider.go +++ b/server/db/providers/mongodb/provider.go @@ -118,6 +118,12 @@ func NewProvider() (*provider, error) { Options: options.Index().SetUnique(true).SetSparse(true), }, }, options.CreateIndexes()) + otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ + { + Keys: bson.M{"phone_number": 1}, + Options: options.Index().SetUnique(true).SetSparse(true), + }, + }, options.CreateIndexes()) mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection()) smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection()) diff --git a/server/db/providers/mongodb/sms_verification_requests.go b/server/db/providers/mongodb/sms_verification_requests.go index 1183df1..0ee0e6c 100644 --- a/server/db/providers/mongodb/sms_verification_requests.go +++ b/server/db/providers/mongodb/sms_verification_requests.go @@ -12,10 +12,7 @@ import ( // UpsertSMSRequest adds/updates SMS verification request func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - smsVerificationRequest, err := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) - if err != nil { - return nil, err - } + smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) // Boolean to check if we should create a new record or update the existing one shouldCreate := false if smsVerificationRequest == nil { @@ -29,7 +26,7 @@ func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSV } shouldCreate = true } - + var err error smsVerificationRequest.UpdatedAt = time.Now().Unix() smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) if shouldCreate { diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index 31c021c..c6065c1 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -82,6 +82,8 @@ type Provider interface { UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error) // GetOTPByEmail to get otp for a given email address GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) + // GetOTPByPhoneNumber to get otp for a given phone number + GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) // DeleteOTP to delete otp DeleteOTP(ctx context.Context, otp *models.OTP) error diff --git a/server/db/providers/sql/otp.go b/server/db/providers/sql/otp.go index 9aabcab..5503a7d 100644 --- a/server/db/providers/sql/otp.go +++ b/server/db/providers/sql/otp.go @@ -2,6 +2,7 @@ package sql import ( "context" + "errors" "time" "github.com/authorizerdev/authorizer/server/db/models" @@ -14,13 +15,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, if otp.ID == "" { otp.ID = uuid.New().String() } - + // check if email or phone number is present + if otp.Email == "" && otp.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otp.Email == "" && otp.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } otp.Key = otp.ID otp.CreatedAt = time.Now().Unix() otp.UpdatedAt = time.Now().Unix() - res := p.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "email"}}, + Columns: []clause.Column{{Name: uniqueField}}, DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}), }).Create(&otp) if res.Error != nil { @@ -33,7 +40,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - result := p.db.Where("email = ?", emailAddress).First(&otp) if result.Error != nil { return nil, result.Error @@ -41,6 +47,16 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return &otp, nil } +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + result := p.db.Where("phone_number = ?", phoneNumber).First(&otp) + if result.Error != nil { + return nil, result.Error + } + return &otp, nil +} + // DeleteOTP to delete otp func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { result := p.db.Delete(&models.OTP{ From 6fa0ad180971b6f5ee897afb028968a67668c5ab Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Wed, 12 Jul 2023 22:12:17 +0530 Subject: [PATCH 04/37] feat: add resolver to validate browser session --- server/graph/generated/generated.go | 263 +++++++++++++++++++++++++++ server/graph/model/models_gen.go | 10 +- server/graph/schema.graphqls | 10 + server/graph/schema.resolvers.go | 5 + server/resolvers/validate_session.go | 59 ++++++ server/test/resolvers_test.go | 1 + server/test/validate_session_test.go | 61 +++++++ 7 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 server/resolvers/validate_session.go create mode 100644 server/test/validate_session_test.go diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index e849306..885b04d 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -219,6 +219,7 @@ type ComplexityRoot struct { User func(childComplexity int, params model.GetUserRequest) int Users func(childComplexity int, params *model.PaginatedInput) int ValidateJwtToken func(childComplexity int, params model.ValidateJWTTokenInput) int + ValidateSession func(childComplexity int, params *model.ValidateSessionInput) int VerificationRequests func(childComplexity int, params *model.PaginatedInput) int Webhook func(childComplexity int, params model.WebhookRequest) int WebhookLogs func(childComplexity int, params *model.ListWebhookLogRequest) int @@ -275,6 +276,10 @@ type ComplexityRoot struct { IsValid func(childComplexity int) int } + ValidateSessionResponse struct { + IsValid func(childComplexity int) int + } + VerificationRequest struct { CreatedAt func(childComplexity int) int Email func(childComplexity int) int @@ -363,6 +368,7 @@ type QueryResolver interface { Session(ctx context.Context, params *model.SessionQueryInput) (*model.AuthResponse, error) Profile(ctx context.Context) (*model.User, error) ValidateJwtToken(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error) + ValidateSession(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) User(ctx context.Context, params model.GetUserRequest) (*model.User, error) VerificationRequests(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) @@ -1572,6 +1578,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ValidateJwtToken(childComplexity, args["params"].(model.ValidateJWTTokenInput)), true + case "Query.validate_session": + if e.complexity.Query.ValidateSession == nil { + break + } + + args, err := ec.field_Query_validate_session_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ValidateSession(childComplexity, args["params"].(*model.ValidateSessionInput)), true + case "Query._verification_requests": if e.complexity.Query.VerificationRequests == nil { break @@ -1844,6 +1862,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ValidateJWTTokenResponse.IsValid(childComplexity), true + case "ValidateSessionResponse.is_valid": + if e.complexity.ValidateSessionResponse.IsValid == nil { + break + } + + return e.complexity.ValidateSessionResponse.IsValid(childComplexity), true + case "VerificationRequest.created_at": if e.complexity.VerificationRequest.CreatedAt == nil { break @@ -2093,6 +2118,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateUserInput, ec.unmarshalInputUpdateWebhookRequest, ec.unmarshalInputValidateJWTTokenInput, + ec.unmarshalInputValidateSessionInput, ec.unmarshalInputVerifyEmailInput, ec.unmarshalInputVerifyMobileRequest, ec.unmarshalInputVerifyOTPRequest, @@ -2341,6 +2367,10 @@ type ValidateJWTTokenResponse { claims: Map } +type ValidateSessionResponse { + is_valid: Boolean! +} + type GenerateJWTKeysResponse { secret: String public_key: String @@ -2633,6 +2663,11 @@ input ValidateJWTTokenInput { roles: [String!] } +input ValidateSessionInput { + cookie: String! + roles: [String!] +} + input GenerateJWTKeysInput { type: String! } @@ -2755,6 +2790,7 @@ type Query { session(params: SessionQueryInput): AuthResponse! profile: User! validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! + validate_session(params: ValidateSessionInput): ValidateSessionResponse! # admin only apis _users(params: PaginatedInput): Users! _user(params: GetUserRequest!): User! @@ -3374,6 +3410,21 @@ func (ec *executionContext) field_Query_validate_jwt_token_args(ctx context.Cont return args, nil } +func (ec *executionContext) field_Query_validate_session_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *model.ValidateSessionInput + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalOValidateSessionInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -10159,6 +10210,65 @@ func (ec *executionContext) fieldContext_Query_validate_jwt_token(ctx context.Co return fc, nil } +func (ec *executionContext) _Query_validate_session(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_validate_session(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ValidateSession(rctx, fc.Args["params"].(*model.ValidateSessionInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.ValidateSessionResponse) + fc.Result = res + return ec.marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_validate_session(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "is_valid": + return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_validate_session_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return + } + return fc, nil +} + func (ec *executionContext) _Query__users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query__users(ctx, field) if err != nil { @@ -12381,6 +12491,50 @@ func (ec *executionContext) fieldContext_ValidateJWTTokenResponse_claims(ctx con return fc, nil } +func (ec *executionContext) _ValidateSessionResponse_is_valid(ctx context.Context, field graphql.CollectedField, obj *model.ValidateSessionResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsValid, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ValidateSessionResponse_is_valid(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValidateSessionResponse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field graphql.CollectedField, obj *model.VerificationRequest) (ret graphql.Marshaler) { fc, err := ec.fieldContext_VerificationRequest_id(ctx, field) if err != nil { @@ -17555,6 +17709,42 @@ func (ec *executionContext) unmarshalInputValidateJWTTokenInput(ctx context.Cont return it, nil } +func (ec *executionContext) unmarshalInputValidateSessionInput(ctx context.Context, obj interface{}) (model.ValidateSessionInput, error) { + var it model.ValidateSessionInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"cookie", "roles"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "cookie": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("cookie")) + it.Cookie, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "roles": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("roles")) + it.Roles, err = ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, obj interface{}) (model.VerifyEmailInput, error) { var it model.VerifyEmailInput asMap := map[string]interface{}{} @@ -18866,6 +19056,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) } + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "validate_session": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_validate_session(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) @@ -19395,6 +19608,34 @@ func (ec *executionContext) _ValidateJWTTokenResponse(ctx context.Context, sel a return out } +var validateSessionResponseImplementors = []string{"ValidateSessionResponse"} + +func (ec *executionContext) _ValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, obj *model.ValidateSessionResponse) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, validateSessionResponseImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ValidateSessionResponse") + case "is_valid": + + out.Values[i] = ec._ValidateSessionResponse_is_valid(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var verificationRequestImplementors = []string{"VerificationRequest"} func (ec *executionContext) _VerificationRequest(ctx context.Context, sel ast.SelectionSet, obj *model.VerificationRequest) graphql.Marshaler { @@ -20470,6 +20711,20 @@ func (ec *executionContext) marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋa return ec._ValidateJWTTokenResponse(ctx, sel, v) } +func (ec *executionContext) marshalNValidateSessionResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v model.ValidateSessionResponse) graphql.Marshaler { + return ec._ValidateSessionResponse(ctx, sel, &v) +} + +func (ec *executionContext) marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v *model.ValidateSessionResponse) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ValidateSessionResponse(ctx, sel, v) +} + func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.VerificationRequest) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -21158,6 +21413,14 @@ func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋautho return ec._User(ctx, sel, v) } +func (ec *executionContext) unmarshalOValidateSessionInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionInput(ctx context.Context, v interface{}) (*model.ValidateSessionInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputValidateSessionInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 7a1e376..d327f9a 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -120,7 +120,6 @@ type Env struct { AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"` DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"` DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"` - SmsCodeExpiryTime *string `json:"SMS_CODE_EXPIRY_TIME"` } type Error struct { @@ -456,6 +455,15 @@ type ValidateJWTTokenResponse struct { Claims map[string]interface{} `json:"claims"` } +type ValidateSessionInput struct { + Cookie string `json:"cookie"` + Roles []string `json:"roles"` +} + +type ValidateSessionResponse struct { + IsValid bool `json:"is_valid"` +} + type VerificationRequest struct { ID string `json:"id"` Identifier *string `json:"identifier"` diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 4013b12..c830236 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -182,6 +182,10 @@ type ValidateJWTTokenResponse { claims: Map } +type ValidateSessionResponse { + is_valid: Boolean! +} + type GenerateJWTKeysResponse { secret: String public_key: String @@ -474,6 +478,11 @@ input ValidateJWTTokenInput { roles: [String!] } +input ValidateSessionInput { + cookie: String! + roles: [String!] +} + input GenerateJWTKeysInput { type: String! } @@ -596,6 +605,7 @@ type Query { session(params: SessionQueryInput): AuthResponse! profile: User! validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! + validate_session(params: ValidateSessionInput): ValidateSessionResponse! # admin only apis _users(params: PaginatedInput): Users! _user(params: GetUserRequest!): User! diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 75dad85..beb49b2 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -191,6 +191,11 @@ func (r *queryResolver) ValidateJwtToken(ctx context.Context, params model.Valid return resolvers.ValidateJwtTokenResolver(ctx, params) } +// ValidateSession is the resolver for the validate_session field. +func (r *queryResolver) ValidateSession(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) { + return resolvers.ValidateSessionResolver(ctx, params) +} + // Users is the resolver for the _users field. func (r *queryResolver) Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) { return resolvers.UsersResolver(ctx, params) diff --git a/server/resolvers/validate_session.go b/server/resolvers/validate_session.go new file mode 100644 index 0000000..cb2b11f --- /dev/null +++ b/server/resolvers/validate_session.go @@ -0,0 +1,59 @@ +package resolvers + +import ( + "context" + "errors" + "fmt" + + "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/db" + "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/token" + "github.com/authorizerdev/authorizer/server/utils" + log "github.com/sirupsen/logrus" +) + +// ValidateSessionResolver is used to validate a cookie session without its rotation +func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) { + gc, err := utils.GinContextFromContext(ctx) + if err != nil { + log.Debug("Failed to get GinContext: ", err) + return nil, err + } + sessionToken := params.Cookie + if sessionToken == "" { + sessionToken, err = cookie.GetSession(gc) + if err != nil { + log.Debug("Failed to get session token: ", err) + return nil, errors.New("unauthorized") + } + } + claims, err := token.ValidateBrowserSession(gc, sessionToken) + if err != nil { + log.Debug("Failed to validate session token", err) + return nil, errors.New("unauthorized") + } + userID := claims.Subject + log := log.WithFields(log.Fields{ + "user_id": userID, + }) + _, err = db.Provider.GetUserByID(ctx, userID) + if err != nil { + return nil, err + } + // refresh token has "roles" as claim + claimRoleInterface := claims.Roles + claimRoles := []string{} + claimRoles = append(claimRoles, claimRoleInterface...) + if params != nil && params.Roles != nil && len(params.Roles) > 0 { + for _, v := range params.Roles { + if !utils.StringSliceContains(claimRoles, v) { + log.Debug("User does not have required role: ", claimRoles, v) + return nil, fmt.Errorf(`unauthorized`) + } + } + } + return &model.ValidateSessionResponse{ + IsValid: true, + }, nil +} diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index 4c83bf3..446986c 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -136,6 +136,7 @@ func TestResolvers(t *testing.T) { verifyOTPTest(t, s) resendOTPTest(t, s) verifyMobileTest(t, s) + validateSessionTests(t, s) updateAllUsersTest(t, s) webhookLogsTest(t, s) // get logs after above resolver tests are done diff --git a/server/test/validate_session_test.go b/server/test/validate_session_test.go new file mode 100644 index 0000000..16211ad --- /dev/null +++ b/server/test/validate_session_test.go @@ -0,0 +1,61 @@ +package test + +import ( + "fmt" + "strings" + "testing" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db" + "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/memorystore" + "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/authorizerdev/authorizer/server/token" + "github.com/stretchr/testify/assert" +) + +// ValidateSessionTests tests all the validate session resolvers +func validateSessionTests(t *testing.T, s TestSetup) { + t.Helper() + t.Run(`should validate session`, func(t *testing.T) { + req, ctx := createContext(s) + email := "validate_session." + s.TestInfo.Email + + resolvers.SignupResolver(ctx, model.SignUpInput{ + Email: email, + Password: s.TestInfo.Password, + ConfirmPassword: s.TestInfo.Password, + }) + _, err := resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{}) + assert.NotNil(t, err, "unauthorized") + verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup) + assert.NoError(t, err) + assert.NotNil(t, verificationRequest) + verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{ + Token: verificationRequest.Token, + }) + assert.NoError(t, err) + assert.NotNil(t, verifyRes) + accessToken := *verifyRes.AccessToken + assert.NotEmpty(t, accessToken) + claims, err := token.ParseJWTToken(accessToken) + assert.NoError(t, err) + assert.NotEmpty(t, claims) + sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + verifyRes.User.ID + sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string)) + assert.NoError(t, err) + assert.NotEmpty(t, sessionToken) + cookie := fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken) + cookie = strings.TrimSuffix(cookie, ";") + res, err := resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{ + Cookie: sessionToken, + }) + assert.Nil(t, err) + assert.True(t, res.IsValid) + req.Header.Set("Cookie", cookie) + res, err = resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{}) + assert.Nil(t, err) + assert.True(t, res.IsValid) + cleanData(email) + }) +} From d04f79557aed67e85474a808a9775304f78c46d8 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 13 Jul 2023 11:39:22 +0530 Subject: [PATCH 05/37] Refactor code for otp --- server/constants/auth_methods.go | 2 + server/db/models/sms_verification_requests.go | 12 -- server/db/providers/arangodb/otp.go | 59 +++++- server/db/providers/arangodb/provider.go | 17 +- .../arangodb/sms_verification_requests.go | 22 --- server/db/providers/cassandradb/otp.go | 46 ++++- server/db/providers/cassandradb/provider.go | 6 +- .../cassandradb/sms_verification_requests.go | 22 --- server/db/providers/couchbase/otp.go | 51 ++++-- server/db/providers/couchbase/provider.go | 4 + .../couchbase/sms_verification_requests.go | 22 --- server/db/providers/dynamodb/otp.go | 54 ++++-- .../dynamodb/sms_verification_requests.go | 22 --- server/db/providers/mongodb/otp.go | 38 ++-- server/db/providers/mongodb/provider.go | 9 - .../mongodb/sms_verification_requests.go | 66 ------- server/db/providers/provider_template/otp.go | 5 + .../sms_verification_requests.go | 22 --- server/db/providers/providers.go | 7 - server/db/providers/sql/provider.go | 2 +- .../sql/sms_verification_requests.go | 49 ----- server/graph/generated/generated.go | 173 ++---------------- server/graph/model/models_gen.go | 12 +- server/graph/schema.graphqls | 10 +- server/graph/schema.resolvers.go | 5 - server/resolvers/mobile_signup.go | 22 +-- server/resolvers/verify_mobile.go | 62 ------- server/resolvers/verify_otp.go | 45 +++-- server/test/mobile_login_test.go | 14 +- server/test/resend_otp_test.go | 4 +- server/test/resolvers_test.go | 1 - server/test/verify_mobile_test.go | 79 -------- server/test/verify_otp_test.go | 2 +- 33 files changed, 279 insertions(+), 687 deletions(-) delete mode 100644 server/db/models/sms_verification_requests.go delete mode 100644 server/db/providers/arangodb/sms_verification_requests.go delete mode 100644 server/db/providers/cassandradb/sms_verification_requests.go delete mode 100644 server/db/providers/couchbase/sms_verification_requests.go delete mode 100644 server/db/providers/dynamodb/sms_verification_requests.go delete mode 100644 server/db/providers/mongodb/sms_verification_requests.go delete mode 100644 server/db/providers/provider_template/sms_verification_requests.go delete mode 100644 server/db/providers/sql/sms_verification_requests.go delete mode 100644 server/resolvers/verify_mobile.go delete mode 100644 server/test/verify_mobile_test.go diff --git a/server/constants/auth_methods.go b/server/constants/auth_methods.go index 9e7b9fa..dbe5175 100644 --- a/server/constants/auth_methods.go +++ b/server/constants/auth_methods.go @@ -7,6 +7,8 @@ const ( AuthRecipeMethodMobileBasicAuth = "mobile_basic_auth" // AuthRecipeMethodMagicLinkLogin is the magic_link_login auth method AuthRecipeMethodMagicLinkLogin = "magic_link_login" + // AuthRecipeMethodMobileOTP is the mobile_otp auth method + AuthRecipeMethodMobileOTP = "mobile_otp" // AuthRecipeMethodGoogle is the google auth method AuthRecipeMethodGoogle = "google" // AuthRecipeMethodGithub is the github auth method diff --git a/server/db/models/sms_verification_requests.go b/server/db/models/sms_verification_requests.go deleted file mode 100644 index e14da4c..0000000 --- a/server/db/models/sms_verification_requests.go +++ /dev/null @@ -1,12 +0,0 @@ -package models - -// SMSVerificationRequest is SMS verification requests model for database -type SMSVerificationRequest struct { - Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` - PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` - Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` - CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"` - CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` - UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` -} diff --git a/server/db/providers/arangodb/otp.go b/server/db/providers/arangodb/otp.go index 29f265a..8fef639 100644 --- a/server/db/providers/arangodb/otp.go +++ b/server/db/providers/arangodb/otp.go @@ -2,6 +2,7 @@ package arangodb import ( "context" + "errors" "fmt" "time" @@ -12,17 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { @@ -67,7 +82,35 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod for { if !cursor.HasMore() { if otp.Key == "" { - return nil, fmt.Errorf("email template not found") + return nil, fmt.Errorf("otp with given email not found") + } + break + } + _, err := cursor.ReadDocument(ctx, &otp) + if err != nil { + return nil, err + } + } + + return &otp, nil +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.OTP) + bindVars := map[string]interface{}{ + "phone_number": phoneNumber, + } + cursor, err := p.db.Query(ctx, query, bindVars) + if err != nil { + return nil, err + } + defer cursor.Close() + for { + if !cursor.HasMore() { + if otp.Key == "" { + return nil, fmt.Errorf("otp with given phone_number not found") } break } diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 88fc6e4..2dd7b28 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -233,22 +233,7 @@ func NewProvider() (*provider, error) { Unique: true, Sparse: true, }) - - smsVerificationCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.SMSVerificationRequest) - if err != nil { - return nil, err - } - if !smsVerificationCollectionExists { - _, err = arangodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, nil) - if err != nil { - return nil, err - } - } - smsVerificationCollection, err := arangodb.Collection(ctx, models.Collections.SMSVerificationRequest) - if err != nil { - return nil, err - } - smsVerificationCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + otpCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ Unique: true, Sparse: true, }) diff --git a/server/db/providers/arangodb/sms_verification_requests.go b/server/db/providers/arangodb/sms_verification_requests.go deleted file mode 100644 index 6eb97b8..0000000 --- a/server/db/providers/arangodb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package arangodb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/cassandradb/otp.go b/server/db/providers/cassandradb/otp.go index bfe481d..e453242 100644 --- a/server/db/providers/cassandradb/otp.go +++ b/server/db/providers/cassandradb/otp.go @@ -2,6 +2,7 @@ package cassandradb import ( "context" + "errors" "fmt" "time" @@ -12,17 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { shouldCreate = true otp = &models.OTP{ - ID: uuid.NewString(), - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), - UpdatedAt: time.Now().Unix(), + ID: uuid.NewString(), + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), + UpdatedAt: time.Now().Unix(), } } else { otp.Otp = otpParam.Otp @@ -32,7 +47,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models otp.UpdatedAt = time.Now().Unix() query := "" if shouldCreate { - query = fmt.Sprintf(`INSERT INTO %s (id, email, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt) + query = fmt.Sprintf(`INSERT INTO %s (id, email, phone_number, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.PhoneNumber, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt) } else { query = fmt.Sprintf(`UPDATE %s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, KeySpace+"."+models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID) } @@ -48,8 +63,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - query := fmt.Sprintf(`SELECT id, email, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress) - err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) + query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress) + err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) + if err != nil { + return nil, err + } + return &otp, nil +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, phoneNumber) + err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) if err != nil { return nil, err } diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go index 1d8fa49..1c989be 100644 --- a/server/db/providers/cassandradb/provider.go +++ b/server/db/providers/cassandradb/provider.go @@ -254,7 +254,11 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } - + otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP) + err = session.Query(otpIndexQueryPhoneNumber).Exec() + if err != nil { + return nil, err + } return &provider{ db: session, }, err diff --git a/server/db/providers/cassandradb/sms_verification_requests.go b/server/db/providers/cassandradb/sms_verification_requests.go deleted file mode 100644 index ddead30..0000000 --- a/server/db/providers/cassandradb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package cassandradb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/couchbase/otp.go b/server/db/providers/couchbase/otp.go index cdcfde9..1fe6532 100644 --- a/server/db/providers/couchbase/otp.go +++ b/server/db/providers/couchbase/otp.go @@ -2,6 +2,7 @@ package couchbase import ( "context" + "errors" "fmt" "time" @@ -12,24 +13,36 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) - + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { shouldCreate = true otp = &models.OTP{ - ID: uuid.NewString(), - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), - UpdatedAt: time.Now().Unix(), + ID: uuid.NewString(), + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), + UpdatedAt: time.Now().Unix(), } } else { otp.Otp = otpParam.Otp otp.ExpiresAt = otpParam.ExpiresAt } - otp.UpdatedAt = time.Now().Unix() if shouldCreate { insertOpt := gocb.InsertOptions{ @@ -54,7 +67,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { otp := models.OTP{} - query := fmt.Sprintf(`SELECT _id, email, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) + query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) q, err := p.db.Query(query, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistencyRequestPlus, PositionalParameters: []interface{}{emailAddress}, @@ -63,11 +76,27 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return nil, err } err = q.One(&otp) - if err != nil { return nil, err } + return &otp, nil +} +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + otp := models.OTP{} + query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) + q, err := p.db.Query(query, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + PositionalParameters: []interface{}{phoneNumber}, + }) + if err != nil { + return nil, err + } + err = q.One(&otp) + if err != nil { + return nil, err + } return &otp, nil } diff --git a/server/db/providers/couchbase/provider.go b/server/db/providers/couchbase/provider.go index c5d5404..723e47a 100644 --- a/server/db/providers/couchbase/provider.go +++ b/server/db/providers/couchbase/provider.go @@ -166,5 +166,9 @@ func GetIndex(scopeName string) map[string][]string { otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, models.Collections.OTP) indices[models.Collections.OTP] = []string{otpIndex1} + // OTP index + otpIndex2 := fmt.Sprintf("CREATE INDEX OTPPhoneNumberIndex ON %s.%s(phone_number)", scopeName, models.Collections.OTP) + indices[models.Collections.OTP] = []string{otpIndex2} + return indices } diff --git a/server/db/providers/couchbase/sms_verification_requests.go b/server/db/providers/couchbase/sms_verification_requests.go deleted file mode 100644 index 0639179..0000000 --- a/server/db/providers/couchbase/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package couchbase - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/dynamodb/otp.go b/server/db/providers/dynamodb/otp.go index 063f634..bb55523 100644 --- a/server/db/providers/dynamodb/otp.go +++ b/server/db/providers/dynamodb/otp.go @@ -11,27 +11,39 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { otp.Otp = otpParam.Otp otp.ExpiresAt = otpParam.ExpiresAt } - collection := p.db.Table(models.Collections.OTP) otp.UpdatedAt = time.Now().Unix() - var err error if shouldCreate { err = collection.Put(otp).RunWithContext(ctx) @@ -41,7 +53,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models if err != nil { return nil, err } - return otp, nil } @@ -49,20 +60,32 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otps []models.OTP var otp models.OTP - collection := p.db.Table(models.Collections.OTP) - err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps) - if err != nil { return nil, err } if len(otps) > 0 { otp = otps[0] return &otp, nil - } else { - return nil, errors.New("no docuemnt found") } + return nil, errors.New("no docuemnt found") +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otps []models.OTP + var otp models.OTP + collection := p.db.Table(models.Collections.OTP) + err := collection.Scan().Index("phone_number").Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) + if err != nil { + return nil, err + } + if len(otps) > 0 { + otp = otps[0] + return &otp, nil + } + return nil, errors.New("no docuemnt found") } // DeleteOTP to delete otp @@ -75,6 +98,5 @@ func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { return err } } - return nil } diff --git a/server/db/providers/dynamodb/sms_verification_requests.go b/server/db/providers/dynamodb/sms_verification_requests.go deleted file mode 100644 index 6569a54..0000000 --- a/server/db/providers/dynamodb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package dynamodb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/mongodb/otp.go b/server/db/providers/mongodb/otp.go index 8726f5a..d70818d 100644 --- a/server/db/providers/mongodb/otp.go +++ b/server/db/providers/mongodb/otp.go @@ -13,29 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - // check if email or phone number is present - if otpParam.Email == "" && otpParam.PhoneNumber == "" { - return nil, errors.New("email or phone_number is required") - } // check if email or phone number is present if otpParam.Email == "" && otpParam.PhoneNumber == "" { return nil, errors.New("email or phone_number is required") } uniqueField := models.FieldNameEmail - if otp.Email == "" && otp.PhoneNumber != "" { + if otpParam.Email == "" && otpParam.PhoneNumber != "" { uniqueField = models.FieldNamePhoneNumber } - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { @@ -54,20 +56,28 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models if err != nil { return nil, err } - return otp, nil } // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - otpCollection := p.db.Collection(models.Collections.OTP, options.Collection()) err := otpCollection.FindOne(ctx, bson.M{"email": emailAddress}).Decode(&otp) if err != nil { return nil, err } + return &otp, nil +} +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + otpCollection := p.db.Collection(models.Collections.OTP, options.Collection()) + err := otpCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&otp) + if err != nil { + return nil, err + } return &otp, nil } diff --git a/server/db/providers/mongodb/provider.go b/server/db/providers/mongodb/provider.go index 1922b0e..30af342 100644 --- a/server/db/providers/mongodb/provider.go +++ b/server/db/providers/mongodb/provider.go @@ -125,15 +125,6 @@ func NewProvider() (*provider, error) { }, }, options.CreateIndexes()) - mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection()) - smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - smsCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ - { - Keys: bson.M{"phone_number": 1}, - Options: options.Index().SetUnique(true).SetSparse(true), - }, - }, options.CreateIndexes()) - return &provider{ db: mongodb, }, nil diff --git a/server/db/providers/mongodb/sms_verification_requests.go b/server/db/providers/mongodb/sms_verification_requests.go deleted file mode 100644 index 0ee0e6c..0000000 --- a/server/db/providers/mongodb/sms_verification_requests.go +++ /dev/null @@ -1,66 +0,0 @@ -package mongodb - -import ( - "context" - "time" - - "github.com/authorizerdev/authorizer/server/db/models" - "github.com/google/uuid" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo/options" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) - // Boolean to check if we should create a new record or update the existing one - shouldCreate := false - if smsVerificationRequest == nil { - id := uuid.NewString() - smsVerificationRequest = &models.SMSVerificationRequest{ - ID: id, - CreatedAt: time.Now().Unix(), - Code: smsRequest.Code, - PhoneNumber: smsRequest.PhoneNumber, - CodeExpiresAt: smsRequest.CodeExpiresAt, - } - shouldCreate = true - } - var err error - smsVerificationRequest.UpdatedAt = time.Now().Unix() - smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - if shouldCreate { - _, err = smsRequestCollection.InsertOne(ctx, smsVerificationRequest) - } else { - _, err = smsRequestCollection.UpdateOne(ctx, bson.M{"phone_number": bson.M{"$eq": smsRequest.PhoneNumber}}, bson.M{"$set": smsVerificationRequest}, options.MergeUpdateOptions()) - } - if err != nil { - return nil, err - } - return smsVerificationRequest, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var smsVerificationRequest models.SMSVerificationRequest - - smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - err := smsRequestCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&smsVerificationRequest) - - if err != nil { - return nil, err - } - - return &smsVerificationRequest, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - smsVerificationRequests := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - _, err := smsVerificationRequests.DeleteOne(nil, bson.M{"_id": smsRequest.ID}, options.Delete()) - if err != nil { - return err - } - - return nil -} diff --git a/server/db/providers/provider_template/otp.go b/server/db/providers/provider_template/otp.go index d8685e7..0716711 100644 --- a/server/db/providers/provider_template/otp.go +++ b/server/db/providers/provider_template/otp.go @@ -16,6 +16,11 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return nil, nil } +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + return nil, nil +} + // DeleteOTP to delete otp func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { return nil diff --git a/server/db/providers/provider_template/sms_verification_requests.go b/server/db/providers/provider_template/sms_verification_requests.go deleted file mode 100644 index d238a80..0000000 --- a/server/db/providers/provider_template/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package provider_template - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index c6065c1..be25b53 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -86,11 +86,4 @@ type Provider interface { GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) // DeleteOTP to delete otp DeleteOTP(ctx context.Context, otp *models.OTP) error - - // UpsertSMSRequest adds/updates SMS verification request - UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) - // GetCodeByPhone to get code for a given phone number - GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) - // DeleteSMSRequest to delete SMS verification request - DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error } diff --git a/server/db/providers/sql/provider.go b/server/db/providers/sql/provider.go index 89ea31b..2101953 100644 --- a/server/db/providers/sql/provider.go +++ b/server/db/providers/sql/provider.go @@ -77,7 +77,7 @@ func NewProvider() (*provider, error) { logrus.Debug("Failed to drop phone number constraint:", err) } - err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}, &models.SMSVerificationRequest{}) + err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}) if err != nil { return nil, err } diff --git a/server/db/providers/sql/sms_verification_requests.go b/server/db/providers/sql/sms_verification_requests.go deleted file mode 100644 index 387b5eb..0000000 --- a/server/db/providers/sql/sms_verification_requests.go +++ /dev/null @@ -1,49 +0,0 @@ -package sql - -import ( - "context" - "time" - - "github.com/authorizerdev/authorizer/server/db/models" - "github.com/google/uuid" - "gorm.io/gorm/clause" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - if smsRequest.ID == "" { - smsRequest.ID = uuid.New().String() - } - smsRequest.CreatedAt = time.Now().Unix() - smsRequest.UpdatedAt = time.Now().Unix() - res := p.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "phone_number"}}, - DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at", "updated_at"}), - }).Create(smsRequest) - if res.Error != nil { - return nil, res.Error - } - return smsRequest, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - result := p.db.Where("phone_number = ?", phoneNumber).First(&sms_verification_request) - if result.Error != nil { - return nil, result.Error - } - return &sms_verification_request, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - result := p.db.Delete(&models.SMSVerificationRequest{ - ID: smsRequest.ID, - }) - if result.Error != nil { - return result.Error - } - return nil -} diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 885b04d..b2493ef 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -198,7 +198,6 @@ type ComplexityRoot struct { UpdateUser func(childComplexity int, params model.UpdateUserInput) int UpdateWebhook func(childComplexity int, params model.UpdateWebhookRequest) int VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int - VerifyMobile func(childComplexity int, params model.VerifyMobileRequest) int VerifyOtp func(childComplexity int, params model.VerifyOTPRequest) int } @@ -344,7 +343,6 @@ type MutationResolver interface { Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error) ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) - VerifyMobile(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) @@ -1438,18 +1436,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.VerifyEmail(childComplexity, args["params"].(model.VerifyEmailInput)), true - case "Mutation.verify_mobile": - if e.complexity.Mutation.VerifyMobile == nil { - break - } - - args, err := ec.field_Mutation_verify_mobile_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.VerifyMobile(childComplexity, args["params"].(model.VerifyMobileRequest)), true - case "Mutation.verify_otp": if e.complexity.Mutation.VerifyOtp == nil { break @@ -2120,7 +2106,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputValidateJWTTokenInput, ec.unmarshalInputValidateSessionInput, ec.unmarshalInputVerifyEmailInput, - ec.unmarshalInputVerifyMobileRequest, ec.unmarshalInputVerifyOTPRequest, ec.unmarshalInputWebhookRequest, ) @@ -2269,11 +2254,6 @@ type SMSVerificationRequests { updated_at: Int64 } -input VerifyMobileRequest { - phone_number: String! - code: String! -} - type Error { message: String! reason: String! @@ -2728,7 +2708,9 @@ input DeleteEmailTemplateRequest { } input VerifyOTPRequest { - email: String! + # either email or phone_number is required + email: String + phone_number: String otp: String! # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login @@ -2764,7 +2746,6 @@ type Mutation { revoke(params: OAuthRevokeInput!): Response! verify_otp(params: VerifyOTPRequest!): AuthResponse! resend_otp(params: ResendOTPRequest!): Response! - verify_mobile(params: VerifyMobileRequest!): AuthResponse! # admin only apis _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! @@ -3230,21 +3211,6 @@ func (ec *executionContext) field_Mutation_verify_email_args(ctx context.Context return args, nil } -func (ec *executionContext) field_Mutation_verify_mobile_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 model.VerifyMobileRequest - if tmp, ok := rawArgs["params"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) - arg0, err = ec.unmarshalNVerifyMobileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyMobileRequest(ctx, tmp) - if err != nil { - return nil, err - } - } - args["params"] = arg0 - return args, nil -} - func (ec *executionContext) field_Mutation_verify_otp_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -8635,77 +8601,6 @@ func (ec *executionContext) fieldContext_Mutation_resend_otp(ctx context.Context return fc, nil } -func (ec *executionContext) _Mutation_verify_mobile(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_verify_mobile(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().VerifyMobile(rctx, fc.Args["params"].(model.VerifyMobileRequest)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*model.AuthResponse) - fc.Result = res - return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Mutation_verify_mobile(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Mutation", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "message": - return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) - case "access_token": - return ec.fieldContext_AuthResponse_access_token(ctx, field) - case "id_token": - return ec.fieldContext_AuthResponse_id_token(ctx, field) - case "refresh_token": - return ec.fieldContext_AuthResponse_refresh_token(ctx, field) - case "expires_in": - return ec.fieldContext_AuthResponse_expires_in(ctx, field) - case "user": - return ec.fieldContext_AuthResponse_user(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type AuthResponse", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_verify_mobile_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return - } - return fc, nil -} - func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation__delete_user(ctx, field) if err != nil { @@ -17781,42 +17676,6 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, return it, nil } -func (ec *executionContext) unmarshalInputVerifyMobileRequest(ctx context.Context, obj interface{}) (model.VerifyMobileRequest, error) { - var it model.VerifyMobileRequest - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"phone_number", "code"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "phone_number": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) - it.PhoneNumber, err = ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - case "code": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("code")) - it.Code, err = ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - } - } - - return it, nil -} - func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, obj interface{}) (model.VerifyOTPRequest, error) { var it model.VerifyOTPRequest asMap := map[string]interface{}{} @@ -17824,7 +17683,7 @@ func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"email", "otp", "state"} + fieldsInOrder := [...]string{"email", "phone_number", "otp", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -17835,7 +17694,15 @@ func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email")) - it.Email, err = ec.unmarshalNString2string(ctx, v) + it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "phone_number": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) + it.PhoneNumber, err = ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } @@ -18723,15 +18590,6 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) return ec._Mutation_resend_otp(ctx, field) }) - if out.Values[i] == graphql.Null { - invalids++ - } - case "verify_mobile": - - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_verify_mobile(ctx, field) - }) - if out.Values[i] == graphql.Null { invalids++ } @@ -20798,11 +20656,6 @@ func (ec *executionContext) unmarshalNVerifyEmailInput2githubᚗcomᚋauthorizer return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNVerifyMobileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyMobileRequest(ctx context.Context, v interface{}) (model.VerifyMobileRequest, error) { - res, err := ec.unmarshalInputVerifyMobileRequest(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyOTPRequest(ctx context.Context, v interface{}) (model.VerifyOTPRequest, error) { res, err := ec.unmarshalInputVerifyOTPRequest(ctx, v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index d327f9a..7621995 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -486,15 +486,11 @@ type VerifyEmailInput struct { State *string `json:"state"` } -type VerifyMobileRequest struct { - PhoneNumber string `json:"phone_number"` - Code string `json:"code"` -} - type VerifyOTPRequest struct { - Email string `json:"email"` - Otp string `json:"otp"` - State *string `json:"state"` + Email *string `json:"email"` + PhoneNumber *string `json:"phone_number"` + Otp string `json:"otp"` + State *string `json:"state"` } type Webhook struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index c830236..bb83b9b 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -84,11 +84,6 @@ type SMSVerificationRequests { updated_at: Int64 } -input VerifyMobileRequest { - phone_number: String! - code: String! -} - type Error { message: String! reason: String! @@ -543,7 +538,9 @@ input DeleteEmailTemplateRequest { } input VerifyOTPRequest { - email: String! + # either email or phone_number is required + email: String + phone_number: String otp: String! # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login @@ -579,7 +576,6 @@ type Mutation { revoke(params: OAuthRevokeInput!): Response! verify_otp(params: VerifyOTPRequest!): AuthResponse! resend_otp(params: ResendOTPRequest!): Response! - verify_mobile(params: VerifyMobileRequest!): AuthResponse! # admin only apis _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index beb49b2..eecb6b2 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -81,11 +81,6 @@ func (r *mutationResolver) ResendOtp(ctx context.Context, params model.ResendOTP return resolvers.ResendOTPResolver(ctx, params) } -// VerifyMobile is the resolver for the verify_mobile field. -func (r *mutationResolver) VerifyMobile(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) { - return resolvers.VerifyMobileResolver(ctx, params) -} - // DeleteUser is the resolver for the _delete_user field. func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) { return resolvers.DeleteUserResolver(ctx, params) diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 9aee0a6..908ecfe 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" log "github.com/sirupsen/logrus" - + "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/crypto" @@ -17,9 +17,9 @@ import ( "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/utils" - "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/validators" ) @@ -133,8 +133,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } user := models.User{ - Email: emailInput, - PhoneNumber: &mobile, + Email: emailInput, + PhoneNumber: &mobile, } user.Roles = strings.Join(inputRoles, ",") @@ -179,7 +179,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("MFA service not enabled: ", err) isMFAEnforced = false } - + if isMFAEnforced { user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true) } @@ -197,11 +197,11 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - + if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() - + smsBody := strings.Builder{} smsBody.WriteString("Your verification code is: ") smsBody.WriteString(smsCode) @@ -213,10 +213,10 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } go func() { - db.Provider.UpsertSMSRequest(ctx, &models.SMSVerificationRequest{ - PhoneNumber: mobile, - Code: smsCode, - CodeExpiresAt: time.Now().Add(duration).Unix(), + db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: mobile, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), }) smsproviders.SendSMS(mobile, smsBody.String()) }() diff --git a/server/resolvers/verify_mobile.go b/server/resolvers/verify_mobile.go deleted file mode 100644 index 4e077d7..0000000 --- a/server/resolvers/verify_mobile.go +++ /dev/null @@ -1,62 +0,0 @@ -package resolvers - -import ( - "fmt" - "context" - "time" - - "github.com/authorizerdev/authorizer/server/graph/model" - "github.com/authorizerdev/authorizer/server/utils" - "github.com/authorizerdev/authorizer/server/db" - log "github.com/sirupsen/logrus" -) - -func VerifyMobileResolver(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) { - var res *model.AuthResponse - - _, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug("Failed to get GinContext: ", err) - return res, err - } - - smsVerificationRequest, err := db.Provider.GetCodeByPhone(ctx, params.PhoneNumber) - if err != nil { - log.Debug("Failed to get sms request by phone: ", err) - return res, err - } - - if smsVerificationRequest.Code != params.Code { - log.Debug("Failed to verify request: bad credentials") - return res, fmt.Errorf(`bad credentials`) - } - - expiresIn := smsVerificationRequest.CodeExpiresAt - time.Now().Unix() - if expiresIn < 0 { - log.Debug("Failed to verify sms request: Timeout") - return res, fmt.Errorf("time expired") - } - - res = &model.AuthResponse{ - Message: "successful", - } - - user, err := db.Provider.GetUserByPhoneNumber(ctx, params.PhoneNumber) - if user.PhoneNumberVerifiedAt == nil { - now := time.Now().Unix() - user.PhoneNumberVerifiedAt = &now - } - - _, err = db.Provider.UpdateUser(ctx, *user) - if err != nil { - log.Debug("Failed to update user: ", err) - return res, err - } - - err = db.Provider.DeleteSMSRequest(ctx, smsVerificationRequest) - if err != nil { - log.Debug("Failed to delete sms request: ", err.Error()) - } - - return res, err -} diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 80080d9..124ee3f 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -27,36 +27,53 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to get GinContext: ", err) return res, err } - - otp, err := db.Provider.GetOTPByEmail(ctx, params.Email) - if err != nil { - log.Debug("Failed to get otp request by email: ", err) - return res, fmt.Errorf(`invalid email: %s`, err.Error()) + if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" { + log.Debug("Email or phone number is required") + return res, fmt.Errorf(`email or phone_number is required`) } + currentField := models.FieldNameEmail + if refs.StringValue(params.Email) == "" { + currentField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if currentField == models.FieldNameEmail { + otp, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email)) + } else { + otp, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + } + if otp == nil && err != nil { + log.Debugf("Failed to get otp request for %s: %s", currentField, err.Error()) + return res, fmt.Errorf(`invalid %s: %s`, currentField, err.Error()) + } if params.Otp != otp.Otp { log.Debug("Failed to verify otp request: Incorrect value") return res, fmt.Errorf(`invalid otp`) } - expiresIn := otp.ExpiresAt - time.Now().Unix() - if expiresIn < 0 { log.Debug("Failed to verify otp request: Timeout") return res, fmt.Errorf("otp expired") } - - user, err := db.Provider.GetUserByEmail(ctx, params.Email) - if err != nil { + var user models.User + if currentField == models.FieldNameEmail { + user, err = db.Provider.GetUserByEmail(ctx, refs.StringValue(params.Email)) + } else { + // TODO fix after refs of db providers are fixed + var u *models.User + u, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + user = *u + } + if user.ID == "" && err != nil { log.Debug("Failed to get user by email: ", err) return res, err } - - isSignUp := user.EmailVerifiedAt == nil - + isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil // TODO - Add Login method in DB when we introduce OTP for social media login loginMethod := constants.AuthRecipeMethodBasicAuth - + if currentField == models.FieldNamePhoneNumber { + loginMethod = constants.AuthRecipeMethodMobileOTP + } roles := strings.Split(user.Roles, ",") scope := []string{"openid", "email", "profile"} code := "" diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go index 48b7690..d81d780 100644 --- a/server/test/mobile_login_test.go +++ b/server/test/mobile_login_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/db" + "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" "github.com/stretchr/testify/assert" @@ -54,17 +54,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) { assert.NotNil(t, err, "should fail because phone is not verified") assert.Nil(t, res) - smsRequest, err := db.Provider.GetCodeByPhone(ctx, phoneNumber) + smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.NoError(t, err) - assert.NotEmpty(t, smsRequest.Code) + assert.NotEmpty(t, smsRequest.Otp) - verifySMSRequest, err := resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: smsRequest.Code, + verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ + PhoneNumber: &phoneNumber, + Otp: smsRequest.Otp, }) assert.Nil(t, err) assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - + res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, Password: s.TestInfo.Password, diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go index 73e715d..eb6993f 100644 --- a/server/test/resend_otp_test.go +++ b/server/test/resend_otp_test.go @@ -84,13 +84,13 @@ func resendOTPTest(t *testing.T, s TestSetup) { // Should return error for older otp verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: otp.Otp, }) assert.Error(t, err) assert.Nil(t, verifyOtpRes) verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: newOtp.Otp, }) assert.NoError(t, err) diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index 446986c..ecda491 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -135,7 +135,6 @@ func TestResolvers(t *testing.T) { validateJwtTokenTest(t, s) verifyOTPTest(t, s) resendOTPTest(t, s) - verifyMobileTest(t, s) validateSessionTests(t, s) updateAllUsersTest(t, s) diff --git a/server/test/verify_mobile_test.go b/server/test/verify_mobile_test.go deleted file mode 100644 index b4daa5e..0000000 --- a/server/test/verify_mobile_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package test - -import ( - "strings" - "testing" - - "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/graph/model" - "github.com/authorizerdev/authorizer/server/db" - "github.com/authorizerdev/authorizer/server/refs" - "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/stretchr/testify/assert" -) - -func verifyMobileTest(t *testing.T, s TestSetup) { - t.Helper() - t.Run(`should verify mobile`, func(t *testing.T) { - _, ctx := createContext(s) - email := "mobile_verification." + s.TestInfo.Email - phoneNumber := "2234567890" - signUpRes, err := resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ - Email: refs.NewStringRef(email), - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - ConfirmPassword: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotNil(t, signUpRes) - assert.Equal(t, email, signUpRes.User.Email) - assert.Equal(t, phoneNumber, refs.StringValue(signUpRes.User.PhoneNumber)) - assert.True(t, strings.Contains(signUpRes.User.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth)) - assert.Len(t, strings.Split(signUpRes.User.SignupMethods, ","), 1) - - res, err := resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: "random_test", - }) - assert.Error(t, err) - assert.Nil(t, res) - - // should fail because phone is not verified - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NotNil(t, err, "should fail because phone is not verified") - assert.Nil(t, res) - - // get code from db - smsRequest, err := db.Provider.GetCodeByPhone(ctx, phoneNumber) - assert.NoError(t, err) - assert.NotEmpty(t, smsRequest.Code) - - // throw an error if the code is not correct - verifySMSRequest, err := resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: "rand_12@1", - }) - assert.NotNil(t, err, "should fail because of bad credentials") - assert.Nil(t, verifySMSRequest) - - verifySMSRequest, err = resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: smsRequest.Code, - }) - assert.Nil(t, err) - assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.NotEmpty(t, res.IDToken) - - cleanData(email) - }) -} diff --git a/server/test/verify_otp_test.go b/server/test/verify_otp_test.go index 9e074cd..750deb5 100644 --- a/server/test/verify_otp_test.go +++ b/server/test/verify_otp_test.go @@ -65,7 +65,7 @@ func verifyOTPTest(t *testing.T, s TestSetup) { assert.NotEmpty(t, otp.Otp) verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: otp.Otp, }) assert.Nil(t, err) From 87a962504fe14a99a71c9ad0bc8e8933e9a8ca15 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 16 Jul 2023 22:57:56 +0530 Subject: [PATCH 06/37] Increase timeout for redis --- server/memorystore/providers/redis/provider.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/memorystore/providers/redis/provider.go b/server/memorystore/providers/redis/provider.go index 894a75e..17fb475 100644 --- a/server/memorystore/providers/redis/provider.go +++ b/server/memorystore/providers/redis/provider.go @@ -9,6 +9,10 @@ import ( log "github.com/sirupsen/logrus" ) +const ( + dialTimeout = 60 * time.Second +) + // RedisClient is the interface for redis client & redis cluster client type RedisClient interface { HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd @@ -41,8 +45,7 @@ func NewRedisProvider(redisURL string) (*provider, error) { urls := []string{opt.Addr} urlList := redisURLHostPortsList[1:] urls = append(urls, urlList...) - clusterOpt := &redis.ClusterOptions{Addrs: urls} - + clusterOpt := &redis.ClusterOptions{Addrs: urls, DialTimeout: dialTimeout} rdb := redis.NewClusterClient(clusterOpt) ctx := context.Background() _, err = rdb.Ping(ctx).Result() @@ -62,7 +65,7 @@ func NewRedisProvider(redisURL string) (*provider, error) { log.Debug("error parsing redis url: ", err) return nil, err } - + opt.DialTimeout = dialTimeout rdb := redis.NewClient(opt) ctx := context.Background() _, err = rdb.Ping(ctx).Result() From edb5412c17212e4fc957faed109d2664d2024fa9 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 18 Jul 2023 22:50:23 +0530 Subject: [PATCH 07/37] Fix tests --- server/db/models/otp.go | 2 +- server/resolvers/mobile_login.go | 40 +++++++++++++++++++++++++++++++ server/resolvers/mobile_signup.go | 22 ++++++++++------- server/smsproviders/twilio.go | 20 ++++++---------- server/test/mobile_login_test.go | 21 ++-------------- server/test/mobile_signup_test.go | 22 +++++++++++++---- 6 files changed, 81 insertions(+), 46 deletions(-) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index b0e02ee..8ccb13e 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -12,7 +12,7 @@ type OTP struct { Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 9da0a53..8368745 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -17,6 +17,7 @@ import ( "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/validators" @@ -94,6 +95,45 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m roles = params.Roles } + disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + if disablePhoneVerification { + now := time.Now().Unix() + user.PhoneNumberVerifiedAt = &now + } + fmt.Println("=> disablePhoneVerification", disablePhoneVerification) + + if !disablePhoneVerification { + duration, _ := time.ParseDuration("10m") + smsCode := utils.GenerateOTP() + + smsBody := strings.Builder{} + smsBody.WriteString("Your verification code is: ") + smsBody.WriteString(smsCode) + + // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api + if err != nil { + log.Debug("error while upserting user: ", err.Error()) + return nil, err + } + _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: params.PhoneNumber, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), + }) + if err != nil { + log.Debug("error while upserting OTP: ", err.Error()) + return nil, err + } + go func() { + + smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) + }() + return &model.AuthResponse{ + Message: "Please check the OTP", + ShouldShowOtpScreen: refs.NewBoolRef(true), + }, nil + } + scope := []string{"openid", "email", "profile"} if params.Scope != nil && len(scope) > 0 { scope = params.Scope diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 908ecfe..610b238 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -105,7 +105,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } inputRoles := []string{} - if len(params.Roles) > 0 { // check if roles exists rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles) @@ -197,7 +196,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - + fmt.Println("=> disablePhoneVerification signup", disablePhoneVerification) if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() @@ -211,15 +210,22 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("error while upserting user: ", err.Error()) return nil, err } - + _, err = db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: mobile, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), + }) + if err != nil { + log.Debug("error while upserting OTP: ", err.Error()) + return nil, err + } go func() { - db.Provider.UpsertOTP(ctx, &models.OTP{ - PhoneNumber: mobile, - Otp: smsCode, - ExpiresAt: time.Now().Add(duration).Unix(), - }) smsproviders.SendSMS(mobile, smsBody.String()) }() + return &model.AuthResponse{ + Message: "Please check the OTP in your inbox", + ShouldShowOtpScreen: refs.NewBoolRef(true), + }, nil } roles := strings.Split(user.Roles, ",") diff --git a/server/smsproviders/twilio.go b/server/smsproviders/twilio.go index 093e924..900be6d 100644 --- a/server/smsproviders/twilio.go +++ b/server/smsproviders/twilio.go @@ -1,43 +1,37 @@ package smsproviders import ( - twilio "github.com/twilio/twilio-go" - api "github.com/twilio/twilio-go/rest/api/v2010" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/memorystore" log "github.com/sirupsen/logrus" + twilio "github.com/twilio/twilio-go" + api "github.com/twilio/twilio-go/rest/api/v2010" ) // TODO: Should be restructured to interface when another provider is added func SendSMS(sendTo, messageBody string) error { - twilioAPISecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPISecret) - if err != nil || twilioAPISecret == ""{ - log.Errorf("Failed to get api secret: ", err) + if err != nil || twilioAPISecret == "" { + log.Debug("Failed to get api secret: ", err) return err } - twilioAPIKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPIKey) - if err != nil || twilioAPIKey == ""{ - log.Errorf("Failed to get api key: ", err) + if err != nil || twilioAPIKey == "" { + log.Debug("Failed to get api key: ", err) return err } - twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSenderFrom) if err != nil || twilioSenderFrom == "" { - log.Errorf("Failed to get sender: ", err) + log.Debug("Failed to get sender: ", err) return err } - // accountSID is not a must to send sms on twilio twilioAccountSID, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAccountSID) - client := twilio.NewRestClientWithParams(twilio.ClientParams{ Username: twilioAPIKey, Password: twilioAPISecret, AccountSid: twilioAccountSID, }) - message := &api.CreateMessageParams{} message.SetBody(messageBody) message.SetFrom(twilioSenderFrom) diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go index d81d780..4cc181a 100644 --- a/server/test/mobile_login_test.go +++ b/server/test/mobile_login_test.go @@ -1,10 +1,8 @@ package test import ( - "strings" "testing" - "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/refs" @@ -26,11 +24,6 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotNil(t, signUpRes) - assert.Equal(t, email, signUpRes.User.Email) - assert.Equal(t, phoneNumber, refs.StringValue(signUpRes.User.PhoneNumber)) - assert.True(t, strings.Contains(signUpRes.User.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth)) - assert.Len(t, strings.Split(signUpRes.User.SignupMethods, ","), 1) - res, err := resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, Password: "random_test", @@ -45,7 +38,6 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.Error(t, err) assert.Nil(t, res) - // should fail because phone is not verified res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, @@ -53,26 +45,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "should fail because phone is not verified") assert.Nil(t, res) - smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.NoError(t, err) assert.NotEmpty(t, smsRequest.Otp) - verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ PhoneNumber: &phoneNumber, Otp: smsRequest.Otp, }) assert.Nil(t, err) assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.NotEmpty(t, res.IDToken) - + assert.NotEmpty(t, verifySMSRequest.AccessToken) + assert.NotEmpty(t, verifySMSRequest.IDToken) cleanData(email) }) } diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 11deccc..56e96a8 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -1,9 +1,11 @@ package test import ( + "fmt" "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" @@ -65,16 +67,26 @@ func mobileSingupTest(t *testing.T, s TestSetup) { }) assert.Error(t, err) assert.Nil(t, res) - + phoneNumber := "1234567890" res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ - PhoneNumber: "1234567890", + PhoneNumber: phoneNumber, Password: s.TestInfo.Password, ConfirmPassword: s.TestInfo.Password, }) assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.Equal(t, "1234567890@authorizer.dev", res.User.Email) - + assert.NotNil(t, res) + assert.True(t, *res.ShouldShowOtpScreen) + // Verify with otp + otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) + fmt.Println("=> otp", otp, err) + assert.Nil(t, err) + assert.NotEmpty(t, otp.Otp) + otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ + PhoneNumber: &phoneNumber, + Otp: otp.Otp, + }) + assert.Nil(t, err) + assert.NotEmpty(t, otpRes.Message) res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ PhoneNumber: "1234567890", Password: s.TestInfo.Password, From 5018462559435d8133a6522908735dcb7c6cd005 Mon Sep 17 00:00:00 2001 From: catusax Date: Thu, 20 Jul 2023 15:11:39 +0800 Subject: [PATCH 08/37] feat: add mfa session to secure otp login --- server/constants/cookie.go | 2 + server/cookie/mfa_session.go | 89 +++++++++++++++++++ .../providers/inmemory/provider.go | 18 ++-- .../memorystore/providers/inmemory/store.go | 18 ++++ .../memorystore/providers/provider_tests.go | 11 +++ server/memorystore/providers/providers.go | 4 + server/memorystore/providers/redis/store.go | 30 +++++++ server/resolvers/login.go | 11 ++- server/resolvers/verify_otp.go | 11 +++ 9 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 server/cookie/mfa_session.go diff --git a/server/constants/cookie.go b/server/constants/cookie.go index 71320a9..6dda49d 100644 --- a/server/constants/cookie.go +++ b/server/constants/cookie.go @@ -5,4 +5,6 @@ const ( AppCookieName = "cookie" // AdminCookieName is the name of the cookie that is used to store the admin token AdminCookieName = "authorizer-admin" + + MfaCookieName = "mfa" ) diff --git a/server/cookie/mfa_session.go b/server/cookie/mfa_session.go new file mode 100644 index 0000000..bf691ce --- /dev/null +++ b/server/cookie/mfa_session.go @@ -0,0 +1,89 @@ +package cookie + +import ( + "net/http" + "net/url" + + log "github.com/sirupsen/logrus" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/memorystore" + "github.com/authorizerdev/authorizer/server/parsers" + "github.com/gin-gonic/gin" +) + +// SetSession sets the session cookie in the response +func SetMfaSession(gc *gin.Context, sessionID string) { + appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure) + if err != nil { + log.Debug("Error while getting app cookie secure from env variable: %v", err) + appCookieSecure = true + } + + secure := appCookieSecure + httpOnly := appCookieSecure + hostname := parsers.GetHost(gc) + host, _ := parsers.GetHostParts(hostname) + domain := parsers.GetDomainName(hostname) + if domain != "localhost" { + domain = "." + domain + } + + // Since app cookie can come from cross site it becomes important to set this in lax mode when insecure. + // Example person using custom UI on their app domain and making request to authorizer domain. + // For more information check: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + // https://github.com/gin-gonic/gin/blob/master/context.go#L86 + // TODO add ability to sameSite = none / strict from dashboard + if !appCookieSecure { + gc.SetSameSite(http.SameSiteLaxMode) + } else { + gc.SetSameSite(http.SameSiteNoneMode) + } + // TODO allow configuring from dashboard + age := 60 + + gc.SetCookie(constants.MfaCookieName+"_session", sessionID, age, "/", host, secure, httpOnly) + gc.SetCookie(constants.MfaCookieName+"_session_domain", sessionID, age, "/", domain, secure, httpOnly) +} + +// DeleteSession sets session cookies to expire +func DeleteMfaSession(gc *gin.Context) { + appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure) + if err != nil { + log.Debug("Error while getting app cookie secure from env variable: %v", err) + appCookieSecure = true + } + + secure := appCookieSecure + httpOnly := appCookieSecure + hostname := parsers.GetHost(gc) + host, _ := parsers.GetHostParts(hostname) + domain := parsers.GetDomainName(hostname) + if domain != "localhost" { + domain = "." + domain + } + + gc.SetSameSite(http.SameSiteNoneMode) + gc.SetCookie(constants.MfaCookieName+"_session", "", -1, "/", host, secure, httpOnly) + gc.SetCookie(constants.MfaCookieName+"_session_domain", "", -1, "/", domain, secure, httpOnly) +} + +// GetSession gets the session cookie from context +func GetMfaSession(gc *gin.Context) (string, error) { + var cookie *http.Cookie + var err error + cookie, err = gc.Request.Cookie(constants.MfaCookieName + "_session") + if err != nil { + cookie, err = gc.Request.Cookie(constants.MfaCookieName + "_session_domain") + if err != nil { + return "", err + } + } + + decodedValue, err := url.PathUnescape(cookie.Value) + if err != nil { + return "", err + } + return decodedValue, nil +} diff --git a/server/memorystore/providers/inmemory/provider.go b/server/memorystore/providers/inmemory/provider.go index 952092d..e726502 100644 --- a/server/memorystore/providers/inmemory/provider.go +++ b/server/memorystore/providers/inmemory/provider.go @@ -7,18 +7,20 @@ import ( ) type provider struct { - mutex sync.Mutex - sessionStore *stores.SessionStore - stateStore *stores.StateStore - envStore *stores.EnvStore + mutex sync.Mutex + sessionStore *stores.SessionStore + mfasessionStore *stores.SessionStore + stateStore *stores.StateStore + envStore *stores.EnvStore } // NewInMemoryStore returns a new in-memory store. func NewInMemoryProvider() (*provider, error) { return &provider{ - mutex: sync.Mutex{}, - envStore: stores.NewEnvStore(), - sessionStore: stores.NewSessionStore(), - stateStore: stores.NewStateStore(), + mutex: sync.Mutex{}, + envStore: stores.NewEnvStore(), + sessionStore: stores.NewSessionStore(), + mfasessionStore: stores.NewSessionStore(), + stateStore: stores.NewStateStore(), }, nil } diff --git a/server/memorystore/providers/inmemory/store.go b/server/memorystore/providers/inmemory/store.go index 4a8e8ce..45a7986 100644 --- a/server/memorystore/providers/inmemory/store.go +++ b/server/memorystore/providers/inmemory/store.go @@ -42,6 +42,24 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } +func (c *provider) SetMfaSession(email, key string, expiration int64) error { + c.mfasessionStore.Set(email, key, email, expiration) + return nil +} + +func (c *provider) GetMfaSession(email, key string) (string, error) { + val := c.mfasessionStore.Get(email, key) + if val == "" { + return "", fmt.Errorf("Not found") + } + return val, nil +} + +func (c *provider) DeleteMfaSession(email, key string) error { + c.mfasessionStore.Remove(email, key) + return nil +} + // SetState sets the state in the in-memory store. func (c *provider) SetState(key, state string) error { if os.Getenv("ENV") != constants.TestEnv { diff --git a/server/memorystore/providers/provider_tests.go b/server/memorystore/providers/provider_tests.go index e569fe8..47f4dba 100644 --- a/server/memorystore/providers/provider_tests.go +++ b/server/memorystore/providers/provider_tests.go @@ -112,4 +112,15 @@ func ProviderTests(t *testing.T, p Provider) { key, err = p.GetUserSession("auth_provider1:124", "access_token_key") assert.Empty(t, key) assert.Error(t, err) + + err = p.SetMfaSession("auth_provider:123", "session123", time.Now().Add(60*time.Second).Unix()) + assert.NoError(t, err) + key, err = p.GetMfaSession("auth_provider:123", "session123") + assert.NoError(t, err) + assert.Equal(t, "auth_provider:123", key) + err = p.DeleteMfaSession("auth_provider:123", "session123") + assert.NoError(t, err) + key, err = p.GetMfaSession("auth_provider:123", "session123") + assert.Error(t, err) + assert.Empty(t, key) } diff --git a/server/memorystore/providers/providers.go b/server/memorystore/providers/providers.go index db58aa7..ae1249f 100644 --- a/server/memorystore/providers/providers.go +++ b/server/memorystore/providers/providers.go @@ -13,6 +13,10 @@ type Provider interface { // DeleteSessionForNamespace deletes the session for a given namespace DeleteSessionForNamespace(namespace string) error + SetMfaSession(email, key string, expiration int64) error + GetMfaSession(email, key string) (string, error) + DeleteMfaSession(email, key string) error + // SetState sets the login state (key, value form) in the session store SetState(key, state string) error // GetState returns the state from the session store diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go index 058e95e..d55e741 100644 --- a/server/memorystore/providers/redis/store.go +++ b/server/memorystore/providers/redis/store.go @@ -16,6 +16,8 @@ var ( envStorePrefix = "authorizer_env" ) +const mfaSessionPrefix = "mfa_sess_" + // SetUserSession sets the user session for given user identifier in form recipe:user_id func (c *provider) SetUserSession(userId, key, token string, expiration int64) error { currentTime := time.Now() @@ -91,6 +93,34 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } +func (c *provider) SetMfaSession(email, key string, expiration int64) error { + currentTime := time.Now() + expireTime := time.Unix(expiration, 0) + duration := expireTime.Sub(currentTime) + err := c.store.Set(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key), email, duration).Err() + if err != nil { + log.Debug("Error saving user session to redis: ", err) + return err + } + return nil +} + +func (c *provider) GetMfaSession(email, key string) (string, error) { + data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Result() + if err != nil { + return "", err + } + return data, nil +} + +func (c *provider) DeleteMfaSession(email, key string) error { + if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Err(); err != nil { + log.Debug("Error deleting user session from redis: ", err) + // continue + } + return nil +} + // SetState sets the state in redis store. func (c *provider) SetState(key, value string) error { err := c.store.Set(c.ctx, stateStorePrefix+key, value, 0).Err() diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 28a2289..e05d012 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -113,16 +113,25 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes // If email service is not enabled continue the process in any way if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled { otp := utils.GenerateOTP() + expires := time.Now().Add(1 * time.Minute).Unix() otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{ Email: user.Email, Otp: otp, - ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), + ExpiresAt: expires, }) if err != nil { log.Debug("Failed to add otp: ", err) return nil, err } + mfaSession := uuid.NewString() + err = memorystore.Provider.SetMfaSession(params.Email, mfaSession, expires) + if err != nil { + log.Debug("Failed to add mfasession: ", err) + return nil, err + } + cookie.SetMfaSession(gc, mfaSession) + go func() { // exec it as go routine so that we can reduce the api latency go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{ diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 80080d9..aac55e2 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -28,6 +28,17 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod return res, err } + mfaSession, err := cookie.GetMfaSession(gc) + if err != nil { + log.Debug("Failed to get otp request by email: ", err) + return res, fmt.Errorf(`invalid session: %s`, err.Error()) + } + + if _, err := memorystore.Provider.GetMfaSession(params.Email, mfaSession); err != nil { + log.Debug("Failed to get mfa session: ", err) + return res, fmt.Errorf(`invalid session: %s`, err.Error()) + } + otp, err := db.Provider.GetOTPByEmail(ctx, params.Email) if err != nil { log.Debug("Failed to get otp request by email: ", err) From fac333e1950eeef003eec2fc9e933840ecaf1b29 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 07:29:29 +0530 Subject: [PATCH 09/37] fix: tests for otp refactor --- server/db/models/otp.go | 2 +- server/db/providers/arangodb/provider.go | 6 +----- server/db/providers/cassandradb/provider.go | 8 ++++++++ server/db/providers/dynamodb/otp.go | 2 +- server/db/providers/dynamodb/provider.go | 2 +- server/go.mod | 5 +++-- server/go.sum | 19 +++++++++++++++++++ server/resolvers/mobile_login.go | 2 -- server/resolvers/mobile_signup.go | 2 -- ...{resolvers_test.go => integration_test.go} | 6 +++++- server/test/mobile_signup_test.go | 2 -- server/test/update_webhook_test.go | 6 +++--- server/test/webhook_test.go | 2 +- server/test/webhooks_test.go | 2 +- 14 files changed, 44 insertions(+), 22 deletions(-) rename server/test/{resolvers_test.go => integration_test.go} (93%) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index 8ccb13e..bd0b41c 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -12,7 +12,7 @@ type OTP struct { Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"` Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 2dd7b28..979d56e 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -229,11 +229,7 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } - otpCollection.EnsureHashIndex(ctx, []string{"email"}, &arangoDriver.EnsureHashIndexOptions{ - Unique: true, - Sparse: true, - }) - otpCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + otpCollection.EnsureHashIndex(ctx, []string{models.FieldNameEmail, models.FieldNamePhoneNumber}, &arangoDriver.EnsureHashIndexOptions{ Unique: true, Sparse: true, }) diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go index 1c989be..6f1fe6b 100644 --- a/server/db/providers/cassandradb/provider.go +++ b/server/db/providers/cassandradb/provider.go @@ -254,6 +254,14 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } + // Add phone_number column to otp table + otpAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (phone_number text);`, KeySpace, models.Collections.OTP) + err = session.Query(otpAlterQuery).Exec() + if err != nil { + log.Debug("Failed to alter table as column exists: ", err) + // continue + } + // Add phone number index otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP) err = session.Query(otpIndexQueryPhoneNumber).Exec() if err != nil { diff --git a/server/db/providers/dynamodb/otp.go b/server/db/providers/dynamodb/otp.go index bb55523..d4abf73 100644 --- a/server/db/providers/dynamodb/otp.go +++ b/server/db/providers/dynamodb/otp.go @@ -77,7 +77,7 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) var otps []models.OTP var otp models.OTP collection := p.db.Table(models.Collections.OTP) - err := collection.Scan().Index("phone_number").Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) + err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) if err != nil { return nil, err } diff --git a/server/db/providers/dynamodb/provider.go b/server/db/providers/dynamodb/provider.go index 4bf3345..7935e37 100644 --- a/server/db/providers/dynamodb/provider.go +++ b/server/db/providers/dynamodb/provider.go @@ -31,11 +31,11 @@ func NewProvider() (*provider, error) { if awsRegion != "" { config.Region = aws.String(awsRegion) } - // custom awsAccessKeyID, awsSecretAccessKey took first priority, if not then fetch config from aws credentials if awsAccessKeyID != "" && awsSecretAccessKey != "" { config.Credentials = credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, "") } else if dbURL != "" { + log.Debug("Tring to use database url for dynamodb") // static config in case of testing or local-setup config.Credentials = credentials.NewStaticCredentials("key", "key", "") config.Endpoint = aws.String(dbURL) diff --git a/server/go.mod b/server/go.mod index 3408404..62a3227 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/99designs/gqlgen v0.17.20 github.com/arangodb/go-driver v1.2.1 - github.com/aws/aws-sdk-go v1.44.109 + github.com/aws/aws-sdk-go v1.44.298 github.com/coreos/go-oidc/v3 v3.1.0 github.com/couchbase/gocb/v2 v2.6.0 github.com/gin-gonic/gin v1.8.1 @@ -13,11 +13,12 @@ require ( github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/goccy/go-json v0.9.11 // indirect github.com/gocql/gocql v1.2.0 + github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.6 // indirect github.com/google/uuid v1.3.0 - github.com/guregu/dynamo v1.16.0 + github.com/guregu/dynamo v1.20.0 github.com/joho/godotenv v1.3.0 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect diff --git a/server/go.sum b/server/go.sum index 224e06d..e8387ab 100644 --- a/server/go.sum +++ b/server/go.sum @@ -54,6 +54,8 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdK github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= +github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= @@ -65,6 +67,8 @@ github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -208,6 +212,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c= github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= +github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= +github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -442,8 +448,11 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -464,6 +473,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -508,12 +519,17 @@ golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -523,8 +539,11 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 8368745..bfef56c 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -100,8 +100,6 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } - fmt.Println("=> disablePhoneVerification", disablePhoneVerification) - if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 610b238..5cf1029 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -92,7 +92,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) if err != nil { log.Debug("Failed to get user by email: ", err) } - if existingUser != nil { if existingUser.PhoneNumberVerifiedAt != nil { // email is verified @@ -196,7 +195,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - fmt.Println("=> disablePhoneVerification signup", disablePhoneVerification) if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/test/resolvers_test.go b/server/test/integration_test.go similarity index 93% rename from server/test/resolvers_test.go rename to server/test/integration_test.go index ecda491..9c9dfa2 100644 --- a/server/test/resolvers_test.go +++ b/server/test/integration_test.go @@ -46,7 +46,6 @@ func TestResolvers(t *testing.T) { for dbType, dbURL := range databases { ctx := context.Background() - memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseType, dbType) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseName, testDb) @@ -57,6 +56,11 @@ func TestResolvers(t *testing.T) { if dbType == constants.DbTypeDynamoDB { memorystore.Provider.UpdateEnvVariable(constants.EnvAwsRegion, "ap-south-1") os.Setenv(constants.EnvAwsRegion, "ap-south-1") + os.Unsetenv(constants.EnvAwsAccessKeyID) + os.Unsetenv(constants.EnvAwsSecretAccessKey) + // Remove aws credentials from env, so that local dynamodb can be used + memorystore.Provider.UpdateEnvVariable(constants.EnvAwsAccessKeyID, "") + memorystore.Provider.UpdateEnvVariable(constants.EnvAwsSecretAccessKey, "") } if dbType == constants.DbTypeCouchbaseDB { memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseUsername, "Administrator") diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 56e96a8..8169d9e 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -1,7 +1,6 @@ package test import ( - "fmt" "testing" "github.com/authorizerdev/authorizer/server/constants" @@ -78,7 +77,6 @@ func mobileSingupTest(t *testing.T, s TestSetup) { assert.True(t, *res.ShouldShowOtpScreen) // Verify with otp otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) - fmt.Println("=> otp", otp, err) assert.Nil(t, err) assert.NotEmpty(t, otp.Otp) otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ diff --git a/server/test/update_webhook_test.go b/server/test/update_webhook_test.go index 14ccb94..6e2d023 100644 --- a/server/test/update_webhook_test.go +++ b/server/test/update_webhook_test.go @@ -27,7 +27,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, webhooks) - assert.Equal(t, 2, len(webhooks)) + assert.GreaterOrEqual(t, len(webhooks), 2) for _, webhook := range webhooks { // it should completely replace headers webhook.Headers = map[string]interface{}{ @@ -58,7 +58,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { // Check if webhooks with new name is as per expected len accessWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserAccessEnabledWebhookEvent) assert.NoError(t, err) - assert.Equal(t, 3, len(accessWebhooks)) + assert.GreaterOrEqual(t, len(accessWebhooks), 3) // Revert name change res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{ ID: w.ID, @@ -69,7 +69,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { updatedWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, updatedWebhooks) - assert.Equal(t, 2, len(updatedWebhooks)) + assert.GreaterOrEqual(t, len(updatedWebhooks), 2) for _, updatedWebhook := range updatedWebhooks { assert.Contains(t, refs.StringValue(updatedWebhook.EventName), constants.UserDeletedWebhookEvent) assert.Len(t, updatedWebhook.Headers, 1) diff --git a/server/test/webhook_test.go b/server/test/webhook_test.go index 0fb789f..a556f9d 100644 --- a/server/test/webhook_test.go +++ b/server/test/webhook_test.go @@ -28,7 +28,7 @@ func webhookTest(t *testing.T, s TestSetup) { webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, webhooks) - assert.Equal(t, 2, len(webhooks)) + assert.GreaterOrEqual(t, len(webhooks), 2) for _, webhook := range webhooks { res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{ ID: webhook.ID, diff --git a/server/test/webhooks_test.go b/server/test/webhooks_test.go index 6ed1bb2..74cad74 100644 --- a/server/test/webhooks_test.go +++ b/server/test/webhooks_test.go @@ -30,6 +30,6 @@ func webhooksTest(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotEmpty(t, webhooks) - assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes)*2) + assert.GreaterOrEqual(t, len(webhooks.Webhooks), len(s.TestInfo.TestWebhookEventTypes)*2) }) } From 55fc4b2608ecf32adf745af2bbd70de9f01b319c Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 10:03:37 +0530 Subject: [PATCH 10/37] Update resend otp --- .env.test | 4 + server/constants/env.go | 13 ++-- server/env/env.go | 49 ++++++++---- server/env/persist_env.go | 2 +- server/go.mod | 1 - server/go.sum | 15 ---- server/graph/generated/generated.go | 15 +++- server/graph/model/models_gen.go | 5 +- server/graph/schema.graphqls | 3 +- server/memorystore/memory_store.go | 1 + server/memorystore/providers/redis/store.go | 2 +- server/resolvers/login.go | 2 +- server/resolvers/mobile_login.go | 71 +++++------------- server/resolvers/mobile_signup.go | 6 +- server/resolvers/resend_otp.go | 83 ++++++++++++++------- server/resolvers/update_env.go | 7 ++ server/smsproviders/twilio.go | 3 +- server/test/resend_otp_test.go | 4 +- server/test/test.go | 4 + server/utils/webhook.go | 2 + 20 files changed, 162 insertions(+), 130 deletions(-) diff --git a/.env.test b/.env.test index 99c8081..293248a 100644 --- a/.env.test +++ b/.env.test @@ -7,5 +7,9 @@ SMTP_PORT=2525 SMTP_USERNAME=test SMTP_PASSWORD=test SENDER_EMAIL="info@authorizer.dev" +TWILIO_API_KEY=test +TWILIO_API_SECRET=test +TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +TWILIO_SENDER=909921212112 SENDER_NAME="Authorizer" AWS_REGION=ap-south-1 \ No newline at end of file diff --git a/server/constants/env.go b/server/constants/env.go index 0f26ede..74b9d36 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -66,6 +66,8 @@ const ( EnvKeySenderName = "SENDER_NAME" // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED" + // EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED + EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED" // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE EnvKeyAppCookieSecure = "APP_COOKIE_SECURE" // EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE @@ -158,6 +160,9 @@ const ( // EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION // this variable is used to completely disable multi factor authentication. It will have no effect on profile preference EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION" + // EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION + // this variable is used to disable phone verification + EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" // Slice variables // EnvKeyRoles key for env variable ROLES @@ -177,17 +182,13 @@ const ( // This env is used for setting default response mode in authorize handler EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE" - // Phone verification setting - EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" - // Twilio env variables - // EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY EnvKeyTwilioAPIKey = "TWILIO_API_KEY" // EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET EnvKeyTwilioAPISecret = "TWILIO_API_SECRET" // EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID" - // EnvKeyTwilioSenderFrom key for env variable TWILIO_SENDER_FROM - EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM" + // EnvKeyTwilioSender key for env variable TWILIO_SENDER + EnvKeyTwilioSender = "TWILIO_SENDER" ) diff --git a/server/env/env.go b/server/env/env.go index f61b093..8525927 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -104,6 +104,13 @@ func InitAllEnv() error { osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword) osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication) osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication) + // phone verification var + osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification) + // twilio vars + osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey) + osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret) + osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID) + osTwilioSender := os.Getenv(constants.EnvKeyTwilioSender) // os slice vars osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins) @@ -111,15 +118,6 @@ func InitAllEnv() error { osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles) osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles) - // phone verification var - osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification) - - // twilio vars - osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey) - osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret) - osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID) - osTwilioSenderFrom := os.Getenv(constants.EnvKeyTwilioSenderFrom) - ienv, ok := envData[constants.EnvKeyEnv] if !ok || ienv == "" { envData[constants.EnvKeyEnv] = osEnv @@ -145,7 +143,7 @@ func InitAllEnv() error { if val, ok := envData[constants.EnvAwsRegion]; !ok || val == "" { envData[constants.EnvAwsRegion] = osAwsRegion } - + if osAwsRegion != "" && envData[constants.EnvAwsRegion] != osAwsRegion { envData[constants.EnvAwsRegion] = osAwsRegion } @@ -691,11 +689,11 @@ func InitAllEnv() error { envData[constants.EnvKeyIsEmailServiceEnabled] = false } - if envData[constants.EnvKeySmtpHost] != "" || envData[constants.EnvKeySmtpUsername] != "" || envData[constants.EnvKeySmtpPassword] != "" || envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" { + if envData[constants.EnvKeySmtpHost] != "" && envData[constants.EnvKeySmtpUsername] != "" && envData[constants.EnvKeySmtpPassword] != "" && envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" { envData[constants.EnvKeyIsEmailServiceEnabled] = true } - if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) { + if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) && !envData[constants.EnvKeyIsSMSServiceEnabled].(bool) { return errors.New("to enable multi factor authentication, please enable email service") } @@ -777,29 +775,39 @@ func InitAllEnv() error { envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode } + if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" { + envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret + } if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret { envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret } + if val, ok := envData[constants.EnvKeyTwilioAPIKey]; !ok || val == "" { + envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey + } if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey { envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey } + if val, ok := envData[constants.EnvKeyTwilioAccountSID]; !ok || val == "" { + envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid + } if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid { envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid } - if osTwilioSenderFrom != "" && envData[constants.EnvKeyTwilioSenderFrom] != osTwilioSenderFrom { - envData[constants.EnvKeyTwilioSenderFrom] = osTwilioSenderFrom + if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" { + envData[constants.EnvKeyTwilioSender] = osTwilioSender + } + if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender { + envData[constants.EnvKeyTwilioSender] = osTwilioSender } if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok { envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false" } - if osDisablePhoneVerification != "" { boolValue, err := strconv.ParseBool(osDisablePhoneVerification) - if err != nil { return err } @@ -808,6 +816,15 @@ func InitAllEnv() error { } } + if envData[constants.EnvKeyTwilioAPIKey] == "" || envData[constants.EnvKeyTwilioAPISecret] == "" || envData[constants.EnvKeyTwilioAccountSID] == "" || envData[constants.EnvKeyTwilioSender] == "" { + envData[constants.EnvKeyDisablePhoneVerification] = true + envData[constants.EnvKeyIsSMSServiceEnabled] = false + } + if envData[constants.EnvKeyTwilioAPIKey] != "" && envData[constants.EnvKeyTwilioAPISecret] != "" && envData[constants.EnvKeyTwilioAccountSID] != "" && envData[constants.EnvKeyTwilioSender] != "" { + envData[constants.EnvKeyDisablePhoneVerification] = false + envData[constants.EnvKeyIsSMSServiceEnabled] = true + } + err = memorystore.Provider.UpdateEnvStore(envData) if err != nil { log.Debug("Error while updating env store: ", err) diff --git a/server/env/persist_env.go b/server/env/persist_env.go index 8ba33f2..719c91d 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -200,7 +200,7 @@ func PersistEnv() error { envValue := strings.TrimSpace(os.Getenv(key)) if envValue != "" { switch key { - case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification: + case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification: if envValueBool, err := strconv.ParseBool(envValue); err == nil { if value.(bool) != envValueBool { storeData[key] = envValueBool diff --git a/server/go.mod b/server/go.mod index 62a3227..0d50507 100644 --- a/server/go.mod +++ b/server/go.mod @@ -13,7 +13,6 @@ require ( github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/goccy/go-json v0.9.11 // indirect github.com/gocql/gocql v1.2.0 - github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.6 // indirect diff --git a/server/go.sum b/server/go.sum index e8387ab..4a2c928 100644 --- a/server/go.sum +++ b/server/go.sum @@ -51,9 +51,6 @@ github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2 github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= -github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= -github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= @@ -65,8 +62,6 @@ github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -134,8 +129,6 @@ github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE= github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= -github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= @@ -210,8 +203,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c= -github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= @@ -444,12 +435,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -471,7 +459,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -520,7 +507,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -540,7 +526,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index b2493ef..3b46684 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -2719,7 +2719,8 @@ input VerifyOTPRequest { } input ResendOTPRequest { - email: String! + email: String + phone_number: String # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token @@ -16375,7 +16376,7 @@ func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"email", "state"} + fieldsInOrder := [...]string{"email", "phone_number", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -16386,7 +16387,15 @@ func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email")) - it.Email, err = ec.unmarshalNString2string(ctx, v) + it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "phone_number": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) + it.PhoneNumber, err = ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 7621995..8bd0edc 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -245,8 +245,9 @@ type PaginationInput struct { } type ResendOTPRequest struct { - Email string `json:"email"` - State *string `json:"state"` + Email *string `json:"email"` + PhoneNumber *string `json:"phone_number"` + State *string `json:"state"` } type ResendVerifyEmailInput struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index bb83b9b..106d561 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -549,7 +549,8 @@ input VerifyOTPRequest { } input ResendOTPRequest { - email: String! + email: String + phone_number: String # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login # and use that code for setting `c_hash` in id_token diff --git a/server/memorystore/memory_store.go b/server/memorystore/memory_store.go index 4285860..2b3c9b2 100644 --- a/server/memorystore/memory_store.go +++ b/server/memorystore/memory_store.go @@ -33,6 +33,7 @@ func InitMemStore() error { constants.EnvKeyDisableSignUp: false, constants.EnvKeyDisableStrongPassword: false, constants.EnvKeyIsEmailServiceEnabled: false, + constants.EnvKeyIsSMSServiceEnabled: false, constants.EnvKeyEnforceMultiFactorAuthentication: false, constants.EnvKeyDisableMultiFactorAuthentication: false, constants.EnvKeyAppCookieSecure: true, diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go index 058e95e..ad44b26 100644 --- a/server/memorystore/providers/redis/store.go +++ b/server/memorystore/providers/redis/store.go @@ -143,7 +143,7 @@ func (c *provider) GetEnvStore() (map[string]interface{}, error) { return nil, err } for key, value := range data { - if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure { + if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyIsSMSServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure { boolValue, err := strconv.ParseBool(value) if err != nil { return res, err diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 28a2289..fde5600 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -106,7 +106,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes } isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) - if err != nil || !isEmailServiceEnabled { + if err != nil || !isMFADisabled { log.Debug("MFA service not enabled: ", err) } diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index bfef56c..749b00f 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -95,24 +95,33 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m roles = params.Roles } - disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + disablePhoneVerification, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + if err != nil { + log.Debug("Error getting disable phone verification: ", err) + } if disablePhoneVerification { now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } - if !disablePhoneVerification { + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("SMS service not enabled: ", err) + } + if disablePhoneVerification { + now := time.Now().Unix() + user.PhoneNumberVerifiedAt = &now + } + isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) + if err != nil || !isMFADisabled { + log.Debug("MFA service not enabled: ", err) + } + if !disablePhoneVerification && isSMSServiceEnabled && !isMFADisabled { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() smsBody := strings.Builder{} smsBody.WriteString("Your verification code is: ") smsBody.WriteString(smsCode) - - // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api - if err != nil { - log.Debug("error while upserting user: ", err.Error()) - return nil, err - } _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ PhoneNumber: params.PhoneNumber, Otp: smsCode, @@ -123,7 +132,7 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m return nil, err } go func() { - + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, *user) smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) }() return &model.AuthResponse{ @@ -137,50 +146,6 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m scope = params.Scope } - /* - // TODO use sms authentication for MFA - isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) - if err != nil || !isEmailServiceEnabled { - log.Debug("Email service not enabled: ", err) - } - - isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) - if err != nil || !isEmailServiceEnabled { - log.Debug("MFA service not enabled: ", err) - } - - // If email service is not enabled continue the process in any way - if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled { - otp := utils.GenerateOTP() - otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{ - Email: user.Email, - Otp: otp, - ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), - }) - if err != nil { - log.Debug("Failed to add otp: ", err) - return nil, err - } - - go func() { - // exec it as go routine so that we can reduce the api latency - go email.SendEmail([]string{params.PhoneNumber}, constants.VerificationTypeOTP, map[string]interface{}{ - "user": user.ToMap(), - "organization": utils.GetOrganization(), - "otp": otpData.Otp, - }) - if err != nil { - log.Debug("Failed to send otp email: ", err) - } - }() - - return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), - }, nil - } - */ - code := "" codeChallenge := "" nonce := "" diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 5cf1029..a00c440 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -187,6 +187,10 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("SMS service not enabled: ", err) + } user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth user, err = db.Provider.AddUser(ctx, user) @@ -195,7 +199,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - if !disablePhoneVerification { + if !disablePhoneVerification && isSMSServiceEnabled { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/resolvers/resend_otp.go b/server/resolvers/resend_otp.go index 65d9cf1..dafe9dd 100644 --- a/server/resolvers/resend_otp.go +++ b/server/resolvers/resend_otp.go @@ -12,23 +12,49 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" - "github.com/authorizerdev/authorizer/server/email" + emailHelper "github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/utils" ) // ResendOTPResolver is a resolver for resend otp mutation func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) { + email := strings.ToLower(strings.Trim(refs.StringValue(params.Email), " ")) + phoneNumber := strings.Trim(refs.StringValue(params.PhoneNumber), " ") log := log.WithFields(log.Fields{ - "email": params.Email, + "email": email, + "phone_number": phoneNumber, }) - params.Email = strings.ToLower(params.Email) - user, err := db.Provider.GetUserByEmail(ctx, params.Email) + if email == "" && phoneNumber == "" { + log.Debug("Email or phone number is required") + return nil, errors.New("email or phone number is required") + } + var user models.User + var err error + if email != "" { + isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) + if err != nil || !isEmailServiceEnabled { + log.Debug("Email service not enabled: ", err) + return nil, errors.New("email service not enabled") + } + user, err = db.Provider.GetUserByEmail(ctx, email) + } else { + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("Email service not enabled: ", err) + return nil, errors.New("email service not enabled") + } + // TODO fix after refs fixes + var u *models.User + u, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) + user = *u + } if err != nil { log.Debug("Failed to get user by email: ", err) - return nil, fmt.Errorf(`user with this email not found`) + return nil, fmt.Errorf(`user with this email/phone not found`) } if user.RevokedTimestamp != nil { @@ -36,35 +62,38 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod return nil, fmt.Errorf(`user access has been revoked`) } - if user.EmailVerifiedAt == nil { + if email != "" && user.EmailVerifiedAt == nil { log.Debug("User email is not verified") return nil, fmt.Errorf(`email not verified`) } + if phoneNumber != "" && user.PhoneNumberVerifiedAt == nil { + log.Debug("User phone number is not verified") + return nil, fmt.Errorf(`phone number not verified`) + } + if !refs.BoolValue(user.IsMultiFactorAuthEnabled) { log.Debug("User multi factor authentication is not enabled") return nil, fmt.Errorf(`multi factor authentication not enabled`) } - isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) - if err != nil || !isEmailServiceEnabled { - log.Debug("Email service not enabled: ", err) - return nil, errors.New("email service not enabled") - } - isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) if err != nil || isMFADisabled { log.Debug("MFA service not enabled: ", err) return nil, errors.New("multi factor authentication is disabled for this instance") } - // get otp by email - otpData, err := db.Provider.GetOTPByEmail(ctx, params.Email) + // get otp by email or phone number + var otpData *models.OTP + if email != "" { + otpData, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email)) + } else { + otpData, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + } if err != nil { log.Debug("Failed to get otp for given email: ", err) return nil, err } - if otpData == nil { log.Debug("No otp found for given email: ", params.Email) return &model.Response{ @@ -73,28 +102,30 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod } otp := utils.GenerateOTP() - otpData, err = db.Provider.UpsertOTP(ctx, &models.OTP{ + if _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ Email: user.Email, Otp: otp, ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), - }) - if err != nil { - log.Debug("Error generating new otp: ", err) + }); err != nil { + log.Debug("Error upserting otp: ", err) return nil, err } - go func() { + if email != "" { // exec it as go routine so that we can reduce the api latency - go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{ + go emailHelper.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), "otp": otp, }) - if err != nil { - log.Debug("Error sending otp email: ", otp) - } - }() - + } else { + smsBody := strings.Builder{} + smsBody.WriteString("Your verification code is: ") + smsBody.WriteString(otp) + // exec it as go routine so that we can reduce the api latency + go smsproviders.SendSMS(phoneNumber, smsBody.String()) + } + log.Info("OTP has been resent") return &model.Response{ Message: `OTP has been sent. Please check your inbox`, }, nil diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index d9d6881..437565e 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -267,6 +267,13 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model updatedData[constants.EnvKeyIsEmailServiceEnabled] = true } + if updatedData[constants.EnvKeyTwilioAPIKey] == "" || updatedData[constants.EnvKeyTwilioAPISecret] == "" || updatedData[constants.EnvKeyTwilioAccountSID] == "" || updatedData[constants.EnvKeyTwilioSender] == "" { + updatedData[constants.EnvKeyIsSMSServiceEnabled] = false + if !updatedData[constants.EnvKeyIsSMSServiceEnabled].(bool) { + updatedData[constants.EnvKeyDisablePhoneVerification] = true + } + } + if !currentData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) { go db.Provider.UpdateUsers(ctx, map[string]interface{}{ "is_multi_factor_auth_enabled": true, diff --git a/server/smsproviders/twilio.go b/server/smsproviders/twilio.go index 900be6d..f4f1acb 100644 --- a/server/smsproviders/twilio.go +++ b/server/smsproviders/twilio.go @@ -8,6 +8,7 @@ import ( api "github.com/twilio/twilio-go/rest/api/v2010" ) +// SendSMS util to send sms // TODO: Should be restructured to interface when another provider is added func SendSMS(sendTo, messageBody string) error { twilioAPISecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPISecret) @@ -20,7 +21,7 @@ func SendSMS(sendTo, messageBody string) error { log.Debug("Failed to get api key: ", err) return err } - twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSenderFrom) + twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSender) if err != nil || twilioSenderFrom == "" { log.Debug("Failed to get sender: ", err) return err diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go index eb6993f..1550957 100644 --- a/server/test/resend_otp_test.go +++ b/server/test/resend_otp_test.go @@ -51,7 +51,7 @@ func resendOTPTest(t *testing.T, s TestSetup) { assert.NotNil(t, updateRes) // Resend otp should return error as no initial opt is being sent resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{ - Email: email, + Email: refs.NewStringRef(email), }) assert.Error(t, err) assert.Nil(t, resendOtpRes) @@ -72,7 +72,7 @@ func resendOTPTest(t *testing.T, s TestSetup) { // resend otp resendOtpRes, err = resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{ - Email: email, + Email: refs.NewStringRef(email), }) assert.NoError(t, err) assert.NotEmpty(t, resendOtpRes.Message) diff --git a/server/test/test.go b/server/test/test.go index b2727ea..217ad39 100644 --- a/server/test/test.go +++ b/server/test/test.go @@ -126,6 +126,10 @@ func testSetup() TestSetup { memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpPassword, "test") memorystore.Provider.UpdateEnvVariable(constants.EnvKeySenderEmail, "info@yopmail.com") memorystore.Provider.UpdateEnvVariable(constants.EnvKeyProtectedRoles, "admin") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPIKey, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPISecret, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAccountSID, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioSender, "1234567890") err = db.InitDB() if err != nil { diff --git a/server/utils/webhook.go b/server/utils/webhook.go index 705c571..4c6fbd0 100644 --- a/server/utils/webhook.go +++ b/server/utils/webhook.go @@ -16,6 +16,8 @@ import ( log "github.com/sirupsen/logrus" ) +// RegisterEvent util to register event +// TODO change user to user ref func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error { webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName) if err != nil { From e7652db89cf8d524a29df482979a1247db347e4f Mon Sep 17 00:00:00 2001 From: catusax <11882183+catusax@users.noreply.github.com> Date: Sun, 23 Jul 2023 13:02:14 +0800 Subject: [PATCH 11/37] add comments --- server/constants/cookie.go | 2 +- server/cookie/mfa_session.go | 6 +++--- server/memorystore/providers/inmemory/store.go | 3 +++ server/memorystore/providers/providers.go | 4 +++- server/memorystore/providers/redis/store.go | 3 +++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/server/constants/cookie.go b/server/constants/cookie.go index 6dda49d..8f6399b 100644 --- a/server/constants/cookie.go +++ b/server/constants/cookie.go @@ -5,6 +5,6 @@ const ( AppCookieName = "cookie" // AdminCookieName is the name of the cookie that is used to store the admin token AdminCookieName = "authorizer-admin" - + // MfaCookieName is the name of the cookie that is used to store the mfa session MfaCookieName = "mfa" ) diff --git a/server/cookie/mfa_session.go b/server/cookie/mfa_session.go index bf691ce..3fdcaac 100644 --- a/server/cookie/mfa_session.go +++ b/server/cookie/mfa_session.go @@ -12,7 +12,7 @@ import ( "github.com/gin-gonic/gin" ) -// SetSession sets the session cookie in the response +// SetMfaSession sets the mfa session cookie in the response func SetMfaSession(gc *gin.Context, sessionID string) { appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure) if err != nil { @@ -47,7 +47,7 @@ func SetMfaSession(gc *gin.Context, sessionID string) { gc.SetCookie(constants.MfaCookieName+"_session_domain", sessionID, age, "/", domain, secure, httpOnly) } -// DeleteSession sets session cookies to expire +// DeleteMfaSession deletes the mfa session cookies to expire func DeleteMfaSession(gc *gin.Context) { appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure) if err != nil { @@ -69,7 +69,7 @@ func DeleteMfaSession(gc *gin.Context) { gc.SetCookie(constants.MfaCookieName+"_session_domain", "", -1, "/", domain, secure, httpOnly) } -// GetSession gets the session cookie from context +// GetMfaSession gets the mfa session cookie from context func GetMfaSession(gc *gin.Context) (string, error) { var cookie *http.Cookie var err error diff --git a/server/memorystore/providers/inmemory/store.go b/server/memorystore/providers/inmemory/store.go index 45a7986..d03a9df 100644 --- a/server/memorystore/providers/inmemory/store.go +++ b/server/memorystore/providers/inmemory/store.go @@ -42,11 +42,13 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } +// SetMfaSession sets the mfa session with key and value of email func (c *provider) SetMfaSession(email, key string, expiration int64) error { c.mfasessionStore.Set(email, key, email, expiration) return nil } +// GetMfaSession returns value of given mfa session func (c *provider) GetMfaSession(email, key string) (string, error) { val := c.mfasessionStore.Get(email, key) if val == "" { @@ -55,6 +57,7 @@ func (c *provider) GetMfaSession(email, key string) (string, error) { return val, nil } +// DeleteMfaSession deletes given mfa session from in-memory store. func (c *provider) DeleteMfaSession(email, key string) error { c.mfasessionStore.Remove(email, key) return nil diff --git a/server/memorystore/providers/providers.go b/server/memorystore/providers/providers.go index ae1249f..6b3eba0 100644 --- a/server/memorystore/providers/providers.go +++ b/server/memorystore/providers/providers.go @@ -12,9 +12,11 @@ type Provider interface { DeleteAllUserSessions(userId string) error // DeleteSessionForNamespace deletes the session for a given namespace DeleteSessionForNamespace(namespace string) error - + // SetMfaSession sets the mfa session with key and value of email SetMfaSession(email, key string, expiration int64) error + // GetMfaSession returns value of given mfa session GetMfaSession(email, key string) (string, error) + // DeleteMfaSession deletes given mfa session from in-memory store. DeleteMfaSession(email, key string) error // SetState sets the login state (key, value form) in the session store diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go index d55e741..63e3e37 100644 --- a/server/memorystore/providers/redis/store.go +++ b/server/memorystore/providers/redis/store.go @@ -93,6 +93,7 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } +// SetMfaSession sets the mfa session with key and value of email func (c *provider) SetMfaSession(email, key string, expiration int64) error { currentTime := time.Now() expireTime := time.Unix(expiration, 0) @@ -105,6 +106,7 @@ func (c *provider) SetMfaSession(email, key string, expiration int64) error { return nil } + // GetMfaSession returns value of given mfa session func (c *provider) GetMfaSession(email, key string) (string, error) { data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Result() if err != nil { @@ -113,6 +115,7 @@ func (c *provider) GetMfaSession(email, key string) (string, error) { return data, nil } +// DeleteMfaSession deletes given mfa session from in-memory store. func (c *provider) DeleteMfaSession(email, key string) error { if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Err(); err != nil { log.Debug("Error deleting user session from redis: ", err) From 43fdc826c483aa31bd60d38ada85ce75418fb93e Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 11:23:24 +0530 Subject: [PATCH 12/37] Add optional show_mobile_otp_screen --- server/graph/generated/generated.go | 130 +++++++++++++++++++++------- server/graph/model/models_gen.go | 15 ++-- server/graph/schema.graphqls | 3 +- server/resolvers/login.go | 4 +- server/resolvers/mobile_login.go | 4 +- server/resolvers/mobile_signup.go | 4 +- server/test/mobile_signup_test.go | 2 +- 7 files changed, 116 insertions(+), 46 deletions(-) diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 3b46684..887207c 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -45,13 +45,14 @@ type DirectiveRoot struct { type ComplexityRoot struct { AuthResponse struct { - AccessToken func(childComplexity int) int - ExpiresIn func(childComplexity int) int - IDToken func(childComplexity int) int - Message func(childComplexity int) int - RefreshToken func(childComplexity int) int - ShouldShowOtpScreen func(childComplexity int) int - User func(childComplexity int) int + AccessToken func(childComplexity int) int + ExpiresIn func(childComplexity int) int + IDToken func(childComplexity int) int + Message func(childComplexity int) int + RefreshToken func(childComplexity int) int + ShouldShowEmailOtpScreen func(childComplexity int) int + ShouldShowMobileOtpScreen func(childComplexity int) int + User func(childComplexity int) int } EmailTemplate struct { @@ -428,12 +429,19 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.AuthResponse.RefreshToken(childComplexity), true - case "AuthResponse.should_show_otp_screen": - if e.complexity.AuthResponse.ShouldShowOtpScreen == nil { + case "AuthResponse.should_show_email_otp_screen": + if e.complexity.AuthResponse.ShouldShowEmailOtpScreen == nil { break } - return e.complexity.AuthResponse.ShouldShowOtpScreen(childComplexity), true + return e.complexity.AuthResponse.ShouldShowEmailOtpScreen(childComplexity), true + + case "AuthResponse.should_show_mobile_otp_screen": + if e.complexity.AuthResponse.ShouldShowMobileOtpScreen == nil { + break + } + + return e.complexity.AuthResponse.ShouldShowMobileOtpScreen(childComplexity), true case "AuthResponse.user": if e.complexity.AuthResponse.User == nil { @@ -2261,7 +2269,8 @@ type Error { type AuthResponse { message: String! - should_show_otp_screen: Boolean + should_show_email_otp_screen: Boolean + should_show_mobile_otp_screen: Boolean access_token: String id_token: String refresh_token: String @@ -3474,8 +3483,8 @@ func (ec *executionContext) fieldContext_AuthResponse_message(ctx context.Contex return fc, nil } -func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) +func (ec *executionContext) _AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) if err != nil { return graphql.Null } @@ -3488,7 +3497,7 @@ func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Con }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ShouldShowOtpScreen, nil + return obj.ShouldShowEmailOtpScreen, nil }) if err != nil { ec.Error(ctx, err) @@ -3502,7 +3511,48 @@ func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Con return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AuthResponse_should_show_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuthResponse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ShouldShowMobileOtpScreen, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AuthResponse", Field: field, @@ -7756,8 +7806,10 @@ func (ec *executionContext) fieldContext_Mutation_signup(ctx context.Context, fi switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7827,8 +7879,10 @@ func (ec *executionContext) fieldContext_Mutation_mobile_signup(ctx context.Cont switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7898,8 +7952,10 @@ func (ec *executionContext) fieldContext_Mutation_login(ctx context.Context, fie switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7969,8 +8025,10 @@ func (ec *executionContext) fieldContext_Mutation_mobile_login(ctx context.Conte switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -8206,8 +8264,10 @@ func (ec *executionContext) fieldContext_Mutation_verify_email(ctx context.Conte switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -8513,8 +8573,10 @@ func (ec *executionContext) fieldContext_Mutation_verify_otp(ctx context.Context switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -9931,8 +9993,10 @@ func (ec *executionContext) fieldContext_Query_session(ctx context.Context, fiel switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -17790,9 +17854,13 @@ func (ec *executionContext) _AuthResponse(ctx context.Context, sel ast.Selection if out.Values[i] == graphql.Null { invalids++ } - case "should_show_otp_screen": + case "should_show_email_otp_screen": - out.Values[i] = ec._AuthResponse_should_show_otp_screen(ctx, field, obj) + out.Values[i] = ec._AuthResponse_should_show_email_otp_screen(ctx, field, obj) + + case "should_show_mobile_otp_screen": + + out.Values[i] = ec._AuthResponse_should_show_mobile_otp_screen(ctx, field, obj) case "access_token": diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 8bd0edc..d6139c9 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -26,13 +26,14 @@ type AdminSignupInput struct { } type AuthResponse struct { - Message string `json:"message"` - ShouldShowOtpScreen *bool `json:"should_show_otp_screen"` - AccessToken *string `json:"access_token"` - IDToken *string `json:"id_token"` - RefreshToken *string `json:"refresh_token"` - ExpiresIn *int64 `json:"expires_in"` - User *User `json:"user"` + Message string `json:"message"` + ShouldShowEmailOtpScreen *bool `json:"should_show_email_otp_screen"` + ShouldShowMobileOtpScreen *bool `json:"should_show_mobile_otp_screen"` + AccessToken *string `json:"access_token"` + IDToken *string `json:"id_token"` + RefreshToken *string `json:"refresh_token"` + ExpiresIn *int64 `json:"expires_in"` + User *User `json:"user"` } type DeleteEmailTemplateRequest struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 106d561..7ceef43 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -91,7 +91,8 @@ type Error { type AuthResponse { message: String! - should_show_otp_screen: Boolean + should_show_email_otp_screen: Boolean + should_show_mobile_otp_screen: Boolean access_token: String id_token: String refresh_token: String diff --git a/server/resolvers/login.go b/server/resolvers/login.go index fde5600..93d3377 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -136,8 +136,8 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes }() return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP in your inbox", + ShouldShowEmailOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 749b00f..fc131b0 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -136,8 +136,8 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) }() return &model.AuthResponse{ - Message: "Please check the OTP", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP", + ShouldShowMobileOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index a00c440..70b6d60 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -225,8 +225,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) smsproviders.SendSMS(mobile, smsBody.String()) }() return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP in your inbox", + ShouldShowMobileOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 8169d9e..c93472f 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -74,7 +74,7 @@ func mobileSingupTest(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotNil(t, res) - assert.True(t, *res.ShouldShowOtpScreen) + assert.True(t, *res.ShouldShowMobileOtpScreen) // Verify with otp otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.Nil(t, err) From 1796cace155367137e9ce9f30c871c61a265a487 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 11:30:43 +0530 Subject: [PATCH 13/37] [app] bump authorizer-react 1.1.12 --- app/package-lock.json | 58 +++++++++++++++++++++---------------------- app/package.json | 2 +- app/yarn.lock | 34 ++++++++++++------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index cf332cb..efba452 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.11", + "@authorizerdev/authorizer-react": "^1.1.12", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", - "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", + "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -41,11 +41,11 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", - "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", + "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.2.3" + "@authorizerdev/authorizer-js": "^1.2.5" }, "engines": { "node": ">=10" @@ -406,11 +406,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "dependencies": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.12" } }, "node_modules/css-color-keywords": { @@ -567,9 +567,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -837,19 +837,19 @@ }, "dependencies": { "@authorizerdev/authorizer-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", - "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", + "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", "requires": { "cross-fetch": "^3.1.5" } }, "@authorizerdev/authorizer-react": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", - "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", + "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", "requires": { - "@authorizerdev/authorizer-js": "^1.2.3" + "@authorizerdev/authorizer-js": "^1.2.5" } }, "@babel/code-frame": { @@ -1144,11 +1144,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "requires": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.12" } }, "css-color-keywords": { @@ -1270,9 +1270,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "requires": { "whatwg-url": "^5.0.0" } diff --git a/app/package.json b/app/package.json index 1225346..fa9b74a 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.11", + "@authorizerdev/authorizer-react": "^1.1.12", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/yarn.lock b/app/yarn.lock index 380f761..16c1059 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2,19 +2,19 @@ # yarn lockfile v1 -"@authorizerdev/authorizer-js@^1.2.3": - "integrity" "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz" - "version" "1.2.3" +"@authorizerdev/authorizer-js@^1.2.5": + "integrity" "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz" + "version" "1.2.5" dependencies: "cross-fetch" "^3.1.5" -"@authorizerdev/authorizer-react@^1.1.11": - "integrity" "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz" - "version" "1.1.11" +"@authorizerdev/authorizer-react@^1.1.12": + "integrity" "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz" + "version" "1.1.12" dependencies: - "@authorizerdev/authorizer-js" "^1.2.3" + "@authorizerdev/authorizer-js" "^1.2.5" "@babel/code-frame@^7.16.7": "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" @@ -278,11 +278,11 @@ "version" "1.1.3" "cross-fetch@^3.1.5": - "integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==" - "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" - "version" "3.1.5" + "integrity" "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==" + "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz" + "version" "3.1.8" dependencies: - "node-fetch" "2.6.7" + "node-fetch" "^2.6.12" "css-color-keywords@^1.0.0": "integrity" "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" @@ -389,10 +389,10 @@ "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" "version" "2.1.2" -"node-fetch@2.6.7": - "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" - "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" - "version" "2.6.7" +"node-fetch@^2.6.12": + "integrity" "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==" + "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz" + "version" "2.6.12" dependencies: "whatwg-url" "^5.0.0" From 2fc438d810dfef3214f187c1f502584b4217039b Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 16:13:40 +0530 Subject: [PATCH 14/37] [app] bump authorizer-react 1.1.13 --- app/package-lock.json | 30 +++++++++++++++--------------- app/package.json | 2 +- app/yarn.lock | 18 +++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index efba452..1b7f5a4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.12", + "@authorizerdev/authorizer-react": "^1.1.13", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", - "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz", + "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -41,11 +41,11 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", - "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz", + "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.2.5" + "@authorizerdev/authorizer-js": "^1.2.6" }, "engines": { "node": ">=10" @@ -837,19 +837,19 @@ }, "dependencies": { "@authorizerdev/authorizer-js": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", - "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz", + "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==", "requires": { "cross-fetch": "^3.1.5" } }, "@authorizerdev/authorizer-react": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", - "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz", + "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==", "requires": { - "@authorizerdev/authorizer-js": "^1.2.5" + "@authorizerdev/authorizer-js": "^1.2.6" } }, "@babel/code-frame": { diff --git a/app/package.json b/app/package.json index fa9b74a..2406108 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.12", + "@authorizerdev/authorizer-react": "^1.1.13", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/yarn.lock b/app/yarn.lock index 16c1059..2be982c 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2,19 +2,19 @@ # yarn lockfile v1 -"@authorizerdev/authorizer-js@^1.2.5": - "integrity" "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz" - "version" "1.2.5" +"@authorizerdev/authorizer-js@^1.2.6": + "integrity" "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz" + "version" "1.2.6" dependencies: "cross-fetch" "^3.1.5" -"@authorizerdev/authorizer-react@^1.1.12": - "integrity" "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz" - "version" "1.1.12" +"@authorizerdev/authorizer-react@^1.1.13": + "integrity" "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz" + "version" "1.1.13" dependencies: - "@authorizerdev/authorizer-js" "^1.2.5" + "@authorizerdev/authorizer-js" "^1.2.6" "@babel/code-frame@^7.16.7": "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" From 85ca0f09bfdc4efaa6ef225980a909a1bced582b Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Wed, 12 Jul 2023 11:24:13 +0530 Subject: [PATCH 15/37] [draft] Move sms verificaiton to otp models --- server/db/models/otp.go | 22 +++++++++++------ server/db/models/sms_verification_requests.go | 3 ++- server/db/providers/arangodb/provider.go | 19 ++++++++++++++- server/db/providers/couchbase/shared.go | 5 ---- server/db/providers/mongodb/otp.go | 13 ++++++++++ server/db/providers/mongodb/provider.go | 6 +++++ .../mongodb/sms_verification_requests.go | 7 ++---- server/db/providers/providers.go | 2 ++ server/db/providers/sql/otp.go | 24 +++++++++++++++---- 9 files changed, 78 insertions(+), 23 deletions(-) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index ac9732b..b0e02ee 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -1,14 +1,22 @@ package models +const ( + // FieldName email is the field name for email + FieldNameEmail = "email" + // FieldNamePhoneNumber is the field name for phone number + FieldNamePhoneNumber = "phone_number" +) + // OTP model for database type OTP struct { - Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` - Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` - ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` - CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` - UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` + Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb + ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` + Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` + PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` + ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` + CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` + UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` } type Paging struct { diff --git a/server/db/models/sms_verification_requests.go b/server/db/models/sms_verification_requests.go index a938298..e14da4c 100644 --- a/server/db/models/sms_verification_requests.go +++ b/server/db/models/sms_verification_requests.go @@ -1,7 +1,8 @@ package models -// SMS verification requests model for database +// SMSVerificationRequest is SMS verification requests model for database type SMSVerificationRequest struct { + Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 5488428..88fc6e4 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -225,7 +225,6 @@ func NewProvider() (*provider, error) { return nil, err } } - otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP) if err != nil { return nil, err @@ -235,6 +234,24 @@ func NewProvider() (*provider, error) { Sparse: true, }) + smsVerificationCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.SMSVerificationRequest) + if err != nil { + return nil, err + } + if !smsVerificationCollectionExists { + _, err = arangodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, nil) + if err != nil { + return nil, err + } + } + smsVerificationCollection, err := arangodb.Collection(ctx, models.Collections.SMSVerificationRequest) + if err != nil { + return nil, err + } + smsVerificationCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + Unique: true, + Sparse: true, + }) return &provider{ db: arangodb, }, err diff --git a/server/db/providers/couchbase/shared.go b/server/db/providers/couchbase/shared.go index 104ad02..d640f68 100644 --- a/server/db/providers/couchbase/shared.go +++ b/server/db/providers/couchbase/shared.go @@ -11,24 +11,19 @@ import ( func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) { params := make(map[string]interface{}, 1) - updateFields := "" - for key, value := range webhookMap { if key == "_id" { continue } - if key == "_key" { continue } - if value == nil { updateFields += fmt.Sprintf("%s=$%s,", key, key) params[key] = "null" continue } - valueType := reflect.TypeOf(value) if valueType.Name() == "string" { updateFields += fmt.Sprintf("%s = $%s, ", key, key) diff --git a/server/db/providers/mongodb/otp.go b/server/db/providers/mongodb/otp.go index d6ff2df..8726f5a 100644 --- a/server/db/providers/mongodb/otp.go +++ b/server/db/providers/mongodb/otp.go @@ -2,6 +2,7 @@ package mongodb import ( "context" + "errors" "time" "github.com/authorizerdev/authorizer/server/db/models" @@ -12,6 +13,18 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otp.Email == "" && otp.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) shouldCreate := false if otp == nil { diff --git a/server/db/providers/mongodb/provider.go b/server/db/providers/mongodb/provider.go index fd4a0b2..1922b0e 100644 --- a/server/db/providers/mongodb/provider.go +++ b/server/db/providers/mongodb/provider.go @@ -118,6 +118,12 @@ func NewProvider() (*provider, error) { Options: options.Index().SetUnique(true).SetSparse(true), }, }, options.CreateIndexes()) + otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ + { + Keys: bson.M{"phone_number": 1}, + Options: options.Index().SetUnique(true).SetSparse(true), + }, + }, options.CreateIndexes()) mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection()) smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection()) diff --git a/server/db/providers/mongodb/sms_verification_requests.go b/server/db/providers/mongodb/sms_verification_requests.go index 1183df1..0ee0e6c 100644 --- a/server/db/providers/mongodb/sms_verification_requests.go +++ b/server/db/providers/mongodb/sms_verification_requests.go @@ -12,10 +12,7 @@ import ( // UpsertSMSRequest adds/updates SMS verification request func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - smsVerificationRequest, err := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) - if err != nil { - return nil, err - } + smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) // Boolean to check if we should create a new record or update the existing one shouldCreate := false if smsVerificationRequest == nil { @@ -29,7 +26,7 @@ func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSV } shouldCreate = true } - + var err error smsVerificationRequest.UpdatedAt = time.Now().Unix() smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) if shouldCreate { diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index 31c021c..c6065c1 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -82,6 +82,8 @@ type Provider interface { UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error) // GetOTPByEmail to get otp for a given email address GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) + // GetOTPByPhoneNumber to get otp for a given phone number + GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) // DeleteOTP to delete otp DeleteOTP(ctx context.Context, otp *models.OTP) error diff --git a/server/db/providers/sql/otp.go b/server/db/providers/sql/otp.go index 9aabcab..5503a7d 100644 --- a/server/db/providers/sql/otp.go +++ b/server/db/providers/sql/otp.go @@ -2,6 +2,7 @@ package sql import ( "context" + "errors" "time" "github.com/authorizerdev/authorizer/server/db/models" @@ -14,13 +15,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, if otp.ID == "" { otp.ID = uuid.New().String() } - + // check if email or phone number is present + if otp.Email == "" && otp.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otp.Email == "" && otp.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } otp.Key = otp.ID otp.CreatedAt = time.Now().Unix() otp.UpdatedAt = time.Now().Unix() - res := p.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "email"}}, + Columns: []clause.Column{{Name: uniqueField}}, DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}), }).Create(&otp) if res.Error != nil { @@ -33,7 +40,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - result := p.db.Where("email = ?", emailAddress).First(&otp) if result.Error != nil { return nil, result.Error @@ -41,6 +47,16 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return &otp, nil } +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + result := p.db.Where("phone_number = ?", phoneNumber).First(&otp) + if result.Error != nil { + return nil, result.Error + } + return &otp, nil +} + // DeleteOTP to delete otp func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { result := p.db.Delete(&models.OTP{ From 2f849b8f0c268bd089010fdcad4694adab57ae8c Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 13 Jul 2023 11:39:22 +0530 Subject: [PATCH 16/37] Refactor code for otp --- server/constants/auth_methods.go | 2 + server/db/models/sms_verification_requests.go | 12 -- server/db/providers/arangodb/otp.go | 59 +++++- server/db/providers/arangodb/provider.go | 17 +- .../arangodb/sms_verification_requests.go | 22 --- server/db/providers/cassandradb/otp.go | 46 ++++- server/db/providers/cassandradb/provider.go | 6 +- .../cassandradb/sms_verification_requests.go | 22 --- server/db/providers/couchbase/otp.go | 51 ++++-- server/db/providers/couchbase/provider.go | 4 + .../couchbase/sms_verification_requests.go | 22 --- server/db/providers/dynamodb/otp.go | 54 ++++-- .../dynamodb/sms_verification_requests.go | 22 --- server/db/providers/mongodb/otp.go | 38 ++-- server/db/providers/mongodb/provider.go | 9 - .../mongodb/sms_verification_requests.go | 66 ------- server/db/providers/provider_template/otp.go | 5 + .../sms_verification_requests.go | 22 --- server/db/providers/providers.go | 7 - server/db/providers/sql/provider.go | 2 +- .../sql/sms_verification_requests.go | 49 ----- server/graph/generated/generated.go | 173 ++---------------- server/graph/model/models_gen.go | 12 +- server/graph/schema.graphqls | 10 +- server/graph/schema.resolvers.go | 5 - server/resolvers/mobile_signup.go | 22 +-- server/resolvers/verify_mobile.go | 62 ------- server/resolvers/verify_otp.go | 52 +++--- server/test/mobile_login_test.go | 14 +- server/test/resend_otp_test.go | 4 +- server/test/resolvers_test.go | 1 - server/test/verify_mobile_test.go | 79 -------- server/test/verify_otp_test.go | 2 +- 33 files changed, 277 insertions(+), 696 deletions(-) delete mode 100644 server/db/models/sms_verification_requests.go delete mode 100644 server/db/providers/arangodb/sms_verification_requests.go delete mode 100644 server/db/providers/cassandradb/sms_verification_requests.go delete mode 100644 server/db/providers/couchbase/sms_verification_requests.go delete mode 100644 server/db/providers/dynamodb/sms_verification_requests.go delete mode 100644 server/db/providers/mongodb/sms_verification_requests.go delete mode 100644 server/db/providers/provider_template/sms_verification_requests.go delete mode 100644 server/db/providers/sql/sms_verification_requests.go delete mode 100644 server/resolvers/verify_mobile.go delete mode 100644 server/test/verify_mobile_test.go diff --git a/server/constants/auth_methods.go b/server/constants/auth_methods.go index 9e7b9fa..dbe5175 100644 --- a/server/constants/auth_methods.go +++ b/server/constants/auth_methods.go @@ -7,6 +7,8 @@ const ( AuthRecipeMethodMobileBasicAuth = "mobile_basic_auth" // AuthRecipeMethodMagicLinkLogin is the magic_link_login auth method AuthRecipeMethodMagicLinkLogin = "magic_link_login" + // AuthRecipeMethodMobileOTP is the mobile_otp auth method + AuthRecipeMethodMobileOTP = "mobile_otp" // AuthRecipeMethodGoogle is the google auth method AuthRecipeMethodGoogle = "google" // AuthRecipeMethodGithub is the github auth method diff --git a/server/db/models/sms_verification_requests.go b/server/db/models/sms_verification_requests.go deleted file mode 100644 index e14da4c..0000000 --- a/server/db/models/sms_verification_requests.go +++ /dev/null @@ -1,12 +0,0 @@ -package models - -// SMSVerificationRequest is SMS verification requests model for database -type SMSVerificationRequest struct { - Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` - PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` - Code string `json:"code" bson:"code" cql:"code" dynamo:"code"` - CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"` - CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` - UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` -} diff --git a/server/db/providers/arangodb/otp.go b/server/db/providers/arangodb/otp.go index 29f265a..8fef639 100644 --- a/server/db/providers/arangodb/otp.go +++ b/server/db/providers/arangodb/otp.go @@ -2,6 +2,7 @@ package arangodb import ( "context" + "errors" "fmt" "time" @@ -12,17 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { @@ -67,7 +82,35 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod for { if !cursor.HasMore() { if otp.Key == "" { - return nil, fmt.Errorf("email template not found") + return nil, fmt.Errorf("otp with given email not found") + } + break + } + _, err := cursor.ReadDocument(ctx, &otp) + if err != nil { + return nil, err + } + } + + return &otp, nil +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.OTP) + bindVars := map[string]interface{}{ + "phone_number": phoneNumber, + } + cursor, err := p.db.Query(ctx, query, bindVars) + if err != nil { + return nil, err + } + defer cursor.Close() + for { + if !cursor.HasMore() { + if otp.Key == "" { + return nil, fmt.Errorf("otp with given phone_number not found") } break } diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 88fc6e4..2dd7b28 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -233,22 +233,7 @@ func NewProvider() (*provider, error) { Unique: true, Sparse: true, }) - - smsVerificationCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.SMSVerificationRequest) - if err != nil { - return nil, err - } - if !smsVerificationCollectionExists { - _, err = arangodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, nil) - if err != nil { - return nil, err - } - } - smsVerificationCollection, err := arangodb.Collection(ctx, models.Collections.SMSVerificationRequest) - if err != nil { - return nil, err - } - smsVerificationCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + otpCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ Unique: true, Sparse: true, }) diff --git a/server/db/providers/arangodb/sms_verification_requests.go b/server/db/providers/arangodb/sms_verification_requests.go deleted file mode 100644 index 6eb97b8..0000000 --- a/server/db/providers/arangodb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package arangodb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/cassandradb/otp.go b/server/db/providers/cassandradb/otp.go index bfe481d..e453242 100644 --- a/server/db/providers/cassandradb/otp.go +++ b/server/db/providers/cassandradb/otp.go @@ -2,6 +2,7 @@ package cassandradb import ( "context" + "errors" "fmt" "time" @@ -12,17 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { shouldCreate = true otp = &models.OTP{ - ID: uuid.NewString(), - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), - UpdatedAt: time.Now().Unix(), + ID: uuid.NewString(), + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), + UpdatedAt: time.Now().Unix(), } } else { otp.Otp = otpParam.Otp @@ -32,7 +47,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models otp.UpdatedAt = time.Now().Unix() query := "" if shouldCreate { - query = fmt.Sprintf(`INSERT INTO %s (id, email, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt) + query = fmt.Sprintf(`INSERT INTO %s (id, email, phone_number, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.PhoneNumber, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt) } else { query = fmt.Sprintf(`UPDATE %s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, KeySpace+"."+models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID) } @@ -48,8 +63,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - query := fmt.Sprintf(`SELECT id, email, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress) - err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) + query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress) + err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) + if err != nil { + return nil, err + } + return &otp, nil +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, phoneNumber) + err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) if err != nil { return nil, err } diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go index 1d8fa49..1c989be 100644 --- a/server/db/providers/cassandradb/provider.go +++ b/server/db/providers/cassandradb/provider.go @@ -254,7 +254,11 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } - + otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP) + err = session.Query(otpIndexQueryPhoneNumber).Exec() + if err != nil { + return nil, err + } return &provider{ db: session, }, err diff --git a/server/db/providers/cassandradb/sms_verification_requests.go b/server/db/providers/cassandradb/sms_verification_requests.go deleted file mode 100644 index ddead30..0000000 --- a/server/db/providers/cassandradb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package cassandradb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/couchbase/otp.go b/server/db/providers/couchbase/otp.go index cdcfde9..1fe6532 100644 --- a/server/db/providers/couchbase/otp.go +++ b/server/db/providers/couchbase/otp.go @@ -2,6 +2,7 @@ package couchbase import ( "context" + "errors" "fmt" "time" @@ -12,24 +13,36 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) - + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { shouldCreate = true otp = &models.OTP{ - ID: uuid.NewString(), - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), - UpdatedAt: time.Now().Unix(), + ID: uuid.NewString(), + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), + UpdatedAt: time.Now().Unix(), } } else { otp.Otp = otpParam.Otp otp.ExpiresAt = otpParam.ExpiresAt } - otp.UpdatedAt = time.Now().Unix() if shouldCreate { insertOpt := gocb.InsertOptions{ @@ -54,7 +67,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { otp := models.OTP{} - query := fmt.Sprintf(`SELECT _id, email, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) + query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) q, err := p.db.Query(query, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistencyRequestPlus, PositionalParameters: []interface{}{emailAddress}, @@ -63,11 +76,27 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return nil, err } err = q.One(&otp) - if err != nil { return nil, err } + return &otp, nil +} +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + otp := models.OTP{} + query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1`, p.scopeName, models.Collections.OTP) + q, err := p.db.Query(query, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + PositionalParameters: []interface{}{phoneNumber}, + }) + if err != nil { + return nil, err + } + err = q.One(&otp) + if err != nil { + return nil, err + } return &otp, nil } diff --git a/server/db/providers/couchbase/provider.go b/server/db/providers/couchbase/provider.go index c5d5404..723e47a 100644 --- a/server/db/providers/couchbase/provider.go +++ b/server/db/providers/couchbase/provider.go @@ -166,5 +166,9 @@ func GetIndex(scopeName string) map[string][]string { otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, models.Collections.OTP) indices[models.Collections.OTP] = []string{otpIndex1} + // OTP index + otpIndex2 := fmt.Sprintf("CREATE INDEX OTPPhoneNumberIndex ON %s.%s(phone_number)", scopeName, models.Collections.OTP) + indices[models.Collections.OTP] = []string{otpIndex2} + return indices } diff --git a/server/db/providers/couchbase/sms_verification_requests.go b/server/db/providers/couchbase/sms_verification_requests.go deleted file mode 100644 index 0639179..0000000 --- a/server/db/providers/couchbase/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package couchbase - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/dynamodb/otp.go b/server/db/providers/dynamodb/otp.go index 063f634..bb55523 100644 --- a/server/db/providers/dynamodb/otp.go +++ b/server/db/providers/dynamodb/otp.go @@ -11,27 +11,39 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + // check if email or phone number is present + if otpParam.Email == "" && otpParam.PhoneNumber == "" { + return nil, errors.New("email or phone_number is required") + } + uniqueField := models.FieldNameEmail + if otpParam.Email == "" && otpParam.PhoneNumber != "" { + uniqueField = models.FieldNamePhoneNumber + } + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { otp.Otp = otpParam.Otp otp.ExpiresAt = otpParam.ExpiresAt } - collection := p.db.Table(models.Collections.OTP) otp.UpdatedAt = time.Now().Unix() - var err error if shouldCreate { err = collection.Put(otp).RunWithContext(ctx) @@ -41,7 +53,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models if err != nil { return nil, err } - return otp, nil } @@ -49,20 +60,32 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otps []models.OTP var otp models.OTP - collection := p.db.Table(models.Collections.OTP) - err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps) - if err != nil { return nil, err } if len(otps) > 0 { otp = otps[0] return &otp, nil - } else { - return nil, errors.New("no docuemnt found") } + return nil, errors.New("no docuemnt found") +} + +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otps []models.OTP + var otp models.OTP + collection := p.db.Table(models.Collections.OTP) + err := collection.Scan().Index("phone_number").Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) + if err != nil { + return nil, err + } + if len(otps) > 0 { + otp = otps[0] + return &otp, nil + } + return nil, errors.New("no docuemnt found") } // DeleteOTP to delete otp @@ -75,6 +98,5 @@ func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { return err } } - return nil } diff --git a/server/db/providers/dynamodb/sms_verification_requests.go b/server/db/providers/dynamodb/sms_verification_requests.go deleted file mode 100644 index 6569a54..0000000 --- a/server/db/providers/dynamodb/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package dynamodb - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/mongodb/otp.go b/server/db/providers/mongodb/otp.go index 8726f5a..d70818d 100644 --- a/server/db/providers/mongodb/otp.go +++ b/server/db/providers/mongodb/otp.go @@ -13,29 +13,31 @@ import ( // UpsertOTP to add or update otp func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { - // check if email or phone number is present - if otpParam.Email == "" && otpParam.PhoneNumber == "" { - return nil, errors.New("email or phone_number is required") - } // check if email or phone number is present if otpParam.Email == "" && otpParam.PhoneNumber == "" { return nil, errors.New("email or phone_number is required") } uniqueField := models.FieldNameEmail - if otp.Email == "" && otp.PhoneNumber != "" { + if otpParam.Email == "" && otpParam.PhoneNumber != "" { uniqueField = models.FieldNamePhoneNumber } - otp, _ := p.GetOTPByEmail(ctx, otpParam.Email) + var otp *models.OTP + if uniqueField == models.FieldNameEmail { + otp, _ = p.GetOTPByEmail(ctx, otpParam.Email) + } else { + otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber) + } shouldCreate := false if otp == nil { id := uuid.NewString() otp = &models.OTP{ - ID: id, - Key: id, - Otp: otpParam.Otp, - Email: otpParam.Email, - ExpiresAt: otpParam.ExpiresAt, - CreatedAt: time.Now().Unix(), + ID: id, + Key: id, + Otp: otpParam.Otp, + Email: otpParam.Email, + PhoneNumber: otpParam.PhoneNumber, + ExpiresAt: otpParam.ExpiresAt, + CreatedAt: time.Now().Unix(), } shouldCreate = true } else { @@ -54,20 +56,28 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models if err != nil { return nil, err } - return otp, nil } // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { var otp models.OTP - otpCollection := p.db.Collection(models.Collections.OTP, options.Collection()) err := otpCollection.FindOne(ctx, bson.M{"email": emailAddress}).Decode(&otp) if err != nil { return nil, err } + return &otp, nil +} +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + var otp models.OTP + otpCollection := p.db.Collection(models.Collections.OTP, options.Collection()) + err := otpCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&otp) + if err != nil { + return nil, err + } return &otp, nil } diff --git a/server/db/providers/mongodb/provider.go b/server/db/providers/mongodb/provider.go index 1922b0e..30af342 100644 --- a/server/db/providers/mongodb/provider.go +++ b/server/db/providers/mongodb/provider.go @@ -125,15 +125,6 @@ func NewProvider() (*provider, error) { }, }, options.CreateIndexes()) - mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection()) - smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - smsCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ - { - Keys: bson.M{"phone_number": 1}, - Options: options.Index().SetUnique(true).SetSparse(true), - }, - }, options.CreateIndexes()) - return &provider{ db: mongodb, }, nil diff --git a/server/db/providers/mongodb/sms_verification_requests.go b/server/db/providers/mongodb/sms_verification_requests.go deleted file mode 100644 index 0ee0e6c..0000000 --- a/server/db/providers/mongodb/sms_verification_requests.go +++ /dev/null @@ -1,66 +0,0 @@ -package mongodb - -import ( - "context" - "time" - - "github.com/authorizerdev/authorizer/server/db/models" - "github.com/google/uuid" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo/options" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber) - // Boolean to check if we should create a new record or update the existing one - shouldCreate := false - if smsVerificationRequest == nil { - id := uuid.NewString() - smsVerificationRequest = &models.SMSVerificationRequest{ - ID: id, - CreatedAt: time.Now().Unix(), - Code: smsRequest.Code, - PhoneNumber: smsRequest.PhoneNumber, - CodeExpiresAt: smsRequest.CodeExpiresAt, - } - shouldCreate = true - } - var err error - smsVerificationRequest.UpdatedAt = time.Now().Unix() - smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - if shouldCreate { - _, err = smsRequestCollection.InsertOne(ctx, smsVerificationRequest) - } else { - _, err = smsRequestCollection.UpdateOne(ctx, bson.M{"phone_number": bson.M{"$eq": smsRequest.PhoneNumber}}, bson.M{"$set": smsVerificationRequest}, options.MergeUpdateOptions()) - } - if err != nil { - return nil, err - } - return smsVerificationRequest, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var smsVerificationRequest models.SMSVerificationRequest - - smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - err := smsRequestCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&smsVerificationRequest) - - if err != nil { - return nil, err - } - - return &smsVerificationRequest, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - smsVerificationRequests := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection()) - _, err := smsVerificationRequests.DeleteOne(nil, bson.M{"_id": smsRequest.ID}, options.Delete()) - if err != nil { - return err - } - - return nil -} diff --git a/server/db/providers/provider_template/otp.go b/server/db/providers/provider_template/otp.go index d8685e7..0716711 100644 --- a/server/db/providers/provider_template/otp.go +++ b/server/db/providers/provider_template/otp.go @@ -16,6 +16,11 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return nil, nil } +// GetOTPByPhoneNumber to get otp for a given phone number +func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { + return nil, nil +} + // DeleteOTP to delete otp func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { return nil diff --git a/server/db/providers/provider_template/sms_verification_requests.go b/server/db/providers/provider_template/sms_verification_requests.go deleted file mode 100644 index d238a80..0000000 --- a/server/db/providers/provider_template/sms_verification_requests.go +++ /dev/null @@ -1,22 +0,0 @@ -package provider_template - -import ( - "context" - - "github.com/authorizerdev/authorizer/server/db/models" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - return nil, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - return nil -} diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index c6065c1..be25b53 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -86,11 +86,4 @@ type Provider interface { GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) // DeleteOTP to delete otp DeleteOTP(ctx context.Context, otp *models.OTP) error - - // UpsertSMSRequest adds/updates SMS verification request - UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) - // GetCodeByPhone to get code for a given phone number - GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) - // DeleteSMSRequest to delete SMS verification request - DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error } diff --git a/server/db/providers/sql/provider.go b/server/db/providers/sql/provider.go index 89ea31b..2101953 100644 --- a/server/db/providers/sql/provider.go +++ b/server/db/providers/sql/provider.go @@ -77,7 +77,7 @@ func NewProvider() (*provider, error) { logrus.Debug("Failed to drop phone number constraint:", err) } - err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}, &models.SMSVerificationRequest{}) + err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}) if err != nil { return nil, err } diff --git a/server/db/providers/sql/sms_verification_requests.go b/server/db/providers/sql/sms_verification_requests.go deleted file mode 100644 index 387b5eb..0000000 --- a/server/db/providers/sql/sms_verification_requests.go +++ /dev/null @@ -1,49 +0,0 @@ -package sql - -import ( - "context" - "time" - - "github.com/authorizerdev/authorizer/server/db/models" - "github.com/google/uuid" - "gorm.io/gorm/clause" -) - -// UpsertSMSRequest adds/updates SMS verification request -func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) { - if smsRequest.ID == "" { - smsRequest.ID = uuid.New().String() - } - smsRequest.CreatedAt = time.Now().Unix() - smsRequest.UpdatedAt = time.Now().Unix() - res := p.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "phone_number"}}, - DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at", "updated_at"}), - }).Create(smsRequest) - if res.Error != nil { - return nil, res.Error - } - return smsRequest, nil -} - -// GetCodeByPhone to get code for a given phone number -func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) { - var sms_verification_request models.SMSVerificationRequest - - result := p.db.Where("phone_number = ?", phoneNumber).First(&sms_verification_request) - if result.Error != nil { - return nil, result.Error - } - return &sms_verification_request, nil -} - -// DeleteSMSRequest to delete SMS verification request -func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error { - result := p.db.Delete(&models.SMSVerificationRequest{ - ID: smsRequest.ID, - }) - if result.Error != nil { - return result.Error - } - return nil -} diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 885b04d..b2493ef 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -198,7 +198,6 @@ type ComplexityRoot struct { UpdateUser func(childComplexity int, params model.UpdateUserInput) int UpdateWebhook func(childComplexity int, params model.UpdateWebhookRequest) int VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int - VerifyMobile func(childComplexity int, params model.VerifyMobileRequest) int VerifyOtp func(childComplexity int, params model.VerifyOTPRequest) int } @@ -344,7 +343,6 @@ type MutationResolver interface { Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error) ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) - VerifyMobile(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) @@ -1438,18 +1436,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.VerifyEmail(childComplexity, args["params"].(model.VerifyEmailInput)), true - case "Mutation.verify_mobile": - if e.complexity.Mutation.VerifyMobile == nil { - break - } - - args, err := ec.field_Mutation_verify_mobile_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.VerifyMobile(childComplexity, args["params"].(model.VerifyMobileRequest)), true - case "Mutation.verify_otp": if e.complexity.Mutation.VerifyOtp == nil { break @@ -2120,7 +2106,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputValidateJWTTokenInput, ec.unmarshalInputValidateSessionInput, ec.unmarshalInputVerifyEmailInput, - ec.unmarshalInputVerifyMobileRequest, ec.unmarshalInputVerifyOTPRequest, ec.unmarshalInputWebhookRequest, ) @@ -2269,11 +2254,6 @@ type SMSVerificationRequests { updated_at: Int64 } -input VerifyMobileRequest { - phone_number: String! - code: String! -} - type Error { message: String! reason: String! @@ -2728,7 +2708,9 @@ input DeleteEmailTemplateRequest { } input VerifyOTPRequest { - email: String! + # either email or phone_number is required + email: String + phone_number: String otp: String! # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login @@ -2764,7 +2746,6 @@ type Mutation { revoke(params: OAuthRevokeInput!): Response! verify_otp(params: VerifyOTPRequest!): AuthResponse! resend_otp(params: ResendOTPRequest!): Response! - verify_mobile(params: VerifyMobileRequest!): AuthResponse! # admin only apis _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! @@ -3230,21 +3211,6 @@ func (ec *executionContext) field_Mutation_verify_email_args(ctx context.Context return args, nil } -func (ec *executionContext) field_Mutation_verify_mobile_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 model.VerifyMobileRequest - if tmp, ok := rawArgs["params"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) - arg0, err = ec.unmarshalNVerifyMobileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyMobileRequest(ctx, tmp) - if err != nil { - return nil, err - } - } - args["params"] = arg0 - return args, nil -} - func (ec *executionContext) field_Mutation_verify_otp_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -8635,77 +8601,6 @@ func (ec *executionContext) fieldContext_Mutation_resend_otp(ctx context.Context return fc, nil } -func (ec *executionContext) _Mutation_verify_mobile(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_verify_mobile(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().VerifyMobile(rctx, fc.Args["params"].(model.VerifyMobileRequest)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*model.AuthResponse) - fc.Result = res - return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Mutation_verify_mobile(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Mutation", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "message": - return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) - case "access_token": - return ec.fieldContext_AuthResponse_access_token(ctx, field) - case "id_token": - return ec.fieldContext_AuthResponse_id_token(ctx, field) - case "refresh_token": - return ec.fieldContext_AuthResponse_refresh_token(ctx, field) - case "expires_in": - return ec.fieldContext_AuthResponse_expires_in(ctx, field) - case "user": - return ec.fieldContext_AuthResponse_user(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type AuthResponse", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_verify_mobile_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return - } - return fc, nil -} - func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation__delete_user(ctx, field) if err != nil { @@ -17781,42 +17676,6 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, return it, nil } -func (ec *executionContext) unmarshalInputVerifyMobileRequest(ctx context.Context, obj interface{}) (model.VerifyMobileRequest, error) { - var it model.VerifyMobileRequest - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"phone_number", "code"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "phone_number": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) - it.PhoneNumber, err = ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - case "code": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("code")) - it.Code, err = ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - } - } - - return it, nil -} - func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, obj interface{}) (model.VerifyOTPRequest, error) { var it model.VerifyOTPRequest asMap := map[string]interface{}{} @@ -17824,7 +17683,7 @@ func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"email", "otp", "state"} + fieldsInOrder := [...]string{"email", "phone_number", "otp", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -17835,7 +17694,15 @@ func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email")) - it.Email, err = ec.unmarshalNString2string(ctx, v) + it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "phone_number": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) + it.PhoneNumber, err = ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } @@ -18723,15 +18590,6 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) return ec._Mutation_resend_otp(ctx, field) }) - if out.Values[i] == graphql.Null { - invalids++ - } - case "verify_mobile": - - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_verify_mobile(ctx, field) - }) - if out.Values[i] == graphql.Null { invalids++ } @@ -20798,11 +20656,6 @@ func (ec *executionContext) unmarshalNVerifyEmailInput2githubᚗcomᚋauthorizer return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNVerifyMobileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyMobileRequest(ctx context.Context, v interface{}) (model.VerifyMobileRequest, error) { - res, err := ec.unmarshalInputVerifyMobileRequest(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyOTPRequest(ctx context.Context, v interface{}) (model.VerifyOTPRequest, error) { res, err := ec.unmarshalInputVerifyOTPRequest(ctx, v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index d327f9a..7621995 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -486,15 +486,11 @@ type VerifyEmailInput struct { State *string `json:"state"` } -type VerifyMobileRequest struct { - PhoneNumber string `json:"phone_number"` - Code string `json:"code"` -} - type VerifyOTPRequest struct { - Email string `json:"email"` - Otp string `json:"otp"` - State *string `json:"state"` + Email *string `json:"email"` + PhoneNumber *string `json:"phone_number"` + Otp string `json:"otp"` + State *string `json:"state"` } type Webhook struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index c830236..bb83b9b 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -84,11 +84,6 @@ type SMSVerificationRequests { updated_at: Int64 } -input VerifyMobileRequest { - phone_number: String! - code: String! -} - type Error { message: String! reason: String! @@ -543,7 +538,9 @@ input DeleteEmailTemplateRequest { } input VerifyOTPRequest { - email: String! + # either email or phone_number is required + email: String + phone_number: String otp: String! # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login @@ -579,7 +576,6 @@ type Mutation { revoke(params: OAuthRevokeInput!): Response! verify_otp(params: VerifyOTPRequest!): AuthResponse! resend_otp(params: ResendOTPRequest!): Response! - verify_mobile(params: VerifyMobileRequest!): AuthResponse! # admin only apis _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index beb49b2..eecb6b2 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -81,11 +81,6 @@ func (r *mutationResolver) ResendOtp(ctx context.Context, params model.ResendOTP return resolvers.ResendOTPResolver(ctx, params) } -// VerifyMobile is the resolver for the verify_mobile field. -func (r *mutationResolver) VerifyMobile(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) { - return resolvers.VerifyMobileResolver(ctx, params) -} - // DeleteUser is the resolver for the _delete_user field. func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) { return resolvers.DeleteUserResolver(ctx, params) diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 9aee0a6..908ecfe 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" log "github.com/sirupsen/logrus" - + "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/crypto" @@ -17,9 +17,9 @@ import ( "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/utils" - "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/validators" ) @@ -133,8 +133,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } user := models.User{ - Email: emailInput, - PhoneNumber: &mobile, + Email: emailInput, + PhoneNumber: &mobile, } user.Roles = strings.Join(inputRoles, ",") @@ -179,7 +179,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("MFA service not enabled: ", err) isMFAEnforced = false } - + if isMFAEnforced { user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true) } @@ -197,11 +197,11 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - + if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() - + smsBody := strings.Builder{} smsBody.WriteString("Your verification code is: ") smsBody.WriteString(smsCode) @@ -213,10 +213,10 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } go func() { - db.Provider.UpsertSMSRequest(ctx, &models.SMSVerificationRequest{ - PhoneNumber: mobile, - Code: smsCode, - CodeExpiresAt: time.Now().Add(duration).Unix(), + db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: mobile, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), }) smsproviders.SendSMS(mobile, smsBody.String()) }() diff --git a/server/resolvers/verify_mobile.go b/server/resolvers/verify_mobile.go deleted file mode 100644 index 4e077d7..0000000 --- a/server/resolvers/verify_mobile.go +++ /dev/null @@ -1,62 +0,0 @@ -package resolvers - -import ( - "fmt" - "context" - "time" - - "github.com/authorizerdev/authorizer/server/graph/model" - "github.com/authorizerdev/authorizer/server/utils" - "github.com/authorizerdev/authorizer/server/db" - log "github.com/sirupsen/logrus" -) - -func VerifyMobileResolver(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) { - var res *model.AuthResponse - - _, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug("Failed to get GinContext: ", err) - return res, err - } - - smsVerificationRequest, err := db.Provider.GetCodeByPhone(ctx, params.PhoneNumber) - if err != nil { - log.Debug("Failed to get sms request by phone: ", err) - return res, err - } - - if smsVerificationRequest.Code != params.Code { - log.Debug("Failed to verify request: bad credentials") - return res, fmt.Errorf(`bad credentials`) - } - - expiresIn := smsVerificationRequest.CodeExpiresAt - time.Now().Unix() - if expiresIn < 0 { - log.Debug("Failed to verify sms request: Timeout") - return res, fmt.Errorf("time expired") - } - - res = &model.AuthResponse{ - Message: "successful", - } - - user, err := db.Provider.GetUserByPhoneNumber(ctx, params.PhoneNumber) - if user.PhoneNumberVerifiedAt == nil { - now := time.Now().Unix() - user.PhoneNumberVerifiedAt = &now - } - - _, err = db.Provider.UpdateUser(ctx, *user) - if err != nil { - log.Debug("Failed to update user: ", err) - return res, err - } - - err = db.Provider.DeleteSMSRequest(ctx, smsVerificationRequest) - if err != nil { - log.Debug("Failed to delete sms request: ", err.Error()) - } - - return res, err -} diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index aac55e2..124ee3f 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -27,47 +27,53 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to get GinContext: ", err) return res, err } - - mfaSession, err := cookie.GetMfaSession(gc) - if err != nil { - log.Debug("Failed to get otp request by email: ", err) - return res, fmt.Errorf(`invalid session: %s`, err.Error()) + if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" { + log.Debug("Email or phone number is required") + return res, fmt.Errorf(`email or phone_number is required`) } - if _, err := memorystore.Provider.GetMfaSession(params.Email, mfaSession); err != nil { - log.Debug("Failed to get mfa session: ", err) - return res, fmt.Errorf(`invalid session: %s`, err.Error()) + currentField := models.FieldNameEmail + if refs.StringValue(params.Email) == "" { + currentField = models.FieldNamePhoneNumber } - - otp, err := db.Provider.GetOTPByEmail(ctx, params.Email) - if err != nil { - log.Debug("Failed to get otp request by email: ", err) - return res, fmt.Errorf(`invalid email: %s`, err.Error()) + var otp *models.OTP + if currentField == models.FieldNameEmail { + otp, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email)) + } else { + otp, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + } + if otp == nil && err != nil { + log.Debugf("Failed to get otp request for %s: %s", currentField, err.Error()) + return res, fmt.Errorf(`invalid %s: %s`, currentField, err.Error()) } - if params.Otp != otp.Otp { log.Debug("Failed to verify otp request: Incorrect value") return res, fmt.Errorf(`invalid otp`) } - expiresIn := otp.ExpiresAt - time.Now().Unix() - if expiresIn < 0 { log.Debug("Failed to verify otp request: Timeout") return res, fmt.Errorf("otp expired") } - - user, err := db.Provider.GetUserByEmail(ctx, params.Email) - if err != nil { + var user models.User + if currentField == models.FieldNameEmail { + user, err = db.Provider.GetUserByEmail(ctx, refs.StringValue(params.Email)) + } else { + // TODO fix after refs of db providers are fixed + var u *models.User + u, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + user = *u + } + if user.ID == "" && err != nil { log.Debug("Failed to get user by email: ", err) return res, err } - - isSignUp := user.EmailVerifiedAt == nil - + isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil // TODO - Add Login method in DB when we introduce OTP for social media login loginMethod := constants.AuthRecipeMethodBasicAuth - + if currentField == models.FieldNamePhoneNumber { + loginMethod = constants.AuthRecipeMethodMobileOTP + } roles := strings.Split(user.Roles, ",") scope := []string{"openid", "email", "profile"} code := "" diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go index 48b7690..d81d780 100644 --- a/server/test/mobile_login_test.go +++ b/server/test/mobile_login_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/db" + "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" "github.com/stretchr/testify/assert" @@ -54,17 +54,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) { assert.NotNil(t, err, "should fail because phone is not verified") assert.Nil(t, res) - smsRequest, err := db.Provider.GetCodeByPhone(ctx, phoneNumber) + smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.NoError(t, err) - assert.NotEmpty(t, smsRequest.Code) + assert.NotEmpty(t, smsRequest.Otp) - verifySMSRequest, err := resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: smsRequest.Code, + verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ + PhoneNumber: &phoneNumber, + Otp: smsRequest.Otp, }) assert.Nil(t, err) assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - + res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, Password: s.TestInfo.Password, diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go index 73e715d..eb6993f 100644 --- a/server/test/resend_otp_test.go +++ b/server/test/resend_otp_test.go @@ -84,13 +84,13 @@ func resendOTPTest(t *testing.T, s TestSetup) { // Should return error for older otp verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: otp.Otp, }) assert.Error(t, err) assert.Nil(t, verifyOtpRes) verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: newOtp.Otp, }) assert.NoError(t, err) diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index 446986c..ecda491 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -135,7 +135,6 @@ func TestResolvers(t *testing.T) { validateJwtTokenTest(t, s) verifyOTPTest(t, s) resendOTPTest(t, s) - verifyMobileTest(t, s) validateSessionTests(t, s) updateAllUsersTest(t, s) diff --git a/server/test/verify_mobile_test.go b/server/test/verify_mobile_test.go deleted file mode 100644 index b4daa5e..0000000 --- a/server/test/verify_mobile_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package test - -import ( - "strings" - "testing" - - "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/graph/model" - "github.com/authorizerdev/authorizer/server/db" - "github.com/authorizerdev/authorizer/server/refs" - "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/stretchr/testify/assert" -) - -func verifyMobileTest(t *testing.T, s TestSetup) { - t.Helper() - t.Run(`should verify mobile`, func(t *testing.T) { - _, ctx := createContext(s) - email := "mobile_verification." + s.TestInfo.Email - phoneNumber := "2234567890" - signUpRes, err := resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ - Email: refs.NewStringRef(email), - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - ConfirmPassword: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotNil(t, signUpRes) - assert.Equal(t, email, signUpRes.User.Email) - assert.Equal(t, phoneNumber, refs.StringValue(signUpRes.User.PhoneNumber)) - assert.True(t, strings.Contains(signUpRes.User.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth)) - assert.Len(t, strings.Split(signUpRes.User.SignupMethods, ","), 1) - - res, err := resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: "random_test", - }) - assert.Error(t, err) - assert.Nil(t, res) - - // should fail because phone is not verified - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NotNil(t, err, "should fail because phone is not verified") - assert.Nil(t, res) - - // get code from db - smsRequest, err := db.Provider.GetCodeByPhone(ctx, phoneNumber) - assert.NoError(t, err) - assert.NotEmpty(t, smsRequest.Code) - - // throw an error if the code is not correct - verifySMSRequest, err := resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: "rand_12@1", - }) - assert.NotNil(t, err, "should fail because of bad credentials") - assert.Nil(t, verifySMSRequest) - - verifySMSRequest, err = resolvers.VerifyMobileResolver(ctx, model.VerifyMobileRequest{ - PhoneNumber: phoneNumber, - Code: smsRequest.Code, - }) - assert.Nil(t, err) - assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.NotEmpty(t, res.IDToken) - - cleanData(email) - }) -} diff --git a/server/test/verify_otp_test.go b/server/test/verify_otp_test.go index 9e074cd..750deb5 100644 --- a/server/test/verify_otp_test.go +++ b/server/test/verify_otp_test.go @@ -65,7 +65,7 @@ func verifyOTPTest(t *testing.T, s TestSetup) { assert.NotEmpty(t, otp.Otp) verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ - Email: email, + Email: &email, Otp: otp.Otp, }) assert.Nil(t, err) From cf54fcef031ba03b06adb81a96ecd2adbc1e63c5 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 18 Jul 2023 22:50:23 +0530 Subject: [PATCH 17/37] Fix tests --- server/db/models/otp.go | 2 +- server/resolvers/mobile_login.go | 40 +++++++++++++++++++++++++++++++ server/resolvers/mobile_signup.go | 22 ++++++++++------- server/smsproviders/twilio.go | 20 ++++++---------- server/test/mobile_login_test.go | 21 ++-------------- server/test/mobile_signup_test.go | 22 +++++++++++++---- 6 files changed, 81 insertions(+), 46 deletions(-) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index b0e02ee..8ccb13e 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -12,7 +12,7 @@ type OTP struct { Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 9da0a53..8368745 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -17,6 +17,7 @@ import ( "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/validators" @@ -94,6 +95,45 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m roles = params.Roles } + disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + if disablePhoneVerification { + now := time.Now().Unix() + user.PhoneNumberVerifiedAt = &now + } + fmt.Println("=> disablePhoneVerification", disablePhoneVerification) + + if !disablePhoneVerification { + duration, _ := time.ParseDuration("10m") + smsCode := utils.GenerateOTP() + + smsBody := strings.Builder{} + smsBody.WriteString("Your verification code is: ") + smsBody.WriteString(smsCode) + + // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api + if err != nil { + log.Debug("error while upserting user: ", err.Error()) + return nil, err + } + _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: params.PhoneNumber, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), + }) + if err != nil { + log.Debug("error while upserting OTP: ", err.Error()) + return nil, err + } + go func() { + + smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) + }() + return &model.AuthResponse{ + Message: "Please check the OTP", + ShouldShowOtpScreen: refs.NewBoolRef(true), + }, nil + } + scope := []string{"openid", "email", "profile"} if params.Scope != nil && len(scope) > 0 { scope = params.Scope diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 908ecfe..610b238 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -105,7 +105,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } inputRoles := []string{} - if len(params.Roles) > 0 { // check if roles exists rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles) @@ -197,7 +196,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - + fmt.Println("=> disablePhoneVerification signup", disablePhoneVerification) if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() @@ -211,15 +210,22 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("error while upserting user: ", err.Error()) return nil, err } - + _, err = db.Provider.UpsertOTP(ctx, &models.OTP{ + PhoneNumber: mobile, + Otp: smsCode, + ExpiresAt: time.Now().Add(duration).Unix(), + }) + if err != nil { + log.Debug("error while upserting OTP: ", err.Error()) + return nil, err + } go func() { - db.Provider.UpsertOTP(ctx, &models.OTP{ - PhoneNumber: mobile, - Otp: smsCode, - ExpiresAt: time.Now().Add(duration).Unix(), - }) smsproviders.SendSMS(mobile, smsBody.String()) }() + return &model.AuthResponse{ + Message: "Please check the OTP in your inbox", + ShouldShowOtpScreen: refs.NewBoolRef(true), + }, nil } roles := strings.Split(user.Roles, ",") diff --git a/server/smsproviders/twilio.go b/server/smsproviders/twilio.go index 093e924..900be6d 100644 --- a/server/smsproviders/twilio.go +++ b/server/smsproviders/twilio.go @@ -1,43 +1,37 @@ package smsproviders import ( - twilio "github.com/twilio/twilio-go" - api "github.com/twilio/twilio-go/rest/api/v2010" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/memorystore" log "github.com/sirupsen/logrus" + twilio "github.com/twilio/twilio-go" + api "github.com/twilio/twilio-go/rest/api/v2010" ) // TODO: Should be restructured to interface when another provider is added func SendSMS(sendTo, messageBody string) error { - twilioAPISecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPISecret) - if err != nil || twilioAPISecret == ""{ - log.Errorf("Failed to get api secret: ", err) + if err != nil || twilioAPISecret == "" { + log.Debug("Failed to get api secret: ", err) return err } - twilioAPIKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPIKey) - if err != nil || twilioAPIKey == ""{ - log.Errorf("Failed to get api key: ", err) + if err != nil || twilioAPIKey == "" { + log.Debug("Failed to get api key: ", err) return err } - twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSenderFrom) if err != nil || twilioSenderFrom == "" { - log.Errorf("Failed to get sender: ", err) + log.Debug("Failed to get sender: ", err) return err } - // accountSID is not a must to send sms on twilio twilioAccountSID, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAccountSID) - client := twilio.NewRestClientWithParams(twilio.ClientParams{ Username: twilioAPIKey, Password: twilioAPISecret, AccountSid: twilioAccountSID, }) - message := &api.CreateMessageParams{} message.SetBody(messageBody) message.SetFrom(twilioSenderFrom) diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go index d81d780..4cc181a 100644 --- a/server/test/mobile_login_test.go +++ b/server/test/mobile_login_test.go @@ -1,10 +1,8 @@ package test import ( - "strings" "testing" - "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/refs" @@ -26,11 +24,6 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotNil(t, signUpRes) - assert.Equal(t, email, signUpRes.User.Email) - assert.Equal(t, phoneNumber, refs.StringValue(signUpRes.User.PhoneNumber)) - assert.True(t, strings.Contains(signUpRes.User.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth)) - assert.Len(t, strings.Split(signUpRes.User.SignupMethods, ","), 1) - res, err := resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, Password: "random_test", @@ -45,7 +38,6 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.Error(t, err) assert.Nil(t, res) - // should fail because phone is not verified res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ PhoneNumber: phoneNumber, @@ -53,26 +45,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "should fail because phone is not verified") assert.Nil(t, res) - smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.NoError(t, err) assert.NotEmpty(t, smsRequest.Otp) - verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ PhoneNumber: &phoneNumber, Otp: smsRequest.Otp, }) assert.Nil(t, err) assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty") - - res, err = resolvers.MobileLoginResolver(ctx, model.MobileLoginInput{ - PhoneNumber: phoneNumber, - Password: s.TestInfo.Password, - }) - assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.NotEmpty(t, res.IDToken) - + assert.NotEmpty(t, verifySMSRequest.AccessToken) + assert.NotEmpty(t, verifySMSRequest.IDToken) cleanData(email) }) } diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 11deccc..56e96a8 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -1,9 +1,11 @@ package test import ( + "fmt" "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" @@ -65,16 +67,26 @@ func mobileSingupTest(t *testing.T, s TestSetup) { }) assert.Error(t, err) assert.Nil(t, res) - + phoneNumber := "1234567890" res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ - PhoneNumber: "1234567890", + PhoneNumber: phoneNumber, Password: s.TestInfo.Password, ConfirmPassword: s.TestInfo.Password, }) assert.NoError(t, err) - assert.NotEmpty(t, res.AccessToken) - assert.Equal(t, "1234567890@authorizer.dev", res.User.Email) - + assert.NotNil(t, res) + assert.True(t, *res.ShouldShowOtpScreen) + // Verify with otp + otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) + fmt.Println("=> otp", otp, err) + assert.Nil(t, err) + assert.NotEmpty(t, otp.Otp) + otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ + PhoneNumber: &phoneNumber, + Otp: otp.Otp, + }) + assert.Nil(t, err) + assert.NotEmpty(t, otpRes.Message) res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{ PhoneNumber: "1234567890", Password: s.TestInfo.Password, From 60777026261a56fa61e7e95d4c66ca0cedd74cf4 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 07:29:29 +0530 Subject: [PATCH 18/37] fix: tests for otp refactor --- server/db/models/otp.go | 2 +- server/db/providers/arangodb/provider.go | 6 +----- server/db/providers/cassandradb/provider.go | 8 ++++++++ server/db/providers/dynamodb/otp.go | 2 +- server/db/providers/dynamodb/provider.go | 2 +- server/go.mod | 5 +++-- server/go.sum | 19 +++++++++++++++++++ server/resolvers/mobile_login.go | 2 -- server/resolvers/mobile_signup.go | 2 -- ...{resolvers_test.go => integration_test.go} | 6 +++++- server/test/mobile_signup_test.go | 2 -- server/test/update_webhook_test.go | 6 +++--- server/test/webhook_test.go | 2 +- server/test/webhooks_test.go | 2 +- 14 files changed, 44 insertions(+), 22 deletions(-) rename server/test/{resolvers_test.go => integration_test.go} (93%) diff --git a/server/db/models/otp.go b/server/db/models/otp.go index 8ccb13e..bd0b41c 100644 --- a/server/db/models/otp.go +++ b/server/db/models/otp.go @@ -12,7 +12,7 @@ type OTP struct { Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"` - PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"` + PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"` Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"` ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 2dd7b28..979d56e 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -229,11 +229,7 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } - otpCollection.EnsureHashIndex(ctx, []string{"email"}, &arangoDriver.EnsureHashIndexOptions{ - Unique: true, - Sparse: true, - }) - otpCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{ + otpCollection.EnsureHashIndex(ctx, []string{models.FieldNameEmail, models.FieldNamePhoneNumber}, &arangoDriver.EnsureHashIndexOptions{ Unique: true, Sparse: true, }) diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go index 1c989be..6f1fe6b 100644 --- a/server/db/providers/cassandradb/provider.go +++ b/server/db/providers/cassandradb/provider.go @@ -254,6 +254,14 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } + // Add phone_number column to otp table + otpAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (phone_number text);`, KeySpace, models.Collections.OTP) + err = session.Query(otpAlterQuery).Exec() + if err != nil { + log.Debug("Failed to alter table as column exists: ", err) + // continue + } + // Add phone number index otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP) err = session.Query(otpIndexQueryPhoneNumber).Exec() if err != nil { diff --git a/server/db/providers/dynamodb/otp.go b/server/db/providers/dynamodb/otp.go index bb55523..d4abf73 100644 --- a/server/db/providers/dynamodb/otp.go +++ b/server/db/providers/dynamodb/otp.go @@ -77,7 +77,7 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) var otps []models.OTP var otp models.OTP collection := p.db.Table(models.Collections.OTP) - err := collection.Scan().Index("phone_number").Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) + err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps) if err != nil { return nil, err } diff --git a/server/db/providers/dynamodb/provider.go b/server/db/providers/dynamodb/provider.go index 4bf3345..7935e37 100644 --- a/server/db/providers/dynamodb/provider.go +++ b/server/db/providers/dynamodb/provider.go @@ -31,11 +31,11 @@ func NewProvider() (*provider, error) { if awsRegion != "" { config.Region = aws.String(awsRegion) } - // custom awsAccessKeyID, awsSecretAccessKey took first priority, if not then fetch config from aws credentials if awsAccessKeyID != "" && awsSecretAccessKey != "" { config.Credentials = credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, "") } else if dbURL != "" { + log.Debug("Tring to use database url for dynamodb") // static config in case of testing or local-setup config.Credentials = credentials.NewStaticCredentials("key", "key", "") config.Endpoint = aws.String(dbURL) diff --git a/server/go.mod b/server/go.mod index 3408404..62a3227 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/99designs/gqlgen v0.17.20 github.com/arangodb/go-driver v1.2.1 - github.com/aws/aws-sdk-go v1.44.109 + github.com/aws/aws-sdk-go v1.44.298 github.com/coreos/go-oidc/v3 v3.1.0 github.com/couchbase/gocb/v2 v2.6.0 github.com/gin-gonic/gin v1.8.1 @@ -13,11 +13,12 @@ require ( github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/goccy/go-json v0.9.11 // indirect github.com/gocql/gocql v1.2.0 + github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.6 // indirect github.com/google/uuid v1.3.0 - github.com/guregu/dynamo v1.16.0 + github.com/guregu/dynamo v1.20.0 github.com/joho/godotenv v1.3.0 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect diff --git a/server/go.sum b/server/go.sum index 224e06d..e8387ab 100644 --- a/server/go.sum +++ b/server/go.sum @@ -54,6 +54,8 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdK github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= +github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= @@ -65,6 +67,8 @@ github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -208,6 +212,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c= github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= +github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= +github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -442,8 +448,11 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -464,6 +473,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -508,12 +519,17 @@ golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -523,8 +539,11 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 8368745..bfef56c 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -100,8 +100,6 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } - fmt.Println("=> disablePhoneVerification", disablePhoneVerification) - if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 610b238..5cf1029 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -92,7 +92,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) if err != nil { log.Debug("Failed to get user by email: ", err) } - if existingUser != nil { if existingUser.PhoneNumberVerifiedAt != nil { // email is verified @@ -196,7 +195,6 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - fmt.Println("=> disablePhoneVerification signup", disablePhoneVerification) if !disablePhoneVerification { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/test/resolvers_test.go b/server/test/integration_test.go similarity index 93% rename from server/test/resolvers_test.go rename to server/test/integration_test.go index ecda491..9c9dfa2 100644 --- a/server/test/resolvers_test.go +++ b/server/test/integration_test.go @@ -46,7 +46,6 @@ func TestResolvers(t *testing.T) { for dbType, dbURL := range databases { ctx := context.Background() - memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseType, dbType) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseName, testDb) @@ -57,6 +56,11 @@ func TestResolvers(t *testing.T) { if dbType == constants.DbTypeDynamoDB { memorystore.Provider.UpdateEnvVariable(constants.EnvAwsRegion, "ap-south-1") os.Setenv(constants.EnvAwsRegion, "ap-south-1") + os.Unsetenv(constants.EnvAwsAccessKeyID) + os.Unsetenv(constants.EnvAwsSecretAccessKey) + // Remove aws credentials from env, so that local dynamodb can be used + memorystore.Provider.UpdateEnvVariable(constants.EnvAwsAccessKeyID, "") + memorystore.Provider.UpdateEnvVariable(constants.EnvAwsSecretAccessKey, "") } if dbType == constants.DbTypeCouchbaseDB { memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseUsername, "Administrator") diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 56e96a8..8169d9e 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -1,7 +1,6 @@ package test import ( - "fmt" "testing" "github.com/authorizerdev/authorizer/server/constants" @@ -78,7 +77,6 @@ func mobileSingupTest(t *testing.T, s TestSetup) { assert.True(t, *res.ShouldShowOtpScreen) // Verify with otp otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) - fmt.Println("=> otp", otp, err) assert.Nil(t, err) assert.NotEmpty(t, otp.Otp) otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ diff --git a/server/test/update_webhook_test.go b/server/test/update_webhook_test.go index 14ccb94..6e2d023 100644 --- a/server/test/update_webhook_test.go +++ b/server/test/update_webhook_test.go @@ -27,7 +27,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, webhooks) - assert.Equal(t, 2, len(webhooks)) + assert.GreaterOrEqual(t, len(webhooks), 2) for _, webhook := range webhooks { // it should completely replace headers webhook.Headers = map[string]interface{}{ @@ -58,7 +58,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { // Check if webhooks with new name is as per expected len accessWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserAccessEnabledWebhookEvent) assert.NoError(t, err) - assert.Equal(t, 3, len(accessWebhooks)) + assert.GreaterOrEqual(t, len(accessWebhooks), 3) // Revert name change res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{ ID: w.ID, @@ -69,7 +69,7 @@ func updateWebhookTest(t *testing.T, s TestSetup) { updatedWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, updatedWebhooks) - assert.Equal(t, 2, len(updatedWebhooks)) + assert.GreaterOrEqual(t, len(updatedWebhooks), 2) for _, updatedWebhook := range updatedWebhooks { assert.Contains(t, refs.StringValue(updatedWebhook.EventName), constants.UserDeletedWebhookEvent) assert.Len(t, updatedWebhook.Headers, 1) diff --git a/server/test/webhook_test.go b/server/test/webhook_test.go index 0fb789f..a556f9d 100644 --- a/server/test/webhook_test.go +++ b/server/test/webhook_test.go @@ -28,7 +28,7 @@ func webhookTest(t *testing.T, s TestSetup) { webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent) assert.NoError(t, err) assert.NotNil(t, webhooks) - assert.Equal(t, 2, len(webhooks)) + assert.GreaterOrEqual(t, len(webhooks), 2) for _, webhook := range webhooks { res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{ ID: webhook.ID, diff --git a/server/test/webhooks_test.go b/server/test/webhooks_test.go index 6ed1bb2..74cad74 100644 --- a/server/test/webhooks_test.go +++ b/server/test/webhooks_test.go @@ -30,6 +30,6 @@ func webhooksTest(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotEmpty(t, webhooks) - assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes)*2) + assert.GreaterOrEqual(t, len(webhooks.Webhooks), len(s.TestInfo.TestWebhookEventTypes)*2) }) } From 27e3ed82e41c29b781898bb218b9e62fb51b7f21 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 10:03:37 +0530 Subject: [PATCH 19/37] Update resend otp --- .env.test | 4 + server/constants/env.go | 13 ++-- server/env/env.go | 49 ++++++++---- server/env/persist_env.go | 2 +- server/go.mod | 1 - server/go.sum | 15 ---- server/graph/generated/generated.go | 15 +++- server/graph/model/models_gen.go | 5 +- server/graph/schema.graphqls | 3 +- server/memorystore/memory_store.go | 1 + server/memorystore/providers/redis/store.go | 2 +- server/resolvers/login.go | 2 +- server/resolvers/mobile_login.go | 71 +++++------------- server/resolvers/mobile_signup.go | 6 +- server/resolvers/resend_otp.go | 83 ++++++++++++++------- server/resolvers/update_env.go | 7 ++ server/smsproviders/twilio.go | 3 +- server/test/resend_otp_test.go | 4 +- server/test/test.go | 4 + server/utils/webhook.go | 2 + 20 files changed, 162 insertions(+), 130 deletions(-) diff --git a/.env.test b/.env.test index 99c8081..293248a 100644 --- a/.env.test +++ b/.env.test @@ -7,5 +7,9 @@ SMTP_PORT=2525 SMTP_USERNAME=test SMTP_PASSWORD=test SENDER_EMAIL="info@authorizer.dev" +TWILIO_API_KEY=test +TWILIO_API_SECRET=test +TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +TWILIO_SENDER=909921212112 SENDER_NAME="Authorizer" AWS_REGION=ap-south-1 \ No newline at end of file diff --git a/server/constants/env.go b/server/constants/env.go index 0f26ede..74b9d36 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -66,6 +66,8 @@ const ( EnvKeySenderName = "SENDER_NAME" // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED" + // EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED + EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED" // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE EnvKeyAppCookieSecure = "APP_COOKIE_SECURE" // EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE @@ -158,6 +160,9 @@ const ( // EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION // this variable is used to completely disable multi factor authentication. It will have no effect on profile preference EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION" + // EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION + // this variable is used to disable phone verification + EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" // Slice variables // EnvKeyRoles key for env variable ROLES @@ -177,17 +182,13 @@ const ( // This env is used for setting default response mode in authorize handler EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE" - // Phone verification setting - EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" - // Twilio env variables - // EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY EnvKeyTwilioAPIKey = "TWILIO_API_KEY" // EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET EnvKeyTwilioAPISecret = "TWILIO_API_SECRET" // EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID" - // EnvKeyTwilioSenderFrom key for env variable TWILIO_SENDER_FROM - EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM" + // EnvKeyTwilioSender key for env variable TWILIO_SENDER + EnvKeyTwilioSender = "TWILIO_SENDER" ) diff --git a/server/env/env.go b/server/env/env.go index f61b093..8525927 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -104,6 +104,13 @@ func InitAllEnv() error { osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword) osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication) osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication) + // phone verification var + osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification) + // twilio vars + osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey) + osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret) + osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID) + osTwilioSender := os.Getenv(constants.EnvKeyTwilioSender) // os slice vars osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins) @@ -111,15 +118,6 @@ func InitAllEnv() error { osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles) osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles) - // phone verification var - osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification) - - // twilio vars - osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey) - osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret) - osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID) - osTwilioSenderFrom := os.Getenv(constants.EnvKeyTwilioSenderFrom) - ienv, ok := envData[constants.EnvKeyEnv] if !ok || ienv == "" { envData[constants.EnvKeyEnv] = osEnv @@ -145,7 +143,7 @@ func InitAllEnv() error { if val, ok := envData[constants.EnvAwsRegion]; !ok || val == "" { envData[constants.EnvAwsRegion] = osAwsRegion } - + if osAwsRegion != "" && envData[constants.EnvAwsRegion] != osAwsRegion { envData[constants.EnvAwsRegion] = osAwsRegion } @@ -691,11 +689,11 @@ func InitAllEnv() error { envData[constants.EnvKeyIsEmailServiceEnabled] = false } - if envData[constants.EnvKeySmtpHost] != "" || envData[constants.EnvKeySmtpUsername] != "" || envData[constants.EnvKeySmtpPassword] != "" || envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" { + if envData[constants.EnvKeySmtpHost] != "" && envData[constants.EnvKeySmtpUsername] != "" && envData[constants.EnvKeySmtpPassword] != "" && envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" { envData[constants.EnvKeyIsEmailServiceEnabled] = true } - if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) { + if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) && !envData[constants.EnvKeyIsSMSServiceEnabled].(bool) { return errors.New("to enable multi factor authentication, please enable email service") } @@ -777,29 +775,39 @@ func InitAllEnv() error { envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode } + if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" { + envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret + } if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret { envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret } + if val, ok := envData[constants.EnvKeyTwilioAPIKey]; !ok || val == "" { + envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey + } if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey { envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey } + if val, ok := envData[constants.EnvKeyTwilioAccountSID]; !ok || val == "" { + envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid + } if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid { envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid } - if osTwilioSenderFrom != "" && envData[constants.EnvKeyTwilioSenderFrom] != osTwilioSenderFrom { - envData[constants.EnvKeyTwilioSenderFrom] = osTwilioSenderFrom + if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" { + envData[constants.EnvKeyTwilioSender] = osTwilioSender + } + if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender { + envData[constants.EnvKeyTwilioSender] = osTwilioSender } if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok { envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false" } - if osDisablePhoneVerification != "" { boolValue, err := strconv.ParseBool(osDisablePhoneVerification) - if err != nil { return err } @@ -808,6 +816,15 @@ func InitAllEnv() error { } } + if envData[constants.EnvKeyTwilioAPIKey] == "" || envData[constants.EnvKeyTwilioAPISecret] == "" || envData[constants.EnvKeyTwilioAccountSID] == "" || envData[constants.EnvKeyTwilioSender] == "" { + envData[constants.EnvKeyDisablePhoneVerification] = true + envData[constants.EnvKeyIsSMSServiceEnabled] = false + } + if envData[constants.EnvKeyTwilioAPIKey] != "" && envData[constants.EnvKeyTwilioAPISecret] != "" && envData[constants.EnvKeyTwilioAccountSID] != "" && envData[constants.EnvKeyTwilioSender] != "" { + envData[constants.EnvKeyDisablePhoneVerification] = false + envData[constants.EnvKeyIsSMSServiceEnabled] = true + } + err = memorystore.Provider.UpdateEnvStore(envData) if err != nil { log.Debug("Error while updating env store: ", err) diff --git a/server/env/persist_env.go b/server/env/persist_env.go index 8ba33f2..719c91d 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -200,7 +200,7 @@ func PersistEnv() error { envValue := strings.TrimSpace(os.Getenv(key)) if envValue != "" { switch key { - case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification: + case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification: if envValueBool, err := strconv.ParseBool(envValue); err == nil { if value.(bool) != envValueBool { storeData[key] = envValueBool diff --git a/server/go.mod b/server/go.mod index 62a3227..0d50507 100644 --- a/server/go.mod +++ b/server/go.mod @@ -13,7 +13,6 @@ require ( github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/goccy/go-json v0.9.11 // indirect github.com/gocql/gocql v1.2.0 - github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.6 // indirect diff --git a/server/go.sum b/server/go.sum index e8387ab..4a2c928 100644 --- a/server/go.sum +++ b/server/go.sum @@ -51,9 +51,6 @@ github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2 github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= -github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= -github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= @@ -65,8 +62,6 @@ github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -134,8 +129,6 @@ github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE= github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= -github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= @@ -210,8 +203,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c= -github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= @@ -444,12 +435,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -471,7 +459,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -520,7 +507,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -540,7 +526,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index b2493ef..3b46684 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -2719,7 +2719,8 @@ input VerifyOTPRequest { } input ResendOTPRequest { - email: String! + email: String + phone_number: String # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token @@ -16375,7 +16376,7 @@ func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"email", "state"} + fieldsInOrder := [...]string{"email", "phone_number", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -16386,7 +16387,15 @@ func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email")) - it.Email, err = ec.unmarshalNString2string(ctx, v) + it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "phone_number": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number")) + it.PhoneNumber, err = ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 7621995..8bd0edc 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -245,8 +245,9 @@ type PaginationInput struct { } type ResendOTPRequest struct { - Email string `json:"email"` - State *string `json:"state"` + Email *string `json:"email"` + PhoneNumber *string `json:"phone_number"` + State *string `json:"state"` } type ResendVerifyEmailInput struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index bb83b9b..106d561 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -549,7 +549,8 @@ input VerifyOTPRequest { } input ResendOTPRequest { - email: String! + email: String + phone_number: String # state is used for authorization code grant flow # it is used to get code for an on-going auth process during login # and use that code for setting `c_hash` in id_token diff --git a/server/memorystore/memory_store.go b/server/memorystore/memory_store.go index 4285860..2b3c9b2 100644 --- a/server/memorystore/memory_store.go +++ b/server/memorystore/memory_store.go @@ -33,6 +33,7 @@ func InitMemStore() error { constants.EnvKeyDisableSignUp: false, constants.EnvKeyDisableStrongPassword: false, constants.EnvKeyIsEmailServiceEnabled: false, + constants.EnvKeyIsSMSServiceEnabled: false, constants.EnvKeyEnforceMultiFactorAuthentication: false, constants.EnvKeyDisableMultiFactorAuthentication: false, constants.EnvKeyAppCookieSecure: true, diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go index 63e3e37..d42e2c0 100644 --- a/server/memorystore/providers/redis/store.go +++ b/server/memorystore/providers/redis/store.go @@ -176,7 +176,7 @@ func (c *provider) GetEnvStore() (map[string]interface{}, error) { return nil, err } for key, value := range data { - if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure { + if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyIsSMSServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure { boolValue, err := strconv.ParseBool(value) if err != nil { return res, err diff --git a/server/resolvers/login.go b/server/resolvers/login.go index e05d012..667e895 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -106,7 +106,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes } isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) - if err != nil || !isEmailServiceEnabled { + if err != nil || !isMFADisabled { log.Debug("MFA service not enabled: ", err) } diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index bfef56c..749b00f 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -95,24 +95,33 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m roles = params.Roles } - disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + disablePhoneVerification, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + if err != nil { + log.Debug("Error getting disable phone verification: ", err) + } if disablePhoneVerification { now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } - if !disablePhoneVerification { + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("SMS service not enabled: ", err) + } + if disablePhoneVerification { + now := time.Now().Unix() + user.PhoneNumberVerifiedAt = &now + } + isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) + if err != nil || !isMFADisabled { + log.Debug("MFA service not enabled: ", err) + } + if !disablePhoneVerification && isSMSServiceEnabled && !isMFADisabled { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() smsBody := strings.Builder{} smsBody.WriteString("Your verification code is: ") smsBody.WriteString(smsCode) - - // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api - if err != nil { - log.Debug("error while upserting user: ", err.Error()) - return nil, err - } _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ PhoneNumber: params.PhoneNumber, Otp: smsCode, @@ -123,7 +132,7 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m return nil, err } go func() { - + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, *user) smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) }() return &model.AuthResponse{ @@ -137,50 +146,6 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m scope = params.Scope } - /* - // TODO use sms authentication for MFA - isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) - if err != nil || !isEmailServiceEnabled { - log.Debug("Email service not enabled: ", err) - } - - isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) - if err != nil || !isEmailServiceEnabled { - log.Debug("MFA service not enabled: ", err) - } - - // If email service is not enabled continue the process in any way - if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled { - otp := utils.GenerateOTP() - otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{ - Email: user.Email, - Otp: otp, - ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), - }) - if err != nil { - log.Debug("Failed to add otp: ", err) - return nil, err - } - - go func() { - // exec it as go routine so that we can reduce the api latency - go email.SendEmail([]string{params.PhoneNumber}, constants.VerificationTypeOTP, map[string]interface{}{ - "user": user.ToMap(), - "organization": utils.GetOrganization(), - "otp": otpData.Otp, - }) - if err != nil { - log.Debug("Failed to send otp email: ", err) - } - }() - - return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), - }, nil - } - */ - code := "" codeChallenge := "" nonce := "" diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 5cf1029..a00c440 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -187,6 +187,10 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) now := time.Now().Unix() user.PhoneNumberVerifiedAt = &now } + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("SMS service not enabled: ", err) + } user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth user, err = db.Provider.AddUser(ctx, user) @@ -195,7 +199,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) log.Debug("Failed to add user: ", err) return res, err } - if !disablePhoneVerification { + if !disablePhoneVerification && isSMSServiceEnabled { duration, _ := time.ParseDuration("10m") smsCode := utils.GenerateOTP() diff --git a/server/resolvers/resend_otp.go b/server/resolvers/resend_otp.go index 65d9cf1..dafe9dd 100644 --- a/server/resolvers/resend_otp.go +++ b/server/resolvers/resend_otp.go @@ -12,23 +12,49 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" - "github.com/authorizerdev/authorizer/server/email" + emailHelper "github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" + "github.com/authorizerdev/authorizer/server/smsproviders" "github.com/authorizerdev/authorizer/server/utils" ) // ResendOTPResolver is a resolver for resend otp mutation func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) { + email := strings.ToLower(strings.Trim(refs.StringValue(params.Email), " ")) + phoneNumber := strings.Trim(refs.StringValue(params.PhoneNumber), " ") log := log.WithFields(log.Fields{ - "email": params.Email, + "email": email, + "phone_number": phoneNumber, }) - params.Email = strings.ToLower(params.Email) - user, err := db.Provider.GetUserByEmail(ctx, params.Email) + if email == "" && phoneNumber == "" { + log.Debug("Email or phone number is required") + return nil, errors.New("email or phone number is required") + } + var user models.User + var err error + if email != "" { + isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) + if err != nil || !isEmailServiceEnabled { + log.Debug("Email service not enabled: ", err) + return nil, errors.New("email service not enabled") + } + user, err = db.Provider.GetUserByEmail(ctx, email) + } else { + isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) + if err != nil || !isSMSServiceEnabled { + log.Debug("Email service not enabled: ", err) + return nil, errors.New("email service not enabled") + } + // TODO fix after refs fixes + var u *models.User + u, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) + user = *u + } if err != nil { log.Debug("Failed to get user by email: ", err) - return nil, fmt.Errorf(`user with this email not found`) + return nil, fmt.Errorf(`user with this email/phone not found`) } if user.RevokedTimestamp != nil { @@ -36,35 +62,38 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod return nil, fmt.Errorf(`user access has been revoked`) } - if user.EmailVerifiedAt == nil { + if email != "" && user.EmailVerifiedAt == nil { log.Debug("User email is not verified") return nil, fmt.Errorf(`email not verified`) } + if phoneNumber != "" && user.PhoneNumberVerifiedAt == nil { + log.Debug("User phone number is not verified") + return nil, fmt.Errorf(`phone number not verified`) + } + if !refs.BoolValue(user.IsMultiFactorAuthEnabled) { log.Debug("User multi factor authentication is not enabled") return nil, fmt.Errorf(`multi factor authentication not enabled`) } - isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) - if err != nil || !isEmailServiceEnabled { - log.Debug("Email service not enabled: ", err) - return nil, errors.New("email service not enabled") - } - isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication) if err != nil || isMFADisabled { log.Debug("MFA service not enabled: ", err) return nil, errors.New("multi factor authentication is disabled for this instance") } - // get otp by email - otpData, err := db.Provider.GetOTPByEmail(ctx, params.Email) + // get otp by email or phone number + var otpData *models.OTP + if email != "" { + otpData, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email)) + } else { + otpData, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) + } if err != nil { log.Debug("Failed to get otp for given email: ", err) return nil, err } - if otpData == nil { log.Debug("No otp found for given email: ", params.Email) return &model.Response{ @@ -73,28 +102,30 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod } otp := utils.GenerateOTP() - otpData, err = db.Provider.UpsertOTP(ctx, &models.OTP{ + if _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ Email: user.Email, Otp: otp, ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), - }) - if err != nil { - log.Debug("Error generating new otp: ", err) + }); err != nil { + log.Debug("Error upserting otp: ", err) return nil, err } - go func() { + if email != "" { // exec it as go routine so that we can reduce the api latency - go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{ + go emailHelper.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{ "user": user.ToMap(), "organization": utils.GetOrganization(), "otp": otp, }) - if err != nil { - log.Debug("Error sending otp email: ", otp) - } - }() - + } else { + smsBody := strings.Builder{} + smsBody.WriteString("Your verification code is: ") + smsBody.WriteString(otp) + // exec it as go routine so that we can reduce the api latency + go smsproviders.SendSMS(phoneNumber, smsBody.String()) + } + log.Info("OTP has been resent") return &model.Response{ Message: `OTP has been sent. Please check your inbox`, }, nil diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index d9d6881..437565e 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -267,6 +267,13 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model updatedData[constants.EnvKeyIsEmailServiceEnabled] = true } + if updatedData[constants.EnvKeyTwilioAPIKey] == "" || updatedData[constants.EnvKeyTwilioAPISecret] == "" || updatedData[constants.EnvKeyTwilioAccountSID] == "" || updatedData[constants.EnvKeyTwilioSender] == "" { + updatedData[constants.EnvKeyIsSMSServiceEnabled] = false + if !updatedData[constants.EnvKeyIsSMSServiceEnabled].(bool) { + updatedData[constants.EnvKeyDisablePhoneVerification] = true + } + } + if !currentData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) { go db.Provider.UpdateUsers(ctx, map[string]interface{}{ "is_multi_factor_auth_enabled": true, diff --git a/server/smsproviders/twilio.go b/server/smsproviders/twilio.go index 900be6d..f4f1acb 100644 --- a/server/smsproviders/twilio.go +++ b/server/smsproviders/twilio.go @@ -8,6 +8,7 @@ import ( api "github.com/twilio/twilio-go/rest/api/v2010" ) +// SendSMS util to send sms // TODO: Should be restructured to interface when another provider is added func SendSMS(sendTo, messageBody string) error { twilioAPISecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPISecret) @@ -20,7 +21,7 @@ func SendSMS(sendTo, messageBody string) error { log.Debug("Failed to get api key: ", err) return err } - twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSenderFrom) + twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSender) if err != nil || twilioSenderFrom == "" { log.Debug("Failed to get sender: ", err) return err diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go index eb6993f..1550957 100644 --- a/server/test/resend_otp_test.go +++ b/server/test/resend_otp_test.go @@ -51,7 +51,7 @@ func resendOTPTest(t *testing.T, s TestSetup) { assert.NotNil(t, updateRes) // Resend otp should return error as no initial opt is being sent resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{ - Email: email, + Email: refs.NewStringRef(email), }) assert.Error(t, err) assert.Nil(t, resendOtpRes) @@ -72,7 +72,7 @@ func resendOTPTest(t *testing.T, s TestSetup) { // resend otp resendOtpRes, err = resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{ - Email: email, + Email: refs.NewStringRef(email), }) assert.NoError(t, err) assert.NotEmpty(t, resendOtpRes.Message) diff --git a/server/test/test.go b/server/test/test.go index b2727ea..217ad39 100644 --- a/server/test/test.go +++ b/server/test/test.go @@ -126,6 +126,10 @@ func testSetup() TestSetup { memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpPassword, "test") memorystore.Provider.UpdateEnvVariable(constants.EnvKeySenderEmail, "info@yopmail.com") memorystore.Provider.UpdateEnvVariable(constants.EnvKeyProtectedRoles, "admin") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPIKey, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPISecret, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAccountSID, "test") + memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioSender, "1234567890") err = db.InitDB() if err != nil { diff --git a/server/utils/webhook.go b/server/utils/webhook.go index 705c571..4c6fbd0 100644 --- a/server/utils/webhook.go +++ b/server/utils/webhook.go @@ -16,6 +16,8 @@ import ( log "github.com/sirupsen/logrus" ) +// RegisterEvent util to register event +// TODO change user to user ref func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error { webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName) if err != nil { From 2a2b7abc087b9693c0b61031f1ae97e9a28ec280 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 11:23:24 +0530 Subject: [PATCH 20/37] Add optional show_mobile_otp_screen --- server/graph/generated/generated.go | 130 +++++++++++++++++++++------- server/graph/model/models_gen.go | 15 ++-- server/graph/schema.graphqls | 3 +- server/resolvers/login.go | 4 +- server/resolvers/mobile_login.go | 4 +- server/resolvers/mobile_signup.go | 4 +- server/test/mobile_signup_test.go | 2 +- 7 files changed, 116 insertions(+), 46 deletions(-) diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 3b46684..887207c 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -45,13 +45,14 @@ type DirectiveRoot struct { type ComplexityRoot struct { AuthResponse struct { - AccessToken func(childComplexity int) int - ExpiresIn func(childComplexity int) int - IDToken func(childComplexity int) int - Message func(childComplexity int) int - RefreshToken func(childComplexity int) int - ShouldShowOtpScreen func(childComplexity int) int - User func(childComplexity int) int + AccessToken func(childComplexity int) int + ExpiresIn func(childComplexity int) int + IDToken func(childComplexity int) int + Message func(childComplexity int) int + RefreshToken func(childComplexity int) int + ShouldShowEmailOtpScreen func(childComplexity int) int + ShouldShowMobileOtpScreen func(childComplexity int) int + User func(childComplexity int) int } EmailTemplate struct { @@ -428,12 +429,19 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.AuthResponse.RefreshToken(childComplexity), true - case "AuthResponse.should_show_otp_screen": - if e.complexity.AuthResponse.ShouldShowOtpScreen == nil { + case "AuthResponse.should_show_email_otp_screen": + if e.complexity.AuthResponse.ShouldShowEmailOtpScreen == nil { break } - return e.complexity.AuthResponse.ShouldShowOtpScreen(childComplexity), true + return e.complexity.AuthResponse.ShouldShowEmailOtpScreen(childComplexity), true + + case "AuthResponse.should_show_mobile_otp_screen": + if e.complexity.AuthResponse.ShouldShowMobileOtpScreen == nil { + break + } + + return e.complexity.AuthResponse.ShouldShowMobileOtpScreen(childComplexity), true case "AuthResponse.user": if e.complexity.AuthResponse.User == nil { @@ -2261,7 +2269,8 @@ type Error { type AuthResponse { message: String! - should_show_otp_screen: Boolean + should_show_email_otp_screen: Boolean + should_show_mobile_otp_screen: Boolean access_token: String id_token: String refresh_token: String @@ -3474,8 +3483,8 @@ func (ec *executionContext) fieldContext_AuthResponse_message(ctx context.Contex return fc, nil } -func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) +func (ec *executionContext) _AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) if err != nil { return graphql.Null } @@ -3488,7 +3497,7 @@ func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Con }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ShouldShowOtpScreen, nil + return obj.ShouldShowEmailOtpScreen, nil }) if err != nil { ec.Error(ctx, err) @@ -3502,7 +3511,48 @@ func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Con return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_AuthResponse_should_show_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuthResponse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ShouldShowMobileOtpScreen, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "AuthResponse", Field: field, @@ -7756,8 +7806,10 @@ func (ec *executionContext) fieldContext_Mutation_signup(ctx context.Context, fi switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7827,8 +7879,10 @@ func (ec *executionContext) fieldContext_Mutation_mobile_signup(ctx context.Cont switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7898,8 +7952,10 @@ func (ec *executionContext) fieldContext_Mutation_login(ctx context.Context, fie switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -7969,8 +8025,10 @@ func (ec *executionContext) fieldContext_Mutation_mobile_login(ctx context.Conte switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -8206,8 +8264,10 @@ func (ec *executionContext) fieldContext_Mutation_verify_email(ctx context.Conte switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -8513,8 +8573,10 @@ func (ec *executionContext) fieldContext_Mutation_verify_otp(ctx context.Context switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -9931,8 +9993,10 @@ func (ec *executionContext) fieldContext_Query_session(ctx context.Context, fiel switch field.Name { case "message": return ec.fieldContext_AuthResponse_message(ctx, field) - case "should_show_otp_screen": - return ec.fieldContext_AuthResponse_should_show_otp_screen(ctx, field) + case "should_show_email_otp_screen": + return ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field) + case "should_show_mobile_otp_screen": + return ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field) case "access_token": return ec.fieldContext_AuthResponse_access_token(ctx, field) case "id_token": @@ -17790,9 +17854,13 @@ func (ec *executionContext) _AuthResponse(ctx context.Context, sel ast.Selection if out.Values[i] == graphql.Null { invalids++ } - case "should_show_otp_screen": + case "should_show_email_otp_screen": - out.Values[i] = ec._AuthResponse_should_show_otp_screen(ctx, field, obj) + out.Values[i] = ec._AuthResponse_should_show_email_otp_screen(ctx, field, obj) + + case "should_show_mobile_otp_screen": + + out.Values[i] = ec._AuthResponse_should_show_mobile_otp_screen(ctx, field, obj) case "access_token": diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 8bd0edc..d6139c9 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -26,13 +26,14 @@ type AdminSignupInput struct { } type AuthResponse struct { - Message string `json:"message"` - ShouldShowOtpScreen *bool `json:"should_show_otp_screen"` - AccessToken *string `json:"access_token"` - IDToken *string `json:"id_token"` - RefreshToken *string `json:"refresh_token"` - ExpiresIn *int64 `json:"expires_in"` - User *User `json:"user"` + Message string `json:"message"` + ShouldShowEmailOtpScreen *bool `json:"should_show_email_otp_screen"` + ShouldShowMobileOtpScreen *bool `json:"should_show_mobile_otp_screen"` + AccessToken *string `json:"access_token"` + IDToken *string `json:"id_token"` + RefreshToken *string `json:"refresh_token"` + ExpiresIn *int64 `json:"expires_in"` + User *User `json:"user"` } type DeleteEmailTemplateRequest struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 106d561..7ceef43 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -91,7 +91,8 @@ type Error { type AuthResponse { message: String! - should_show_otp_screen: Boolean + should_show_email_otp_screen: Boolean + should_show_mobile_otp_screen: Boolean access_token: String id_token: String refresh_token: String diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 667e895..299c6ef 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -145,8 +145,8 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes }() return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP in your inbox", + ShouldShowEmailOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index 749b00f..fc131b0 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -136,8 +136,8 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) }() return &model.AuthResponse{ - Message: "Please check the OTP", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP", + ShouldShowMobileOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index a00c440..70b6d60 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -225,8 +225,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) smsproviders.SendSMS(mobile, smsBody.String()) }() return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowOtpScreen: refs.NewBoolRef(true), + Message: "Please check the OTP in your inbox", + ShouldShowMobileOtpScreen: refs.NewBoolRef(true), }, nil } diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index 8169d9e..c93472f 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -74,7 +74,7 @@ func mobileSingupTest(t *testing.T, s TestSetup) { }) assert.NoError(t, err) assert.NotNil(t, res) - assert.True(t, *res.ShouldShowOtpScreen) + assert.True(t, *res.ShouldShowMobileOtpScreen) // Verify with otp otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.Nil(t, err) From 80f3698f0668aba6b527ae3c091590304b0d2543 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 11:30:43 +0530 Subject: [PATCH 21/37] [app] bump authorizer-react 1.1.12 --- app/package-lock.json | 58 +++++++++++++++++++++---------------------- app/package.json | 2 +- app/yarn.lock | 34 ++++++++++++------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index cf332cb..efba452 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.11", + "@authorizerdev/authorizer-react": "^1.1.12", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", - "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", + "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -41,11 +41,11 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", - "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", + "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.2.3" + "@authorizerdev/authorizer-js": "^1.2.5" }, "engines": { "node": ">=10" @@ -406,11 +406,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "dependencies": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.12" } }, "node_modules/css-color-keywords": { @@ -567,9 +567,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -837,19 +837,19 @@ }, "dependencies": { "@authorizerdev/authorizer-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", - "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", + "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", "requires": { "cross-fetch": "^3.1.5" } }, "@authorizerdev/authorizer-react": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", - "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", + "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", "requires": { - "@authorizerdev/authorizer-js": "^1.2.3" + "@authorizerdev/authorizer-js": "^1.2.5" } }, "@babel/code-frame": { @@ -1144,11 +1144,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "requires": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.12" } }, "css-color-keywords": { @@ -1270,9 +1270,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "requires": { "whatwg-url": "^5.0.0" } diff --git a/app/package.json b/app/package.json index 1225346..fa9b74a 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.11", + "@authorizerdev/authorizer-react": "^1.1.12", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/yarn.lock b/app/yarn.lock index 380f761..16c1059 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2,19 +2,19 @@ # yarn lockfile v1 -"@authorizerdev/authorizer-js@^1.2.3": - "integrity" "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz" - "version" "1.2.3" +"@authorizerdev/authorizer-js@^1.2.5": + "integrity" "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz" + "version" "1.2.5" dependencies: "cross-fetch" "^3.1.5" -"@authorizerdev/authorizer-react@^1.1.11": - "integrity" "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz" - "version" "1.1.11" +"@authorizerdev/authorizer-react@^1.1.12": + "integrity" "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz" + "version" "1.1.12" dependencies: - "@authorizerdev/authorizer-js" "^1.2.3" + "@authorizerdev/authorizer-js" "^1.2.5" "@babel/code-frame@^7.16.7": "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" @@ -278,11 +278,11 @@ "version" "1.1.3" "cross-fetch@^3.1.5": - "integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==" - "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" - "version" "3.1.5" + "integrity" "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==" + "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz" + "version" "3.1.8" dependencies: - "node-fetch" "2.6.7" + "node-fetch" "^2.6.12" "css-color-keywords@^1.0.0": "integrity" "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" @@ -389,10 +389,10 @@ "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" "version" "2.1.2" -"node-fetch@2.6.7": - "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" - "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" - "version" "2.6.7" +"node-fetch@^2.6.12": + "integrity" "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==" + "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz" + "version" "2.6.12" dependencies: "whatwg-url" "^5.0.0" From 9f52c088832328017b72f2ea3404ac8bd9525775 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 23 Jul 2023 16:13:40 +0530 Subject: [PATCH 22/37] [app] bump authorizer-react 1.1.13 --- app/package-lock.json | 30 +++++++++++++++--------------- app/package.json | 2 +- app/yarn.lock | 18 +++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index efba452..1b7f5a4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.12", + "@authorizerdev/authorizer-react": "^1.1.13", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", - "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz", + "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -41,11 +41,11 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", - "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz", + "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.2.5" + "@authorizerdev/authorizer-js": "^1.2.6" }, "engines": { "node": ">=10" @@ -837,19 +837,19 @@ }, "dependencies": { "@authorizerdev/authorizer-js": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz", - "integrity": "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz", + "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==", "requires": { "cross-fetch": "^3.1.5" } }, "@authorizerdev/authorizer-react": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz", - "integrity": "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz", + "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==", "requires": { - "@authorizerdev/authorizer-js": "^1.2.5" + "@authorizerdev/authorizer-js": "^1.2.6" } }, "@babel/code-frame": { diff --git a/app/package.json b/app/package.json index fa9b74a..2406108 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.12", + "@authorizerdev/authorizer-react": "^1.1.13", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/yarn.lock b/app/yarn.lock index 16c1059..2be982c 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2,19 +2,19 @@ # yarn lockfile v1 -"@authorizerdev/authorizer-js@^1.2.5": - "integrity" "sha512-X855+gqw+xuyVxUkqJh98bi+XgZPupaIgLmURQdZo2jfRVDqnnCP5bAkNr37SyX67r+IMBoPndj6xkN8cwS91Q==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.5.tgz" - "version" "1.2.5" +"@authorizerdev/authorizer-js@^1.2.6": + "integrity" "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz" + "version" "1.2.6" dependencies: "cross-fetch" "^3.1.5" -"@authorizerdev/authorizer-react@^1.1.12": - "integrity" "sha512-CbwkUkcVNPJueY13QyPnXJOeJyJtgtBdycsqSXcxyh4iNrqnxkv9mFRxJn8G/o16jZWmPDH6lNSnZOIfLRKfLA==" - "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.12.tgz" - "version" "1.1.12" +"@authorizerdev/authorizer-react@^1.1.13": + "integrity" "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==" + "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz" + "version" "1.1.13" dependencies: - "@authorizerdev/authorizer-js" "^1.2.5" + "@authorizerdev/authorizer-js" "^1.2.6" "@babel/code-frame@^7.16.7": "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" From ba0cf189de056ca3f5fe1dab6af9e2b042638a5d Mon Sep 17 00:00:00 2001 From: catusax Date: Mon, 24 Jul 2023 11:58:36 +0800 Subject: [PATCH 23/37] userid ass mfa session key --- server/memorystore/providers/inmemory/store.go | 14 +++++++------- server/memorystore/providers/providers.go | 8 ++++---- server/memorystore/providers/redis/store.go | 16 ++++++++-------- server/resolvers/login.go | 2 +- server/resolvers/mobile_login.go | 12 +++++++++++- server/resolvers/verify_otp.go | 13 +++++++++++++ 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/server/memorystore/providers/inmemory/store.go b/server/memorystore/providers/inmemory/store.go index d03a9df..b20fb62 100644 --- a/server/memorystore/providers/inmemory/store.go +++ b/server/memorystore/providers/inmemory/store.go @@ -42,15 +42,15 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } -// SetMfaSession sets the mfa session with key and value of email -func (c *provider) SetMfaSession(email, key string, expiration int64) error { - c.mfasessionStore.Set(email, key, email, expiration) +// SetMfaSession sets the mfa session with key and value of userId +func (c *provider) SetMfaSession(userId, key string, expiration int64) error { + c.mfasessionStore.Set(userId, key, userId, expiration) return nil } // GetMfaSession returns value of given mfa session -func (c *provider) GetMfaSession(email, key string) (string, error) { - val := c.mfasessionStore.Get(email, key) +func (c *provider) GetMfaSession(userId, key string) (string, error) { + val := c.mfasessionStore.Get(userId, key) if val == "" { return "", fmt.Errorf("Not found") } @@ -58,8 +58,8 @@ func (c *provider) GetMfaSession(email, key string) (string, error) { } // DeleteMfaSession deletes given mfa session from in-memory store. -func (c *provider) DeleteMfaSession(email, key string) error { - c.mfasessionStore.Remove(email, key) +func (c *provider) DeleteMfaSession(userId, key string) error { + c.mfasessionStore.Remove(userId, key) return nil } diff --git a/server/memorystore/providers/providers.go b/server/memorystore/providers/providers.go index 6b3eba0..331e34a 100644 --- a/server/memorystore/providers/providers.go +++ b/server/memorystore/providers/providers.go @@ -12,12 +12,12 @@ type Provider interface { DeleteAllUserSessions(userId string) error // DeleteSessionForNamespace deletes the session for a given namespace DeleteSessionForNamespace(namespace string) error - // SetMfaSession sets the mfa session with key and value of email - SetMfaSession(email, key string, expiration int64) error + // SetMfaSession sets the mfa session with key and value of userId + SetMfaSession(userId, key string, expiration int64) error // GetMfaSession returns value of given mfa session - GetMfaSession(email, key string) (string, error) + GetMfaSession(userId, key string) (string, error) // DeleteMfaSession deletes given mfa session from in-memory store. - DeleteMfaSession(email, key string) error + DeleteMfaSession(userId, key string) error // SetState sets the login state (key, value form) in the session store SetState(key, state string) error diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go index d42e2c0..a6ff08f 100644 --- a/server/memorystore/providers/redis/store.go +++ b/server/memorystore/providers/redis/store.go @@ -93,12 +93,12 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error { return nil } -// SetMfaSession sets the mfa session with key and value of email -func (c *provider) SetMfaSession(email, key string, expiration int64) error { +// SetMfaSession sets the mfa session with key and value of userId +func (c *provider) SetMfaSession(userId, key string, expiration int64) error { currentTime := time.Now() expireTime := time.Unix(expiration, 0) duration := expireTime.Sub(currentTime) - err := c.store.Set(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key), email, duration).Err() + err := c.store.Set(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key), userId, duration).Err() if err != nil { log.Debug("Error saving user session to redis: ", err) return err @@ -106,9 +106,9 @@ func (c *provider) SetMfaSession(email, key string, expiration int64) error { return nil } - // GetMfaSession returns value of given mfa session -func (c *provider) GetMfaSession(email, key string) (string, error) { - data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Result() +// GetMfaSession returns value of given mfa session +func (c *provider) GetMfaSession(userId, key string) (string, error) { + data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Result() if err != nil { return "", err } @@ -116,8 +116,8 @@ func (c *provider) GetMfaSession(email, key string) (string, error) { } // DeleteMfaSession deletes given mfa session from in-memory store. -func (c *provider) DeleteMfaSession(email, key string) error { - if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, email, key)).Err(); err != nil { +func (c *provider) DeleteMfaSession(userId, key string) error { + if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Err(); err != nil { log.Debug("Error deleting user session from redis: ", err) // continue } diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 299c6ef..c588ca7 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -125,7 +125,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes } mfaSession := uuid.NewString() - err = memorystore.Provider.SetMfaSession(params.Email, mfaSession, expires) + err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires) if err != nil { log.Debug("Failed to add mfasession: ", err) return nil, err diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index fc131b0..89c3825 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -122,15 +122,25 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m smsBody := strings.Builder{} smsBody.WriteString("Your verification code is: ") smsBody.WriteString(smsCode) + expires := time.Now().Add(duration).Unix() _, err := db.Provider.UpsertOTP(ctx, &models.OTP{ PhoneNumber: params.PhoneNumber, Otp: smsCode, - ExpiresAt: time.Now().Add(duration).Unix(), + ExpiresAt: expires, }) if err != nil { log.Debug("error while upserting OTP: ", err.Error()) return nil, err } + + mfaSession := uuid.NewString() + err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires) + if err != nil { + log.Debug("Failed to add mfasession: ", err) + return nil, err + } + cookie.SetMfaSession(gc, mfaSession) + go func() { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, *user) smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 124ee3f..2982859 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -27,6 +27,13 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to get GinContext: ", err) return res, err } + + mfaSession, err := cookie.GetMfaSession(gc) + if err != nil { + log.Debug("Failed to get otp request by email: ", err) + return res, fmt.Errorf(`invalid session: %s`, err.Error()) + } + if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" { log.Debug("Email or phone number is required") return res, fmt.Errorf(`email or phone_number is required`) @@ -68,6 +75,12 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to get user by email: ", err) return res, err } + + if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil { + log.Debug("Failed to get mfa session: ", err) + return res, fmt.Errorf(`invalid session: %s`, err.Error()) + } + isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil // TODO - Add Login method in DB when we introduce OTP for social media login loginMethod := constants.AuthRecipeMethodBasicAuth From 146561bacbbde5f78596b4d16985a0ce7a9f4e65 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 25 Jul 2023 11:45:04 +0530 Subject: [PATCH 24/37] fix: allow multi tenant for microsooft --- server/oauth/oauth.go | 2 +- server/resolvers/meta.go | 8 +------- server/resolvers/update_env.go | 4 ++-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go index 7841909..2d41252 100644 --- a/server/oauth/oauth.go +++ b/server/oauth/oauth.go @@ -172,7 +172,7 @@ func InitOAuth() error { } microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) if err != nil { - microsoftActiveDirTenantID = "" + microsoftActiveDirTenantID = "common" } if microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "" { p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID)) diff --git a/server/resolvers/meta.go b/server/resolvers/meta.go index 5322517..9290a41 100644 --- a/server/resolvers/meta.go +++ b/server/resolvers/meta.go @@ -101,12 +101,6 @@ func MetaResolver(ctx context.Context) (*model.Meta, error) { microsoftClientSecret = "" } - microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) - if err != nil { - log.Debug("Failed to get Microsoft Active Directory Tenant ID from environment variable", err) - microsoftActiveDirTenantID = "" - } - isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) if err != nil { log.Debug("Failed to get Disable Basic Authentication from environment variable", err) @@ -152,7 +146,7 @@ func MetaResolver(ctx context.Context) (*model.Meta, error) { IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "", IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "", IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "", - IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "", + IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "", IsBasicAuthenticationEnabled: !isBasicAuthDisabled, IsEmailVerificationEnabled: !isEmailVerificationDisabled, IsMagicLinkLoginEnabled: !isMagicLinkLoginDisabled, diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index 437565e..96388aa 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -33,7 +33,7 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) { isCurrentGithubLoginEnabled := currentData[constants.EnvKeyGithubClientID] != nil && currentData[constants.EnvKeyGithubClientSecret] != nil && currentData[constants.EnvKeyGithubClientID].(string) != "" && currentData[constants.EnvKeyGithubClientSecret].(string) != "" isCurrentLinkedInLoginEnabled := currentData[constants.EnvKeyLinkedInClientID] != nil && currentData[constants.EnvKeyLinkedInClientSecret] != nil && currentData[constants.EnvKeyLinkedInClientID].(string) != "" && currentData[constants.EnvKeyLinkedInClientSecret].(string) != "" isCurrentTwitterLoginEnabled := currentData[constants.EnvKeyTwitterClientID] != nil && currentData[constants.EnvKeyTwitterClientSecret] != nil && currentData[constants.EnvKeyTwitterClientID].(string) != "" && currentData[constants.EnvKeyTwitterClientSecret].(string) != "" - isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != "" && currentData[constants.EnvKeyMicrosoftActiveDirectoryTenantID].(string) != "" + isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != "" isUpdatedBasicAuthEnabled := !updatedData[constants.EnvKeyDisableBasicAuthentication].(bool) isUpdatedMobileBasicAuthEnabled := !updatedData[constants.EnvKeyDisableMobileBasicAuthentication].(bool) @@ -44,7 +44,7 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) { isUpdatedGithubLoginEnabled := updatedData[constants.EnvKeyGithubClientID] != nil && updatedData[constants.EnvKeyGithubClientSecret] != nil && updatedData[constants.EnvKeyGithubClientID].(string) != "" && updatedData[constants.EnvKeyGithubClientSecret].(string) != "" isUpdatedLinkedInLoginEnabled := updatedData[constants.EnvKeyLinkedInClientID] != nil && updatedData[constants.EnvKeyLinkedInClientSecret] != nil && updatedData[constants.EnvKeyLinkedInClientID].(string) != "" && updatedData[constants.EnvKeyLinkedInClientSecret].(string) != "" isUpdatedTwitterLoginEnabled := updatedData[constants.EnvKeyTwitterClientID] != nil && updatedData[constants.EnvKeyTwitterClientSecret] != nil && updatedData[constants.EnvKeyTwitterClientID].(string) != "" && updatedData[constants.EnvKeyTwitterClientSecret].(string) != "" - isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != "" && updatedData[constants.EnvKeyMicrosoftActiveDirectoryTenantID].(string) != "" + isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != "" if isCurrentBasicAuthEnabled && !isUpdatedBasicAuthEnabled { memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodBasicAuth) From 15a4be543173a5bb9c3f4d4bb920305728cc55fc Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Mon, 31 Jul 2023 16:42:11 +0530 Subject: [PATCH 25/37] fix: refs for db provider and few utils --- .../db/providers/arangodb/email_template.go | 17 +++--- server/db/providers/arangodb/env.go | 8 +-- server/db/providers/arangodb/session.go | 2 +- server/db/providers/arangodb/user.go | 42 ++++--------- .../arangodb/verification_requests.go | 21 +++---- server/db/providers/arangodb/webhook.go | 17 +++--- server/db/providers/arangodb/webhook_log.go | 8 +-- .../providers/cassandradb/email_template.go | 16 ++--- server/db/providers/cassandradb/env.go | 8 +-- server/db/providers/cassandradb/session.go | 2 +- server/db/providers/cassandradb/user.go | 35 +++++------ .../cassandradb/verification_requests.go | 21 ++++--- server/db/providers/cassandradb/webhook.go | 16 ++--- .../db/providers/cassandradb/webhook_log.go | 10 ++-- .../db/providers/couchbase/email_template.go | 16 +++-- server/db/providers/couchbase/env.go | 8 +-- server/db/providers/couchbase/session.go | 2 +- server/db/providers/couchbase/user.go | 27 ++++----- .../couchbase/verification_requests.go | 23 ++++---- server/db/providers/couchbase/webhook.go | 14 ++--- server/db/providers/couchbase/webhook_log.go | 8 +-- .../db/providers/dynamodb/email_template.go | 17 +++--- server/db/providers/dynamodb/env.go | 8 +-- server/db/providers/dynamodb/session.go | 2 +- server/db/providers/dynamodb/user.go | 59 +++++-------------- .../dynamodb/verification_requests.go | 18 +++--- server/db/providers/dynamodb/webhook.go | 14 ++--- server/db/providers/dynamodb/webhook_log.go | 8 +-- server/db/providers/mongodb/email_template.go | 14 ++--- server/db/providers/mongodb/env.go | 8 +-- server/db/providers/mongodb/session.go | 2 +- server/db/providers/mongodb/user.go | 44 ++++---------- .../mongodb/verification_requests.go | 18 +++--- server/db/providers/mongodb/webhook.go | 14 ++--- server/db/providers/mongodb/webhook_log.go | 8 +-- .../provider_template/email_template.go | 6 +- server/db/providers/provider_template/env.go | 8 +-- .../db/providers/provider_template/session.go | 2 +- server/db/providers/provider_template/user.go | 23 +++----- .../verification_requests.go | 14 ++--- .../db/providers/provider_template/webhook.go | 6 +- .../provider_template/webhook_log.go | 4 +- server/db/providers/providers.go | 46 +++++++-------- server/db/providers/sql/email_template.go | 16 +++-- server/db/providers/sql/env.go | 11 ++-- server/db/providers/sql/provider.go | 2 +- server/db/providers/sql/session.go | 2 +- server/db/providers/sql/user.go | 27 ++++----- .../db/providers/sql/verification_requests.go | 31 +++------- server/db/providers/sql/webhook.go | 10 ++-- server/db/providers/sql/webhook_log.go | 6 +- server/env/persist_env.go | 5 +- server/handlers/oauth_callback.go | 41 +++++++------ server/handlers/verify_email.go | 3 +- server/resolvers/add_email_template.go | 2 +- server/resolvers/add_webhook.go | 2 +- server/resolvers/email_templates.go | 1 - server/resolvers/forgot_password.go | 2 +- server/resolvers/invite_members.go | 4 +- server/resolvers/login.go | 2 +- server/resolvers/magic_link_login.go | 4 +- server/resolvers/mobile_login.go | 8 +-- server/resolvers/mobile_signup.go | 4 +- server/resolvers/resend_otp.go | 7 +-- server/resolvers/resend_verify_email.go | 2 +- server/resolvers/signup.go | 6 +- server/resolvers/update_email_template.go | 2 +- server/resolvers/update_profile.go | 2 +- server/resolvers/update_user.go | 2 +- server/resolvers/update_webhook.go | 2 +- server/resolvers/verification_requests.go | 1 - server/resolvers/verify_email.go | 2 +- server/resolvers/verify_otp.go | 9 +-- server/resolvers/webhook_logs.go | 4 +- server/resolvers/webhooks.go | 1 - server/test/delete_email_template_test.go | 4 +- server/test/delete_webhook_test.go | 6 +- server/test/update_all_users_tests.go | 6 +- server/test/validate_jwt_token_test.go | 2 +- server/token/auth_token.go | 10 ++-- server/utils/pagination.go | 4 +- server/utils/webhook.go | 8 +-- 82 files changed, 394 insertions(+), 533 deletions(-) diff --git a/server/db/providers/arangodb/email_template.go b/server/db/providers/arangodb/email_template.go index 8134cbe..d668a75 100644 --- a/server/db/providers/arangodb/email_template.go +++ b/server/db/providers/arangodb/email_template.go @@ -12,7 +12,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() emailTemplate.Key = emailTemplate.ID @@ -31,7 +31,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate) @@ -46,23 +46,20 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { emailTemplates := []*model.EmailTemplate{} - query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.EmailTemplate, pagination.Offset, pagination.Limit) - sctx := arangoDriver.WithQueryFullCount(ctx) cursor, err := p.db.Query(sctx, query, nil) if err != nil { return nil, err } defer cursor.Close() - paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() for { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate meta, err := cursor.ReadDocument(ctx, &emailTemplate) if arangoDriver.IsNoMoreDocuments(err) { @@ -77,14 +74,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin } return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: emailTemplates, }, nil } // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate query := fmt.Sprintf("FOR d in %s FILTER d._key == @email_template_id RETURN d", models.Collections.EmailTemplate) bindVars := map[string]interface{}{ "email_template_id": emailTemplateID, @@ -113,7 +110,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", models.Collections.EmailTemplate) bindVars := map[string]interface{}{ "event_name": eventName, diff --git a/server/db/providers/arangodb/env.go b/server/db/providers/arangodb/env.go index 29687a8..1bc8162 100644 --- a/server/db/providers/arangodb/env.go +++ b/server/db/providers/arangodb/env.go @@ -12,7 +12,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() env.Key = env.ID @@ -31,7 +31,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() collection, _ := p.db.Collection(ctx, models.Collections.Env) meta, err := collection.UpdateDocument(ctx, env.Key, env) @@ -45,8 +45,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env) cursor, err := p.db.Query(ctx, query, nil) diff --git a/server/db/providers/arangodb/session.go b/server/db/providers/arangodb/session.go index 9bc46ca..5672b73 100644 --- a/server/db/providers/arangodb/session.go +++ b/server/db/providers/arangodb/session.go @@ -9,7 +9,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() session.Key = session.ID diff --git a/server/db/providers/arangodb/user.go b/server/db/providers/arangodb/user.go index cccbf94..c5572c0 100644 --- a/server/db/providers/arangodb/user.go +++ b/server/db/providers/arangodb/user.go @@ -18,7 +18,7 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() user.Key = user.ID @@ -52,7 +52,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() collection, _ := p.db.Collection(ctx, models.Collections.User) @@ -67,7 +67,7 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { collection, _ := p.db.Collection(ctx, models.Collections.User) _, err := collection.RemoveDocument(ctx, user.Key) if err != nil { @@ -88,7 +88,7 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error { } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { var users []*model.User sctx := arangoDriver.WithQueryFullCount(ctx) @@ -104,41 +104,36 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( paginationClone.Total = cursor.Statistics().FullCount() for { - var user models.User + var user *models.User meta, err := cursor.ReadDocument(ctx, &user) - if arangoDriver.IsNoMoreDocuments(err) { break } else if err != nil { return nil, err } - if meta.Key != "" { users = append(users, user.AsAPIUser()) } } return &model.Users{ - Pagination: &paginationClone, + Pagination: paginationClone, Users: users, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.User) bindVars := map[string]interface{}{ "email": email, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return user, err } defer cursor.Close() - for { if !cursor.HasMore() { if user.Key == "" { @@ -151,25 +146,21 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use return user, err } } - return user, nil } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("FOR d in %s FILTER d._id == @id LIMIT 1 RETURN d", models.Collections.User) bindVars := map[string]interface{}{ "id": id, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return user, err } defer cursor.Close() - for { if !cursor.HasMore() { if user.Key == "" { @@ -182,7 +173,6 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err return user, err } } - return user, nil } @@ -191,12 +181,10 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error { // set updated_at time for all users data["updated_at"] = time.Now().Unix() - userInfoBytes, err := json.Marshal(data) if err != nil { return err } - query := "" if len(ids) > 0 { keysArray := "" @@ -209,30 +197,25 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, } else { query = fmt.Sprintf("FOR u IN %s UPDATE u._key with %s IN %s", models.Collections.User, string(userInfoBytes), models.Collections.User) } - _, err = p.db.Query(ctx, query, nil) if err != nil { return err } - return nil } // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { - var user models.User - + var user *models.User query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.User) bindVars := map[string]interface{}{ "phone_number": phoneNumber, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return nil, err } defer cursor.Close() - for { if !cursor.HasMore() { if user.Key == "" { @@ -245,6 +228,5 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) return nil, err } } - - return &user, nil + return user, nil } diff --git a/server/db/providers/arangodb/verification_requests.go b/server/db/providers/arangodb/verification_requests.go index f69bcb0..0bbdad4 100644 --- a/server/db/providers/arangodb/verification_requests.go +++ b/server/db/providers/arangodb/verification_requests.go @@ -12,7 +12,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() verificationRequest.Key = verificationRequest.ID @@ -32,8 +32,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", models.Collections.VerificationRequest) bindVars := map[string]interface{}{ "token": token, @@ -62,8 +62,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", models.Collections.VerificationRequest) bindVars := map[string]interface{}{ @@ -94,22 +94,19 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { var verificationRequests []*model.VerificationRequest sctx := arangoDriver.WithQueryFullCount(ctx) query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.VerificationRequest, pagination.Offset, pagination.Limit) - cursor, err := p.db.Query(sctx, query, nil) if err != nil { return nil, err } defer cursor.Close() - paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() - for { - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest meta, err := cursor.ReadDocument(ctx, &verificationRequest) if arangoDriver.IsNoMoreDocuments(err) { @@ -126,12 +123,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode return &model.VerificationRequests{ VerificationRequests: verificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { collection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest) _, err := collection.RemoveDocument(ctx, verificationRequest.Key) if err != nil { diff --git a/server/db/providers/arangodb/webhook.go b/server/db/providers/arangodb/webhook.go index 73cefad..b9fa5fe 100644 --- a/server/db/providers/arangodb/webhook.go +++ b/server/db/providers/arangodb/webhook.go @@ -14,7 +14,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() webhook.Key = webhook.ID @@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -50,11 +50,9 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { webhooks := []*model.Webhook{} - query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.Webhook, pagination.Offset, pagination.Limit) - sctx := arangoDriver.WithQueryFullCount(ctx) cursor, err := p.db.Query(sctx, query, nil) if err != nil { @@ -64,9 +62,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() for { - var webhook models.Webhook + var webhook *models.Webhook meta, err := cursor.ReadDocument(ctx, &webhook) - if arangoDriver.IsNoMoreDocuments(err) { break } else if err != nil { @@ -79,14 +76,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) } return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: webhooks, }, nil } // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook models.Webhook + var webhook *models.Webhook query := fmt.Sprintf("FOR d in %s FILTER d._key == @webhook_id RETURN d", models.Collections.Webhook) bindVars := map[string]interface{}{ "webhook_id": webhookID, @@ -124,7 +121,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) defer cursor.Close() webhooks := []*model.Webhook{} for { - var webhook models.Webhook + var webhook *models.Webhook if _, err := cursor.ReadDocument(ctx, &webhook); driver.IsNoMoreDocuments(err) { // We're done break diff --git a/server/db/providers/arangodb/webhook_log.go b/server/db/providers/arangodb/webhook_log.go index 42de751..dba46ae 100644 --- a/server/db/providers/arangodb/webhook_log.go +++ b/server/db/providers/arangodb/webhook_log.go @@ -12,7 +12,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() webhookLog.Key = webhookLog.ID @@ -30,7 +30,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { webhookLogs := []*model.WebhookLog{} bindVariables := map[string]interface{}{} @@ -54,7 +54,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat paginationClone.Total = cursor.Statistics().FullCount() for { - var webhookLog models.WebhookLog + var webhookLog *models.WebhookLog meta, err := cursor.ReadDocument(ctx, &webhookLog) if arangoDriver.IsNoMoreDocuments(err) { @@ -69,7 +69,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat } return &model.WebhookLogs{ - Pagination: &paginationClone, + Pagination: paginationClone, WebhookLogs: webhookLogs, }, nil } diff --git a/server/db/providers/cassandradb/email_template.go b/server/db/providers/cassandradb/email_template.go index 7cb64cb..06b7708 100644 --- a/server/db/providers/cassandradb/email_template.go +++ b/server/db/providers/cassandradb/email_template.go @@ -15,7 +15,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } @@ -39,7 +39,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() bytes, err := json.Marshal(emailTemplate) @@ -90,12 +90,12 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { emailTemplates := []*model.EmailTemplate{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.EmailTemplate) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) if err != nil { return nil, err } @@ -109,7 +109,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { return nil, err @@ -120,14 +120,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin } return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: emailTemplates, }, nil } // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { @@ -138,7 +138,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { diff --git a/server/db/providers/cassandradb/env.go b/server/db/providers/cassandradb/env.go index 384b539..16c4050 100644 --- a/server/db/providers/cassandradb/env.go +++ b/server/db/providers/cassandradb/env.go @@ -11,7 +11,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() } @@ -28,7 +28,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() updateEnvQuery := fmt.Sprintf("UPDATE %s SET env = '%s', updated_at = %d WHERE id = '%s'", KeySpace+"."+models.Collections.Env, env.EnvData, env.UpdatedAt, env.ID) @@ -40,8 +40,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+models.Collections.Env) err := p.db.Query(query).Consistency(gocql.One).Scan(&env.ID, &env.EnvData, &env.Hash, &env.CreatedAt, &env.UpdatedAt) diff --git a/server/db/providers/cassandradb/session.go b/server/db/providers/cassandradb/session.go index e6042ea..c8d9232 100644 --- a/server/db/providers/cassandradb/session.go +++ b/server/db/providers/cassandradb/session.go @@ -10,7 +10,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() } diff --git a/server/db/providers/cassandradb/user.go b/server/db/providers/cassandradb/user.go index f8be709..e290049 100644 --- a/server/db/providers/cassandradb/user.go +++ b/server/db/providers/cassandradb/user.go @@ -18,7 +18,7 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() } @@ -87,7 +87,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() bytes, err := json.Marshal(user) @@ -138,13 +138,12 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.User, user.ID) err := p.db.Query(query).Exec() if err != nil { return err } - getSessionsQuery := fmt.Sprintf("SELECT id FROM %s WHERE user_id = '%s' ALLOW FILTERING", KeySpace+"."+models.Collections.Session, user.ID) scanner := p.db.Query(getSessionsQuery).Iter().Scanner() sessionIDs := "" @@ -167,11 +166,11 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error { } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { responseUsers := []*model.User{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) if err != nil { return nil, err } @@ -180,13 +179,12 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( // so we fetch till limit + offset // and return the results from offset to limit query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.User, pagination.Limit+pagination.Offset) - scanner := p.db.Query(query).Iter().Scanner() counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var user models.User - err := scanner.Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) + var user *models.User + err := scanner.Scan(user.ID, user.Email, user.EmailVerifiedAt, user.Password, user.SignupMethods, user.GivenName, user.FamilyName, user.MiddleName, user.Nickname, user.Birthdate, user.PhoneNumber, user.PhoneNumberVerifiedAt, user.Picture, user.Roles, user.RevokedTimestamp, user.IsMultiFactorAuthEnabled, user.CreatedAt, user.UpdatedAt) if err != nil { return nil, err } @@ -195,14 +193,14 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( counter++ } return &model.Users{ + Pagination: paginationClone, Users: responseUsers, - Pagination: &paginationClone, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var user models.User +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, email) err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { @@ -212,8 +210,8 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - var user models.User +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+models.Collections.User, id) err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { @@ -252,9 +250,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, } updateFields = strings.Trim(updateFields, " ") updateFields = strings.TrimSuffix(updateFields, ",") - query := "" - if ids != nil && len(ids) > 0 { + if len(ids) > 0 { idsString := "" for _, id := range ids { idsString += fmt.Sprintf("'%s', ", id) @@ -309,11 +306,11 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { - var user models.User + var user *models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber) - err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) + err := p.db.Query(query).Consistency(gocql.One).Scan(user.ID, user.Email, user.EmailVerifiedAt, user.Password, user.SignupMethods, user.GivenName, user.FamilyName, user.MiddleName, user.Nickname, user.Birthdate, user.PhoneNumber, user.PhoneNumberVerifiedAt, user.Picture, user.Roles, user.RevokedTimestamp, user.IsMultiFactorAuthEnabled, user.CreatedAt, user.UpdatedAt) if err != nil { return nil, err } - return &user, nil + return user, nil } diff --git a/server/db/providers/cassandradb/verification_requests.go b/server/db/providers/cassandradb/verification_requests.go index 3786a2b..f35196a 100644 --- a/server/db/providers/cassandradb/verification_requests.go +++ b/server/db/providers/cassandradb/verification_requests.go @@ -12,7 +12,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() } @@ -29,8 +29,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE jwt_token = '%s' LIMIT 1`, KeySpace+"."+models.Collections.VerificationRequest, token) err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) @@ -41,8 +41,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE email = '%s' AND identifier = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.VerificationRequest, email, identifier) err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) @@ -54,12 +54,11 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { var verificationRequests []*model.VerificationRequest - paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) if err != nil { return nil, err } @@ -73,7 +72,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) if err != nil { return nil, err @@ -85,12 +84,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode return &model.VerificationRequests{ VerificationRequests: verificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.VerificationRequest, verificationRequest.ID) err := p.db.Query(query).Exec() if err != nil { diff --git a/server/db/providers/cassandradb/webhook.go b/server/db/providers/cassandradb/webhook.go index cb50f08..b9b8abf 100644 --- a/server/db/providers/cassandradb/webhook.go +++ b/server/db/providers/cassandradb/webhook.go @@ -15,7 +15,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() } @@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -81,11 +81,11 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { webhooks := []*model.Webhook{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var webhook models.Webhook + var webhook *models.Webhook err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { return nil, err @@ -108,14 +108,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) } return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: webhooks, }, nil } // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook models.Webhook + var webhook *models.Webhook query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID) err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { @@ -130,7 +130,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) scanner := p.db.Query(query).Iter().Scanner() webhooks := []*model.Webhook{} for scanner.Next() { - var webhook models.Webhook + var webhook *models.Webhook err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { return nil, err diff --git a/server/db/providers/cassandradb/webhook_log.go b/server/db/providers/cassandradb/webhook_log.go index 9ecf939..3eded48 100644 --- a/server/db/providers/cassandradb/webhook_log.go +++ b/server/db/providers/cassandradb/webhook_log.go @@ -12,7 +12,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } @@ -30,7 +30,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { webhookLogs := []*model.WebhookLog{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.WebhookLog) @@ -44,7 +44,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat query = fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s WHERE webhook_id = '%s' LIMIT %d ALLOW FILTERING", KeySpace+"."+models.Collections.WebhookLog, webhookID, pagination.Limit+pagination.Offset) } - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) if err != nil { return nil, err } @@ -53,7 +53,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var webhookLog models.WebhookLog + var webhookLog *models.WebhookLog err := scanner.Scan(&webhookLog.ID, &webhookLog.HttpStatus, &webhookLog.Response, &webhookLog.Request, &webhookLog.WebhookID, &webhookLog.CreatedAt, &webhookLog.UpdatedAt) if err != nil { return nil, err @@ -64,7 +64,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat } return &model.WebhookLogs{ - Pagination: &paginationClone, + Pagination: paginationClone, WebhookLogs: webhookLogs, }, nil } diff --git a/server/db/providers/couchbase/email_template.go b/server/db/providers/couchbase/email_template.go index bd37482..9b58999 100644 --- a/server/db/providers/couchbase/email_template.go +++ b/server/db/providers/couchbase/email_template.go @@ -15,7 +15,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() @@ -37,7 +37,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { bytes, err := json.Marshal(emailTemplate) if err != nil { return nil, err @@ -67,7 +67,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { emailTemplates := []*model.EmailTemplate{} paginationClone := pagination total, err := p.GetTotalDocs(ctx, models.Collections.EmailTemplate) @@ -88,7 +88,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin } for queryResult.Next() { - emailTemplate := models.EmailTemplate{} + var emailTemplate *models.EmailTemplate err := queryResult.Row(&emailTemplate) if err != nil { log.Fatal(err) @@ -102,15 +102,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin } return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: emailTemplates, }, nil } // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - emailTemplate := models.EmailTemplate{} - + var emailTemplate *models.EmailTemplate query := fmt.Sprintf(`SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1`, p.scopeName, models.Collections.EmailTemplate) q, err := p.db.Query(query, &gocb.QueryOptions{ Context: ctx, @@ -132,8 +131,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - emailTemplate := models.EmailTemplate{} - + var emailTemplate *models.EmailTemplate query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE event_name=$1 LIMIT 1", p.scopeName, models.Collections.EmailTemplate) q, err := p.db.Query(query, &gocb.QueryOptions{ Context: ctx, diff --git a/server/db/providers/couchbase/env.go b/server/db/providers/couchbase/env.go index 3addb9f..77d9aeb 100644 --- a/server/db/providers/couchbase/env.go +++ b/server/db/providers/couchbase/env.go @@ -11,7 +11,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() } @@ -31,7 +31,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() env.EncryptionKey = env.Hash @@ -49,8 +49,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env query := fmt.Sprintf("SELECT _id, env, encryption_key, created_at, updated_at FROM %s.%s LIMIT 1", p.scopeName, models.Collections.Env) q, err := p.db.Query(query, &gocb.QueryOptions{ diff --git a/server/db/providers/couchbase/session.go b/server/db/providers/couchbase/session.go index 6f0d84f..7907bdb 100644 --- a/server/db/providers/couchbase/session.go +++ b/server/db/providers/couchbase/session.go @@ -10,7 +10,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() } diff --git a/server/db/providers/couchbase/user.go b/server/db/providers/couchbase/user.go index 2dc813c..5850f36 100644 --- a/server/db/providers/couchbase/user.go +++ b/server/db/providers/couchbase/user.go @@ -15,7 +15,7 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() } @@ -41,7 +41,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() unsertOpt := gocb.UpsertOptions{ Context: ctx, @@ -54,7 +54,7 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { removeOpt := gocb.RemoveOptions{ Context: ctx, } @@ -66,12 +66,10 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error { } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { users := []*model.User{} paginationClone := pagination - userQuery := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s ORDER BY id OFFSET $1 LIMIT $2", p.scopeName, models.Collections.User) - queryResult, err := p.db.Query(userQuery, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistencyRequestPlus, Context: ctx, @@ -86,7 +84,7 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( } paginationClone.Total = total for queryResult.Next() { - var user models.User + var user *models.User err := queryResult.Row(&user) if err != nil { log.Fatal(err) @@ -97,21 +95,20 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( return nil, err } return &model.Users{ - Pagination: &paginationClone, + Pagination: paginationClone, Users: users, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - user := models.User{} +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1", p.scopeName, models.Collections.User) q, err := p.db.Query(query, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistencyRequestPlus, Context: ctx, PositionalParameters: []interface{}{email}, }) - if err != nil { return user, err } @@ -119,13 +116,12 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use if err != nil { return user, err } - return user, nil } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - user := models.User{} +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1", p.scopeName, models.Collections.User) q, err := p.db.Query(query, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistencyRequestPlus, @@ -139,7 +135,6 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err if err != nil { return user, err } - return user, nil } @@ -174,7 +169,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, return err } } - return nil } @@ -194,6 +188,5 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) if err != nil { return user, err } - return user, nil } diff --git a/server/db/providers/couchbase/verification_requests.go b/server/db/providers/couchbase/verification_requests.go index 6971065..f1d2b00 100644 --- a/server/db/providers/couchbase/verification_requests.go +++ b/server/db/providers/couchbase/verification_requests.go @@ -13,7 +13,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() } @@ -33,8 +33,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - verificationRequest := models.VerificationRequest{} +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest params := make(map[string]interface{}, 1) params["token"] = token query := fmt.Sprintf("SELECT _id, token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE token=$1 LIMIT 1", p.scopeName, models.Collections.VerificationRequest) @@ -57,7 +57,7 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { query := fmt.Sprintf("SELECT _id, identifier, token, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE email=$1 AND identifier=$2 LIMIT 1", p.scopeName, models.Collections.VerificationRequest) queryResult, err := p.db.Query(query, &gocb.QueryOptions{ @@ -65,14 +65,11 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri PositionalParameters: []interface{}{email, identifier}, ScanConsistency: gocb.QueryScanConsistencyRequestPlus, }) - verificationRequest := models.VerificationRequest{} - if err != nil { - return verificationRequest, err + return nil, err } - + var verificationRequest *models.VerificationRequest err = queryResult.One(&verificationRequest) - if err != nil { return verificationRequest, err } @@ -80,7 +77,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { var verificationRequests []*model.VerificationRequest paginationClone := pagination total, err := p.GetTotalDocs(ctx, models.Collections.VerificationRequest) @@ -98,7 +95,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode return nil, err } for queryResult.Next() { - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest err := queryResult.Row(&verificationRequest) if err != nil { log.Fatal(err) @@ -111,12 +108,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode } return &model.VerificationRequests{ VerificationRequests: verificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { removeOpt := gocb.RemoveOptions{ Context: ctx, } diff --git a/server/db/providers/couchbase/webhook.go b/server/db/providers/couchbase/webhook.go index 2f51acd..9647419 100644 --- a/server/db/providers/couchbase/webhook.go +++ b/server/db/providers/couchbase/webhook.go @@ -15,7 +15,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() } @@ -35,7 +35,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -68,7 +68,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { webhooks := []*model.Webhook{} paginationClone := pagination params := make(map[string]interface{}, 1) @@ -89,7 +89,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) return nil, err } for queryResult.Next() { - var webhook models.Webhook + var webhook *models.Webhook err := queryResult.Row(&webhook) if err != nil { log.Fatal(err) @@ -100,14 +100,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) return nil, err } return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: webhooks, }, nil } // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook models.Webhook + var webhook *models.Webhook params := make(map[string]interface{}, 1) params["_id"] = webhookID query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook) @@ -141,7 +141,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) } webhooks := []*model.Webhook{} for queryResult.Next() { - var webhook models.Webhook + var webhook *models.Webhook err := queryResult.Row(&webhook) if err != nil { log.Fatal(err) diff --git a/server/db/providers/couchbase/webhook_log.go b/server/db/providers/couchbase/webhook_log.go index 7c4fd15..73d45dd 100644 --- a/server/db/providers/couchbase/webhook_log.go +++ b/server/db/providers/couchbase/webhook_log.go @@ -13,7 +13,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } @@ -34,7 +34,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { var query string var err error @@ -66,7 +66,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat return nil, err } for queryResult.Next() { - var webhookLog models.WebhookLog + var webhookLog *models.WebhookLog err := queryResult.Row(&webhookLog) if err != nil { log.Fatal(err) @@ -79,7 +79,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat } return &model.WebhookLogs{ - Pagination: &paginationClone, + Pagination: paginationClone, WebhookLogs: webhookLogs, }, nil } diff --git a/server/db/providers/dynamodb/email_template.go b/server/db/providers/dynamodb/email_template.go index 08745cf..091c841 100644 --- a/server/db/providers/dynamodb/email_template.go +++ b/server/db/providers/dynamodb/email_template.go @@ -12,7 +12,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { collection := p.db.Table(models.Collections.EmailTemplate) if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() @@ -31,7 +31,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { collection := p.db.Table(models.Collections.EmailTemplate) emailTemplate.UpdatedAt = time.Now().Unix() err := UpdateByHashKey(collection, "id", emailTemplate.ID, emailTemplate) @@ -42,9 +42,9 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate var iter dynamo.PagingIter var lastEval dynamo.PagingKey var iteration int64 = 0 @@ -73,7 +73,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin paginationClone.Total = count return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: emailTemplates, }, nil } @@ -81,7 +81,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { collection := p.db.Table(models.Collections.EmailTemplate) - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate err := collection.Get("id", emailTemplateID).OneWithContext(ctx, &emailTemplate) if err != nil { return nil, err @@ -92,9 +92,8 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { collection := p.db.Table(models.Collections.EmailTemplate) - var emailTemplates []models.EmailTemplate - var emailTemplate models.EmailTemplate - + var emailTemplates []*models.EmailTemplate + var emailTemplate *models.EmailTemplate err := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Limit(1).AllWithContext(ctx, &emailTemplates) if err != nil { return nil, err diff --git a/server/db/providers/dynamodb/env.go b/server/db/providers/dynamodb/env.go index d491e19..daa2e3e 100644 --- a/server/db/providers/dynamodb/env.go +++ b/server/db/providers/dynamodb/env.go @@ -11,7 +11,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { collection := p.db.Table(models.Collections.Env) if env.ID == "" { @@ -33,7 +33,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { collection := p.db.Table(models.Collections.Env) env.UpdatedAt = time.Now().Unix() @@ -46,8 +46,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env collection := p.db.Table(models.Collections.Env) // As there is no Findone supported. diff --git a/server/db/providers/dynamodb/session.go b/server/db/providers/dynamodb/session.go index 68457e5..03218b3 100644 --- a/server/db/providers/dynamodb/session.go +++ b/server/db/providers/dynamodb/session.go @@ -9,7 +9,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { collection := p.db.Table(models.Collections.Session) if session.ID == "" { diff --git a/server/db/providers/dynamodb/user.go b/server/db/providers/dynamodb/user.go index d7c47e3..f93956b 100644 --- a/server/db/providers/dynamodb/user.go +++ b/server/db/providers/dynamodb/user.go @@ -18,13 +18,11 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { collection := p.db.Table(models.Collections.User) - if user.ID == "" { user.ID = uuid.New().String() } - if user.Roles == "" { defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles) if err != nil { @@ -32,18 +30,14 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } user.Roles = defaultRoles } - if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" { if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil { return user, fmt.Errorf("user with given phone number already exists") } } - user.CreatedAt = time.Now().Unix() user.UpdatedAt = time.Now().Unix() - err := collection.Put(user).RunWithContext(ctx) - if err != nil { return user, err } @@ -51,18 +45,14 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { collection := p.db.Table(models.Collections.User) - if user.ID != "" { - user.UpdatedAt = time.Now().Unix() - err := UpdateByHashKey(collection, "id", user.ID, user) if err != nil { return user, err } - if err != nil { return user, err } @@ -72,18 +62,15 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { collection := p.db.Table(models.Collections.User) sessionCollection := p.db.Table(models.Collections.Session) - if user.ID != "" { err := collection.Delete("id", user.ID).Run() if err != nil { return err } - _, err = sessionCollection.Batch("id").Write().Delete(dynamo.Keys{"user_id", user.ID}).RunWithContext(ctx) - if err != nil { return err } @@ -92,23 +79,19 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error { } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { - var user models.User +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { + var user *models.User var lastEval dynamo.PagingKey var iter dynamo.PagingIter var iteration int64 = 0 - collection := p.db.Table(models.Collections.User) users := []*model.User{} - paginationClone := pagination scanner := collection.Scan() count, err := scanner.Count() - if err != nil { return nil, err } - for (paginationClone.Offset + paginationClone.Limit) > iteration { iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter() for iter.NextWithContext(ctx, &user) { @@ -119,48 +102,39 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( lastEval = iter.LastEvaluatedKey() iteration += paginationClone.Limit } - err = iter.Err() - if err != nil { return nil, err } - paginationClone.Total = count - return &model.Users{ - Pagination: &paginationClone, + Pagination: paginationClone, Users: users, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var users []models.User - var user models.User - +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var users []*models.User + var user *models.User collection := p.db.Table(models.Collections.User) err := collection.Scan().Index("email").Filter("'email' = ?", email).AllWithContext(ctx, &users) - if err != nil { return user, nil } - if len(users) > 0 { user = users[0] return user, nil } else { return user, errors.New("no record found") } - } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { collection := p.db.Table(models.Collections.User) - var user models.User + var user *models.User err := collection.Get("id", id).OneWithContext(ctx, &user) - if err != nil { if user.Email == "" { return user, errors.New("no documets found") @@ -186,7 +160,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, } else { // as there is no facility to update all doc - https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.UpdateData.html userCollection.Scan().All(&allUsers) - for _, user := range allUsers { err = UpdateByHashKey(userCollection, "id", user.ID, data) if err == nil { @@ -194,7 +167,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, } } } - if err != nil { return err } else { @@ -205,19 +177,16 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { - var users []models.User - var user models.User - + var users []*models.User + var user *models.User collection := p.db.Table(models.Collections.User) err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).AllWithContext(ctx, &users) - if err != nil { return nil, err } - if len(users) > 0 { user = users[0] - return &user, nil + return user, nil } else { return nil, errors.New("no record found") } diff --git a/server/db/providers/dynamodb/verification_requests.go b/server/db/providers/dynamodb/verification_requests.go index 990c288..e261c2f 100644 --- a/server/db/providers/dynamodb/verification_requests.go +++ b/server/db/providers/dynamodb/verification_requests.go @@ -11,7 +11,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { collection := p.db.Table(models.Collections.VerificationRequest) if verificationRequest.ID == "" { @@ -28,9 +28,9 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { collection := p.db.Table(models.Collections.VerificationRequest) - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest iter := collection.Scan().Filter("'token' = ?", token).Iter() for iter.NextWithContext(ctx, &verificationRequest) { @@ -45,8 +45,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest collection := p.db.Table(models.Collections.VerificationRequest) iter := collection.Scan().Filter("'email' = ?", email).Filter("'identifier' = ?", identifier).Iter() for iter.NextWithContext(ctx, &verificationRequest) { @@ -61,9 +61,9 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { verificationRequests := []*model.VerificationRequest{} - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest var lastEval dynamo.PagingKey var iter dynamo.PagingIter var iteration int64 = 0 @@ -97,12 +97,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode return &model.VerificationRequests{ VerificationRequests: verificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { collection := p.db.Table(models.Collections.VerificationRequest) if verificationRequest.ID != "" { diff --git a/server/db/providers/dynamodb/webhook.go b/server/db/providers/dynamodb/webhook.go index 8f1ffb7..920173b 100644 --- a/server/db/providers/dynamodb/webhook.go +++ b/server/db/providers/dynamodb/webhook.go @@ -15,7 +15,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { collection := p.db.Table(models.Collections.Webhook) if webhook.ID == "" { webhook.ID = uuid.New().String() @@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -48,9 +48,9 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { webhooks := []*model.Webhook{} - var webhook models.Webhook + var webhook *models.Webhook var lastEval dynamo.PagingKey var iter dynamo.PagingIter var iteration int64 = 0 @@ -77,7 +77,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) } paginationClone.Total = count return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: webhooks, }, nil } @@ -85,7 +85,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { collection := p.db.Table(models.Collections.Webhook) - var webhook models.Webhook + var webhook *models.Webhook err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook) if err != nil { return nil, err @@ -116,7 +116,7 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er // Also delete webhook logs for given webhook id if webhook.ID != "" { webhookCollection := p.db.Table(models.Collections.Webhook) - pagination := model.Pagination{} + var pagination *model.Pagination webhookLogCollection := p.db.Table(models.Collections.WebhookLog) err := webhookCollection.Delete("id", webhook.ID).RunWithContext(ctx) if err != nil { diff --git a/server/db/providers/dynamodb/webhook_log.go b/server/db/providers/dynamodb/webhook_log.go index e9d1dcd..a1fc8ca 100644 --- a/server/db/providers/dynamodb/webhook_log.go +++ b/server/db/providers/dynamodb/webhook_log.go @@ -11,7 +11,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { collection := p.db.Table(models.Collections.WebhookLog) if webhookLog.ID == "" { @@ -30,9 +30,9 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { webhookLogs := []*model.WebhookLog{} - var webhookLog models.WebhookLog + var webhookLog *models.WebhookLog var lastEval dynamo.PagingKey var iter dynamo.PagingIter var iteration int64 = 0 @@ -72,7 +72,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat paginationClone.Total = count // paginationClone.Cursor = iter.LastEvaluatedKey() return &model.WebhookLogs{ - Pagination: &paginationClone, + Pagination: paginationClone, WebhookLogs: webhookLogs, }, nil } diff --git a/server/db/providers/mongodb/email_template.go b/server/db/providers/mongodb/email_template.go index 0a0d1d9..f412b4c 100644 --- a/server/db/providers/mongodb/email_template.go +++ b/server/db/providers/mongodb/email_template.go @@ -12,7 +12,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } @@ -30,7 +30,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) @@ -43,7 +43,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { var emailTemplates []*model.EmailTemplate opts := options.Find() opts.SetLimit(pagination.Limit) @@ -67,7 +67,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin defer cursor.Close(ctx) for cursor.Next(ctx) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate err := cursor.Decode(&emailTemplate) if err != nil { return nil, err @@ -76,14 +76,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin } return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: emailTemplates, }, nil } // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) err := emailTemplateCollection.FindOne(ctx, bson.M{"_id": emailTemplateID}).Decode(&emailTemplate) if err != nil { @@ -94,7 +94,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) err := emailTemplateCollection.FindOne(ctx, bson.M{"event_name": eventName}).Decode(&emailTemplate) if err != nil { diff --git a/server/db/providers/mongodb/env.go b/server/db/providers/mongodb/env.go index a4b114c..ec6afd9 100644 --- a/server/db/providers/mongodb/env.go +++ b/server/db/providers/mongodb/env.go @@ -12,7 +12,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() } @@ -29,7 +29,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() configCollection := p.db.Collection(models.Collections.Env, options.Collection()) _, err := configCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions()) @@ -40,8 +40,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env configCollection := p.db.Collection(models.Collections.Env, options.Collection()) cursor, err := configCollection.Find(ctx, bson.M{}, options.Find()) if err != nil { diff --git a/server/db/providers/mongodb/session.go b/server/db/providers/mongodb/session.go index 4030130..01b35bc 100644 --- a/server/db/providers/mongodb/session.go +++ b/server/db/providers/mongodb/session.go @@ -10,7 +10,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() } diff --git a/server/db/providers/mongodb/user.go b/server/db/providers/mongodb/user.go index 32b6a17..078322e 100644 --- a/server/db/providers/mongodb/user.go +++ b/server/db/providers/mongodb/user.go @@ -16,11 +16,10 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() } - if user.Roles == "" { defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles) if err != nil { @@ -36,12 +35,11 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, if err != nil { return user, err } - return user, nil } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() userCollection := p.db.Collection(models.Collections.User, options.Collection()) _, err := userCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions()) @@ -52,83 +50,72 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { userCollection := p.db.Collection(models.Collections.User, options.Collection()) _, err := userCollection.DeleteOne(ctx, bson.M{"_id": user.ID}, options.Delete()) if err != nil { return err } - sessionCollection := p.db.Collection(models.Collections.Session, options.Collection()) _, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete()) if err != nil { return err } - return nil } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { var users []*model.User opts := options.Find() opts.SetLimit(pagination.Limit) opts.SetSkip(pagination.Offset) opts.SetSort(bson.M{"created_at": -1}) - paginationClone := pagination - userCollection := p.db.Collection(models.Collections.User, options.Collection()) count, err := userCollection.CountDocuments(ctx, bson.M{}, options.Count()) if err != nil { return nil, err } - paginationClone.Total = count - cursor, err := userCollection.Find(ctx, bson.M{}, opts) if err != nil { return nil, err } defer cursor.Close(ctx) - for cursor.Next(ctx) { - var user models.User + var user *models.User err := cursor.Decode(&user) if err != nil { return nil, err } users = append(users, user.AsAPIUser()) } - return &model.Users{ - Pagination: &paginationClone, + Pagination: paginationClone, Users: users, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var user models.User +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User userCollection := p.db.Collection(models.Collections.User, options.Collection()) err := userCollection.FindOne(ctx, bson.M{"email": email}).Decode(&user) if err != nil { return user, err } - return user, nil } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User userCollection := p.db.Collection(models.Collections.User, options.Collection()) err := userCollection.FindOne(ctx, bson.M{"_id": id}).Decode(&user) if err != nil { return user, err } - return user, nil } @@ -137,17 +124,14 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error { // set updated_at time for all users data["updated_at"] = time.Now().Unix() - userCollection := p.db.Collection(models.Collections.User, options.Collection()) - var res *mongo.UpdateResult var err error - if ids != nil && len(ids) > 0 { + if len(ids) > 0 { res, err = userCollection.UpdateMany(ctx, bson.M{"_id": bson.M{"$in": ids}}, bson.M{"$set": data}) } else { res, err = userCollection.UpdateMany(ctx, bson.M{}, bson.M{"$set": data}) } - if err != nil { return err } else { @@ -158,13 +142,11 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { - var user models.User - + var user *models.User userCollection := p.db.Collection(models.Collections.User, options.Collection()) err := userCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&user) if err != nil { return nil, err } - - return &user, nil + return user, nil } diff --git a/server/db/providers/mongodb/verification_requests.go b/server/db/providers/mongodb/verification_requests.go index ff6f908..532d8c8 100644 --- a/server/db/providers/mongodb/verification_requests.go +++ b/server/db/providers/mongodb/verification_requests.go @@ -12,7 +12,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() @@ -30,8 +30,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) err := verificationRequestCollection.FindOne(ctx, bson.M{"token": token}).Decode(&verificationRequest) @@ -43,8 +43,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) err := verificationRequestCollection.FindOne(ctx, bson.M{"email": email, "identifier": identifier}).Decode(&verificationRequest) @@ -56,7 +56,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { var verificationRequests []*model.VerificationRequest opts := options.Find() @@ -77,7 +77,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode defer cursor.Close(ctx) for cursor.Next(ctx) { - var verificationRequest models.VerificationRequest + var verificationRequest *models.VerificationRequest err := cursor.Decode(&verificationRequest) if err != nil { return nil, err @@ -87,12 +87,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode return &model.VerificationRequests{ VerificationRequests: verificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) _, err := verificationRequestCollection.DeleteOne(ctx, bson.M{"_id": verificationRequest.ID}, options.Delete()) if err != nil { diff --git a/server/db/providers/mongodb/webhook.go b/server/db/providers/mongodb/webhook.go index 843aec9..ef6b382 100644 --- a/server/db/providers/mongodb/webhook.go +++ b/server/db/providers/mongodb/webhook.go @@ -14,7 +14,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() } @@ -32,7 +32,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -47,7 +47,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { webhooks := []*model.Webhook{} opts := options.Find() opts.SetLimit(pagination.Limit) @@ -66,7 +66,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) } defer cursor.Close(ctx) for cursor.Next(ctx) { - var webhook models.Webhook + var webhook *models.Webhook err := cursor.Decode(&webhook) if err != nil { return nil, err @@ -74,14 +74,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) webhooks = append(webhooks, webhook.AsAPIWebhook()) } return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: webhooks, }, nil } // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook models.Webhook + var webhook *models.Webhook webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection()) err := webhookCollection.FindOne(ctx, bson.M{"_id": webhookID}).Decode(&webhook) if err != nil { @@ -104,7 +104,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) } defer cursor.Close(ctx) for cursor.Next(ctx) { - var webhook models.Webhook + var webhook *models.Webhook err := cursor.Decode(&webhook) if err != nil { return nil, err diff --git a/server/db/providers/mongodb/webhook_log.go b/server/db/providers/mongodb/webhook_log.go index 6e1081c..0c464d8 100644 --- a/server/db/providers/mongodb/webhook_log.go +++ b/server/db/providers/mongodb/webhook_log.go @@ -12,7 +12,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } @@ -30,7 +30,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { webhookLogs := []*model.WebhookLog{} opts := options.Find() opts.SetLimit(pagination.Limit) @@ -59,7 +59,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat defer cursor.Close(ctx) for cursor.Next(ctx) { - var webhookLog models.WebhookLog + var webhookLog *models.WebhookLog err := cursor.Decode(&webhookLog) if err != nil { return nil, err @@ -68,7 +68,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat } return &model.WebhookLogs{ - Pagination: &paginationClone, + Pagination: paginationClone, WebhookLogs: webhookLogs, }, nil } diff --git a/server/db/providers/provider_template/email_template.go b/server/db/providers/provider_template/email_template.go index e6a1f50..a306479 100644 --- a/server/db/providers/provider_template/email_template.go +++ b/server/db/providers/provider_template/email_template.go @@ -10,7 +10,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } @@ -22,13 +22,13 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() return emailTemplate.AsAPIEmailTemplate(), nil } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { return nil, nil } diff --git a/server/db/providers/provider_template/env.go b/server/db/providers/provider_template/env.go index af232e8..823d4e3 100644 --- a/server/db/providers/provider_template/env.go +++ b/server/db/providers/provider_template/env.go @@ -9,7 +9,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() } @@ -20,14 +20,14 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() return env, nil } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env return env, nil } diff --git a/server/db/providers/provider_template/session.go b/server/db/providers/provider_template/session.go index c6f45ec..fd1e853 100644 --- a/server/db/providers/provider_template/session.go +++ b/server/db/providers/provider_template/session.go @@ -9,7 +9,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() } diff --git a/server/db/providers/provider_template/user.go b/server/db/providers/provider_template/user.go index 286e74d..9f4c7f8 100644 --- a/server/db/providers/provider_template/user.go +++ b/server/db/providers/provider_template/user.go @@ -12,11 +12,10 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() } - if user.Roles == "" { defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles) if err != nil { @@ -24,40 +23,36 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } user.Roles = defaultRoles } - user.CreatedAt = time.Now().Unix() user.UpdatedAt = time.Now().Unix() - return user, nil } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() return user, nil } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { return nil } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { return nil, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User return user, nil } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User return user, nil } @@ -66,13 +61,11 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error { // set updated_at time for all users data["updated_at"] = time.Now().Unix() - return nil } // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { var user *models.User - return user, nil } diff --git a/server/db/providers/provider_template/verification_requests.go b/server/db/providers/provider_template/verification_requests.go index 577d2f6..c3a7f18 100644 --- a/server/db/providers/provider_template/verification_requests.go +++ b/server/db/providers/provider_template/verification_requests.go @@ -10,7 +10,7 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() } @@ -22,25 +22,25 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest return verificationRequest, nil } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest return verificationRequest, nil } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { return nil, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { return nil } diff --git a/server/db/providers/provider_template/webhook.go b/server/db/providers/provider_template/webhook.go index faf18fa..cf0edbe 100644 --- a/server/db/providers/provider_template/webhook.go +++ b/server/db/providers/provider_template/webhook.go @@ -12,7 +12,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() } @@ -25,7 +25,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -35,7 +35,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { return nil, nil } diff --git a/server/db/providers/provider_template/webhook_log.go b/server/db/providers/provider_template/webhook_log.go index 9814bc3..9ad81d2 100644 --- a/server/db/providers/provider_template/webhook_log.go +++ b/server/db/providers/provider_template/webhook_log.go @@ -10,7 +10,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } @@ -22,6 +22,6 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { return nil, nil } diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index be25b53..1df7e37 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -9,50 +9,50 @@ import ( type Provider interface { // AddUser to save user information in database - AddUser(ctx context.Context, user models.User) (models.User, error) + AddUser(ctx context.Context, user *models.User) (*models.User, error) // UpdateUser to update user information in database - UpdateUser(ctx context.Context, user models.User) (models.User, error) + UpdateUser(ctx context.Context, user *models.User) (*models.User, error) // DeleteUser to delete user information from database - DeleteUser(ctx context.Context, user models.User) error + DeleteUser(ctx context.Context, user *models.User) error // ListUsers to get list of users from database - ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) + ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) // GetUserByEmail to get user information from database using email address - GetUserByEmail(ctx context.Context, email string) (models.User, error) + GetUserByEmail(ctx context.Context, email string) (*models.User, error) // GetUserByPhoneNumber to get user information from database using phone number GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) // GetUserByID to get user information from database using user ID - GetUserByID(ctx context.Context, id string) (models.User, error) + GetUserByID(ctx context.Context, id string) (*models.User, error) // UpdateUsers to update multiple users, with parameters of user IDs slice // If ids set to nil / empty all the users will be updated UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error // AddVerification to save verification request in database - AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) + AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) // GetVerificationRequestByToken to get verification request from database using token - GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) + GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) // GetVerificationRequestByEmail to get verification request by email from database - GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) + GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) // ListVerificationRequests to get list of verification requests from database - ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) + ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) // DeleteVerificationRequest to delete verification request from database - DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error + DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error // AddSession to save session information in database - AddSession(ctx context.Context, session models.Session) error + AddSession(ctx context.Context, session *models.Session) error // AddEnv to save environment information in database - AddEnv(ctx context.Context, env models.Env) (models.Env, error) + AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) // UpdateEnv to update environment information in database - UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) + UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) // GetEnv to get environment information from database - GetEnv(ctx context.Context) (models.Env, error) + GetEnv(ctx context.Context) (*models.Env, error) // AddWebhook to add webhook - AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) + AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) // UpdateWebhook to update webhook - UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) + UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) // ListWebhooks to list webhook - ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) + ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) // GetWebhookByID to get webhook by id GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) // GetWebhookByEventName to get webhook by event_name @@ -61,16 +61,16 @@ type Provider interface { DeleteWebhook(ctx context.Context, webhook *model.Webhook) error // AddWebhookLog to add webhook log - AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) + AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) // ListWebhookLogs to list webhook logs - ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) + ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) // AddEmailTemplate to add EmailTemplate - AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) + AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) // UpdateEmailTemplate to update EmailTemplate - UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) + UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) // ListEmailTemplates to list EmailTemplate - ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) + ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) // GetEmailTemplateByID to get EmailTemplate by id GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) // GetEmailTemplateByEventName to get EmailTemplate by event_name diff --git a/server/db/providers/sql/email_template.go b/server/db/providers/sql/email_template.go index 1a8e0d2..8928b6f 100644 --- a/server/db/providers/sql/email_template.go +++ b/server/db/providers/sql/email_template.go @@ -10,7 +10,7 @@ import ( ) // AddEmailTemplate to add EmailTemplate -func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } @@ -27,7 +27,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em } // UpdateEmailTemplate to update EmailTemplate -func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) { +func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() res := p.db.Save(&emailTemplate) @@ -38,9 +38,8 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models } // ListEmailTemplates to list EmailTemplate -func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) { - var emailTemplates []models.EmailTemplate - +func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { + var emailTemplates []*models.EmailTemplate result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&emailTemplates) if result.Error != nil { return nil, result.Error @@ -60,14 +59,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin responseEmailTemplates = append(responseEmailTemplates, w.AsAPIEmailTemplate()) } return &model.EmailTemplates{ - Pagination: &paginationClone, + Pagination: paginationClone, EmailTemplates: responseEmailTemplates, }, nil } // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate result := p.db.Where("id = ?", emailTemplateID).First(&emailTemplate) if result.Error != nil { @@ -78,7 +77,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate models.EmailTemplate + var emailTemplate *models.EmailTemplate result := p.db.Where("event_name = ?", eventName).First(&emailTemplate) if result.Error != nil { @@ -95,6 +94,5 @@ func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model if result.Error != nil { return result.Error } - return nil } diff --git a/server/db/providers/sql/env.go b/server/db/providers/sql/env.go index 1f34c38..11584a0 100644 --- a/server/db/providers/sql/env.go +++ b/server/db/providers/sql/env.go @@ -9,7 +9,7 @@ import ( ) // AddEnv to save environment information in database -func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { if env.ID == "" { env.ID = uuid.New().String() } @@ -26,10 +26,9 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro } // UpdateEnv to update environment information in database -func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) { +func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() result := p.db.Save(&env) - if result.Error != nil { return env, result.Error } @@ -37,13 +36,11 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e } // GetEnv to get environment information from database -func (p *provider) GetEnv(ctx context.Context) (models.Env, error) { - var env models.Env +func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { + var env *models.Env result := p.db.First(&env) - if result.Error != nil { return env, result.Error } - return env, nil } diff --git a/server/db/providers/sql/provider.go b/server/db/providers/sql/provider.go index 2101953..0512ecf 100644 --- a/server/db/providers/sql/provider.go +++ b/server/db/providers/sql/provider.go @@ -77,7 +77,7 @@ func NewProvider() (*provider, error) { logrus.Debug("Failed to drop phone number constraint:", err) } - err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}) + err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, &models.WebhookLog{}, &models.EmailTemplate{}, &models.OTP{}) if err != nil { return nil, err } diff --git a/server/db/providers/sql/session.go b/server/db/providers/sql/session.go index 0ed7317..07b4849 100644 --- a/server/db/providers/sql/session.go +++ b/server/db/providers/sql/session.go @@ -10,7 +10,7 @@ import ( ) // AddSession to save session information in database -func (p *provider) AddSession(ctx context.Context, session models.Session) error { +func (p *provider) AddSession(ctx context.Context, session *models.Session) error { if session.ID == "" { session.ID = uuid.New().String() } diff --git a/server/db/providers/sql/user.go b/server/db/providers/sql/user.go index a4b40c0..5243ad6 100644 --- a/server/db/providers/sql/user.go +++ b/server/db/providers/sql/user.go @@ -17,7 +17,7 @@ import ( ) // AddUser to save user information in database -func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) { if user.ID == "" { user.ID = uuid.New().String() } @@ -53,7 +53,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, } // UpdateUser to update user information in database -func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) { +func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) { user.UpdatedAt = time.Now().Unix() result := p.db.Save(&user) @@ -66,7 +66,7 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use } // DeleteUser to delete user information from database -func (p *provider) DeleteUser(ctx context.Context, user models.User) error { +func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { result := p.db.Where("user_id = ?", user.ID).Delete(&models.Session{}) if result.Error != nil { return result.Error @@ -81,7 +81,7 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error { } // ListUsers to get list of users from database -func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) { +func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) { var users []models.User result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users) if result.Error != nil { @@ -103,31 +103,28 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( paginationClone.Total = total return &model.Users{ - Pagination: &paginationClone, + Pagination: paginationClone, Users: responseUsers, }, nil } // GetUserByEmail to get user information from database using email address -func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) { - var user models.User +func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { + var user *models.User result := p.db.Where("email = ?", email).First(&user) if result.Error != nil { return user, result.Error } - return user, nil } // GetUserByID to get user information from database using user ID -func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) { - var user models.User - +func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { + var user *models.User result := p.db.Where("id = ?", id).First(&user) if result.Error != nil { return user, result.Error } - return user, nil } @@ -136,14 +133,12 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error { // set updated_at time for all users data["updated_at"] = time.Now().Unix() - var res *gorm.DB - if ids != nil && len(ids) > 0 { + if len(ids) > 0 { res = p.db.Model(&models.User{}).Where("id in ?", ids).Updates(data) } else { res = p.db.Model(&models.User{}).Updates(data) } - if res.Error != nil { return res.Error } @@ -154,10 +149,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { var user *models.User result := p.db.Where("phone_number = ?", phoneNumber).First(&user) - if result.Error != nil { return nil, result.Error } - return user, nil } diff --git a/server/db/providers/sql/verification_requests.go b/server/db/providers/sql/verification_requests.go index 5b413b0..ac91bec 100644 --- a/server/db/providers/sql/verification_requests.go +++ b/server/db/providers/sql/verification_requests.go @@ -11,11 +11,10 @@ import ( ) // AddVerification to save verification request in database -func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { +func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() } - verificationRequest.Key = verificationRequest.ID verificationRequest.CreatedAt = time.Now().Unix() verificationRequest.UpdatedAt = time.Now().Unix() @@ -23,75 +22,61 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque Columns: []clause.Column{{Name: "email"}, {Name: "identifier"}}, DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at", "nonce", "redirect_uri"}), }).Create(&verificationRequest) - if result.Error != nil { return verificationRequest, result.Error } - return verificationRequest, nil } // GetVerificationRequestByToken to get verification request from database using token -func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest +func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest result := p.db.Where("token = ?", token).First(&verificationRequest) - if result.Error != nil { return verificationRequest, result.Error } - return verificationRequest, nil } // GetVerificationRequestByEmail to get verification request by email from database -func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) { - var verificationRequest models.VerificationRequest - +func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { + var verificationRequest *models.VerificationRequest result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest) - if result.Error != nil { return verificationRequest, result.Error } - return verificationRequest, nil } // ListVerificationRequests to get list of verification requests from database -func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) { +func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) { var verificationRequests []models.VerificationRequest - result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&verificationRequests) if result.Error != nil { return nil, result.Error } - responseVerificationRequests := []*model.VerificationRequest{} for _, v := range verificationRequests { responseVerificationRequests = append(responseVerificationRequests, v.AsAPIVerificationRequest()) } - var total int64 totalRes := p.db.Model(&models.VerificationRequest{}).Count(&total) if totalRes.Error != nil { return nil, totalRes.Error } - paginationClone := pagination paginationClone.Total = total - return &model.VerificationRequests{ VerificationRequests: responseVerificationRequests, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } // DeleteVerificationRequest to delete verification request from database -func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error { +func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { result := p.db.Delete(&verificationRequest) - if result.Error != nil { return result.Error } - return nil } diff --git a/server/db/providers/sql/webhook.go b/server/db/providers/sql/webhook.go index 72f3cb4..54e2d13 100644 --- a/server/db/providers/sql/webhook.go +++ b/server/db/providers/sql/webhook.go @@ -12,7 +12,7 @@ import ( ) // AddWebhook to add webhook -func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { if webhook.ID == "" { webhook.ID = uuid.New().String() } @@ -29,7 +29,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod } // UpdateWebhook to update webhook -func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) { +func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) { webhook.UpdatedAt = time.Now().Unix() // Event is changed if !strings.Contains(webhook.EventName, "-") { @@ -43,7 +43,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* } // ListWebhooks to list webhook -func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) { +func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) { var webhooks []models.Webhook result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks) if result.Error != nil { @@ -61,14 +61,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) responseWebhooks = append(responseWebhooks, w.AsAPIWebhook()) } return &model.Webhooks{ - Pagination: &paginationClone, + Pagination: paginationClone, Webhooks: responseWebhooks, }, nil } // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook models.Webhook + var webhook *models.Webhook result := p.db.Where("id = ?", webhookID).First(&webhook) if result.Error != nil { diff --git a/server/db/providers/sql/webhook_log.go b/server/db/providers/sql/webhook_log.go index 0ccbca2..cf50be2 100644 --- a/server/db/providers/sql/webhook_log.go +++ b/server/db/providers/sql/webhook_log.go @@ -12,7 +12,7 @@ import ( ) // AddWebhookLog to add webhook log -func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) { +func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } @@ -32,7 +32,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL } // ListWebhookLogs to list webhook logs -func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) { +func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { var webhookLogs []models.WebhookLog var result *gorm.DB var totalRes *gorm.DB @@ -63,6 +63,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat } return &model.WebhookLogs{ WebhookLogs: responseWebhookLogs, - Pagination: &paginationClone, + Pagination: paginationClone, }, nil } diff --git a/server/env/persist_env.go b/server/env/persist_env.go index 719c91d..c930b01 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -134,12 +134,11 @@ func PersistEnv() error { return err } - env = models.Env{ + env = &models.Env{ Hash: encodedHash, EnvData: encryptedConfig, } - - env, err = db.Provider.AddEnv(ctx, env) + _, err = db.Provider.AddEnv(ctx, env) if err != nil { log.Debug("Error while persisting env data to db: ", err) return err diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index 1c547e2..ed6a81a 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -55,7 +55,7 @@ func OAuthCallbackHandler() gin.HandlerFunc { inputRoles := strings.Split(sessionSplit[2], ",") scopes := strings.Split(sessionSplit[3], ",") - user := models.User{} + var user *models.User oauthCode := ctx.Request.FormValue("code") switch provider { case constants.AuthRecipeMethodGoogle: @@ -263,7 +263,7 @@ func OAuthCallbackHandler() gin.HandlerFunc { } else { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user) } - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(ctx.Request), IP: utils.GetIP(ctx.Request), @@ -279,15 +279,14 @@ func OAuthCallbackHandler() gin.HandlerFunc { } } -func processGoogleUserInfo(code string) (models.User, error) { - user := models.User{} +func processGoogleUserInfo(code string) (*models.User, error) { + var user *models.User ctx := context.Background() oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) return user, fmt.Errorf("invalid google exchange code: %s", err.Error()) } - verifier := oauth.OIDCProviders.GoogleOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.GoogleConfig.ClientID}) // Extract the ID Token from OAuth2 token. @@ -312,8 +311,8 @@ func processGoogleUserInfo(code string) (models.User, error) { return user, nil } -func processGithubUserInfo(code string) (models.User, error) { - user := models.User{} +func processGithubUserInfo(code string) (*models.User, error) { + var user *models.User oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(context.TODO(), code) if err != nil { log.Debug("Failed to exchange code for token: ", err) @@ -409,7 +408,7 @@ func processGithubUserInfo(code string) (models.User, error) { } } - user = models.User{ + user = &models.User{ GivenName: &firstName, FamilyName: &lastName, Picture: &picture, @@ -419,8 +418,8 @@ func processGithubUserInfo(code string) (models.User, error) { return user, nil } -func processFacebookUserInfo(code string) (models.User, error) { - user := models.User{} +func processFacebookUserInfo(code string) (*models.User, error) { + var user *models.User oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(context.TODO(), code) if err != nil { log.Debug("Invalid facebook exchange code: ", err) @@ -460,7 +459,7 @@ func processFacebookUserInfo(code string) (models.User, error) { lastName := fmt.Sprintf("%v", userRawData["last_name"]) picture := fmt.Sprintf("%v", picDataObject["url"]) - user = models.User{ + user = &models.User{ GivenName: &firstName, FamilyName: &lastName, Picture: &picture, @@ -470,8 +469,8 @@ func processFacebookUserInfo(code string) (models.User, error) { return user, nil } -func processLinkedInUserInfo(code string) (models.User, error) { - user := models.User{} +func processLinkedInUserInfo(code string) (*models.User, error) { + var user *models.User oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(context.TODO(), code) if err != nil { log.Debug("Failed to exchange code for token: ", err) @@ -542,7 +541,7 @@ func processLinkedInUserInfo(code string) (models.User, error) { profilePicture := userRawData["profilePicture"].(map[string]interface{})["displayImage~"].(map[string]interface{})["elements"].([]interface{})[0].(map[string]interface{})["identifiers"].([]interface{})[0].(map[string]interface{})["identifier"].(string) emailAddress := emailRawData["elements"].([]interface{})[0].(map[string]interface{})["handle~"].(map[string]interface{})["emailAddress"].(string) - user = models.User{ + user = &models.User{ GivenName: &firstName, FamilyName: &lastName, Picture: &profilePicture, @@ -552,8 +551,8 @@ func processLinkedInUserInfo(code string) (models.User, error) { return user, nil } -func processAppleUserInfo(code string) (models.User, error) { - user := models.User{} +func processAppleUserInfo(code string) (*models.User, error) { + var user *models.User oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(context.TODO(), code) if err != nil { log.Debug("Failed to exchange code for token: ", err) @@ -605,8 +604,8 @@ func processAppleUserInfo(code string) (models.User, error) { return user, err } -func processTwitterUserInfo(code, verifier string) (models.User, error) { - user := models.User{} +func processTwitterUserInfo(code, verifier string) (*models.User, error) { + var user *models.User oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(context.TODO(), code, oauth2.SetAuthURLParam("code_verifier", verifier)) if err != nil { log.Debug("Failed to exchange code for token: ", err) @@ -662,7 +661,7 @@ func processTwitterUserInfo(code, verifier string) (models.User, error) { nickname := userRawData["username"].(string) profilePicture := userRawData["profile_image_url"].(string) - user = models.User{ + user = &models.User{ GivenName: &firstName, FamilyName: &lastName, Picture: &profilePicture, @@ -673,8 +672,8 @@ func processTwitterUserInfo(code, verifier string) (models.User, error) { } // process microsoft user information -func processMicrosoftUserInfo(code string) (models.User, error) { - user := models.User{} +func processMicrosoftUserInfo(code string) (*models.User, error) { + var user *models.User ctx := context.Background() oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code) if err != nil { diff --git a/server/handlers/verify_email.go b/server/handlers/verify_email.go index 452820f..2ed9280 100644 --- a/server/handlers/verify_email.go +++ b/server/handlers/verify_email.go @@ -178,8 +178,7 @@ func VerifyEmailHandler() gin.HandlerFunc { } else { utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user) } - - db.Provider.AddSession(c, models.Session{ + db.Provider.AddSession(c, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(c.Request), IP: utils.GetIP(c.Request), diff --git a/server/resolvers/add_email_template.go b/server/resolvers/add_email_template.go index 311b18a..487edc2 100644 --- a/server/resolvers/add_email_template.go +++ b/server/resolvers/add_email_template.go @@ -47,7 +47,7 @@ func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplate design = "" } - _, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{ + _, err = db.Provider.AddEmailTemplate(ctx, &models.EmailTemplate{ EventName: params.EventName, Template: params.Template, Subject: params.Subject, diff --git a/server/resolvers/add_webhook.go b/server/resolvers/add_webhook.go index 596b1e0..3380779 100644 --- a/server/resolvers/add_webhook.go +++ b/server/resolvers/add_webhook.go @@ -43,7 +43,7 @@ func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*m if params.EventDescription == nil { params.EventDescription = refs.NewStringRef(strings.Join(strings.Split(params.EventName, "."), " ")) } - _, err = db.Provider.AddWebhook(ctx, models.Webhook{ + _, err = db.Provider.AddWebhook(ctx, &models.Webhook{ EventDescription: refs.StringValue(params.EventDescription), EventName: params.EventName, EndPoint: params.Endpoint, diff --git a/server/resolvers/email_templates.go b/server/resolvers/email_templates.go index 7230400..0e1ee66 100644 --- a/server/resolvers/email_templates.go +++ b/server/resolvers/email_templates.go @@ -25,7 +25,6 @@ func EmailTemplatesResolver(ctx context.Context, params *model.PaginatedInput) ( } pagination := utils.GetPagination(params) - emailTemplates, err := db.Provider.ListEmailTemplate(ctx, pagination) if err != nil { log.Debug("failed to get email templates: ", err) diff --git a/server/resolvers/forgot_password.go b/server/resolvers/forgot_password.go index f497b31..028ff11 100644 --- a/server/resolvers/forgot_password.go +++ b/server/resolvers/forgot_password.go @@ -81,7 +81,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu log.Debug("Failed to create verification token", err) return res, err } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: constants.VerificationTypeForgotPassword, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), diff --git a/server/resolvers/invite_members.go b/server/resolvers/invite_members.go index c15ca7e..ee5e0a1 100644 --- a/server/resolvers/invite_members.go +++ b/server/resolvers/invite_members.go @@ -105,7 +105,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) defaultRoles = strings.Split(defaultRolesString, ",") } - user := models.User{ + user := &models.User{ Email: email, Roles: strings.Join(defaultRoles, ","), } @@ -128,7 +128,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) log.Debug("Failed to create verification token: ", err) } - verificationRequest := models.VerificationRequest{ + verificationRequest := &models.VerificationRequest{ Token: verificationToken, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), Email: email, diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 93d3377..9a886ef 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -203,7 +203,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes go func() { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/magic_link_login.go b/server/resolvers/magic_link_login.go index 5ce90c8..a500c27 100644 --- a/server/resolvers/magic_link_login.go +++ b/server/resolvers/magic_link_login.go @@ -55,7 +55,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu inputRoles := []string{} - user := models.User{ + user := &models.User{ Email: params.Email, } @@ -207,7 +207,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu if err != nil { log.Debug("Failed to create verification token: ", err) } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: verificationType, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index fc131b0..64a108d 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -132,7 +132,7 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m return nil, err } go func() { - utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, *user) + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) }() return &model.AuthResponse{ @@ -168,7 +168,7 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m nonce = uuid.New().String() } - authToken, err := token.CreateAuthToken(gc, *user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code) + authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code) if err != nil { log.Debug("Failed to create auth token", err) return res, err @@ -207,8 +207,8 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m } go func() { - utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, *user) - db.Provider.AddSession(ctx, models.Session{ + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 70b6d60..63f5ea0 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -130,7 +130,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } } - user := models.User{ + user := &models.User{ Email: emailInput, PhoneNumber: &mobile, } @@ -298,7 +298,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) go func() { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/resend_otp.go b/server/resolvers/resend_otp.go index dafe9dd..74da143 100644 --- a/server/resolvers/resend_otp.go +++ b/server/resolvers/resend_otp.go @@ -32,7 +32,7 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod log.Debug("Email or phone number is required") return nil, errors.New("email or phone number is required") } - var user models.User + var user *models.User var err error if email != "" { isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) @@ -47,10 +47,7 @@ func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*mod log.Debug("Email service not enabled: ", err) return nil, errors.New("email service not enabled") } - // TODO fix after refs fixes - var u *models.User - u, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) - user = *u + user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) } if err != nil { log.Debug("Failed to get user by email: ", err) diff --git a/server/resolvers/resend_verify_email.go b/server/resolvers/resend_verify_email.go index 6c94024..b5a789f 100644 --- a/server/resolvers/resend_verify_email.go +++ b/server/resolvers/resend_verify_email.go @@ -67,7 +67,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma if err != nil { log.Debug("Failed to create verification token: ", err) } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: params.Identifier, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 757efeb..1828033 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -117,7 +117,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR } } - user := models.User{ + user := &models.User{ Email: params.Email, } @@ -208,7 +208,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR log.Debug("Failed to create verification token: ", err) return res, err } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: verificationType, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), @@ -302,7 +302,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR go func() { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/update_email_template.go b/server/resolvers/update_email_template.go index cf4e948..c08a49f 100644 --- a/server/resolvers/update_email_template.go +++ b/server/resolvers/update_email_template.go @@ -34,7 +34,7 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe return nil, err } - emailTemplateDetails := models.EmailTemplate{ + emailTemplateDetails := &models.EmailTemplate{ ID: emailTemplate.ID, Key: emailTemplate.ID, EventName: emailTemplate.EventName, diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go index da74258..a8fcb5a 100644 --- a/server/resolvers/update_profile.go +++ b/server/resolvers/update_profile.go @@ -242,7 +242,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) log.Debug("Failed to create verification token: ", err) return res, err } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: verificationType, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go index bd61428..d9741ae 100644 --- a/server/resolvers/update_user.go +++ b/server/resolvers/update_user.go @@ -147,7 +147,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod if err != nil { log.Debug("Failed to create verification token: ", err) } - _, err = db.Provider.AddVerificationRequest(ctx, models.VerificationRequest{ + _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{ Token: verificationToken, Identifier: verificationType, ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), diff --git a/server/resolvers/update_webhook.go b/server/resolvers/update_webhook.go index 5783984..3d09568 100644 --- a/server/resolvers/update_webhook.go +++ b/server/resolvers/update_webhook.go @@ -41,7 +41,7 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques } headersString = string(headerBytes) } - webhookDetails := models.Webhook{ + webhookDetails := &models.Webhook{ ID: webhook.ID, Key: webhook.ID, EventName: refs.StringValue(webhook.EventName), diff --git a/server/resolvers/verification_requests.go b/server/resolvers/verification_requests.go index 4a629de..9a55be7 100644 --- a/server/resolvers/verification_requests.go +++ b/server/resolvers/verification_requests.go @@ -27,7 +27,6 @@ func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedIn } pagination := utils.GetPagination(params) - res, err := db.Provider.ListVerificationRequests(ctx, pagination) if err != nil { log.Debug("Failed to get verification requests: ", err) diff --git a/server/resolvers/verify_email.go b/server/resolvers/verify_email.go index d1fd81d..9ee0181 100644 --- a/server/resolvers/verify_email.go +++ b/server/resolvers/verify_email.go @@ -129,7 +129,7 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 124ee3f..290b6fd 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -55,14 +55,11 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to verify otp request: Timeout") return res, fmt.Errorf("otp expired") } - var user models.User + var user *models.User if currentField == models.FieldNameEmail { user, err = db.Provider.GetUserByEmail(ctx, refs.StringValue(params.Email)) } else { - // TODO fix after refs of db providers are fixed - var u *models.User - u, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) - user = *u + user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) } if user.ID == "" && err != nil { log.Debug("Failed to get user by email: ", err) @@ -118,7 +115,7 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } - db.Provider.AddSession(ctx, models.Session{ + db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), IP: utils.GetIP(gc.Request), diff --git a/server/resolvers/webhook_logs.go b/server/resolvers/webhook_logs.go index 7c9cc7b..cd7b62d 100644 --- a/server/resolvers/webhook_logs.go +++ b/server/resolvers/webhook_logs.go @@ -25,7 +25,7 @@ func WebhookLogsResolver(ctx context.Context, params *model.ListWebhookLogReques return nil, fmt.Errorf("unauthorized") } - var pagination model.Pagination + var pagination *model.Pagination var webhookID string if params != nil { @@ -37,7 +37,7 @@ func WebhookLogsResolver(ctx context.Context, params *model.ListWebhookLogReques pagination = utils.GetPagination(nil) webhookID = "" } - + // TODO fix webhookLogs, err := db.Provider.ListWebhookLogs(ctx, pagination, webhookID) if err != nil { log.Debug("failed to get webhook logs: ", err) diff --git a/server/resolvers/webhooks.go b/server/resolvers/webhooks.go index 5a6ccbb..733df82 100644 --- a/server/resolvers/webhooks.go +++ b/server/resolvers/webhooks.go @@ -25,7 +25,6 @@ func WebhooksResolver(ctx context.Context, params *model.PaginatedInput) (*model } pagination := utils.GetPagination(params) - webhooks, err := db.Provider.ListWebhook(ctx, pagination) if err != nil { log.Debug("failed to get webhooks: ", err) diff --git a/server/test/delete_email_template_test.go b/server/test/delete_email_template_test.go index ef79db9..c32b6d5 100644 --- a/server/test/delete_email_template_test.go +++ b/server/test/delete_email_template_test.go @@ -24,7 +24,7 @@ func deleteEmailTemplateTest(t *testing.T, s TestSetup) { req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h)) // get all email templates - emailTemplates, err := db.Provider.ListEmailTemplate(ctx, model.Pagination{ + emailTemplates, err := db.Provider.ListEmailTemplate(ctx, &model.Pagination{ Limit: 10, Page: 1, Offset: 0, @@ -41,7 +41,7 @@ func deleteEmailTemplateTest(t *testing.T, s TestSetup) { assert.NotEmpty(t, res.Message) } - emailTemplates, err = db.Provider.ListEmailTemplate(ctx, model.Pagination{ + emailTemplates, err = db.Provider.ListEmailTemplate(ctx, &model.Pagination{ Limit: 10, Page: 1, Offset: 0, diff --git a/server/test/delete_webhook_test.go b/server/test/delete_webhook_test.go index ab9b9f2..3404a42 100644 --- a/server/test/delete_webhook_test.go +++ b/server/test/delete_webhook_test.go @@ -24,7 +24,7 @@ func deleteWebhookTest(t *testing.T, s TestSetup) { req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h)) // get all webhooks - webhooks, err := db.Provider.ListWebhook(ctx, model.Pagination{ + webhooks, err := db.Provider.ListWebhook(ctx, &model.Pagination{ Limit: 20, Page: 1, Offset: 0, @@ -41,14 +41,14 @@ func deleteWebhookTest(t *testing.T, s TestSetup) { assert.NotEmpty(t, res.Message) } - webhooks, err = db.Provider.ListWebhook(ctx, model.Pagination{ + webhooks, err = db.Provider.ListWebhook(ctx, &model.Pagination{ Limit: 20, Page: 1, Offset: 0, }) assert.NoError(t, err) assert.Len(t, webhooks.Webhooks, 0) - webhookLogs, err := db.Provider.ListWebhookLogs(ctx, model.Pagination{ + webhookLogs, err := db.Provider.ListWebhookLogs(ctx, &model.Pagination{ Limit: 100, Page: 1, Offset: 0, diff --git a/server/test/update_all_users_tests.go b/server/test/update_all_users_tests.go index 375158f..b2e507f 100644 --- a/server/test/update_all_users_tests.go +++ b/server/test/update_all_users_tests.go @@ -18,7 +18,7 @@ func updateAllUsersTest(t *testing.T, s TestSetup) { t.Run("Should update all users", func(t *testing.T) { _, ctx := createContext(s) for i := 0; i < 10; i++ { - user := models.User{ + user := &models.User{ Email: fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email), SignupMethods: constants.AuthRecipeMethodBasicAuth, Roles: "user", @@ -33,7 +33,7 @@ func updateAllUsersTest(t *testing.T, s TestSetup) { }, nil) assert.NoError(t, err) - listUsers, err := db.Provider.ListUsers(ctx, model.Pagination{ + listUsers, err := db.Provider.ListUsers(ctx, &model.Pagination{ Limit: 20, Offset: 0, }) @@ -49,7 +49,7 @@ func updateAllUsersTest(t *testing.T, s TestSetup) { }, updateIds) assert.NoError(t, err) - listUsers, err = db.Provider.ListUsers(ctx, model.Pagination{ + listUsers, err = db.Provider.ListUsers(ctx, &model.Pagination{ Limit: 20, Offset: 0, }) diff --git a/server/test/validate_jwt_token_test.go b/server/test/validate_jwt_token_test.go index d2ab257..f9a108a 100644 --- a/server/test/validate_jwt_token_test.go +++ b/server/test/validate_jwt_token_test.go @@ -39,7 +39,7 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) { }) scope := []string{"openid", "email", "profile", "offline_access"} - user := models.User{ + user := &models.User{ ID: uuid.New().String(), Email: "jwt_test_" + s.TestInfo.Email, Roles: "user", diff --git a/server/token/auth_token.go b/server/token/auth_token.go index 6d2c942..f482db8 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -51,7 +51,7 @@ type SessionData struct { } // CreateAuthToken creates a new auth token when userlogs in -func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string, code string) (*Token, error) { +func CreateAuthToken(gc *gin.Context, user *models.User, roles, scope []string, loginMethod, nonce string, code string) (*Token, error) { hostname := parsers.GetHost(gc) _, fingerPrintHash, sessionTokenExpiresAt, err := CreateSessionToken(user, nonce, roles, scope, loginMethod) if err != nil { @@ -104,7 +104,7 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l } // CreateSessionToken creates a new session token -func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, int64, error) { +func CreateSessionToken(user *models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, int64, error) { expiresAt := time.Now().AddDate(1, 0, 0).Unix() fingerPrintMap := &SessionData{ Nonce: nonce, @@ -125,7 +125,7 @@ func CreateSessionToken(user models.User, nonce string, roles, scope []string, l } // CreateRefreshToken util to create JWT token -func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) { +func CreateRefreshToken(user *models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) { // expires in 1 year expiryBound := time.Hour * 8760 expiresAt := time.Now().Add(expiryBound).Unix() @@ -157,7 +157,7 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc // CreateAccessToken util to create JWT token, based on // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT -func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce, loginMethod string) (string, int64, error) { +func CreateAccessToken(user *models.User, roles, scopes []string, hostName, nonce, loginMethod string) (string, int64, error) { expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime) if err != nil { return "", 0, err @@ -372,7 +372,7 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT // For response_type (code) / authorization_code grant nonce should be empty // for implicit flow it should be present to verify with actual state -func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cHash, loginMethod string) (string, int64, error) { +func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, cHash, loginMethod string) (string, int64, error) { expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime) if err != nil { return "", 0, err diff --git a/server/utils/pagination.go b/server/utils/pagination.go index e27eb53..d0bfff9 100644 --- a/server/utils/pagination.go +++ b/server/utils/pagination.go @@ -7,7 +7,7 @@ import ( // GetPagination helps getting pagination data from paginated input // also returns default limit and offset if pagination data is not present -func GetPagination(paginatedInput *model.PaginatedInput) model.Pagination { +func GetPagination(paginatedInput *model.PaginatedInput) *model.Pagination { limit := int64(constants.DefaultLimit) page := int64(1) @@ -21,7 +21,7 @@ func GetPagination(paginatedInput *model.PaginatedInput) model.Pagination { } } - return model.Pagination{ + return &model.Pagination{ Limit: limit, Offset: (page - 1) * limit, Page: page, diff --git a/server/utils/webhook.go b/server/utils/webhook.go index 4c6fbd0..2571cf5 100644 --- a/server/utils/webhook.go +++ b/server/utils/webhook.go @@ -18,10 +18,10 @@ import ( // RegisterEvent util to register event // TODO change user to user ref -func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error { +func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user *models.User) error { webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName) if err != nil { - log.Debug("Error getting webhook: %v", err) + log.Debug("error getting webhook: %v", err) return err } for _, webhook := range webhooks { @@ -63,7 +63,7 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use continue } if envKey == constants.TestEnv { - _, err := db.Provider.AddWebhookLog(ctx, models.WebhookLog{ + _, err := db.Provider.AddWebhookLog(ctx, &models.WebhookLog{ HttpStatus: 200, Request: string(requestBody), Response: string(`{"message": "test"}`), @@ -104,7 +104,7 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use } statusCode := int64(resp.StatusCode) - _, err = db.Provider.AddWebhookLog(ctx, models.WebhookLog{ + _, err = db.Provider.AddWebhookLog(ctx, &models.WebhookLog{ HttpStatus: statusCode, Request: string(requestBody), Response: string(responseBytes), From c2defdbaac0f2263390f9cc7a968200ffddfe2e6 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 1 Aug 2023 16:09:17 +0530 Subject: [PATCH 26/37] fix: refs for cassandra db --- dashboard/yarn.lock | 6 ++--- .../db/providers/arangodb/email_template.go | 16 ++---------- server/db/providers/arangodb/env.go | 4 +-- server/db/providers/arangodb/otp.go | 21 +++++----------- server/db/providers/arangodb/provider.go | 11 -------- server/db/providers/arangodb/session.go | 6 ++++- server/db/providers/arangodb/user.go | 12 +++------ .../arangodb/verification_requests.go | 14 ++--------- server/db/providers/arangodb/webhook.go | 2 +- server/db/providers/arangodb/webhook_log.go | 9 ------- .../providers/cassandradb/email_template.go | 17 +++---------- server/db/providers/cassandradb/env.go | 10 +++----- server/db/providers/cassandradb/session.go | 7 ++++-- server/db/providers/cassandradb/user.go | 25 +++++++++---------- .../cassandradb/verification_requests.go | 18 ++++++------- server/db/providers/cassandradb/webhook.go | 8 +++--- .../db/providers/cassandradb/webhook_log.go | 5 ++-- .../db/providers/couchbase/email_template.go | 8 +----- server/db/providers/couchbase/env.go | 4 --- server/db/providers/couchbase/session.go | 2 -- server/db/providers/couchbase/shared.go | 3 --- server/db/providers/couchbase/user.go | 2 +- .../couchbase/verification_requests.go | 4 +-- server/db/providers/couchbase/webhook.go | 5 +--- server/db/providers/couchbase/webhook_log.go | 10 +------- .../db/providers/dynamodb/email_template.go | 7 ------ server/db/providers/dynamodb/env.go | 15 +---------- server/db/providers/dynamodb/otp.go | 1 - server/db/providers/dynamodb/provider.go | 3 --- server/db/providers/dynamodb/session.go | 2 -- server/db/providers/dynamodb/shared.go | 6 ----- .../dynamodb/verification_requests.go | 12 --------- server/db/providers/dynamodb/webhook_log.go | 5 ---- server/db/providers/mongodb/email_template.go | 11 -------- server/db/providers/mongodb/env.go | 6 +---- server/db/providers/mongodb/session.go | 5 ++++ .../db/providers/provider_template/session.go | 1 - server/db/providers/providers.go | 2 ++ server/db/providers/sql/session.go | 5 ++++ server/env/env.go | 2 +- server/env/persist_env.go | 7 ++---- server/resolvers/signup.go | 19 +++++++------- server/resolvers/verify_otp.go | 5 ++-- server/test/admin_signup_test.go | 5 ++-- server/test/integration_test.go | 7 ++++-- server/test/verification_requests_test.go | 2 -- server/utils/pagination.go | 1 - 47 files changed, 103 insertions(+), 255 deletions(-) diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index 79e25d9..e1239de 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -1222,9 +1222,9 @@ dependencies: "is-arrayish" "^0.2.1" -"esbuild-linux-64@0.14.9": - "integrity" "sha512-WoEI+R6/PLZAxS7XagfQMFgRtLUi5cjqqU9VCfo3tnWmAXh/wt8QtUfCVVCcXVwZLS/RNvI19CtfjlrJU61nOg==" - "resolved" "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.9.tgz" +"esbuild-darwin-arm64@0.14.9": + "integrity" "sha512-3ue+1T4FR5TaAu4/V1eFMG8Uwn0pgAwQZb/WwL1X78d5Cy8wOVQ67KNH1lsjU+y/9AcwMKZ9x0GGNxBB4a1Rbw==" + "resolved" "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.9.tgz" "version" "0.14.9" "esbuild@^0.14.9": diff --git a/server/db/providers/arangodb/email_template.go b/server/db/providers/arangodb/email_template.go index d668a75..30c0fd0 100644 --- a/server/db/providers/arangodb/email_template.go +++ b/server/db/providers/arangodb/email_template.go @@ -17,11 +17,9 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E emailTemplate.ID = uuid.New().String() emailTemplate.Key = emailTemplate.ID } - emailTemplate.Key = emailTemplate.ID emailTemplate.CreatedAt = time.Now().Unix() emailTemplate.UpdatedAt = time.Now().Unix() - emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate) _, err := emailTemplateCollection.CreateDocument(ctx, emailTemplate) if err != nil { @@ -33,13 +31,11 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E // UpdateEmailTemplate to update EmailTemplate func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() - emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate) meta, err := emailTemplateCollection.UpdateDocument(ctx, emailTemplate.Key, emailTemplate) if err != nil { return nil, err } - emailTemplate.Key = meta.Key emailTemplate.ID = meta.ID.String() return emailTemplate.AsAPIEmailTemplate(), nil @@ -57,22 +53,18 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi defer cursor.Close() paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() - for { var emailTemplate *models.EmailTemplate meta, err := cursor.ReadDocument(ctx, &emailTemplate) - if arangoDriver.IsNoMoreDocuments(err) { break } else if err != nil { return nil, err } - if meta.Key != "" { emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate()) } } - return &model.EmailTemplates{ Pagination: paginationClone, EmailTemplates: emailTemplates, @@ -86,16 +78,14 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str bindVars := map[string]interface{}{ "email_template_id": emailTemplateID, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return nil, err } defer cursor.Close() - for { if !cursor.HasMore() { - if emailTemplate.Key == "" { + if emailTemplate == nil { return nil, fmt.Errorf("email template not found") } break @@ -115,16 +105,14 @@ func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName st bindVars := map[string]interface{}{ "event_name": eventName, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return nil, err } defer cursor.Close() - for { if !cursor.HasMore() { - if emailTemplate.Key == "" { + if emailTemplate == nil { return nil, fmt.Errorf("email template not found") } break diff --git a/server/db/providers/arangodb/env.go b/server/db/providers/arangodb/env.go index 1bc8162..bb4610a 100644 --- a/server/db/providers/arangodb/env.go +++ b/server/db/providers/arangodb/env.go @@ -48,16 +48,14 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { var env *models.Env query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env) - cursor, err := p.db.Query(ctx, query, nil) if err != nil { return env, err } defer cursor.Close() - for { if !cursor.HasMore() { - if env.Key == "" { + if env == nil { return env, fmt.Errorf("config not found") } break diff --git a/server/db/providers/arangodb/otp.go b/server/db/providers/arangodb/otp.go index 8fef639..3f8f464 100644 --- a/server/db/providers/arangodb/otp.go +++ b/server/db/providers/arangodb/otp.go @@ -44,10 +44,8 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models otp.Otp = otpParam.Otp otp.ExpiresAt = otpParam.ExpiresAt } - otp.UpdatedAt = time.Now().Unix() otpCollection, _ := p.db.Collection(ctx, models.Collections.OTP) - var meta driver.DocumentMeta var err error if shouldCreate { @@ -55,11 +53,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models } else { meta, err = otpCollection.UpdateDocument(ctx, otp.Key, otp) } - if err != nil { return nil, err } - otp.Key = meta.Key otp.ID = meta.ID.String() return otp, nil @@ -67,21 +63,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models // GetOTPByEmail to get otp for a given email address func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { - var otp models.OTP + var otp *models.OTP query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.OTP) bindVars := map[string]interface{}{ "email": emailAddress, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return nil, err } defer cursor.Close() - for { if !cursor.HasMore() { - if otp.Key == "" { + if otp == nil { return nil, fmt.Errorf("otp with given email not found") } break @@ -91,13 +85,12 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod return nil, err } } - - return &otp, nil + return otp, nil } // GetOTPByPhoneNumber to get otp for a given phone number func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) { - var otp models.OTP + var otp *models.OTP query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.OTP) bindVars := map[string]interface{}{ "phone_number": phoneNumber, @@ -109,7 +102,7 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) defer cursor.Close() for { if !cursor.HasMore() { - if otp.Key == "" { + if otp == nil { return nil, fmt.Errorf("otp with given phone_number not found") } break @@ -119,8 +112,7 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) return nil, err } } - - return &otp, nil + return otp, nil } // DeleteOTP to delete otp @@ -130,6 +122,5 @@ func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { if err != nil { return err } - return nil } diff --git a/server/db/providers/arangodb/provider.go b/server/db/providers/arangodb/provider.go index 979d56e..507a938 100644 --- a/server/db/providers/arangodb/provider.go +++ b/server/db/providers/arangodb/provider.go @@ -61,7 +61,6 @@ func NewProvider() (*provider, error) { if err != nil { return nil, err } - var arangodb arangoDriver.Database dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName arangodb_exists, err := arangoClient.DatabaseExists(ctx, dbName) @@ -79,7 +78,6 @@ func NewProvider() (*provider, error) { return nil, err } } - userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User) if err != nil { return nil, err @@ -113,7 +111,6 @@ func NewProvider() (*provider, error) { return nil, err } } - verificationRequestCollection, err := arangodb.Collection(ctx, models.Collections.VerificationRequest) if err != nil { return nil, err @@ -136,7 +133,6 @@ func NewProvider() (*provider, error) { return nil, err } } - sessionCollection, err := arangodb.Collection(ctx, models.Collections.Session) if err != nil { return nil, err @@ -144,7 +140,6 @@ func NewProvider() (*provider, error) { sessionCollection.EnsureHashIndex(ctx, []string{"user_id"}, &arangoDriver.EnsureHashIndexOptions{ Sparse: true, }) - envCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Env) if err != nil { return nil, err @@ -155,7 +150,6 @@ func NewProvider() (*provider, error) { return nil, err } } - webhookCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Webhook) if err != nil { return nil, err @@ -166,7 +160,6 @@ func NewProvider() (*provider, error) { return nil, err } } - webhookCollection, err := arangodb.Collection(ctx, models.Collections.Webhook) if err != nil { return nil, err @@ -186,7 +179,6 @@ func NewProvider() (*provider, error) { return nil, err } } - webhookLogCollection, err := arangodb.Collection(ctx, models.Collections.WebhookLog) if err != nil { return nil, err @@ -194,7 +186,6 @@ func NewProvider() (*provider, error) { webhookLogCollection.EnsureHashIndex(ctx, []string{"webhook_id"}, &arangoDriver.EnsureHashIndexOptions{ Sparse: true, }) - emailTemplateCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.EmailTemplate) if err != nil { return nil, err @@ -205,7 +196,6 @@ func NewProvider() (*provider, error) { return nil, err } } - emailTemplateCollection, err := arangodb.Collection(ctx, models.Collections.EmailTemplate) if err != nil { return nil, err @@ -214,7 +204,6 @@ func NewProvider() (*provider, error) { Unique: true, Sparse: true, }) - otpCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.OTP) if err != nil { return nil, err diff --git a/server/db/providers/arangodb/session.go b/server/db/providers/arangodb/session.go index 5672b73..5dc981d 100644 --- a/server/db/providers/arangodb/session.go +++ b/server/db/providers/arangodb/session.go @@ -14,7 +14,6 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro session.ID = uuid.New().String() session.Key = session.ID } - session.CreatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix() sessionCollection, _ := p.db.Collection(ctx, models.Collections.Session) @@ -24,3 +23,8 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro } return nil } + +// DeleteSession to delete session information from database +func (p *provider) DeleteSession(ctx context.Context, userId string) error { + return nil +} diff --git a/server/db/providers/arangodb/user.go b/server/db/providers/arangodb/user.go index c5572c0..926cdb9 100644 --- a/server/db/providers/arangodb/user.go +++ b/server/db/providers/arangodb/user.go @@ -73,7 +73,6 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { if err != nil { return err } - query := fmt.Sprintf(`FOR d IN %s FILTER d.user_id == @user_id REMOVE { _key: d._key } IN %s`, models.Collections.Session, models.Collections.Session) bindVars := map[string]interface{}{ "user_id": user.Key, @@ -83,7 +82,6 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error { return err } defer cursor.Close() - return nil } @@ -93,16 +91,13 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) sctx := arangoDriver.WithQueryFullCount(ctx) query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.User, pagination.Offset, pagination.Limit) - cursor, err := p.db.Query(sctx, query, nil) if err != nil { return nil, err } defer cursor.Close() - paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() - for { var user *models.User meta, err := cursor.ReadDocument(ctx, &user) @@ -115,7 +110,6 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) users = append(users, user.AsAPIUser()) } } - return &model.Users{ Pagination: paginationClone, Users: users, @@ -136,7 +130,7 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us defer cursor.Close() for { if !cursor.HasMore() { - if user.Key == "" { + if user == nil { return user, fmt.Errorf("user not found") } break @@ -163,7 +157,7 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, er defer cursor.Close() for { if !cursor.HasMore() { - if user.Key == "" { + if user == nil { return user, fmt.Errorf("user not found") } break @@ -218,7 +212,7 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) defer cursor.Close() for { if !cursor.HasMore() { - if user.Key == "" { + if user == nil { return nil, fmt.Errorf("user not found") } break diff --git a/server/db/providers/arangodb/verification_requests.go b/server/db/providers/arangodb/verification_requests.go index 0bbdad4..05a8186 100644 --- a/server/db/providers/arangodb/verification_requests.go +++ b/server/db/providers/arangodb/verification_requests.go @@ -17,7 +17,6 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque verificationRequest.ID = uuid.New().String() verificationRequest.Key = verificationRequest.ID } - verificationRequest.CreatedAt = time.Now().Unix() verificationRequest.UpdatedAt = time.Now().Unix() verificationRequestRequestCollection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest) @@ -27,7 +26,6 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque } verificationRequest.Key = meta.Key verificationRequest.ID = meta.ID.String() - return verificationRequest, nil } @@ -38,16 +36,14 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri bindVars := map[string]interface{}{ "token": token, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return verificationRequest, err } defer cursor.Close() - for { if !cursor.HasMore() { - if verificationRequest.Key == "" { + if verificationRequest == nil { return verificationRequest, fmt.Errorf("verification request not found") } break @@ -57,29 +53,25 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri return verificationRequest, err } } - return verificationRequest, nil } // GetVerificationRequestByEmail to get verification request by email from database func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { var verificationRequest *models.VerificationRequest - query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", models.Collections.VerificationRequest) bindVars := map[string]interface{}{ "email": email, "identifier": identifier, } - cursor, err := p.db.Query(ctx, query, bindVars) if err != nil { return verificationRequest, err } defer cursor.Close() - for { if !cursor.HasMore() { - if verificationRequest.Key == "" { + if verificationRequest == nil { return verificationRequest, fmt.Errorf("verification request not found") } break @@ -89,7 +81,6 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri return verificationRequest, err } } - return verificationRequest, nil } @@ -120,7 +111,6 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod } } - return &model.VerificationRequests{ VerificationRequests: verificationRequests, Pagination: paginationClone, diff --git a/server/db/providers/arangodb/webhook.go b/server/db/providers/arangodb/webhook.go index b9fa5fe..dbdc9e4 100644 --- a/server/db/providers/arangodb/webhook.go +++ b/server/db/providers/arangodb/webhook.go @@ -95,7 +95,7 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model defer cursor.Close() for { if !cursor.HasMore() { - if webhook.Key == "" { + if webhook == nil { return nil, fmt.Errorf("webhook not found") } break diff --git a/server/db/providers/arangodb/webhook_log.go b/server/db/providers/arangodb/webhook_log.go index dba46ae..64db2cb 100644 --- a/server/db/providers/arangodb/webhook_log.go +++ b/server/db/providers/arangodb/webhook_log.go @@ -17,7 +17,6 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook webhookLog.ID = uuid.New().String() webhookLog.Key = webhookLog.ID } - webhookLog.Key = webhookLog.ID webhookLog.CreatedAt = time.Now().Unix() webhookLog.UpdatedAt = time.Now().Unix() @@ -33,41 +32,33 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { webhookLogs := []*model.WebhookLog{} bindVariables := map[string]interface{}{} - query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit) - if webhookID != "" { query = fmt.Sprintf("FOR d in %s FILTER d.webhook_id == @webhook_id SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit) bindVariables = map[string]interface{}{ "webhook_id": webhookID, } } - sctx := arangoDriver.WithQueryFullCount(ctx) cursor, err := p.db.Query(sctx, query, bindVariables) if err != nil { return nil, err } defer cursor.Close() - paginationClone := pagination paginationClone.Total = cursor.Statistics().FullCount() - for { var webhookLog *models.WebhookLog meta, err := cursor.ReadDocument(ctx, &webhookLog) - if arangoDriver.IsNoMoreDocuments(err) { break } else if err != nil { return nil, err } - if meta.Key != "" { webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog()) } } - return &model.WebhookLogs{ Pagination: paginationClone, WebhookLogs: webhookLogs, diff --git a/server/db/providers/cassandradb/email_template.go b/server/db/providers/cassandradb/email_template.go index 06b7708..9adb768 100644 --- a/server/db/providers/cassandradb/email_template.go +++ b/server/db/providers/cassandradb/email_template.go @@ -19,29 +19,24 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } - emailTemplate.Key = emailTemplate.ID emailTemplate.CreatedAt = time.Now().Unix() emailTemplate.UpdatedAt = time.Now().Unix() - existingEmailTemplate, _ := p.GetEmailTemplateByEventName(ctx, emailTemplate.EventName) if existingEmailTemplate != nil { return nil, fmt.Errorf("Email template with %s event_name already exists", emailTemplate.EventName) } - insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, design, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Design, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt) err := p.db.Query(insertQuery).Exec() if err != nil { return nil, err } - return emailTemplate.AsAPIEmailTemplate(), nil } // UpdateEmailTemplate to update EmailTemplate func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() - bytes, err := json.Marshal(emailTemplate) if err != nil { return nil, err @@ -54,22 +49,18 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *model if err != nil { return nil, err } - updateFields := "" for key, value := range emailTemplateMap { if key == "_id" { continue } - if key == "_key" { continue } - if value == nil { updateFields += fmt.Sprintf("%s = null,", key) continue } - valueType := reflect.TypeOf(value) if valueType.Name() == "string" { updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string)) @@ -95,7 +86,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.EmailTemplate) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) if err != nil { return nil, err } @@ -109,7 +100,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var emailTemplate *models.EmailTemplate + var emailTemplate models.EmailTemplate err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { return nil, err @@ -127,7 +118,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi // GetEmailTemplateByID to get EmailTemplate by id func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { - var emailTemplate *models.EmailTemplate + var emailTemplate models.EmailTemplate query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { @@ -138,7 +129,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate *models.EmailTemplate + var emailTemplate models.EmailTemplate query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) if err != nil { diff --git a/server/db/providers/cassandradb/env.go b/server/db/providers/cassandradb/env.go index 16c4050..636f9f4 100644 --- a/server/db/providers/cassandradb/env.go +++ b/server/db/providers/cassandradb/env.go @@ -15,7 +15,6 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er if env.ID == "" { env.ID = uuid.New().String() } - env.CreatedAt = time.Now().Unix() env.UpdatedAt = time.Now().Unix() insertEnvQuery := fmt.Sprintf("INSERT INTO %s (id, env, hash, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Env, env.ID, env.EnvData, env.Hash, env.CreatedAt, env.UpdatedAt) @@ -30,7 +29,6 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er // UpdateEnv to update environment information in database func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { env.UpdatedAt = time.Now().Unix() - updateEnvQuery := fmt.Sprintf("UPDATE %s SET env = '%s', updated_at = %d WHERE id = '%s'", KeySpace+"."+models.Collections.Env, env.EnvData, env.UpdatedAt, env.ID) err := p.db.Query(updateEnvQuery).Exec() if err != nil { @@ -41,13 +39,11 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, // GetEnv to get environment information from database func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { - var env *models.Env - + var env models.Env query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+models.Collections.Env) err := p.db.Query(query).Consistency(gocql.One).Scan(&env.ID, &env.EnvData, &env.Hash, &env.CreatedAt, &env.UpdatedAt) if err != nil { - return env, err + return nil, err } - - return env, nil + return &env, nil } diff --git a/server/db/providers/cassandradb/session.go b/server/db/providers/cassandradb/session.go index c8d9232..bdf205c 100644 --- a/server/db/providers/cassandradb/session.go +++ b/server/db/providers/cassandradb/session.go @@ -14,10 +14,8 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro if session.ID == "" { session.ID = uuid.New().String() } - session.CreatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix() - insertSessionQuery := fmt.Sprintf("INSERT INTO %s (id, user_id, user_agent, ip, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Session, session.ID, session.UserID, session.UserAgent, session.IP, session.CreatedAt, session.UpdatedAt) err := p.db.Query(insertSessionQuery).Exec() if err != nil { @@ -25,3 +23,8 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro } return nil } + +// DeleteSession to delete session information from database +func (p *provider) DeleteSession(ctx context.Context, userId string) error { + return nil +} diff --git a/server/db/providers/cassandradb/user.go b/server/db/providers/cassandradb/user.go index e290049..376a6db 100644 --- a/server/db/providers/cassandradb/user.go +++ b/server/db/providers/cassandradb/user.go @@ -77,7 +77,6 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User values = values[:len(values)-1] + ")" query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values) - err = p.db.Query(query).Exec() if err != nil { return user, err @@ -170,7 +169,7 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) responseUsers := []*model.User{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) if err != nil { return nil, err } @@ -183,8 +182,8 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var user *models.User - err := scanner.Scan(user.ID, user.Email, user.EmailVerifiedAt, user.Password, user.SignupMethods, user.GivenName, user.FamilyName, user.MiddleName, user.Nickname, user.Birthdate, user.PhoneNumber, user.PhoneNumberVerifiedAt, user.Picture, user.Roles, user.RevokedTimestamp, user.IsMultiFactorAuthEnabled, user.CreatedAt, user.UpdatedAt) + var user models.User + err := scanner.Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { return nil, err } @@ -200,24 +199,24 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) // GetUserByEmail to get user information from database using email address func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) { - var user *models.User + var user models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, email) err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { - return user, err + return nil, err } - return user, nil + return &user, nil } // GetUserByID to get user information from database using user ID func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) { - var user *models.User + var user models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+models.Collections.User, id) err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { - return user, err + return nil, err } - return user, nil + return &user, nil } // UpdateUsers to update multiple users, with parameters of user IDs slice @@ -306,11 +305,11 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, // GetUserByPhoneNumber to get user information from database using phone number func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) { - var user *models.User + var user models.User query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber) - err := p.db.Query(query).Consistency(gocql.One).Scan(user.ID, user.Email, user.EmailVerifiedAt, user.Password, user.SignupMethods, user.GivenName, user.FamilyName, user.MiddleName, user.Nickname, user.Birthdate, user.PhoneNumber, user.PhoneNumberVerifiedAt, user.Picture, user.Roles, user.RevokedTimestamp, user.IsMultiFactorAuthEnabled, user.CreatedAt, user.UpdatedAt) + err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt) if err != nil { return nil, err } - return user, nil + return &user, nil } diff --git a/server/db/providers/cassandradb/verification_requests.go b/server/db/providers/cassandradb/verification_requests.go index f35196a..2fffee4 100644 --- a/server/db/providers/cassandradb/verification_requests.go +++ b/server/db/providers/cassandradb/verification_requests.go @@ -30,27 +30,27 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque // GetVerificationRequestByToken to get verification request from database using token func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { - var verificationRequest *models.VerificationRequest + var verificationRequest models.VerificationRequest query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE jwt_token = '%s' LIMIT 1`, KeySpace+"."+models.Collections.VerificationRequest, token) err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) if err != nil { - return verificationRequest, err + return nil, err } - return verificationRequest, nil + return &verificationRequest, nil } // GetVerificationRequestByEmail to get verification request by email from database func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) { - var verificationRequest *models.VerificationRequest + var verificationRequest models.VerificationRequest query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE email = '%s' AND identifier = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.VerificationRequest, email, identifier) err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) if err != nil { - return verificationRequest, err + return nil, err } - return verificationRequest, nil + return &verificationRequest, nil } // ListVerificationRequests to get list of verification requests from database @@ -58,11 +58,10 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod var verificationRequests []*model.VerificationRequest paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) if err != nil { return nil, err } - // there is no offset in cassandra // so we fetch till limit + offset // and return the results from offset to limit @@ -72,9 +71,10 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var verificationRequest *models.VerificationRequest + var verificationRequest models.VerificationRequest err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) if err != nil { + fmt.Println("=> getting error here...", err) return nil, err } verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest()) diff --git a/server/db/providers/cassandradb/webhook.go b/server/db/providers/cassandradb/webhook.go index b9b8abf..e80dfdd 100644 --- a/server/db/providers/cassandradb/webhook.go +++ b/server/db/providers/cassandradb/webhook.go @@ -85,7 +85,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination webhooks := []*model.Webhook{} paginationClone := pagination totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook) - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var webhook *models.Webhook + var webhook models.Webhook err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { return nil, err @@ -115,7 +115,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination // GetWebhookByID to get webhook by id func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) { - var webhook *models.Webhook + var webhook models.Webhook query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID) err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { @@ -130,7 +130,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) scanner := p.db.Query(query).Iter().Scanner() webhooks := []*model.Webhook{} for scanner.Next() { - var webhook *models.Webhook + var webhook models.Webhook err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt) if err != nil { return nil, err diff --git a/server/db/providers/cassandradb/webhook_log.go b/server/db/providers/cassandradb/webhook_log.go index 3eded48..d587e02 100644 --- a/server/db/providers/cassandradb/webhook_log.go +++ b/server/db/providers/cassandradb/webhook_log.go @@ -38,13 +38,12 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina // so we fetch till limit + offset // and return the results from offset to limit query := fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.WebhookLog, pagination.Limit+pagination.Offset) - if webhookID != "" { totalCountQuery = fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE webhook_id='%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.WebhookLog, webhookID) query = fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s WHERE webhook_id = '%s' LIMIT %d ALLOW FILTERING", KeySpace+"."+models.Collections.WebhookLog, webhookID, pagination.Limit+pagination.Offset) } - err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(paginationClone.Total) + err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) if err != nil { return nil, err } @@ -53,7 +52,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina counter := int64(0) for scanner.Next() { if counter >= pagination.Offset { - var webhookLog *models.WebhookLog + var webhookLog models.WebhookLog err := scanner.Scan(&webhookLog.ID, &webhookLog.HttpStatus, &webhookLog.Response, &webhookLog.Request, &webhookLog.WebhookID, &webhookLog.CreatedAt, &webhookLog.UpdatedAt) if err != nil { return nil, err diff --git a/server/db/providers/couchbase/email_template.go b/server/db/providers/couchbase/email_template.go index 9b58999..14f5ba9 100644 --- a/server/db/providers/couchbase/email_template.go +++ b/server/db/providers/couchbase/email_template.go @@ -116,38 +116,32 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str ScanConsistency: gocb.QueryScanConsistencyRequestPlus, PositionalParameters: []interface{}{emailTemplateID}, }) - if err != nil { return nil, err } err = q.One(&emailTemplate) - if err != nil { return nil, err } - return emailTemplate.AsAPIEmailTemplate(), nil } // GetEmailTemplateByEventName to get EmailTemplate by event_name func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { - var emailTemplate *models.EmailTemplate + var emailTemplate models.EmailTemplate query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE event_name=$1 LIMIT 1", p.scopeName, models.Collections.EmailTemplate) q, err := p.db.Query(query, &gocb.QueryOptions{ Context: ctx, ScanConsistency: gocb.QueryScanConsistencyRequestPlus, PositionalParameters: []interface{}{eventName}, }) - if err != nil { return nil, err } err = q.One(&emailTemplate) - if err != nil { return nil, err } - return emailTemplate.AsAPIEmailTemplate(), nil } diff --git a/server/db/providers/couchbase/env.go b/server/db/providers/couchbase/env.go index 77d9aeb..3f24937 100644 --- a/server/db/providers/couchbase/env.go +++ b/server/db/providers/couchbase/env.go @@ -19,7 +19,6 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er env.UpdatedAt = time.Now().Unix() env.Key = env.ID env.EncryptionKey = env.Hash - insertOpt := gocb.InsertOptions{ Context: ctx, } @@ -40,11 +39,9 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, Context: ctx, PositionalParameters: []interface{}{env.EnvData, env.UpdatedAt, env.UpdatedAt, env.ID}, }) - if err != nil { return env, err } - return env, nil } @@ -61,7 +58,6 @@ func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { return env, err } err = q.One(&env) - if err != nil { return env, err } diff --git a/server/db/providers/couchbase/session.go b/server/db/providers/couchbase/session.go index 7907bdb..a3b9915 100644 --- a/server/db/providers/couchbase/session.go +++ b/server/db/providers/couchbase/session.go @@ -14,7 +14,6 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro if session.ID == "" { session.ID = uuid.New().String() } - session.CreatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix() insertOpt := gocb.InsertOptions{ @@ -24,7 +23,6 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro if err != nil { return err } - return nil } diff --git a/server/db/providers/couchbase/shared.go b/server/db/providers/couchbase/shared.go index d640f68..00a8cfa 100644 --- a/server/db/providers/couchbase/shared.go +++ b/server/db/providers/couchbase/shared.go @@ -41,14 +41,11 @@ func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interfa func (p *provider) GetTotalDocs(ctx context.Context, collection string) (int64, error) { totalDocs := TotalDocs{} - countQuery := fmt.Sprintf("SELECT COUNT(*) as Total FROM %s.%s", p.scopeName, collection) queryRes, err := p.db.Query(countQuery, &gocb.QueryOptions{ Context: ctx, }) - queryRes.One(&totalDocs) - if err != nil { return totalDocs.Total, err } diff --git a/server/db/providers/couchbase/user.go b/server/db/providers/couchbase/user.go index 5850f36..f5d2195 100644 --- a/server/db/providers/couchbase/user.go +++ b/server/db/providers/couchbase/user.go @@ -84,7 +84,7 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) } paginationClone.Total = total for queryResult.Next() { - var user *models.User + var user models.User err := queryResult.Row(&user) if err != nil { log.Fatal(err) diff --git a/server/db/providers/couchbase/verification_requests.go b/server/db/providers/couchbase/verification_requests.go index f1d2b00..314f69a 100644 --- a/server/db/providers/couchbase/verification_requests.go +++ b/server/db/providers/couchbase/verification_requests.go @@ -17,7 +17,6 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() } - verificationRequest.Key = verificationRequest.ID verificationRequest.CreatedAt = time.Now().Unix() verificationRequest.UpdatedAt = time.Now().Unix() @@ -28,7 +27,6 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque if err != nil { return verificationRequest, err } - return verificationRequest, nil } @@ -95,7 +93,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod return nil, err } for queryResult.Next() { - var verificationRequest *models.VerificationRequest + var verificationRequest models.VerificationRequest err := queryResult.Row(&verificationRequest) if err != nil { log.Fatal(err) diff --git a/server/db/providers/couchbase/webhook.go b/server/db/providers/couchbase/webhook.go index 9647419..92b0111 100644 --- a/server/db/providers/couchbase/webhook.go +++ b/server/db/providers/couchbase/webhook.go @@ -89,7 +89,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination return nil, err } for queryResult.Next() { - var webhook *models.Webhook + var webhook models.Webhook err := queryResult.Row(&webhook) if err != nil { log.Fatal(err) @@ -162,11 +162,9 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er Context: ctx, } _, err := p.db.Collection(models.Collections.Webhook).Remove(webhook.ID, &removeOpt) - if err != nil { return err } - query := fmt.Sprintf(`DELETE FROM %s.%s WHERE webhook_id=$webhook_id`, p.scopeName, models.Collections.WebhookLog) _, err = p.db.Query(query, &gocb.QueryOptions{ Context: ctx, @@ -176,6 +174,5 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er if err != nil { return err } - return nil } diff --git a/server/db/providers/couchbase/webhook_log.go b/server/db/providers/couchbase/webhook_log.go index 73d45dd..0482394 100644 --- a/server/db/providers/couchbase/webhook_log.go +++ b/server/db/providers/couchbase/webhook_log.go @@ -17,11 +17,9 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } - webhookLog.Key = webhookLog.ID webhookLog.CreatedAt = time.Now().Unix() webhookLog.UpdatedAt = time.Now().Unix() - insertOpt := gocb.InsertOptions{ Context: ctx, } @@ -29,7 +27,6 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook if err != nil { return webhookLog.AsAPIWebhookLog(), err } - return webhookLog.AsAPIWebhookLog(), nil } @@ -37,11 +34,9 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) { var query string var err error - webhookLogs := []*model.WebhookLog{} params := make(map[string]interface{}, 1) paginationClone := pagination - params["webhookID"] = webhookID params["offset"] = paginationClone.Offset params["limit"] = paginationClone.Limit @@ -55,25 +50,22 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina } else { query = fmt.Sprintf("SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.WebhookLog) } - queryResult, err := p.db.Query(query, &gocb.QueryOptions{ Context: ctx, ScanConsistency: gocb.QueryScanConsistencyRequestPlus, NamedParameters: params, }) - if err != nil { return nil, err } for queryResult.Next() { - var webhookLog *models.WebhookLog + var webhookLog models.WebhookLog err := queryResult.Row(&webhookLog) if err != nil { log.Fatal(err) } webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog()) } - if err := queryResult.Err(); err != nil { return nil, err diff --git a/server/db/providers/dynamodb/email_template.go b/server/db/providers/dynamodb/email_template.go index 091c841..7355bbb 100644 --- a/server/db/providers/dynamodb/email_template.go +++ b/server/db/providers/dynamodb/email_template.go @@ -43,22 +43,18 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *model // ListEmailTemplates to list EmailTemplate func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) { - var emailTemplate *models.EmailTemplate var iter dynamo.PagingIter var lastEval dynamo.PagingKey var iteration int64 = 0 - collection := p.db.Table(models.Collections.EmailTemplate) emailTemplates := []*model.EmailTemplate{} paginationClone := pagination scanner := collection.Scan() count, err := scanner.Count() - if err != nil { return nil, err } - for (paginationClone.Offset + paginationClone.Limit) > iteration { iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter() for iter.NextWithContext(ctx, &emailTemplate) { @@ -69,9 +65,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi lastEval = iter.LastEvaluatedKey() iteration += paginationClone.Limit } - paginationClone.Total = count - return &model.EmailTemplates{ Pagination: paginationClone, EmailTemplates: emailTemplates, @@ -111,7 +105,6 @@ func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName st func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error { collection := p.db.Table(models.Collections.EmailTemplate) err := collection.Delete("id", emailTemplate.ID).RunWithContext(ctx) - if err != nil { return err } diff --git a/server/db/providers/dynamodb/env.go b/server/db/providers/dynamodb/env.go index daa2e3e..0b356f7 100644 --- a/server/db/providers/dynamodb/env.go +++ b/server/db/providers/dynamodb/env.go @@ -13,22 +13,16 @@ import ( // AddEnv to save environment information in database func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) { collection := p.db.Table(models.Collections.Env) - if env.ID == "" { env.ID = uuid.New().String() } - env.Key = env.ID - env.CreatedAt = time.Now().Unix() env.UpdatedAt = time.Now().Unix() - err := collection.Put(env).RunWithContext(ctx) - if err != nil { return env, err } - return env, nil } @@ -36,9 +30,7 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) { collection := p.db.Table(models.Collections.Env) env.UpdatedAt = time.Now().Unix() - err := UpdateByHashKey(collection, "id", env.ID, env) - if err != nil { return env, err } @@ -48,24 +40,19 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, // GetEnv to get environment information from database func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { var env *models.Env - collection := p.db.Table(models.Collections.Env) // As there is no Findone supported. iter := collection.Scan().Limit(1).Iter() - for iter.NextWithContext(ctx, &env) { - if env.ID == "" { + if env == nil { return env, errors.New("no documets found") } else { return env, nil } } - err := iter.Err() - if err != nil { return env, fmt.Errorf("config not found") } - return env, nil } diff --git a/server/db/providers/dynamodb/otp.go b/server/db/providers/dynamodb/otp.go index d4abf73..23273e2 100644 --- a/server/db/providers/dynamodb/otp.go +++ b/server/db/providers/dynamodb/otp.go @@ -91,7 +91,6 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) // DeleteOTP to delete otp func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { collection := p.db.Table(models.Collections.OTP) - if otp.ID != "" { err := collection.Delete("id", otp.ID).RunWithContext(ctx) if err != nil { diff --git a/server/db/providers/dynamodb/provider.go b/server/db/providers/dynamodb/provider.go index 7935e37..4cc4084 100644 --- a/server/db/providers/dynamodb/provider.go +++ b/server/db/providers/dynamodb/provider.go @@ -42,10 +42,8 @@ func NewProvider() (*provider, error) { } else { log.Debugf("%s or %s or %s not found. Trying to load default credentials from aws config", constants.EnvAwsRegion, constants.EnvAwsAccessKeyID, constants.EnvAwsSecretAccessKey) } - session := session.Must(session.NewSession(&config)) db := dynamo.New(session) - db.CreateTable(models.Collections.User, models.User{}).Wait() db.CreateTable(models.Collections.Session, models.Session{}).Wait() db.CreateTable(models.Collections.EmailTemplate, models.EmailTemplate{}).Wait() @@ -54,7 +52,6 @@ func NewProvider() (*provider, error) { db.CreateTable(models.Collections.VerificationRequest, models.VerificationRequest{}).Wait() db.CreateTable(models.Collections.Webhook, models.Webhook{}).Wait() db.CreateTable(models.Collections.WebhookLog, models.WebhookLog{}).Wait() - return &provider{ db: db, }, nil diff --git a/server/db/providers/dynamodb/session.go b/server/db/providers/dynamodb/session.go index 03218b3..d65da9a 100644 --- a/server/db/providers/dynamodb/session.go +++ b/server/db/providers/dynamodb/session.go @@ -11,11 +11,9 @@ import ( // AddSession to save session information in database func (p *provider) AddSession(ctx context.Context, session *models.Session) error { collection := p.db.Table(models.Collections.Session) - if session.ID == "" { session.ID = uuid.New().String() } - session.CreatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix() err := collection.Put(session).RunWithContext(ctx) diff --git a/server/db/providers/dynamodb/shared.go b/server/db/providers/dynamodb/shared.go index ed91eca..5597c0a 100644 --- a/server/db/providers/dynamodb/shared.go +++ b/server/db/providers/dynamodb/shared.go @@ -9,16 +9,13 @@ import ( func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item interface{}) error { existingValue, err := dynamo.MarshalItem(item) var i interface{} - if err != nil { return err } - nullableValue, err := dynamodbattribute.MarshalMap(item) if err != nil { return err } - u := table.Update(hashKey, hashValue) for k, v := range existingValue { if k == hashKey { @@ -26,7 +23,6 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item } u = u.Set(k, v) } - for k, v := range nullableValue { if k == hashKey { continue @@ -36,11 +32,9 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item u = u.SetNullable(k, v) } } - err = u.Run() if err != nil { return err } - return nil } diff --git a/server/db/providers/dynamodb/verification_requests.go b/server/db/providers/dynamodb/verification_requests.go index e261c2f..0ae0365 100644 --- a/server/db/providers/dynamodb/verification_requests.go +++ b/server/db/providers/dynamodb/verification_requests.go @@ -13,7 +13,6 @@ import ( // AddVerification to save verification request in database func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) { collection := p.db.Table(models.Collections.VerificationRequest) - if verificationRequest.ID == "" { verificationRequest.ID = uuid.New().String() verificationRequest.CreatedAt = time.Now().Unix() @@ -23,7 +22,6 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque return verificationRequest, err } } - return verificationRequest, nil } @@ -31,12 +29,10 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) { collection := p.db.Table(models.Collections.VerificationRequest) var verificationRequest *models.VerificationRequest - iter := collection.Scan().Filter("'token' = ?", token).Iter() for iter.NextWithContext(ctx, &verificationRequest) { return verificationRequest, nil } - err := iter.Err() if err != nil { return verificationRequest, err @@ -52,7 +48,6 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri for iter.NextWithContext(ctx, &verificationRequest) { return verificationRequest, nil } - err := iter.Err() if err != nil { return verificationRequest, err @@ -67,17 +62,13 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod var lastEval dynamo.PagingKey var iter dynamo.PagingIter var iteration int64 = 0 - collection := p.db.Table(models.Collections.VerificationRequest) paginationClone := pagination - scanner := collection.Scan() count, err := scanner.Count() - if err != nil { return nil, err } - for (paginationClone.Offset + paginationClone.Limit) > iteration { iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter() for iter.NextWithContext(ctx, &verificationRequest) { @@ -92,9 +83,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod lastEval = iter.LastEvaluatedKey() iteration += paginationClone.Limit } - paginationClone.Total = count - return &model.VerificationRequests{ VerificationRequests: verificationRequests, Pagination: paginationClone, @@ -104,7 +93,6 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod // DeleteVerificationRequest to delete verification request from database func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { collection := p.db.Table(models.Collections.VerificationRequest) - if verificationRequest.ID != "" { err := collection.Delete("id", verificationRequest.ID).RunWithContext(ctx) diff --git a/server/db/providers/dynamodb/webhook_log.go b/server/db/providers/dynamodb/webhook_log.go index a1fc8ca..18ba261 100644 --- a/server/db/providers/dynamodb/webhook_log.go +++ b/server/db/providers/dynamodb/webhook_log.go @@ -13,16 +13,13 @@ import ( // AddWebhookLog to add webhook log func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) { collection := p.db.Table(models.Collections.WebhookLog) - if webhookLog.ID == "" { webhookLog.ID = uuid.New().String() } - webhookLog.Key = webhookLog.ID webhookLog.CreatedAt = time.Now().Unix() webhookLog.UpdatedAt = time.Now().Unix() err := collection.Put(webhookLog).RunWithContext(ctx) - if err != nil { return nil, err } @@ -42,7 +39,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina collection := p.db.Table(models.Collections.WebhookLog) paginationClone := pagination scanner := collection.Scan() - if webhookID != "" { iter = scanner.Index("webhook_id").Filter("'webhook_id' = ?", webhookID).Iter() for iter.NextWithContext(ctx, &webhookLog) { @@ -68,7 +64,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina iteration += paginationClone.Limit } } - paginationClone.Total = count // paginationClone.Cursor = iter.LastEvaluatedKey() return &model.WebhookLogs{ diff --git a/server/db/providers/mongodb/email_template.go b/server/db/providers/mongodb/email_template.go index f412b4c..c3fa31b 100644 --- a/server/db/providers/mongodb/email_template.go +++ b/server/db/providers/mongodb/email_template.go @@ -16,11 +16,9 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E if emailTemplate.ID == "" { emailTemplate.ID = uuid.New().String() } - emailTemplate.Key = emailTemplate.ID emailTemplate.CreatedAt = time.Now().Unix() emailTemplate.UpdatedAt = time.Now().Unix() - emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) _, err := emailTemplateCollection.InsertOne(ctx, emailTemplate) if err != nil { @@ -32,13 +30,11 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E // UpdateEmailTemplate to update EmailTemplate func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) { emailTemplate.UpdatedAt = time.Now().Unix() - emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) _, err := emailTemplateCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": emailTemplate.ID}}, bson.M{"$set": emailTemplate}, options.MergeUpdateOptions()) if err != nil { return nil, err } - return emailTemplate.AsAPIEmailTemplate(), nil } @@ -49,23 +45,18 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi opts.SetLimit(pagination.Limit) opts.SetSkip(pagination.Offset) opts.SetSort(bson.M{"created_at": -1}) - paginationClone := pagination - emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection()) count, err := emailTemplateCollection.CountDocuments(ctx, bson.M{}, options.Count()) if err != nil { return nil, err } - paginationClone.Total = count - cursor, err := emailTemplateCollection.Find(ctx, bson.M{}, opts) if err != nil { return nil, err } defer cursor.Close(ctx) - for cursor.Next(ctx) { var emailTemplate *models.EmailTemplate err := cursor.Decode(&emailTemplate) @@ -74,7 +65,6 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi } emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate()) } - return &model.EmailTemplates{ Pagination: paginationClone, EmailTemplates: emailTemplates, @@ -110,6 +100,5 @@ func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model if err != nil { return err } - return nil } diff --git a/server/db/providers/mongodb/env.go b/server/db/providers/mongodb/env.go index ec6afd9..b725612 100644 --- a/server/db/providers/mongodb/env.go +++ b/server/db/providers/mongodb/env.go @@ -16,7 +16,6 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er if env.ID == "" { env.ID = uuid.New().String() } - env.CreatedAt = time.Now().Unix() env.UpdatedAt = time.Now().Unix() env.Key = env.ID @@ -48,17 +47,14 @@ func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) { return env, err } defer cursor.Close(ctx) - for cursor.Next(nil) { err := cursor.Decode(&env) if err != nil { return env, err } } - - if env.ID == "" { + if env == nil { return env, fmt.Errorf("config not found") } - return env, nil } diff --git a/server/db/providers/mongodb/session.go b/server/db/providers/mongodb/session.go index 01b35bc..860eeef 100644 --- a/server/db/providers/mongodb/session.go +++ b/server/db/providers/mongodb/session.go @@ -25,3 +25,8 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro } return nil } + +// DeleteSession to delete session information from database +func (p *provider) DeleteSession(ctx context.Context, userId string) error { + return nil +} diff --git a/server/db/providers/provider_template/session.go b/server/db/providers/provider_template/session.go index fd1e853..e398e8c 100644 --- a/server/db/providers/provider_template/session.go +++ b/server/db/providers/provider_template/session.go @@ -13,7 +13,6 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro if session.ID == "" { session.ID = uuid.New().String() } - session.CreatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix() return nil diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index 1df7e37..65b9010 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -39,6 +39,8 @@ type Provider interface { // AddSession to save session information in database AddSession(ctx context.Context, session *models.Session) error + // DeleteSession to delete session information from database + DeleteSession(ctx context.Context, userId string) error // AddEnv to save environment information in database AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) diff --git a/server/db/providers/sql/session.go b/server/db/providers/sql/session.go index 07b4849..a7e3e13 100644 --- a/server/db/providers/sql/session.go +++ b/server/db/providers/sql/session.go @@ -27,3 +27,8 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro } return nil } + +// DeleteSession to delete session information from database +func (p *provider) DeleteSession(ctx context.Context, userId string) error { + return nil +} diff --git a/server/env/env.go b/server/env/env.go index 8525927..a4bcfcc 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -19,7 +19,7 @@ import ( // InitEnv to initialize EnvData and through error if required env are not present func InitAllEnv() error { envData, err := GetEnvData() - if err != nil { + if err != nil || envData == nil { log.Info("No env data found in db, using local clone of env data") // get clone of current store envData, err = memorystore.Provider.GetEnvStore() diff --git a/server/env/persist_env.go b/server/env/persist_env.go index c930b01..83b5857 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -62,7 +62,7 @@ func GetEnvData() (map[string]interface{}, error) { ctx := context.Background() env, err := db.Provider.GetEnv(ctx) // config not found in db - if err != nil { + if err != nil || env == nil { log.Debug("Error while getting env data from db: ", err) return result, err } @@ -112,7 +112,7 @@ func PersistEnv() error { ctx := context.Background() env, err := db.Provider.GetEnv(ctx) // config not found in db - if err != nil || env.EnvData == "" { + if err != nil || env == nil { // AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid hash := uuid.New().String()[:36-4] err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash) @@ -121,19 +121,16 @@ func PersistEnv() error { return err } encodedHash := crypto.EncryptB64(hash) - res, err := memorystore.Provider.GetEnvStore() if err != nil { log.Debug("Error while getting env store: ", err) return err } - encryptedConfig, err := crypto.EncryptEnvData(res) if err != nil { log.Debug("Error while encrypting env data: ", err) return err } - env = &models.Env{ Hash: encodedHash, EnvData: encryptedConfig, diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 1828033..67c7f2d 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -81,13 +81,15 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR log.Debug("Failed to get user by email: ", err) } - if existingUser.EmailVerifiedAt != nil { - // email is verified - log.Debug("Email is already verified and signed up.") - return res, fmt.Errorf(`%s has already signed up`, params.Email) - } else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil { - log.Debug("Email is already signed up. Verification pending...") - return res, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", params.Email) + if existingUser != nil { + if existingUser.EmailVerifiedAt != nil { + // email is verified + log.Debug("Email is already verified and signed up.") + return res, fmt.Errorf(`%s has already signed up`, params.Email) + } else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil { + log.Debug("Email is already signed up. Verification pending...") + return res, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", params.Email) + } } inputRoles := []string{} @@ -116,13 +118,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR inputRoles = strings.Split(inputRolesString, ",") } } - user := &models.User{ Email: params.Email, } - user.Roles = strings.Join(inputRoles, ",") - password, _ := crypto.EncryptPassword(params.Password) user.Password = &password diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 290b6fd..42ee81d 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -61,8 +61,9 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod } else { user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) } - if user.ID == "" && err != nil { - log.Debug("Failed to get user by email: ", err) + if user == nil || err != nil { + fmt.Println("=> failing here....", err) + log.Debug("Failed to get user by email or phone number: ", err) return res, err } isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil diff --git a/server/test/admin_signup_test.go b/server/test/admin_signup_test.go index 9596f4d..9e42553 100644 --- a/server/test/admin_signup_test.go +++ b/server/test/admin_signup_test.go @@ -17,11 +17,10 @@ func adminSignupTests(t *testing.T, s TestSetup) { _, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{ AdminSecret: "admin", }) - assert.NotNil(t, err) // reset env for test to pass - memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, "") - + err = memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, "") + assert.Nil(t, err) _, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{ AdminSecret: "admin123", }) diff --git a/server/test/integration_test.go b/server/test/integration_test.go index 9c9dfa2..3d4bb3d 100644 --- a/server/test/integration_test.go +++ b/server/test/integration_test.go @@ -9,6 +9,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" + "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/env" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/utils" @@ -78,8 +79,10 @@ func TestResolvers(t *testing.T) { // clean the persisted config for test to use fresh config envData, err := db.Provider.GetEnv(ctx) - if err == nil && envData.ID != "" { - envData.EnvData = "" + if err == nil && envData == nil { + envData = &models.Env{ + EnvData: "", + } _, err = db.Provider.UpdateEnv(ctx, envData) if err != nil { t.Logf("Error updating env: %s", err.Error()) diff --git a/server/test/verification_requests_test.go b/server/test/verification_requests_test.go index 0d0ce65..e5d5d73 100644 --- a/server/test/verification_requests_test.go +++ b/server/test/verification_requests_test.go @@ -44,9 +44,7 @@ func verificationRequestsTest(t *testing.T, s TestSetup) { assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h)) requests, err = resolvers.VerificationRequestsResolver(ctx, pagination) - assert.Nil(t, err) - rLen := len(requests.VerificationRequests) assert.GreaterOrEqual(t, rLen, 1) diff --git a/server/utils/pagination.go b/server/utils/pagination.go index d0bfff9..384eebd 100644 --- a/server/utils/pagination.go +++ b/server/utils/pagination.go @@ -10,7 +10,6 @@ import ( func GetPagination(paginatedInput *model.PaginatedInput) *model.Pagination { limit := int64(constants.DefaultLimit) page := int64(1) - if paginatedInput != nil && paginatedInput.Pagination != nil { if paginatedInput.Pagination.Limit != nil { limit = *paginatedInput.Pagination.Limit From 3fefcfcd9aa677fa8482e4e1c6485edb1bfe7cc2 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Tue, 1 Aug 2023 17:37:34 +0530 Subject: [PATCH 27/37] fix: refs for dynamo db --- server/db/providers/dynamodb/verification_requests.go | 2 +- server/db/providers/dynamodb/webhook.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/db/providers/dynamodb/verification_requests.go b/server/db/providers/dynamodb/verification_requests.go index 0ae0365..5fdf078 100644 --- a/server/db/providers/dynamodb/verification_requests.go +++ b/server/db/providers/dynamodb/verification_requests.go @@ -93,7 +93,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod // DeleteVerificationRequest to delete verification request from database func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error { collection := p.db.Table(models.Collections.VerificationRequest) - if verificationRequest.ID != "" { + if verificationRequest != nil { err := collection.Delete("id", verificationRequest.ID).RunWithContext(ctx) if err != nil { diff --git a/server/db/providers/dynamodb/webhook.go b/server/db/providers/dynamodb/webhook.go index 920173b..c50e1fb 100644 --- a/server/db/providers/dynamodb/webhook.go +++ b/server/db/providers/dynamodb/webhook.go @@ -114,14 +114,14 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) // DeleteWebhook to delete webhook func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error { // Also delete webhook logs for given webhook id - if webhook.ID != "" { + if webhook != nil { webhookCollection := p.db.Table(models.Collections.Webhook) - var pagination *model.Pagination webhookLogCollection := p.db.Table(models.Collections.WebhookLog) err := webhookCollection.Delete("id", webhook.ID).RunWithContext(ctx) if err != nil { return err } + pagination := &model.Pagination{} webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID) for _, webhookLog := range webhookLogs.WebhookLogs { err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx) From 9a8d20b6985498a752424119c36b414f58ac74f4 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Wed, 2 Aug 2023 00:04:07 +0530 Subject: [PATCH 28/37] fix: test webhook endpoint mutation Resolves #376 --- dashboard/src/pages/Webhooks.tsx | 1 - server/graph/generated/generated.go | 11 ++++++++++- server/graph/model/models_gen.go | 7 ++++--- server/graph/schema.graphqls | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dashboard/src/pages/Webhooks.tsx b/dashboard/src/pages/Webhooks.tsx index a4484b5..9d90378 100644 --- a/dashboard/src/pages/Webhooks.tsx +++ b/dashboard/src/pages/Webhooks.tsx @@ -118,7 +118,6 @@ const Webhooks = () => { useEffect(() => { fetchWebookData(); }, [paginationProps.page, paginationProps.limit]); - console.log({ webhookData }); return ( diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 887207c..34378e5 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -2690,6 +2690,7 @@ input WebhookRequest { input TestEndpointRequest { endpoint: String! event_name: String! + event_description: String headers: Map } @@ -16756,7 +16757,7 @@ func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Contex asMap[k] = v } - fieldsInOrder := [...]string{"endpoint", "event_name", "headers"} + fieldsInOrder := [...]string{"endpoint", "event_name", "event_description", "headers"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -16779,6 +16780,14 @@ func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Contex if err != nil { return it, err } + case "event_description": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_description")) + it.EventDescription, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } case "headers": var err error diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index d6139c9..9e435ee 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -301,9 +301,10 @@ type SignUpInput struct { } type TestEndpointRequest struct { - Endpoint string `json:"endpoint"` - EventName string `json:"event_name"` - Headers map[string]interface{} `json:"headers"` + Endpoint string `json:"endpoint"` + EventName string `json:"event_name"` + EventDescription *string `json:"event_description"` + Headers map[string]interface{} `json:"headers"` } type TestEndpointResponse struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 7ceef43..61c0692 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -512,6 +512,7 @@ input WebhookRequest { input TestEndpointRequest { endpoint: String! event_name: String! + event_description: String headers: Map } From a8503666e388fae130b52d70e8b0900107c2526d Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Wed, 2 Aug 2023 10:02:41 +0530 Subject: [PATCH 29/37] fix: add events for signup --- server/handlers/oauth_callback.go | 2 ++ server/handlers/verify_email.go | 2 ++ server/resolvers/mobile_signup.go | 3 +++ server/resolvers/signup.go | 2 ++ server/resolvers/verify_email.go | 2 ++ server/resolvers/verify_otp.go | 2 ++ 6 files changed, 13 insertions(+) diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index ed6a81a..80a9ab1 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -260,6 +260,8 @@ func OAuthCallbackHandler() gin.HandlerFunc { go func() { if isSignUp { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user) + // User is also logged in with signup + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user) } else { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user) } diff --git a/server/handlers/verify_email.go b/server/handlers/verify_email.go index 2ed9280..47f61d3 100644 --- a/server/handlers/verify_email.go +++ b/server/handlers/verify_email.go @@ -175,6 +175,8 @@ func VerifyEmailHandler() gin.HandlerFunc { go func() { if isSignUp { utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user) + // User is also logged in with signup + utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user) } else { utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user) } diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go index 63f5ea0..60b3a88 100644 --- a/server/resolvers/mobile_signup.go +++ b/server/resolvers/mobile_signup.go @@ -223,6 +223,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) } go func() { smsproviders.SendSMS(mobile, smsBody.String()) + utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) }() return &model.AuthResponse{ Message: "Please check the OTP in your inbox", @@ -298,6 +299,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) go func() { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) + // User is also logged in with signup + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 67c7f2d..af9fb52 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -301,6 +301,8 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR go func() { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) + // User is also logged in with signup + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) db.Provider.AddSession(ctx, &models.Session{ UserID: user.ID, UserAgent: utils.GetUserAgent(gc.Request), diff --git a/server/resolvers/verify_email.go b/server/resolvers/verify_email.go index 9ee0181..d263629 100644 --- a/server/resolvers/verify_email.go +++ b/server/resolvers/verify_email.go @@ -125,6 +125,8 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m go func() { if isSignUp { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user) + // User is also logged in with signup + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } else { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 42ee81d..85a119a 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -112,6 +112,8 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod db.Provider.DeleteOTP(gc, otp) if isSignUp { utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user) + // User is also logged in with signup + utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } else { utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) } From e5400bc7bd6fb59c0f53cb51d8e519715fc78458 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 3 Aug 2023 12:33:20 +0530 Subject: [PATCH 30/37] fix microsoft active directory config --- server/oauth/oauth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go index 2d41252..b102a25 100644 --- a/server/oauth/oauth.go +++ b/server/oauth/oauth.go @@ -171,7 +171,7 @@ func InitOAuth() error { microsoftClientSecret = "" } microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) - if err != nil { + if err != nil || microsoftActiveDirTenantID == "" { microsoftActiveDirTenantID = "common" } if microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "" { From a042c202a0b0cde1fed9572b420d7d4fa32be8d3 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 3 Aug 2023 13:29:07 +0530 Subject: [PATCH 31/37] fix microsoft active directory config --- server/oauth/oauth.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go index b102a25..7841909 100644 --- a/server/oauth/oauth.go +++ b/server/oauth/oauth.go @@ -171,8 +171,8 @@ func InitOAuth() error { microsoftClientSecret = "" } microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) - if err != nil || microsoftActiveDirTenantID == "" { - microsoftActiveDirTenantID = "common" + if err != nil { + microsoftActiveDirTenantID = "" } if microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "" { p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID)) From e625ed9633d52719713f175b8501d9fec6697aff Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 3 Aug 2023 14:43:27 +0530 Subject: [PATCH 32/37] allow common tenant for microsoft --- server/oauth/oauth.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go index 7841909..3f02916 100644 --- a/server/oauth/oauth.go +++ b/server/oauth/oauth.go @@ -10,11 +10,16 @@ import ( githubOAuth2 "golang.org/x/oauth2/github" linkedInOAuth2 "golang.org/x/oauth2/linkedin" microsoftOAuth2 "golang.org/x/oauth2/microsoft" + "google.golang.org/appengine/log" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/memorystore" ) +const ( + microsoftCommonTenant = "common" +) + // OAuthProviders is a struct that contains reference all the OAuth providers type OAuthProvider struct { GoogleConfig *oauth2.Config @@ -171,12 +176,16 @@ func InitOAuth() error { microsoftClientSecret = "" } microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) - if err != nil { - microsoftActiveDirTenantID = "" + if err != nil || microsoftActiveDirTenantID == "" { + microsoftActiveDirTenantID = microsoftCommonTenant } - if microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "" { + if microsoftClientID != "" && microsoftClientSecret != "" { + if microsoftActiveDirTenantID == microsoftCommonTenant { + ctx = oidc.InsecureIssuerURLContext(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID)) + } p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID)) if err != nil { + log.Debugf(ctx, "Error while creating OIDC provider for Microsoft: %v", err) return err } OIDCProviders.MicrosoftOIDC = p From 35e563ab3bb9809594df7914d1d28957f8128769 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Mon, 14 Aug 2023 12:01:37 +0530 Subject: [PATCH 33/37] Add app_data --- server/db/models/user.go | 5 +- server/email/email.go | 1 - server/go.mod | 2 +- server/go.sum | 1275 +++++++++++++++++++++++++++ server/graph/generated/generated.go | 110 ++- server/graph/model/models_gen.go | 159 ++-- server/graph/schema.graphqls | 5 + server/resolvers/login.go | 1 - server/resolvers/signup.go | 13 + server/resolvers/update_profile.go | 15 +- server/resolvers/update_user.go | 12 + server/token/auth_token.go | 1 + 12 files changed, 1511 insertions(+), 88 deletions(-) diff --git a/server/db/models/user.go b/server/db/models/user.go index 4628359..a262823 100644 --- a/server/db/models/user.go +++ b/server/db/models/user.go @@ -33,12 +33,14 @@ type User struct { IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled" dynamo:"is_multi_factor_auth_enabled"` UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` + AppData *string `json:"app_data" bson:"app_data" cql:"app_data" dynamo:"app_data"` } func (user *User) AsAPIUser() *model.User { isEmailVerified := user.EmailVerifiedAt != nil isPhoneVerified := user.PhoneNumberVerifiedAt != nil - + appDataMap := make(map[string]interface{}) + json.Unmarshal([]byte(refs.StringValue(user.AppData)), &appDataMap) // id := user.ID // if strings.Contains(id, Collections.User+"/") { // id = strings.TrimPrefix(id, Collections.User+"/") @@ -63,6 +65,7 @@ func (user *User) AsAPIUser() *model.User { IsMultiFactorAuthEnabled: user.IsMultiFactorAuthEnabled, CreatedAt: refs.NewInt64Ref(user.CreatedAt), UpdatedAt: refs.NewInt64Ref(user.UpdatedAt), + AppData: appDataMap, } } diff --git a/server/email/email.go b/server/email/email.go index 1b7d84d..e7222ac 100644 --- a/server/email/email.go +++ b/server/email/email.go @@ -72,7 +72,6 @@ func getEmailTemplate(event string, data map[string]interface{}) (*model.EmailTe return nil, err } subjectString := buf.String() - return &model.EmailTemplate{ Template: templateString, Subject: subjectString, diff --git a/server/go.mod b/server/go.mod index 0d50507..d1747e2 100644 --- a/server/go.mod +++ b/server/go.mod @@ -30,7 +30,7 @@ require ( go.mongodb.org/mongo-driver v1.8.1 golang.org/x/crypto v0.4.0 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 - google.golang.org/appengine v1.6.7 // indirect + google.golang.org/appengine v1.6.7 google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/mail.v2 v2.3.1 diff --git a/server/go.sum b/server/go.sum index 4a2c928..76bb186 100644 --- a/server/go.sum +++ b/server/go.sum @@ -3,6 +3,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -13,77 +14,707 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/99designs/gqlgen v0.17.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw= github.com/99designs/gqlgen v0.17.20/go.mod h1:Mja2HI23kWT1VRH09hvWshFgOzKswpO20o4ScpJIES4= +github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go= +github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/arangodb/go-driver v1.2.1 h1:HREDHhDmzdIWxHmfkfTESbYUnRjESjPh4WUuXq7FZa8= github.com/arangodb/go-driver v1.2.1/go.mod h1:zdDkJJnCj8DAkfbtIjIXnsTrWIiy6VhP3Vy14p+uQeY= +github.com/arangodb/go-driver v1.6.0 h1:NFWj/idqXZxhFVueihMSI2R9NotNIsgvNfM/xmpekb4= +github.com/arangodb/go-driver v1.6.0/go.mod h1:HQmdGkvNMVBTE3SIPSQ8T/ZddC6iwNsfMR+dDJQxIsI= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.306/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.320 h1:o2cno15HVUYj+IAgZHJ5No6ifAxwa2HcluzahMEPfOw= +github.com/aws/aws-sdk-go v1.44.320/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-iptables v0.4.3/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= +github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= +github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/couchbase/gocb/v2 v2.6.0 h1:DhkLNatDcddCcS411D6kNwZspSEAWVeI/N3abzt/HLc= github.com/couchbase/gocb/v2 v2.6.0/go.mod h1:5su8b1gBF3V4j07SiGw+CA0bK9a84YWEb6UH7up0MEs= +github.com/couchbase/gocb/v2 v2.6.3 h1:5RsMo+RRfK0mVxHLAfpBz3/tHlgXZb1WBNItLk9Ab+c= +github.com/couchbase/gocb/v2 v2.6.3/go.mod h1:yF5F6BHTZ/ZowhEuZbySbXrlI4rHd1TIhm5azOaMbJU= github.com/couchbase/gocbcore/v10 v10.2.0 h1:ZoSBLtcmt+lXbxVVT4SAhXDVNR+D48iSOZWNzHucVVk= github.com/couchbase/gocbcore/v10 v10.2.0/go.mod h1:qkPnOBziCs0guMEEvd0cRFo+AjOW0yEL99cU3I4n3Ao= +github.com/couchbase/gocbcore/v10 v10.2.3 h1:PEkRSNSkKjUBXx82Ucr094+anoiCG5GleOOQZOHo6D4= +github.com/couchbase/gocbcore/v10 v10.2.3/go.mod h1:lYQIIk+tzoMcwtwU5GzPbDdqEkwkH3isI2rkSpfL0oM= github.com/couchbaselabs/gocaves/client v0.0.0-20220223122017-22859b310bd2 h1:UlwJ2GWpZQAQCLHyO3xHKcqAjUUcX2w7FKpbxCIUQks= github.com/couchbaselabs/gocaves/client v0.0.0-20220223122017-22859b310bd2/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= +github.com/couchbaselabs/gocaves/client v0.0.0-20230307083111-cc3960c624b1/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= +github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259 h1:2TXy68EGEzIMHOx9UvczR5ApVecwCfQZ0LjkmwMI6g4= +github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -95,53 +726,108 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/glebarez/go-sqlite v1.19.1 h1:o2XhjyR8CQ2m84+bVz10G0cabmG0tY4sIMiCbrcUTrY= github.com/glebarez/go-sqlite v1.19.1/go.mod h1:9AykawGIyIcxoSfpYWiX1SgTNHTNsa/FVc75cDkbp4M= +github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= +github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= github.com/glebarez/sqlite v1.5.0 h1:+8LAEpmywqresSoGlqjjT+I9m4PseIM3NcerIJ/V7mk= github.com/glebarez/sqlite v1.5.0/go.mod h1:0wzXzTvfVJIN2GqRhCdMbnYd+m+aH5/QV7B30rM6NgY= +github.com/glebarez/sqlite v1.9.0 h1:Aj6bPA12ZEx5GbSF6XADmCkYXlljPNUY+Zf1EQxynXs= +github.com/glebarez/sqlite v1.9.0/go.mod h1:YBYCoyupOao60lzp1MVBLEjZfgkq0tdB1voAQ09K9zw= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw= +github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE= github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= +github.com/gocql/gocql v1.5.2 h1:WnKf8xRQImcT/KLaEWG2pjEeryDB7K0qQN9mPs1C58Q= +github.com/gocql/gocql v1.5.2/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -149,6 +835,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -164,15 +851,20 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -182,12 +874,20 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -195,23 +895,68 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= +github.com/guregu/dynamo v1.20.1 h1:FFfi2unN453kcsRbyEbgG/LHSNuEWqMpdj285buyp6w= +github.com/guregu/dynamo v1.20.1/go.mod h1:rNSE8PT6IaNbcEno0/i0y6E5XFHDWUyLRxpGlF8O5CU= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -219,7 +964,16 @@ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -231,15 +985,27 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -251,20 +1017,35 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275 h1:IZycmTpoUtQK3PD60UYBwjaCUHUP7cML494ao9/O8+Q= github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275/go.mod h1:zt6UU74K6Z6oMOYJbJzYpYucqdcQwSMPBEdSvGiaUMw= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= +github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc= +github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -273,41 +1054,73 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= +github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM= github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw= +github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0= +github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -317,24 +1130,43 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/twilio/twilio-go v1.7.2 h1:tX38DXbSuDWWIK+tKAE2AJSMR6d8i7lf9ksY8J29VLE= github.com/twilio/twilio-go v1.7.2/go.mod h1:tdnfQ5TjbewoAu4lf9bMsGvfuJ/QU9gYuv9yx3TSIXU= +github.com/twilio/twilio-go v1.11.0 h1:ixO2DfAV4c0Yza0Tom5F5ZZB8WUbigiFc9wD84vbYnc= +github.com/twilio/twilio-go v1.11.0/go.mod h1:tdnfQ5TjbewoAu4lf9bMsGvfuJ/QU9gYuv9yx3TSIXU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4= github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY= +github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= +github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= +github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4= +github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= @@ -346,40 +1178,82 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.mongodb.org/mongo-driver v1.8.1 h1:OZE4Wni/SJlrcmSIBRYNzunX5TKxjrTS4jKSnA99oKU= go.mongodb.org/mongo-driver v1.8.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= +go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -390,6 +1264,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -398,10 +1274,19 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -431,23 +1316,76 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 h1:3B43BWw0xEBsLZ/NO1VALz6fppU3481pik+2Ksv45z8= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -457,9 +1395,15 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -489,51 +1433,109 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -548,6 +1550,7 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -574,16 +1577,46 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -600,6 +1633,51 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -631,12 +1709,127 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -649,6 +1842,36 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -661,9 +1884,14 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -677,6 +1905,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= @@ -685,6 +1914,7 @@ gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -695,14 +1925,25 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= +gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= +gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= gorm.io/driver/postgres v1.4.7 h1:J06jXZCNq7Pdf7LIPn8tZn9LsWjd81BRSKveKNr0ZfA= gorm.io/driver/postgres v1.4.7/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4= +gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= +gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig= +gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4= +gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+kt0nM= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.2 h1:9wR6CFD+G8nOusLdvkZelOEhpJVwwHzpQOUM+REd6U0= gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= +gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8= +gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -710,38 +1951,72 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= modernc.org/libc v1.19.0 h1:bXyVhGQg6KIClTr8FMVIDPl7jtbcs7aS5WP7vLDaxPs= modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= +modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk= modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/sqlite v1.19.1 h1:8xmS5oLnZtAK//vnd4aTVj8VOeTAccEFOtUnIzfSw+4= modernc.org/sqlite v1.19.1/go.mod h1:UfQ83woKMaPW/ZBruK0T7YaFCrI+IE0LeWVY6pmnVms= +modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= +modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/tcl v1.14.0/go.mod h1:gQ7c1YPMvryCHCcmf8acB6VPabE59QBeuRQLL7cTUlM= +modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= modernc.org/z v1.6.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= +modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 34378e5..5a001b7 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -245,6 +245,7 @@ type ComplexityRoot struct { } User struct { + AppData func(childComplexity int) int Birthdate func(childComplexity int) int CreatedAt func(childComplexity int) int Email func(childComplexity int) int @@ -1695,6 +1696,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TestEndpointResponse.Response(childComplexity), true + case "User.app_data": + if e.complexity.User.AppData == nil { + break + } + + return e.complexity.User.AppData(childComplexity), true + case "User.birthdate": if e.complexity.User.Birthdate == nil { break @@ -2229,6 +2237,7 @@ type User { updated_at: Int64 revoked_timestamp: Int64 is_multi_factor_auth_enabled: Boolean + app_data: Map } type Users { @@ -2500,6 +2509,7 @@ input MobileSignUpInput { # it is used to get code for an on-going auth process during login # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token state: String + app_data: Map } input SignUpInput { @@ -2522,6 +2532,7 @@ input SignUpInput { # it is used to get code for an on-going auth process during login # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token state: String + app_data: Map } input LoginInput { @@ -2577,6 +2588,7 @@ input UpdateProfileInput { phone_number: String picture: String is_multi_factor_auth_enabled: Boolean + app_data: Map } input UpdateUserInput { @@ -2593,6 +2605,7 @@ input UpdateUserInput { picture: String roles: [String] is_multi_factor_auth_enabled: Boolean + app_data: Map } input ForgotPasswordInput { @@ -3804,6 +3817,8 @@ func (ec *executionContext) fieldContext_AuthResponse_user(ctx context.Context, return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -7099,6 +7114,8 @@ func (ec *executionContext) fieldContext_InviteMembersResponse_Users(ctx context return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -8801,6 +8818,8 @@ func (ec *executionContext) fieldContext_Mutation__update_user(ctx context.Conte return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -10103,6 +10122,8 @@ func (ec *executionContext) fieldContext_Query_profile(ctx context.Context, fiel return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -10368,6 +10389,8 @@ func (ec *executionContext) fieldContext_Query__user(ctx context.Context, field return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -12229,6 +12252,47 @@ func (ec *executionContext) fieldContext_User_is_multi_factor_auth_enabled(ctx c return fc, nil } +func (ec *executionContext) _User_app_data(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_User_app_data(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.AppData, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(map[string]interface{}) + fc.Result = res + return ec.marshalOMap2map(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_User_app_data(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "User", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Map does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Users_pagination(ctx context.Context, field graphql.CollectedField, obj *model.Users) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Users_pagination(ctx, field) if err != nil { @@ -12360,6 +12424,8 @@ func (ec *executionContext) fieldContext_Users_users(ctx context.Context, field return ec.fieldContext_User_revoked_timestamp(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type User", field.Name) }, @@ -16201,7 +16267,7 @@ func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state"} + fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state", "app_data"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -16336,6 +16402,14 @@ func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context, if err != nil { return it, err } + case "app_data": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data")) + it.AppData, err = ec.unmarshalOMap2map(ctx, v) + if err != nil { + return it, err + } } } @@ -16609,7 +16683,7 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i asMap[k] = v } - fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state"} + fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state", "app_data"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -16744,6 +16818,14 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i if err != nil { return it, err } + case "app_data": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data")) + it.AppData, err = ec.unmarshalOMap2map(ctx, v) + if err != nil { + return it, err + } } } @@ -17333,7 +17415,7 @@ func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context asMap[k] = v } - fieldsInOrder := [...]string{"old_password", "new_password", "confirm_new_password", "email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "is_multi_factor_auth_enabled"} + fieldsInOrder := [...]string{"old_password", "new_password", "confirm_new_password", "email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "is_multi_factor_auth_enabled", "app_data"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -17444,6 +17526,14 @@ func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context if err != nil { return it, err } + case "app_data": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data")) + it.AppData, err = ec.unmarshalOMap2map(ctx, v) + if err != nil { + return it, err + } } } @@ -17457,7 +17547,7 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o asMap[k] = v } - fieldsInOrder := [...]string{"id", "email", "email_verified", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "roles", "is_multi_factor_auth_enabled"} + fieldsInOrder := [...]string{"id", "email", "email_verified", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "roles", "is_multi_factor_auth_enabled", "app_data"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -17568,6 +17658,14 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o if err != nil { return it, err } + case "app_data": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data")) + it.AppData, err = ec.unmarshalOMap2map(ctx, v) + if err != nil { + return it, err + } } } @@ -19474,6 +19572,10 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj out.Values[i] = ec._User_is_multi_factor_auth_enabled(ctx, field, obj) + case "app_data": + + out.Values[i] = ec._User_app_data(ctx, field, obj) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 9e435ee..cac0235 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -207,22 +207,23 @@ type MobileLoginInput struct { } type MobileSignUpInput struct { - Email *string `json:"email"` - GivenName *string `json:"given_name"` - FamilyName *string `json:"family_name"` - MiddleName *string `json:"middle_name"` - Nickname *string `json:"nickname"` - Gender *string `json:"gender"` - Birthdate *string `json:"birthdate"` - PhoneNumber string `json:"phone_number"` - Picture *string `json:"picture"` - Password string `json:"password"` - ConfirmPassword string `json:"confirm_password"` - Roles []string `json:"roles"` - Scope []string `json:"scope"` - RedirectURI *string `json:"redirect_uri"` - IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` - State *string `json:"state"` + Email *string `json:"email"` + GivenName *string `json:"given_name"` + FamilyName *string `json:"family_name"` + MiddleName *string `json:"middle_name"` + Nickname *string `json:"nickname"` + Gender *string `json:"gender"` + Birthdate *string `json:"birthdate"` + PhoneNumber string `json:"phone_number"` + Picture *string `json:"picture"` + Password string `json:"password"` + ConfirmPassword string `json:"confirm_password"` + Roles []string `json:"roles"` + Scope []string `json:"scope"` + RedirectURI *string `json:"redirect_uri"` + IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + State *string `json:"state"` + AppData map[string]interface{} `json:"app_data"` } type OAuthRevokeInput struct { @@ -282,22 +283,23 @@ type SessionQueryInput struct { } type SignUpInput struct { - Email string `json:"email"` - GivenName *string `json:"given_name"` - FamilyName *string `json:"family_name"` - MiddleName *string `json:"middle_name"` - Nickname *string `json:"nickname"` - Gender *string `json:"gender"` - Birthdate *string `json:"birthdate"` - PhoneNumber *string `json:"phone_number"` - Picture *string `json:"picture"` - Password string `json:"password"` - ConfirmPassword string `json:"confirm_password"` - Roles []string `json:"roles"` - Scope []string `json:"scope"` - RedirectURI *string `json:"redirect_uri"` - IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` - State *string `json:"state"` + Email string `json:"email"` + GivenName *string `json:"given_name"` + FamilyName *string `json:"family_name"` + MiddleName *string `json:"middle_name"` + Nickname *string `json:"nickname"` + Gender *string `json:"gender"` + Birthdate *string `json:"birthdate"` + PhoneNumber *string `json:"phone_number"` + Picture *string `json:"picture"` + Password string `json:"password"` + ConfirmPassword string `json:"confirm_password"` + Roles []string `json:"roles"` + Scope []string `json:"scope"` + RedirectURI *string `json:"redirect_uri"` + IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + State *string `json:"state"` + AppData map[string]interface{} `json:"app_data"` } type TestEndpointRequest struct { @@ -380,35 +382,37 @@ type UpdateEnvInput struct { } type UpdateProfileInput struct { - OldPassword *string `json:"old_password"` - NewPassword *string `json:"new_password"` - ConfirmNewPassword *string `json:"confirm_new_password"` - Email *string `json:"email"` - GivenName *string `json:"given_name"` - FamilyName *string `json:"family_name"` - MiddleName *string `json:"middle_name"` - Nickname *string `json:"nickname"` - Gender *string `json:"gender"` - Birthdate *string `json:"birthdate"` - PhoneNumber *string `json:"phone_number"` - Picture *string `json:"picture"` - IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + OldPassword *string `json:"old_password"` + NewPassword *string `json:"new_password"` + ConfirmNewPassword *string `json:"confirm_new_password"` + Email *string `json:"email"` + GivenName *string `json:"given_name"` + FamilyName *string `json:"family_name"` + MiddleName *string `json:"middle_name"` + Nickname *string `json:"nickname"` + Gender *string `json:"gender"` + Birthdate *string `json:"birthdate"` + PhoneNumber *string `json:"phone_number"` + Picture *string `json:"picture"` + IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + AppData map[string]interface{} `json:"app_data"` } type UpdateUserInput struct { - ID string `json:"id"` - Email *string `json:"email"` - EmailVerified *bool `json:"email_verified"` - GivenName *string `json:"given_name"` - FamilyName *string `json:"family_name"` - MiddleName *string `json:"middle_name"` - Nickname *string `json:"nickname"` - Gender *string `json:"gender"` - Birthdate *string `json:"birthdate"` - PhoneNumber *string `json:"phone_number"` - Picture *string `json:"picture"` - Roles []*string `json:"roles"` - IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + ID string `json:"id"` + Email *string `json:"email"` + EmailVerified *bool `json:"email_verified"` + GivenName *string `json:"given_name"` + FamilyName *string `json:"family_name"` + MiddleName *string `json:"middle_name"` + Nickname *string `json:"nickname"` + Gender *string `json:"gender"` + Birthdate *string `json:"birthdate"` + PhoneNumber *string `json:"phone_number"` + Picture *string `json:"picture"` + Roles []*string `json:"roles"` + IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + AppData map[string]interface{} `json:"app_data"` } type UpdateWebhookRequest struct { @@ -421,25 +425,26 @@ type UpdateWebhookRequest struct { } type User struct { - ID string `json:"id"` - Email string `json:"email"` - EmailVerified bool `json:"email_verified"` - SignupMethods string `json:"signup_methods"` - GivenName *string `json:"given_name"` - FamilyName *string `json:"family_name"` - MiddleName *string `json:"middle_name"` - Nickname *string `json:"nickname"` - PreferredUsername *string `json:"preferred_username"` - Gender *string `json:"gender"` - Birthdate *string `json:"birthdate"` - PhoneNumber *string `json:"phone_number"` - PhoneNumberVerified *bool `json:"phone_number_verified"` - Picture *string `json:"picture"` - Roles []string `json:"roles"` - CreatedAt *int64 `json:"created_at"` - UpdatedAt *int64 `json:"updated_at"` - RevokedTimestamp *int64 `json:"revoked_timestamp"` - IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + ID string `json:"id"` + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + SignupMethods string `json:"signup_methods"` + GivenName *string `json:"given_name"` + FamilyName *string `json:"family_name"` + MiddleName *string `json:"middle_name"` + Nickname *string `json:"nickname"` + PreferredUsername *string `json:"preferred_username"` + Gender *string `json:"gender"` + Birthdate *string `json:"birthdate"` + PhoneNumber *string `json:"phone_number"` + PhoneNumberVerified *bool `json:"phone_number_verified"` + Picture *string `json:"picture"` + Roles []string `json:"roles"` + CreatedAt *int64 `json:"created_at"` + UpdatedAt *int64 `json:"updated_at"` + RevokedTimestamp *int64 `json:"revoked_timestamp"` + IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + AppData map[string]interface{} `json:"app_data"` } type Users struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 61c0692..1985aa7 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -51,6 +51,7 @@ type User { updated_at: Int64 revoked_timestamp: Int64 is_multi_factor_auth_enabled: Boolean + app_data: Map } type Users { @@ -322,6 +323,7 @@ input MobileSignUpInput { # it is used to get code for an on-going auth process during login # and use that code for setting `c_hash` in id_token state: String + app_data: Map } input SignUpInput { @@ -344,6 +346,7 @@ input SignUpInput { # it is used to get code for an on-going auth process during login # and use that code for setting `c_hash` in id_token state: String + app_data: Map } input LoginInput { @@ -399,6 +402,7 @@ input UpdateProfileInput { phone_number: String picture: String is_multi_factor_auth_enabled: Boolean + app_data: Map } input UpdateUserInput { @@ -415,6 +419,7 @@ input UpdateUserInput { picture: String roles: [String] is_multi_factor_auth_enabled: Boolean + app_data: Map } input ForgotPasswordInput { diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 185789d..9dcec5a 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -171,7 +171,6 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes if nonce == "" { nonce = uuid.New().String() } - authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code) if err != nil { log.Debug("Failed to create auth token", err) diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index af9fb52..cefcfb2 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -2,6 +2,8 @@ package resolvers import ( "context" + "encoding/json" + "errors" "fmt" "strings" "time" @@ -171,6 +173,17 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true) } + if params.AppData != nil { + appDataString := "" + appDataBytes, err := json.Marshal(params.AppData) + if err != nil { + log.Debug("failed to marshall source app_data: ", err) + return nil, errors.New("malformed app_data") + } + appDataString = string(appDataBytes) + user.AppData = &appDataString + } + user.SignupMethods = constants.AuthRecipeMethodBasicAuth isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) if err != nil { diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go index a8fcb5a..c478182 100644 --- a/server/resolvers/update_profile.go +++ b/server/resolvers/update_profile.go @@ -2,6 +2,7 @@ package resolvers import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -47,7 +48,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) } // validate if all params are not empty - if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.NewPassword == nil && params.ConfirmNewPassword == nil && params.IsMultiFactorAuthEnabled == nil { + if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.NewPassword == nil && params.ConfirmNewPassword == nil && params.IsMultiFactorAuthEnabled == nil && params.AppData == nil { log.Debug("All params are empty") return res, fmt.Errorf("please enter at least one param to update") } @@ -56,7 +57,6 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) log := log.WithFields(log.Fields{ "user_id": userID, }) - user, err := db.Provider.GetUserByID(ctx, userID) if err != nil { log.Debug("Failed to get user by id: ", err) @@ -99,7 +99,16 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) if params.Picture != nil && refs.StringValue(user.Picture) != refs.StringValue(params.Picture) { user.Picture = params.Picture } - + if params.AppData != nil { + appDataString := "" + appDataBytes, err := json.Marshal(params.AppData) + if err != nil { + log.Debug("failed to marshall source app_data: ", err) + return nil, errors.New("malformed app_data") + } + appDataString = string(appDataBytes) + user.AppData = &appDataString + } if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) { if refs.BoolValue(params.IsMultiFactorAuthEnabled) { isEnvServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go index d9741ae..ee751ab 100644 --- a/server/resolvers/update_user.go +++ b/server/resolvers/update_user.go @@ -2,6 +2,7 @@ package resolvers import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -95,6 +96,17 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod user.Picture = params.Picture } + if params.AppData != nil { + appDataString := "" + appDataBytes, err := json.Marshal(params.AppData) + if err != nil { + log.Debug("failed to marshall source app_data: ", err) + return nil, errors.New("malformed app_data") + } + appDataString = string(appDataBytes) + user.AppData = &appDataString + } + if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) { user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled if refs.BoolValue(params.IsMultiFactorAuthEnabled) { diff --git a/server/token/auth_token.go b/server/token/auth_token.go index f482db8..8312825 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -386,6 +386,7 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c userBytes, _ := json.Marshal(&resUser) var userMap map[string]interface{} json.Unmarshal(userBytes, &userMap) + fmt.Println("=> userBytes", string(userBytes)) claimKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) if err != nil { claimKey = "roles" From cf96a0087fc11d060f982c2ade744382b74d85fc Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Mon, 14 Aug 2023 14:15:52 +0530 Subject: [PATCH 34/37] Fix tests for verifying otp using mfa session --- server/resolvers/verify_otp.go | 18 ++++++++++++++++++ server/test/mobile_login_test.go | 17 +++++++++++++++++ server/test/mobile_signup_test.go | 15 +++++++++++++++ server/test/resend_otp_test.go | 15 +++++++++++++++ server/test/verify_otp_test.go | 16 +++++++++++++++- 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index adf0e35..6a63683 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -31,6 +31,15 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod mfaSession, err := cookie.GetMfaSession(gc) if err != nil { log.Debug("Failed to get otp request by email: ", err) + // // Ignore mfa session error in test env + // // dont trigger email sending in case of test + // envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv) + // if err != nil { + // envKey = "" + // } + // if envKey != constants.TestEnv { + // + // } return res, fmt.Errorf(`invalid session: %s`, err.Error()) } @@ -76,6 +85,15 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil { log.Debug("Failed to get mfa session: ", err) + // Ignore mfa session error in test env + // dont trigger email sending in case of test + // envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv) + // if err != nil { + // envKey = "" + // } + // if envKey != constants.TestEnv { + // + // } return res, fmt.Errorf(`invalid session: %s`, err.Error()) } diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go index 4cc181a..6f0823c 100644 --- a/server/test/mobile_login_test.go +++ b/server/test/mobile_login_test.go @@ -1,12 +1,18 @@ package test import ( + "fmt" + "strings" "testing" + "time" + "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -48,6 +54,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) { smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.NoError(t, err) assert.NotEmpty(t, smsRequest.Otp) + // Get user by phone number + user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) + assert.NoError(t, err) + assert.NotNil(t, user) + // Set mfa cookie session + mfaSession := uuid.NewString() + memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix()) + cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession) + cookie = strings.TrimSuffix(cookie, ";") + req, ctx := createContext(s) + req.Header.Set("Cookie", cookie) verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ PhoneNumber: &phoneNumber, Otp: smsRequest.Otp, diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go index c93472f..e0982e1 100644 --- a/server/test/mobile_signup_test.go +++ b/server/test/mobile_signup_test.go @@ -1,7 +1,10 @@ package test import ( + "fmt" + "strings" "testing" + "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" @@ -9,6 +12,7 @@ import ( "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -79,6 +83,17 @@ func mobileSingupTest(t *testing.T, s TestSetup) { otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) assert.Nil(t, err) assert.NotEmpty(t, otp.Otp) + // Get user by phone number + user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber) + assert.NoError(t, err) + assert.NotNil(t, user) + // Set mfa cookie session + mfaSession := uuid.NewString() + memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix()) + cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession) + cookie = strings.TrimSuffix(cookie, ";") + req, ctx := createContext(s) + req.Header.Set("Cookie", cookie) otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ PhoneNumber: &phoneNumber, Otp: otp.Otp, diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go index 1550957..3f1e738 100644 --- a/server/test/resend_otp_test.go +++ b/server/test/resend_otp_test.go @@ -2,13 +2,18 @@ package test import ( "context" + "fmt" + "strings" "testing" + "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -89,6 +94,16 @@ func resendOTPTest(t *testing.T, s TestSetup) { }) assert.Error(t, err) assert.Nil(t, verifyOtpRes) + // Get user by email + user, err := db.Provider.GetUserByEmail(ctx, email) + assert.NoError(t, err) + assert.NotNil(t, user) + // Set mfa cookie session + mfaSession := uuid.NewString() + memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix()) + cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession) + cookie = strings.TrimSuffix(cookie, ";") + req.Header.Set("Cookie", cookie) verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ Email: &email, Otp: newOtp.Otp, diff --git a/server/test/verify_otp_test.go b/server/test/verify_otp_test.go index 750deb5..455ac12 100644 --- a/server/test/verify_otp_test.go +++ b/server/test/verify_otp_test.go @@ -2,13 +2,18 @@ package test import ( "context" + "fmt" + "strings" "testing" + "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -63,7 +68,16 @@ func verifyOTPTest(t *testing.T, s TestSetup) { otp, err := db.Provider.GetOTPByEmail(ctx, email) assert.NoError(t, err) assert.NotEmpty(t, otp.Otp) - + // Get user by email + user, err := db.Provider.GetUserByEmail(ctx, email) + assert.NoError(t, err) + assert.NotNil(t, user) + // Set mfa cookie session + mfaSession := uuid.NewString() + memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix()) + cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession) + cookie = strings.TrimSuffix(cookie, ";") + req.Header.Set("Cookie", cookie) verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ Email: &email, Otp: otp.Otp, From 171d4e3fff217438e4381b98cda0691a0f1b6e4f Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Mon, 14 Aug 2023 14:16:54 +0530 Subject: [PATCH 35/37] remove unused code --- server/resolvers/verify_otp.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index 6a63683..adf0e35 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -31,15 +31,6 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod mfaSession, err := cookie.GetMfaSession(gc) if err != nil { log.Debug("Failed to get otp request by email: ", err) - // // Ignore mfa session error in test env - // // dont trigger email sending in case of test - // envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv) - // if err != nil { - // envKey = "" - // } - // if envKey != constants.TestEnv { - // - // } return res, fmt.Errorf(`invalid session: %s`, err.Error()) } @@ -85,15 +76,6 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil { log.Debug("Failed to get mfa session: ", err) - // Ignore mfa session error in test env - // dont trigger email sending in case of test - // envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv) - // if err != nil { - // envKey = "" - // } - // if envKey != constants.TestEnv { - // - // } return res, fmt.Errorf(`invalid session: %s`, err.Error()) } From 5e6b033024b2b451cb4a5991aadc5e75fd6a51b6 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 17 Aug 2023 14:20:31 +0530 Subject: [PATCH 36/37] fix microsoft active directory config --- .../cassandradb/verification_requests.go | 1 - server/handlers/oauth_callback.go | 61 ++++++++++--------- server/resolvers/verify_otp.go | 1 - server/token/auth_token.go | 1 - 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/server/db/providers/cassandradb/verification_requests.go b/server/db/providers/cassandradb/verification_requests.go index 2fffee4..aa8e66d 100644 --- a/server/db/providers/cassandradb/verification_requests.go +++ b/server/db/providers/cassandradb/verification_requests.go @@ -74,7 +74,6 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod var verificationRequest models.VerificationRequest err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) if err != nil { - fmt.Println("=> getting error here...", err) return nil, err } verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest()) diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index 80a9ab1..782da41 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -32,11 +32,11 @@ func OAuthCallbackHandler() gin.HandlerFunc { return func(ctx *gin.Context) { provider := ctx.Param("oauth_provider") state := ctx.Request.FormValue("state") - sessionState, err := memorystore.Provider.GetState(state) if sessionState == "" || err != nil { log.Debug("Invalid oauth state: ", state) ctx.JSON(400, gin.H{"error": "invalid oauth state"}) + return } // contains random token, redirect url, role sessionSplit := strings.Split(state, "___") @@ -46,32 +46,34 @@ func OAuthCallbackHandler() gin.HandlerFunc { ctx.JSON(400, gin.H{"error": "invalid redirect url"}) return } - // remove state from store go memorystore.Provider.RemoveState(state) - stateValue := sessionSplit[0] redirectURL := sessionSplit[1] inputRoles := strings.Split(sessionSplit[2], ",") scopes := strings.Split(sessionSplit[3], ",") - var user *models.User oauthCode := ctx.Request.FormValue("code") + if oauthCode == "" { + log.Debug("Invalid oauth code: ", oauthCode) + ctx.JSON(400, gin.H{"error": "invalid oauth code"}) + return + } switch provider { case constants.AuthRecipeMethodGoogle: - user, err = processGoogleUserInfo(oauthCode) + user, err = processGoogleUserInfo(ctx, oauthCode) case constants.AuthRecipeMethodGithub: - user, err = processGithubUserInfo(oauthCode) + user, err = processGithubUserInfo(ctx, oauthCode) case constants.AuthRecipeMethodFacebook: - user, err = processFacebookUserInfo(oauthCode) + user, err = processFacebookUserInfo(ctx, oauthCode) case constants.AuthRecipeMethodLinkedIn: - user, err = processLinkedInUserInfo(oauthCode) + user, err = processLinkedInUserInfo(ctx, oauthCode) case constants.AuthRecipeMethodApple: - user, err = processAppleUserInfo(oauthCode) + user, err = processAppleUserInfo(ctx, oauthCode) case constants.AuthRecipeMethodTwitter: - user, err = processTwitterUserInfo(oauthCode, sessionState) + user, err = processTwitterUserInfo(ctx, oauthCode, sessionState) case constants.AuthRecipeMethodMicrosoft: - user, err = processMicrosoftUserInfo(oauthCode) + user, err = processMicrosoftUserInfo(ctx, oauthCode) default: log.Info("Invalid oauth provider") err = fmt.Errorf(`invalid oauth provider`) @@ -281,9 +283,8 @@ func OAuthCallbackHandler() gin.HandlerFunc { } } -func processGoogleUserInfo(code string) (*models.User, error) { +func processGoogleUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - ctx := context.Background() oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) @@ -313,9 +314,9 @@ func processGoogleUserInfo(code string) (*models.User, error) { return user, nil } -func processGithubUserInfo(code string) (*models.User, error) { +func processGithubUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(context.TODO(), code) + oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) return user, fmt.Errorf("invalid github exchange code: %s", err.Error()) @@ -420,9 +421,9 @@ func processGithubUserInfo(code string) (*models.User, error) { return user, nil } -func processFacebookUserInfo(code string) (*models.User, error) { +func processFacebookUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(context.TODO(), code) + oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(ctx, code) if err != nil { log.Debug("Invalid facebook exchange code: ", err) return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error()) @@ -471,9 +472,9 @@ func processFacebookUserInfo(code string) (*models.User, error) { return user, nil } -func processLinkedInUserInfo(code string) (*models.User, error) { +func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(context.TODO(), code) + oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) return user, fmt.Errorf("invalid linkedin exchange code: %s", err.Error()) @@ -553,9 +554,9 @@ func processLinkedInUserInfo(code string) (*models.User, error) { return user, nil } -func processAppleUserInfo(code string) (*models.User, error) { +func processAppleUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(context.TODO(), code) + oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) return user, fmt.Errorf("invalid apple exchange code: %s", err.Error()) @@ -606,9 +607,9 @@ func processAppleUserInfo(code string) (*models.User, error) { return user, err } -func processTwitterUserInfo(code, verifier string) (*models.User, error) { +func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models.User, error) { var user *models.User - oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(context.TODO(), code, oauth2.SetAuthURLParam("code_verifier", verifier)) + oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier)) if err != nil { log.Debug("Failed to exchange code for token: ", err) return user, fmt.Errorf("invalid twitter exchange code: %s", err.Error()) @@ -674,24 +675,24 @@ func processTwitterUserInfo(code, verifier string) (*models.User, error) { } // process microsoft user information -func processMicrosoftUserInfo(code string) (*models.User, error) { +func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, error) { var user *models.User - ctx := context.Background() oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code) if err != nil { log.Debug("Failed to exchange code for token: ", err) - return user, fmt.Errorf("invalid google exchange code: %s", err.Error()) + return user, fmt.Errorf("invalid microsoft exchange code: %s", err.Error()) } - - verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID}) - + // we need to skip issuer check because for common tenant it will return internal issuer which does not match + verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{ + ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID, + SkipIssuerCheck: true, + }) // Extract the ID Token from OAuth2 token. rawIDToken, ok := oauth2Token.Extra("id_token").(string) if !ok { log.Debug("Failed to extract ID Token from OAuth2 token") return user, fmt.Errorf("unable to extract id_token") } - // Parse and verify ID Token payload. idToken, err := verifier.Verify(ctx, rawIDToken) if err != nil { diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index adf0e35..bab3323 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -69,7 +69,6 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) } if user == nil || err != nil { - fmt.Println("=> failing here....", err) log.Debug("Failed to get user by email or phone number: ", err) return res, err } diff --git a/server/token/auth_token.go b/server/token/auth_token.go index 8312825..f482db8 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -386,7 +386,6 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c userBytes, _ := json.Marshal(&resUser) var userMap map[string]interface{} json.Unmarshal(userBytes, &userMap) - fmt.Println("=> userBytes", string(userBytes)) claimKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) if err != nil { claimKey = "roles" From a124edfaee77150ee9b59ba61cf1820cf9da60d9 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sat, 19 Aug 2023 20:44:38 +0530 Subject: [PATCH 37/37] Add user to validate_session Resolves #379 --- server/go.sum | 1275 -------------------------- server/graph/generated/generated.go | 104 +++ server/graph/model/models_gen.go | 3 +- server/graph/schema.graphqls | 1 + server/resolvers/validate_session.go | 4 +- server/test/validate_session_test.go | 1 + 6 files changed, 111 insertions(+), 1277 deletions(-) diff --git a/server/go.sum b/server/go.sum index 76bb186..4a2c928 100644 --- a/server/go.sum +++ b/server/go.sum @@ -3,7 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -14,707 +13,77 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= -cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= -cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= -cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= -cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= -cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= -cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= -cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= -cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= -cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= -cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= -cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= -cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= -cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= -cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= -cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= -cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= -cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= -cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= -cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= -cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= -cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= -cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= -cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= -cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= -cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= -cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= -cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= -cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= -cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= -cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= -cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= -cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= -cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= -cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= -cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= -cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= -cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= -cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= -cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= -cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= -cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= -cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= -cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= -cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= -cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= -cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= -cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= -cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= -cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= -cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= -cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= -cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= -cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= -cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= -cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= -cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= -cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= -cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= -cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= -cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= -cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= -cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= -cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= -cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= -cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= -cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= -cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= -cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= -cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= -cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= -cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= -cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= -cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= -cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= -cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= -cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= -cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= -cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= -cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= -cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= -cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= -cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= -cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= -git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/99designs/gqlgen v0.17.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw= github.com/99designs/gqlgen v0.17.20/go.mod h1:Mja2HI23kWT1VRH09hvWshFgOzKswpO20o4ScpJIES4= -github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go= -github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= -github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= -github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= -github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/arangodb/go-driver v1.2.1 h1:HREDHhDmzdIWxHmfkfTESbYUnRjESjPh4WUuXq7FZa8= github.com/arangodb/go-driver v1.2.1/go.mod h1:zdDkJJnCj8DAkfbtIjIXnsTrWIiy6VhP3Vy14p+uQeY= -github.com/arangodb/go-driver v1.6.0 h1:NFWj/idqXZxhFVueihMSI2R9NotNIsgvNfM/xmpekb4= -github.com/arangodb/go-driver v1.6.0/go.mod h1:HQmdGkvNMVBTE3SIPSQ8T/ZddC6iwNsfMR+dDJQxIsI= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go v1.44.306/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go v1.44.320 h1:o2cno15HVUYj+IAgZHJ5No6ifAxwa2HcluzahMEPfOw= -github.com/aws/aws-sdk-go v1.44.320/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-iptables v0.4.3/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= -github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= -github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/couchbase/gocb/v2 v2.6.0 h1:DhkLNatDcddCcS411D6kNwZspSEAWVeI/N3abzt/HLc= github.com/couchbase/gocb/v2 v2.6.0/go.mod h1:5su8b1gBF3V4j07SiGw+CA0bK9a84YWEb6UH7up0MEs= -github.com/couchbase/gocb/v2 v2.6.3 h1:5RsMo+RRfK0mVxHLAfpBz3/tHlgXZb1WBNItLk9Ab+c= -github.com/couchbase/gocb/v2 v2.6.3/go.mod h1:yF5F6BHTZ/ZowhEuZbySbXrlI4rHd1TIhm5azOaMbJU= github.com/couchbase/gocbcore/v10 v10.2.0 h1:ZoSBLtcmt+lXbxVVT4SAhXDVNR+D48iSOZWNzHucVVk= github.com/couchbase/gocbcore/v10 v10.2.0/go.mod h1:qkPnOBziCs0guMEEvd0cRFo+AjOW0yEL99cU3I4n3Ao= -github.com/couchbase/gocbcore/v10 v10.2.3 h1:PEkRSNSkKjUBXx82Ucr094+anoiCG5GleOOQZOHo6D4= -github.com/couchbase/gocbcore/v10 v10.2.3/go.mod h1:lYQIIk+tzoMcwtwU5GzPbDdqEkwkH3isI2rkSpfL0oM= github.com/couchbaselabs/gocaves/client v0.0.0-20220223122017-22859b310bd2 h1:UlwJ2GWpZQAQCLHyO3xHKcqAjUUcX2w7FKpbxCIUQks= github.com/couchbaselabs/gocaves/client v0.0.0-20220223122017-22859b310bd2/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= -github.com/couchbaselabs/gocaves/client v0.0.0-20230307083111-cc3960c624b1/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= -github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259 h1:2TXy68EGEzIMHOx9UvczR5ApVecwCfQZ0LjkmwMI6g4= -github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -726,108 +95,53 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/glebarez/go-sqlite v1.19.1 h1:o2XhjyR8CQ2m84+bVz10G0cabmG0tY4sIMiCbrcUTrY= github.com/glebarez/go-sqlite v1.19.1/go.mod h1:9AykawGIyIcxoSfpYWiX1SgTNHTNsa/FVc75cDkbp4M= -github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= -github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= github.com/glebarez/sqlite v1.5.0 h1:+8LAEpmywqresSoGlqjjT+I9m4PseIM3NcerIJ/V7mk= github.com/glebarez/sqlite v1.5.0/go.mod h1:0wzXzTvfVJIN2GqRhCdMbnYd+m+aH5/QV7B30rM6NgY= -github.com/glebarez/sqlite v1.9.0 h1:Aj6bPA12ZEx5GbSF6XADmCkYXlljPNUY+Zf1EQxynXs= -github.com/glebarez/sqlite v1.9.0/go.mod h1:YBYCoyupOao60lzp1MVBLEjZfgkq0tdB1voAQ09K9zw= -github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= -github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= -github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= -github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= -github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw= -github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= -github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE= github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= -github.com/gocql/gocql v1.5.2 h1:WnKf8xRQImcT/KLaEWG2pjEeryDB7K0qQN9mPs1C58Q= -github.com/gocql/gocql v1.5.2/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -835,7 +149,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -851,20 +164,15 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -874,20 +182,12 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -895,68 +195,23 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4= github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE= -github.com/guregu/dynamo v1.20.1 h1:FFfi2unN453kcsRbyEbgG/LHSNuEWqMpdj285buyp6w= -github.com/guregu/dynamo v1.20.1/go.mod h1:rNSE8PT6IaNbcEno0/i0y6E5XFHDWUyLRxpGlF8O5CU= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -964,16 +219,7 @@ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= -github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= -github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels= -github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= -github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= -github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= -github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -985,27 +231,15 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -1017,35 +251,20 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275 h1:IZycmTpoUtQK3PD60UYBwjaCUHUP7cML494ao9/O8+Q= github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275/go.mod h1:zt6UU74K6Z6oMOYJbJzYpYucqdcQwSMPBEdSvGiaUMw= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= -github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc= -github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk= -github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= -github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1054,73 +273,41 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= -github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= -github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM= github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw= -github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0= -github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= -github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1130,43 +317,24 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/twilio/twilio-go v1.7.2 h1:tX38DXbSuDWWIK+tKAE2AJSMR6d8i7lf9ksY8J29VLE= github.com/twilio/twilio-go v1.7.2/go.mod h1:tdnfQ5TjbewoAu4lf9bMsGvfuJ/QU9gYuv9yx3TSIXU= -github.com/twilio/twilio-go v1.11.0 h1:ixO2DfAV4c0Yza0Tom5F5ZZB8WUbigiFc9wD84vbYnc= -github.com/twilio/twilio-go v1.11.0/go.mod h1:tdnfQ5TjbewoAu4lf9bMsGvfuJ/QU9gYuv9yx3TSIXU= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4= github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY= -github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= -github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= -github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4= -github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= @@ -1178,82 +346,40 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.mongodb.org/mongo-driver v1.8.1 h1:OZE4Wni/SJlrcmSIBRYNzunX5TKxjrTS4jKSnA99oKU= go.mongodb.org/mongo-driver v1.8.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= -go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= -go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1264,8 +390,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1274,19 +398,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1316,76 +431,23 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 h1:3B43BWw0xEBsLZ/NO1VALz6fppU3481pik+2Ksv45z8= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1395,15 +457,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1433,109 +489,51 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1550,7 +548,6 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1577,46 +574,16 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= -gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1633,51 +600,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= -google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= -google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1709,127 +631,12 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1842,36 +649,6 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1884,14 +661,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1905,7 +677,6 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= @@ -1914,7 +685,6 @@ gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -1925,25 +695,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= -gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= -gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= gorm.io/driver/postgres v1.4.7 h1:J06jXZCNq7Pdf7LIPn8tZn9LsWjd81BRSKveKNr0ZfA= gorm.io/driver/postgres v1.4.7/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4= -gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= -gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig= -gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4= -gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+kt0nM= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.2 h1:9wR6CFD+G8nOusLdvkZelOEhpJVwwHzpQOUM+REd6U0= gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= -gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8= -gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1951,72 +710,38 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= -modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= -modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= -modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0= -modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= -modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= -modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= -modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= -modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= -modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= modernc.org/libc v1.19.0 h1:bXyVhGQg6KIClTr8FMVIDPl7jtbcs7aS5WP7vLDaxPs= modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= -modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= -modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= -modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= -modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk= modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= -modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/sqlite v1.19.1 h1:8xmS5oLnZtAK//vnd4aTVj8VOeTAccEFOtUnIzfSw+4= modernc.org/sqlite v1.19.1/go.mod h1:UfQ83woKMaPW/ZBruK0T7YaFCrI+IE0LeWVY6pmnVms= -modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= -modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/tcl v1.14.0/go.mod h1:gQ7c1YPMvryCHCcmf8acB6VPabE59QBeuRQLL7cTUlM= -modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= modernc.org/z v1.6.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= -modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 5a001b7..77eba10 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -279,6 +279,7 @@ type ComplexityRoot struct { ValidateSessionResponse struct { IsValid func(childComplexity int) int + User func(childComplexity int) int } VerificationRequest struct { @@ -1871,6 +1872,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ValidateSessionResponse.IsValid(childComplexity), true + case "ValidateSessionResponse.user": + if e.complexity.ValidateSessionResponse.User == nil { + break + } + + return e.complexity.ValidateSessionResponse.User(childComplexity), true + case "VerificationRequest.created_at": if e.complexity.VerificationRequest.CreatedAt == nil { break @@ -2367,6 +2375,7 @@ type ValidateJWTTokenResponse { type ValidateSessionResponse { is_valid: Boolean! + user: User! } type GenerateJWTKeysResponse { @@ -10233,6 +10242,8 @@ func (ec *executionContext) fieldContext_Query_validate_session(ctx context.Cont switch field.Name { case "is_valid": return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field) + case "user": + return ec.fieldContext_ValidateSessionResponse_user(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name) }, @@ -12562,6 +12573,92 @@ func (ec *executionContext) fieldContext_ValidateSessionResponse_is_valid(ctx co return fc, nil } +func (ec *executionContext) _ValidateSessionResponse_user(ctx context.Context, field graphql.CollectedField, obj *model.ValidateSessionResponse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ValidateSessionResponse_user(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.User, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.User) + fc.Result = res + return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ValidateSessionResponse_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValidateSessionResponse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_User_id(ctx, field) + case "email": + return ec.fieldContext_User_email(ctx, field) + case "email_verified": + return ec.fieldContext_User_email_verified(ctx, field) + case "signup_methods": + return ec.fieldContext_User_signup_methods(ctx, field) + case "given_name": + return ec.fieldContext_User_given_name(ctx, field) + case "family_name": + return ec.fieldContext_User_family_name(ctx, field) + case "middle_name": + return ec.fieldContext_User_middle_name(ctx, field) + case "nickname": + return ec.fieldContext_User_nickname(ctx, field) + case "preferred_username": + return ec.fieldContext_User_preferred_username(ctx, field) + case "gender": + return ec.fieldContext_User_gender(ctx, field) + case "birthdate": + return ec.fieldContext_User_birthdate(ctx, field) + case "phone_number": + return ec.fieldContext_User_phone_number(ctx, field) + case "phone_number_verified": + return ec.fieldContext_User_phone_number_verified(ctx, field) + case "picture": + return ec.fieldContext_User_picture(ctx, field) + case "roles": + return ec.fieldContext_User_roles(ctx, field) + case "created_at": + return ec.fieldContext_User_created_at(ctx, field) + case "updated_at": + return ec.fieldContext_User_updated_at(ctx, field) + case "revoked_timestamp": + return ec.fieldContext_User_revoked_timestamp(ctx, field) + case "is_multi_factor_auth_enabled": + return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) + case "app_data": + return ec.fieldContext_User_app_data(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type User", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field graphql.CollectedField, obj *model.VerificationRequest) (ret graphql.Marshaler) { fc, err := ec.fieldContext_VerificationRequest_id(ctx, field) if err != nil { @@ -19668,6 +19765,13 @@ func (ec *executionContext) _ValidateSessionResponse(ctx context.Context, sel as out.Values[i] = ec._ValidateSessionResponse_is_valid(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "user": + + out.Values[i] = ec._ValidateSessionResponse_user(ctx, field, obj) + if out.Values[i] == graphql.Null { invalids++ } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index cac0235..a76b0e3 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -469,7 +469,8 @@ type ValidateSessionInput struct { } type ValidateSessionResponse struct { - IsValid bool `json:"is_valid"` + IsValid bool `json:"is_valid"` + User *User `json:"user"` } type VerificationRequest struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 1985aa7..9125acd 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -181,6 +181,7 @@ type ValidateJWTTokenResponse { type ValidateSessionResponse { is_valid: Boolean! + user: User! } type GenerateJWTKeysResponse { diff --git a/server/resolvers/validate_session.go b/server/resolvers/validate_session.go index cb2b11f..39adb1f 100644 --- a/server/resolvers/validate_session.go +++ b/server/resolvers/validate_session.go @@ -37,8 +37,9 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI log := log.WithFields(log.Fields{ "user_id": userID, }) - _, err = db.Provider.GetUserByID(ctx, userID) + user, err := db.Provider.GetUserByID(ctx, userID) if err != nil { + log.Debug("Failed to get user: ", err) return nil, err } // refresh token has "roles" as claim @@ -55,5 +56,6 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI } return &model.ValidateSessionResponse{ IsValid: true, + User: user.AsAPIUser(), }, nil } diff --git a/server/test/validate_session_test.go b/server/test/validate_session_test.go index 16211ad..b9573cb 100644 --- a/server/test/validate_session_test.go +++ b/server/test/validate_session_test.go @@ -56,6 +56,7 @@ func validateSessionTests(t *testing.T, s TestSetup) { res, err = resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{}) assert.Nil(t, err) assert.True(t, res.IsValid) + assert.Equal(t, res.User.ID, verifyRes.User.ID) cleanData(email) }) }