|
|
@@ -122,7 +122,6 @@ const SystemSetting = () => {
|
|
|
const [domainList, setDomainList] = useState([]);
|
|
|
const [ipList, setIpList] = useState([]);
|
|
|
const [allowedPorts, setAllowedPorts] = useState([]);
|
|
|
- const [passkeyOrigins, setPasskeyOrigins] = useState([]);
|
|
|
|
|
|
const getOptions = async () => {
|
|
|
setLoading(true);
|
|
|
@@ -188,22 +187,19 @@ const SystemSetting = () => {
|
|
|
item.value = toBoolean(item.value);
|
|
|
break;
|
|
|
case 'passkey.origins':
|
|
|
- try {
|
|
|
- const origins = item.value ? JSON.parse(item.value) : [];
|
|
|
- setPasskeyOrigins(Array.isArray(origins) ? origins : []);
|
|
|
- item.value = Array.isArray(origins) ? origins : [];
|
|
|
- } catch (e) {
|
|
|
- setPasskeyOrigins([]);
|
|
|
- item.value = [];
|
|
|
- }
|
|
|
+ // origins是逗号分隔的字符串,直接使用
|
|
|
+ item.value = item.value || '';
|
|
|
break;
|
|
|
case 'passkey.rp_display_name':
|
|
|
case 'passkey.rp_id':
|
|
|
- case 'passkey.user_verification':
|
|
|
case 'passkey.attachment_preference':
|
|
|
// 确保字符串字段不为null/undefined
|
|
|
item.value = item.value || '';
|
|
|
break;
|
|
|
+ case 'passkey.user_verification':
|
|
|
+ // 确保有默认值
|
|
|
+ item.value = item.value || 'preferred';
|
|
|
+ break;
|
|
|
case 'Price':
|
|
|
case 'MinTopUp':
|
|
|
item.value = parseFloat(item.value);
|
|
|
@@ -611,42 +607,33 @@ const SystemSetting = () => {
|
|
|
};
|
|
|
|
|
|
const submitPasskeySettings = async () => {
|
|
|
+ // 使用formApi直接获取当前表单值
|
|
|
+ const formValues = formApiRef.current?.getValues() || {};
|
|
|
+
|
|
|
const options = [];
|
|
|
|
|
|
- // 只在值有变化时才提交,并确保空值转换为空字符串
|
|
|
- if (originInputs['passkey.rp_display_name'] !== inputs['passkey.rp_display_name']) {
|
|
|
- options.push({
|
|
|
- key: 'passkey.rp_display_name',
|
|
|
- value: inputs['passkey.rp_display_name'] || '',
|
|
|
- });
|
|
|
- }
|
|
|
- if (originInputs['passkey.rp_id'] !== inputs['passkey.rp_id']) {
|
|
|
- options.push({
|
|
|
- key: 'passkey.rp_id',
|
|
|
- value: inputs['passkey.rp_id'] || '',
|
|
|
- });
|
|
|
- }
|
|
|
- if (originInputs['passkey.user_verification'] !== inputs['passkey.user_verification']) {
|
|
|
- options.push({
|
|
|
- key: 'passkey.user_verification',
|
|
|
- value: inputs['passkey.user_verification'] || 'preferred',
|
|
|
- });
|
|
|
- }
|
|
|
- if (originInputs['passkey.attachment_preference'] !== inputs['passkey.attachment_preference']) {
|
|
|
- options.push({
|
|
|
- key: 'passkey.attachment_preference',
|
|
|
- value: inputs['passkey.attachment_preference'] || '',
|
|
|
- });
|
|
|
- }
|
|
|
- // Origins总是提交,因为它们可能会被用户清空
|
|
|
+ options.push({
|
|
|
+ key: 'passkey.rp_display_name',
|
|
|
+ value: formValues['passkey.rp_display_name'] || inputs['passkey.rp_display_name'] || '',
|
|
|
+ });
|
|
|
+ options.push({
|
|
|
+ key: 'passkey.rp_id',
|
|
|
+ value: formValues['passkey.rp_id'] || inputs['passkey.rp_id'] || '',
|
|
|
+ });
|
|
|
+ options.push({
|
|
|
+ key: 'passkey.user_verification',
|
|
|
+ value: formValues['passkey.user_verification'] || inputs['passkey.user_verification'] || 'preferred',
|
|
|
+ });
|
|
|
+ options.push({
|
|
|
+ key: 'passkey.attachment_preference',
|
|
|
+ value: formValues['passkey.attachment_preference'] || inputs['passkey.attachment_preference'] || '',
|
|
|
+ });
|
|
|
options.push({
|
|
|
key: 'passkey.origins',
|
|
|
- value: JSON.stringify(Array.isArray(passkeyOrigins) ? passkeyOrigins : []),
|
|
|
+ value: formValues['passkey.origins'] || inputs['passkey.origins'] || '',
|
|
|
});
|
|
|
|
|
|
- if (options.length > 0) {
|
|
|
- await updateOptions(options);
|
|
|
- }
|
|
|
+ await updateOptions(options);
|
|
|
};
|
|
|
|
|
|
const handleCheckboxChange = async (optionKey, event) => {
|
|
|
@@ -1037,7 +1024,7 @@ const SystemSetting = () => {
|
|
|
>
|
|
|
<Col xs={24} sm={24} md={24} lg={24} xl={24}>
|
|
|
<Form.Checkbox
|
|
|
- field='passkey.enabled'
|
|
|
+ field="['passkey.enabled']"
|
|
|
noLabel
|
|
|
onChange={(e) =>
|
|
|
handleCheckboxChange('passkey.enabled', e)
|
|
|
@@ -1052,7 +1039,7 @@ const SystemSetting = () => {
|
|
|
>
|
|
|
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
|
|
<Form.Input
|
|
|
- field='passkey.rp_display_name'
|
|
|
+ field="['passkey.rp_display_name']"
|
|
|
label={t('服务显示名称')}
|
|
|
placeholder={t('默认使用系统名称')}
|
|
|
extraText={t('用户注册时看到的网站名称,比如\'我的网站\'')}
|
|
|
@@ -1060,7 +1047,7 @@ const SystemSetting = () => {
|
|
|
</Col>
|
|
|
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
|
|
<Form.Input
|
|
|
- field='passkey.rp_id'
|
|
|
+ field="['passkey.rp_id']"
|
|
|
label={t('网站域名标识')}
|
|
|
placeholder={t('例如:example.com')}
|
|
|
extraText={t('留空自动使用当前域名')}
|
|
|
@@ -1073,7 +1060,7 @@ const SystemSetting = () => {
|
|
|
>
|
|
|
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
|
|
<Form.Select
|
|
|
- field='passkey.user_verification'
|
|
|
+ field="['passkey.user_verification']"
|
|
|
label={t('安全验证级别')}
|
|
|
placeholder={t('是否要求指纹/面容等生物识别')}
|
|
|
optionList={[
|
|
|
@@ -1086,7 +1073,7 @@ const SystemSetting = () => {
|
|
|
</Col>
|
|
|
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
|
|
<Form.Select
|
|
|
- field='passkey.attachment_preference'
|
|
|
+ field="['passkey.attachment_preference']"
|
|
|
label={t('设备类型偏好')}
|
|
|
placeholder={t('选择支持的认证设备类型')}
|
|
|
optionList={[
|
|
|
@@ -1104,7 +1091,7 @@ const SystemSetting = () => {
|
|
|
>
|
|
|
<Col xs={24} sm={24} md={24} lg={24} xl={24}>
|
|
|
<Form.Checkbox
|
|
|
- field='passkey.allow_insecure_origin'
|
|
|
+ field="['passkey.allow_insecure_origin']"
|
|
|
noLabel
|
|
|
extraText={t('仅用于开发环境,生产环境应使用 HTTPS')}
|
|
|
onChange={(e) =>
|
|
|
@@ -1120,21 +1107,11 @@ const SystemSetting = () => {
|
|
|
style={{ marginTop: 16 }}
|
|
|
>
|
|
|
<Col xs={24} sm={24} md={24} lg={24} xl={24}>
|
|
|
- <Text strong>{t('允许的 Origins')}</Text>
|
|
|
- <Text type="secondary" style={{ display: 'block', marginBottom: 8 }}>
|
|
|
- {t('留空将自动使用服务器地址,多个 Origin 用于支持多域名部署')}
|
|
|
- </Text>
|
|
|
- <TagInput
|
|
|
- value={passkeyOrigins}
|
|
|
- onChange={(value) => {
|
|
|
- setPasskeyOrigins(value);
|
|
|
- setInputs(prev => ({
|
|
|
- ...prev,
|
|
|
- 'passkey.origins': value
|
|
|
- }));
|
|
|
- }}
|
|
|
- placeholder={t('输入 Origin 后回车,如:https://example.com')}
|
|
|
- style={{ width: '100%' }}
|
|
|
+ <Form.Input
|
|
|
+ field="['passkey.origins']"
|
|
|
+ label={t('允许的 Origins')}
|
|
|
+ placeholder={t('填写带https的域名,逗号分隔')}
|
|
|
+ extraText={t('空的话则不限制 Origin,多个 Origin 用逗号分隔')}
|
|
|
/>
|
|
|
</Col>
|
|
|
</Row>
|