Merge pull request #127 from jumpserver/v2.0

feat: 更新Dev分支代码
This commit is contained in:
八千流
2020-07-02 16:55:57 +08:00
committed by GitHub
34 changed files with 214 additions and 50 deletions

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "src/views/xpack"]
path = src/views/xpack
url = git@github.com:fit2cloudrd/js-xpack-web.git
url = git@github.com:jumpserver/lina-xpack.git

View File

@@ -24,7 +24,7 @@ export function getSessionCommands(id) {
export function getTerminalDetail(id) {
return request({
url: `/api/v1/terminal/terminals/${id}/`,
url: `/api/v1/terminal/terminal/${id}/`,
method: 'get'
})
}

View File

@@ -1,7 +1,12 @@
<template>
<div :class="grouped ? 'el-button-group' : ''">
<el-button v-for="item in iActions" :key="item.name" :size="size" v-bind="item" @click="handleClick(item.name)">
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
<el-tooltip v-if="['actionExport', 'actionImport', 'actionRefresh'].indexOf(item.name) !== -1" effect="dark" :content="item.tip" placement="top">
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
</el-tooltip>
<span v-else>
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
</span>
</el-button>
<el-dropdown v-if="iMoreActions.length > 0" trigger="click" @command="handleClick">
<el-button :size="size" :type="moreActionsType" class="btn-more-actions">

View File

@@ -51,6 +51,13 @@ export default {
}
if (field.type === 'choice' && field.choices) {
option.children = field.choices.map(item => {
if (typeof (item.value) === 'boolean') {
if (item.value) {
return { label: item.display_name, value: 'True' }
} else {
return { label: item.display_name, value: 'False' }
}
}
return { label: item.display_name, value: item.value }
})
}

View File

@@ -86,7 +86,6 @@ export default {
computed: {
tableConfig() {
const config = Object.assign(this.defaultConfig, this.config)
this.$log.debug('Datatable found config change')
return config
},
iListeners() {
@@ -96,7 +95,6 @@ export default {
watch: {
config: {
handler() {
this.$log.debug('DataTable: found config change', this.tableConfig.url)
// this.getList()
},
deep: true

View File

@@ -54,9 +54,9 @@ export default {
data() {
return {
defaultRightSideActions: [
{ name: 'actionExport', fa: 'fa-download', has: this.hasExport, callback: this.handleExport.bind(this) },
{ name: 'actionImport', fa: 'fa-upload', has: this.hasImport, callback: this.handleImport.bind(this) },
{ name: 'actionRefresh', fa: 'fa-refresh', has: this.hasRefresh, callback: this.handleRefresh }
{ name: 'actionExport', fa: 'fa-download', tip: this.$t('common.Export'), has: this.hasExport, callback: this.handleExport.bind(this) },
{ name: 'actionImport', fa: 'fa-upload', tip: this.$t('common.Import'), has: this.hasImport, callback: this.handleImport.bind(this) },
{ name: 'actionRefresh', fa: 'fa-refresh', tip: this.$t('common.Refresh'), has: this.hasRefresh, callback: this.handleRefresh }
],
dialogExportVisible: false,
exportValue: 2

View File

@@ -1,6 +1,7 @@
<template>
<div>
<el-tooltip v-if="formatterArgs.hasTips" :content="tips" placement="bottom" effect="dark">
<el-tooltip v-if="formatterArgs.hasTips" placement="bottom" effect="dark">
<div slot="content">{{ tipStatus }}<br>{{ tipTime }}</div>
<i :class="'fa ' + iconClass" />
</el-tooltip>
<i v-else :class="'fa ' + iconClass" />
@@ -25,8 +26,14 @@ export default {
return !!val
},
hasTips: false,
tips(val) {
return val.datetime
tipStatus(val, vm) {
if (val.status === 0) {
return vm.$t('assets.Unreachable')
} else if (val.status === 1) {
return vm.$t('assets.Reachable')
} else if (val.status === 2) {
return vm.$t('assets.Unknown')
}
}
}
}
@@ -42,8 +49,12 @@ export default {
const key = this.formatterArgs.typeChange(this.cellValue)
return this.formatterArgs.iconChoices[key]
},
tips() {
return this.formatterArgs.tips(this.cellValue)
tipStatus() {
const vm = this
return this.formatterArgs.tipStatus(this.cellValue, vm)
},
tipTime() {
return this.cellValue.datetime
}
}
}

View File

@@ -68,9 +68,7 @@ export default {
this.dataTable.getList()
},
search(attrs) {
if (Object.keys(attrs).length > 0) {
return this.dataTable.search(attrs, true)
}
return this.dataTable.search(attrs, true)
},
handleDateChange(attrs) {
this.$set(this.extraQuery, 'date_from', attrs[0].toISOString())

View File

@@ -240,7 +240,6 @@ export default {
this.params.spm = data.spm
await this.getInitialOptions()
}
this.$log.debug('Start get select2 options')
await this.getOptions()
if (this.iOptions.length === 0) {
this.remote = false

View File

@@ -74,7 +74,12 @@ export default {
}
},
mounted() {
setTimeout(() => this.$emit('tagSearch', this.filterMaps), 400)
setTimeout(() => {
if (Object.keys(this.filterMaps).length > 0) {
return this.$emit('tagSearch', this.filterMaps)
}
}
, 400)
// this.$nextTick(() => this.$emit('tagSearch', this.filterMaps))
},
methods: {
@@ -95,7 +100,6 @@ export default {
return ''
},
handleMenuItemChange(keys) {
this.$log.debug('Tag search keys: ', keys)
if (keys.length === 0) {
return
}

View File

@@ -100,6 +100,8 @@
"PushSystemUserNow": "推送系统用户",
"QuickUpdate": "快速更新",
"Reachable": "可连接",
"Unreachable": "不可连接",
"Unknown": "未知",
"Refresh": "刷新",
"RefreshHardware": "更新硬件信息",
"RemoteAppListHelpMessage": "使用此功能前,请确保已将应用加载器上传到应用服务器并成功发布为一个 RemoteApp 应用 <b><a href='https://github.com/jumpserver/Jmservisor/releases'>下载应用加载器</a></b>",
@@ -174,6 +176,7 @@
"EnterForSearch": "按回车进行搜索",
"Export": "导出",
"Import": "导入",
"Refresh": "刷新",
"Info": "提示",
"MFAConfirm": "MFA 认证",
"MFARequireForSecurity": "为了安全请输入MFA",
@@ -827,9 +830,35 @@
"CoveredAlwaysHelpTips": "资产信息总是被覆盖",
"SyncInstanceTaskCreate": "创建同步实例任务",
"SyncInstanceTaskList": "同步实例任务列表",
"SyncInstanceTaskDetail": "同步实例任务详情",
"SyncInstanceTaskUpdate": "更新同步实例任务",
"SyncInstanceTaskHistoryList": "同步历史列表",
"SyncInstanceTaskHistoryAssetList": "同步实例列表",
"CloudSource": "同步源",
"SaveSetting": "同步设置"
"SaveSetting": "同步设置",
"Name": "名称",
"Account":"账户",
"Node": "节点",
"AdminUser":"管理用户",
"CoveredAlways": "总是覆盖",
"Periodic":"执行周期",
"PeriodicPerform":"定时执行",
"RegularlyPerform": "定期执行",
"CyclePerform": "周期执行",
"DateLastSync":"最后同步日期",
"DateCreated":"创建日期",
"Region": "地域",
"Comment": "备注",
"RunTaskManually":"手动执行",
"True":"是",
"False": "否",
"NewCount": "新增",
"UnSyncCount": "未同步",
"SyncedCount": "已同步",
"ReleasedCount": "已释放",
"DateSync": "同步日期",
"Status": "状态",
"Log": "日志"
},
"Corporation": "公司",
"Edition": "版本",
@@ -855,7 +884,9 @@
"OrganizationCreate": "创建组织",
"OrganizationDetail": "组织详情",
"OrganizationList": "组织管理",
"OrganizationUpdate": "更新组织"
"OrganizationUpdate": "更新组织",
"DeleteOrgTitle": "请确保组织内的以下信息已删除",
"DeleteOrgMsg": "用户列表、用户组、资产列表、网域列表、管理用户、系统用户、标签管理、资产授权规则"
},
"RestoreButton": "恢复默认",
"SubscriptionID": "订阅授权ID",

View File

@@ -100,6 +100,8 @@
"PushSystemUserNow": "Push system user now",
"QuickUpdate": "Quick update",
"Reachable": "Reachable",
"Unreachable": "Unreachable",
"Unknown": "Unknown",
"Refresh": "Refresh",
"RefreshHardware": "Refresh hardware",
"RemoteAppListHelpMessage": "Before using this feature, make sure that the application loader has been uploaded to the application server and successfully published as a RemoteApp application <b><a href='https://github.com/jumpserver/Jmservisor/releases'> Download application loader</a></b>",
@@ -175,6 +177,7 @@
"EnterForSearch": "Press enter to search",
"Export": "Export",
"Import": "Import",
"Refresh": "Refresh",
"Info": "Info",
"MFAConfirm": "MFA Confirm",
"MFARequireForSecurity": "MFA required for security",
@@ -533,7 +536,7 @@
"replaySession": "Replay session",
"replayStorage": "Replay storage",
"riskLevel": "Risk level",
"session": "session",
"session": "Session",
"sshPort": "SSH port",
"storage": "Storage",
"systemUser": "System user",
@@ -826,9 +829,35 @@
"CoveredAlwaysHelpTips": "The asset information is always covered",
"SyncInstanceTaskCreate": "Create sync instance task",
"SyncInstanceTaskList": "Sync instance task list",
"SyncInstanceTaskDetail": "Sync instance task detail",
"SyncInstanceTaskUpdate": "Update sync instance task",
"SyncInstanceTaskHistoryList": "Sync task history",
"SyncInstanceTaskHistoryAssetList": "Sync instance list",
"CloudSource": "Cloud source",
"SaveSetting": "Save setting"
"SaveSetting": "Save setting",
"Name": "Name",
"Account":"Account",
"Node": "Node",
"AdminUser":"Admin user",
"CoveredAlways": "Covered always",
"PeriodicPerform":"Periodic perform",
"Periodic":"Periodic",
"RegularlyPerform": "Regularly perform",
"CyclePerform": "Cycle perform",
"DateLastSync":"Date last sync",
"DateCreated":"Date created",
"Region": "Region",
"RunTaskManually":"Run task manually",
"Comment": "Comment",
"True":"True",
"False": "False",
"NewCount": "New count",
"UnSyncCount": "Unsync count",
"SyncedCount": "Synced count",
"ReleasedCount": "Released count",
"DateSync": "Date sync",
"Status": "Status",
"Log": "Log"
},
"Corporation": "Corporation",
"Edition": "Edition",
@@ -854,7 +883,9 @@
"OrganizationCreate": "Create organization",
"OrganizationDetail": "Org detail",
"OrganizationList": "Organlizations",
"OrganizationUpdate": "Update org"
"OrganizationUpdate": "Update org",
"DeleteOrgTitle":"Please ensure that the following information in the organization has been deleted",
"DeleteOrgMsg":"User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission"
},
"RestoreButton": "Restore Default",
"SubscriptionID": "Subscription ID",

View File

@@ -1,7 +1,7 @@
<template>
<div class="footer" :style="style">
<div class="pull-right">
Version <strong>2.0.0</strong> <span v-if="!publicSettings.XPACK_LICENSE_IS_VALID"> GPLv2. </span>
Version <strong>2.0.1</strong> <span v-if="!publicSettings.XPACK_LICENSE_IS_VALID"> GPLv2. </span>
</div>
<div v-if="!publicSettings.XPACK_LICENSE_IS_VALID" style="padding-left:20px;">
<strong>Copyright</strong> FIT2CLOUD 飞致云 © 2014-2020

View File

@@ -40,7 +40,7 @@ export default {
formatter: DialogDetailFormatter,
showOverflowTooltip: true,
formatterArgs: {
getDialogTile: function({ col, row, cellValue }) { this.$t('assets.AssetDetail') }.bind(this),
getDialogTitle: function({ col, row, cellValue }) { this.$t('assets.AssetDetail') }.bind(this),
getDetailItems: function({ col, row, cellValue }) {
return [
{
@@ -62,6 +62,10 @@ export default {
{
key: this.$t('assets.Domain'),
value: row.domain
},
{
key: this.$t('assets.Comment'),
value: row.comment
}
]
}.bind(this)

View File

@@ -49,9 +49,12 @@ service.interceptors.request.use(
)
function ifUnauthorized({ response, error }) {
if (response.status === 401 && response.request.responseURL.indexOf('/users/profile') === -1) {
if (response.status === 401) {
response.config.disableFlashErrorMsg = true
// 未授权重定向到登录页面
if (response.request.responseURL.indexOf('/users/profile/') !== -1) {
window.location = '/core/auth/login/'
return
}
const title = i18n.t('common.Info')
const msg = i18n.t('auth.LoginRequiredMsg')
MessageBox.confirm(msg, title, {

View File

@@ -164,7 +164,7 @@ export default {
},
{
key: this.$t('assets.Protocols'),
value: this.object.protocols
value: this.object.protocols.toString()
},
{
key: this.$t('assets.PublicIp'),

View File

@@ -2,7 +2,7 @@
<IBox fa="fa-info-circle" :title="title" v-bind="$attrs">
<div class="quick-actions">
<p v-if="iLabels.length === 0">{{ $t('common.Nothing') }}</p>
<el-tag v-for="i in iLabels" :key="i.name + i.value" type="info">{{ i.name }}: {{ i.value }}</el-tag>
<el-tag v-for="i in iLabels" :key="i.name + i.value" type="info">{{ i.name }}:{{ i.value }}</el-tag>
</div>
</IBox>
</template>

View File

@@ -68,6 +68,7 @@ import $ from '@/utils/jquery-vendor'
import Dialog from '@/components/Dialog'
import TreeTable from '@/components/TreeTable'
import { GenericUpdateFormDialog } from '@/layout/components'
import rules from '@/components/DataForm/rules'
export default {
components: {
@@ -309,6 +310,7 @@ export default {
}
},
admin_user: {
rules: [rules.RequiredChange],
label: this.$t('assets.AdminUser'),
hidden: () => false,
el: {

View File

@@ -13,10 +13,11 @@ export default {
base: 'Linux',
console: 'true',
security: 'RDP',
comment: ''
comment: '',
charset: 'utf8'
},
fields: [
[this.$t('perms.Basic'), ['name', 'base', 'security', 'console', 'comment']]
[this.$t('perms.Basic'), ['name', 'base', 'charset', 'security', 'console', 'comment']]
],
fieldsMeta: {
security: {
@@ -62,6 +63,7 @@ export default {
}
postData.name = formdata.name
postData.base = formdata.base
postData.charset = formdata.charset
postData.comment = formdata.comment || ''
const params = this.$route.params

View File

@@ -105,6 +105,23 @@ export default {
)
}.bind(this)
}
},
{
title: this.$t('assets.PushSystemUserNow'),
attrs: {
type: 'primary',
disabled: !vm.object.auto_push,
label: this.$t('common.Push')
},
callbacks: {
click: function({ row }) {
const theUrl = `/api/v1/assets/system-users/${vm.object.id}/tasks/`
const data = { action: 'push' }
this.$axios.post(theUrl, data).then(resp => {
window.open(`/#/ops/celery/task/${resp.task}/log/`, '', 'width=900,height=600')
})
}.bind(this)
}
}
],
nodeRelationConfig: {

View File

@@ -40,11 +40,16 @@ export default {
return <el-link onClick={onClick}>{ cellValue.length }</el-link>
}
},
command: {
showOverflowTooltip: true
},
user: {
formatter: DisplayFormatter
formatter: DisplayFormatter,
showOverflowTooltip: true
},
run_as: {
formatter: DisplayFormatter
formatter: DisplayFormatter,
showOverflowTooltip: true
},
is_finished: {
width: '100px'

View File

@@ -25,6 +25,9 @@ export default {
user: {
showOverflowTooltip: true
},
asset: {
showOverflowTooltip: true
},
system_user: {
showOverflowTooltip: true
},

View File

@@ -19,6 +19,9 @@ export default {
url: '/api/v1/audits/login-logs/',
columns: ['username', 'type', 'ip', 'city', 'user_agent', 'mfa', 'reason', 'status', 'datetime'],
columnsMeta: {
username: {
showOverflowTooltip: true
},
user_agent: {
width: '150px',
showOverflowTooltip: true
@@ -38,6 +41,9 @@ export default {
},
datetime: {
width: '160px'
},
reason: {
showOverflowTooltip: true
}
},
extraQuery: {

View File

@@ -19,6 +19,15 @@ export default {
url: '/api/v1/audits/operate-logs/',
columns: ['user', 'action', 'resource_type', 'resource', 'remote_addr', 'datetime'],
columnsMeta: {
user: {
showOverflowTooltip: true
},
resource_type: {
showOverflowTooltip: true
},
resource: {
showOverflowTooltip: true
},
datetime: {
width: '160px'
},

View File

@@ -19,6 +19,15 @@ export default {
url: '/api/v1/audits/password-change-logs/',
columns: ['user', 'change_by', 'remote_addr', 'datetime'],
columnsMeta: {
user: {
showOverflowTooltip: true
},
change_by: {
showOverflowTooltip: true
},
remote_addr: {
showOverflowTooltip: true
},
datetime: {
width: '180px'
}

View File

@@ -32,7 +32,7 @@ export default {
},
host_amount: {
label: this.$t('ops.hosts'),
width: '50px',
width: '65px',
formatter: function(row) {
return row.latest_execution.hosts_amount
}
@@ -50,14 +50,14 @@ export default {
},
date_start: {
label: this.$t('ops.date'),
width: '140px',
width: '150px',
formatter: function(row) {
return toSafeLocalDateStr(row.latest_execution.date_start)
}
},
time: {
label: this.$t('ops.time'),
width: '140px',
width: '100px',
formatter: function(row) {
return timeOffset(row.latest_execution.date_start, row.latest_execution.date_finished)
}

View File

@@ -31,7 +31,8 @@ export default {
routeQuery: {
activeTab: 'AssetPermissionDetail'
}
}
},
showOverflowTooltip: true
},
users_amount: {
label: this.$t('perms.User'),

View File

@@ -50,15 +50,7 @@ export default {
el: {
value: [],
ajax: {
url: '/api/v1/assets/system-users/',
processResults(data) {
let results = data.results
results = results.filter((item) => item.protocol === 'mysql').map((item) => {
return { label: item.name + '(' + item.username + ')', value: item.id }
})
const more = !!data.next
return { results: results, pagination: more, total: data.count }
}
url: '/api/v1/assets/system-users/?protocol=mysql'
}
}
},

View File

@@ -21,7 +21,8 @@ export default {
routeQuery: {
activeTab: 'DatabaseAppPermissionDetail'
}
}
},
showOverflowTooltip: true
},
users_amount: {
label: this.$t('perms.User'),

View File

@@ -20,6 +20,14 @@ export default {
'is_valid', 'actions'
],
columnsMeta: {
name: {
formatterArgs: {
routeQuery: {
activeTab: 'RemoteAppPermissionDetail'
}
},
showOverflowTooltip: true
},
users_amount: {
label: this.$t('users.Users'),
formatter: DetailFormatter,

View File

@@ -36,6 +36,7 @@ export default {
},
risk_level: {
label: this.$t('sessions.riskLevel'),
width: '120px',
formatter: (row, col, cellValue) => {
const display = row.risk_level_display
if (cellValue === 0) {
@@ -45,9 +46,19 @@ export default {
}
}
},
user: {
width: '140px'
},
asset: {
width: '140px'
},
system_user: {
width: '140px'
},
session: {
label: this.$t('sessions.session'),
formatter: DetailFormatter,
width: '80px',
formatterArgs: {
getTitle() {
return vm.$t('sessions.goto')
@@ -62,6 +73,7 @@ export default {
},
timestamp: {
label: this.$t('sessions.date'),
width: '150px',
formatter: function(row) {
return toSafeLocalDateStr(row.timestamp * 1000)
}

View File

@@ -9,6 +9,7 @@
:object="object"
:fields-meta="fieldsMeta"
:get-method="getMethod"
:on-perform-success="onPerformSuccess"
/>
</IBox>
</template>
@@ -115,6 +116,11 @@ export default {
},
getMethod() {
return 'put'
},
onPerformSuccess(res, method, vm) {
this.$emit('submitSuccess', res)
this.$message.success(this.$t('common.updateSuccessMsg'))
setTimeout(() => window.location.reload(), 500)
}
}
}

View File

@@ -45,7 +45,7 @@ export default {
prop: 'status',
label: this.$t('tickets.status'),
align: 'center',
width: '80px',
width: '100px',
sortable: 'custom',
formatter: row => {
if (row.status === 'open') {