Merge branch 'feitianbubu-upstream'
This commit is contained in:
@@ -592,7 +592,14 @@ func UpdateSelf(c *gin.Context) {
|
|||||||
user.Password = "" // rollback to what it should be
|
user.Password = "" // rollback to what it should be
|
||||||
cleanUser.Password = ""
|
cleanUser.Password = ""
|
||||||
}
|
}
|
||||||
updatePassword := user.Password != ""
|
updatePassword, err := checkUpdatePassword(user.OriginalPassword, user.Password, cleanUser.Id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"message": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := cleanUser.Update(updatePassword); err != nil {
|
if err := cleanUser.Update(updatePassword); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@@ -608,6 +615,23 @@ func UpdateSelf(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkUpdatePassword(originalPassword string, newPassword string, userId int) (updatePassword bool, err error) {
|
||||||
|
var currentUser *model.User
|
||||||
|
currentUser, err = model.GetUserById(userId, true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !common.ValidatePasswordAndHash(originalPassword, currentUser.Password) {
|
||||||
|
err = fmt.Errorf("原密码错误")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if newPassword == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updatePassword = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteUser(c *gin.Context) {
|
func DeleteUser(c *gin.Context) {
|
||||||
id, err := strconv.Atoi(c.Param("id"))
|
id, err := strconv.Atoi(c.Param("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type User struct {
|
|||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
Username string `json:"username" gorm:"unique;index" validate:"max=12"`
|
Username string `json:"username" gorm:"unique;index" validate:"max=12"`
|
||||||
Password string `json:"password" gorm:"not null;" validate:"min=8,max=20"`
|
Password string `json:"password" gorm:"not null;" validate:"min=8,max=20"`
|
||||||
|
OriginalPassword string `json:"original_password" gorm:"-:all"` // this field is only for Password change verification, don't save it to database!
|
||||||
DisplayName string `json:"display_name" gorm:"index" validate:"max=20"`
|
DisplayName string `json:"display_name" gorm:"index" validate:"max=20"`
|
||||||
Role int `json:"role" gorm:"type:int;default:1"` // admin, common
|
Role int `json:"role" gorm:"type:int;default:1"` // admin, common
|
||||||
Status int `json:"status" gorm:"type:int;default:1"` // enabled, disabled
|
Status int `json:"status" gorm:"type:int;default:1"` // enabled, disabled
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ const PersonalSetting = () => {
|
|||||||
email_verification_code: '',
|
email_verification_code: '',
|
||||||
email: '',
|
email: '',
|
||||||
self_account_deletion_confirmation: '',
|
self_account_deletion_confirmation: '',
|
||||||
|
original_password: '',
|
||||||
set_new_password: '',
|
set_new_password: '',
|
||||||
set_new_password_confirmation: '',
|
set_new_password_confirmation: '',
|
||||||
});
|
});
|
||||||
@@ -239,11 +240,24 @@ const PersonalSetting = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changePassword = async () => {
|
const changePassword = async () => {
|
||||||
|
if (inputs.original_password === '') {
|
||||||
|
showError(t('请输入原密码!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (inputs.set_new_password === '') {
|
||||||
|
showError(t('请输入新密码!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (inputs.original_password === inputs.set_new_password) {
|
||||||
|
showError(t('新密码需要和原密码不一致!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (inputs.set_new_password !== inputs.set_new_password_confirmation) {
|
if (inputs.set_new_password !== inputs.set_new_password_confirmation) {
|
||||||
showError(t('两次输入的密码不一致!'));
|
showError(t('两次输入的密码不一致!'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await API.put(`/api/user/self`, {
|
const res = await API.put(`/api/user/self`, {
|
||||||
|
original_password: inputs.original_password,
|
||||||
password: inputs.set_new_password,
|
password: inputs.set_new_password,
|
||||||
});
|
});
|
||||||
const { success, message } = res.data;
|
const { success, message } = res.data;
|
||||||
@@ -816,8 +830,8 @@ const PersonalSetting = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Card style={{ marginTop: 10 }}>
|
<Card style={{ marginTop: 10 }}>
|
||||||
<Tabs type="line" defaultActiveKey="notification">
|
<Tabs type='line' defaultActiveKey='notification'>
|
||||||
<TabPane tab={t('通知设置')} itemKey="notification">
|
<TabPane tab={t('通知设置')} itemKey='notification'>
|
||||||
<div style={{ marginTop: 20 }}>
|
<div style={{ marginTop: 20 }}>
|
||||||
<Typography.Text strong>{t('通知方式')}</Typography.Text>
|
<Typography.Text strong>{t('通知方式')}</Typography.Text>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{ marginTop: 10 }}>
|
||||||
@@ -993,23 +1007,36 @@ const PersonalSetting = () => {
|
|||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab={t('价格设置')} itemKey="price">
|
<TabPane tab={t('价格设置')} itemKey='price'>
|
||||||
<div style={{ marginTop: 20 }}>
|
<div style={{ marginTop: 20 }}>
|
||||||
<Typography.Text strong>{t('接受未设置价格模型')}</Typography.Text>
|
<Typography.Text strong>
|
||||||
|
{t('接受未设置价格模型')}
|
||||||
|
</Typography.Text>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{ marginTop: 10 }}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={notificationSettings.acceptUnsetModelRatioModel}
|
checked={
|
||||||
onChange={e => handleNotificationSettingChange('acceptUnsetModelRatioModel', e.target.checked)}
|
notificationSettings.acceptUnsetModelRatioModel
|
||||||
|
}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleNotificationSettingChange(
|
||||||
|
'acceptUnsetModelRatioModel',
|
||||||
|
e.target.checked,
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{t('接受未设置价格模型')}
|
{t('接受未设置价格模型')}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
<Typography.Text type="secondary" style={{ marginTop: 8, display: 'block' }}>
|
<Typography.Text
|
||||||
{t('当模型没有设置价格时仍接受调用,仅当您信任该网站时使用,可能会产生高额费用')}
|
type='secondary'
|
||||||
|
style={{ marginTop: 8, display: 'block' }}
|
||||||
|
>
|
||||||
|
{t(
|
||||||
|
'当模型没有设置价格时仍接受调用,仅当您信任该网站时使用,可能会产生高额费用',
|
||||||
|
)}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div style={{ marginTop: 20 }}>
|
<div style={{ marginTop: 20 }}>
|
||||||
<Button type='primary' onClick={saveNotificationSettings}>
|
<Button type='primary' onClick={saveNotificationSettings}>
|
||||||
@@ -1118,6 +1145,16 @@ const PersonalSetting = () => {
|
|||||||
>
|
>
|
||||||
<div style={{ marginTop: 20 }}>
|
<div style={{ marginTop: 20 }}>
|
||||||
<Input
|
<Input
|
||||||
|
name='original_password'
|
||||||
|
placeholder={t('原密码')}
|
||||||
|
type='password'
|
||||||
|
value={inputs.original_password}
|
||||||
|
onChange={(value) =>
|
||||||
|
handleInputChange('original_password', value)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
style={{ marginTop: 20 }}
|
||||||
name='set_new_password'
|
name='set_new_password'
|
||||||
placeholder={t('新密码')}
|
placeholder={t('新密码')}
|
||||||
value={inputs.set_new_password}
|
value={inputs.set_new_password}
|
||||||
|
|||||||
Reference in New Issue
Block a user