Skip to content

Commit abe809c

Browse files
committed
[draft] Move sms verificaiton to otp models
1 parent 07f71e8 commit abe809c

File tree

9 files changed

+78
-23
lines changed

9 files changed

+78
-23
lines changed

server/db/models/otp.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package models
22

3+
const (
4+
// FieldName email is the field name for email
5+
FieldNameEmail = "email"
6+
// FieldNamePhoneNumber is the field name for phone number
7+
FieldNamePhoneNumber = "phone_number"
8+
)
9+
310
// OTP model for database
411
type OTP struct {
5-
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
6-
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
7-
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"`
8-
Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
9-
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
10-
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
11-
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
12+
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
13+
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
14+
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"`
15+
PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"`
16+
Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
17+
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
18+
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
19+
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
1220
}
1321

1422
type Paging struct {

server/db/models/sms_verification_requests.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package models
22

3-
// SMS verification requests model for database
3+
// SMSVerificationRequest is SMS verification requests model for database
44
type SMSVerificationRequest struct {
5+
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
56
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
67
PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"`
78
Code string `json:"code" bson:"code" cql:"code" dynamo:"code"`

server/db/providers/arangodb/provider.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ func NewProvider() (*provider, error) {
225225
return nil, err
226226
}
227227
}
228-
229228
otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP)
230229
if err != nil {
231230
return nil, err
@@ -235,6 +234,24 @@ func NewProvider() (*provider, error) {
235234
Sparse: true,
236235
})
237236

237+
smsVerificationCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.SMSVerificationRequest)
238+
if err != nil {
239+
return nil, err
240+
}
241+
if !smsVerificationCollectionExists {
242+
_, err = arangodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, nil)
243+
if err != nil {
244+
return nil, err
245+
}
246+
}
247+
smsVerificationCollection, err := arangodb.Collection(ctx, models.Collections.SMSVerificationRequest)
248+
if err != nil {
249+
return nil, err
250+
}
251+
smsVerificationCollection.EnsureHashIndex(ctx, []string{"phone_number"}, &arangoDriver.EnsureHashIndexOptions{
252+
Unique: true,
253+
Sparse: true,
254+
})
238255
return &provider{
239256
db: arangodb,
240257
}, err

server/db/providers/couchbase/shared.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,19 @@ import (
1111

1212
func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) {
1313
params := make(map[string]interface{}, 1)
14-
1514
updateFields := ""
16-
1715
for key, value := range webhookMap {
1816
if key == "_id" {
1917
continue
2018
}
21-
2219
if key == "_key" {
2320
continue
2421
}
25-
2622
if value == nil {
2723
updateFields += fmt.Sprintf("%s=$%s,", key, key)
2824
params[key] = "null"
2925
continue
3026
}
31-
3227
valueType := reflect.TypeOf(value)
3328
if valueType.Name() == "string" {
3429
updateFields += fmt.Sprintf("%s = $%s, ", key, key)

server/db/providers/mongodb/otp.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mongodb
22

33
import (
44
"context"
5+
"errors"
56
"time"
67

78
"github.com/authorizerdev/authorizer/server/db/models"
@@ -12,6 +13,18 @@ import (
1213

1314
// UpsertOTP to add or update otp
1415
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
16+
// check if email or phone number is present
17+
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
18+
return nil, errors.New("email or phone_number is required")
19+
}
20+
// check if email or phone number is present
21+
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
22+
return nil, errors.New("email or phone_number is required")
23+
}
24+
uniqueField := models.FieldNameEmail
25+
if otp.Email == "" && otp.PhoneNumber != "" {
26+
uniqueField = models.FieldNamePhoneNumber
27+
}
1528
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
1629
shouldCreate := false
1730
if otp == nil {

server/db/providers/mongodb/provider.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ func NewProvider() (*provider, error) {
118118
Options: options.Index().SetUnique(true).SetSparse(true),
119119
},
120120
}, options.CreateIndexes())
121+
otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
122+
{
123+
Keys: bson.M{"phone_number": 1},
124+
Options: options.Index().SetUnique(true).SetSparse(true),
125+
},
126+
}, options.CreateIndexes())
121127

122128
mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection())
123129
smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection())

server/db/providers/mongodb/sms_verification_requests.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ import (
1212

1313
// UpsertSMSRequest adds/updates SMS verification request
1414
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
15-
smsVerificationRequest, err := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
16-
if err != nil {
17-
return nil, err
18-
}
15+
smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
1916
// Boolean to check if we should create a new record or update the existing one
2017
shouldCreate := false
2118
if smsVerificationRequest == nil {
@@ -29,7 +26,7 @@ func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSV
2926
}
3027
shouldCreate = true
3128
}
32-
29+
var err error
3330
smsVerificationRequest.UpdatedAt = time.Now().Unix()
3431
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
3532
if shouldCreate {

server/db/providers/providers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ type Provider interface {
8282
UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
8383
// GetOTPByEmail to get otp for a given email address
8484
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
85+
// GetOTPByPhoneNumber to get otp for a given phone number
86+
GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error)
8587
// DeleteOTP to delete otp
8688
DeleteOTP(ctx context.Context, otp *models.OTP) error
8789

server/db/providers/sql/otp.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package sql
22

33
import (
44
"context"
5+
"errors"
56
"time"
67

78
"github.com/authorizerdev/authorizer/server/db/models"
@@ -14,13 +15,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP,
1415
if otp.ID == "" {
1516
otp.ID = uuid.New().String()
1617
}
17-
18+
// check if email or phone number is present
19+
if otp.Email == "" && otp.PhoneNumber == "" {
20+
return nil, errors.New("email or phone_number is required")
21+
}
22+
uniqueField := models.FieldNameEmail
23+
if otp.Email == "" && otp.PhoneNumber != "" {
24+
uniqueField = models.FieldNamePhoneNumber
25+
}
1826
otp.Key = otp.ID
1927
otp.CreatedAt = time.Now().Unix()
2028
otp.UpdatedAt = time.Now().Unix()
21-
2229
res := p.db.Clauses(clause.OnConflict{
23-
Columns: []clause.Column{{Name: "email"}},
30+
Columns: []clause.Column{{Name: uniqueField}},
2431
DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}),
2532
}).Create(&otp)
2633
if res.Error != nil {
@@ -33,14 +40,23 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP,
3340
// GetOTPByEmail to get otp for a given email address
3441
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
3542
var otp models.OTP
36-
3743
result := p.db.Where("email = ?", emailAddress).First(&otp)
3844
if result.Error != nil {
3945
return nil, result.Error
4046
}
4147
return &otp, nil
4248
}
4349

50+
// GetOTPByPhoneNumber to get otp for a given phone number
51+
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
52+
var otp models.OTP
53+
result := p.db.Where("phone_number = ?", phoneNumber).First(&otp)
54+
if result.Error != nil {
55+
return nil, result.Error
56+
}
57+
return &otp, nil
58+
}
59+
4460
// DeleteOTP to delete otp
4561
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
4662
result := p.db.Delete(&models.OTP{

0 commit comments

Comments
 (0)