feat(address): 支持最大地址数量设置为 0 表示无限制 (#968)

* feat(address): 支持最大地址数量设置为 0 表示无限制

- 移除角色配置中 =0 时回退到全局设置的逻辑
- 添加负数校验防止无效输入
- 更新前端文案说明 0 表示无限制

* fix(admin): 修复 maxAddressCount 验证逻辑,禁止负数和非对象输入

在 saveRoleAddressConfig 接口增加 configs 参数类型校验,
确保其为有效对象而非数组或 null。同时在 UserSettings 模型中
验证 maxAddressCount 必须大于等于 0,防止无效数据进入系统。

* style: 修正错误的缩进
This commit is contained in:
YewFence
2026-04-09 17:04:58 +08:00
committed by GitHub
parent 873a10ddb1
commit 1cafbbf220
5 changed files with 17 additions and 8 deletions

View File

@@ -13,20 +13,20 @@ const { t } = useI18n({
messages: {
en: {
role: 'Role',
maxAddressCount: 'Max Address Count',
maxAddressCount: 'Max Address Count (0 = Unlimited)',
save: 'Save',
successTip: 'Success',
noRolesAvailable: 'No roles available in system config',
roleConfigDesc: 'Configure maximum address count for each user role. Role-based limits take priority over global settings.',
roleConfigDesc: 'Configure maximum address count for each user role. Role-based limits take priority over global settings. Set 0 for unlimited.',
notConfigured: 'Not Configured (Use Global Settings)',
},
zh: {
role: '角色',
maxAddressCount: '最大地址数量',
maxAddressCount: '最大地址数量0 为不限制)',
save: '保存',
successTip: '成功',
noRolesAvailable: '系统配置中没有可用的角色',
roleConfigDesc: '为每个用户角色配置最大地址数量。角色配置优先于全局设置。',
roleConfigDesc: '为每个用户角色配置最大地址数量。角色配置优先于全局设置。设置为 0 表示不限制。',
notConfigured: '未配置(使用全局设置)',
}
}

View File

@@ -20,7 +20,7 @@ const { t } = useI18n({
enableMailAllowList: 'Enable Mail Address Allow List(Manually enterable)',
manualInputPrompt: 'Type and press Enter to add',
mailAllowList: 'Mail Address Allow List',
maxAddressCount: 'Maximum number of email addresses that can be binded',
maxAddressCount: 'Maximum number of email addresses that can be binded (0 = Unlimited)',
emailCheckRegex: "Email Check Regex (e.g. ^[^.]+{'@'}.+$ to disallow dots before {'@'})",
enableEmailCheckRegex: 'Enable Email Check Regex',
},
@@ -34,7 +34,7 @@ const { t } = useI18n({
enableMailAllowList: '启用邮件地址白名单(可手动输入, 回车增加)',
manualInputPrompt: '输入后按回车键添加',
mailAllowList: '邮件地址白名单',
maxAddressCount: '可绑定最大邮箱地址数量',
maxAddressCount: '可绑定最大邮箱地址数量0 为不限制)',
emailCheckRegex: "邮箱正则校验 (例如 ^[^.]+{'@'}.+$ 禁止{'@'}前面有.)",
enableEmailCheckRegex: '启用邮箱正则校验',
}

View File

@@ -181,7 +181,16 @@ export default {
return c.json({ configs });
},
saveRoleAddressConfig: async (c: Context<HonoCustomType>) => {
const msgs = i18n.getMessagesbyContext(c);
const { configs } = await c.req.json<{ configs: RoleAddressConfig }>();
if (typeof configs !== "object" || configs === null || Array.isArray(configs)) {
return c.text(msgs.InvalidMaxAddressCountMsg, 400);
}
for (const config of Object.values(configs)) {
if (typeof config?.maxAddressCount === "number" && config.maxAddressCount < 0) {
return c.text(msgs.InvalidMaxAddressCountMsg, 400);
}
}
await saveSetting(c, CONSTANTS.ROLE_ADDRESS_CONFIG_KEY, JSON.stringify(configs));
return c.json({ success: true });
},

View File

@@ -113,7 +113,7 @@ export class UserSettings {
this.verifyMailSender = verifyMailSender;
this.enableMailAllowList = enableMailAllowList;
this.mailAllowList = mailAllowList;
this.maxAddressCount = maxAddressCount || 5;
this.maxAddressCount = (typeof maxAddressCount === "number" && maxAddressCount >= 0) ? maxAddressCount : 5;
this.enableEmailCheckRegex = enableEmailCheckRegex;
this.emailCheckRegex = emailCheckRegex;
}

View File

@@ -366,7 +366,7 @@ export const getMaxAddressCount = async (
if (!roleConfigs) return settings.maxAddressCount;
const roleMaxCount = roleConfigs[userRole]?.maxAddressCount;
if (typeof roleMaxCount !== 'number') return settings.maxAddressCount;
if (roleMaxCount <= 0) return settings.maxAddressCount;
if (roleMaxCount < 0) return settings.maxAddressCount;
return roleMaxCount;
};