soft finishing register verify with otp, mail link and qr code
This commit is contained in:
parent
47816debd3
commit
89913a91ff
2
.env
2
.env
|
|
@ -1,5 +1,5 @@
|
||||||
MONGO_URI="mongodb://adminLinh:linhporo1@localhost:27017"
|
MONGO_URI="mongodb://adminLinh:linhporo1@localhost:27017"
|
||||||
API_TEST_PORT=":8080"
|
API_TEST_PORT=":8080"
|
||||||
REDIS_URI="redis://localhost:6379/0"
|
REDIS_URI="redis://localhost:6379/0"
|
||||||
STMP_PASS="btmp judz ebys pfxw"
|
SMTP_PASS="btmp judz ebys pfxw"
|
||||||
EMAIL_VERIFY_SECRET="WDc&4+&vYP(n'}?LHNE#5M?IE|g(c812"
|
EMAIL_VERIFY_SECRET="WDc&4+&vYP(n'}?LHNE#5M?IE|g(c812"
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,14 @@
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<img
|
||||||
|
src="{{ .QrCode }}"
|
||||||
|
height="200"
|
||||||
|
width="200"
|
||||||
|
alt="qrcode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package models
|
||||||
import (
|
import (
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"html/template"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
@ -81,12 +82,18 @@ func PasswordValidator(fl validator.FieldLevel) bool {
|
||||||
|
|
||||||
//Interal Type
|
//Interal Type
|
||||||
|
|
||||||
type EmailTemplate struct {
|
|
||||||
Otp string `json:"otp"`
|
|
||||||
AlternativeLink string `json:"alternativeLink"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OtpGenerate struct {
|
type OtpGenerate struct {
|
||||||
PureOTP string
|
PureOTP string
|
||||||
HashOTP string
|
HashOTP string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MailVefiry struct {
|
||||||
|
LinkMail string
|
||||||
|
ImageBase64 string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmailTemplate struct {
|
||||||
|
Otp string `json:"otp"`
|
||||||
|
AlternativeLink string `json:"alternativeLink"`
|
||||||
|
QrCode template.URL
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"linhdevtran99/rest-api/models"
|
"linhdevtran99/rest-api/models"
|
||||||
"linhdevtran99/rest-api/rest-api/routes"
|
"linhdevtran99/rest-api/rest-api/routes"
|
||||||
"linhdevtran99/rest-api/rest-api/services"
|
|
||||||
"linhdevtran99/rest-api/utils"
|
"linhdevtran99/rest-api/utils"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -45,22 +44,6 @@ func (s *APIServer) TestRoute(w http.ResponseWriter, r *http.Request) error {
|
||||||
if r.Method == http.MethodGet {
|
if r.Method == http.MethodGet {
|
||||||
fmt.Println("hit")
|
fmt.Println("hit")
|
||||||
|
|
||||||
//m := mail.NewMessage()
|
|
||||||
//
|
|
||||||
//emailBody := utils.BuildEmail()
|
|
||||||
//m.SetHeader("From", "kotomi.poro1@gmail.com")
|
|
||||||
//m.SetHeader("To", "nhocdl.poro1@gmail.com")
|
|
||||||
//m.SetHeader("Subject", "Hello!")
|
|
||||||
//m.SetBody("text/html", emailBody)
|
|
||||||
//
|
|
||||||
//d := mail.NewDialer("smtp.gmail.com", 587, "kotomi.poro1@gmail.com", "btmpjudzebyspfxw")
|
|
||||||
//d.StartTLSPolicy = mail.MandatoryStartTLS
|
|
||||||
//
|
|
||||||
//// Send the email to Bob, Cora and Dan.
|
|
||||||
//if err := d.DialAndSend(m); err != nil {
|
|
||||||
// panic(err)
|
|
||||||
//}
|
|
||||||
|
|
||||||
//serect := os.Getenv("EMAIL_VERIFY_SECRET")
|
//serect := os.Getenv("EMAIL_VERIFY_SECRET")
|
||||||
|
|
||||||
//_, otp := services.GeneratorOtp("hello", "nhocdl.poro1@gmail.com", 12, serect)
|
//_, otp := services.GeneratorOtp("hello", "nhocdl.poro1@gmail.com", 12, serect)
|
||||||
|
|
@ -68,23 +51,19 @@ func (s *APIServer) TestRoute(w http.ResponseWriter, r *http.Request) error {
|
||||||
//fmt.Println(otp.PureOTP)
|
//fmt.Println(otp.PureOTP)
|
||||||
|
|
||||||
//utils.EncryptAESMailLink("nhocdl.poro2@gmail.com", serect, w)
|
//utils.EncryptAESMailLink("nhocdl.poro2@gmail.com", serect, w)
|
||||||
|
preUserData := &models.PreusersMongo{
|
||||||
//jsonData, _ := json.Marshal(map[string]string{"email": "nhocdl.poro1@gmail.com", "user": "thewind121212"})
|
|
||||||
////
|
|
||||||
//utils.Redis.Set(context.Background(), "otp:nhocdl.poro1@gmail.com", string(jsonData), time.Minute)
|
|
||||||
//
|
|
||||||
//utils.CheckAndWriteRedis("nhocdl.poro1@gmail.com", "thewind121212", "lasdjflasdjlfj")
|
|
||||||
|
|
||||||
services.CheckAndWritePreuser(&models.PreusersMongo{
|
|
||||||
Username: "thewind121212",
|
Username: "thewind121212",
|
||||||
Email: "nhocdl.poro2@gmail.com",
|
Email: "nhocdl.poro1@gmail.com",
|
||||||
PhoneNumber: "0918327132",
|
PhoneNumber: "0918327132",
|
||||||
VerifySentCount: 0,
|
HashPassword: "it ok now ",
|
||||||
CreatedDate: time.Now(),
|
CreatedDate: time.Now(),
|
||||||
UpdateDate: time.Now(),
|
UpdateDate: time.Now(),
|
||||||
})
|
VerifySentCount: 1,
|
||||||
|
}
|
||||||
|
|
||||||
//
|
_ = preUserData
|
||||||
|
|
||||||
|
//services.WriteOTPInRedis(preUserData, "tranduy linh ", w)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ func RegisterNewAccount(w http.ResponseWriter, r *http.Request) error {
|
||||||
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
||||||
}
|
}
|
||||||
//call function check data user use in past or not
|
//call function check data user use in past or not
|
||||||
isValidData, responseAPI := services.CheckAccountExist(utils.MongoDB, registerInfo.Username, registerInfo.Email)
|
isValidData, responseAPI := services.CheckAccountExist(registerInfo.Username, registerInfo.Email)
|
||||||
if responseAPI != nil {
|
if responseAPI != nil {
|
||||||
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ func RegisterNewAccount(w http.ResponseWriter, r *http.Request) error {
|
||||||
VerifySentCount: 1,
|
VerifySentCount: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
services.CheckAndWritePreuser(preUserData)
|
services.GenerateVerifyAccount(preUserData, w)
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
if isValidData == true || validRegisterInfo == true {
|
if isValidData == true || validRegisterInfo == true {
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,20 @@ package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base32"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-mail/mail"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/pquerna/otp"
|
|
||||||
"github.com/pquerna/otp/hotp"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"linhdevtran99/rest-api/models"
|
"linhdevtran99/rest-api/models"
|
||||||
"linhdevtran99/rest-api/utils"
|
"linhdevtran99/rest-api/utils"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -68,7 +69,7 @@ func CheckAndValidRegisterFiled(registerData *models.CreateUser) (bool, *Respons
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckAccountExist Checking in db is user input same data in
|
// CheckAccountExist Checking in db is user input same data in
|
||||||
func CheckAccountExist(mongoClient *mongo.Client, userName string, email string) (bool, *ResponseError) {
|
func CheckAccountExist(userName string, email string) (bool, *ResponseError) {
|
||||||
//filter in mongodb
|
//filter in mongodb
|
||||||
var isValid bool
|
var isValid bool
|
||||||
var errAPI *ResponseError
|
var errAPI *ResponseError
|
||||||
|
|
@ -80,7 +81,7 @@ func CheckAccountExist(mongoClient *mongo.Client, userName string, email string)
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := utils.PreUserData.FindOne(context.TODO(), filter).Raw()
|
_, err := utils.User.FindOne(context.TODO(), filter).Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
isValid = true
|
isValid = true
|
||||||
errAPI = nil
|
errAPI = nil
|
||||||
|
|
@ -96,55 +97,89 @@ func CheckAccountExist(mongoClient *mongo.Client, userName string, email string)
|
||||||
return isValid, errAPI
|
return isValid, errAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneratorOtp Generate HOtp for confirm information
|
// GeneratorOtp Generate OTP Verify Link and Qr Link
|
||||||
|
|
||||||
func GeneratorOtp(userName string, email string, counter uint64, serect string) (bool, *models.OtpGenerate) {
|
const (
|
||||||
|
otpDigits = 6
|
||||||
|
mailValidTime = time.Hour * 24
|
||||||
|
)
|
||||||
|
|
||||||
serectBase32 := base32.StdEncoding.EncodeToString([]byte(serect + userName + email))
|
func GenerateVerifyAccount(registerInfo *models.PreusersMongo, w http.ResponseWriter) {
|
||||||
passCode, err := hotp.GenerateCodeCustom(serectBase32, counter, hotp.ValidateOpts{
|
var wg sync.WaitGroup
|
||||||
Digits: 6,
|
|
||||||
Algorithm: otp.AlgorithmSHA256,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
otpChannel := make(chan models.OtpGenerate, 1)
|
||||||
fmt.Println("Fail to create OTP")
|
mailChannel := make(chan models.MailVefiry, 1)
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
hashed, err := bcrypt.GenerateFromPassword([]byte(passCode), 5)
|
counter := CheckAndWritePreuser(registerInfo, w)
|
||||||
if err != nil {
|
wg.Add(1)
|
||||||
fmt.Println("Fail to create OTP")
|
go utils.GenOTP(registerInfo, counter, otpDigits, w, otpChannel, &wg)
|
||||||
return false, nil
|
wg.Add(1)
|
||||||
}
|
go utils.EncryptAESMailLink(registerInfo, w, mailChannel, &wg)
|
||||||
|
go createMailVerify(registerInfo, otpChannel, mailChannel, w)
|
||||||
|
go writeOTPInRedis(registerInfo, otpChannel, w)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
return true, &models.OtpGenerate{
|
|
||||||
PureOTP: passCode,
|
|
||||||
HashOTP: string(hashed),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateLinkVerify Create a alternative verify link
|
// CreateLinkVerify Create a alternative verify link
|
||||||
func CreateLinkVerify(registerInfo string, secrect string) string {
|
func createMailVerify(registerInfo *models.PreusersMongo, otpChan chan models.OtpGenerate, mailChan chan models.MailVefiry, w http.ResponseWriter) {
|
||||||
return "linh"
|
smtpPass := os.Getenv("SMTP_PASS")
|
||||||
|
m := mail.NewMessage()
|
||||||
|
|
||||||
|
opt := <-otpChan
|
||||||
|
mailVerify := <-mailChan
|
||||||
|
|
||||||
|
decodedImage, err := base64.StdEncoding.DecodeString(mailVerify.ImageBase64)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error decoding base64 image:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
qrFileName := registerInfo.Email + registerInfo.Username + ".png"
|
||||||
|
os.WriteFile("./temp/"+qrFileName, decodedImage, 0666)
|
||||||
|
emailBody := utils.BuildEmail(opt.PureOTP, mailVerify.LinkMail, qrFileName)
|
||||||
|
|
||||||
|
m.SetHeader("From", "kotomi.poro1@gmail.com")
|
||||||
|
m.SetHeader("To", registerInfo.Email)
|
||||||
|
m.SetHeader("Subject", "Thanks For Join My Business")
|
||||||
|
m.SetBody("text/html", emailBody)
|
||||||
|
m.Embed("./temp/" + qrFileName)
|
||||||
|
|
||||||
|
d := mail.NewDialer("smtp.gmail.com", 587, "kotomi.poro1@gmail.com", smtpPass)
|
||||||
|
d.StartTLSPolicy = mail.MandatoryStartTLS
|
||||||
|
|
||||||
|
// Send the email to Bob, Cora and Dan.
|
||||||
|
if err := d.DialAndSend(m); err != nil {
|
||||||
|
fmt.Println("Internal Log: Fail to send email check smtp")
|
||||||
|
_ = utils.WriteJSONInternalError(w, "Fail to send email check smtp")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
os.Remove("./temp/" + qrFileName)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// check and write pre use into mongo db
|
// check and write pre use into mongo db
|
||||||
func CheckAndWritePreuser(registerInfo *models.PreusersMongo) {
|
func CheckAndWritePreuser(registerInfo *models.PreusersMongo, w http.ResponseWriter) uint64 {
|
||||||
//checking
|
//checking
|
||||||
email := registerInfo.Email
|
email := registerInfo.Email
|
||||||
|
count := 1
|
||||||
filter := bson.D{{"email", email}}
|
filter := bson.D{{"email", email}}
|
||||||
_, err := utils.PreUserData.FindOne(context.Background(), filter).Raw()
|
raw, err := utils.PreUserData.FindOne(context.Background(), filter).Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hashed, err := bcrypt.GenerateFromPassword([]byte(registerInfo.HashPassword), 10)
|
hashed, err := bcrypt.GenerateFromPassword([]byte(registerInfo.HashPassword), 10)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Fail to create OTP")
|
fmt.Println("Internal Log :Fail to create OTP")
|
||||||
|
_ = utils.WriteJSONInternalError(w, "Fail to create OTP")
|
||||||
}
|
}
|
||||||
registerInfo.HashPassword = string(hashed)
|
registerInfo.HashPassword = string(hashed)
|
||||||
_, err = utils.PreUserData.InsertOne(context.Background(), registerInfo)
|
_, err = utils.PreUserData.InsertOne(context.Background(), registerInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Something Went Wrong")
|
fmt.Println("Internal Log: Can't Insert Data To PreUser")
|
||||||
|
_ = utils.WriteJSONInternalError(w, "Can't Insert Data To PreUser")
|
||||||
}
|
}
|
||||||
|
return uint64(count)
|
||||||
} else {
|
} else {
|
||||||
update := bson.D{
|
update := bson.D{
|
||||||
{"$inc", bson.D{
|
{"$inc", bson.D{
|
||||||
|
|
@ -157,9 +192,36 @@ func CheckAndWritePreuser(registerInfo *models.PreusersMongo) {
|
||||||
|
|
||||||
_, err := utils.PreUserData.UpdateOne(context.Background(), filter, update)
|
_, err := utils.PreUserData.UpdateOne(context.Background(), filter, update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Internal log: update document fail")
|
fmt.Println("Internal log: Update document fail")
|
||||||
|
_ = utils.WriteJSONInternalError(w, "Update document fail")
|
||||||
}
|
}
|
||||||
|
fmt.Println()
|
||||||
|
count = int(raw.Lookup("verify_sent_count").Int32() + 1)
|
||||||
|
return uint64(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//write otp in redis for valid if otp expired
|
||||||
|
|
||||||
|
func writeOTPInRedis(registerInfo *models.PreusersMongo, otpChan chan models.OtpGenerate, w http.ResponseWriter) {
|
||||||
|
|
||||||
|
otp := <-otpChan
|
||||||
|
|
||||||
|
data := map[string]string{
|
||||||
|
"email": registerInfo.Email,
|
||||||
|
"user": registerInfo.Username,
|
||||||
|
"create_date": registerInfo.CreatedDate.String(),
|
||||||
|
"hashOTP": otp.HashOTP,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Internal log: Can't stringfy json data")
|
||||||
|
_ = utils.WriteJSONInternalError(w, "Can't stringfy json data")
|
||||||
|
}
|
||||||
|
status := utils.Redis.Set(context.Background(), "otp:nhocdl.poro1@gmail.com", string(jsonData), time.Minute*2)
|
||||||
|
|
||||||
|
fmt.Println(status.Err())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,26 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base32"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/pquerna/otp"
|
||||||
|
"github.com/pquerna/otp/hotp"
|
||||||
"github.com/skip2/go-qrcode"
|
"github.com/skip2/go-qrcode"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"linhdevtran99/rest-api/models"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//const
|
||||||
|
|
||||||
|
var serect = os.Getenv("EMAIL_VERIFY_SECRET")
|
||||||
|
|
||||||
//Mail
|
//Mail
|
||||||
|
|
||||||
type MyCustomClaims struct {
|
type MyCustomClaims struct {
|
||||||
|
|
@ -20,21 +31,19 @@ type MyCustomClaims struct {
|
||||||
func buildTokenLink(token string, w http.ResponseWriter) (string, string) {
|
func buildTokenLink(token string, w http.ResponseWriter) (string, string) {
|
||||||
tokenCustomTrim := strings.ReplaceAll(token, ".", "&")
|
tokenCustomTrim := strings.ReplaceAll(token, ".", "&")
|
||||||
emailVerifyLink := "http://www.totoday.com/?p=" + tokenCustomTrim
|
emailVerifyLink := "http://www.totoday.com/?p=" + tokenCustomTrim
|
||||||
fmt.Println(emailVerifyLink)
|
|
||||||
png, err := qrcode.Encode(emailVerifyLink, qrcode.Low, 200)
|
png, err := qrcode.Encode(emailVerifyLink, qrcode.Low, 200)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Internal log: error create qr ")
|
fmt.Println("Internal log: error create qr ")
|
||||||
_ = WriteJSONInternalError(w, "error create QR code")
|
_ = WriteJSONInternalError(w, "error create QR code")
|
||||||
}
|
}
|
||||||
base64Image := base64.StdEncoding.EncodeToString(png)
|
base64Image := base64.StdEncoding.EncodeToString(png)
|
||||||
dataURL := "data:image/png;base64," + base64Image
|
|
||||||
|
|
||||||
return emailVerifyLink, dataURL
|
return emailVerifyLink, base64Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncryptAESMailLink(data string, key string, w http.ResponseWriter) (string, string) {
|
func EncryptAESMailLink(registerInfo *models.PreusersMongo, w http.ResponseWriter, mailChan chan models.MailVefiry, wg *sync.WaitGroup) chan models.MailVefiry {
|
||||||
claims := MyCustomClaims{
|
claims := MyCustomClaims{
|
||||||
data,
|
registerInfo.Email,
|
||||||
jwt.RegisteredClaims{
|
jwt.RegisteredClaims{
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
|
@ -46,13 +55,24 @@ func EncryptAESMailLink(data string, key string, w http.ResponseWriter) (string,
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
token.Header["purpose"] = "Email_Verify"
|
token.Header["purpose"] = "Email_Verify"
|
||||||
|
|
||||||
tokenString, err := token.SignedString([]byte(key))
|
tokenString, err := token.SignedString([]byte(serect))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Internal Log: Error signed token fail", err.Error())
|
fmt.Println("Internal Log: Error signed token fail", err.Error())
|
||||||
_ = WriteJSONInternalError(w, "Error signing token fail")
|
_ = WriteJSONInternalError(w, "Error signing token fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildTokenLink(tokenString, w)
|
linkMail, imageB64 := buildTokenLink(tokenString, w)
|
||||||
|
|
||||||
|
data := models.MailVefiry{
|
||||||
|
LinkMail: linkMail,
|
||||||
|
ImageBase64: imageB64,
|
||||||
|
}
|
||||||
|
|
||||||
|
mailChan <- data
|
||||||
|
|
||||||
|
wg.Done()
|
||||||
|
return mailChan
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -60,24 +80,34 @@ func EncryptAESMailLink(data string, key string, w http.ResponseWriter) (string,
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//OTP
|
//OTP
|
||||||
//Write preuser to mongo db
|
|
||||||
|
|
||||||
//func WriteToMongo(registerInfo *models.PreusersMongo) {
|
func GenOTP(registerInfo *models.PreusersMongo, counter uint64, otpDigits int, w http.ResponseWriter, otpChan chan models.OtpGenerate, wg *sync.WaitGroup) chan models.OtpGenerate {
|
||||||
//
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
//Write otp to redis
|
serectBase32 := base32.StdEncoding.EncodeToString([]byte(serect + registerInfo.Username + registerInfo.Email))
|
||||||
|
passCode, err := hotp.GenerateCodeCustom(serectBase32, counter, hotp.ValidateOpts{
|
||||||
|
Digits: otp.Digits(otpDigits),
|
||||||
|
Algorithm: otp.AlgorithmSHA256,
|
||||||
|
})
|
||||||
|
|
||||||
//func CheckAndWriteRedis(email string, username string, hashOTP string) {
|
if err != nil {
|
||||||
// //checking does it valid or have in redis or not
|
fmt.Println("Internal log: Fail to create OTP")
|
||||||
// //var count int
|
_ = WriteJSONInternalError(w, "Fail to create OTP")
|
||||||
// exists, err := Redis.Exists(context.Background(), "otp:nhocdl.poro1@gmail.com").Result()
|
}
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("something went wrong")
|
hashed, err := bcrypt.GenerateFromPassword([]byte(passCode), 5)
|
||||||
// }
|
if err != nil {
|
||||||
// if exists == 0 {
|
fmt.Println("Internal log: Fail to encrypt OTP")
|
||||||
// //count = 0
|
_ = WriteJSONInternalError(w, "Fail to encrypt OTP")
|
||||||
//
|
}
|
||||||
// }
|
|
||||||
//}
|
data := models.OtpGenerate{
|
||||||
|
PureOTP: passCode,
|
||||||
|
HashOTP: string(hashed),
|
||||||
|
}
|
||||||
|
|
||||||
|
otpChan <- data
|
||||||
|
otpChan <- data
|
||||||
|
wg.Done()
|
||||||
|
return otpChan
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,17 @@ import (
|
||||||
"linhdevtran99/rest-api/models"
|
"linhdevtran99/rest-api/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildEmail() string {
|
func BuildEmail(otp string, mailLink string, fileName string) string {
|
||||||
|
|
||||||
|
qrcodeURL := template.URL("cid:" + fileName)
|
||||||
|
|
||||||
data := models.EmailTemplate{
|
data := models.EmailTemplate{
|
||||||
Otp: "11017",
|
Otp: otp,
|
||||||
AlternativeLink: "https://www.google.com.vn",
|
AlternativeLink: mailLink,
|
||||||
|
QrCode: qrcodeURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//tmpl, err := template.ParseFiles("./Template/email.html")
|
||||||
tmpl, err := template.ParseFiles("./Template/email.html")
|
tmpl, err := template.ParseFiles("./Template/email.html")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
var MongoDB *mongo.Client
|
var MongoDB *mongo.Client
|
||||||
var PreUserData *mongo.Collection
|
var PreUserData *mongo.Collection
|
||||||
|
var User *mongo.Collection
|
||||||
|
|
||||||
func InitMongoDriver(mongoUri string) *mongo.Client {
|
func InitMongoDriver(mongoUri string) *mongo.Client {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
|
@ -32,6 +33,7 @@ func InitMongoDriver(mongoUri string) *mongo.Client {
|
||||||
|
|
||||||
MongoDB = client
|
MongoDB = client
|
||||||
PreUserData = MongoDB.Database("Totoday-shop").Collection("preusers")
|
PreUserData = MongoDB.Database("Totoday-shop").Collection("preusers")
|
||||||
|
User = MongoDB.Database("Totoday-shop").Collection("users")
|
||||||
|
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue