150 lines
4.8 KiB
Go
150 lines
4.8 KiB
Go
package user
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"github.com/google/uuid"
|
|
"nCovTrack-Backend/global"
|
|
"nCovTrack-Backend/models"
|
|
"nCovTrack-Backend/utils"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
EMAIL_CODE_REDIS_KEY = "verify_code_"
|
|
)
|
|
|
|
// Login if login success, will return token
|
|
func Login(user map[string]interface{}) (token string) {
|
|
// TODO: need to detect is passed or not
|
|
account := user["account"].(string)
|
|
var queryMap []map[string]interface{}
|
|
if strings.Contains(account, "@") {
|
|
queryMap = append(queryMap, map[string]interface{}{"email": account})
|
|
} else {
|
|
queryMap = append(queryMap, map[string]interface{}{"phone": account})
|
|
}
|
|
userInfo := models.Get[models.BackUser](queryMap)
|
|
if userInfo == nil {
|
|
return ""
|
|
}
|
|
if userInfo["approver"].(int) <= 0 {
|
|
return ""
|
|
}
|
|
if !utils.PasswordCompare(user["password"].(string), userInfo["password"].(string)) {
|
|
return ""
|
|
}
|
|
claims := jwt.MapClaims{
|
|
"id": userInfo["id"],
|
|
"username": userInfo["username"],
|
|
"email": userInfo["email"],
|
|
"region": userInfo["region"],
|
|
"role": userInfo["role"],
|
|
}
|
|
return utils.GenerateToken(claims)
|
|
}
|
|
|
|
// Register user register, user can use account after approved
|
|
func Register(user map[string]interface{}) bool {
|
|
user["password"] = utils.PasswordEncrypt(user["password"].(string))
|
|
user["approver"] = 0
|
|
colMap := models.MapJ2c[models.BackUser](user, false)
|
|
ok, rowsAffected := models.Upsert[models.BackUser](colMap)
|
|
if !ok || rowsAffected == 0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// ListRegister list the registers in the redis to be approved
|
|
func ListRegister(claims models.TokenClaims) *[]map[string]interface{} {
|
|
registers := []map[string]interface{}{}
|
|
tx := global.Db.Model(new(models.BackUser)).Omit("password")
|
|
if claims.Region == "" {
|
|
// do nothing
|
|
} else if !strings.Contains(claims.Region, " ") {
|
|
tx.Where("approver = 0 AND is_delete = 0 AND region LIKE ? AND role = ?", claims.Region+" %", global.ROLE_ID_MAP["ADMIN"])
|
|
registers = *models.ListByOrm(tx)
|
|
} else {
|
|
tx.Where("approver = 0 AND is_delete = 0 AND region = ? AND role in ?", claims.Region, []int{global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]})
|
|
registers = *models.ListByOrm(tx)
|
|
}
|
|
return ®isters
|
|
}
|
|
|
|
// ListApprovedRegister list registers approved by the admin
|
|
func ListApprovedRegister(claims models.TokenClaims) *[]map[string]interface{} {
|
|
approvedRegisters := []map[string]interface{}{}
|
|
tx := global.Db.Model(new(models.BackUser)).Omit("password").Where("approver in ? and is_delete = 0", []int{claims.ID, -claims.ID})
|
|
approvedRegisters = *models.ListByOrm(tx)
|
|
return &approvedRegisters
|
|
}
|
|
|
|
// ApproveRegister approve a register
|
|
func ApproveRegister(claims models.TokenClaims, email string, pass bool) bool {
|
|
queryMap := []map[string]interface{}{{"email": email}}
|
|
var approver int
|
|
if pass {
|
|
approver = claims.ID
|
|
} else {
|
|
approver = -claims.ID
|
|
}
|
|
updateMap := map[string]interface{}{"approver": approver}
|
|
ok, rowsAffected := models.Update[models.BackUser](queryMap, updateMap)
|
|
if !ok || rowsAffected == 0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// ChangePassword user change password, or user forgot password
|
|
func ChangePassword(changePwd map[string]interface{}) bool {
|
|
match := VerifyEmailCode(changePwd["email"].(string), changePwd["code"].(string))["match"].(bool)
|
|
if !match {
|
|
return false
|
|
}
|
|
newPassword := utils.PasswordEncrypt(changePwd["newPassword"].(string))
|
|
colMap := map[string]interface{}{
|
|
"id": 1,
|
|
"password": newPassword,
|
|
}
|
|
models.BeforeSave(colMap, -1)
|
|
delete(colMap, "id")
|
|
rowAffected := global.Db.Model(models.BackUser{}).Where("email = ?", changePwd["email"]).Updates(colMap).RowsAffected
|
|
if rowAffected == 0 {
|
|
return false
|
|
}
|
|
now := time.Now().Unix()
|
|
global.Redis.HSet(global.CHANGEPWD_REDIS_KEY, changePwd["email"].(string), now)
|
|
return true
|
|
}
|
|
|
|
// NoDuplicatePhoneOrEmail detect the phone or email is registered or not
|
|
func NoDuplicatePhoneOrEmail(phone string, email string) bool {
|
|
var queryMap []map[string]interface{}
|
|
if phone != "" {
|
|
queryMap = append(queryMap, map[string]interface{}{"phone": phone})
|
|
}
|
|
if email != "" {
|
|
queryMap = append(queryMap, map[string]interface{}{"email": email})
|
|
}
|
|
return len(queryMap) != 0 && models.Count[models.BackUser](queryMap) == 0
|
|
}
|
|
|
|
// SendEmailCode used to send email verify code
|
|
func SendEmailCode(email string) bool {
|
|
code := uuid.New().String()[0:6]
|
|
text := fmt.Sprintf("Your Verify Code is :%s, Will Expire After 10 Minutes", code)
|
|
subject := "nCovTrack Verify"
|
|
// only set expired, not limit the frequency of use
|
|
global.Redis.Set(EMAIL_CODE_REDIS_KEY+email, code, 10*time.Minute)
|
|
return utils.SendEmail(subject, text, email)
|
|
}
|
|
|
|
// VerifyEmailCode use to verify user's verify code is correct or not
|
|
func VerifyEmailCode(email string, code string) map[string]interface{} {
|
|
verifyCode := global.Redis.Get(EMAIL_CODE_REDIS_KEY + email).Val()
|
|
return map[string]interface{}{"match": verifyCode == code}
|
|
}
|