Skip to content

Commit bde08b9

Browse files
feat: add email regex validation for user registration (dreamhunter2333#835)
1 parent 56351ed commit bde08b9

6 files changed

Lines changed: 47 additions & 1 deletion

File tree

frontend/src/views/admin/UserSettings.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const { t } = useI18n({
2121
manualInputPrompt: 'Type and press Enter to add',
2222
mailAllowList: 'Mail Address Allow List',
2323
maxAddressCount: 'Maximum number of email addresses that can be binded',
24+
emailCheckRegex: 'Email Check Regex (e.g. ^[^.]+@.+$ to disallow dots before @)',
25+
enableEmailCheckRegex: 'Enable Email Check Regex',
2426
},
2527
zh: {
2628
save: '保存',
@@ -33,6 +35,8 @@ const { t } = useI18n({
3335
manualInputPrompt: '输入后按回车键添加',
3436
mailAllowList: '邮件地址白名单',
3537
maxAddressCount: '可绑定最大邮箱地址数量',
38+
emailCheckRegex: '邮箱正则校验 (例如 ^[^.]+@.+$ 禁止@前面有.)',
39+
enableEmailCheckRegex: '启用邮箱正则校验',
3640
}
3741
}
3842
});
@@ -53,6 +57,8 @@ const userSettings = ref({
5357
enableMailAllowList: false,
5458
mailAllowList: commonMail,
5559
maxAddressCount: 5,
60+
enableEmailCheckRegex: false,
61+
emailCheckRegex: "",
5662
});
5763
5864
const fetchData = async () => {
@@ -125,6 +131,16 @@ onMounted(async () => {
125131
:placeholder="t('maxAddressCount')" />
126132
</n-input-group>
127133
</n-form-item-row>
134+
<n-form-item-row :label="t('enableEmailCheckRegex')">
135+
<n-input-group>
136+
<n-checkbox v-model:checked="userSettings.enableEmailCheckRegex" style="width: 20%;">
137+
{{ t('enable') }}
138+
</n-checkbox>
139+
<n-input v-model:value="userSettings.emailCheckRegex"
140+
v-if="userSettings.enableEmailCheckRegex"
141+
style="width: 80%;" :placeholder="t('emailCheckRegex')" />
142+
</n-input-group>
143+
</n-form-item-row>
128144
</n-form>
129145
</n-card>
130146
</div>

worker/src/i18n/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const messages: LocaleMessages = {
2626
FailedToRegisterMsg: "Failed to register",
2727
UserRegistrationDisabledMsg: "User registration is disabled, please contact the administrator",
2828
UserMailDomainMustInMsg: "User mail domain must be in this list",
29+
UserEmailNotMatchRegexMsg: "Email address format does not match the required pattern",
2930
InvalidVerifyCodeMsg: "Invalid verify code",
3031
InvalidEmailOrPasswordMsg: "Invalid email or password",
3132
VerifyMailSenderNotSetMsg: "Verify mail sender address is not set, please contact the administrator",

worker/src/i18n/type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type LocaleMessages = {
2424
FailedToRegisterMsg: string
2525
UserRegistrationDisabledMsg: string
2626
UserMailDomainMustInMsg: string
27+
UserEmailNotMatchRegexMsg: string
2728
InvalidVerifyCodeMsg: string
2829
InvalidEmailOrPasswordMsg: string
2930
VerifyMailSenderNotSetMsg: string

worker/src/i18n/zh.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const messages: LocaleMessages = {
2626
FailedToRegisterMsg: "注册失败",
2727
UserRegistrationDisabledMsg: "用户注册已禁用, 请联系管理员",
2828
UserMailDomainMustInMsg: "用户邮箱域必须在此列表中",
29+
UserEmailNotMatchRegexMsg: "邮箱地址格式不符合要求",
2930
InvalidVerifyCodeMsg: "无效的验证码",
3031
InvalidEmailOrPasswordMsg: "无效的邮箱或密码",
3132
VerifyMailSenderNotSetMsg: "验证邮件发送邮箱未设置, 请联系管理员",

worker/src/models/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,18 +99,23 @@ export class UserSettings {
9999
enableMailAllowList: boolean | undefined;
100100
mailAllowList: string[] | undefined;
101101
maxAddressCount: number;
102+
enableEmailCheckRegex: boolean | undefined;
103+
emailCheckRegex: string | undefined;
102104

103105
constructor(data: UserSettings | undefined | null) {
104106
const {
105107
enable, enableMailVerify, verifyMailSender,
106-
enableMailAllowList, mailAllowList, maxAddressCount
108+
enableMailAllowList, mailAllowList, maxAddressCount,
109+
enableEmailCheckRegex, emailCheckRegex
107110
} = data || {};
108111
this.enable = enable;
109112
this.enableMailVerify = enableMailVerify;
110113
this.verifyMailSender = verifyMailSender;
111114
this.enableMailAllowList = enableMailAllowList;
112115
this.mailAllowList = mailAllowList;
113116
this.maxAddressCount = maxAddressCount || 5;
117+
this.enableEmailCheckRegex = enableEmailCheckRegex;
118+
this.emailCheckRegex = emailCheckRegex;
114119
}
115120
}
116121

worker/src/user_api/user.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ export default {
2727
) {
2828
return c.text(`${msgs.UserMailDomainMustInMsg} ${JSON.stringify(settings.mailAllowList, null, 2)}`, 400)
2929
}
30+
// check email regex
31+
if (settings.enableEmailCheckRegex && settings.emailCheckRegex) {
32+
try {
33+
const regex = new RegExp(settings.emailCheckRegex);
34+
if (!regex.test(email)) {
35+
return c.text(`${msgs.UserEmailNotMatchRegexMsg}: /${settings.emailCheckRegex}/`, 400)
36+
}
37+
} catch (e) {
38+
console.error("Failed to check user email regex", e);
39+
}
40+
}
3041
if (!settings.verifyMailSender) {
3142
return c.text(msgs.VerifyMailSenderNotSetMsg, 400)
3243
}
@@ -82,6 +93,17 @@ export default {
8293
) {
8394
return c.text(`${msgs.UserMailDomainMustInMsg} ${JSON.stringify(settings.mailAllowList, null, 2)}`, 400)
8495
}
96+
// check email regex
97+
if (settings.enableEmailCheckRegex && settings.emailCheckRegex) {
98+
try {
99+
const regex = new RegExp(settings.emailCheckRegex);
100+
if (!regex.test(email)) {
101+
return c.text(`${msgs.UserEmailNotMatchRegexMsg}: /${settings.emailCheckRegex}/`, 400)
102+
}
103+
} catch (e) {
104+
console.error("Failed to check user email regex", e);
105+
}
106+
}
85107
// check code
86108
if (settings.enableMailVerify) {
87109
const verifyCode = await c.env.KV.get(`temp-mail:${email}`)

0 commit comments

Comments
 (0)