🔀 sync: sync upstream
This commit is contained in:
parent
ef041e28a1
commit
45fd814d77
@ -9,9 +9,9 @@ import (
|
||||
)
|
||||
|
||||
type Log struct {
|
||||
Id int `json:"id;index:idx_created_at_id,priority:1"`
|
||||
Id int `json:"id"`
|
||||
UserId int `json:"user_id" gorm:"index"`
|
||||
CreatedAt int64 `json:"created_at" gorm:"bigint;index:idx_created_at_id,priority:2;index:idx_created_at_type"`
|
||||
CreatedAt int64 `json:"created_at" gorm:"bigint;index:idx_created_at_type"`
|
||||
Type int `json:"type" gorm:"index:idx_created_at_type"`
|
||||
Content string `json:"content"`
|
||||
Username string `json:"username" gorm:"index:index_username_model_name,priority:2;default:''"`
|
||||
|
@ -3,8 +3,9 @@ package model
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"one-api/common"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Token struct {
|
||||
@ -38,39 +39,43 @@ func ValidateUserToken(key string) (token *Token, err error) {
|
||||
return nil, errors.New("未提供令牌")
|
||||
}
|
||||
token, err = CacheGetTokenByKey(key)
|
||||
if err == nil {
|
||||
if token.Status == common.TokenStatusExhausted {
|
||||
return nil, errors.New("该令牌额度已用尽")
|
||||
} else if token.Status == common.TokenStatusExpired {
|
||||
return nil, errors.New("该令牌已过期")
|
||||
if err != nil {
|
||||
common.SysError("CacheGetTokenByKey failed: " + err.Error())
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("无效的令牌")
|
||||
}
|
||||
if token.Status != common.TokenStatusEnabled {
|
||||
return nil, errors.New("该令牌状态不可用")
|
||||
}
|
||||
if token.ExpiredTime != -1 && token.ExpiredTime < common.GetTimestamp() {
|
||||
if !common.RedisEnabled {
|
||||
token.Status = common.TokenStatusExpired
|
||||
err := token.SelectUpdate()
|
||||
if err != nil {
|
||||
common.SysError("failed to update token status" + err.Error())
|
||||
}
|
||||
}
|
||||
return nil, errors.New("该令牌已过期")
|
||||
}
|
||||
if !token.UnlimitedQuota && token.RemainQuota <= 0 {
|
||||
if !common.RedisEnabled {
|
||||
// in this case, we can make sure the token is exhausted
|
||||
token.Status = common.TokenStatusExhausted
|
||||
err := token.SelectUpdate()
|
||||
if err != nil {
|
||||
common.SysError("failed to update token status" + err.Error())
|
||||
}
|
||||
}
|
||||
return nil, errors.New("该令牌额度已用尽")
|
||||
}
|
||||
return token, nil
|
||||
return nil, errors.New("令牌验证失败")
|
||||
}
|
||||
return nil, errors.New("无效的令牌")
|
||||
if token.Status == common.TokenStatusExhausted {
|
||||
return nil, errors.New("该令牌额度已用尽")
|
||||
} else if token.Status == common.TokenStatusExpired {
|
||||
return nil, errors.New("该令牌已过期")
|
||||
}
|
||||
if token.Status != common.TokenStatusEnabled {
|
||||
return nil, errors.New("该令牌状态不可用")
|
||||
}
|
||||
if token.ExpiredTime != -1 && token.ExpiredTime < common.GetTimestamp() {
|
||||
if !common.RedisEnabled {
|
||||
token.Status = common.TokenStatusExpired
|
||||
err := token.SelectUpdate()
|
||||
if err != nil {
|
||||
common.SysError("failed to update token status" + err.Error())
|
||||
}
|
||||
}
|
||||
return nil, errors.New("该令牌已过期")
|
||||
}
|
||||
if !token.UnlimitedQuota && token.RemainQuota <= 0 {
|
||||
if !common.RedisEnabled {
|
||||
// in this case, we can make sure the token is exhausted
|
||||
token.Status = common.TokenStatusExhausted
|
||||
err := token.SelectUpdate()
|
||||
if err != nil {
|
||||
common.SysError("failed to update token status" + err.Error())
|
||||
}
|
||||
}
|
||||
return nil, errors.New("该令牌额度已用尽")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func GetTokenByIds(id int, userId int) (*Token, error) {
|
||||
|
@ -139,7 +139,15 @@ func (user *User) ValidateAndFill() (err error) {
|
||||
if user.Username == "" || password == "" {
|
||||
return errors.New("用户名或密码为空")
|
||||
}
|
||||
DB.Where(User{Username: user.Username}).First(user)
|
||||
err = DB.Where("username = ?", user.Username).First(user).Error
|
||||
if err != nil {
|
||||
// we must make sure check username firstly
|
||||
// consider this case: a malicious user set his username as other's email
|
||||
err := DB.Where("email = ?", user.Username).First(user).Error
|
||||
if err != nil {
|
||||
return errors.New("用户名或密码错误,或用户已被封禁")
|
||||
}
|
||||
}
|
||||
okay := common.ValidatePasswordAndHash(password, user.Password)
|
||||
if !okay || user.Status != common.UserStatusEnabled {
|
||||
return errors.New("用户名或密码错误,或用户已被封禁")
|
||||
|
@ -157,7 +157,7 @@ const ProfileSection = () => {
|
||||
<ListItemIcon>
|
||||
<IconLogout stroke={1.5} size="1.3rem" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={<Typography variant="body2">Logout</Typography>} />
|
||||
<ListItemText primary={<Typography variant="body2">注销</Typography>} />
|
||||
</ListItemButton>
|
||||
</List>
|
||||
</MainCard>
|
||||
|
@ -121,7 +121,6 @@ const MenuCard = () => {
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
{/* <LinearProgressWithLabel value={80} /> */}
|
||||
</CardContent>
|
||||
</CardStyle>
|
||||
);
|
||||
|
@ -38,9 +38,6 @@ const Sidebar = ({ drawerOpen, drawerToggle, window }) => {
|
||||
>
|
||||
<MenuList />
|
||||
<MenuCard />
|
||||
<Stack direction="row" justifyContent="center" sx={{ mb: 2 }}>
|
||||
<Chip label={process.env.REACT_APP_VERSION} disabled chipcolor="secondary" size="small" sx={{ cursor: 'pointer' }} />
|
||||
</Stack>
|
||||
</PerfectScrollbar>
|
||||
</BrowserView>
|
||||
<MobileView>
|
||||
|
@ -44,7 +44,7 @@ const Header = () => {
|
||||
</Button>
|
||||
) : (
|
||||
<Button component={Link} variant="contained" to="/login" color="primary">
|
||||
登入
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
|
@ -22,7 +22,7 @@ const panel = {
|
||||
children: [
|
||||
{
|
||||
id: 'dashboard',
|
||||
title: 'Dashboard',
|
||||
title: '仪表盘',
|
||||
type: 'item',
|
||||
url: '/panel/dashboard',
|
||||
icon: icons.IconDashboard,
|
||||
@ -40,7 +40,7 @@ const panel = {
|
||||
},
|
||||
{
|
||||
id: 'token',
|
||||
title: 'Token',
|
||||
title: '令牌',
|
||||
type: 'item',
|
||||
url: '/panel/token',
|
||||
icon: icons.IconKey,
|
||||
|
@ -180,7 +180,7 @@ const LoginForm = ({ ...others }) => {
|
||||
{({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => (
|
||||
<form noValidate onSubmit={handleSubmit} {...others}>
|
||||
<FormControl fullWidth error={Boolean(touched.username && errors.username)} sx={{ ...theme.typography.customInput }}>
|
||||
<InputLabel htmlFor="outlined-adornment-username-login">用户名</InputLabel>
|
||||
<InputLabel htmlFor="outlined-adornment-username-login">用户名/邮箱</InputLabel>
|
||||
<OutlinedInput
|
||||
id="outlined-adornment-username-login"
|
||||
type="text"
|
||||
@ -188,7 +188,7 @@ const LoginForm = ({ ...others }) => {
|
||||
name="username"
|
||||
onBlur={handleBlur}
|
||||
onChange={handleChange}
|
||||
label="用户名"
|
||||
label="用户名/邮箱"
|
||||
inputProps={{ autoComplete: 'username' }}
|
||||
/>
|
||||
{touched.username && errors.username && (
|
||||
|
@ -103,7 +103,7 @@ const EditModal = ({ open, tokenId, onCancel, onOk }) => {
|
||||
return (
|
||||
<Dialog open={open} onClose={onCancel} fullWidth maxWidth={'md'}>
|
||||
<DialogTitle sx={{ margin: '0px', fontWeight: 700, lineHeight: '1.55556', padding: '24px', fontSize: '1.125rem' }}>
|
||||
{tokenId ? '编辑Token' : '新建Token'}
|
||||
{tokenId ? '编辑令牌' : '新建令牌'}
|
||||
</DialogTitle>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
|
@ -158,7 +158,7 @@ export default function Token() {
|
||||
return (
|
||||
<>
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" mb={5}>
|
||||
<Typography variant="h4">Token</Typography>
|
||||
<Typography variant="h4">令牌</Typography>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
@ -168,7 +168,7 @@ export default function Token() {
|
||||
}}
|
||||
startIcon={<IconPlus />}
|
||||
>
|
||||
新建Token
|
||||
新建令牌
|
||||
</Button>
|
||||
</Stack>
|
||||
<Stack mb={5}>
|
||||
|
Loading…
Reference in New Issue
Block a user