Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.8.0 #3450

Merged
merged 49 commits into from
Oct 19, 2023
Merged

v3.8.0 #3450

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
01d0c9a
feat: 用户登录提醒
feng626 Sep 25, 2023
bdd1a86
Merge pull request #3410 from jumpserver/pr@dev@user_login_reminder
feng626 Sep 25, 2023
66e90f1
perf: 列表搜索框退格键可以删除搜索条件
huailei000 Sep 25, 2023
063dc9f
perf: 优化资产授权详情、账号改密详情中已经添加了的资产没有给出标记还能重复选择的问题
huailei000 Sep 27, 2023
071822e
fix: 系统设置 邮件设置 不能设置后缀
feng626 Sep 27, 2023
f6a2fcb
feat: 登录资产消息提示
feng626 Oct 7, 2023
a6d7cc1
Merge pull request #3416 from jumpserver/pr@dev@asset_notice
feng626 Oct 7, 2023
c50db40
perf: 隐藏设置 terminal_theme_name
LeeEirc Oct 9, 2023
f54d819
feat: 快捷命令增加设置执行目录
Aaron3S Oct 9, 2023
f75d696
perf: 用户首次登录 条款和条件 提示优化
feng626 Oct 10, 2023
8bc617c
Merge pull request #3421 from jumpserver/pr@dev@user_notice
feng626 Oct 10, 2023
50af6fe
perf: 优化确认的 dialog
ibuler Oct 9, 2023
f8b7720
feat: 支持自定义短信认证(文件)
O-Jiangweidong Oct 10, 2023
8e8dd38
perf: 左上角profile accesskey 改成个人设置
feng626 Oct 11, 2023
4eb6137
Merge pull request #3423 from jumpserver/pr@dev@profile
feng626 Oct 11, 2023
4c3673a
perf: 优化账号模版同步更新账号信息
huailei000 Oct 11, 2023
fd018dc
perf: 仅本地用户允许使用 passkey
ibuler Oct 11, 2023
8727bac
perf: 登录资产复核增加跳转会话入口
huailei000 Oct 11, 2023
e055429
perf: 优化用户详情 phone 显示
BaiJiangJie Oct 11, 2023
2d2a4be
perf: 优化账号收集、账号改密、账号备份多次点击执行次数不能正常跳转到执行列表问题
huailei000 Sep 28, 2023
50a9ce3
perf: 重构用户确认
ibuler Oct 12, 2023
ae2391f
perf: 优化数据库必填
ibuler Oct 12, 2023
6a8161d
perf:创建api key,弹窗关闭后刷新列表
huailei000 Oct 12, 2023
fb75768
perf: 资产批量更新平台字段,根据平台约束协议自动生效
feng626 Oct 12, 2023
8d8ab48
Merge pull request #3430 from jumpserver/pr@dev@platform
feng626 Oct 12, 2023
23b0859
perf: 工单配置社区版隐藏
feng626 Oct 13, 2023
0dc6271
Merge pull request #3431 from jumpserver/pr@dev@ticket
feng626 Oct 13, 2023
6fa8052
fix: 修复连接令牌过期按钮被禁用的问题
BaiJiangJie Oct 13, 2023
fc5029e
feat: 增加DB2图标
Halo1236 Oct 13, 2023
759e205
perf: 优化确认操作
ibuler Oct 13, 2023
81f34f0
perf: remove debug
ibuler Oct 13, 2023
f8ec2bc
merge: with dev
ibuler Oct 13, 2023
bd33524
perf: 优化用户确认
ibuler Oct 13, 2023
e274640
Merge pull request #3433 from jumpserver/pr@dev@refactor_confirm
ibuler Oct 13, 2023
0310163
perf: 优化查看账号密码控制台报错问题
huailei000 Oct 16, 2023
7b15ca4
perf: 优化角色创建时权限没有提示
ibuler Oct 17, 2023
af3f6c5
perf: 资产登录工单 去掉session信息
feng626 Oct 18, 2023
52522b7
Merge pull request #3441 from jumpserver/pr@dev@session_ticket
feng626 Oct 18, 2023
c05992c
perf: 修改许可证
ibuler Oct 18, 2023
53d130f
perf: 优化个人设置
ibuler Oct 18, 2023
a08fbc3
perf: 优化table组件在有查询条件的情况下列表会重复请求接口的问题
huailei000 Oct 18, 2023
ae61586
fix: 命令过滤,点击命令组跳转到了规则基本信息,而不是命令组那里
feng626 Oct 18, 2023
f2eff11
Merge pull request #3443 from jumpserver/pr@dev@command_filter_acl
feng626 Oct 18, 2023
62e4956
perf: 优化日期,去掉 nwaring
ibuler Oct 18, 2023
62be588
Merge pull request #3444 from jumpserver/pr@dev@perf_date_expired
ibuler Oct 18, 2023
601bd47
perf: 优化账号推送,推送参数不准确问题
huailei000 Oct 18, 2023
80509dc
perf: 修改profile icon
feng626 Oct 19, 2023
4852e3d
Merge pull request #3446 from jumpserver/pr@dev@profile
feng626 Oct 19, 2023
3a66e83
perf:优化折线图显示不准确问题
huailei000 Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions src/components/Apps/AccountListTable/ViewSecret.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
<template>
<div>
<div v-if="mfaDialogVisible">
<UserConfirmDialog
:url="url"
@UserConfirmCancel="exit"
@UserConfirmDone="getAuthInfo"
/>
</div>
<Dialog
:destroy-on-close="true"
:show-cancel="false"
Expand Down Expand Up @@ -67,7 +60,6 @@
<script>
import Dialog from '@/components/Dialog/index.vue'
import PasswordHistoryDialog from './PasswordHistoryDialog.vue'
import UserConfirmDialog from '@/components/Apps/UserConfirmDialog/index.vue'
import { ShowKeyCopyFormatter } from '@/components/Table/TableFormatters'
import { encryptPassword } from '@/utils/crypto'

