begin doing opt verify

This commit is contained in:
linhdevtran99 committed 2024-01-16 17:14:47 +07:00
1 parent 193b955915
commit 0125a020a0
9 files changed
+162 -12

No files matched your search

+6 -2
View File
@@ -2,6 +2,7 @@ package rest_api
import (
"fmt"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"linhdevtran99/rest-api/rest-api/routes"
"linhdevtran99/rest-api/utils"
@@ -21,8 +22,10 @@ func NewAPIServer(listenAddr string) *APIServer {
func startMuxServer(s *APIServer, router *mux.Router) {
log.Println("Listening on", s.listenAddr)
if err := http.ListenAndServe(s.listenAddr, router); err != nil {
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
originsOk := handlers.AllowedOrigins([]string{"https://app.wliafdew.dev"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
if err := http.ListenAndServe(s.listenAddr, handlers.CORS(originsOk, headersOk, methodsOk)(router)); err != nil {
log.Fatal(err)
}
}
@@ -40,6 +43,7 @@ func (s *APIServer) Run() {
func (s *APIServer) TestRoute(w http.ResponseWriter, r *http.Request) error {
if r.Method == http.MethodGet {
//utils.VerifyOTP()
fmt.Println("hello")
}
+10 -5
View File
@@ -43,6 +43,7 @@ func RegisterNewAccount(w http.ResponseWriter, r *http.Request) error {
Email: registerInfo.Email,
PhoneNumber: registerInfo.PhoneNumber,
HashPassword: registerInfo.Password,
UUID: registerInfo.UUID,
CreatedDate: time.Now(),
UpdateDate: time.Now(),
VerifySentCount: 1,
@@ -60,12 +61,15 @@ func RegisterNewAccount(w http.ResponseWriter, r *http.Request) error {
return nil
}
func Linh(w http.ResponseWriter, r *http.Request) error {
if r.Method == http.MethodGet {
var registerInfo models.CreateUser
func VerifyWithOTP(w http.ResponseWriter, r *http.Request) error {
_ = json.NewDecoder(r.Body).Decode(&registerInfo)
fmt.Println(registerInfo)
if r.Method == http.MethodPost {
// declare variable
var otpInfo models.OTPVerify
//get data from body
_ = json.NewDecoder(r.Body).Decode(&otpInfo)
//check otp and create user
services.CheckOTPIsValid(&otpInfo, w)
}
return nil
@@ -74,4 +78,5 @@ func Linh(w http.ResponseWriter, r *http.Request) error {
func AuthRouterSetup(router *mux.Router) {
authRouter := router.PathPrefix("/account").Subrouter()
authRouter.Handle("/register", utils.MakeHTTPHandlerFn(RegisterNewAccount)).Methods("POST")
authRouter.Handle("/register/verifyAccountOTP", utils.MakeHTTPHandlerFn(VerifyWithOTP)).Methods("POST")
}
+101 -4
View File
@@ -8,6 +8,7 @@ import (
"fmt"
"github.com/go-mail/mail"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"golang.org/x/crypto/bcrypt"
"linhdevtran99/rest-api/models"
@@ -120,10 +121,10 @@ func CheckAccountValid(userName string, email string) (bool, *ResponseError) {
const (
otpDigits = 6
mailValidTime = time.Hour * 24
mailValidTime = time.Minute * 15
)
func GenerateVerifyAccount(registerInfo *models.PreusersMongo, w http.ResponseWriter) {
func GenerateVerifyAccount(registerInfo *models.PreusersMongo, w http.ResponseWriter) error {
var wg sync.WaitGroup
otpChannel := make(chan models.OtpGenerate, 1)
@@ -135,9 +136,11 @@ func GenerateVerifyAccount(registerInfo *models.PreusersMongo, w http.ResponseWr
wg.Add(1)
go utils.EncryptAESMailLink(registerInfo, w, mailChannel, &wg)
go createMailVerify(registerInfo, otpChannel, mailChannel, w)
go writeOTPInRedis(registerInfo, otpChannel, w)
go writeOTPInRedis(counter, registerInfo, otpChannel, w)
wg.Wait()
err := utils.WriteJSON(w, http.StatusOK, "Success register account please verify your account")
return err
}
@@ -223,7 +226,7 @@ func CheckAndWritePreuser(registerInfo *models.PreusersMongo, w http.ResponseWri
//write otp in redis for valid if otp expired
func writeOTPInRedis(registerInfo *models.PreusersMongo, otpChan chan models.OtpGenerate, w http.ResponseWriter) {
func writeOTPInRedis(counter uint64, registerInfo *models.PreusersMongo, otpChan chan models.OtpGenerate, w http.ResponseWriter) {
otp := <-otpChan
@@ -232,6 +235,7 @@ func writeOTPInRedis(registerInfo *models.PreusersMongo, otpChan chan models.Otp
User: registerInfo.Username,
CreatedDate: registerInfo.CreatedDate.Unix(),
HashOTP: otp.HashOTP,
Counter: counter,
}
jsonData, err := json.Marshal(dataRedis)
@@ -244,3 +248,96 @@ func writeOTPInRedis(registerInfo *models.PreusersMongo, otpChan chan models.Otp
fmt.Println(status.Err())
}
// ////////////////////////Create User Complete//////////////////////////
func CreateUserAfterVerify(otpInfo *models.OTPVerify, redis *models.RedisOTP, w http.ResponseWriter) bool {
isValid := true
var preUserData models.PreusersMongo
filter := bson.D{{"email", otpInfo.Email}}
err := utils.PreUserData.FindOne(context.Background(), filter).Decode(&preUserData)
if err != nil {
fmt.Println("Internal log: Can't get preuser data")
_ = utils.WriteJSONInternalError(w, "Please register again")
isValid = false
}
user := models.UsersMongo{
Username: preUserData.Username,
Email: preUserData.Email,
PhoneNumber: preUserData.PhoneNumber,
HashPassword: preUserData.HashPassword,
Active: true,
CreatedDate: time.Now(),
UpdateDate: time.Now(),
VerifySentCount: int(redis.Counter),
}
_, err = utils.User.InsertOne(context.Background(), user)
if err != nil {
fmt.Println("Internal log: Can't insert user data")
_ = utils.WriteJSONInternalError(w, "Can't insert user data")
isValid = false
}
if isValid == true {
fmt.Println("Internal log: Success verify account")
_ = utils.WriteJSON(w, http.StatusOK, "Success verify account")
}
return isValid
}
//////////////////////////Verify OTP//////////////////////////
func CheckUserVerify(otpInfo *models.OTPVerify, w http.ResponseWriter) bool {
isVerified := false
filter := bson.D{{"email", otpInfo.Email}}
var user models.UsersMongo
_ = utils.User.FindOne(context.Background(), filter).Decode(&user)
if user.Active == true {
fmt.Println("Internal log: Account already verify")
_ = utils.WriteJSON(w, http.StatusBadRequest, "Account already verify")
isVerified = true
}
return isVerified
}
func CheckOTPIsValid(otpInfo *models.OTPVerify, w http.ResponseWriter) bool {
var isValid bool
isValid = true
//get data from redis
var dataRedis models.RedisOTP
//verify uuid and email
value, err := utils.Redis.Get(context.Background(), "otp:"+otpInfo.Email).Result()
if err != nil {
fmt.Println("Internal log: Email not valid")
_ = utils.WriteJSON(w, http.StatusBadRequest, "Email is not valid")
isValid = false
return false
}
_ = json.Unmarshal([]byte(value), &dataRedis)
_, err = uuid.Parse(otpInfo.UUID)
if err != nil {
fmt.Println("Internal log: UUID not valid")
_ = utils.WriteJSON(w, http.StatusBadRequest, "UUID not valid")
isValid = false
}
if isVerified := CheckUserVerify(otpInfo, w); isVerified == true {
return false
}
isValid = utils.VerifyOTP(otpInfo, dataRedis, w)
if isValid == true {
CreateUserAfterVerify(otpInfo, &dataRedis, w)
}
return true
}