Fix: email duplicated key

pull/134/head
zijiren233 2 years ago
parent cb3d03bb31
commit 65d4d6757c

@ -49,8 +49,10 @@ const (
) )
func initGuestUser() error { func initGuestUser() error {
user := model.User{} user := model.User{
err := db.Where("id = ?", GuestUserID).First(&user).Error ID: GuestUserID,
}
err := db.First(&user).Error
if err == nil || !errors.Is(err, gorm.ErrRecordNotFound) { if err == nil || !errors.Is(err, gorm.ErrRecordNotFound) {
return err return err
} }

@ -1,6 +1,7 @@
package db package db
import ( import (
"database/sql"
"errors" "errors"
"fmt" "fmt"
@ -65,7 +66,10 @@ func WithRegisteredByProvider(b bool) CreateUserConfig {
func WithEmail(email string) CreateUserConfig { func WithEmail(email string) CreateUserConfig {
return func(u *model.User) { return func(u *model.User) {
u.Email = email u.Email = sql.NullString{
String: email,
Valid: true,
}
} }
} }
@ -424,7 +428,10 @@ func SetUserHashedPassword(id string, hashedPassword []byte) error {
} }
func BindEmail(id string, email string) error { func BindEmail(id string, email string) error {
err := db.Model(&model.User{}).Where("id = ?", id).Update("email", email).Error err := db.Model(&model.User{}).Where("id = ?", id).Update("email", sql.NullString{
String: email,
Valid: true,
}).Error
return HandleNotFound(err, "user") return HandleNotFound(err, "user")
} }
@ -434,12 +441,12 @@ func UnbindEmail(uid string) error {
if err := tx.Where("id = ?", uid).First(&user).Error; err != nil { if err := tx.Where("id = ?", uid).First(&user).Error; err != nil {
return HandleNotFound(err, "user") return HandleNotFound(err, "user")
} }
if user.Email == "" { if user.Email.String == "" {
return errors.New("user has no email") return errors.New("user has no email")
} }
if user.RegisteredByEmail { if user.RegisteredByEmail {
return errors.New("user must have one email") return errors.New("user must have one email")
} }
return tx.Model(&model.User{}).Where("id = ?", uid).Update("email", "").Error return tx.Model(&model.User{}).Where("id = ?", uid).Update("email", sql.NullString{}).Error
}) })
} }

@ -1,6 +1,7 @@
package model package model
import ( import (
"database/sql"
"fmt" "fmt"
"math/rand" "math/rand"
"time" "time"
@ -47,7 +48,7 @@ type User struct {
UserProviders []*UserProvider `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserProviders []*UserProvider `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Username string `gorm:"not null;uniqueIndex;type:varchar(32)"` Username string `gorm:"not null;uniqueIndex;type:varchar(32)"`
HashedPassword []byte `gorm:"not null"` HashedPassword []byte `gorm:"not null"`
Email string `gorm:"type:varchar(128);uniqueIndex:,where:email <> ''"` Email sql.NullString `gorm:"type:varchar(128);uniqueIndex"`
Role Role `gorm:"not null;default:2"` Role Role `gorm:"not null;default:2"`
RoomMembers []*RoomMember `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` RoomMembers []*RoomMember `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Rooms []*Room `gorm:"foreignKey:CreatorID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` Rooms []*Room `gorm:"foreignKey:CreatorID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`

@ -1,6 +1,7 @@
package op package op
import ( import (
"database/sql"
"errors" "errors"
"hash/crc32" "hash/crc32"
"sync/atomic" "sync/atomic"
@ -443,7 +444,10 @@ func (u *User) BindEmail(e string) error {
if err != nil { if err != nil {
return err return err
} }
u.Email = e u.Email = sql.NullString{
String: e,
Valid: true,
}
return nil return nil
} }
@ -452,30 +456,30 @@ func (u *User) UnbindEmail() error {
if err != nil { if err != nil {
return err return err
} }
u.Email = "" u.Email = sql.NullString{}
return nil return nil
} }
var ErrEmailUnbound = errors.New("email unbound") var ErrEmailUnbound = errors.New("email unbound")
func (u *User) SendTestEmail() error { func (u *User) SendTestEmail() error {
if u.Email == "" { if u.Email.String == "" {
return ErrEmailUnbound return ErrEmailUnbound
} }
return email.SendTestEmail(u.Username, u.Email) return email.SendTestEmail(u.Username, u.Email.String)
} }
func (u *User) SendRetrievePasswordCaptchaEmail(host string) error { func (u *User) SendRetrievePasswordCaptchaEmail(host string) error {
if u.Email == "" { if u.Email.String == "" {
return ErrEmailUnbound return ErrEmailUnbound
} }
return email.SendRetrievePasswordCaptchaEmail(u.ID, u.Email, host) return email.SendRetrievePasswordCaptchaEmail(u.ID, u.Email.String, host)
} }
func (u *User) VerifyRetrievePasswordCaptchaEmail(e, captcha string) (bool, error) { func (u *User) VerifyRetrievePasswordCaptchaEmail(e, captcha string) (bool, error) {
if u.Email != e { if u.Email.String != e {
return false, errors.New("email has changed, please resend the captcha email") return false, errors.New("email has changed, please resend the captcha email")
} }
return email.VerifyRetrievePasswordCaptchaEmail(u.ID, e, captcha) return email.VerifyRetrievePasswordCaptchaEmail(u.ID, e, captcha)

@ -32,7 +32,7 @@ func Me(ctx *gin.Context) {
Username: user.Username, Username: user.Username,
Role: user.Role, Role: user.Role,
CreatedAt: user.CreatedAt.UnixMilli(), CreatedAt: user.CreatedAt.UnixMilli(),
Email: user.Email, Email: user.Email.String,
})) }))
} }
@ -304,7 +304,7 @@ func SendUserBindEmailCaptcha(ctx *gin.Context) {
return return
} }
if user.Email == req.Email { if user.Email.String == req.Email {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("this email same as current email")) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("this email same as current email"))
return return
} }

Loading…
Cancel
Save