Expand All @@ -76,7 +68,6 @@ export default {
components: {
Dialog,
PasswordHistoryDialog,
UserConfirmDialog,
ShowKeyCopyFormatter
},
props: {
Expand Down Expand Up @@ -128,7 +119,10 @@ export default {
const url = `/api/v1/accounts/account-secrets/${this.account.id}/histories/?limit=1`
this.$axios.get(url, { disableFlashErrorMsg: true }).then(resp => {
this.versions = resp.count
this.showSecretDialog()
})
} else {
this.showSecretDialog()
}
},
methods: {
Expand All @@ -146,10 +140,10 @@ export default {
this.$message.success(this.$tc('common.updateSuccessMsg'))
})
},
getAuthInfo() {
this.$axios.get(this.url, { disableFlashErrorMsg: true }).then(resp => {
this.secretInfo = resp
this.sshKeyFingerprint = resp?.spec_info?.ssh_key_fingerprint || '-'
showSecretDialog() {
return this.$axios.get(this.url, { disableFlashErrorMsg: true }).then((res) => {
this.secretInfo = res
this.sshKeyFingerprint = res?.spec_info?.ssh_key_fingerprint || '-'
this.showSecret = true
})
},
Expand Down
1 change: 0 additions & 1 deletion src/components/Apps/AutomationParams/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export default {
},
async mounted() {
await this.getUrlMeta()
await this.handleFieldChange()
},
methods: {
async getUrlMeta() {
Expand Down
218 changes: 105 additions & 113 deletions src/components/Apps/UserConfirmDialog/index.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
<template>
<Dialog
:destroy-on-close="true"
:close-on-click-modal="false"
:destory-on-close="true"
:show-cancel="false"
:show-confirm="false"
:title="title"
:visible.sync="visible"
:width="'36%'"
class="dialog-content"
v-bind="$attrs"
width="600px"
@confirm="visible = false"
v-on="$listeners"
>
<div v-if="ConfirmType === 'relogin'">
<div v-if="confirmTypeRequired === 'relogin'">
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24">
<el-alert
:closable="false"
:title="$tc('auth.ReLoginTitle')"
center
style="margin-bottom: 20px;"
type="info"
type="error"
/>
</el-col>
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24">
<el-button
size="mini"
style="width: 100%; line-height:20px;"
type="primary"
@click="logOut"
>
<el-button class="confirm-btn" size="mini" type="primary" @click="logout">
{{ this.$t('auth.ReLogin') }}
</el-button>
</el-col>
Expand All @@ -39,14 +35,13 @@
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24" :span="24" class="add">
<el-select
v-model="Select"
:disabled="ConfirmType === 'password'"
v-model="subTypeSelected"
style="width: 100%; margin-bottom: 20px;"
@change="helpText(Select)"
@change="handleSubTypeChange"
>
<el-option
v-for="(item, i) of Content"
:key="i"
v-for="item of subTypeChoices"
:key="item.name"
:disabled="item.disabled"
:label="item.display_name"
:value="item.name"
Expand All @@ -56,28 +51,23 @@
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-col :md="24" :sm="24" style="display: flex; margin-bottom: 20px;">
<el-input v-model="SecretKey" :placeholder="HelpText" :show-password="showPassword" />
<span v-if="Select === 'sms'" style="margin: -1px 0 0 20px;">
<el-input v-model="secretValue" :placeholder="inputPlaceholder" :show-password="showPassword" />
<span v-if="subTypeSelected === 'sms'" style="margin: -1px 0 0 20px;">
<el-button
:disabled="smsBtndisabled"
:disabled="smsBtnDisabled"
size="mini"
style="line-height:20px; float: right;"
type="primary"
@click="sendChallengeCode"
@click="sendSMSCode"
>
{{ smsBtnText }}
</el-button>
</span>
</el-col>
</el-row>
<el-row :gutter="24" style="margin: 0 auto;">
<el-row :gutter="24" style="margin: 10px auto;">
<el-col :md="24" :sm="24">
<el-button
size="mini"
style="width: 100%; line-height:20px;"
type="primary"
@click="userConfirm"
>
<el-button class="confirm-btn" size="mini" type="primary" @click="handleConfirm">
{{ this.$t('common.Confirm') }}
</el-button>
</el-col>
Expand All @@ -96,125 +86,116 @@ export default {
props: {
url: {
type: String,
default: () => ''
default: ''
},
handler: {
type: Function,
default: null
}
},
data() {
return {
title: '',
title: this.$t('common.CurrentUserVerify'),
smsWidth: 0,
Select: '',
Level: null,
HelpText: '',
smsBtnText: '',
smsBtndisabled: false,
ConfirmType: '',
Content: null,
SecretKey: '',
visible: false
subTypeSelected: '',
inputPlaceholder: '',
smsBtnText: this.$t('common.SendVerificationCode'),
smsBtnDisabled: false,
confirmTypeRequired: '',
subTypeChoices: [],
secretValue: '',
visible: false,
callback: null,
cancel: null,
processing: false
}
},

computed: {
showPassword() {
if (this.ConfirmType === 'password') {
return true
}
return false
}
},
watch: {
visible(val) {
if (!val) {
this.$emit('UserConfirmCancel', true)
}
return this.confirmTypeRequired === 'password'
}
},
mounted() {
this.smsBtnText = this.$t('common.SendVerificationCode')
this.$axios.get(`${this.url}`, { disableFlashErrorMsg: true }).then(
() => { this.$emit('UserConfirmDone', true) }).catch((err) => {
const confirm_type = err.response.data.code
this.$axios.get('/api/v1/authentication/confirm/', { params: { confirm_type: confirm_type }}).then((data) => {
this.ConfirmType = data.confirm_type
this.Content = data.content
if (this.ConfirmType === 'relogin') {
this.$axios.post(
`/api/v1/authentication/confirm/`,
{
confirm_type: this.ConfirmType,
secret_key: ''
},
{ disableFlashErrorMsg: true },
).then(() => { this.$emit('UserConfirmDone', true) }).catch(() => {
// const onRecvCallback = _.debounce(this.performConfirm, 500)
this.$eventBus.$on('showConfirmDialog', this.performConfirm)
},
methods: {
handleSubTypeChange(val) {
this.inputPlaceholder = this.subTypeChoices.filter(item => item.name === val)[0]?.placeholder
this.smsWidth = val === 'sms' ? 6 : 0
},
performConfirm({ response, callback, cancel }) {
if (this.processing || this.visible) {
return
}
this.processing = true
this.callback = callback
this.cancel = cancel
this.$log.debug('perform confirm action')
const confirmType = response.data?.code
const confirmUrl = '/api/v1/authentication/confirm/'
this.$axios.get(confirmUrl, { params: { confirm_type: confirmType }}).then((data) => {
this.confirmTypeRequired = data.confirm_type

if (this.confirmTypeRequired === 'relogin') {
this.$axios.post(confirmUrl, { 'confirm_type': 'relogin', 'secret_key': 'x' }).then(() => {
this.callback()
this.visible = false
}).catch(() => {
this.title = this.$t('auth.NeedReLogin')
this.visible = true
})
return
}
if (this.ConfirmType === 'mfa') {
this.Select = this.Content.filter(item => !item.disabled)[0].name
if (this.Select === 'sms') {
this.smsWidth = 6
}
this.HelpText = this.Content.filter(item => !item.disabled)[0].placeholder
} else if (this.ConfirmType === 'password') {
this.Select = this.$t('setting.password')
this.HelpText = this.$t('common.PasswordRequireForSecurity')
this.Content = [{ 'name': 'password' }]
}
this.title = this.$t('common.CurrentUserVerify')
this.subTypeChoices = data.content
const defaultSubType = this.subTypeChoices.filter(item => !item.disabled)[0]
this.subTypeSelected = defaultSubType.name
this.inputPlaceholder = defaultSubType.placeholder
this.visible = true
}).catch(() => {
this.$emit('AuthMFAError', true)
}).catch((err) => {
const data = err.response?.data
const msg = data?.error || data?.detail || data?.msg || this.$t('common.GetConfirmTypeFailed')
this.$message.error(msg)
this.cancel(err)
}).finally(() => {
this.processing = false
})
})
},
methods: {
helpText(val) {
this.HelpText = this.Content.filter(item => item.name === val)[0]?.placeholder
if (val === 'sms') {
this.smsWidth = 6
} else {
this.smsWidth = 0
}
},
logOut() {
logout() {
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
},
sendChallengeCode() {
this.$axios.post(
`/api/v1/authentication/mfa/select/`, {
type: 'sms'
}
).then(res => {
this.$message.success(this.$t('common.VerificationCodeSent'))
sendSMSCode() {
this.$axios.post(`/api/v1/authentication/mfa/select/`, { type: 'sms' }).then(res => {
this.$message.success(this.$tc('common.VerificationCodeSent'))
let time = 60
const interval = setInterval(() => {
const originText = this.smsBtnText
this.smsBtnText = this.$t('common.Pending') + `: ${time}`
this.smsBtndisabled = true
this.smsBtnDisabled = true
time -= 1

if (time === 0) {
this.smsBtnText = this.$t('common.SendVerificationCode')
this.smsBtndisabled = false
this.smsBtnText = originText
this.smsBtnDisabled = false
clearInterval(interval)
}
}, 1000)
})
},
userConfirm() {
if (this.Select === 'otp' && this.SecretKey.length !== 6) {
return this.$message.error(this.$t('common.MFAErrorMsg'))
handleConfirm() {
if (this.confirmTypeRequired === 'relogin') {
return this.logout()
}
this.$axios.post(
`/api/v1/authentication/confirm/`, {
confirm_type: this.ConfirmType,
mfa_type: this.ConfirmType === 'password' ? undefined : this.Select,
secret_key: this.SecretKey
}
).then(res => {
this.$emit('UserConfirmDone', true)
if (this.subTypeSelected === 'otp' && this.secretValue.length !== 6) {
return this.$message.error(this.$tc('common.MFAErrorMsg'))
}
const data = {
confirm_type: this.confirmTypeRequired,
mfa_type: this.confirmTypeRequired === 'mfa' ? this.subTypeSelected : '',
secret_key: this.secretValue
}
this.$axios.post(`/api/v1/authentication/confirm/`, data).then(res => {
this.callback()
this.visible = false
})
}
}
Expand All @@ -228,5 +209,16 @@ export default {

.dialog-content >>> .el-dialog {
padding: 8px;

.el-dialog__body {
padding-top: 30px;
padding-bottom: 30px;
}
}

.confirm-btn {
width: 100%;
line-height: 20px;
}

</style>
Loading