mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
Add config to hide default passwords or force password change at first login #1355
This commit is contained in:
committed by
fit2cloud-chenyw
parent
c1d333e62d
commit
4ee923c968
@@ -2,21 +2,29 @@ from typing import Annotated
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from apps.system.schemas.logout_schema import LogoutSchema
|
||||
from apps.system.schemas.system_schema import BaseUserDTO
|
||||
from apps.system.schemas.system_schema import BaseUserDTO, LoginPwdEditor
|
||||
from common.core.deps import SessionDep, Trans
|
||||
from common.utils.crypto import sqlbot_decrypt
|
||||
from ..crud.user import authenticate
|
||||
from common.core.security import create_access_token
|
||||
from ..crud.user import authenticate, check_pwd_format, clean_user_cache, get_db_user
|
||||
from common.core.security import create_access_token, default_pwd, md5pwd, verify_md5pwd
|
||||
from datetime import timedelta
|
||||
from common.core.config import settings
|
||||
from common.core.schemas import Token
|
||||
from sqlbot_xpack.authentication.manage import logout as xpack_logout
|
||||
from sqlbot_xpack.config.arg_manage import get_group_args
|
||||
|
||||
from common.audit.models.log_model import OperationType, OperationModules
|
||||
from common.audit.schemas.logger_decorator import system_log, LogConfig
|
||||
|
||||
router = APIRouter(tags=["login"], prefix="/login")
|
||||
|
||||
|
||||
async def initial_pwd_disabled(session) -> bool:
|
||||
login_args = await get_group_args(session=session, flag='login')
|
||||
disabled_arg = next((a for a in login_args if a.pkey == 'login.initial_pwd_disabled'), None)
|
||||
return bool(disabled_arg and str(disabled_arg.pval).strip().lower() == 'true')
|
||||
|
||||
|
||||
@router.post("/access-token")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.LOGIN,
|
||||
@@ -39,13 +47,46 @@ async def local_login(
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.user_disable', msg = trans('i18n_concat_admin')))
|
||||
if user.origin is not None and user.origin != 0:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.origin_error'))
|
||||
if (
|
||||
user.id != 1
|
||||
and await initial_pwd_disabled(session)
|
||||
and verify_md5pwd(default_pwd(), user.password)
|
||||
):
|
||||
return Token(access_token='', need_change_pwd=True)
|
||||
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
user_dict = user.to_dict()
|
||||
return Token(access_token=create_access_token(
|
||||
user_dict, expires_delta=access_token_expires
|
||||
))
|
||||
return Token(
|
||||
access_token=create_access_token(user_dict, expires_delta=access_token_expires),
|
||||
need_change_pwd=False,
|
||||
)
|
||||
|
||||
@router.post("/logout")
|
||||
|
||||
@router.post("/change-pwd")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE_PWD,
|
||||
module=OperationModules.USER,
|
||||
result_id_expr="id"
|
||||
))
|
||||
async def login_change_pwd(session: SessionDep, trans: Trans, editor: LoginPwdEditor):
|
||||
origin_account = await sqlbot_decrypt(editor.account)
|
||||
origin_pwd = await sqlbot_decrypt(editor.pwd)
|
||||
new_pwd = await sqlbot_decrypt(editor.new_pwd)
|
||||
user: BaseUserDTO = authenticate(session=session, account=origin_account, password=origin_pwd)
|
||||
if not user:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.account_pwd_error'))
|
||||
if user.origin is not None and user.origin != 0:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.origin_error'))
|
||||
if not check_pwd_format(new_pwd):
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_format_invalid', key = trans('i18n_user.password')))
|
||||
if await initial_pwd_disabled(session) and new_pwd == default_pwd():
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.new_pwd_is_initial'))
|
||||
db_user = get_db_user(session=session, user_id=user.id)
|
||||
db_user.password = md5pwd(new_pwd)
|
||||
session.add(db_user)
|
||||
await clean_user_cache(user.id)
|
||||
return db_user
|
||||
|
||||
@router.post("/logout")
|
||||
async def logout(session: SessionDep, request: Request, dto: LogoutSchema):
|
||||
if dto.origin != 0:
|
||||
return await xpack_logout(session, request, dto)
|
||||
|
||||
@@ -18,6 +18,7 @@ from common.core.security import default_md5_pwd, md5pwd, verify_md5pwd
|
||||
from common.core.sqlbot_cache import clear_cache
|
||||
from common.core.config import settings
|
||||
from apps.swagger.i18n import PLACEHOLDER_PREFIX
|
||||
from sqlbot_xpack.config.arg_manage import get_group_args
|
||||
|
||||
router = APIRouter(tags=["system_user"], prefix="/user")
|
||||
|
||||
@@ -45,7 +46,11 @@ async def user_info(current_user: CurrentUser) -> UserInfoDTO:
|
||||
|
||||
@router.get("/defaultPwd", include_in_schema=False)
|
||||
@require_permissions(permission=SqlbotPermission(role=['admin']))
|
||||
async def default_pwd() -> str:
|
||||
async def default_pwd(session: SessionDep) -> str:
|
||||
login_args = await get_group_args(session=session, flag='login')
|
||||
hidden_arg = next((a for a in login_args if a.pkey == 'login.initial_pwd_hidden'), None)
|
||||
if hidden_arg and str(hidden_arg.pval).strip().lower() == 'true':
|
||||
return ''
|
||||
return settings.DEFAULT_PWD
|
||||
|
||||
@router.get("/pager/{pageNum}/{pageSize}", response_model=PaginatedResponse[UserGrid], summary=f"{PLACEHOLDER_PREFIX}system_user_grid", description=f"{PLACEHOLDER_PREFIX}system_user_grid")
|
||||
|
||||
@@ -83,6 +83,12 @@ class PwdEditor(BaseModel):
|
||||
new_pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}new_pwd")
|
||||
|
||||
|
||||
class LoginPwdEditor(BaseModel):
|
||||
account: str = Field(description=f"{PLACEHOLDER_PREFIX}user_account")
|
||||
pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}origin_pwd")
|
||||
new_pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}new_pwd")
|
||||
|
||||
|
||||
class UserWsBase(BaseModel):
|
||||
uid_list: list[int] = Field(description=f"{PLACEHOLDER_PREFIX}uid")
|
||||
oid: Optional[int] = Field(default=None, description=f"{PLACEHOLDER_PREFIX}oid")
|
||||
|
||||
@@ -16,6 +16,7 @@ class Token(SQLModel):
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
platform_info: Optional[dict] = None
|
||||
need_change_pwd: Optional[bool] = None
|
||||
|
||||
class XOAuth2PasswordBearer(OAuth2PasswordBearer):
|
||||
async def __call__(self, request: Request) -> Optional[str]:
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "Account is disabled, {msg}",
|
||||
"origin_error": "Invalid login method",
|
||||
"prohibit_auto_create": "Automatically creating users is prohibited. Please synchronize users first",
|
||||
"no_platform_user": "Account does not exist. Please sync the user first."
|
||||
"no_platform_user": "Account does not exist. Please sync the user first.",
|
||||
"new_pwd_is_initial": "The new password cannot be the initial password"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "Account",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "계정이 비활성화되었습니다, {msg}",
|
||||
"origin_error": "잘못된 로그인 방식입니다",
|
||||
"prohibit_auto_create": "사용자 자동 생성이 금지되어 있습니다. 먼저 사용자를 동기화해 주세요",
|
||||
"no_platform_user": "계정이 존재하지 않습니다. 먼저 사용자를 동기화하세요."
|
||||
"no_platform_user": "계정이 존재하지 않습니다. 먼저 사용자를 동기화하세요.",
|
||||
"new_pwd_is_initial": "새 비밀번호는 초기 비밀번호로 설정할 수 없습니다"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "계정",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "账号已禁用,{msg}",
|
||||
"origin_error": "登录方式错误",
|
||||
"prohibit_auto_create": "禁止自动创建用户,请先同步用户",
|
||||
"no_platform_user": "账号不存在,请先同步用户"
|
||||
"no_platform_user": "账号不存在,请先同步用户",
|
||||
"new_pwd_is_initial": "新密码不能为初始密码"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "账号",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "帳號已禁用,{msg}",
|
||||
"origin_error": "登入方式錯誤",
|
||||
"prohibit_auto_create": "禁止自動建立用戶,請先同步用戶",
|
||||
"no_platform_user": "帳號不存在,請先同步用戶"
|
||||
"no_platform_user": "帳號不存在,請先同步用戶",
|
||||
"new_pwd_is_initial": "新密碼不能為初始密碼"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "帳號",
|
||||
|
||||
@@ -14,6 +14,14 @@ export const AuthApi = {
|
||||
},
|
||||
})
|
||||
},
|
||||
changePwd: (data: { account: string; pwd: string; new_pwd: string }) => {
|
||||
const entry = {
|
||||
account: LicenseGenerator.sqlbotEncrypt(data.account),
|
||||
pwd: LicenseGenerator.sqlbotEncrypt(data.pwd),
|
||||
new_pwd: LicenseGenerator.sqlbotEncrypt(data.new_pwd),
|
||||
}
|
||||
return request.post('/login/change-pwd', entry)
|
||||
},
|
||||
logout: (data: any) => request.post('/login/logout', data),
|
||||
info: () => request.get('/user/info'),
|
||||
}
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
"closed_by_default": "In the Question Count window, control whether the model thinking process is expanded or closed by default.",
|
||||
"and_platform_integration": "Authentication-related",
|
||||
"login_settings": "Login Settings",
|
||||
"default_login": "Default Login Method"
|
||||
"default_login": "Default Login Method",
|
||||
"disable_initial_password": "Disable Initial Password",
|
||||
"hide_initial_password": "Hide Initial Password on Page"
|
||||
},
|
||||
"prompt": {
|
||||
"default_password": "Default password:{msg}",
|
||||
@@ -932,6 +934,9 @@
|
||||
"default_login": "Default",
|
||||
"ldap_login": "LDAP Login",
|
||||
"account_login": "Account Login",
|
||||
"force_change_pwd_title": "Change Initial Password",
|
||||
"force_change_pwd_tips": "Your current password is the system initial password. Please change it and log in again.",
|
||||
"force_change_pwd_success": "Password changed successfully",
|
||||
"other_login": "Other Login Methods",
|
||||
"pwd_invalid_error": "Password has expired, please contact administrator to modify or reset",
|
||||
"pwd_exp_tips": "Password will expire in {0} days, please change it as soon as possible",
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
"closed_by_default": "질문 수 창에서 모델 사고 프로세스를 기본적으로 확장할지 또는 닫을지 여부를 제어합니다.",
|
||||
"and_platform_integration": "인증 관련",
|
||||
"login_settings": "로그인 설정",
|
||||
"default_login": "기본 로그인 방식"
|
||||
"default_login": "기본 로그인 방식",
|
||||
"disable_initial_password": "초기 비밀번호 비활성화",
|
||||
"hide_initial_password": "페이지에서 초기 비밀번호 숨기기"
|
||||
},
|
||||
"prompt": {
|
||||
"default_password:": "기본 비밀번호:{msg}",
|
||||
@@ -932,6 +934,9 @@
|
||||
"default_login": "기본값",
|
||||
"ldap_login": "LDAP 로그인",
|
||||
"account_login": "계정 로그인",
|
||||
"force_change_pwd_title": "초기 비밀번호 변경",
|
||||
"force_change_pwd_tips": "현재 비밀번호는 시스템 초기 비밀번호입니다. 비밀번호를 변경한 후 로그인해 주세요.",
|
||||
"force_change_pwd_success": "비밀번호가 변경되었습니다",
|
||||
"other_login": "기타 로그인 방식",
|
||||
"pwd_invalid_error": "비밀번호가 만료되었습니다. 관리자에게 문의하여 수정 또는 재설정해 주세요",
|
||||
"pwd_exp_tips": "비밀번호가 {0}일 후에 만료됩니다.尽快尽快 비밀번호를 변경해 주세요",
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
"closed_by_default": "在问数窗口中,控制模型思考过程默认展开或者关闭",
|
||||
"and_platform_integration": "登录认证相关",
|
||||
"login_settings": "登录设置",
|
||||
"default_login": "默认登录方式"
|
||||
"default_login": "默认登录方式",
|
||||
"disable_initial_password": "禁用初始密码",
|
||||
"hide_initial_password": "页面隐藏初始密码"
|
||||
},
|
||||
"prompt": {
|
||||
"default_password": "默认密码:{msg}",
|
||||
@@ -932,6 +934,9 @@
|
||||
"default_login": "默认",
|
||||
"ldap_login": "LDAP 登录",
|
||||
"account_login": "账号登录",
|
||||
"force_change_pwd_title": "修改初始密码",
|
||||
"force_change_pwd_tips": "当前密码为系统初始密码,请修改密码后再登录",
|
||||
"force_change_pwd_success": "密码修改成功",
|
||||
"other_login": "其他登录方式",
|
||||
"pwd_invalid_error": "密码已过期请联系管理员修改或重置",
|
||||
"pwd_exp_tips": "密码在 {0} 天后过期,请尽快修改密码",
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
"closed_by_default": "在問數視窗中,控制模型思考過程預設展開或者關閉",
|
||||
"and_platform_integration": "登入認證相關",
|
||||
"login_settings": "登入設定",
|
||||
"default_login": "預設登入方式"
|
||||
"default_login": "預設登入方式",
|
||||
"disable_initial_password": "禁用初始密碼",
|
||||
"hide_initial_password": "頁面隱藏初始密碼"
|
||||
},
|
||||
"prompt": {
|
||||
"default_password": "預設密碼:{msg}",
|
||||
@@ -932,6 +934,9 @@
|
||||
"default_login": "預設",
|
||||
"ldap_login": "LDAP 登入",
|
||||
"account_login": "帳號登入",
|
||||
"force_change_pwd_title": "修改初始密碼",
|
||||
"force_change_pwd_tips": "目前密碼為系統初始密碼,請修改密碼後再登入",
|
||||
"force_change_pwd_success": "密碼修改成功",
|
||||
"other_login": "其他登入方式",
|
||||
"pwd_invalid_error": "密碼已過期請聯繫管理員修改或重設",
|
||||
"pwd_exp_tips": "密碼在 {0} 天後過期,請盡快修改密碼",
|
||||
|
||||
@@ -83,7 +83,10 @@ export const UserStore = defineStore('user', {
|
||||
actions: {
|
||||
async login(formData: { username: string; password: string }) {
|
||||
const res: any = await AuthApi.login(formData)
|
||||
this.setToken(res.access_token)
|
||||
if (res.access_token) {
|
||||
this.setToken(res.access_token)
|
||||
}
|
||||
return res
|
||||
},
|
||||
|
||||
async logout() {
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { AuthApi } from '@/api/login'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: Boolean, required: true },
|
||||
account: { type: String, required: true },
|
||||
oldPwd: { type: String, required: true },
|
||||
})
|
||||
const emits = defineEmits(['update:modelValue', 'pwdSaved'])
|
||||
|
||||
const { t } = useI18n()
|
||||
const pwdRef = ref()
|
||||
const pwdForm = reactive({
|
||||
pwd: '',
|
||||
new_pwd: '',
|
||||
confirm_pwd: '',
|
||||
})
|
||||
const PWD_REGEX =
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+\-={}|:"<>?`\[\];',./])[A-Za-z\d~!@#$%^&*()_+\-={}|:"<>?`\[\];',./]{8,20}$/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const validatePass = (rule: any, value: any, callback: any) => {
|
||||
if (value === '') {
|
||||
callback(new Error(t('common.please_input', { msg: t('user.upgrade_pwd.new_pwd') })))
|
||||
} else {
|
||||
if (!PWD_REGEX.test(value)) {
|
||||
callback(new Error(t('user.upgrade_pwd.pwd_format_error')))
|
||||
return
|
||||
}
|
||||
if (pwdForm.confirm_pwd !== '') {
|
||||
if (!pwdRef.value) return
|
||||
pwdRef.value.validateField('confirm_pwd')
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const validatePass2 = (rule: any, value: any, callback: any) => {
|
||||
if (value === '') {
|
||||
callback(new Error(t('common.please_input', { msg: t('user.upgrade_pwd.confirm_pwd') })))
|
||||
} else if (!PWD_REGEX.test(value)) {
|
||||
callback(new Error(t('user.upgrade_pwd.pwd_format_error')))
|
||||
} else if (value !== pwdForm.new_pwd) {
|
||||
callback(new Error(t('user.upgrade_pwd.two_pwd_not_match')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const rules = {
|
||||
pwd: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.please_input', { msg: t('user.upgrade_pwd.old_pwd') }),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
new_pwd: [{ validator: validatePass, trigger: 'blur' }],
|
||||
confirm_pwd: [{ validator: validatePass2, trigger: 'blur' }],
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (val) {
|
||||
pwdForm.pwd = props.oldPwd
|
||||
pwdForm.new_pwd = ''
|
||||
pwdForm.confirm_pwd = ''
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const closeHandler = () => {
|
||||
emits('update:modelValue', false)
|
||||
}
|
||||
|
||||
const submit = () => {
|
||||
pwdRef.value.validate((res: any) => {
|
||||
if (res) {
|
||||
AuthApi.changePwd({
|
||||
account: props.account,
|
||||
pwd: pwdForm.pwd,
|
||||
new_pwd: pwdForm.new_pwd,
|
||||
}).then(() => {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: t('login.force_change_pwd_success'),
|
||||
})
|
||||
emits('pwdSaved', pwdForm.new_pwd)
|
||||
closeHandler()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog
|
||||
:model-value="modelValue"
|
||||
:title="t('login.force_change_pwd_title')"
|
||||
width="480"
|
||||
append-to-body
|
||||
@update:model-value="(val: boolean) => emits('update:modelValue', val)"
|
||||
@close="closeHandler"
|
||||
>
|
||||
<div class="initial-pwd-tips">{{ t('login.force_change_pwd_tips') }}</div>
|
||||
<el-form
|
||||
ref="pwdRef"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
:model="pwdForm"
|
||||
style="width: 100%"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item prop="pwd" :label="t('user.upgrade_pwd.old_pwd')">
|
||||
<el-input
|
||||
v-model="pwdForm.pwd"
|
||||
:placeholder="t('common.please_input', { msg: t('user.upgrade_pwd.old_pwd') })"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="new_pwd" :label="t('user.upgrade_pwd.new_pwd')">
|
||||
<el-input
|
||||
v-model="pwdForm.new_pwd"
|
||||
:placeholder="t('common.please_input', { msg: t('user.upgrade_pwd.new_pwd') })"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="confirm_pwd" :label="t('user.upgrade_pwd.confirm_pwd')">
|
||||
<el-input
|
||||
v-model="pwdForm.confirm_pwd"
|
||||
:placeholder="t('common.please_input', { msg: t('user.upgrade_pwd.confirm_pwd') })"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button secondary @click="closeHandler">{{ t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ t('common.save') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.initial-pwd-tips {
|
||||
margin-bottom: 16px;
|
||||
color: var(--ed-color-warning, #e6a23c);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
</style>
|
||||
@@ -71,6 +71,12 @@
|
||||
jsname="L2NvbXBvbmVudC9sb2dpbi9IYW5kbGVy"
|
||||
@switch-tab="switchTab"
|
||||
/>
|
||||
<InitialPwdDialog
|
||||
v-model="initPwdDialogVisible"
|
||||
:account="loginForm.username"
|
||||
:old-pwd="loginForm.password"
|
||||
@pwd-saved="onInitPwdSaved"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -88,6 +94,7 @@ import login_image from '@/assets/embedded/login_image.png'
|
||||
import { useAppearanceStoreWithOut } from '@/stores/appearance'
|
||||
import loginImage from '@/assets/blue/login-image_blue.png'
|
||||
import Handler from './xpack/Handler.vue'
|
||||
import InitialPwdDialog from './InitialPwdDialog.vue'
|
||||
import { toLoginSuccess } from '@/utils/utils'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
|
||||
@@ -134,12 +141,20 @@ const loginFormRef = ref()
|
||||
const submitForm = () => {
|
||||
loginFormRef.value.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
userStore.login(loginForm.value).then(() => {
|
||||
userStore.login(loginForm.value).then((res: any) => {
|
||||
if (res?.need_change_pwd) {
|
||||
initPwdDialogVisible.value = true
|
||||
return
|
||||
}
|
||||
toLoginSuccess(router)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const initPwdDialogVisible = ref(false)
|
||||
const onInitPwdSaved = (newPwd: string) => {
|
||||
loginForm.value.password = newPwd
|
||||
}
|
||||
const switchTab = (name: string) => {
|
||||
activeName.value = name || 'simple'
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="anyPlatformEnable" class="card">
|
||||
<div v-if="xpackValid" class="card">
|
||||
<div class="card-title">
|
||||
{{ t('parameter.login_settings') }}
|
||||
</div>
|
||||
<div class="card-item" style="width: 100%">
|
||||
<div v-if="anyPlatformEnable" class="card-item" style="width: 100%">
|
||||
<div class="label">
|
||||
{{ t('parameter.default_login') }}
|
||||
</div>
|
||||
@@ -79,6 +79,20 @@
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-item" style="width: 100%">
|
||||
<div class="label">{{ t('parameter.disable_initial_password') }}</div>
|
||||
<div class="value">
|
||||
<el-switch v-model="formData['login.initial_pwd_disabled']" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-item" style="width: 100%">
|
||||
<div class="label">{{ t('parameter.hide_initial_password') }}</div>
|
||||
<div class="value">
|
||||
<el-switch v-model="formData['login.initial_pwd_hidden']" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -97,6 +111,8 @@ const defaultForm = reactive<Record<string, any>>({
|
||||
'platform.oid': 1,
|
||||
'platform.rid': 1,
|
||||
'login.default_login': 0,
|
||||
'login.initial_pwd_disabled': false,
|
||||
'login.initial_pwd_hidden': false,
|
||||
})
|
||||
|
||||
const loginTypeOptions = shallowRef<any[]>([{ value: 0, label: t('login.account_login') }])
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
</span>
|
||||
<span class="header-span">{{ t('datasource.the_original_one') }}</span>
|
||||
</div>
|
||||
<div class="confirm-content">
|
||||
<div v-if="showInitPwd" class="confirm-content">
|
||||
<span>{{ defaultPwd }}</span>
|
||||
<el-button style="margin-left: 4px" text @click="copyText">{{
|
||||
t('datasource.copy')
|
||||
@@ -284,7 +284,7 @@
|
||||
size="600px"
|
||||
:before-close="onFormClose"
|
||||
>
|
||||
<div style="margin-bottom: 12px" class="down-template">
|
||||
<div v-if="showInitPwd" style="margin-bottom: 12px" class="down-template">
|
||||
<span class="icon-span">
|
||||
<el-icon>
|
||||
<Icon name="icon_warning_filled"><icon_warning_filled class="svg-icon" /></Icon>
|
||||
@@ -584,6 +584,7 @@ import { request } from '@/utils/request'
|
||||
import { workspaceList } from '@/api/workspace'
|
||||
import { variablesApi } from '@/api/variables'
|
||||
import { formatTimestamp } from '@/utils/date'
|
||||
import { formatArg } from '@/utils/utils'
|
||||
import { ClickOutside as vClickOutside } from 'element-plus-secondary'
|
||||
import icon_warning_filled from '@/assets/svg/icon_warning_filled.svg'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
@@ -1291,6 +1292,21 @@ const loadDefaultPwd = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
const showInitPwd = ref(true)
|
||||
const loadInitPwdHidden = () => {
|
||||
request
|
||||
.get('/system/parameter/login')
|
||||
.then((res: any) => {
|
||||
const argObj: Record<string, string> = {}
|
||||
;(res || []).forEach((item: any) => {
|
||||
argObj[item.pkey] = item.pval
|
||||
})
|
||||
showInitPwd.value = !formatArg(argObj['login.initial_pwd_hidden'])
|
||||
})
|
||||
.catch(() => {
|
||||
showInitPwd.value = true
|
||||
})
|
||||
}
|
||||
const formatUserOrigin = (origin?: number) => {
|
||||
if (!origin) {
|
||||
return t('user.local_creation')
|
||||
@@ -1327,6 +1343,7 @@ onMounted(() => {
|
||||
handleCurrentChange(1)
|
||||
|
||||
loadDefaultPwd()
|
||||
loadInitPwdHidden()
|
||||
})
|
||||
const downErrorExcel = (dataKey: any) => {
|
||||
userApi.errorRecord(dataKey).then((res: any) => {
|
||||
|
||||
Reference in New Issue
Block a user