feat: Add Invitation Code to Generate Invitation Link (#2666)

Add auto-population of invitation fields in the registration page based on the invitation code in the link
This commit is contained in:
HGZ-20
2024-02-02 21:12:56 +08:00
committed by GitHub
parent bbbda1982f
commit b7be1943fa
56 changed files with 269 additions and 27 deletions

View File

@ -184,6 +184,15 @@ func CheckInvitationCode(application *Application, organization *Organization, a
}
}
func CheckInvitationDefaultCode(code string, defaultCode string, lang string) error {
if matched, err := util.IsInvitationCodeMatch(code, defaultCode); err != nil {
return err
} else if !matched {
return fmt.Errorf(i18n.Translate(lang, "check:Default code does not match the code's matching rules"))
}
return nil
}
func checkSigninErrorTimes(user *User, lang string) error {
failedSigninLimit, failedSigninFrozenTime, err := GetFailedSigninConfigByUser(user)
if err != nil {

View File

@ -40,6 +40,7 @@ type Invitation struct {
Phone string `xorm:"varchar(100)" json:"phone"`
SignupGroup string `xorm:"varchar(100)" json:"signupGroup"`
DefaultCode string `xorm:"varchar(100)" json:"defaultCode"`
State string `xorm:"varchar(100)" json:"state"`
}
@ -93,7 +94,45 @@ func GetInvitation(id string) (*Invitation, error) {
return getInvitation(owner, name)
}
func UpdateInvitation(id string, invitation *Invitation) (bool, error) {
func GetInvitationByCode(code string, organizationName string, lang string) (*Invitation, string) {
invitations, err := GetInvitations(organizationName)
if err != nil {
return nil, err.Error()
}
errMsg := ""
for _, invitation := range invitations {
if isValid, msg := invitation.SimpleCheckInvitationCode(code, lang); isValid {
return invitation, msg
} else if msg != "" && errMsg == "" {
errMsg = msg
}
}
if errMsg != "" {
return nil, errMsg
} else {
return nil, i18n.Translate(lang, "check:Invitation code is invalid")
}
}
func GetMaskedInvitation(invitation *Invitation) *Invitation {
if invitation == nil {
return nil
}
invitation.CreatedTime = ""
invitation.UpdatedTime = ""
invitation.Code = "***"
invitation.DefaultCode = "***"
invitation.IsRegexp = false
invitation.Quota = -1
invitation.UsedCount = -1
invitation.SignupGroup = ""
return invitation
}
func UpdateInvitation(id string, invitation *Invitation, lang string) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
if p, err := getInvitation(owner, name); err != nil {
return false, err
@ -107,6 +146,11 @@ func UpdateInvitation(id string, invitation *Invitation) (bool, error) {
invitation.IsRegexp = isRegexp
}
err := CheckInvitationDefaultCode(invitation.Code, invitation.DefaultCode, lang)
if err != nil {
return false, err
}
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(invitation)
if err != nil {
return false, err
@ -115,13 +159,18 @@ func UpdateInvitation(id string, invitation *Invitation) (bool, error) {
return affected != 0, nil
}
func AddInvitation(invitation *Invitation) (bool, error) {
func AddInvitation(invitation *Invitation, lang string) (bool, error) {
if isRegexp, err := util.IsRegexp(invitation.Code); err != nil {
return false, err
} else {
invitation.IsRegexp = isRegexp
}
err := CheckInvitationDefaultCode(invitation.Code, invitation.DefaultCode, lang)
if err != nil {
return false, err
}
affected, err := ormer.Engine.Insert(invitation)
if err != nil {
return false, err
@ -147,7 +196,7 @@ func VerifyInvitation(id string) (payment *Payment, attachInfo map[string]interf
return nil, nil, fmt.Errorf("the invitation: %s does not exist", id)
}
func (invitation *Invitation) IsInvitationCodeValid(application *Application, invitationCode string, username string, email string, phone string, lang string) (bool, string) {
func (invitation *Invitation) SimpleCheckInvitationCode(invitationCode string, lang string) (bool, string) {
if matched, err := util.IsInvitationCodeMatch(invitation.Code, invitationCode); err != nil {
return false, err.Error()
} else if !matched {
@ -160,15 +209,6 @@ func (invitation *Invitation) IsInvitationCodeValid(application *Application, in
if invitation.UsedCount >= invitation.Quota {
return false, i18n.Translate(lang, "check:Invitation code exhausted")
}
if application.IsSignupItemRequired("Username") && invitation.Username != "" && invitation.Username != username {
return false, i18n.Translate(lang, "check:Please register using the username corresponding to the invitation code")
}
if application.IsSignupItemRequired("Email") && invitation.Email != "" && invitation.Email != email {
return false, i18n.Translate(lang, "check:Please register using the email corresponding to the invitation code")
}
if application.IsSignupItemRequired("Phone") && invitation.Phone != "" && invitation.Phone != phone {
return false, i18n.Translate(lang, "check:Please register using the phone corresponding to the invitation code")
}
// Determine whether the invitation code is in the form of a regular expression other than pure numbers and letters
if invitation.IsRegexp {
@ -179,3 +219,19 @@ func (invitation *Invitation) IsInvitationCodeValid(application *Application, in
}
return true, ""
}
func (invitation *Invitation) IsInvitationCodeValid(application *Application, invitationCode string, username string, email string, phone string, lang string) (bool, string) {
if isValid, msg := invitation.SimpleCheckInvitationCode(invitationCode, lang); !isValid {
return false, msg
}
if application.IsSignupItemRequired("Username") && invitation.Username != "" && invitation.Username != username {
return false, i18n.Translate(lang, "check:Please register using the username corresponding to the invitation code")
}
if application.IsSignupItemRequired("Email") && invitation.Email != "" && invitation.Email != email {
return false, i18n.Translate(lang, "check:Please register using the email corresponding to the invitation code")
}
if application.IsSignupItemRequired("Phone") && invitation.Phone != "" && invitation.Phone != phone {
return false, i18n.Translate(lang, "check:Please register using the phone corresponding to the invitation code")
}
return true, ""
}