diff --git a/authz/authz.go b/authz/authz.go index e2ae4144..48a92a52 100644 --- a/authz/authz.go +++ b/authz/authz.go @@ -96,6 +96,7 @@ p, *, *, GET, /api/get-organization-names, *, * p, *, *, GET, /api/get-all-objects, *, * p, *, *, GET, /api/get-all-actions, *, * p, *, *, GET, /api/get-all-roles, *, * +p, *, *, GET, /api/get-invitation-info, *, * ` sa := stringadapter.NewAdapter(ruleText) diff --git a/controllers/account.go b/controllers/account.go index 7538c501..7dde0493 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -227,7 +227,7 @@ func (c *ApiController) Signup() { if invitation != nil { invitation.UsedCount += 1 - _, err := object.UpdateInvitation(invitation.GetId(), invitation) + _, err := object.UpdateInvitation(invitation.GetId(), invitation, c.GetAcceptLanguage()) if err != nil { c.ResponseError(err.Error()) return diff --git a/controllers/invitation.go b/controllers/invitation.go index c4f65f9e..25743ca4 100644 --- a/controllers/invitation.go +++ b/controllers/invitation.go @@ -84,6 +84,32 @@ func (c *ApiController) GetInvitation() { c.ResponseOk(invitation) } +// GetInvitationCodeInfo +// @Title GetInvitationCodeInfo +// @Tag Invitation API +// @Description get invitation code information +// @Param code query string true "Invitation code" +// @Success 200 {object} object.Invitation The Response object +// @router /get-invitation-info [get] +func (c *ApiController) GetInvitationCodeInfo() { + code := c.Input().Get("code") + applicationId := c.Input().Get("applicationId") + + application, err := object.GetApplication(applicationId) + if err != nil { + c.ResponseError(err.Error()) + return + } + + invitation, msg := object.GetInvitationByCode(code, application.Organization, c.GetAcceptLanguage()) + if msg != "" { + c.ResponseError(msg) + return + } + + c.ResponseOk(object.GetMaskedInvitation(invitation)) +} + // UpdateInvitation // @Title UpdateInvitation // @Tag Invitation API @@ -102,7 +128,7 @@ func (c *ApiController) UpdateInvitation() { return } - c.Data["json"] = wrapActionResponse(object.UpdateInvitation(id, &invitation)) + c.Data["json"] = wrapActionResponse(object.UpdateInvitation(id, &invitation, c.GetAcceptLanguage())) c.ServeJSON() } @@ -121,7 +147,7 @@ func (c *ApiController) AddInvitation() { return } - c.Data["json"] = wrapActionResponse(object.AddInvitation(&invitation)) + c.Data["json"] = wrapActionResponse(object.AddInvitation(&invitation, c.GetAcceptLanguage())) c.ServeJSON() } diff --git a/i18n/locales/ar/data.json b/i18n/locales/ar/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/ar/data.json +++ b/i18n/locales/ar/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/de/data.json b/i18n/locales/de/data.json index 3f89c3c5..61346698 100644 --- a/i18n/locales/de/data.json +++ b/i18n/locales/de/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Zugehörigkeit darf nicht leer sein", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "Anzeigename kann nicht leer sein", "DisplayName is not valid real name": "DisplayName ist kein gültiger Vorname", "Email already exists": "E-Mail existiert bereits", diff --git a/i18n/locales/en/data.json b/i18n/locales/en/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/en/data.json +++ b/i18n/locales/en/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/es/data.json b/i18n/locales/es/data.json index 42c13c9c..fc6096c0 100644 --- a/i18n/locales/es/data.json +++ b/i18n/locales/es/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Afiliación no puede estar en blanco", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "El nombre de visualización no puede estar en blanco", "DisplayName is not valid real name": "El nombre de pantalla no es un nombre real válido", "Email already exists": "El correo electrónico ya existe", diff --git a/i18n/locales/fa/data.json b/i18n/locales/fa/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/fa/data.json +++ b/i18n/locales/fa/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/fi/data.json b/i18n/locales/fi/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/fi/data.json +++ b/i18n/locales/fi/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/fr/data.json b/i18n/locales/fr/data.json index 40d52fbb..626d4643 100644 --- a/i18n/locales/fr/data.json +++ b/i18n/locales/fr/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation ne peut pas être vide", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "Le nom d'affichage ne peut pas être vide", "DisplayName is not valid real name": "DisplayName n'est pas un nom réel valide", "Email already exists": "E-mail déjà existant", diff --git a/i18n/locales/he/data.json b/i18n/locales/he/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/he/data.json +++ b/i18n/locales/he/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/id/data.json b/i18n/locales/id/data.json index b4d14892..73111cac 100644 --- a/i18n/locales/id/data.json +++ b/i18n/locales/id/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Keterkaitan tidak boleh kosong", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "Nama Pengguna tidak boleh kosong", "DisplayName is not valid real name": "DisplayName bukanlah nama asli yang valid", "Email already exists": "Email sudah ada", diff --git a/i18n/locales/it/data.json b/i18n/locales/it/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/it/data.json +++ b/i18n/locales/it/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/ja/data.json b/i18n/locales/ja/data.json index fb105452..f4616226 100644 --- a/i18n/locales/ja/data.json +++ b/i18n/locales/ja/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "所属は空白にできません", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "表示名は空白にできません", "DisplayName is not valid real name": "表示名は有効な実名ではありません", "Email already exists": "メールは既に存在します", diff --git a/i18n/locales/kk/data.json b/i18n/locales/kk/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/kk/data.json +++ b/i18n/locales/kk/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/ko/data.json b/i18n/locales/ko/data.json index ed9e7b19..e9e0d6cd 100644 --- a/i18n/locales/ko/data.json +++ b/i18n/locales/ko/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "소속은 비워 둘 수 없습니다", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName는 비어 있을 수 없습니다", "DisplayName is not valid real name": "DisplayName는 유효한 실제 이름이 아닙니다", "Email already exists": "이메일이 이미 존재합니다", diff --git a/i18n/locales/ms/data.json b/i18n/locales/ms/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/ms/data.json +++ b/i18n/locales/ms/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/nl/data.json b/i18n/locales/nl/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/nl/data.json +++ b/i18n/locales/nl/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/pl/data.json b/i18n/locales/pl/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/pl/data.json +++ b/i18n/locales/pl/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/pt/data.json b/i18n/locales/pt/data.json index 29a6e7a9..c4b00438 100644 --- a/i18n/locales/pt/data.json +++ b/i18n/locales/pt/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/ru/data.json b/i18n/locales/ru/data.json index 058da3a5..ddd24ab3 100644 --- a/i18n/locales/ru/data.json +++ b/i18n/locales/ru/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Принадлежность не может быть пустым значением", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "Имя отображения не может быть пустым", "DisplayName is not valid real name": "DisplayName не является действительным именем", "Email already exists": "Электронная почта уже существует", diff --git a/i18n/locales/sv/data.json b/i18n/locales/sv/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/sv/data.json +++ b/i18n/locales/sv/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/tr/data.json b/i18n/locales/tr/data.json index 7ce577db..05f589a8 100644 --- a/i18n/locales/tr/data.json +++ b/i18n/locales/tr/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/uk/data.json b/i18n/locales/uk/data.json index 3086b85c..8a4a8aab 100644 --- a/i18n/locales/uk/data.json +++ b/i18n/locales/uk/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Affiliation cannot be blank", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "DisplayName cannot be blank", "DisplayName is not valid real name": "DisplayName is not valid real name", "Email already exists": "Email already exists", diff --git a/i18n/locales/vi/data.json b/i18n/locales/vi/data.json index 6f4ac244..3c3c6072 100644 --- a/i18n/locales/vi/data.json +++ b/i18n/locales/vi/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "Tình trạng liên kết không thể để trống", + "Default code does not match the code's matching rules": "Default code does not match the code's matching rules", "DisplayName cannot be blank": "Tên hiển thị không thể để trống", "DisplayName is not valid real name": "DisplayName không phải là tên thật hợp lệ", "Email already exists": "Email đã tồn tại", diff --git a/i18n/locales/zh/data.json b/i18n/locales/zh/data.json index 514512da..21a3408f 100644 --- a/i18n/locales/zh/data.json +++ b/i18n/locales/zh/data.json @@ -30,6 +30,7 @@ }, "check": { "Affiliation cannot be blank": "工作单位不可为空", + "Default code does not match the code's matching rules": "邀请码默认值和邀请码规则不匹配", "DisplayName cannot be blank": "显示名称不可为空", "DisplayName is not valid real name": "显示名称必须是真实姓名", "Email already exists": "该邮箱已存在", diff --git a/object/check.go b/object/check.go index b937c0d0..2fe97a3e 100644 --- a/object/check.go +++ b/object/check.go @@ -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 { diff --git a/object/invitation.go b/object/invitation.go index f90f0466..57f4b0e8 100644 --- a/object/invitation.go +++ b/object/invitation.go @@ -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, "" +} diff --git a/routers/router.go b/routers/router.go index dbf8658c..ba228c68 100644 --- a/routers/router.go +++ b/routers/router.go @@ -94,6 +94,7 @@ func initAPI() { beego.Router("/api/get-invitations", &controllers.ApiController{}, "GET:GetInvitations") beego.Router("/api/get-invitation", &controllers.ApiController{}, "GET:GetInvitation") + beego.Router("/api/get-invitation-info", &controllers.ApiController{}, "GET:GetInvitationCodeInfo") beego.Router("/api/update-invitation", &controllers.ApiController{}, "POST:UpdateInvitation") beego.Router("/api/add-invitation", &controllers.ApiController{}, "POST:AddInvitation") beego.Router("/api/delete-invitation", &controllers.ApiController{}, "POST:DeleteInvitation") diff --git a/web/src/InvitationEditPage.js b/web/src/InvitationEditPage.js index 7aa8510d..7889ff72 100644 --- a/web/src/InvitationEditPage.js +++ b/web/src/InvitationEditPage.js @@ -19,6 +19,7 @@ import * as OrganizationBackend from "./backend/OrganizationBackend"; import * as ApplicationBackend from "./backend/ApplicationBackend"; import * as Setting from "./Setting"; import i18next from "i18next"; +import copy from "copy-to-clipboard"; const {Option} = Select; @@ -99,6 +100,18 @@ class InvitationEditPage extends React.Component { {this.state.mode === "add" ? i18next.t("invitation:New Invitation") : i18next.t("invitation:Edit Invitation")}     + {this.state.mode === "add" ? : null} } style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner"> @@ -140,10 +153,24 @@ class InvitationEditPage extends React.Component { { + const regex = /[^a-zA-Z0-9]/; + if (!regex.test(e.target.value)) { + this.updateInvitationField("defaultCode", e.target.value); + } this.updateInvitationField("code", e.target.value); }} /> + + + {Setting.getLabel(i18next.t("invitation:Default code"), i18next.t("invitation:Default code - Tooltip"))} : + + + { + this.updateInvitationField("defaultCode", e.target.value); + }} /> + + {Setting.getLabel(i18next.t("invitation:Quota"), i18next.t("invitation:Quota - Tooltip"))} : @@ -274,6 +301,18 @@ class InvitationEditPage extends React.Component {
+ {this.state.mode === "add" ? : null}
diff --git a/web/src/InvitationListPage.js b/web/src/InvitationListPage.js index 3d67a892..59ff9790 100644 --- a/web/src/InvitationListPage.js +++ b/web/src/InvitationListPage.js @@ -22,19 +22,20 @@ import * as InvitationBackend from "./backend/InvitationBackend"; import i18next from "i18next"; import BaseListPage from "./BaseListPage"; import PopconfirmModal from "./common/modal/PopconfirmModal"; -import copy from "copy-to-clipboard"; class InvitationListPage extends BaseListPage { newInvitation() { const randomName = Setting.getRandomName(); const owner = Setting.getRequestOrganization(this.props.account); + const code = Math.random().toString(36).slice(-10); return { owner: owner, name: `invitation_${randomName}`, createdTime: moment().format(), updatedTime: moment().format(), displayName: `New Invitation - ${randomName}`, - code: Math.random().toString(36).slice(-10), + code: code, + defaultCode: code, quota: 1, usedCount: 0, application: "All", @@ -225,17 +226,11 @@ class InvitationListPage extends BaseListPage { title: i18next.t("general:Action"), dataIndex: "", key: "op", - width: "350px", + width: "180px", fixed: (Setting.isMobile()) ? "false" : "right", render: (text, record, index) => { return (
- { + if (res.status === "error") { + Setting.showMessage("error", res.msg); + return; + } + this.setState({invitation: res.data}); + }); + } + getResultPath(application, signupParams) { if (signupParams?.plan && signupParams?.pricing) { // the prompt page needs the user to be signed in, so for paid-user sign up, just go to buy-plan page @@ -235,7 +256,7 @@ class SignupPage extends React.Component { }, ]} > - + ); } else if (signupItem.name === "Display name") { @@ -363,7 +384,7 @@ class SignupPage extends React.Component { }, ]} > - this.setState({email: e.target.value})} /> + this.setState({email: e.target.value})} /> { signupItem.rule !== "No verification" && @@ -434,6 +455,7 @@ class SignupPage extends React.Component { this.setState({phone: e.target.value})} /> @@ -524,7 +546,7 @@ class SignupPage extends React.Component { }, ]} > - + ); } else if (signupItem.name === "Agreement") { @@ -554,6 +576,20 @@ class SignupPage extends React.Component { ); } + if (this.state.invitation !== undefined) { + if (this.state.invitation.username !== "") { + this.form.current?.setFieldValue("username", this.state.invitation.username); + } + if (this.state.invitation.email !== "") { + this.form.current?.setFieldValue("email", this.state.invitation.email); + } + if (this.state.invitation.phone !== "") { + this.form.current?.setFieldValue("phone", this.state.invitation.phone); + } + if (this.state.invitationCode !== "") { + this.form.current?.setFieldValue("invitationCode", this.state.invitationCode); + } + } return (
res.json()); } +export function getInvitationCodeInfo(code, applicationName) { + return fetch(`${Setting.ServerUrl}/api/get-invitation-info?code=${code}&applicationId=${encodeURIComponent(applicationName)}`, { + method: "GET", + credentials: "include", + headers: { + "Accept-Language": Setting.getAcceptLanguage(), + }, + }).then(res => res.json()); +} + export function updateInvitation(owner, name, invitation) { const newInvitation = Setting.deepCopy(invitation); return fetch(`${Setting.ServerUrl}/api/update-invitation?id=${owner}/${encodeURIComponent(name)}`, { diff --git a/web/src/locales/ar/data.json b/web/src/locales/ar/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/ar/data.json +++ b/web/src/locales/ar/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/de/data.json b/web/src/locales/de/data.json index 1d6c2e0a..98e7f6f8 100644 --- a/web/src/locales/de/data.json +++ b/web/src/locales/de/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/en/data.json b/web/src/locales/en/data.json index d4dd6cfe..ca15f5c3 100644 --- a/web/src/locales/en/data.json +++ b/web/src/locales/en/data.json @@ -390,6 +390,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Can be a single string as an invitation code, or a regular expression. All strings matching the regular expression are valid invitation codes", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/es/data.json b/web/src/locales/es/data.json index 763a9392..6cd63c57 100644 --- a/web/src/locales/es/data.json +++ b/web/src/locales/es/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/fa/data.json b/web/src/locales/fa/data.json index 4b1e9a24..dd43f72c 100644 --- a/web/src/locales/fa/data.json +++ b/web/src/locales/fa/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/fi/data.json b/web/src/locales/fi/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/fi/data.json +++ b/web/src/locales/fi/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/fr/data.json b/web/src/locales/fr/data.json index 4f3b7303..31f1dfc1 100644 --- a/web/src/locales/fr/data.json +++ b/web/src/locales/fr/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/he/data.json b/web/src/locales/he/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/he/data.json +++ b/web/src/locales/he/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/id/data.json b/web/src/locales/id/data.json index 2fad5670..75b5ca9e 100644 --- a/web/src/locales/id/data.json +++ b/web/src/locales/id/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/it/data.json b/web/src/locales/it/data.json index 836b6e2e..ac4505f1 100644 --- a/web/src/locales/it/data.json +++ b/web/src/locales/it/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/ja/data.json b/web/src/locales/ja/data.json index 1b80c6dc..82566161 100644 --- a/web/src/locales/ja/data.json +++ b/web/src/locales/ja/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/kk/data.json b/web/src/locales/kk/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/kk/data.json +++ b/web/src/locales/kk/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/ko/data.json b/web/src/locales/ko/data.json index c74afb02..23ce6510 100644 --- a/web/src/locales/ko/data.json +++ b/web/src/locales/ko/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/ms/data.json b/web/src/locales/ms/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/ms/data.json +++ b/web/src/locales/ms/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/nl/data.json b/web/src/locales/nl/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/nl/data.json +++ b/web/src/locales/nl/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/pl/data.json b/web/src/locales/pl/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/pl/data.json +++ b/web/src/locales/pl/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/pt/data.json b/web/src/locales/pt/data.json index aeea946c..ab554381 100644 --- a/web/src/locales/pt/data.json +++ b/web/src/locales/pt/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/ru/data.json b/web/src/locales/ru/data.json index 3b07c37d..321a2938 100644 --- a/web/src/locales/ru/data.json +++ b/web/src/locales/ru/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/sv/data.json b/web/src/locales/sv/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/sv/data.json +++ b/web/src/locales/sv/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/tr/data.json b/web/src/locales/tr/data.json index 4ffd5540..8d94718b 100644 --- a/web/src/locales/tr/data.json +++ b/web/src/locales/tr/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/uk/data.json b/web/src/locales/uk/data.json index db75d74d..c7a68ddf 100644 --- a/web/src/locales/uk/data.json +++ b/web/src/locales/uk/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/vi/data.json b/web/src/locales/vi/data.json index 0a59cfc4..68e20a81 100644 --- a/web/src/locales/vi/data.json +++ b/web/src/locales/vi/data.json @@ -388,6 +388,8 @@ "invitation": { "Code": "Code", "Code - Tooltip": "Code - Tooltip", + "Default code": "Default code", + "Default code - Tooltip": "When the invitation code is a regular expression, please enter the invitation code that matches the regular expression rule as the default invitation code for the invitation link", "Edit Invitation": "Edit Invitation", "New Invitation": "New Invitation", "Quota": "Quota", diff --git a/web/src/locales/zh/data.json b/web/src/locales/zh/data.json index 288c76d6..59c9ad77 100644 --- a/web/src/locales/zh/data.json +++ b/web/src/locales/zh/data.json @@ -390,6 +390,8 @@ "invitation": { "Code": "邀请码", "Code - Tooltip": "可以是一个单独的字符串作为邀请码,也可以是正则表达式,所有符合正则表达式的字符串都是合法的邀请码", + "Default code": "默认邀请码", + "Default code - Tooltip": "当邀请码为正则表达式时,请输入符合正则表达式规则的邀请码作为邀请链接的默认邀请码", "Edit Invitation": "编辑邀请码", "New Invitation": "新建邀请码", "Quota": "配额",