feat: 关联 discord 账号
This commit is contained in:
@@ -52,6 +52,9 @@ const SystemSetting = () => {
|
||||
GitHubOAuthEnabled: '',
|
||||
GitHubClientId: '',
|
||||
GitHubClientSecret: '',
|
||||
DiscordOAuthEnabled: '',
|
||||
DiscordClientId: '',
|
||||
DiscordClientSecret: '',
|
||||
'oidc.enabled': '',
|
||||
'oidc.client_id': '',
|
||||
'oidc.client_secret': '',
|
||||
@@ -179,6 +182,7 @@ const SystemSetting = () => {
|
||||
case 'EmailAliasRestrictionEnabled':
|
||||
case 'SMTPSSLEnabled':
|
||||
case 'LinuxDOOAuthEnabled':
|
||||
case 'DiscordOAuthEnabled':
|
||||
case 'oidc.enabled':
|
||||
case 'passkey.enabled':
|
||||
case 'passkey.allow_insecure_origin':
|
||||
@@ -473,6 +477,27 @@ const SystemSetting = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const submitDiscordOAuth = async () => {
|
||||
const options = [];
|
||||
|
||||
if (originInputs['DiscordClientId'] !== inputs.DiscordClientId) {
|
||||
options.push({ key: 'DiscordClientId', value: inputs.DiscordClientId });
|
||||
}
|
||||
if (
|
||||
originInputs['DiscordClientSecret'] !== inputs.DiscordClientSecret &&
|
||||
inputs.DiscordClientSecret !== ''
|
||||
) {
|
||||
options.push({
|
||||
key: 'DiscordClientSecret',
|
||||
value: inputs.DiscordClientSecret,
|
||||
});
|
||||
}
|
||||
|
||||
if (options.length > 0) {
|
||||
await updateOptions(options);
|
||||
}
|
||||
};
|
||||
|
||||
const submitOIDCSettings = async () => {
|
||||
if (inputs['oidc.well_known'] && inputs['oidc.well_known'] !== '') {
|
||||
if (
|
||||
@@ -1014,6 +1039,15 @@ const SystemSetting = () => {
|
||||
>
|
||||
{t('允许通过 GitHub 账户登录 & 注册')}
|
||||
</Form.Checkbox>
|
||||
<Form.Checkbox
|
||||
field='DiscordOAuthEnabled'
|
||||
noLabel
|
||||
onChange={(e) =>
|
||||
handleCheckboxChange('DiscordOAuthEnabled', e)
|
||||
}
|
||||
>
|
||||
{t('允许通过 Discord 账户登录 & 注册')}
|
||||
</Form.Checkbox>
|
||||
<Form.Checkbox
|
||||
field='LinuxDOOAuthEnabled'
|
||||
noLabel
|
||||
@@ -1410,6 +1444,37 @@ const SystemSetting = () => {
|
||||
</Button>
|
||||
</Form.Section>
|
||||
</Card>
|
||||
<Card>
|
||||
<Form.Section text={t('配置 Discord OAuth')}>
|
||||
<Text>{t('用以支持通过 Discord 进行登录注册')}</Text>
|
||||
<Banner
|
||||
type='info'
|
||||
description={`${t('Homepage URL 填')} ${inputs.ServerAddress ? inputs.ServerAddress : t('网站地址')},${t('Authorization callback URL 填')} ${inputs.ServerAddress ? inputs.ServerAddress : t('网站地址')}/oauth/discord`}
|
||||
style={{ marginBottom: 20, marginTop: 16 }}
|
||||
/>
|
||||
<Row
|
||||
gutter={{ xs: 8, sm: 16, md: 24, lg: 24, xl: 24, xxl: 24 }}
|
||||
>
|
||||
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
||||
<Form.Input
|
||||
field='DiscordClientId'
|
||||
label={t('Discord Client ID')}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={24} sm={24} md={12} lg={12} xl={12}>
|
||||
<Form.Input
|
||||
field='DiscordClientSecret'
|
||||
label={t('Discord Client Secret')}
|
||||
type='password'
|
||||
placeholder={t('敏感信息不会发送到前端显示')}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Button onClick={submitDiscordOAuth}>
|
||||
{t('保存 Discord OAuth 设置')}
|
||||
</Button>
|
||||
</Form.Section>
|
||||
</Card>
|
||||
<Card>
|
||||
<Form.Section text={t('配置 Linux DO OAuth')}>
|
||||
<Text>
|
||||
|
||||
@@ -38,13 +38,14 @@ import {
|
||||
IconLock,
|
||||
IconDelete,
|
||||
} from '@douyinfe/semi-icons';
|
||||
import { SiTelegram, SiWechat, SiLinux } from 'react-icons/si';
|
||||
import { SiTelegram, SiWechat, SiLinux, SiDiscord } from 'react-icons/si';
|
||||
import { UserPlus, ShieldCheck } from 'lucide-react';
|
||||
import TelegramLoginButton from 'react-telegram-login';
|
||||
import {
|
||||
onGitHubOAuthClicked,
|
||||
onOIDCClicked,
|
||||
onLinuxDOOAuthClicked,
|
||||
onDiscordOAuthClicked,
|
||||
} from '../../../../helpers';
|
||||
import TwoFASetting from '../components/TwoFASetting';
|
||||
|
||||
@@ -247,6 +248,47 @@ const AccountManagement = ({
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Discord绑定 */}
|
||||
<Card className='!rounded-xl'>
|
||||
<div className='flex items-center justify-between gap-3'>
|
||||
<div className='flex items-center flex-1 min-w-0'>
|
||||
<div className='w-10 h-10 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-3 flex-shrink-0'>
|
||||
<SiDiscord
|
||||
size={20}
|
||||
className='text-slate-600 dark:text-slate-300'
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-1 min-w-0'>
|
||||
<div className='font-medium text-gray-900'>
|
||||
{t('Discord')}
|
||||
</div>
|
||||
<div className='text-sm text-gray-500 truncate'>
|
||||
{renderAccountInfo(
|
||||
userState.user?.discord_id,
|
||||
t('Discord ID'),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-shrink-0'>
|
||||
<Button
|
||||
type='primary'
|
||||
theme='outline'
|
||||
size='small'
|
||||
onClick={() =>
|
||||
onDiscordOAuthClicked(status.discord_client_id)
|
||||
}
|
||||
disabled={
|
||||
isBound(userState.user?.discord_id) ||
|
||||
!status.discord_oauth
|
||||
}
|
||||
>
|
||||
{status.discord_oauth ? t('绑定') : t('未启用')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* OIDC绑定 */}
|
||||
<Card className='!rounded-xl'>
|
||||
<div className='flex items-center justify-between gap-3'>
|
||||
|
||||
Reference in New Issue
Block a user