[draft] Move sms verificaiton to otp models
This commit is contained in:
parent
07f71e883b
commit
abe809ca68
|
@ -1,14 +1,22 @@
|
||||||
package models
|
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
|
// OTP model for database
|
||||||
type OTP struct {
|
type OTP struct {
|
||||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
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"`
|
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"`
|
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"`
|
PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"`
|
||||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
|
Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
|
||||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
|
||||||
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"`
|
||||||
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Paging struct {
|
type Paging struct {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
// SMS verification requests model for database
|
// SMSVerificationRequest is SMS verification requests model for database
|
||||||
type SMSVerificationRequest struct {
|
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"`
|
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"`
|
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"`
|
Code string `json:"code" bson:"code" cql:"code" dynamo:"code"`
|
||||||
|
|
|
@ -225,7 +225,6 @@ func NewProvider() (*provider, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP)
|
otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -235,6 +234,24 @@ func NewProvider() (*provider, error) {
|
||||||
Sparse: 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{
|
||||||
|
Unique: true,
|
||||||
|
Sparse: true,
|
||||||
|
})
|
||||||
return &provider{
|
return &provider{
|
||||||
db: arangodb,
|
db: arangodb,
|
||||||
}, err
|
}, err
|
||||||
|
|
|
@ -11,24 +11,19 @@ import (
|
||||||
|
|
||||||
func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) {
|
func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) {
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
|
|
||||||
updateFields := ""
|
updateFields := ""
|
||||||
|
|
||||||
for key, value := range webhookMap {
|
for key, value := range webhookMap {
|
||||||
if key == "_id" {
|
if key == "_id" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "_key" {
|
if key == "_key" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
updateFields += fmt.Sprintf("%s=$%s,", key, key)
|
updateFields += fmt.Sprintf("%s=$%s,", key, key)
|
||||||
params[key] = "null"
|
params[key] = "null"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
valueType := reflect.TypeOf(value)
|
valueType := reflect.TypeOf(value)
|
||||||
if valueType.Name() == "string" {
|
if valueType.Name() == "string" {
|
||||||
updateFields += fmt.Sprintf("%s = $%s, ", key, key)
|
updateFields += fmt.Sprintf("%s = $%s, ", key, key)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -12,6 +13,18 @@ import (
|
||||||
|
|
||||||
// UpsertOTP to add or update otp
|
// UpsertOTP to add or update otp
|
||||||
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
|
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)
|
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
|
||||||
shouldCreate := false
|
shouldCreate := false
|
||||||
if otp == nil {
|
if otp == nil {
|
||||||
|
|
|
@ -118,6 +118,12 @@ func NewProvider() (*provider, error) {
|
||||||
Options: options.Index().SetUnique(true).SetSparse(true),
|
Options: options.Index().SetUnique(true).SetSparse(true),
|
||||||
},
|
},
|
||||||
}, options.CreateIndexes())
|
}, 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())
|
mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection())
|
||||||
smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection())
|
smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection())
|
||||||
|
|
|
@ -12,10 +12,7 @@ import (
|
||||||
|
|
||||||
// UpsertSMSRequest adds/updates SMS verification request
|
// UpsertSMSRequest adds/updates SMS verification request
|
||||||
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
|
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
|
||||||
smsVerificationRequest, err := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
|
smsVerificationRequest, _ := 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
|
// Boolean to check if we should create a new record or update the existing one
|
||||||
shouldCreate := false
|
shouldCreate := false
|
||||||
if smsVerificationRequest == nil {
|
if smsVerificationRequest == nil {
|
||||||
|
@ -29,7 +26,7 @@ func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSV
|
||||||
}
|
}
|
||||||
shouldCreate = true
|
shouldCreate = true
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
smsVerificationRequest.UpdatedAt = time.Now().Unix()
|
smsVerificationRequest.UpdatedAt = time.Now().Unix()
|
||||||
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
|
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
|
||||||
if shouldCreate {
|
if shouldCreate {
|
||||||
|
|
|
@ -82,6 +82,8 @@ type Provider interface {
|
||||||
UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
|
UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
|
||||||
// GetOTPByEmail to get otp for a given email address
|
// GetOTPByEmail to get otp for a given email address
|
||||||
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
|
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 to delete otp
|
||||||
DeleteOTP(ctx context.Context, otp *models.OTP) error
|
DeleteOTP(ctx context.Context, otp *models.OTP) error
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"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 == "" {
|
if otp.ID == "" {
|
||||||
otp.ID = uuid.New().String()
|
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.Key = otp.ID
|
||||||
otp.CreatedAt = time.Now().Unix()
|
otp.CreatedAt = time.Now().Unix()
|
||||||
otp.UpdatedAt = time.Now().Unix()
|
otp.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
res := p.db.Clauses(clause.OnConflict{
|
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"}),
|
DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}),
|
||||||
}).Create(&otp)
|
}).Create(&otp)
|
||||||
if res.Error != nil {
|
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
|
// GetOTPByEmail to get otp for a given email address
|
||||||
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
|
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
|
||||||
var otp models.OTP
|
var otp models.OTP
|
||||||
|
|
||||||
result := p.db.Where("email = ?", emailAddress).First(&otp)
|
result := p.db.Where("email = ?", emailAddress).First(&otp)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
|
@ -41,6 +47,16 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
|
||||||
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
|
||||||
|
result := p.db.Where("phone_number = ?", phoneNumber).First(&otp)
|
||||||
|
if result.Error != nil {
|
||||||
|
return nil, result.Error
|
||||||
|
}
|
||||||
|
return &otp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteOTP to delete otp
|
// DeleteOTP to delete otp
|
||||||
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
|
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
|
||||||
result := p.db.Delete(&models.OTP{
|
result := p.db.Delete(&models.OTP{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user