diff --git a/makefile b/makefile
index 603f5aa..1e8ab1b 100644
--- a/makefile
+++ b/makefile
@@ -1,7 +1,7 @@
FRONTEND_DIR = ./web
BACKEND_DIR = .
-.PHONY: all start-frontend start-backend
+.PHONY: all build-frontend start-backend
all: start-frontend start-backend
@@ -9,12 +9,6 @@ build-frontend:
@echo "Building frontend..."
@cd $(FRONTEND_DIR) && npm install && DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat VERSION) npm run build npm run build
-# 启动前端开发服务器
-start-frontend:
- @echo "Starting frontend dev server..."
- @cd $(FRONTEND_DIR) && npm start &
-
-# 启动后端开发服务器
start-backend:
@echo "Starting backend dev server..."
@cd $(BACKEND_DIR) && go run main.go &
diff --git a/model/user.go b/model/user.go
index 3e727a0..7b70bfe 100644
--- a/model/user.go
+++ b/model/user.go
@@ -3,10 +3,11 @@ package model
import (
"errors"
"fmt"
- "gorm.io/gorm"
"one-api/common"
"strings"
"time"
+
+ "gorm.io/gorm"
)
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
@@ -21,6 +22,7 @@ type User struct {
Email string `json:"email" gorm:"index" validate:"max=50"`
GitHubId string `json:"github_id" gorm:"column:github_id;index"`
WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"`
+ TelegramId string `json:"telegram_id" gorm:"column:telegram_id;index"`
VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database!
AccessToken string `json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management
Quota int `json:"quota" gorm:"type:int;default:0"`
diff --git a/web/src/components/LoginForm.js b/web/src/components/LoginForm.js
index 03aec65..ec49ece 100644
--- a/web/src/components/LoginForm.js
+++ b/web/src/components/LoginForm.js
@@ -1,14 +1,14 @@
-import React, {useContext, useEffect, useState} from 'react';
-import {Link, useNavigate, useSearchParams} from 'react-router-dom';
-import {UserContext} from '../context/User';
-import {API, getLogo, isMobile, showError, showInfo, showSuccess, showWarning} from '../helpers';
-import {onGitHubOAuthClicked} from './utils';
+import React, { useContext, useEffect, useState } from 'react';
+import { Link, useNavigate, useSearchParams } from 'react-router-dom';
+import { UserContext } from '../context/User';
+import { API, getLogo, isMobile, showError, showInfo, showSuccess, showWarning } from '../helpers';
+import { onGitHubOAuthClicked } from './utils';
import Turnstile from "react-turnstile";
-import {Layout, Card, Image, Form, Button, Divider, Modal} from "@douyinfe/semi-ui";
+import { Layout, Card, Image, Form, Button, Divider, Modal } from "@douyinfe/semi-ui";
import Title from "@douyinfe/semi-ui/lib/es/typography/title";
import Text from "@douyinfe/semi-ui/lib/es/typography/text";
-import {IconGithubLogo} from '@douyinfe/semi-icons';
+import { IconGithubLogo } from '@douyinfe/semi-icons';
const LoginForm = () => {
const [inputs, setInputs] = useState({
@@ -18,7 +18,7 @@ const LoginForm = () => {
});
const [searchParams, setSearchParams] = useSearchParams();
const [submitted, setSubmitted] = useState(false);
- const {username, password} = inputs;
+ const { username, password } = inputs;
const [userState, userDispatch] = useContext(UserContext);
const [turnstileEnabled, setTurnstileEnabled] = useState(false);
const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
@@ -56,9 +56,9 @@ const LoginForm = () => {
const res = await API.get(
`/api/oauth/wechat?code=${inputs.wechat_verification_code}`
);
- const {success, message, data} = res.data;
+ const { success, message, data } = res.data;
if (success) {
- userDispatch({type: 'login', payload: data});
+ userDispatch({ type: 'login', payload: data });
localStorage.setItem('user', JSON.stringify(data));
navigate('/');
showSuccess('登录成功!');
@@ -69,7 +69,7 @@ const LoginForm = () => {
};
function handleChange(name, value) {
- setInputs((inputs) => ({...inputs, [name]: value}));
+ setInputs((inputs) => ({ ...inputs, [name]: value }));
}
async function handleSubmit(e) {
@@ -83,13 +83,13 @@ const LoginForm = () => {
username,
password
});
- const {success, message, data} = res.data;
+ const { success, message, data } = res.data;
if (success) {
- userDispatch({type: 'login', payload: data});
+ userDispatch({ type: 'login', payload: data });
localStorage.setItem('user', JSON.stringify(data));
showSuccess('登录成功!');
if (username === 'root' && password === '123456') {
- Modal.error({title: '您正在使用默认密码!', content: '请立刻修改默认密码!', centered: true});
+ Modal.error({ title: '您正在使用默认密码!', content: '请立刻修改默认密码!', centered: true });
}
navigate('/token');
} else {
@@ -100,16 +100,23 @@ const LoginForm = () => {
}
}
+ // 添加Telegram登录处理函数
+ const onTelegramLoginClicked = async () => {
+ // 这里调用后端API进行Telegram登录
+ // 例如: const res = await API.get(`/api/oauth/telegram`);
+ // 根据响应处理登录逻辑
+ };
+
return (
-
-
+
+
-
+
用户登录
-
+
没有账号请先 注册账号
@@ -142,16 +149,16 @@ const LoginForm = () => {
忘记密码 点击重置
- {status.github_oauth || status.wechat_login ? (
+ {status.github_oauth || status.wechat_login || status.telegram_oauth ? (
<>
第三方登录
-
+
{status.github_oauth ? (
>
) : (
@@ -208,7 +227,7 @@ const LoginForm = () => {
{/**/}
{turnstileEnabled ? (
-
+
{
diff --git a/web/src/components/PersonalSetting.js b/web/src/components/PersonalSetting.js
index 78d3240..3c67a3f 100644
--- a/web/src/components/PersonalSetting.js
+++ b/web/src/components/PersonalSetting.js
@@ -443,6 +443,27 @@ const PersonalSetting = () => {
+
+
Telegram
+
+
+
+
+
+
+ {
+ status.github_oauth?'绑定':'未启用'
+ }
+
+
+
+
+
生成系统访问令牌
diff --git a/web/src/components/SystemSetting.js b/web/src/components/SystemSetting.js
index f5d87be..436cc67 100644
--- a/web/src/components/SystemSetting.js
+++ b/web/src/components/SystemSetting.js
@@ -34,7 +34,7 @@ const SystemSetting = () => {
EmailDomainRestrictionEnabled: '',
EmailDomainWhitelist: '',
// telegram login
- TelegramLoginEnabled: '',
+ TelegramOAuthEnabled: '',
TelegramBotToken: '',
TelegramBotName: '',
});
@@ -81,7 +81,7 @@ const SystemSetting = () => {
case 'EmailVerificationEnabled':
case 'GitHubOAuthEnabled':
case 'WeChatAuthEnabled':
- case 'TelegramLoginEnabled':
+ case 'TelegramOAuthEnabled':
case 'TurnstileCheckEnabled':
case 'EmailDomainRestrictionEnabled':
case 'RegisterEnabled':
@@ -240,7 +240,7 @@ const SystemSetting = () => {
};
const submitTelegramSettings = async () => {
- await updateOption('TelegramLoginEnabled', inputs.TelegramLoginEnabled);
+ await updateOption('TelegramOAuthEnabled', inputs.TelegramOAuthEnabled);
await updateOption('TelegramBotToken', inputs.TelegramBotToken);
await updateOption('TelegramBotName', inputs.TelegramBotName);
};
@@ -397,6 +397,12 @@ const SystemSetting = () => {
name='WeChatAuthEnabled'
onChange={handleInputChange}
/>
+
{
-
diff --git a/web/src/pages/User/EditUser.js b/web/src/pages/User/EditUser.js
index 705f7a2..6d79127 100644
--- a/web/src/pages/User/EditUser.js
+++ b/web/src/pages/User/EditUser.js
@@ -1,9 +1,9 @@
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
-import {API, isMobile, showError, showSuccess} from '../../helpers';
+import { API, isMobile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
import Title from "@douyinfe/semi-ui/lib/es/typography/title";
-import {SideSheet, Space, Button, Spin, Input, Typography, Select, Divider} from "@douyinfe/semi-ui";
+import { SideSheet, Space, Button, Spin, Input, Typography, Select, Divider } from "@douyinfe/semi-ui";
const EditUser = (props) => {
const userId = props.editingUser.id;
@@ -19,8 +19,8 @@ const EditUser = (props) => {
group: 'default'
});
const [groupOptions, setGroupOptions] = useState([]);
- const { username, display_name, password, github_id, wechat_id, email, quota, group } =
- inputs;
+ const { username, display_name, password, github_id, wechat_id, telegram_id, email, quota, group } =
+ inputs;
const handleInputChange = (name, value) => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
};
@@ -88,126 +88,132 @@ const EditUser = (props) => {
};
return (
- <>
- {'编辑用户'}}
- headerStyle={{borderBottom: '1px solid var(--semi-color-border)'}}
- bodyStyle={{borderBottom: '1px solid var(--semi-color-border)'}}
- visible={props.visible}
- footer={
-
-
- 提交
- 取消
-
+ <>
+
{'编辑用户'}}
+ headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
+ bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
+ visible={props.visible}
+ footer={
+
+
+ 提交
+ 取消
+
+
+ }
+ closeIcon={null}
+ onCancel={() => handleCancel()}
+ width={isMobile() ? '100%' : 600}
+ >
+
+
+ 用户名
+
+ handleInputChange('username', value)}
+ value={username}
+ autoComplete='new-password'
+ />
+
+ 密码
+
+ handleInputChange('password', value)}
+ value={password}
+ autoComplete='new-password'
+ />
+
+ 显示名称
+
+ handleInputChange('display_name', value)}
+ value={display_name}
+ autoComplete='new-password'
+ />
+ {
+ userId && <>
+
+ 分组
- }
- closeIcon={null}
- onCancel={() => handleCancel()}
- width={isMobile() ? '100%' : 600}
- >
-
-
- 用户名
-
- handleInputChange('username', value)}
- value={username}
+
-
-
- >
+ />
+ >
+ }
+
以下信息不可修改
+
+ 已绑定的 GitHub 账户
+
+
+
+ 已绑定的微信账户
+
+
+
+
+ 已绑定的邮箱账户
+
+
+
+
+ >
);
};