mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-14 11:55:34 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c093e7d621 | ||
|
|
b4183b421f | ||
|
|
9c6281cf02 | ||
|
|
e7bdf6276d | ||
|
|
fa860dbd85 | ||
|
|
2bb4ca3ec0 | ||
|
|
93a08d265b | ||
|
|
b7be7784c6 | ||
|
|
375c6bf44b | ||
|
|
542e34208e | ||
|
|
f041b0de74 | ||
|
|
7ff75280a5 | ||
|
|
d76009de3a | ||
|
|
851f4508e2 | ||
|
|
a36e5196f8 | ||
|
|
d22d16681e | ||
|
|
31c86fb281 | ||
|
|
f83739b496 | ||
|
|
1d9eddb11f | ||
|
|
da14abc83b | ||
|
|
7b705dfc75 | ||
|
|
4516d83ce4 |
@@ -25,7 +25,7 @@
|
||||
<el-form-item :label="this.$t('assets.Password')">
|
||||
<el-input v-model="authInfo.password" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item :label="this.$t('assets.SSHKey')">
|
||||
<el-form-item :label="this.$t('users.SSHKey')">
|
||||
<el-input v-model="authInfo['private_key']" class="item-textarea" type="textarea" show-password />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -16,26 +16,27 @@
|
||||
<el-input v-model="account['username']" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="this.$t('assets.Password')">
|
||||
<el-input v-model="authInfo.password" type="password" />
|
||||
<UpdateToken v-model="authInfo.password" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="this.$t('assets.SSHSecretKey')">
|
||||
<UploadKey @input="getFile" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="this.$t('assets.Passphrase')">
|
||||
<el-input v-model="authInfo.passphrase" type="password" />
|
||||
<UpdateToken v-model="authInfo.passphrase" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog'
|
||||
import { UploadKey } from '@/components'
|
||||
import { Dialog, UploadKey } from '@/components'
|
||||
import { UpdateToken } from '@/components/FormFields'
|
||||
export default {
|
||||
name: 'UpdateSecretInfo',
|
||||
components: {
|
||||
Dialog,
|
||||
UploadKey
|
||||
UploadKey,
|
||||
UpdateToken
|
||||
},
|
||||
props: {
|
||||
account: {
|
||||
|
||||
@@ -161,6 +161,7 @@ export default {
|
||||
watch: {
|
||||
url(iNew) {
|
||||
this.$set(this.tableConfig, 'url', iNew)
|
||||
this.$set(this.headerActions.exportOptions, 'url', iNew.replace('/accounts/', '/account-secrets/'))
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -110,9 +110,11 @@ export default {
|
||||
this.currentNode = treeNode
|
||||
this.currentNodeId = treeNode.meta.data.id
|
||||
query['node'] = this.currentNodeId
|
||||
query['asset'] = ''
|
||||
url = `${this.setting.url}${combinator}node_id=${treeNode.meta.data.id}&show_current_asset=${show_current_asset}`
|
||||
} else if (treeNode.meta.type === 'asset') {
|
||||
query['asset'] = treeNode.meta.data.id
|
||||
query['node'] = ''
|
||||
url = `${this.setting.url}${combinator}asset_id=${treeNode.meta.data.id}&show_current_asset=${show_current_asset}`
|
||||
}
|
||||
this.$router.push({ query })
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
<script>
|
||||
import ElFormRender from './components/el-form-renderer'
|
||||
import { scrollToError } from '@/utils'
|
||||
export default {
|
||||
components: {
|
||||
ElFormRender
|
||||
@@ -76,6 +77,7 @@ export default {
|
||||
this.$emit('submit', form.getFormValue(), form, addContinue)
|
||||
} else {
|
||||
this.$emit('invalid', valid)
|
||||
scrollToError(form.$el)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -86,7 +86,11 @@ export default {
|
||||
if (key === '') {
|
||||
key = 'search'
|
||||
}
|
||||
data[key] = value
|
||||
if (key.startsWith('search')) {
|
||||
data['search'] = (data.search ? data.search + ',' : '') + value
|
||||
} else {
|
||||
data[key] = value
|
||||
}
|
||||
}
|
||||
return data
|
||||
},
|
||||
@@ -109,6 +113,19 @@ export default {
|
||||
handler(val) {
|
||||
if (val && val.length > 0) {
|
||||
const routeFilter = this.checkInTableColumns()
|
||||
const routerSearch = routeFilter.search || {}
|
||||
const routerSearchArrs = routerSearch?.value?.split(',') || []
|
||||
const routerSearchArrsLength = routerSearchArrs.length || 0
|
||||
if (routerSearch && routerSearchArrsLength > 0) {
|
||||
for (let i = 0; i < routerSearchArrsLength; i++) {
|
||||
const cur = routerSearchArrs[i]
|
||||
routeFilter[`search_${cur}`] = {
|
||||
...routerSearch,
|
||||
value: cur
|
||||
}
|
||||
}
|
||||
delete routeFilter.search
|
||||
}
|
||||
const asFilterTags = _.cloneDeep(this.filterTags)
|
||||
this.filterTags = {
|
||||
...asFilterTags,
|
||||
@@ -130,37 +147,43 @@ export default {
|
||||
if (Object.keys(this.filterMaps).length > 0) {
|
||||
return this.$emit('tagSearch', this.filterMaps)
|
||||
}
|
||||
}
|
||||
, 400)
|
||||
}, 400)
|
||||
// this.$nextTick(() => this.$emit('tagSearch', this.filterMaps))
|
||||
},
|
||||
methods: {
|
||||
// 判断url中的查询条件
|
||||
// 获取url中的查询条件,判断是不是包含在当前查询条件里
|
||||
checkInTableColumns() {
|
||||
const routeQuery = this.getUrlQuery ? this.$route?.query : {}
|
||||
const routeQueryKeys = Object.keys(routeQuery)
|
||||
const routeQueryKeysLength = routeQueryKeys.length
|
||||
const keys = {}
|
||||
if (routeQueryKeys.length < 1) return keys
|
||||
if (routeQueryKeys.length > 0) {
|
||||
for (let i = 0; i < routeQueryKeys.length; i++) {
|
||||
if (routeQueryKeysLength < 1) return keys
|
||||
if (routeQueryKeysLength > 0) {
|
||||
for (let i = 0; i < routeQueryKeysLength; i++) {
|
||||
const key = routeQueryKeys[i]
|
||||
const valueDecode = decodeURI(routeQuery[key])
|
||||
let valueDecode = decodeURI(routeQuery[key])
|
||||
const isSearch = key !== 'search'
|
||||
for (let k = 0, len = this.options.length; k < len; k++) {
|
||||
const cur = this.options[k]
|
||||
const curOptions = this.options || []
|
||||
for (let k = 0, len = curOptions.length; k < len; k++) {
|
||||
const cur = curOptions[k]
|
||||
if (cur?.type === 'boolean') {
|
||||
valueDecode = !!valueDecode
|
||||
}
|
||||
if (key === cur.value || !isSearch) {
|
||||
const curChildren = cur.children || []
|
||||
keys[key] = {
|
||||
...cur,
|
||||
key,
|
||||
label: isSearch ? cur.label : '',
|
||||
value: valueDecode
|
||||
}
|
||||
if (isSearch && curChildren.length > 0) {
|
||||
curChildren.forEach(item => {
|
||||
for (const item of curChildren) {
|
||||
if (valueDecode === item.value) {
|
||||
keys[key].valueLabel = item.label
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,23 +223,28 @@ export default {
|
||||
this.$nextTick(() => this.$refs.Cascade.handleClear())
|
||||
},
|
||||
handleTagClose(evt) {
|
||||
this.checkUrlFilds(evt)
|
||||
this.$delete(this.filterTags, evt)
|
||||
this.checkUrlFilds(evt)
|
||||
this.$emit('tagSearch', this.filterMaps)
|
||||
return true
|
||||
},
|
||||
handleConfirm() {
|
||||
if (this.filterValue === '') return
|
||||
if (this.filterValue && !this.filterKey) {
|
||||
this.filterKey = 'search'
|
||||
this.filterKey = 'search' + '_' + this.filterValue
|
||||
}
|
||||
const tag = { key: this.filterKey, label: this.keyLabel, value: this.filterValue, valueLabel: this.valueLabel }
|
||||
this.$set(this.filterTags, this.filterKey, tag)
|
||||
this.$emit('tagSearch', this.filterMaps)
|
||||
|
||||
// 修改查询参数时改变url中保存的参数
|
||||
if (this.getUrlQuery) {
|
||||
let newQuery = _.cloneDeep(this.$route.query)
|
||||
newQuery = { ...newQuery, [this.filterKey]: encodeURI(this.filterValue) }
|
||||
if (this.filterKey.startsWith('search')) {
|
||||
newQuery = { ...newQuery, search: encodeURI(this.filterMaps.search) }
|
||||
} else {
|
||||
newQuery = { ...newQuery, [this.filterKey]: encodeURI(this.filterValue) }
|
||||
}
|
||||
this.$router.replace({ query: newQuery })
|
||||
}
|
||||
|
||||
@@ -249,7 +277,15 @@ export default {
|
||||
},
|
||||
// 删除查询条件时改变url
|
||||
checkUrlFilds(evt) {
|
||||
const newQuery = _.omit(this.$route.query, evt)
|
||||
let newQuery = _.omit(this.$route.query, evt)
|
||||
if (this.getUrlQuery && evt.startsWith('search')) {
|
||||
if (newQuery.search) delete newQuery.search
|
||||
const filterMapsSearch = this.filterMaps.search || ''
|
||||
newQuery = {
|
||||
...newQuery,
|
||||
...(filterMapsSearch && { search: encodeURI(filterMapsSearch) })
|
||||
}
|
||||
}
|
||||
this.$router.replace({ query: newQuery })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
"kubernetes":"Kubernetes",
|
||||
"clusterHelpTextMessage": "例如:https://172.16.8.8:8443",
|
||||
"DBInfo": "数据库信息",
|
||||
"RDBProtocol": "关系型数据库协议",
|
||||
"NoSQLProtocol": "非关系型数据库协议"
|
||||
"RDBProtocol": "关系型数据库",
|
||||
"NoSQLProtocol": "非关系数据库"
|
||||
},
|
||||
"assets": {
|
||||
"AppList": "应用列表",
|
||||
@@ -232,8 +232,8 @@
|
||||
"ipDomain": "IP(域名)",
|
||||
"HostProtocol": "主机协议",
|
||||
"DatabaseProtocol": "数据库协议",
|
||||
"RDBProtocol": "关系型数据库协议",
|
||||
"NoSQLProtocol": "非关系型数据库协议",
|
||||
"RDBProtocol": "关系型数据库",
|
||||
"NoSQLProtocol": "非关系数据库",
|
||||
"OtherProtocol": "其它协议",
|
||||
"PasswordOrToken": "密码 / 令牌"
|
||||
},
|
||||
|
||||
@@ -110,3 +110,24 @@ export function param2Obj(url) {
|
||||
export function getDateTimeStamp(dateStr) {
|
||||
return Date.parse(dateStr.replace(/-/gi, '/'))
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动滚动到错误位置
|
||||
* @param {*} el 目标元素
|
||||
* @param {Object} 滚动参数 scrollOption={
|
||||
* behavior: 'smooth',
|
||||
* block: 'center'
|
||||
* }
|
||||
*/
|
||||
export const scrollToError = (
|
||||
el,
|
||||
scrollOption = {
|
||||
behavior: 'smooth',
|
||||
block: 'center'
|
||||
}
|
||||
) => {
|
||||
setTimeout(() => {
|
||||
const isError = el.getElementsByClassName('is-error')
|
||||
isError[0].scrollIntoView(scrollOption)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ export default {
|
||||
GenericTreeListPage, AccountListTable
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
isInit: true,
|
||||
clickedRow: null,
|
||||
@@ -30,24 +29,25 @@ export default {
|
||||
url: '/api/v1/assets/accounts/',
|
||||
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1',
|
||||
callback: {
|
||||
onSelected: function(event, treeNode) {
|
||||
let url = '/api/v1/assets/accounts/'
|
||||
if (treeNode.meta.type === 'node') {
|
||||
const nodeId = treeNode.meta.data.id
|
||||
url = setUrlParam(url, 'asset', '')
|
||||
url = setUrlParam(url, 'node', nodeId)
|
||||
} else if (treeNode.meta.type === 'asset') {
|
||||
const assetId = treeNode.meta.data.id
|
||||
url = setUrlParam(url, 'node', '')
|
||||
url = setUrlParam(url, 'asset', assetId)
|
||||
}
|
||||
setTimeout(() => {
|
||||
vm.accountsUrl = url
|
||||
}, 100)
|
||||
}
|
||||
onSelected: (event, treeNode) => this.getAccountsUrl(event, treeNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAccountsUrl(event, treeNode) {
|
||||
let url = '/api/v1/assets/accounts/'
|
||||
if (treeNode.meta.type === 'node') {
|
||||
const nodeId = treeNode.meta.data.id
|
||||
url = setUrlParam(url, 'asset', '')
|
||||
url = setUrlParam(url, 'node', nodeId)
|
||||
} else if (treeNode.meta.type === 'asset') {
|
||||
const assetId = treeNode.meta.data.id
|
||||
url = setUrlParam(url, 'node', '')
|
||||
url = setUrlParam(url, 'asset', assetId)
|
||||
}
|
||||
this.accountsUrl = url
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -20,11 +20,17 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/assets/cmd-filters/${this.object.id}/rules/`,
|
||||
columns: ['type', 'content', 'action', 'priority', 'pattern', 'comment', 'actions'],
|
||||
columns: ['type', 'content', 'ignore_case', 'action', 'priority', 'pattern', 'comment', 'actions'],
|
||||
columnsMeta: {
|
||||
type: {
|
||||
width: '100px'
|
||||
},
|
||||
ignore_case: {
|
||||
width: '100px',
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
priority: {
|
||||
width: '70px'
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ export default {
|
||||
action: 0
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['filter', 'type', 'content', 'priority', 'action', 'reviewers', 'comment']]
|
||||
[this.$t('common.Basic'), ['filter', 'type', 'content', 'ignore_case', 'priority', 'action', 'reviewers', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
filter: {
|
||||
|
||||
@@ -76,7 +76,6 @@ export default {
|
||||
}
|
||||
},
|
||||
user: {
|
||||
width: '140px',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
asset: {
|
||||
@@ -210,7 +209,6 @@ export default {
|
||||
const queryStr = (url.indexOf('?') > -1 ? '&' : '?') + queryUtil.stringify(_query, '=', '&')
|
||||
const treeUrl = url + queryStr
|
||||
this.$set(this.treeSetting, 'treeUrl', treeUrl)
|
||||
this.treeTable.forceRerenderTree()
|
||||
},
|
||||
handleDateChange(object) {
|
||||
this.query = {
|
||||
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
// 这个页面不去提交auth这些
|
||||
const removeFields = [
|
||||
'AUTH_CAS', 'AUTH_OPENID', 'AUTH_WECOM', 'AUTH_DINGTALK',
|
||||
'AUTH_FEISHU', 'AUTH_RADIUS', 'AUTH_SSO'
|
||||
'AUTH_FEISHU', 'AUTH_RADIUS', 'AUTH_SSO', 'AUTH_SAML2'
|
||||
]
|
||||
for (const i of removeFields) {
|
||||
delete data[i]
|
||||
|
||||
@@ -105,11 +105,17 @@ export default {
|
||||
settings: {
|
||||
visible: false,
|
||||
url: '/api/v1/settings/setting/?category=ldap',
|
||||
fields: ['AUTH_LDAP_SYNC_IS_PERIODIC', 'AUTH_LDAP_SYNC_INTERVAL', 'AUTH_LDAP_SYNC_CRONTAB'],
|
||||
fields: ['AUTH_LDAP_SYNC_IS_PERIODIC', 'AUTH_LDAP_SYNC_CRONTAB', 'AUTH_LDAP_SYNC_INTERVAL'],
|
||||
fieldsMeta: {
|
||||
AUTH_LDAP_SYNC_IS_PERIODIC: {
|
||||
type: 'switch'
|
||||
},
|
||||
AUTH_LDAP_SYNC_CRONTAB: {
|
||||
component: CronTab,
|
||||
helpText: this.$t('xpack.HelpText.CrontabOfCreateUpdatePage')
|
||||
},
|
||||
AUTH_LDAP_SYNC_INTERVAL: {
|
||||
helpText: this.$t('xpack.HelpText.IntervalOfCreateUpdatePage')
|
||||
}
|
||||
},
|
||||
submitMethod: () => 'patch'
|
||||
|
||||
@@ -41,6 +41,7 @@ export default {
|
||||
[
|
||||
'SECURITY_MFA_AUTH',
|
||||
'SECURITY_MFA_IN_LOGIN_PAGE',
|
||||
'SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY',
|
||||
'SECURITY_LOGIN_CHALLENGE_ENABLED',
|
||||
'SECURITY_LOGIN_CAPTCHA_ENABLED',
|
||||
'SECURITY_PASSWORD_EXPIRATION_TIME',
|
||||
|
||||
@@ -132,6 +132,10 @@ export default {
|
||||
{
|
||||
label: 'SQLServer',
|
||||
value: 'sqlserver'
|
||||
},
|
||||
{
|
||||
label: 'Redis',
|
||||
value: 'redis'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -16,17 +16,23 @@ export default {
|
||||
tableConfig: {
|
||||
url: '/api/v1/tickets/flows/',
|
||||
columns: [
|
||||
'type_display', 'created_by',
|
||||
'type_display', 'created_by', 'org_name',
|
||||
'date_created', 'date_updated', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['actions'],
|
||||
default: [
|
||||
'type_display', 'created_by',
|
||||
'type_display', 'created_by', 'org_name',
|
||||
'date_created', 'date_updated', 'actions'
|
||||
]
|
||||
},
|
||||
columnsMeta: {
|
||||
org_name: {
|
||||
formatter: function(row, col, cell) {
|
||||
var currentOrg = vm.$store.getters.currentOrg
|
||||
return currentOrg.is_root ? row.org_name : currentOrg.name
|
||||
}
|
||||
},
|
||||
type_display: {
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
icon: 'fa-gear',
|
||||
name: 'TicketFlow',
|
||||
hidden: () => {
|
||||
return !(vm.$store.getters.currentUserIsSuperAdmin || vm.$store.getters.currentUserIsAdmin)
|
||||
return !vm.$store.getters.currentUserIsSuperAdmin
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user