Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9ae616b6b5 | ||
![]() |
356428ea02 | ||
![]() |
7f47177741 | ||
![]() |
9fb00544cd | ||
![]() |
2b022d1058 | ||
![]() |
1c84d9f4a8 | ||
![]() |
0838b60fae | ||
![]() |
325134466d | ||
![]() |
58d9978dd5 | ||
![]() |
801d64e2f5 | ||
![]() |
dd3cc9de3a | ||
![]() |
8dc7366182 | ||
![]() |
7749534087 | ||
![]() |
510f16e7b0 | ||
![]() |
d5e83ea14f | ||
![]() |
b4a90de1d4 | ||
![]() |
c525ad92f2 | ||
![]() |
9028682e93 | ||
![]() |
3d6bfe4480 | ||
![]() |
043af08bf0 | ||
![]() |
0af78479fc | ||
![]() |
096f686495 | ||
![]() |
c574c6a679 | ||
![]() |
6428b74e64 | ||
![]() |
aa3892025d | ||
![]() |
b2f3d6eb80 | ||
![]() |
348cbf8c38 | ||
![]() |
8ac33a085c | ||
![]() |
6c9b359081 | ||
![]() |
0fde46d274 | ||
![]() |
1a5b446894 | ||
![]() |
930c934fdb | ||
![]() |
4e7074d75b | ||
![]() |
bdfa045a43 | ||
![]() |
a258399bde | ||
![]() |
55a25436a8 | ||
![]() |
9fa402f5c8 | ||
![]() |
1111729ad4 | ||
![]() |
e56c2f58e5 | ||
![]() |
8dbd2556eb | ||
![]() |
17bb077f3e | ||
![]() |
f291417378 | ||
![]() |
f831379d27 | ||
![]() |
a50f6becbd | ||
![]() |
a6f6e0b18a | ||
![]() |
3868157e11 | ||
![]() |
d693c05483 |
@@ -7,4 +7,5 @@ SMTP_PORT=2525
|
||||
SMTP_USERNAME=test
|
||||
SMTP_PASSWORD=test
|
||||
SENDER_EMAIL="info@authorizer.dev"
|
||||
SENDER_NAME="Authorizer"
|
||||
AWS_REGION=ap-south-1
|
@@ -126,6 +126,22 @@ const EmailConfigurations = ({
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Sender Name:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SENDER_NAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
|
@@ -8,86 +8,90 @@ const Features = ({ variables, setVariables }: any) => {
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Disable Features
|
||||
Features
|
||||
</Text>
|
||||
<Stack spacing={6}>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Login Page:</Text>
|
||||
<Text fontSize="sm">Login Page:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_LOGIN_PAGE}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Email Verification:</Text>
|
||||
<Text fontSize="sm">Email Verification:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_EMAIL_VERIFICATION}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Magic Login Link:</Text>
|
||||
<Text fontSize="sm">Magic Login Link:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_MAGIC_LINK_LOGIN}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Basic Authentication:</Text>
|
||||
<Text fontSize="sm">Basic Authentication:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_BASIC_AUTHENTICATION}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Sign Up:</Text>
|
||||
<Text fontSize="sm">Sign Up:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start" mb={3}>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_SIGN_UP}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Disable Strong Password:</Text>
|
||||
<Text fontSize="sm">Strong Password:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start" mb={3}>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_STRONG_PASSWORD}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex alignItems="center">
|
||||
<Flex w="100%" alignItems="baseline" flexDir="column">
|
||||
<Text fontSize="sm">
|
||||
Disable Multi Factor Authentication (MFA):
|
||||
</Text>
|
||||
<Text fontSize="sm">Multi Factor Authentication (MFA):</Text>
|
||||
<Text fontSize="x-small">
|
||||
Note: Enabling this will ignore Enforcing MFA shown below and will
|
||||
also ignore the user MFA setting.
|
||||
@@ -98,15 +102,10 @@ const Features = ({ variables, setVariables }: any) => {
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.DISABLE_MULTI_FACTOR_AUTHENTICATION}
|
||||
hasReversedValue
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Stack>
|
||||
<Divider paddingY={5} />
|
||||
<Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}>
|
||||
Enable Features
|
||||
</Text>
|
||||
<Stack spacing={6}>
|
||||
<Flex alignItems="center">
|
||||
<Flex w="100%" alignItems="baseline" flexDir="column">
|
||||
<Text fontSize="sm">
|
||||
|
@@ -48,6 +48,8 @@ const InputField = ({
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
availableRoles,
|
||||
// This prop is added to improve the user experience for the boolean ENV variable having `DISABLE_` prefix, as those values need to be considered in inverted form.
|
||||
hasReversedValue,
|
||||
...downshiftProps
|
||||
}: any) => {
|
||||
const props = {
|
||||
@@ -398,7 +400,9 @@ const InputField = ({
|
||||
</Text>
|
||||
<Switch
|
||||
size="md"
|
||||
isChecked={variables[inputType]}
|
||||
isChecked={
|
||||
hasReversedValue ? !variables[inputType] : variables[inputType]
|
||||
}
|
||||
onChange={() => {
|
||||
setVariables({
|
||||
...variables,
|
||||
|
@@ -19,6 +19,7 @@ export const TextInputType = {
|
||||
SMTP_USERNAME: 'SMTP_USERNAME',
|
||||
SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME',
|
||||
SENDER_EMAIL: 'SENDER_EMAIL',
|
||||
SENDER_NAME: 'SENDER_NAME',
|
||||
ORGANIZATION_NAME: 'ORGANIZATION_NAME',
|
||||
ORGANIZATION_LOGO: 'ORGANIZATION_LOGO',
|
||||
DATABASE_NAME: 'DATABASE_NAME',
|
||||
@@ -143,6 +144,7 @@ export interface envVarTypes {
|
||||
SMTP_PASSWORD: string;
|
||||
SMTP_LOCAL_NAME: string;
|
||||
SENDER_EMAIL: string;
|
||||
SENDER_NAME: string;
|
||||
ALLOWED_ORIGINS: [string] | [];
|
||||
ORGANIZATION_NAME: string;
|
||||
ORGANIZATION_LOGO: string;
|
||||
|
@@ -50,6 +50,7 @@ export const EnvVariablesQuery = `
|
||||
SMTP_PASSWORD
|
||||
SMTP_LOCAL_NAME
|
||||
SENDER_EMAIL
|
||||
SENDER_NAME
|
||||
ALLOWED_ORIGINS
|
||||
ORGANIZATION_NAME
|
||||
ORGANIZATION_LOGO
|
||||
|
@@ -70,6 +70,7 @@ const Environment = () => {
|
||||
SMTP_PASSWORD: '',
|
||||
SMTP_LOCAL_NAME: '',
|
||||
SENDER_EMAIL: '',
|
||||
SENDER_NAME: '',
|
||||
ALLOWED_ORIGINS: [],
|
||||
ORGANIZATION_NAME: '',
|
||||
ORGANIZATION_LOGO: '',
|
||||
|
@@ -62,6 +62,8 @@ const (
|
||||
EnvKeySmtpLocalName = "SMTP_LOCAL_NAME"
|
||||
// EnvKeySenderEmail key for env variable SENDER_EMAIL
|
||||
EnvKeySenderEmail = "SENDER_EMAIL"
|
||||
// EnvKeySenderName key for env variable SENDER_NAME
|
||||
EnvKeySenderName = "SENDER_NAME"
|
||||
// EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
|
||||
EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED"
|
||||
// EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
|
||||
@@ -174,4 +176,13 @@ const (
|
||||
// EnvKeyDefaultAuthorizeResponseMode key for env variable DEFAULT_AUTHORIZE_RESPONSE_MODE
|
||||
// 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 = "TWILIO_API_KEY"
|
||||
EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
|
||||
EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
|
||||
EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM"
|
||||
)
|
||||
|
@@ -10,6 +10,7 @@ type CollectionList struct {
|
||||
WebhookLog string
|
||||
EmailTemplate string
|
||||
OTP string
|
||||
SMSVerificationRequest string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -25,5 +26,6 @@ var (
|
||||
WebhookLog: Prefix + "webhook_logs",
|
||||
EmailTemplate: Prefix + "email_templates",
|
||||
OTP: Prefix + "otps",
|
||||
SMSVerificationRequest: Prefix + "sms_verification_requests",
|
||||
}
|
||||
)
|
||||
|
11
server/db/models/sms_verification_requests.go
Normal file
11
server/db/models/sms_verification_requests.go
Normal file
@@ -0,0 +1,11 @@
|
||||
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"`
|
||||
}
|
23
server/db/providers/arangodb/sms_verification_requests.go
Normal file
23
server/db/providers/arangodb/sms_verification_requests.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package arangodb
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
|
||||
var sms_verification_request models.SMSVerificationRequest
|
||||
|
||||
return &sms_verification_request, nil
|
||||
}
|
||||
|
||||
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
|
||||
return nil
|
||||
}
|
23
server/db/providers/cassandradb/sms_verification_requests.go
Normal file
23
server/db/providers/cassandradb/sms_verification_requests.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package cassandradb
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
|
||||
var sms_verification_request models.SMSVerificationRequest
|
||||
|
||||
return &sms_verification_request, nil
|
||||
}
|
||||
|
||||
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
|
||||
return nil
|
||||
}
|
23
server/db/providers/couchbase/sms_verification_requests.go
Normal file
23
server/db/providers/couchbase/sms_verification_requests.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package couchbase
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
|
||||
var sms_verification_request models.SMSVerificationRequest
|
||||
|
||||
return &sms_verification_request, nil
|
||||
}
|
||||
|
||||
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
|
||||
return nil
|
||||
}
|
23
server/db/providers/dynamodb/sms_verification_requests.go
Normal file
23
server/db/providers/dynamodb/sms_verification_requests.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package dynamodb
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
|
||||
var sms_verification_request models.SMSVerificationRequest
|
||||
|
||||
return &sms_verification_request, nil
|
||||
}
|
||||
|
||||
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
|
||||
return nil
|
||||
}
|
@@ -119,6 +119,15 @@ 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
|
||||
|
69
server/db/providers/mongodb/sms_verification_requests.go
Normal file
69
server/db/providers/mongodb/sms_verification_requests.go
Normal file
@@ -0,0 +1,69 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// SMS verification Request
|
||||
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
|
||||
smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
@@ -84,4 +84,11 @@ type Provider interface {
|
||||
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
|
||||
// DeleteOTP to delete otp
|
||||
DeleteOTP(ctx context.Context, otp *models.OTP) error
|
||||
|
||||
// Upsert SMS code request
|
||||
UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error)
|
||||
// Get sms code by phone number
|
||||
GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error)
|
||||
// Delete sms
|
||||
DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error
|
||||
}
|
||||
|
@@ -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{}, &models.SMSVerificationRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
51
server/db/providers/sql/sms_verification_requests.go
Normal file
51
server/db/providers/sql/sms_verification_requests.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// 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"}),
|
||||
}).Create(smsRequest)
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
|
||||
return smsRequest, nil
|
||||
}
|
||||
|
||||
// GetOTPByEmail to get otp for a given email address
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
@@ -103,6 +103,12 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
senderName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySenderName)
|
||||
if err != nil {
|
||||
log.Errorf("Error while getting sender name from env variable: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
smtpPort, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)
|
||||
if err != nil {
|
||||
log.Errorf("Error while getting smtp port from env variable: %v", err)
|
||||
@@ -139,7 +145,7 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
m.SetHeader("From", senderEmail)
|
||||
m.SetAddressHeader("From", senderEmail, senderName)
|
||||
m.SetHeader("To", to...)
|
||||
m.SetHeader("Subject", tmp.Subject)
|
||||
m.SetBody("text/html", tmp.Template)
|
||||
|
51
server/env/env.go
vendored
51
server/env/env.go
vendored
@@ -57,6 +57,7 @@ func InitAllEnv() error {
|
||||
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
|
||||
osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName)
|
||||
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
|
||||
osSenderName := os.Getenv(constants.EnvKeySenderName)
|
||||
osJwtType := os.Getenv(constants.EnvKeyJwtType)
|
||||
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
|
||||
osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
|
||||
@@ -110,6 +111,15 @@ 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
|
||||
@@ -135,6 +145,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
|
||||
}
|
||||
@@ -257,6 +268,13 @@ func InitAllEnv() error {
|
||||
envData[constants.EnvKeySenderEmail] = osSenderEmail
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvKeySenderName]; !ok || val == "" {
|
||||
envData[constants.EnvKeySenderName] = osSenderName
|
||||
}
|
||||
if osSenderName != "" && envData[constants.EnvKeySenderName] != osSenderName {
|
||||
envData[constants.EnvKeySenderName] = osSenderName
|
||||
}
|
||||
|
||||
algoVal, ok := envData[constants.EnvKeyJwtType]
|
||||
algo := ""
|
||||
if !ok || algoVal == "" {
|
||||
@@ -583,7 +601,7 @@ func InitAllEnv() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
|
||||
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin] {
|
||||
envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
|
||||
}
|
||||
}
|
||||
@@ -759,6 +777,37 @@ func InitAllEnv() error {
|
||||
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
|
||||
}
|
||||
|
||||
if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret {
|
||||
envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
|
||||
}
|
||||
|
||||
if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey {
|
||||
envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
|
||||
}
|
||||
|
||||
if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
|
||||
envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
|
||||
}
|
||||
|
||||
if osTwilioSenderFrom != "" && envData[constants.EnvKeyTwilioSenderFrom] != osTwilioSenderFrom {
|
||||
envData[constants.EnvKeyTwilioSenderFrom] = osTwilioSenderFrom
|
||||
}
|
||||
|
||||
if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
|
||||
envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
|
||||
}
|
||||
|
||||
if osDisablePhoneVerification != "" {
|
||||
boolValue, err := strconv.ParseBool(osDisablePhoneVerification)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if boolValue != envData[constants.EnvKeyDisablePhoneVerification] {
|
||||
envData[constants.EnvKeyDisablePhoneVerification] = boolValue
|
||||
}
|
||||
}
|
||||
|
||||
err = memorystore.Provider.UpdateEnvStore(envData)
|
||||
if err != nil {
|
||||
log.Debug("Error while updating env store: ", err)
|
||||
|
2
server/env/persist_env.go
vendored
2
server/env/persist_env.go
vendored
@@ -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:
|
||||
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:
|
||||
if envValueBool, err := strconv.ParseBool(envValue); err == nil {
|
||||
if value.(bool) != envValueBool {
|
||||
storeData[key] = envValueBool
|
||||
|
@@ -25,6 +25,7 @@ require (
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/twilio/twilio-go v1.7.2
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
go.mongodb.org/mongo-driver v1.8.1
|
||||
golang.org/x/crypto v0.4.0
|
||||
|
@@ -54,6 +54,7 @@ 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/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=
|
||||
@@ -151,6 +152,8 @@ 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.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=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -251,6 +254,8 @@ 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/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/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
@@ -271,6 +276,7 @@ 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/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=
|
||||
@@ -316,6 +322,8 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
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/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=
|
||||
@@ -338,6 +346,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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=
|
||||
go.mongodb.org/mongo-driver v1.8.1 h1:OZE4Wni/SJlrcmSIBRYNzunX5TKxjrTS4jKSnA99oKU=
|
||||
@@ -392,6 +401,7 @@ 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.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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=
|
||||
@@ -425,6 +435,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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=
|
||||
@@ -483,7 +494,9 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20210124154548-22da62e12c0c/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-20210510120138-977fb7262007/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -558,6 +571,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
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-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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=
|
||||
@@ -651,6 +665,7 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
|
@@ -128,6 +128,7 @@ type ComplexityRoot struct {
|
||||
SMTPPort func(childComplexity int) int
|
||||
SMTPUsername func(childComplexity int) int
|
||||
SenderEmail func(childComplexity int) int
|
||||
SenderName func(childComplexity int) int
|
||||
TwitterClientID func(childComplexity int) int
|
||||
TwitterClientSecret func(childComplexity int) int
|
||||
}
|
||||
@@ -197,6 +198,7 @@ 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
|
||||
}
|
||||
|
||||
@@ -227,6 +229,15 @@ type ComplexityRoot struct {
|
||||
Message func(childComplexity int) int
|
||||
}
|
||||
|
||||
SMSVerificationRequests struct {
|
||||
Code func(childComplexity int) int
|
||||
CodeExpiresAt func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
PhoneNumber func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
}
|
||||
|
||||
TestEndpointResponse struct {
|
||||
HTTPStatus func(childComplexity int) int
|
||||
Response func(childComplexity int) int
|
||||
@@ -328,6 +339,7 @@ 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)
|
||||
@@ -895,6 +907,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Env.SenderEmail(childComplexity), true
|
||||
|
||||
case "Env.SENDER_NAME":
|
||||
if e.complexity.Env.SenderName == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Env.SenderName(childComplexity), true
|
||||
|
||||
case "Env.TWITTER_CLIENT_ID":
|
||||
if e.complexity.Env.TwitterClientID == nil {
|
||||
break
|
||||
@@ -1413,6 +1432,18 @@ 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
|
||||
@@ -1596,6 +1627,48 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Response.Message(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.code":
|
||||
if e.complexity.SMSVerificationRequests.Code == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.Code(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.code_expires_at":
|
||||
if e.complexity.SMSVerificationRequests.CodeExpiresAt == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.CodeExpiresAt(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.created_at":
|
||||
if e.complexity.SMSVerificationRequests.CreatedAt == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.CreatedAt(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.id":
|
||||
if e.complexity.SMSVerificationRequests.ID == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.ID(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.phone_number":
|
||||
if e.complexity.SMSVerificationRequests.PhoneNumber == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.PhoneNumber(childComplexity), true
|
||||
|
||||
case "SMSVerificationRequests.updated_at":
|
||||
if e.complexity.SMSVerificationRequests.UpdatedAt == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SMSVerificationRequests.UpdatedAt(childComplexity), true
|
||||
|
||||
case "TestEndpointResponse.http_status":
|
||||
if e.complexity.TestEndpointResponse.HTTPStatus == nil {
|
||||
break
|
||||
@@ -2021,6 +2094,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
ec.unmarshalInputUpdateWebhookRequest,
|
||||
ec.unmarshalInputValidateJWTTokenInput,
|
||||
ec.unmarshalInputVerifyEmailInput,
|
||||
ec.unmarshalInputVerifyMobileRequest,
|
||||
ec.unmarshalInputVerifyOTPRequest,
|
||||
ec.unmarshalInputWebhookRequest,
|
||||
)
|
||||
@@ -2160,6 +2234,20 @@ type VerificationRequests {
|
||||
verification_requests: [VerificationRequest!]!
|
||||
}
|
||||
|
||||
type SMSVerificationRequests {
|
||||
id: ID!
|
||||
code: String!
|
||||
code_expires_at: Int64!
|
||||
phone_number: String!
|
||||
created_at: Int64!
|
||||
updated_at: Int64
|
||||
}
|
||||
|
||||
input VerifyMobileRequest {
|
||||
phone_number: String!
|
||||
code: String!
|
||||
}
|
||||
|
||||
type Error {
|
||||
message: String!
|
||||
reason: String!
|
||||
@@ -2203,6 +2291,7 @@ type Env {
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
SENDER_NAME: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
@@ -2320,6 +2409,7 @@ input UpdateEnvInput {
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
SENDER_NAME: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
@@ -2620,7 +2710,8 @@ input ResendOTPRequest {
|
||||
}
|
||||
|
||||
input GetUserRequest {
|
||||
id: String!
|
||||
id: String
|
||||
email: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -2638,6 +2729,7 @@ 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!
|
||||
@@ -3102,6 +3194,21 @@ 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{}{}
|
||||
@@ -4795,6 +4902,47 @@ func (ec *executionContext) fieldContext_Env_SENDER_EMAIL(ctx context.Context, f
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Env_SENDER_NAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Env_SENDER_NAME(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.SenderName, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Env_SENDER_NAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Env",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Env_JWT_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Env_JWT_TYPE(ctx, field)
|
||||
if err != nil {
|
||||
@@ -8436,6 +8584,77 @@ 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 {
|
||||
@@ -10280,6 +10499,8 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
|
||||
return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field)
|
||||
case "SENDER_EMAIL":
|
||||
return ec.fieldContext_Env_SENDER_EMAIL(ctx, field)
|
||||
case "SENDER_NAME":
|
||||
return ec.fieldContext_Env_SENDER_NAME(ctx, field)
|
||||
case "JWT_TYPE":
|
||||
return ec.fieldContext_Env_JWT_TYPE(ctx, field)
|
||||
case "JWT_SECRET":
|
||||
@@ -10800,6 +11021,267 @@ func (ec *executionContext) fieldContext_Response_message(ctx context.Context, f
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_id(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_id(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.ID, 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.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNID2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type ID does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_code(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_code(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.Code, 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.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_code(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_code_expires_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_code_expires_at(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.CodeExpiresAt, 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.(int64)
|
||||
fc.Result = res
|
||||
return ec.marshalNInt642int64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_code_expires_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int64 does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_phone_number(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_phone_number(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.PhoneNumber, 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.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_phone_number(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_created_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_created_at(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.CreatedAt, 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.(int64)
|
||||
fc.Result = res
|
||||
return ec.marshalNInt642int64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int64 does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests_updated_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_SMSVerificationRequests_updated_at(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.UpdatedAt, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int64)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_SMSVerificationRequests_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "SMSVerificationRequests",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int64 does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _TestEndpointResponse_http_status(ctx context.Context, field graphql.CollectedField, obj *model.TestEndpointResponse) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_TestEndpointResponse_http_status(ctx, field)
|
||||
if err != nil {
|
||||
@@ -15316,7 +15798,7 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"id"}
|
||||
fieldsInOrder := [...]string{"id", "email"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -15327,7 +15809,15 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id"))
|
||||
it.ID, err = ec.unmarshalNString2string(ctx, v)
|
||||
it.ID, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "email":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
||||
it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
@@ -16276,7 +16766,7 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE"}
|
||||
fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "SENDER_NAME", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -16363,6 +16853,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "SENDER_NAME":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("SENDER_NAME"))
|
||||
it.SenderName, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "JWT_TYPE":
|
||||
var err error
|
||||
|
||||
@@ -17093,6 +17591,42 @@ 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{}{}
|
||||
@@ -17412,6 +17946,10 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
|
||||
|
||||
out.Values[i] = ec._Env_SENDER_EMAIL(ctx, field, obj)
|
||||
|
||||
case "SENDER_NAME":
|
||||
|
||||
out.Values[i] = ec._Env_SENDER_NAME(ctx, field, obj)
|
||||
|
||||
case "JWT_TYPE":
|
||||
|
||||
out.Values[i] = ec._Env_JWT_TYPE(ctx, field, obj)
|
||||
@@ -17995,6 +18533,15 @@ 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++
|
||||
}
|
||||
@@ -18580,6 +19127,66 @@ func (ec *executionContext) _Response(ctx context.Context, sel ast.SelectionSet,
|
||||
return out
|
||||
}
|
||||
|
||||
var sMSVerificationRequestsImplementors = []string{"SMSVerificationRequests"}
|
||||
|
||||
func (ec *executionContext) _SMSVerificationRequests(ctx context.Context, sel ast.SelectionSet, obj *model.SMSVerificationRequests) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, sMSVerificationRequestsImplementors)
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("SMSVerificationRequests")
|
||||
case "id":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_id(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "code":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_code(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "code_expires_at":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_code_expires_at(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "phone_number":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_phone_number(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "created_at":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_created_at(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "updated_at":
|
||||
|
||||
out.Values[i] = ec._SMSVerificationRequests_updated_at(ctx, field, obj)
|
||||
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var testEndpointResponseImplementors = []string{"TestEndpointResponse"}
|
||||
|
||||
func (ec *executionContext) _TestEndpointResponse(ctx context.Context, sel ast.SelectionSet, obj *model.TestEndpointResponse) graphql.Marshaler {
|
||||
@@ -19936,6 +20543,11 @@ 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)
|
||||
|
@@ -77,6 +77,7 @@ type Env struct {
|
||||
SMTPPassword *string `json:"SMTP_PASSWORD"`
|
||||
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
|
||||
SenderEmail *string `json:"SENDER_EMAIL"`
|
||||
SenderName *string `json:"SENDER_NAME"`
|
||||
JwtType *string `json:"JWT_TYPE"`
|
||||
JwtSecret *string `json:"JWT_SECRET"`
|
||||
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
|
||||
@@ -119,6 +120,7 @@ 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 {
|
||||
@@ -143,7 +145,8 @@ type GenerateJWTKeysResponse struct {
|
||||
}
|
||||
|
||||
type GetUserRequest struct {
|
||||
ID string `json:"id"`
|
||||
ID *string `json:"id"`
|
||||
Email *string `json:"email"`
|
||||
}
|
||||
|
||||
type InviteMemberInput struct {
|
||||
@@ -263,6 +266,15 @@ type Response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type SMSVerificationRequests struct {
|
||||
ID string `json:"id"`
|
||||
Code string `json:"code"`
|
||||
CodeExpiresAt int64 `json:"code_expires_at"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt *int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
type SessionQueryInput struct {
|
||||
Roles []string `json:"roles"`
|
||||
Scope []string `json:"scope"`
|
||||
@@ -321,6 +333,7 @@ type UpdateEnvInput struct {
|
||||
SMTPPassword *string `json:"SMTP_PASSWORD"`
|
||||
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
|
||||
SenderEmail *string `json:"SENDER_EMAIL"`
|
||||
SenderName *string `json:"SENDER_NAME"`
|
||||
JwtType *string `json:"JWT_TYPE"`
|
||||
JwtSecret *string `json:"JWT_SECRET"`
|
||||
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
|
||||
@@ -465,6 +478,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"`
|
||||
|
@@ -75,6 +75,20 @@ type VerificationRequests {
|
||||
verification_requests: [VerificationRequest!]!
|
||||
}
|
||||
|
||||
type SMSVerificationRequests {
|
||||
id: ID!
|
||||
code: String!
|
||||
code_expires_at: Int64!
|
||||
phone_number: String!
|
||||
created_at: Int64!
|
||||
updated_at: Int64
|
||||
}
|
||||
|
||||
input VerifyMobileRequest {
|
||||
phone_number: String!
|
||||
code: String!
|
||||
}
|
||||
|
||||
type Error {
|
||||
message: String!
|
||||
reason: String!
|
||||
@@ -118,6 +132,7 @@ type Env {
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
SENDER_NAME: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
@@ -235,6 +250,7 @@ input UpdateEnvInput {
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
SENDER_NAME: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
@@ -535,7 +551,8 @@ input ResendOTPRequest {
|
||||
}
|
||||
|
||||
input GetUserRequest {
|
||||
id: String!
|
||||
id: String
|
||||
email: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -553,6 +570,7 @@ 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!
|
||||
|
@@ -81,6 +81,11 @@ 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)
|
||||
|
@@ -84,9 +84,9 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||
|
||||
if responseMode == "" {
|
||||
if val, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultAuthorizeResponseMode); err == nil {
|
||||
responseType = val
|
||||
responseMode = val
|
||||
} else {
|
||||
responseType = constants.ResponseModeQuery
|
||||
responseMode = constants.ResponseModeQuery
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -452,7 +452,7 @@ func processFacebookUserInfo(code string) (models.User, error) {
|
||||
userRawData := make(map[string]interface{})
|
||||
json.Unmarshal(body, &userRawData)
|
||||
|
||||
email := fmt.Sprintf("%v", userRawData["sub"])
|
||||
email := fmt.Sprintf("%v", userRawData["email"])
|
||||
|
||||
picObject := userRawData["picture"].(map[string]interface{})["data"]
|
||||
picDataObject := picObject.(map[string]interface{})
|
||||
|
@@ -24,21 +24,22 @@ import (
|
||||
// It verifies email based on JWT token in query string
|
||||
func VerifyEmailHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
|
||||
errorRes := gin.H{
|
||||
"error": "invalid_token",
|
||||
"error": "token is required",
|
||||
}
|
||||
tokenInQuery := c.Query("token")
|
||||
if tokenInQuery == "" {
|
||||
log.Debug("Token is empty")
|
||||
c.JSON(400, errorRes)
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery)
|
||||
if err != nil {
|
||||
log.Debug("Error getting verification request: ", err)
|
||||
errorRes["error_description"] = err.Error()
|
||||
c.JSON(400, errorRes)
|
||||
errorRes["error"] = err.Error()
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -47,23 +48,23 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
claim, err := token.ParseJWTToken(tokenInQuery)
|
||||
if err != nil {
|
||||
log.Debug("Error parsing token: ", err)
|
||||
errorRes["error_description"] = err.Error()
|
||||
c.JSON(400, errorRes)
|
||||
errorRes["error"] = err.Error()
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
|
||||
log.Debug("Error validating jwt claims: ", err)
|
||||
errorRes["error_description"] = err.Error()
|
||||
c.JSON(400, errorRes)
|
||||
errorRes["error"] = err.Error()
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email)
|
||||
if err != nil {
|
||||
log.Debug("Error getting user: ", err)
|
||||
errorRes["error_description"] = err.Error()
|
||||
c.JSON(400, errorRes)
|
||||
errorRes["error"] = err.Error()
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -79,7 +80,6 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
db.Provider.DeleteVerificationRequest(c, verificationRequest)
|
||||
|
||||
state := strings.TrimSpace(c.Query("state"))
|
||||
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
|
||||
rolesString := strings.TrimSpace(c.Query("roles"))
|
||||
var roles []string
|
||||
if rolesString == "" {
|
||||
@@ -125,8 +125,8 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code)
|
||||
if err != nil {
|
||||
log.Debug("Error creating auth token: ", err)
|
||||
errorRes["error_description"] = err.Error()
|
||||
c.JSON(500, errorRes)
|
||||
errorRes["error"] = err.Error()
|
||||
utils.HandleRedirectORJsonResponse(c, http.StatusInternalServerError, errorRes, generateRedirectURL(redirectURL, errorRes))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
// if code != "" {
|
||||
// if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
|
||||
// log.Debug("Error setting code state ", err)
|
||||
// errorRes["error_description"] = err.Error()
|
||||
// errorRes["error"] = err.Error()
|
||||
// c.JSON(500, errorRes)
|
||||
// return
|
||||
// }
|
||||
@@ -189,3 +189,21 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||
}
|
||||
}
|
||||
|
||||
func generateRedirectURL(url string, res map[string]interface{}) string {
|
||||
redirectURL := url
|
||||
if redirectURL == "" {
|
||||
return ""
|
||||
}
|
||||
var paramsArr []string
|
||||
for key, value := range res {
|
||||
paramsArr = append(paramsArr, key+"="+value.(string))
|
||||
}
|
||||
params := strings.Join(paramsArr, "&")
|
||||
if strings.Contains(redirectURL, "?") {
|
||||
redirectURL = redirectURL + "&" + params
|
||||
} else {
|
||||
redirectURL = redirectURL + "?" + strings.TrimPrefix(params, "&")
|
||||
}
|
||||
return redirectURL
|
||||
}
|
||||
|
@@ -89,6 +89,9 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||
if val, ok := store[constants.EnvKeySenderEmail]; ok {
|
||||
res.SenderEmail = refs.NewStringRef(val.(string))
|
||||
}
|
||||
if val, ok := store[constants.EnvKeySenderName]; ok {
|
||||
res.SenderName = refs.NewStringRef(val.(string))
|
||||
}
|
||||
if val, ok := store[constants.EnvKeySmtpLocalName]; ok {
|
||||
res.SMTPLocalName = refs.NewStringRef(val.(string))
|
||||
}
|
||||
|
@@ -224,7 +224,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||
go email.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/refs"
|
||||
"github.com/authorizerdev/authorizer/server/token"
|
||||
"github.com/authorizerdev/authorizer/server/utils"
|
||||
"github.com/authorizerdev/authorizer/server/smsproviders"
|
||||
"github.com/authorizerdev/authorizer/server/validators"
|
||||
)
|
||||
|
||||
@@ -131,11 +132,9 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
user := models.User{
|
||||
Email: emailInput,
|
||||
PhoneNumber: &mobile,
|
||||
PhoneNumberVerifiedAt: &now,
|
||||
}
|
||||
|
||||
user.Roles = strings.Join(inputRoles, ",")
|
||||
@@ -185,12 +184,44 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
|
||||
user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
|
||||
}
|
||||
|
||||
disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
|
||||
if disablePhoneVerification {
|
||||
now := time.Now().Unix()
|
||||
user.PhoneNumberVerifiedAt = &now
|
||||
}
|
||||
|
||||
user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth
|
||||
user, err = db.Provider.AddUser(ctx, user)
|
||||
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
go func() {
|
||||
db.Provider.UpsertSMSRequest(ctx, &models.SMSVerificationRequest{
|
||||
PhoneNumber: mobile,
|
||||
Code: smsCode,
|
||||
CodeExpiresAt: time.Now().Add(duration).Unix(),
|
||||
})
|
||||
smsproviders.SendSMS(mobile, smsBody.String())
|
||||
}()
|
||||
}
|
||||
|
||||
roles := strings.Split(user.Roles, ",")
|
||||
userToReturn := user.AsAPIUser()
|
||||
|
||||
|
@@ -83,7 +83,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
|
||||
go email.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI),
|
||||
})
|
||||
|
||||
res = &model.Response{
|
||||
|
@@ -227,7 +227,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||
email.SendEmail([]string{params.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
|
||||
})
|
||||
utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
|
||||
}()
|
||||
|
@@ -259,7 +259,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||
go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
|
||||
})
|
||||
|
||||
}
|
||||
|
@@ -164,7 +164,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||
go email.SendEmail([]string{user.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
|
||||
})
|
||||
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package resolvers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@@ -20,17 +21,28 @@ func UserResolver(ctx context.Context, params model.GetUserRequest) (*model.User
|
||||
log.Debug("Failed to get GinContext: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !token.IsSuperAdmin(gc) {
|
||||
log.Debug("Not logged in as super admin.")
|
||||
return nil, fmt.Errorf("unauthorized")
|
||||
}
|
||||
|
||||
res, err := db.Provider.GetUserByID(ctx, params.ID)
|
||||
if err != nil {
|
||||
log.Debug("Failed to get users: ", err)
|
||||
return nil, err
|
||||
// Try getting user by ID
|
||||
if params.ID != nil && strings.Trim(*params.ID, " ") != "" {
|
||||
res, err := db.Provider.GetUserByID(ctx, *params.ID)
|
||||
if err != nil {
|
||||
log.Debug("Failed to get users by ID: ", err)
|
||||
return nil, err
|
||||
}
|
||||
return res.AsAPIUser(), nil
|
||||
}
|
||||
|
||||
return res.AsAPIUser(), nil
|
||||
// Try getting user by email
|
||||
if params.Email != nil && strings.Trim(*params.Email, " ") != "" {
|
||||
res, err := db.Provider.GetUserByEmail(ctx, *params.Email)
|
||||
if err != nil {
|
||||
log.Debug("Failed to get users by email: ", err)
|
||||
return nil, err
|
||||
}
|
||||
return res.AsAPIUser(), nil
|
||||
}
|
||||
// Return error if no params are provided
|
||||
return nil, fmt.Errorf("invalid params, user id or email is required")
|
||||
}
|
||||
|
62
server/resolvers/verify_mobile.go
Normal file
62
server/resolvers/verify_mobile.go
Normal file
@@ -0,0 +1,62 @@
|
||||
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
|
||||
}
|
54
server/smsproviders/twilio.go
Normal file
54
server/smsproviders/twilio.go
Normal file
@@ -0,0 +1,54 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// 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)
|
||||
return err
|
||||
}
|
||||
|
||||
twilioAPIKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPIKey)
|
||||
if err != nil || twilioAPIKey == ""{
|
||||
log.Errorf("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)
|
||||
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)
|
||||
message.SetTo(sendTo)
|
||||
|
||||
_, err = client.Api.CreateMessage(message)
|
||||
|
||||
if err != nil {
|
||||
log.Debug("Failed to send sms: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"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"
|
||||
@@ -45,6 +46,25 @@ 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,
|
||||
Password: s.TestInfo.Password,
|
||||
})
|
||||
assert.NotNil(t, err, "should fail because phone is not verified")
|
||||
assert.Nil(t, res)
|
||||
|
||||
smsRequest, err := db.Provider.GetCodeByPhone(ctx, phoneNumber)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, smsRequest.Code)
|
||||
|
||||
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,
|
||||
|
@@ -135,6 +135,7 @@ func TestResolvers(t *testing.T) {
|
||||
validateJwtTokenTest(t, s)
|
||||
verifyOTPTest(t, s)
|
||||
resendOTPTest(t, s)
|
||||
verifyMobileTest(t, s)
|
||||
|
||||
updateAllUsersTest(t, s)
|
||||
webhookLogsTest(t, s) // get logs after above resolver tests are done
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/crypto"
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
@@ -26,7 +27,7 @@ func userTest(t *testing.T, s TestSetup) {
|
||||
assert.NotEmpty(t, res.User)
|
||||
|
||||
userRes, err := resolvers.UserResolver(ctx, model.GetUserRequest{
|
||||
ID: res.User.ID,
|
||||
ID: &res.User.ID,
|
||||
})
|
||||
assert.Nil(t, userRes)
|
||||
assert.NotNil(t, err, "unauthorized")
|
||||
@@ -36,14 +37,36 @@ func userTest(t *testing.T, s TestSetup) {
|
||||
h, err := crypto.EncryptPassword(adminSecret)
|
||||
assert.Nil(t, err)
|
||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||
|
||||
// Should throw error for invalid params
|
||||
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{})
|
||||
assert.Nil(t, userRes)
|
||||
assert.NotNil(t, err, "invalid params, user id or email is required")
|
||||
// Should throw error for invalid params with empty id
|
||||
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
|
||||
ID: res.User.ID,
|
||||
ID: refs.NewStringRef(" "),
|
||||
})
|
||||
assert.Nil(t, userRes)
|
||||
assert.NotNil(t, err, "invalid params, user id or email is required")
|
||||
// Should throw error for invalid params with empty email
|
||||
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
|
||||
Email: refs.NewStringRef(" "),
|
||||
})
|
||||
assert.Nil(t, userRes)
|
||||
assert.NotNil(t, err, "invalid params, user id or email is required")
|
||||
// Should get user by id
|
||||
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
|
||||
ID: &res.User.ID,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, res.User.ID, userRes.ID)
|
||||
assert.Equal(t, email, userRes.Email)
|
||||
// Should get user by email
|
||||
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
|
||||
Email: &email,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, res.User.ID, userRes.ID)
|
||||
assert.Equal(t, email, userRes.Email)
|
||||
|
||||
cleanData(email)
|
||||
})
|
||||
}
|
||||
|
79
server/test/verify_mobile_test.go
Normal file
79
server/test/verify_mobile_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
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)
|
||||
})
|
||||
}
|
@@ -92,6 +92,6 @@ func GetInviteVerificationURL(verificationURL, token, redirectURI string) string
|
||||
}
|
||||
|
||||
// GetEmailVerificationURL to get url for invite email verification
|
||||
func GetEmailVerificationURL(token, hostname string) string {
|
||||
return hostname + "/verify_email?token=" + token
|
||||
func GetEmailVerificationURL(token, hostname, redirectURI string) string {
|
||||
return hostname + "/verify_email?token=" + token + "&redirect_uri=" + redirectURI
|
||||
}
|
||||
|
17
server/utils/response.go
Normal file
17
server/utils/response.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// HandleRedirectORJsonResponse handles the response based on redirectURL
|
||||
func HandleRedirectORJsonResponse(c *gin.Context, httpResponse int, response map[string]interface{}, redirectURL string) {
|
||||
if strings.TrimSpace(redirectURL) == "" {
|
||||
c.JSON(httpResponse, response)
|
||||
} else {
|
||||
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user