Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
1ca78291
authored
Mar 01, 2024
by
Ehco1996
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update makefile and user model, add Telegram integration
parent
a9d3c59e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
77 additions
and
43 deletions
+77
-43
makefile
+1
-7
model/user.go
+3
-1
web/src/components/LoginForm.js
+43
-24
web/src/components/PersonalSetting.js
+21
-0
web/src/components/SystemSetting.js
+9
-11
web/src/pages/User/EditUser.js
+0
-0
No files found.
makefile
View file @
1ca78291
FRONTEND_DIR
=
./web
FRONTEND_DIR
=
./web
BACKEND_DIR
=
.
BACKEND_DIR
=
.
.PHONY
:
all
start
-frontend start-backend
.PHONY
:
all
build
-frontend start-backend
all
:
start-frontend start-backend
all
:
start-frontend start-backend
...
@@ -9,12 +9,6 @@ build-frontend:
...
@@ -9,12 +9,6 @@ build-frontend:
@
echo
"Building frontend..."
@
echo
"Building frontend..."
@
cd
$(FRONTEND_DIR)
&&
npm install
&&
DISABLE_ESLINT_PLUGIN
=
'true'
REACT_APP_VERSION
=
$
(
cat
VERSION
)
npm run build npm run build
@
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
:
start-backend
:
@
echo
"Starting backend dev server..."
@
echo
"Starting backend dev server..."
@
cd
$(BACKEND_DIR)
&&
go run main.go &
@
cd
$(BACKEND_DIR)
&&
go run main.go &
...
...
model/user.go
View file @
1ca78291
...
@@ -3,10 +3,11 @@ package model
...
@@ -3,10 +3,11 @@ package model
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"gorm.io/gorm"
"one-api/common"
"one-api/common"
"strings"
"strings"
"time"
"time"
"gorm.io/gorm"
)
)
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
...
@@ -21,6 +22,7 @@ type User struct {
...
@@ -21,6 +22,7 @@ type User struct {
Email
string
`json:"email" gorm:"index" validate:"max=50"`
Email
string
`json:"email" gorm:"index" validate:"max=50"`
GitHubId
string
`json:"github_id" gorm:"column:github_id;index"`
GitHubId
string
`json:"github_id" gorm:"column:github_id;index"`
WeChatId
string
`json:"wechat_id" gorm:"column:wechat_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!
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
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"`
Quota
int
`json:"quota" gorm:"type:int;default:0"`
...
...
web/src/components/LoginForm.js
View file @
1ca78291
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'react'
;
import
{
Link
,
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
Link
,
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
UserContext
}
from
'../context/User'
;
import
{
UserContext
}
from
'../context/User'
;
import
{
API
,
getLogo
,
isMobile
,
showError
,
showInfo
,
showSuccess
,
showWarning
}
from
'../helpers'
;
import
{
API
,
getLogo
,
isMobile
,
showError
,
showInfo
,
showSuccess
,
showWarning
}
from
'../helpers'
;
import
{
onGitHubOAuthClicked
}
from
'./utils'
;
import
{
onGitHubOAuthClicked
}
from
'./utils'
;
import
Turnstile
from
"react-turnstile"
;
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
Title
from
"@douyinfe/semi-ui/lib/es/typography/title"
;
import
Text
from
"@douyinfe/semi-ui/lib/es/typography/text"
;
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
LoginForm
=
()
=>
{
const
[
inputs
,
setInputs
]
=
useState
({
const
[
inputs
,
setInputs
]
=
useState
({
...
@@ -18,7 +18,7 @@ const LoginForm = () => {
...
@@ -18,7 +18,7 @@ const LoginForm = () => {
});
});
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
();
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
();
const
[
submitted
,
setSubmitted
]
=
useState
(
false
);
const
[
submitted
,
setSubmitted
]
=
useState
(
false
);
const
{
username
,
password
}
=
inputs
;
const
{
username
,
password
}
=
inputs
;
const
[
userState
,
userDispatch
]
=
useContext
(
UserContext
);
const
[
userState
,
userDispatch
]
=
useContext
(
UserContext
);
const
[
turnstileEnabled
,
setTurnstileEnabled
]
=
useState
(
false
);
const
[
turnstileEnabled
,
setTurnstileEnabled
]
=
useState
(
false
);
const
[
turnstileSiteKey
,
setTurnstileSiteKey
]
=
useState
(
''
);
const
[
turnstileSiteKey
,
setTurnstileSiteKey
]
=
useState
(
''
);
...
@@ -56,9 +56,9 @@ const LoginForm = () => {
...
@@ -56,9 +56,9 @@ const LoginForm = () => {
const
res
=
await
API
.
get
(
const
res
=
await
API
.
get
(
`/api/oauth/wechat?code=
${
inputs
.
wechat_verification_code
}
`
`/api/oauth/wechat?code=
${
inputs
.
wechat_verification_code
}
`
);
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
userDispatch
({
type
:
'login'
,
payload
:
data
});
userDispatch
({
type
:
'login'
,
payload
:
data
});
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
data
));
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
data
));
navigate
(
'/'
);
navigate
(
'/'
);
showSuccess
(
'登录成功!'
);
showSuccess
(
'登录成功!'
);
...
@@ -69,7 +69,7 @@ const LoginForm = () => {
...
@@ -69,7 +69,7 @@ const LoginForm = () => {
};
};
function
handleChange
(
name
,
value
)
{
function
handleChange
(
name
,
value
)
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
}
}
async
function
handleSubmit
(
e
)
{
async
function
handleSubmit
(
e
)
{
...
@@ -83,13 +83,13 @@ const LoginForm = () => {
...
@@ -83,13 +83,13 @@ const LoginForm = () => {
username
,
username
,
password
password
});
});
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
userDispatch
({
type
:
'login'
,
payload
:
data
});
userDispatch
({
type
:
'login'
,
payload
:
data
});
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
data
));
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
data
));
showSuccess
(
'登录成功!'
);
showSuccess
(
'登录成功!'
);
if
(
username
===
'root'
&&
password
===
'123456'
)
{
if
(
username
===
'root'
&&
password
===
'123456'
)
{
Modal
.
error
({
title
:
'您正在使用默认密码!'
,
content
:
'请立刻修改默认密码!'
,
centered
:
true
});
Modal
.
error
({
title
:
'您正在使用默认密码!'
,
content
:
'请立刻修改默认密码!'
,
centered
:
true
});
}
}
navigate
(
'/token'
);
navigate
(
'/token'
);
}
else
{
}
else
{
...
@@ -100,16 +100,23 @@ const LoginForm = () => {
...
@@ -100,16 +100,23 @@ const LoginForm = () => {
}
}
}
}
// 添加Telegram登录处理函数
const
onTelegramLoginClicked
=
async
()
=>
{
// 这里调用后端API进行Telegram登录
// 例如: const res = await API.get(`/api/oauth/telegram`);
// 根据响应处理登录逻辑
};
return
(
return
(
<
div
>
<
div
>
<
Layout
>
<
Layout
>
<
Layout
.
Header
>
<
Layout
.
Header
>
<
/Layout.Header
>
<
/Layout.Header
>
<
Layout
.
Content
>
<
Layout
.
Content
>
<
div
style
=
{{
justifyContent
:
'center'
,
display
:
"flex"
,
marginTop
:
120
}}
>
<
div
style
=
{{
justifyContent
:
'center'
,
display
:
"flex"
,
marginTop
:
120
}}
>
<
div
style
=
{{
width
:
500
}}
>
<
div
style
=
{{
width
:
500
}}
>
<
Card
>
<
Card
>
<
Title
heading
=
{
2
}
style
=
{{
textAlign
:
'center'
}}
>
<
Title
heading
=
{
2
}
style
=
{{
textAlign
:
'center'
}}
>
用户登录
用户登录
<
/Title
>
<
/Title
>
<
Form
>
<
Form
>
...
@@ -129,12 +136,12 @@ const LoginForm = () => {
...
@@ -129,12 +136,12 @@ const LoginForm = () => {
onChange
=
{(
value
)
=>
handleChange
(
'password'
,
value
)}
onChange
=
{(
value
)
=>
handleChange
(
'password'
,
value
)}
/
>
/
>
<
Button
theme
=
'solid'
style
=
{{
width
:
'100%'
}}
type
=
{
'primary'
}
size
=
'large'
<
Button
theme
=
'solid'
style
=
{{
width
:
'100%'
}}
type
=
{
'primary'
}
size
=
'large'
htmlType
=
{
'submit'
}
onClick
=
{
handleSubmit
}
>
htmlType
=
{
'submit'
}
onClick
=
{
handleSubmit
}
>
登录
登录
<
/Button
>
<
/Button
>
<
/Form
>
<
/Form
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'space-between'
,
marginTop
:
20
}}
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'space-between'
,
marginTop
:
20
}}
>
<
Text
>
<
Text
>
没有账号请先
<
Link
to
=
'/register'
>
注册账号
<
/Link
>
没有账号请先
<
Link
to
=
'/register'
>
注册账号
<
/Link
>
<
/Text
>
<
/Text
>
...
@@ -142,16 +149,16 @@ const LoginForm = () => {
...
@@ -142,16 +149,16 @@ const LoginForm = () => {
忘记密码
<
Link
to
=
'/reset'
>
点击重置
<
/Link
>
忘记密码
<
Link
to
=
'/reset'
>
点击重置
<
/Link
>
<
/Text
>
<
/Text
>
<
/div
>
<
/div
>
{
status
.
github_oauth
||
status
.
wechat_login
?
(
{
status
.
github_oauth
||
status
.
wechat_login
||
status
.
telegram_oauth
?
(
<>
<>
<
Divider
margin
=
'12px'
align
=
'center'
>
<
Divider
margin
=
'12px'
align
=
'center'
>
第三方登录
第三方登录
<
/Divider
>
<
/Divider
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'center'
,
marginTop
:
20
}}
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'center'
,
marginTop
:
20
}}
>
{
status
.
github_oauth
?
(
{
status
.
github_oauth
?
(
<
Button
<
Button
type
=
'primary'
type
=
'primary'
icon
=
{
<
IconGithubLogo
/>
}
icon
=
{
<
IconGithubLogo
/>
}
onClick
=
{()
=>
onGitHubOAuthClicked
(
status
.
github_client_id
)}
onClick
=
{()
=>
onGitHubOAuthClicked
(
status
.
github_client_id
)}
/
>
/
>
)
:
(
)
:
(
...
@@ -167,6 +174,18 @@ const LoginForm = () => {
...
@@ -167,6 +174,18 @@ const LoginForm = () => {
{
/*) : (*/
}
{
/*) : (*/
}
{
/* <></>*/
}
{
/* <></>*/
}
{
/*)}*/
}
{
/*)}*/
}
{
status
.
telegram_oauth
?
(
<
Button
type
=
'primary'
// icon={<IconTelegram/>} // 假设您有Telegram的图标
onClick
=
{
onTelegramLoginClicked
}
>
Telegram
登录
<
/Button
>
)
:
(
<><
/
>
)}
<
/div
>
<
/div
>
<
/
>
<
/
>
)
:
(
)
:
(
...
@@ -208,7 +227,7 @@ const LoginForm = () => {
...
@@ -208,7 +227,7 @@ const LoginForm = () => {
{
/*</Modal>*/
}
{
/*</Modal>*/
}
<
/Card
>
<
/Card
>
{
turnstileEnabled
?
(
{
turnstileEnabled
?
(
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'center'
,
marginTop
:
20
}}
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'center'
,
marginTop
:
20
}}
>
<
Turnstile
<
Turnstile
sitekey
=
{
turnstileSiteKey
}
sitekey
=
{
turnstileSiteKey
}
onVerify
=
{(
token
)
=>
{
onVerify
=
{(
token
)
=>
{
...
...
web/src/components/PersonalSetting.js
View file @
1ca78291
...
@@ -444,6 +444,27 @@ const PersonalSetting = () => {
...
@@ -444,6 +444,27 @@ const PersonalSetting = () => {
</div>
</div>
<div style={{marginTop: 10}}>
<div style={{marginTop: 10}}>
<Typography.Text strong>Telegram</Typography.Text>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<div>
<Input
value={userState.user && userState.user.telegram_id !== ''?userState.user.telegram_id:'未绑定'}
readonly={true}
></Input>
</div>
<div>
<Button
disabled={(userState.user && userState.user.telegram_id !== '') || !status.telegram_oauth}
>
{
status.github_oauth?'绑定':'未启用'
}
</Button>
</div>
</div>
</div>
<div style={{marginTop: 10}}>
<Space>
<Space>
<Button onClick={generateAccessToken}>生成系统访问令牌</Button>
<Button onClick={generateAccessToken}>生成系统访问令牌</Button>
<Button onClick={() => {
<Button onClick={() => {
...
...
web/src/components/SystemSetting.js
View file @
1ca78291
...
@@ -34,7 +34,7 @@ const SystemSetting = () => {
...
@@ -34,7 +34,7 @@ const SystemSetting = () => {
EmailDomainRestrictionEnabled
:
''
,
EmailDomainRestrictionEnabled
:
''
,
EmailDomainWhitelist
:
''
,
EmailDomainWhitelist
:
''
,
// telegram login
// telegram login
Telegram
Login
Enabled
:
''
,
Telegram
OAuth
Enabled
:
''
,
TelegramBotToken
:
''
,
TelegramBotToken
:
''
,
TelegramBotName
:
''
,
TelegramBotName
:
''
,
});
});
...
@@ -81,7 +81,7 @@ const SystemSetting = () => {
...
@@ -81,7 +81,7 @@ const SystemSetting = () => {
case
'EmailVerificationEnabled'
:
case
'EmailVerificationEnabled'
:
case
'GitHubOAuthEnabled'
:
case
'GitHubOAuthEnabled'
:
case
'WeChatAuthEnabled'
:
case
'WeChatAuthEnabled'
:
case
'Telegram
Login
Enabled'
:
case
'Telegram
OAuth
Enabled'
:
case
'TurnstileCheckEnabled'
:
case
'TurnstileCheckEnabled'
:
case
'EmailDomainRestrictionEnabled'
:
case
'EmailDomainRestrictionEnabled'
:
case
'RegisterEnabled'
:
case
'RegisterEnabled'
:
...
@@ -240,7 +240,7 @@ const SystemSetting = () => {
...
@@ -240,7 +240,7 @@ const SystemSetting = () => {
};
};
const
submitTelegramSettings
=
async
()
=>
{
const
submitTelegramSettings
=
async
()
=>
{
await
updateOption
(
'Telegram
LoginEnabled'
,
inputs
.
TelegramLogin
Enabled
);
await
updateOption
(
'Telegram
OAuthEnabled'
,
inputs
.
TelegramOAuth
Enabled
);
await
updateOption
(
'TelegramBotToken'
,
inputs
.
TelegramBotToken
);
await
updateOption
(
'TelegramBotToken'
,
inputs
.
TelegramBotToken
);
await
updateOption
(
'TelegramBotName'
,
inputs
.
TelegramBotName
);
await
updateOption
(
'TelegramBotName'
,
inputs
.
TelegramBotName
);
};
};
...
@@ -397,6 +397,12 @@ const SystemSetting = () => {
...
@@ -397,6 +397,12 @@ const SystemSetting = () => {
name
=
'WeChatAuthEnabled'
name
=
'WeChatAuthEnabled'
onChange
=
{
handleInputChange
}
onChange
=
{
handleInputChange
}
/
>
/
>
<
Form
.
Checkbox
checked
=
{
inputs
.
TelegramOAuthEnabled
===
'true'
}
label
=
'允许通过 Telegram 进行登录'
name
=
'TelegramOAuthEnabled'
onChange
=
{
handleInputChange
}
/
>
<
/Form.Group
>
<
/Form.Group
>
<
Form
.
Group
inline
>
<
Form
.
Group
inline
>
<
Form
.
Checkbox
<
Form
.
Checkbox
...
@@ -596,25 +602,17 @@ const SystemSetting = () => {
...
@@ -596,25 +602,17 @@ const SystemSetting = () => {
<
Divider
/>
<
Divider
/>
<
Header
as
=
'h3'
>
配置
Telegram
登录
<
/Header
>
<
Header
as
=
'h3'
>
配置
Telegram
登录
<
/Header
>
<
Form
.
Group
inline
>
<
Form
.
Group
inline
>
<
Form
.
Checkbox
checked
=
{
inputs
.
TelegramLoginEnabled
===
'true'
}
label
=
'允许通过 Telegram 进行登录'
name
=
'TelegramLoginEnabled'
onChange
=
{
handleInputChange
}
/
>
<
Form
.
Input
<
Form
.
Input
label
=
'Telegram Bot Token'
label
=
'Telegram Bot Token'
name
=
'TelegramBotToken'
name
=
'TelegramBotToken'
value
=
{
inputs
.
TelegramBotToken
}
value
=
{
inputs
.
TelegramBotToken
}
placeholder
=
'输入你的 Telegram Bot Token'
placeholder
=
'输入你的 Telegram Bot Token'
onChange
=
{
handleInputChange
}
/>
/>
<
Form
.
Input
<
Form
.
Input
label
=
'Telegram Bot 名称'
label
=
'Telegram Bot 名称'
name
=
'TelegramBotName'
name
=
'TelegramBotName'
value
=
{
inputs
.
TelegramBotName
}
value
=
{
inputs
.
TelegramBotName
}
placeholder
=
'输入你的 Telegram Bot 名称'
placeholder
=
'输入你的 Telegram Bot 名称'
onChange
=
{
handleInputChange
}
/>
/>
<
/Form.Group
>
<
/Form.Group
>
<
Form
.
Button
onClick
=
{
submitTelegramSettings
}
>
<
Form
.
Button
onClick
=
{
submitTelegramSettings
}
>
...
...
web/src/pages/User/EditUser.js
View file @
1ca78291
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment