Add query for verification requests

Resolves #28
This commit is contained in:
Lakhan Samani 2021-07-18 09:52:54 +05:30
parent c6cbcd2e66
commit e2fc610762
14 changed files with 187 additions and 18 deletions

View File

@ -18,9 +18,10 @@ type Manager interface {
GetUsers() ([]User, error)
GetUserByEmail(email string) (User, error)
UpdateVerificationTime(verifiedAt int64, id uint) error
AddVerification(verification Verification) (Verification, error)
GetVerificationByToken(token string) (Verification, error)
AddVerification(verification VerificationRequest) (VerificationRequest, error)
GetVerificationByToken(token string) (VerificationRequest, error)
DeleteToken(email string) error
GetVerificationRequests() ([]VerificationRequest, error)
}
type manager struct {
@ -50,7 +51,7 @@ func init() {
if err != nil {
log.Fatal("Failed to init db:", err)
} else {
db.AutoMigrate(&User{}, &Verification{})
db.AutoMigrate(&User{}, &VerificationRequest{})
}
Mgr = &manager{db: db}

View File

@ -6,7 +6,7 @@ import (
"gorm.io/gorm/clause"
)
type Verification struct {
type VerificationRequest struct {
ID uint `gorm:"primaryKey"`
Token string `gorm:"index"`
Identifier string
@ -17,7 +17,7 @@ type Verification struct {
}
// AddVerification function to add verification record
func (mgr *manager) AddVerification(verification Verification) (Verification, error) {
func (mgr *manager) AddVerification(verification VerificationRequest) (VerificationRequest, error) {
result := mgr.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "email"}},
DoUpdates: clause.AssignmentColumns([]string{"token", "identifier", "expires_at"}),
@ -29,8 +29,8 @@ func (mgr *manager) AddVerification(verification Verification) (Verification, er
return verification, nil
}
func (mgr *manager) GetVerificationByToken(token string) (Verification, error) {
var verification Verification
func (mgr *manager) GetVerificationByToken(token string) (VerificationRequest, error) {
var verification VerificationRequest
result := mgr.db.Where("token = ?", token).First(&verification)
if result.Error != nil {
@ -42,7 +42,7 @@ func (mgr *manager) GetVerificationByToken(token string) (Verification, error) {
}
func (mgr *manager) DeleteToken(email string) error {
var verification Verification
var verification VerificationRequest
result := mgr.db.Where("email = ?", email).Delete(&verification)
if result.Error != nil {
@ -52,3 +52,14 @@ func (mgr *manager) DeleteToken(email string) error {
return nil
}
// GetUsers function to get all users
func (mgr *manager) GetVerificationRequests() ([]VerificationRequest, error) {
var verificationRequests []VerificationRequest
result := mgr.db.Find(&verificationRequests)
if result.Error != nil {
log.Println(result.Error)
return verificationRequests, result.Error
}
return verificationRequests, nil
}

View File

@ -67,6 +67,7 @@ type ComplexityRoot struct {
Profile func(childComplexity int) int
Token func(childComplexity int) int
Users func(childComplexity int) int
VerificationRequests func(childComplexity int) int
}
Response struct {
@ -108,6 +109,7 @@ type QueryResolver interface {
Users(ctx context.Context) ([]*model.User, error)
Token(ctx context.Context) (*model.LoginResponse, error)
Profile(ctx context.Context) (*model.User, error)
VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error)
}
type executableSchema struct {
@ -243,6 +245,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Query.Users(childComplexity), true
case "Query.verificationRequests":
if e.complexity.Query.VerificationRequests == nil {
break
}
return e.complexity.Query.VerificationRequests(childComplexity), true
case "Response.message":
if e.complexity.Response.Message == nil {
break
@ -517,6 +526,7 @@ type Query {
users: [User!]!
token: LoginResponse
profile: User!
verificationRequests: [VerificationRequest!]!
}
`, BuiltIn: false},
}
@ -1145,6 +1155,41 @@ func (ec *executionContext) _Query_profile(ctx context.Context, field graphql.Co
return ec.marshalNUser2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_verificationRequests(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().VerificationRequests(rctx)
})
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.VerificationRequest)
fc.Result = res
return ec.marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -3248,6 +3293,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
}
return res
})
case "verificationRequests":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_verificationRequests(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "__type":
out.Values[i] = ec._Query___type(ctx, field)
case "__schema":
@ -3764,6 +3823,53 @@ func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋse
return ec._User(ctx, sel, v)
}
func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.VerificationRequest) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
if !isLen1 {
wg.Add(len(v))
}
for i := range v {
i := i
fc := &graphql.FieldContext{
Index: &i,
Result: &v[i],
}
ctx := graphql.WithFieldContext(ctx, fc)
f := func(i int) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = nil
}
}()
if !isLen1 {
defer wg.Done()
}
ret[i] = ec.marshalNVerificationRequest2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerificationRequest(ctx, sel, v[i])
}
if isLen1 {
f(i)
} else {
go f(i)
}
}
wg.Wait()
return ret
}
func (ec *executionContext) marshalNVerificationRequest2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerificationRequest(ctx context.Context, sel ast.SelectionSet, v *model.VerificationRequest) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
return ec._VerificationRequest(ctx, sel, v)
}
func (ec *executionContext) unmarshalNVerifyEmailInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerifyEmailInput(ctx context.Context, v interface{}) (model.VerifyEmailInput, error) {
res, err := ec.unmarshalInputVerifyEmailInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)

View File

@ -82,4 +82,5 @@ type Query {
users: [User!]!
token: LoginResponse
profile: User!
verificationRequests: [VerificationRequest!]!
}

View File

@ -43,6 +43,10 @@ func (r *queryResolver) Profile(ctx context.Context) (*model.User, error) {
return resolvers.Profile(ctx)
}
func (r *queryResolver) VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error) {
return resolvers.VerificationRequests(ctx)
}
// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }

View File

@ -34,9 +34,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse,
if user.EmailVerifiedAt <= 0 {
return res, fmt.Errorf(`email not verified`)
}
// match password
cost, err := bcrypt.Cost([]byte(user.Password))
log.Println(cost, err)
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(params.Password))
if err != nil {
@ -68,6 +66,8 @@ func Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse,
LastName: &user.LastName,
SignupMethod: user.SignupMethod,
EmailVerifiedAt: &user.EmailVerifiedAt,
CreatedAt: &user.CreatedAt,
UpdatedAt: &user.UpdatedAt,
},
}

View File

@ -48,6 +48,8 @@ func Profile(ctx context.Context) (*model.User, error) {
LastName: &user.LastName,
SignupMethod: user.SignupMethod,
EmailVerifiedAt: &user.EmailVerifiedAt,
CreatedAt: &user.CreatedAt,
UpdatedAt: &user.UpdatedAt,
}
return res, nil

View File

@ -62,7 +62,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.Response, err
if err != nil {
log.Println(`Error generating token`, err)
}
db.Mgr.AddVerification(db.Verification{
db.Mgr.AddVerification(db.VerificationRequest{
Token: token,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),

View File

@ -58,6 +58,8 @@ func Token(ctx context.Context) (*model.LoginResponse, error) {
Image: &user.Image,
FirstName: &user.FirstName,
LastName: &user.LastName,
CreatedAt: &user.CreatedAt,
UpdatedAt: &user.UpdatedAt,
},
}
return res, nil

View File

@ -109,7 +109,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
if err != nil {
log.Println(`Error generating token`, err)
}
db.Mgr.AddVerification(db.Verification{
db.Mgr.AddVerification(db.VerificationRequest{
Token: token,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),

View File

@ -34,6 +34,8 @@ func Users(ctx context.Context) ([]*model.User, error) {
LastName: &user.LastName,
Password: &user.Password,
EmailVerifiedAt: &user.EmailVerifiedAt,
CreatedAt: &user.CreatedAt,
UpdatedAt: &user.UpdatedAt,
})
}

View File

@ -0,0 +1,40 @@
package resolvers
import (
"context"
"fmt"
"github.com/yauthdev/yauth/server/db"
"github.com/yauthdev/yauth/server/graph/model"
"github.com/yauthdev/yauth/server/utils"
)
func VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error) {
gc, err := utils.GinContextFromContext(ctx)
var res []*model.VerificationRequest
if err != nil {
return res, err
}
if !utils.IsSuperAdmin(gc) {
return res, fmt.Errorf("unauthorized")
}
verificationRequests, err := db.Mgr.GetVerificationRequests()
if err != nil {
return res, err
}
for _, verificationRequest := range verificationRequests {
res = append(res, &model.VerificationRequest{
ID: fmt.Sprintf("%d", verificationRequest.ID),
Email: &verificationRequest.Email,
Token: &verificationRequest.Token,
Expires: &verificationRequest.ExpiresAt,
CreatedAt: &verificationRequest.CreatedAt,
UpdatedAt: &verificationRequest.UpdatedAt,
})
}
return res, nil
}

View File

@ -65,6 +65,8 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Log
LastName: &user.LastName,
SignupMethod: user.SignupMethod,
EmailVerifiedAt: &user.EmailVerifiedAt,
CreatedAt: &user.CreatedAt,
UpdatedAt: &user.UpdatedAt,
},
}

View File

@ -2,7 +2,6 @@ package main
import (
"context"
"log"
"github.com/gin-gonic/gin"
"github.com/yauthdev/yauth/server/enum"
@ -27,7 +26,6 @@ func main() {
r.GET("/login/google", handlers.HandleOAuthLogin(enum.GoogleProvider))
r.GET("/callback/google", handlers.HandleOAuthCallback(enum.GoogleProvider))
}
log.Println(oauth.OAuthProvider.GithubConfig)
if oauth.OAuthProvider.GithubConfig != nil {
r.GET("/login/github", handlers.HandleOAuthLogin(enum.GithubProvider))
r.GET("/callback/github", handlers.HandleOAuthCallback(enum.GithubProvider))