prepair to using go concurrent
This commit is contained in:
parent
ce0508294c
commit
47816debd3
2
.env
2
.env
|
|
@ -1,5 +1,5 @@
|
|||
MONGO_URI="mongodb://adminLinh:linhporo1@localhost:27017"
|
||||
API_TEST_PORT=":8080"
|
||||
REDIS_URI="redis://localhost:6479/0"
|
||||
REDIS_URI="redis://localhost:6379/0"
|
||||
STMP_PASS="btmp judz ebys pfxw"
|
||||
EMAIL_VERIFY_SECRET="WDc&4+&vYP(n'}?LHNE#5M?IE|g(c812"
|
||||
3
go.mod
3
go.mod
|
|
@ -11,14 +11,17 @@ require (
|
|||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mervick/aes-everywhere/go/aes256 v0.0.0-20220903070135-f13ed3789ae1 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/pquerna/otp v1.4.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.3.0 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -18,6 +18,8 @@ github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqR
|
|||
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
|
|
@ -29,6 +31,8 @@ github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQ
|
|||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mervick/aes-everywhere/go/aes256 v0.0.0-20220903070135-f13ed3789ae1 h1:RLYNaO6dcj6hms2FSzwsXlZsyjxQBJi8qO/8Vkilhz0=
|
||||
github.com/mervick/aes-everywhere/go/aes256 v0.0.0-20220903070135-f13ed3789ae1/go.mod h1:Eb5RMoo9kOQra/2uRiUTGP+LfNuM13Vqm7y7P34+KKo=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
|
|
@ -36,6 +40,8 @@ github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
|||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
|
||||
github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ type PreusersMongo struct {
|
|||
HashPassword string `bson:"hash_password" json:"hash_password"`
|
||||
PhoneNumber string `bson:"phone_number" json:"phone_number"`
|
||||
CreatedDate time.Time `bson:"created_date" json:"created_date"`
|
||||
UpdateDate time.Time `bson:"update_date" json:"update_date"`
|
||||
VerifySentCount int `bson:"verify_sent_count" json:"verify_sent_count"`
|
||||
}
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ type UsersMongo struct {
|
|||
PhoneNumber string `bson:"phone_number" json:"phone_number"`
|
||||
Active bool `bson:"active" json:"active"`
|
||||
CreatedDate time.Time `bson:"created_date" json:"created_date"`
|
||||
UpdateDate time.Time `bson:"update_date" json:"update_date"`
|
||||
VerifySentCount int `bson:"verify_sent_count" json:"verify_sent_count"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,13 @@ package rest_api
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"linhdevtran99/rest-api/models"
|
||||
"linhdevtran99/rest-api/rest-api/routes"
|
||||
"linhdevtran99/rest-api/rest-api/services"
|
||||
"linhdevtran99/rest-api/utils"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type APIServer struct {
|
||||
|
|
@ -30,11 +34,13 @@ func (s *APIServer) Run() {
|
|||
router := mux.NewRouter()
|
||||
|
||||
routes.AuthRouterSetup(router)
|
||||
|
||||
router.HandleFunc("/test", utils.MakeHTTPHandlerFn(s.TestRoute))
|
||||
|
||||
startMuxServer(s, router)
|
||||
}
|
||||
|
||||
func (s *APIServer) AuthRoute(w http.ResponseWriter, r *http.Request) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
func (s *APIServer) TestRoute(w http.ResponseWriter, r *http.Request) error {
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
fmt.Println("hit")
|
||||
|
|
@ -56,23 +62,29 @@ func (s *APIServer) AuthRoute(w http.ResponseWriter, r *http.Request) error {
|
|||
//}
|
||||
|
||||
//serect := os.Getenv("EMAIL_VERIFY_SECRET")
|
||||
//isPass, _ := generatorOtp("hello", "nhocdl.poro1@gmail.com", 12, serect)
|
||||
//fmt.Println(isPass)
|
||||
//cipherBase64 := createLinkVerify(&models.CreateUser{
|
||||
// Username: "thewind121212",
|
||||
// Email: "nhocdl.poro1@gmail.com",
|
||||
// Password: "linhporoQ1@",
|
||||
// ConfirmPassword: "linhporoQ1@",
|
||||
//}, serect)
|
||||
|
||||
//_, otp := services.GeneratorOtp("hello", "nhocdl.poro1@gmail.com", 12, serect)
|
||||
//fmt.Println(otp.HashOTP)
|
||||
//fmt.Println(otp.PureOTP)
|
||||
|
||||
//utils.EncryptAESMailLink("nhocdl.poro2@gmail.com", serect, w)
|
||||
|
||||
//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)
|
||||
//
|
||||
//key := []byte(serect)
|
||||
//utils.CheckAndWriteRedis("nhocdl.poro1@gmail.com", "thewind121212", "lasdjflasdjlfj")
|
||||
|
||||
services.CheckAndWritePreuser(&models.PreusersMongo{
|
||||
Username: "thewind121212",
|
||||
Email: "nhocdl.poro2@gmail.com",
|
||||
PhoneNumber: "0918327132",
|
||||
VerifySentCount: 0,
|
||||
CreatedDate: time.Now(),
|
||||
UpdateDate: time.Now(),
|
||||
})
|
||||
|
||||
//
|
||||
//i, err := utils.DecryptAES(cipherBase64, key)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//fmt.Println(string(i))
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,28 +2,47 @@ package routes
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gorilla/mux"
|
||||
"linhdevtran99/rest-api/models"
|
||||
"linhdevtran99/rest-api/rest-api/services"
|
||||
"linhdevtran99/rest-api/utils"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func RegisterNewAccount(w http.ResponseWriter, r *http.Request) error {
|
||||
client := utils.MongoDB
|
||||
if r.Method == http.MethodPost {
|
||||
var registerInfo models.CreateUser
|
||||
|
||||
_ = json.NewDecoder(r.Body).Decode(®isterInfo)
|
||||
//call function check info user type in
|
||||
validRegisterInfo := services.CheckAndValidRegisterFiled(®isterInfo, w)
|
||||
//call function check data user use in past or not
|
||||
isValidData := services.CheckAccountExist(client, registerInfo.Username, registerInfo.Email, w)
|
||||
|
||||
if isValidData == false || validRegisterInfo == false {
|
||||
return errors.New("USER DON'T HAVE VALID INFO FOR REGISTER ACCOUNT")
|
||||
validRegisterInfo, responseAPI := services.CheckAndValidRegisterFiled(®isterInfo)
|
||||
if responseAPI != nil {
|
||||
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
||||
}
|
||||
//call function check data user use in past or not
|
||||
isValidData, responseAPI := services.CheckAccountExist(utils.MongoDB, registerInfo.Username, registerInfo.Email)
|
||||
if responseAPI != nil {
|
||||
return utils.WriteJSON(w, responseAPI.Code, responseAPI.Err.Error())
|
||||
}
|
||||
|
||||
preUserData := &models.PreusersMongo{
|
||||
Username: registerInfo.Username,
|
||||
Email: registerInfo.Email,
|
||||
PhoneNumber: registerInfo.PhoneNumber,
|
||||
HashPassword: registerInfo.Password,
|
||||
CreatedDate: time.Now(),
|
||||
UpdateDate: time.Now(),
|
||||
VerifySentCount: 1,
|
||||
}
|
||||
|
||||
services.CheckAndWritePreuser(preUserData)
|
||||
|
||||
//debug
|
||||
if isValidData == true || validRegisterInfo == true {
|
||||
return utils.WriteJSON(w, http.StatusOK, "USER HAVE VALID INFO FOR REGISTER ACCOUNT")
|
||||
}
|
||||
//debug
|
||||
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package services
|
|||
import (
|
||||
"context"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/pquerna/otp"
|
||||
|
|
@ -15,10 +15,16 @@ import (
|
|||
"linhdevtran99/rest-api/models"
|
||||
"linhdevtran99/rest-api/utils"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Check the user register field is valid or not
|
||||
func CheckAndValidRegisterFiled(registerData *models.CreateUser, w http.ResponseWriter) bool {
|
||||
type ResponseError struct {
|
||||
Code int
|
||||
Err error
|
||||
}
|
||||
|
||||
// CheckAndValidRegisterFiled Check the user register field is valid or not
|
||||
func CheckAndValidRegisterFiled(registerData *models.CreateUser) (bool, *ResponseError) {
|
||||
_ = models.Validate.RegisterValidation("customPassword", models.PasswordValidator)
|
||||
errs := models.Validate.Struct(registerData)
|
||||
var errStack []string
|
||||
|
|
@ -27,49 +33,45 @@ func CheckAndValidRegisterFiled(registerData *models.CreateUser, w http.Response
|
|||
switch err.Field() {
|
||||
case "Email":
|
||||
{
|
||||
fmt.Println("Email không hợp lệ")
|
||||
fmt.Println("Internal Log: Email không hợp lệ")
|
||||
errStack = append(errStack, "Email")
|
||||
}
|
||||
case "Username":
|
||||
{
|
||||
fmt.Println("User không hợp lệ")
|
||||
fmt.Println("Internal Log: User không hợp lệ")
|
||||
errStack = append(errStack, "User")
|
||||
}
|
||||
case "Password":
|
||||
{
|
||||
fmt.Println("Password không hợp lệ")
|
||||
fmt.Println("Internal Log: Password không hợp lệ")
|
||||
errStack = append(errStack, "Password")
|
||||
}
|
||||
case "ConfirmPassword":
|
||||
{
|
||||
fmt.Println("Nhập lại mật khẩu sai")
|
||||
fmt.Println("Internal Log: Nhập lại mật khẩu sai")
|
||||
errStack = append(errStack, "ConfirmPassword")
|
||||
}
|
||||
case "PhoneNumber":
|
||||
{
|
||||
fmt.Println("SĐT không hợp lệ")
|
||||
fmt.Println("Internal Log: SĐT không hợp lệ")
|
||||
errStack = append(errStack, "PhoneNumber")
|
||||
}
|
||||
}
|
||||
}
|
||||
//handle repose error
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := json.NewEncoder(w).Encode(errStack)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("There is error in write reponse at checking info user")
|
||||
}
|
||||
return false
|
||||
jsonData, _ := json.Marshal(errStack)
|
||||
return false, &ResponseError{Code: http.StatusBadRequest, Err: errors.New(string(jsonData))}
|
||||
}
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
|
||||
}
|
||||
|
||||
// Checking in db is user input same data in
|
||||
func CheckAccountExist(mongoClient *mongo.Client, userName string, email string, w http.ResponseWriter) bool {
|
||||
// CheckAccountExist Checking in db is user input same data in
|
||||
func CheckAccountExist(mongoClient *mongo.Client, userName string, email string) (bool, *ResponseError) {
|
||||
//filter in mongodb
|
||||
var isValid bool
|
||||
var errAPI *ResponseError
|
||||
|
||||
filter := bson.D{
|
||||
{"$or", bson.A{
|
||||
|
|
@ -78,27 +80,24 @@ func CheckAccountExist(mongoClient *mongo.Client, userName string, email string,
|
|||
}},
|
||||
}
|
||||
|
||||
userData := mongoClient.Database("Totoday-shop").Collection("users")
|
||||
|
||||
var result models.UsersMongo
|
||||
err := userData.FindOne(context.TODO(), filter).Decode(&result)
|
||||
_, err := utils.PreUserData.FindOne(context.TODO(), filter).Raw()
|
||||
if err != nil {
|
||||
isValid = true
|
||||
}
|
||||
if err == nil {
|
||||
fmt.Println("Email or username already had register")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := json.NewEncoder(w).Encode("Your username or email had been register before")
|
||||
if err != nil {
|
||||
fmt.Println("There is error in write reponse at checking data user register")
|
||||
}
|
||||
errAPI = nil
|
||||
} else {
|
||||
fmt.Println("Internal Log: Email or username already had register")
|
||||
isValid = false
|
||||
errAPI = &ResponseError{
|
||||
Code: http.StatusBadRequest,
|
||||
Err: errors.New("your username or email had been register before"),
|
||||
}
|
||||
}
|
||||
|
||||
return isValid
|
||||
return isValid, errAPI
|
||||
}
|
||||
|
||||
// Generate HOtp for confirm infomation
|
||||
// GeneratorOtp Generate HOtp for confirm information
|
||||
|
||||
func GeneratorOtp(userName string, email string, counter uint64, serect string) (bool, *models.OtpGenerate) {
|
||||
|
||||
serectBase32 := base32.StdEncoding.EncodeToString([]byte(serect + userName + email))
|
||||
|
|
@ -109,19 +108,13 @@ func GeneratorOtp(userName string, email string, counter uint64, serect string)
|
|||
|
||||
if err != nil {
|
||||
fmt.Println("Fail to create OTP")
|
||||
return false, &models.OtpGenerate{
|
||||
PureOTP: "none",
|
||||
HashOTP: "none",
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(passCode), 5)
|
||||
if err != nil {
|
||||
fmt.Println("Fail to create OTP")
|
||||
return false, &models.OtpGenerate{
|
||||
PureOTP: "none",
|
||||
HashOTP: "none",
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, &models.OtpGenerate{
|
||||
|
|
@ -130,15 +123,43 @@ func GeneratorOtp(userName string, email string, counter uint64, serect string)
|
|||
}
|
||||
}
|
||||
|
||||
// Create a alternative verify link
|
||||
func CreateLinkVerify(registerInfo *models.CreateUser, secrect string) string {
|
||||
// CreateLinkVerify Create a alternative verify link
|
||||
func CreateLinkVerify(registerInfo string, secrect string) string {
|
||||
return "linh"
|
||||
|
||||
}
|
||||
|
||||
// check and write pre use into mongo db
|
||||
func CheckAndWritePreuser(registerInfo *models.PreusersMongo) {
|
||||
//checking
|
||||
email := registerInfo.Email
|
||||
filter := bson.D{{"email", email}}
|
||||
_, err := utils.PreUserData.FindOne(context.Background(), filter).Raw()
|
||||
if err != nil {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(registerInfo.HashPassword), 10)
|
||||
if err != nil {
|
||||
fmt.Println("Fail to create OTP")
|
||||
}
|
||||
registerInfo.HashPassword = string(hashed)
|
||||
_, err = utils.PreUserData.InsertOne(context.Background(), registerInfo)
|
||||
if err != nil {
|
||||
fmt.Println("Something Went Wrong")
|
||||
}
|
||||
} else {
|
||||
update := bson.D{
|
||||
{"$inc", bson.D{
|
||||
{"verify_sent_count", 1},
|
||||
}},
|
||||
{"$set", bson.D{
|
||||
{"update_date", time.Now()},
|
||||
},
|
||||
}}
|
||||
|
||||
_, err := utils.PreUserData.UpdateOne(context.Background(), filter, update)
|
||||
if err != nil {
|
||||
fmt.Println("Internal log: update document fail")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(registerInfo)
|
||||
key := []byte(secrect)
|
||||
|
||||
ciphertext, _ := utils.EncryptAES(data, key)
|
||||
|
||||
cipherTextBase64 := base64.StdEncoding.EncodeToString(ciphertext)
|
||||
|
||||
return cipherTextBase64
|
||||
}
|
||||
|
|
|
|||
118
utils/crypto.go
118
utils/crypto.go
|
|
@ -1,79 +1,83 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/skip2/go-qrcode"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func EncryptAES(data []byte, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
//Mail
|
||||
|
||||
type MyCustomClaims struct {
|
||||
Email string `json:"email"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func buildTokenLink(token string, w http.ResponseWriter) (string, string) {
|
||||
tokenCustomTrim := strings.ReplaceAll(token, ".", "&")
|
||||
emailVerifyLink := "http://www.totoday.com/?p=" + tokenCustomTrim
|
||||
fmt.Println(emailVerifyLink)
|
||||
png, err := qrcode.Encode(emailVerifyLink, qrcode.Low, 200)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
fmt.Println("Internal log: error create qr ")
|
||||
_ = WriteJSONInternalError(w, "error create QR code")
|
||||
}
|
||||
base64Image := base64.StdEncoding.EncodeToString(png)
|
||||
dataURL := "data:image/png;base64," + base64Image
|
||||
|
||||
return emailVerifyLink, dataURL
|
||||
}
|
||||
|
||||
// Generate a random IV (Initialization Vector)
|
||||
iv := make([]byte, aes.BlockSize)
|
||||
if _, err := rand.Read(iv); err != nil {
|
||||
fmt.Println("error generating IV:", err)
|
||||
func EncryptAESMailLink(data string, key string, w http.ResponseWriter) (string, string) {
|
||||
claims := MyCustomClaims{
|
||||
data,
|
||||
jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: "totodayShop",
|
||||
},
|
||||
}
|
||||
|
||||
// Pad the data to a multiple of the block size
|
||||
data = pkcs7Pad(data, aes.BlockSize)
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
token.Header["purpose"] = "Email_Verify"
|
||||
|
||||
// Create a CBC mode cipher block
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
|
||||
// Encrypt the data
|
||||
ciphertext := make([]byte, len(data))
|
||||
mode.CryptBlocks(ciphertext, data)
|
||||
|
||||
// Prepend the IV to the ciphertext
|
||||
ciphertext = append(iv, ciphertext...)
|
||||
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
func DecryptAES(base64Ciphertext string, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
tokenString, err := token.SignedString([]byte(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
fmt.Println("Internal Log: Error signed token fail", err.Error())
|
||||
_ = WriteJSONInternalError(w, "Error signing token fail")
|
||||
}
|
||||
|
||||
// Decode base64
|
||||
ciphertext, err := base64.StdEncoding.DecodeString(base64Ciphertext)
|
||||
if err != nil {
|
||||
fmt.Println("error decoding base64:", err)
|
||||
return buildTokenLink(tokenString, w)
|
||||
}
|
||||
|
||||
// Extract the IV from the ciphertext
|
||||
iv := ciphertext[:aes.BlockSize]
|
||||
ciphertext = ciphertext[aes.BlockSize:]
|
||||
//
|
||||
//func DecryptAESMailLink(data string, key string) string {
|
||||
//}
|
||||
|
||||
// Create a CBC mode cipher block
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
//OTP
|
||||
//Write preuser to mongo db
|
||||
|
||||
// Decrypt the data
|
||||
mode.CryptBlocks(ciphertext, ciphertext)
|
||||
//func WriteToMongo(registerInfo *models.PreusersMongo) {
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
||||
// Remove padding
|
||||
ciphertext = pkcs7Unpad(ciphertext)
|
||||
//Write otp to redis
|
||||
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
// pkcs7Pad pads the input to a multiple of blockSize using PKCS#7 padding
|
||||
func pkcs7Pad(data []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(data)%blockSize
|
||||
padText := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(data, padText...)
|
||||
}
|
||||
|
||||
// pkcs7Unpad removes PKCS#7 padding from the input
|
||||
func pkcs7Unpad(data []byte) []byte {
|
||||
padding := int(data[len(data)-1])
|
||||
return data[:len(data)-padding]
|
||||
}
|
||||
//func CheckAndWriteRedis(email string, username string, hashOTP string) {
|
||||
// //checking does it valid or have in redis or not
|
||||
// //var count int
|
||||
// exists, err := Redis.Exists(context.Background(), "otp:nhocdl.poro1@gmail.com").Result()
|
||||
// if err != nil {
|
||||
// fmt.Println("something went wrong")
|
||||
// }
|
||||
// if exists == 0 {
|
||||
// //count = 0
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
)
|
||||
|
||||
var MongoDB *mongo.Client
|
||||
var PreUserData *mongo.Collection
|
||||
|
||||
func InitMongoDriver(mongoUri string) *mongo.Client {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
|
@ -30,6 +31,7 @@ func InitMongoDriver(mongoUri string) *mongo.Client {
|
|||
}
|
||||
|
||||
MongoDB = client
|
||||
PreUserData = MongoDB.Database("Totoday-shop").Collection("preusers")
|
||||
|
||||
return client
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,21 @@ import (
|
|||
func WriteJSON(w http.ResponseWriter, status int, v any) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
return json.NewEncoder(w).Encode(v)
|
||||
err := json.NewEncoder(w).Encode(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func WriteJSONInternalError(w http.ResponseWriter, v any) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
err := json.NewEncoder(w).Encode(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ApiError struct {
|
||||
|
|
|
|||
Loading…
Reference in New Issue