import React, { useEffect, useState } from 'react'; import { Button, Divider, Form, Grid, Header, Modal, Message } from 'semantic-ui-react'; import { API, removeTrailingSlash, showError } from '../helpers'; const SystemSetting = () => { let [inputs, setInputs] = useState({ PasswordLoginEnabled: '', PasswordRegisterEnabled: '', EmailVerificationEnabled: '', GitHubOAuthEnabled: '', GitHubClientId: '', GitHubClientSecret: '', LarkClientId: '', LarkClientSecret: '', Notice: '', SMTPServer: '', SMTPPort: '', SMTPAccount: '', SMTPFrom: '', SMTPToken: '', ServerAddress: '', Footer: '', WeChatAuthEnabled: '', WeChatServerAddress: '', WeChatServerToken: '', WeChatAccountQRCodeImageURL: '', MessagePusherAddress: '', MessagePusherToken: '', TurnstileCheckEnabled: '', TurnstileSiteKey: '', TurnstileSecretKey: '', RegisterEnabled: '', EmailDomainRestrictionEnabled: '', EmailDomainWhitelist: '' }); const [originInputs, setOriginInputs] = useState({}); let [loading, setLoading] = useState(false); const [EmailDomainWhitelist, setEmailDomainWhitelist] = useState([]); const [restrictedDomainInput, setRestrictedDomainInput] = useState(''); const [showPasswordWarningModal, setShowPasswordWarningModal] = useState(false); const getOptions = async () => { const res = await API.get('/api/option/'); const { success, message, data } = res.data; if (success) { let newInputs = {}; data.forEach((item) => { newInputs[item.key] = item.value; }); setInputs({ ...newInputs, EmailDomainWhitelist: newInputs.EmailDomainWhitelist.split(',') }); setOriginInputs(newInputs); setEmailDomainWhitelist(newInputs.EmailDomainWhitelist.split(',').map((item) => { return { key: item, text: item, value: item }; })); } else { showError(message); } }; useEffect(() => { getOptions().then(); }, []); const updateOption = async (key, value) => { setLoading(true); switch (key) { case 'PasswordLoginEnabled': case 'PasswordRegisterEnabled': case 'EmailVerificationEnabled': case 'GitHubOAuthEnabled': case 'WeChatAuthEnabled': case 'TurnstileCheckEnabled': case 'EmailDomainRestrictionEnabled': case 'RegisterEnabled': value = inputs[key] === 'true' ? 'false' : 'true'; break; default: break; } const res = await API.put('/api/option/', { key, value }); const { success, message } = res.data; if (success) { if (key === 'EmailDomainWhitelist') { value = value.split(','); } setInputs((inputs) => ({ ...inputs, [key]: value })); } else { showError(message); } setLoading(false); }; const handleInputChange = async (e, { name, value }) => { if (name === 'PasswordLoginEnabled' && inputs[name] === 'true') { // block disabling password login setShowPasswordWarningModal(true); return; } if ( name === 'Notice' || name.startsWith('SMTP') || name === 'ServerAddress' || name === 'GitHubClientId' || name === 'GitHubClientSecret' || name === 'LarkClientId' || name === 'LarkClientSecret' || name === 'WeChatServerAddress' || name === 'WeChatServerToken' || name === 'WeChatAccountQRCodeImageURL' || name === 'TurnstileSiteKey' || name === 'TurnstileSecretKey' || name === 'EmailDomainWhitelist' ) { setInputs((inputs) => ({ ...inputs, [name]: value })); } else { await updateOption(name, value); } }; const submitServerAddress = async () => { let ServerAddress = removeTrailingSlash(inputs.ServerAddress); await updateOption('ServerAddress', ServerAddress); }; const submitSMTP = async () => { if (originInputs['SMTPServer'] !== inputs.SMTPServer) { await updateOption('SMTPServer', inputs.SMTPServer); } if (originInputs['SMTPAccount'] !== inputs.SMTPAccount) { await updateOption('SMTPAccount', inputs.SMTPAccount); } if (originInputs['SMTPFrom'] !== inputs.SMTPFrom) { await updateOption('SMTPFrom', inputs.SMTPFrom); } if ( originInputs['SMTPPort'] !== inputs.SMTPPort && inputs.SMTPPort !== '' ) { await updateOption('SMTPPort', inputs.SMTPPort); } if ( originInputs['SMTPToken'] !== inputs.SMTPToken && inputs.SMTPToken !== '' ) { await updateOption('SMTPToken', inputs.SMTPToken); } }; const submitEmailDomainWhitelist = async () => { if ( originInputs['EmailDomainWhitelist'] !== inputs.EmailDomainWhitelist.join(',') && inputs.SMTPToken !== '' ) { await updateOption('EmailDomainWhitelist', inputs.EmailDomainWhitelist.join(',')); } }; const submitWeChat = async () => { if (originInputs['WeChatServerAddress'] !== inputs.WeChatServerAddress) { await updateOption( 'WeChatServerAddress', removeTrailingSlash(inputs.WeChatServerAddress) ); } if ( originInputs['WeChatAccountQRCodeImageURL'] !== inputs.WeChatAccountQRCodeImageURL ) { await updateOption( 'WeChatAccountQRCodeImageURL', inputs.WeChatAccountQRCodeImageURL ); } if ( originInputs['WeChatServerToken'] !== inputs.WeChatServerToken && inputs.WeChatServerToken !== '' ) { await updateOption('WeChatServerToken', inputs.WeChatServerToken); } }; const submitMessagePusher = async () => { if (originInputs['MessagePusherAddress'] !== inputs.MessagePusherAddress) { await updateOption( 'MessagePusherAddress', removeTrailingSlash(inputs.MessagePusherAddress) ); } if ( originInputs['MessagePusherToken'] !== inputs.MessagePusherToken && inputs.MessagePusherToken !== '' ) { await updateOption('MessagePusherToken', inputs.MessagePusherToken); } }; const submitGitHubOAuth = async () => { if (originInputs['GitHubClientId'] !== inputs.GitHubClientId) { await updateOption('GitHubClientId', inputs.GitHubClientId); } if ( originInputs['GitHubClientSecret'] !== inputs.GitHubClientSecret && inputs.GitHubClientSecret !== '' ) { await updateOption('GitHubClientSecret', inputs.GitHubClientSecret); } }; const submitLarkOAuth = async () => { if (originInputs['LarkClientId'] !== inputs.LarkClientId) { await updateOption('LarkClientId', inputs.LarkClientId); } if ( originInputs['LarkClientSecret'] !== inputs.LarkClientSecret && inputs.LarkClientSecret !== '' ) { await updateOption('LarkClientSecret', inputs.LarkClientSecret); } }; const submitTurnstile = async () => { if (originInputs['TurnstileSiteKey'] !== inputs.TurnstileSiteKey) { await updateOption('TurnstileSiteKey', inputs.TurnstileSiteKey); } if ( originInputs['TurnstileSecretKey'] !== inputs.TurnstileSecretKey && inputs.TurnstileSecretKey !== '' ) { await updateOption('TurnstileSecretKey', inputs.TurnstileSecretKey); } }; const submitNewRestrictedDomain = () => { const localDomainList = inputs.EmailDomainWhitelist; if (restrictedDomainInput !== '' && !localDomainList.includes(restrictedDomainInput)) { setRestrictedDomainInput(''); setInputs({ ...inputs, EmailDomainWhitelist: [...localDomainList, restrictedDomainInput], }); setEmailDomainWhitelist([...EmailDomainWhitelist, { key: restrictedDomainInput, text: restrictedDomainInput, value: restrictedDomainInput, }]); } } return (
General Settings
Update Server Address
Configure Login/Registration
{ showPasswordWarningModal && setShowPasswordWarningModal(false)} size={'tiny'} style={{ maxWidth: '450px' }} > Warning

Canceling password login will cause all users (including administrators) who have not bound other login methods to be unable to log in via password, confirm cancel?

}
Configure Email Domain Whitelist To prevent malicious users from using temporary emails to sign up in bulk
{ submitNewRestrictedDomain(); }}>Add } onKeyDown={(e) => { if (e.key === 'Enter') { submitNewRestrictedDomain(); } }} autoComplete='new-password' placeholder='Enter new allowed email domain' value={restrictedDomainInput} onChange={(e, { value }) => { setRestrictedDomainInput(value); }} /> Save Email Domain Whitelist Settings
Configure SMTP To support the system email sending
Save SMTP Settings
Configure GitHub OAuth App To support login & registration via GitHub, Click here Manage your GitHub OAuth App
Fill in the Homepage URL {inputs.ServerAddress} , Fill in the Authorization callback URL{' '} {`${inputs.ServerAddress}/oauth/github`} Save GitHub OAuth Settings
Configure Lark OAuth To support login & registration via Lark, Click here Manage your Lark App
Fill in the Homepage URL {inputs.ServerAddress} , Fill in the Redirect URL{' '} {`${inputs.ServerAddress}/oauth/lark`} Save Lark OAuth Settings
Configure WeChat Server To support login & registration via WeChat, Click here Learn about WeChat Server
Save WeChat Server Settings
Configure Message Pusher To push alert messages, Click here Learn about Message Pusher
Save Message Pusher Settings
Configure Turnstile To support user verification, Click here Manage your Turnstile Sites, recommend selecting Invisible Widget Type
Save Turnstile Settings
); }; export default SystemSetting;