add signup resolver

This commit is contained in:
Lakhan Samani
2021-07-12 23:52:16 +05:30
parent 54bb923e9a
commit 04a522c947
19 changed files with 2828 additions and 311 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,19 +2,69 @@
package model
type NewTodo struct {
Text string `json:"text"`
UserID string `json:"userId"`
type Response interface {
IsResponse()
}
type Todo struct {
ID string `json:"id"`
Text string `json:"text"`
Done bool `json:"done"`
User *User `json:"user"`
type BasicAuthLoginInput struct {
Email string `json:"email"`
Password string `json:"password"`
}
type BasicAuthLoginResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Errors []*Error `json:"errors"`
StatusCode int `json:"statusCode"`
RefreshToken *string `json:"refreshToken"`
User *User `json:"user"`
}
func (BasicAuthLoginResponse) IsResponse() {}
type BasicAuthSignupInput struct {
FirstName *string `json:"firstName"`
LastName *string `json:"lastName"`
Email string `json:"email"`
Password string `json:"password"`
CofirmPassword string `json:"cofirmPassword"`
Image *string `json:"image"`
}
type BasicAuthSignupResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Errors []*Error `json:"errors"`
StatusCode int `json:"statusCode"`
User *User `json:"user"`
}
func (BasicAuthSignupResponse) IsResponse() {}
type Error struct {
Message string `json:"message"`
Reason string `json:"reason"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
ID string `json:"id"`
Email string `json:"email"`
SignUpMethod string `json:"SignUpMethod"`
FirstName *string `json:"firstName"`
LastName *string `json:"lastName"`
EmailVerifiedAt *int64 `json:"emailVerifiedAt"`
Password *string `json:"password"`
Image *string `json:"image"`
CreatedAt *int64 `json:"createdAt"`
UpdatedAt *int64 `json:"updatedAt"`
}
type VerificationRequest struct {
ID string `json:"id"`
Identifier *string `json:"identifier"`
Token *string `json:"token"`
Email *string `json:"email"`
Expires *int64 `json:"expires"`
CreatedAt *int64 `json:"createdAt"`
UpdatedAt *int64 `json:"updatedAt"`
}

View File

@@ -1,28 +1,79 @@
# GraphQL schema example
#
# https://gqlgen.com/getting-started/
type Todo {
id: ID!
text: String!
done: Boolean!
user: User!
}
scalar Int64
type User {
id: ID!
name: String!
email: String!
SignUpMethod: String!
firstName: String
lastName: String
emailVerifiedAt: Int64
password: String
image: String
createdAt: Int64
updatedAt: Int64
}
type VerificationRequest {
id: ID!
identifier: String
token: String
email: String
expires: Int64
createdAt: Int64
updatedAt: Int64
}
type Error {
message: String!
reason: String!
}
interface Response {
success: Boolean!
message: String!
errors: [Error!]
statusCode: Int!
}
type BasicAuthLoginResponse implements Response {
success: Boolean!
message: String!
errors: [Error!]
statusCode: Int!
refreshToken: String
user: User
}
type BasicAuthSignupResponse implements Response {
success: Boolean!
message: String!
errors: [Error!]
statusCode: Int!
user: User
}
type Query {
todos: [Todo!]!
users: [User!]!
}
input NewTodo {
text: String!
userId: String!
input BasicAuthSignupInput {
firstName: String
lastName: String
email: String!
password: String!
cofirmPassword: String!
image: String
}
input BasicAuthLoginInput {
email: String!
password: String!
}
type Mutation {
createTodo(input: NewTodo!): Todo!
}
basicAuthSignUp(params: BasicAuthSignupInput!): BasicAuthSignupResponse!
basicAuthLogin(params: BasicAuthLoginInput!): BasicAuthLoginResponse!
}

View File

@@ -6,17 +6,132 @@ package graph
import (
"context"
"fmt"
"log"
"strings"
"time"
"github.com/yauthdev/yauth/server/db"
"github.com/yauthdev/yauth/server/graph/generated"
"github.com/yauthdev/yauth/server/graph/model"
"github.com/yauthdev/yauth/server/utils"
)
func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) {
func (r *mutationResolver) BasicAuthSignUp(ctx context.Context, params model.BasicAuthSignupInput) (*model.BasicAuthSignupResponse, error) {
var res *model.BasicAuthSignupResponse
if params.CofirmPassword != params.Password {
res = &model.BasicAuthSignupResponse{
Success: false,
Message: `Passowrd and Confirm Password does not match`,
StatusCode: 400,
Errors: []*model.Error{&model.Error{
Message: `Passowrd and Confirm Password does not match`,
Reason: `password and confirm_password fields should match`,
}},
}
}
params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) {
res = &model.BasicAuthSignupResponse{
Success: false,
Message: `Invalid email address`,
StatusCode: 400,
Errors: []*model.Error{&model.Error{
Message: `Invalid email address`,
Reason: `invalid email address`,
}},
}
}
// find user with email
existingUser, err := db.Mgr.GetUserByEmail(params.Email)
if err != nil {
log.Println("User with email " + params.Email + " not found")
}
if existingUser.EmailVerifiedAt > 0 {
// email is verified
res = &model.BasicAuthSignupResponse{
Success: false,
Message: `You have already signed up. Please login`,
StatusCode: 400,
Errors: []*model.Error{&model.Error{
Message: `Already signed up`,
Reason: `already signed up`,
}},
}
} else {
user := db.User{
Email: params.Email,
Password: params.Password,
}
if params.FirstName != nil {
user.FirstName = *params.FirstName
}
if params.LastName != nil {
user.LastName = *params.LastName
}
_, err = db.Mgr.AddUser(user)
if err != nil {
return res, err
}
// insert verification request
verificationType := "BASIC_AUTH_SIGNUP"
token, err := utils.CreateVerificationToken(params.Email, verificationType)
if err != nil {
log.Println(`Error generating token`, err)
}
db.Mgr.AddVerification(db.Verification{
Token: token,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
Email: params.Email,
})
// exec it as go routin so that we can reduce the api latency
go func() {
utils.SendVerificationMail(params.Email, token)
}()
res = &model.BasicAuthSignupResponse{
Success: true,
Message: `Verification email sent successfully. Please check your inbox`,
StatusCode: 200,
}
}
return res, nil
}
func (r *mutationResolver) BasicAuthLogin(ctx context.Context, params model.BasicAuthLoginInput) (*model.BasicAuthLoginResponse, error) {
panic(fmt.Errorf("not implemented"))
}
func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) {
panic(fmt.Errorf("not implemented"))
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
var res []*model.User
users, err := db.Mgr.GetUsers()
if err != nil {
return res, err
}
for _, user := range users {
res = append(res, &model.User{
ID: fmt.Sprintf("%d", user.ID),
Email: user.Email,
SignUpMethod: user.SignupMethod,
FirstName: &user.FirstName,
LastName: &user.LastName,
Password: &user.Password,
EmailVerifiedAt: &user.EmailVerifiedAt,
})
}
return res, nil
}
// Mutation returns generated.MutationResolver implementation.
@@ -25,5 +140,7 @@ func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResol
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type (
mutationResolver struct{ *Resolver }
queryResolver struct{ *Resolver }
)