Compare commits

..

69 Commits

Author SHA1 Message Date
Bryan
77ef172a23 Merge pull request #4320 from jumpserver/dev
v4.1.0
2024-08-15 21:42:42 +08:00
Bryan
4596887bf1 Merge pull request #4178 from jumpserver/dev
v4.0.0
2024-07-03 19:06:07 +08:00
Bryan
0a3dc30c85 Merge pull request #4072 from jumpserver/dev
v3.10.11-lts
2024-06-19 16:04:12 +08:00
Bryan
51d24bc8e5 Merge pull request #3941 from jumpserver/dev
v3.10.10-lts
2024-05-16 16:05:04 +08:00
Bryan
1b15a4d043 Merge pull request #3871 from jumpserver/dev
v3.10.9 (dev to master)
2024-04-22 19:44:33 +08:00
Bryan
7d3f818242 Merge pull request #3864 from jumpserver/v3.10
v3.10.8
2024-04-18 17:58:05 +08:00
Bryan
4e26f18d77 Merge pull request #3862 from jumpserver/dev
v3.10.8
2024-04-18 17:17:36 +08:00
Bryan
b22613617a Revert "build(deps): bump follow-redirects from 1.15.3 to 1.15.4"
This reverts commit e971cbf4a8.
2024-03-27 16:16:07 +08:00
dependabot[bot]
e971cbf4a8 build(deps): bump follow-redirects from 1.15.3 to 1.15.4
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-27 16:11:26 +08:00
wangruidong
4672abae35 fix: 刷新页面根据搜索条件过滤出对应的资源 2024-03-04 19:17:05 +08:00
Bryan
ba36d72602 Merge pull request #3761 from jumpserver/master
v3.10.4 (branch-v3.10)
2024-02-29 16:26:13 +08:00
Bryan
4bfbbba4c5 Merge pull request #3760 from jumpserver/dev
v3.10.4
2024-02-29 16:15:33 +08:00
Bryan
ea038ce43a Merge pull request #3697 from jumpserver/master
v3.10.2
2024-01-17 13:34:12 +00:00
Bryan
e16b19666c Merge pull request #3696 from jumpserver/dev
v3.10.2
2024-01-17 13:33:22 +00:00
Bryan
c7f5409eb6 Merge pull request #3694 from jumpserver/master
v3.10.2
2024-01-17 07:35:33 -04:00
Bryan
fdbd7d2222 Merge pull request #3693 from jumpserver/dev
v3.10.2
2024-01-17 07:24:50 -04:00
Bryan
ddbaeeafea Merge pull request #3668 from jumpserver/master
v3.10.1
2023-12-29 11:34:04 +05:00
Bryan
efb0e9dacb Merge pull request #3665 from jumpserver/dev
v3.10.1
2023-12-29 11:14:54 +05:00
huailei
f6f8301ad5 Revert "perf: 账号收集翻译"
This reverts commit 9a63ae63d4.
2023-12-22 15:25:31 +08:00
“huailei000”
9a63ae63d4 perf: 账号收集翻译 2023-12-22 11:31:45 +08:00
Bryan
1e007ccda3 Merge pull request #3642 from jumpserver/dev
v3.10
2023-12-21 15:15:52 +05:00
老广
d1d0b06b53 Merge pull request #3546 from jumpserver/dev
v3.9.0
2023-11-16 18:25:10 +08:00
Bryan
5fb70d2f24 Merge pull request #3450 from jumpserver/dev
v3.8.0
2023-10-19 03:33:53 -05:00
Bryan
b54a95430f Merge pull request #3404 from jumpserver/dev
v3.7.0
2023-09-21 17:04:42 +08:00
Bryan
4d8b4c45af Merge pull request #3355 from jumpserver/dev
v3.6.0
2023-08-17 14:00:33 +05:00
Bryan
a6d642df60 Merge pull request #3283 from jumpserver/dev
v3.5.0
2023-07-20 19:04:29 +08:00
Jiangjie.Bai
2e74f1522f Merge pull request #3222 from jumpserver/dev
v3.4.0
2023-06-15 14:51:36 +08:00
Jiangjie.Bai
fe615e0314 Merge pull request #3219 from jumpserver/dev
v3.4.0
2023-06-15 14:17:46 +08:00
Jiangjie.Bai
09f734e6fc Merge pull request #3135 from jumpserver/dev
v3.3.0
2023-05-18 19:18:11 +08:00
Jiangjie.Bai
3117046342 Merge pull request #3061 from jumpserver/dev
v3.2.0
2023-04-20 18:40:08 +08:00
Bai
b68aecb5cc fix: 批量更新资产平台help-text 2023-04-20 18:39:22 +08:00
Jiangjie.Bai
1c9b155d97 Merge pull request #3057 from jumpserver/dev
v3.2.0
2023-04-20 18:22:46 +08:00
Jiangjie.Bai
75b1be9864 Merge pull request #3019 from jumpserver/dev
v3.2.0 rc2
2023-04-14 19:01:37 +08:00
Jiangjie.Bai
615c3c1cf4 Merge pull request #3014 from jumpserver/dev
v3.2.0 rc1
2023-04-13 20:02:38 +08:00
Jiangjie.Bai
4d82231af4 Merge pull request #3012 from jumpserver/dev
v3.2.0 rc1
2023-04-13 19:22:38 +08:00
“huailei000”
c6cf6571b6 perf: ldap导入用户列表-组织下拉框设置最大宽度 2023-03-16 16:44:36 +08:00
Bai
8ea990d070 fix: 修复创建资产添加账号模版报错问题 2023-03-16 16:44:36 +08:00
“huailei000”
f4a32170d5 perf: message 2023-03-16 16:44:36 +08:00
ibuler
073508675e perf: 添加默认的信息 2023-03-16 16:44:36 +08:00
Jiangjie.Bai
1d6ca0a93a Merge pull request #2924 from jumpserver/dev
v3.1.0 rc4
2023-03-15 19:46:31 +08:00
Jiangjie.Bai
36aea652d6 Merge pull request #2788 from jumpserver/dev
v3.0.0
2023-02-23 20:16:41 +08:00
Jiangjie.Bai
1a42ce90ab Merge pull request #2760 from jumpserver/dev
v3.0.0-rc-latest
2023-02-22 22:21:54 +08:00
Jiangjie.Bai
31a401b55d Merge pull request #2463 from jumpserver/dev
v3.0.0-rc4
2023-01-31 18:55:34 +08:00
Jiangjie.Bai
582a84178d Merge pull request #2187 from jumpserver/dev
v2.28.0
2022-11-17 17:44:19 +08:00
Jiangjie.Bai
9b9f7c936c Merge pull request #2184 from jumpserver/dev
v2.28.0-rc5
2022-11-17 14:18:15 +08:00
Jiangjie.Bai
2a6100957f Merge pull request #2182 from jumpserver/dev
v2.28.0-rc4
2022-11-16 21:08:55 +08:00
Jiangjie.Bai
16606d6a27 Merge pull request #2176 from jumpserver/dev
v2.28.0-rc2
2022-11-14 10:01:05 +08:00
Jiangjie.Bai
0a612f50e6 Merge pull request #2164 from jumpserver/dev
v2.28.0-rc1
2022-11-10 17:45:47 +08:00
Jiangjie.Bai
fe36fa9390 Merge pull request #2117 from jumpserver/dev
v2.27.0-rc4
2022-10-18 21:02:10 +08:00
Jiangjie.Bai
ba109900ec Merge pull request #2113 from jumpserver/dev
v2.27.0-rc3
2022-10-18 11:20:57 +08:00
Jiangjie.Bai
ec7768267f Merge pull request #2105 from jumpserver/dev
v2.27.0-rc2
2022-10-14 11:01:32 +08:00
Jiangjie.Bai
cc58b374ab Merge pull request #2101 from jumpserver/dev
v2.27.0-rc1
2022-10-13 17:44:53 +08:00
Jiangjie.Bai
04ffbb8fd6 Merge pull request #2097 from jumpserver/dev
v2.27.0-rc1
2022-10-13 15:14:40 +08:00
Jiangjie.Bai
49880f6739 Merge pull request #2059 from jumpserver/dev
v2.26.0
2022-09-15 17:49:44 +08:00
Jiangjie.Bai
e6f98d58c4 Merge pull request #2057 from jumpserver/dev
v2.26.0-rc4
2022-09-15 16:18:03 +08:00
Jiangjie.Bai
fd1f16d43c Merge pull request #2050 from jumpserver/dev
v2.26.0-rc2
2022-09-13 17:41:39 +08:00
Jiangjie.Bai
968b2415b1 Merge pull request #2043 from jumpserver/dev
v2.26.0-rc1
2022-09-08 15:46:44 +08:00
Jiangjie.Bai
776090d6ba Merge pull request #2001 from jumpserver/dev
v2.25.0
2022-08-18 16:12:45 +08:00
Jiangjie.Bai
3a37952288 Merge pull request #1996 from jumpserver/dev
v2.25.0-rc4
2022-08-17 16:53:23 +08:00
Jiangjie.Bai
62b8fc0e3b Merge pull request #1994 from jumpserver/dev
v2.25.0-rc3
2022-08-16 19:08:23 +08:00
Jiangjie.Bai
b2028869cb Merge pull request #1986 from jumpserver/dev
v2.25.0-rc2
2022-08-12 18:06:56 +08:00
Jiangjie.Bai
5277a725f8 Merge pull request #1973 from jumpserver/dev
v2.25.0-rc1
2022-08-11 14:11:59 +08:00
Jiangjie.Bai
f137788c1a Merge pull request #1957 from jumpserver/dev
v2.24.0-rc5
2022-07-20 19:06:03 +08:00
Jiangjie.Bai
f7d17c8de7 Merge pull request #1954 from jumpserver/dev
v2.24.0-rc4
2022-07-19 16:18:13 +08:00
Jiangjie.Bai
feea70b0be Merge pull request #1944 from jumpserver/dev
v2.24.0-rc3
2022-07-18 12:05:42 +08:00
Jiangjie.Bai
04696ef3d6 Merge pull request #1940 from jumpserver/dev
v2.24.0-rc2
2022-07-15 18:07:37 +08:00
Jiangjie.Bai
1731f4f788 Merge pull request #1934 from jumpserver/dev
v2.24.0-rc1
2022-07-14 18:27:51 +08:00
Jiangjie.Bai
6f25d93909 Merge pull request #1931 from jumpserver/dev
v2.24.0-rc1
2022-07-14 17:51:58 +08:00
Jiangjie.Bai
46461ec324 Merge pull request #1925 from jumpserver/dev
v2.24.0-rc1
2022-07-14 15:12:15 +08:00
56 changed files with 302 additions and 662 deletions

View File

@@ -15,13 +15,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Lock Pull Request
run: |
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d '{"state":"pending", "description":"Action running, merge disabled", "context":"Lock PR"}' \
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -64,9 +59,3 @@ jobs:
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Unlock Pull Request
run: |
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d '{"state":"success", "description":"Action running, merge disabled", "context":"Lock PR"}' \
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"

View File

@@ -31,7 +31,7 @@ jobs:
tag: ${{ steps.get_version.outputs.TAG }}
- uses: actions/setup-node@v2
with:
node-version: '20.15'
node-version: '16.20'
- name: Install dependencies
run: yarn install
- name: Build web

View File

@@ -96,7 +96,7 @@
"@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "^9.5.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.2",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"chalk": "2.4.2",
"compression-webpack-plugin": "^6.1.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 940 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -37,10 +37,6 @@ export default {
type: String,
default: '/api/v1/assets/assets/'
},
defaultPageSize: {
type: Number,
default: 10
},
baseNodeUrl: {
type: String,
default: '/api/v1/assets/nodes/'
@@ -74,7 +70,6 @@ export default {
value: iValue,
multiple: true,
clearable: true,
defaultPageSize: this.defaultPageSize,
ajax: {
url: this.baseUrl,
transformOption: (item) => {

View File

@@ -197,24 +197,6 @@ export class FormFieldGenerator {
return field
}
setChoicesTips(field, fieldMeta, fieldRemoteMeta) {
// 设置 checkbox 的 tips
if (['checkbox-group', 'radio-group'].indexOf(field.type) !== -1) {
field.options.map(option => {
if (!option.tip && field.tips) {
option.tip = field.tips[option.value]
}
if (!option.tip) {
const match = option.label.match(/^(.+?)\s*\((.*?)\)$/)
if (match) {
option.label = match[1]
option.tip = match[2]
}
}
})
}
}
afterGenerateField(field) {
field.label = toSentenceCase(field.label)
@@ -222,7 +204,15 @@ export class FormFieldGenerator {
field.el.placeholder = field.placeholder
}
this.setChoicesTips(field)
// 设置 checkbox 的 tips
if (field.tips && ['checkbox-group', 'radio-group'].indexOf(field.type) !== -1) {
field.options.map(option => {
if (!option.tip && field.tips[option.value]) {
option.tip = field.tips[option.value]
}
})
}
return field
}

View File

@@ -125,19 +125,16 @@ export default {
allowCreate: {
type: Boolean,
default: false
},
defaultPageSize: {
type: Number,
default: 10
}
},
data() {
const vm = this
const defaultPageSize = 10
const defaultParams = {
search: '',
page: 1,
hasMore: true,
pageSize: vm.defaultPageSize
pageSize: defaultPageSize
}
// 设置axios全局报错提示不显示
const validateStatus = (status) => {
@@ -197,6 +194,7 @@ export default {
}
},
iAjax() {
const defaultPageSize = 10
const defaultMakeParams = (params) => {
const page = params.page || 1
const offset = (page - 1) * params.pageSize
@@ -239,7 +237,7 @@ export default {
}
const defaultAjax = {
url: '',
pageSize: this.defaultPageSize,
pageSize: defaultPageSize,
makeParams: defaultMakeParams,
transformOption: defaultTransformOption,
processResults: defaultProcessResults,

View File

@@ -44,9 +44,8 @@
import DataTable from '@/components/Table/DataTable/index.vue'
import { getUpdateObjURL } from '@/utils/common'
import { sleep } from '@/utils/time'
import { EditableInputFormatter } from '@/components/Table/TableFormatters'
import { EditableInputFormatter, StatusFormatter } from '@/components/Table/TableFormatters'
import { encryptPassword } from '@/utils/crypto'
import getStatusColumnMeta from '@/components/Table/ListTable/TableAction/const'
export default {
name: 'ImportTable',
@@ -224,7 +223,38 @@ export default {
},
methods: {
generateTableColumns(tableTitles, tableData) {
const columns = [{ ...getStatusColumnMeta.bind(this)().status }]
const vm = this
const columns = [{
prop: '@status',
label: vm.$t('Status'),
width: '80px',
align: 'center',
formatter: StatusFormatter,
formatterArgs: {
faChoices: {
ok: 'fa-check text-primary',
error: 'fa-times text-danger',
pending: 'fa-clock-o'
},
getChoicesKey(val) {
if (val === 'ok' || val === 'pending') {
return val
}
return 'error'
},
getTip(val) {
if (val === 'ok') {
return vm.$t('Success')
} else if (val === 'pending') {
return vm.$t('Pending')
} else if (val && val.name === 'error') {
return val.error
}
return ''
},
hasTips: true
}
}]
for (const item of tableTitles) {
const dataItemLens = tableData.map(d => {
if (!d) {

View File

@@ -1,40 +0,0 @@
import { StatusFormatter } from '@/components/Table/TableFormatters'
import i18n from '@/i18n/i18n'
export const getStatusColumnMeta = (prop = '@status') => {
return {
status: {
prop: prop,
label: i18n.t('Status'),
width: '80px',
align: 'center',
formatter: StatusFormatter,
formatterArgs: {
faChoices: {
ok: 'fa-check text-primary',
error: 'fa-times text-danger',
pending: 'fa-clock-o'
},
getChoicesKey: (val) => {
if (val === 'ok' || val === 'pending') {
return val
}
return 'error'
},
getTip: (val) => {
if (val === 'ok') {
return i18n.t('Success')
} else if (val === 'pending') {
return i18n.t('Pending')
} else if ((val && val.name === 'error') || val.error !== undefined) {
return val.error
}
return ''
},
hasTips: true
}
}
}
}
export default getStatusColumnMeta

View File

@@ -189,23 +189,22 @@ export default {
}
},
mounted() {
this.$set(this.urlUpdated, this.tableUrl, location.href)
this.urlUpdated[this.tableUrl] = location.href
},
deactivated() {
this.isDeactivated = true
},
activated() {
this.$nextTick(() => {
this.isDeactivated = false
const cleanUrl = this.tableUrl.split('?')[0]
const preURL = this.urlUpdated[cleanUrl]
if (!preURL || preURL === location.href) return
this.$set(this.urlUpdated, this.tableUrl, location.href)
this.$log.debug('Reload the table get latest data: pre ', preURL, ' current: ', location.href)
this.isDeactivated = false
const preURL = this.urlUpdated[this.tableUrl]
if (!preURL || preURL === location.href) {
return
}
this.urlUpdated[this.tableUrl] = location.href
this.$log.debug('Reload the table get latest data: pre ', preURL, ' current: ', location.href)
setTimeout(() => {
this.reloadTable()
})
}, 500)
},
methods: {
handleActionInitialDone() {

View File

@@ -234,10 +234,12 @@ export default {
delete routeFilter.search
}
const asFilterTags = _.cloneDeep(this.filterTags)
this.filterTags = {
...asFilterTags,
...routeFilter
}
setTimeout(() => {
this.filterTags = {
...asFilterTags,
...routeFilter
}
}, 100)
},
getValueLabel(key, value) {
for (const field of this.options) {

View File

@@ -39,7 +39,7 @@ export default {
showRenameBtn: false,
drag: {
isCopy: false,
isMove: !this.$store.getters.currentOrgIsRoot
isMove: true
}
},
callback: {

View File

@@ -35,29 +35,13 @@ export default {
]),
announcement() {
const ann = this.publicSettings.ANNOUNCEMENT
return {
id: ann['ID'],
subject: ann['SUBJECT'],
content: ann['CONTENT'],
link: ann['LINK'],
date_start: ann['DATE_START'],
date_end: ann['DATE_END']
}
return { id: ann['ID'], subject: ann['SUBJECT'], content: ann['CONTENT'], link: ann['LINK'] }
},
enabled() {
return this.publicSettings.ANNOUNCEMENT_ENABLED && (this.announcement.content || this.announcement.subject) && this.isDateValid
return this.publicSettings.ANNOUNCEMENT_ENABLED && (this.announcement.content || this.announcement.subject)
},
title() {
return this.$t('Announcement') + ': ' + this.announcement.subject
},
isDateValid() {
if (this.announcement.date_start === undefined || this.announcement.date_end === undefined) {
return true
}
const now = new Date()
const start = new Date(this.announcement.date_start)
const end = new Date(this.announcement.date_end)
return now >= start && now <= end
}
},
methods: {

View File

@@ -33,13 +33,11 @@ export default {
query[k] = v
}
let key
if (this.$route.name.toLowerCase().includes('list')) {
key = _.trimEnd(this.$route.path, '/') + '?' + new URLSearchParams(query).toString()
return _.trimEnd(this.$route.path, '/') + '?' + new URLSearchParams(query).toString()
} else {
key = new Date().getTime()
return new Date().getTime()
}
return key
},
chatAiEnabled() {
return this.publicSettings?.CHAT_AI_ENABLED

View File

@@ -66,15 +66,11 @@ export default {
break
case 'logout':
this.logout()
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
break
}
},
async logout() {
const currentOrg = this.$store.getters.currentOrg
if (currentOrg.autoEnter) {
await this.$store.dispatch('users/setCurrentOrg', this.$store.getters.preOrg)
}
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
logout() {
}
}
}

View File

@@ -70,7 +70,7 @@
<span class="msg-detail-time">{{ formatDate(currentMsg.date_created) }}</span>
</div>
<div class="msg-detail-txt">
<MarkDown :value="currentMsg.content.message" />
<span v-sanitize="currentMsg.content.message" />
</div>
</div>
</Dialog>
@@ -80,14 +80,10 @@
<script>
import { toSafeLocalDateStr } from '@/utils/time'
import Dialog from '@/components/Dialog'
import MarkDown from '@/components/Widgets/MarkDown'
export default {
name: 'SiteMessages',
components: {
Dialog,
MarkDown
},
components: { Dialog },
data() {
return {
show: false,

View File

@@ -46,7 +46,7 @@
<el-alert v-if="helpMessage" type="success">
<span v-sanitize="helpMessage" class="announcement-main" />
</el-alert>
<transition appear mode="out-in" name="fade-transform">
<transition v-if="!loading" appear mode="out-in" name="fade-transform">
<slot>
<keep-alive>
<component :is="computeActiveComponent" />
@@ -83,18 +83,16 @@ export default {
},
data() {
return {
loading: false,
toSentenceCase: toSentenceCase,
activeTab: this.activeMenu
loading: true,
toSentenceCase: toSentenceCase
}
},
computed: {
iActiveMenu: {
get() {
return this.activeTab
return this.activeMenu
},
set(item) {
this.activeTab = item
this.$emit('update:activeMenu', item)
}
},
@@ -121,13 +119,16 @@ export default {
},
watch: {
$route(to, from) {
// 好像没必要
// const activeTab = to.query?.tab
// if (activeTab && this.iActiveMenu !== activeTab) {
// this.iActiveMenu = activeTab
// }
const activeTab = to.query?.tab
if (activeTab && this.iActiveMenu !== activeTab) {
this.iActiveMenu = activeTab
}
}
},
activated() {
this.iActiveMenu = this.getPropActiveTab()
this.loading = false
},
created() {
this.iActiveMenu = this.getPropActiveTab()
this.loading = false
@@ -135,8 +136,15 @@ export default {
methods: {
handleTabClick(tab) {
this.$emit('tab-click', tab)
this.iActiveMenu = tab.name
this.$emit('update:activeMenu', tab.name)
this.$cookie.set(this.$route.path, tab.name, 1)
if (this.$router.currentRoute.query[this.$route.path]) {
this.$router.push({
query: { ...this.$route.query, [this.$route.path]: '' }
})
}
},
getPropActiveTab() {
let activeTab = ''

View File

@@ -24,9 +24,6 @@ async function checkLogin({ to, from, next }) {
} catch (e) {
Vue.$log.error(e)
const status = e.response.status
if (store.getters.currentOrg.autoEnter) {
await store.dispatch('users/setCurrentOrg', store.getters.preOrg)
}
if (status === 401 || status === 403) {
setTimeout(() => {
window.location = process.env.VUE_APP_LOGIN_PATH

View File

@@ -60,7 +60,7 @@ export default {
}
},
reviewers: {
hidden: (item) => !['review', 'warning', 'notify_and_warn'].includes(item.action),
hidden: (item) => !['review', 'warning'].includes(item.action),
rules: [rules.RequiredChange],
el: {
value: [],

View File

@@ -25,17 +25,17 @@ export default {
const platform = this.$route.query.type
const baseFields = [[this.$t('Basic'), ['db_name']]]
let tlsFields = ['use_ssl', 'ca_cert']
const platformFieldsMap = {
redis: ['client_cert', 'client_key'],
postgresql: ['client_cert', 'client_key', 'allow_invalid_cert'],
mysql: ['client_cert', 'client_key', 'allow_invalid_cert'],
mongodb: ['client_key', 'allow_invalid_cert']
switch (platform) {
case 'redis':
tlsFields = tlsFields.concat(['client_cert', 'client_key'])
break
case 'mysql':
tlsFields = tlsFields.concat(['client_cert', 'client_key', 'allow_invalid_cert'])
break
case 'mongodb':
tlsFields = tlsFields.concat(['client_key', 'allow_invalid_cert'])
break
}
if (platformFieldsMap[platform]) {
tlsFields = tlsFields.concat(platformFieldsMap[platform])
}
if (tlsFields.length > 2) {
const secureField = [
this.$t('Secure'), tlsFields, 2

View File

@@ -22,17 +22,17 @@
:key="platform.id"
:span="6"
>
<el-tooltip :content="platform.name" :open-delay="1000">
<el-card
:style="{ borderLeftColor: randomBorderColor(index) }"
class="platform-item"
shadow="hover"
@click.native="createAsset(platform)"
>
<img :src="loadImage(platform)" alt="icon" class="asset-icon">
<el-card
:style="{ borderLeftColor: randomBorderColor(index) }"
class="platform-item"
shadow="hover"
@click.native="createAsset(platform)"
>
<img :src="loadImage(platform)" alt="icon" class="asset-icon">
<el-tooltip :content="platform.name">
<span class="platform-name">{{ platform.name }}</span>
</el-card>
</el-tooltip>
</el-tooltip>
</el-card>
</el-col>
</el-collapse-item>
</el-collapse>
@@ -236,8 +236,8 @@ export default {
}
.asset-icon {
width: 2em;
height: 2em;
width: 1.5em;
height: 1.5em;
vertical-align: -0.2em;
fill: currentColor;
}

View File

@@ -89,15 +89,14 @@ export default {
},
methods: {
handleTabClick(tab) {
// 这样不行,会闪
// const query = _.cloneDeep(this.$route.query)
// const newQuery = {
// ...query,
// tab: tab.name
// }
// this.$nextTick(() => {
// this.$router.replace({ query: newQuery })
// })
const query = _.cloneDeep(this.$route.query)
const newQuery = {
...query,
tab: tab.name
}
this.$nextTick(() => {
this.$router.replace({ query: newQuery })
})
}
}
}

View File

@@ -11,10 +11,11 @@ export default {
BaseAssetCreateUpdate
},
data() {
const platformType = this.$route.query.platform_type
return {
url: '/api/v1/assets/gateways/',
updateInitial: async(initial) => {
const url = `/api/v1/assets/platforms/?name__startswith=Gateway`
const url = `/api/v1/assets/platforms/?name=Gateway`
const platform = await this.$axios.get(url)
initial.platform = parseInt(platform[0].id)
initial.domain = this.$route.query.domain
@@ -25,11 +26,11 @@ export default {
disabled: true
},
platform: {
helpText: this.$t('GatewayPlatformHelpText'),
disabled: true,
el: {
multiple: false,
ajax: {
url: `/api/v1/assets/platforms/?name__startswith=Gateway`,
url: `/api/v1/assets/platforms/?type=${platformType}`,
transformOption: (item) => {
return { label: item.name, value: item.id }
}

View File

@@ -32,7 +32,7 @@ export default {
width: '60%',
tableConfig: {
hasSelection: false,
url: `/api/v1/ops/adhocs/?only_mine=true`,
url: `/api/v1/ops/adhocs/`,
columns: ['name', 'module', 'args', 'comment', 'actions'],
columnsMeta: {
name: {

View File

@@ -83,7 +83,7 @@ export default {
multiple: false,
value: [],
ajax: {
url: `/api/v1/ops/playbooks/?only_mine=true`,
url: '/api/v1/ops/playbooks/',
transformOption: (item) => {
return { label: item.name, value: item.id }
}

View File

@@ -11,13 +11,12 @@ export default {
GenericListTable
},
data() {
const currentUserID = this.$store.state.users.profile.id
return {
tableConfig: {
url: '/api/v1/ops/adhocs/',
columnsShow: {
min: ['name', 'actions'],
default: ['name', 'module', 'args', 'comment', 'scope', 'date_created', 'actions']
default: ['name', 'module', 'args', 'comment', 'date_created', 'actions']
},
columnsMeta: {
name: {
@@ -30,14 +29,10 @@ export default {
formatter: ActionsFormatter,
formatterArgs: {
hasUpdate: true,
canUpdate: ({ row }) => {
return this.$hasPerm('ops.change_adhoc') && row.creator === currentUserID
},
canUpdate: this.$hasPerm('ops.change_adhoc'),
updateRoute: 'AdhocUpdate',
hasDelete: true,
canDelete: ({ row }) => {
return this.$hasPerm('ops.delete_adhoc') && row.creator === currentUserID
},
canDelete: this.$hasPerm('ops.delete_adhoc'),
hasClone: false
}
}

View File

@@ -14,7 +14,7 @@ export default {
return {
url: '/api/v1/ops/adhocs/',
fields: [
[this.$t('Basic'), ['name', 'module', 'args', 'comment', 'scope']]
[this.$t('Basic'), ['name', 'module', 'args', 'comment']]
],
initial: {
module: 'shell',

View File

@@ -16,7 +16,6 @@ export default {
GenericListTable
},
data() {
const currentUserID = this.$store.state.users.profile.id
return {
createDialogVisible: false,
uploadDialogVisible: false,
@@ -24,7 +23,7 @@ export default {
url: '/api/v1/ops/playbooks/',
columnsShow: {
min: ['name', 'actions'],
default: ['name', 'comment', 'scope', 'date_created', 'actions']
default: ['name', 'comment', 'date_created', 'actions']
},
columnsMeta: {
name: {
@@ -37,15 +36,11 @@ export default {
formatter: ActionsFormatter,
formatterArgs: {
hasUpdate: true,
canUpdate: ({ row }) => {
return this.$hasPerm('ops.change_playbook') && row.creator === currentUserID
},
canUpdate: this.$hasPerm('ops.change_playbook'),
updateRoute: 'PlaybookUpdate',
hasDelete: true,
canDelete: ({ row }) => {
return this.$hasPerm('ops.delete_playbook') && row.creator === currentUserID
},
hasClone: true
canDelete: this.$hasPerm('ops.delete_playbook'),
hasClone: false
}
}
}

View File

@@ -13,7 +13,7 @@ export default {
return {
url: '/api/v1/ops/playbooks/',
fields: [
[this.$t('Basic'), ['name', 'comment', 'scope']]
[this.$t('Basic'), ['name', 'comment']]
],
createSuccessNextRoute: {
name: 'Template'

View File

@@ -2,7 +2,7 @@
<div>
<NewNodeDialog v-if="createDialogVisible" :visible.sync="createDialogVisible" @confirm="doCreate" />
<TreeTable ref="TreeTable" :tree-setting="treeSetting">
<template v-if="!disableEdit" slot="rMenu">
<template slot="rMenu">
<li id="m_create_file" class="rmenu" tabindex="-1" @click="onCreate('file')">
{{ $tc('NewFile') }}
</li>
@@ -62,9 +62,7 @@ export default {
}
},
data() {
const disableEdit = this.object.creator !== this.$store.state.users.profile.id
return {
disableEdit: disableEdit,
newNode: {},
createDialogVisible: false,
createType: 'directory',
@@ -72,8 +70,7 @@ export default {
closing: false,
DataZTree: 0,
cmOptions: {
mode: 'yaml',
readOnly: disableEdit
mode: 'yaml'
},
toolbar: {
left: {
@@ -85,7 +82,6 @@ export default {
el: {
type: 'primary'
},
isVisible: disableEdit,
callback: () => {
this.onSave()
}
@@ -98,7 +94,6 @@ export default {
el: {
type: 'primary'
},
isVisible: disableEdit,
callback: () => {
this.onReset()
}

View File

@@ -76,8 +76,6 @@ export default {
}],
el: {
value: [],
defaultPageSize: 300,
baseUrl: '/api/v1/assets/assets/?fields_size=mini',
treeSetting: {
showSearch: false,
showRefresh: false

View File

@@ -1,103 +0,0 @@
<template>
<Dialog
:destroy-on-close="true"
:show-cancel="false"
:show-confirm="false"
:title="$tc('SyncSetting')"
top="10%"
v-bind="$attrs"
width="50%"
v-on="$listeners"
>
<GenericCreateUpdateForm
:has-detail-in-msg="false"
v-bind="settings"
@submitSuccess="onSuccess"
/>
</Dialog>
</template>
<script>
import { GenericCreateUpdateForm } from '@/layout/components'
import { CronTab, Dialog } from '@/components'
import Select2 from '@/components/Form/FormFields/Select2.vue'
import { Required } from '@/components/Form/DataForm/rules'
export default {
name: 'SyncSettingDialog',
components: {
GenericCreateUpdateForm,
Dialog
},
data() {
return {
settings: {
visible: false,
url: '/api/v1/settings/setting/?category=ldap_ha',
fields: [
'AUTH_LDAP_HA_SYNC_ORG_IDS', 'AUTH_LDAP_HA_SYNC_IS_PERIODIC', 'AUTH_LDAP_HA_SYNC_CRONTAB',
'AUTH_LDAP_HA_SYNC_INTERVAL', 'AUTH_LDAP_HA_SYNC_RECEIVERS'
],
fieldsMeta: {
AUTH_LDAP_HA_SYNC_ORG_IDS: {
component: Select2,
rules: [Required],
el: {
popperClass: 'sync-setting-org',
multiple: true,
ajax: {
url: '/api/v1/orgs/orgs/',
transformOption: (item) => {
return { label: item.name, value: item.id }
}
}
},
hidden: (formValue) => {
return !this.$hasLicense()
}
},
AUTH_LDAP_HA_SYNC_IS_PERIODIC: {
type: 'switch'
},
AUTH_LDAP_HA_SYNC_CRONTAB: {
component: CronTab,
helpTip: this.$t('CrontabOfCreateUpdatePage')
},
AUTH_LDAP_HA_SYNC_INTERVAL: {
helpText: this.$t('IntervalOfCreateUpdatePage')
},
AUTH_LDAP_HA_SYNC_RECEIVERS: {
component: Select2,
el: {
value: [],
multiple: true,
ajax: {
url: '/api/v1/users/users/?fields_size=mini&oid=ROOT',
transformOption: (item) => {
return { label: item.name + '(' + item.username + ')', value: item.id }
}
}
}
}
},
submitMethod: () => 'patch',
cleanFormValue(value) {
if (value['AUTH_LDAP_HA_SYNC_INTERVAL'] === '') {
value['AUTH_LDAP_HA_SYNC_INTERVAL'] = null
}
return value
}
}
}
},
methods: {
onSuccess() {
this.$emit('update:visible', false)
}
}
}
</script>
<style scoped>
</style>

View File

@@ -49,7 +49,6 @@ import { DEFAULT_ORG_ID, SYSTEM_ORG_ID } from '@/utils/org'
import ListTable from '@/components/Table/ListTable/index.vue'
import Dialog from '@/components/Dialog/index.vue'
import Select2 from '@/components/Form/FormFields/Select2.vue'
import getStatusColumnMeta from '@/components/Table/ListTable/TableAction/const'
export default {
name: 'ImportDialog',
@@ -58,12 +57,6 @@ export default {
Dialog,
Select2
},
props: {
category: {
type: String,
required: true
}
},
data() {
return {
dialogLdapUserImportLoginStatus: false,
@@ -82,10 +75,9 @@ export default {
}
},
tableConfig: {
url: `/api/v1/settings/ldap/users/?category=${this.category}`,
columns: ['status', 'username', 'name', 'email', 'groups', 'existing'],
url: '/api/v1/settings/ldap/users/',
columns: ['username', 'name', 'email', 'groups', 'existing'],
columnsMeta: {
...getStatusColumnMeta.bind(this)('status'),
username: {
label: this.$t('Username'),
width: '180px'
@@ -197,7 +189,7 @@ export default {
enableWS() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws'
const port = document.location.port ? ':' + document.location.port : ''
const url = `/ws/ldap/?category=${this.category}`
const url = '/ws/ldap/'
const wsURL = scheme + '://' + document.location.hostname + port + url
this.ws = new WebSocket(wsURL)
},

View File

@@ -1,151 +0,0 @@
<template>
<IBox>
<GenericCreateUpdateForm v-bind="$data" />
<ImportDialog v-if="dialogLdapUserImport" :category="category" :visible.sync="dialogLdapUserImport" />
<TestLoginDialog :visible.sync="dialogTest" :category="category" />
<SyncSettingDialog :visible.sync="dialogSyncSetting" />
</IBox>
</template>
<script>
import GenericCreateUpdateForm from '@/layout/components/GenericCreateUpdateForm/index.vue'
import ImportDialog from './ImportDialog.vue'
import TestLoginDialog from './TestLoginDialog.vue'
import SyncSettingDialog from './SyncSettingDialog.vue'
import { IBox } from '@/components'
import rules, { JsonRequired } from '@/components/Form/DataForm/rules'
import { JsonEditor, UpdateToken } from '@/components/Form/FormFields'
export default {
name: 'Ldap',
components: {
GenericCreateUpdateForm,
IBox,
ImportDialog,
TestLoginDialog,
SyncSettingDialog
},
data() {
const category = 'ldap'
return {
category: category,
url: `/api/v1/settings/setting/?category=${category}`,
dialogTest: false,
dialogLdapUserImport: false,
dialogSyncSetting: false,
encryptedFields: ['AUTH_LDAP_BIND_PASSWORD'],
fields: [
[
this.$t('Basic'),
[
'AUTH_LDAP', 'AUTH_LDAP_SERVER_URI',
'AUTH_LDAP_BIND_DN', 'AUTH_LDAP_BIND_PASSWORD'
]
],
[
this.$t('Search'),
[
'AUTH_LDAP_SEARCH_OU', 'AUTH_LDAP_SEARCH_FILTER',
'AUTH_LDAP_USER_ATTR_MAP'
]
],
[
this.$t('Other'),
[
'AUTH_LDAP_CONNECT_TIMEOUT', 'AUTH_LDAP_SEARCH_PAGED_SIZE',
'AUTH_LDAP_CACHE_TIMEOUT'
]
]
],
fieldsMeta: {
AUTH_LDAP_BIND_DN: {
rules: [
rules.Required
]
},
AUTH_LDAP_BIND_PASSWORD: {
component: UpdateToken
},
AUTH_LDAP_SEARCH_OU: {
rules: [
rules.Required
]
},
AUTH_LDAP_USER_ATTR_MAP: {
component: JsonEditor,
rules: [JsonRequired]
}
},
hasDetailInMsg: false,
moreButtons: [
{
title: this.$t('LdapConnectTest'),
loading: false,
callback: function(value, form, btn) {
if (value['AUTH_LDAP_BIND_PASSWORD'] === undefined) {
value['AUTH_LDAP_BIND_PASSWORD'] = ''
}
btn.loading = true
this.enableWS()
this.ws.onopen = (e) => {
this.ws.send(JSON.stringify({ msg_type: 'testing_config', ...value }))
}
this.ws.onmessage = (e) => {
const data = JSON.parse(e.data)
if (data.ok) {
this.$message.success(data.msg)
} else {
this.$message.error(data.msg)
}
btn.loading = false
}
}.bind(this)
},
{
title: this.$t('LdapLoginTest'),
callback: function(value, form) {
this.dialogTest = true
}.bind(this)
},
{
title: this.$t('LdapBulkImport'),
callback: function(value, form) {
this.dialogLdapUserImport = true
}.bind(this)
},
{
title: this.$t('SyncSetting'),
callback: function(value, form) {
this.dialogSyncSetting = true
}.bind(this)
}
],
submitMethod: () => 'patch',
afterGetFormValue(obj) {
return obj
},
cleanFormValue(data) {
if (data['AUTH_LDAP_BIND_PASSWORD'] === '') {
delete data['AUTH_LDAP_BIND_PASSWORD']
}
return data
}
}
},
methods: {
enableWS() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws'
const port = document.location.port ? ':' + document.location.port : ''
const url = '/ws/ldap/'
const wsURL = scheme + '://' + document.location.hostname + port + url
this.ws = new WebSocket(wsURL)
}
}
}
</script>
<style scoped>
.listTable ::v-deep .table-action-right-side {
padding-top: 0 !important;
}
</style>

View File

@@ -1,151 +0,0 @@
<template>
<IBox>
<GenericCreateUpdateForm v-bind="$data" />
<ImportDialog v-if="dialogLdapUserImport" :category="category" :visible.sync="dialogLdapUserImport" />
<TestLoginDialog :visible.sync="dialogTest" :category="category" />
<SyncSettingDialog :visible.sync="dialogSyncSetting" />
</IBox>
</template>
<script>
import GenericCreateUpdateForm from '@/layout/components/GenericCreateUpdateForm/index.vue'
import ImportDialog from './ImportDialog.vue'
import TestLoginDialog from './TestLoginDialog.vue'
import SyncSettingDialog from './HaSyncSettingDialog.vue'
import { IBox } from '@/components'
import rules, { JsonRequired } from '@/components/Form/DataForm/rules'
import { JsonEditor, UpdateToken } from '@/components/Form/FormFields'
export default {
name: 'LdapHA',
components: {
GenericCreateUpdateForm,
IBox,
ImportDialog,
TestLoginDialog,
SyncSettingDialog
},
data() {
const category = 'ldap_ha'
return {
category: category,
url: `/api/v1/settings/setting/?category=${category}`,
dialogTest: false,
dialogLdapUserImport: false,
dialogSyncSetting: false,
encryptedFields: ['AUTH_LDAP_HA_BIND_PASSWORD'],
fields: [
[
this.$t('Basic'),
[
'AUTH_LDAP_HA', 'AUTH_LDAP_HA_SERVER_URI',
'AUTH_LDAP_HA_BIND_DN', 'AUTH_LDAP_HA_BIND_PASSWORD'
]
],
[
this.$t('Search'),
[
'AUTH_LDAP_HA_SEARCH_OU', 'AUTH_LDAP_HA_SEARCH_FILTER',
'AUTH_LDAP_HA_USER_ATTR_MAP'
]
],
[
this.$t('Other'),
[
'AUTH_LDAP_HA_CONNECT_TIMEOUT', 'AUTH_LDAP_HA_SEARCH_PAGED_SIZE',
'AUTH_LDAP_HA_CACHE_TIMEOUT'
]
]
],
fieldsMeta: {
AUTH_LDAP_HA_BIND_DN: {
rules: [
rules.Required
]
},
AUTH_LDAP_HA_BIND_PASSWORD: {
component: UpdateToken
},
AUTH_LDAP_HA_SEARCH_OU: {
rules: [
rules.Required
]
},
AUTH_LDAP_HA_USER_ATTR_MAP: {
component: JsonEditor,
rules: [JsonRequired]
}
},
hasDetailInMsg: false,
moreButtons: [
{
title: this.$t('LdapConnectTest'),
loading: false,
callback: function(value, form, btn) {
if (value['AUTH_LDAP_HA_BIND_PASSWORD'] === undefined) {
value['AUTH_LDAP_HA_BIND_PASSWORD'] = ''
}
btn.loading = true
this.enableWS()
this.ws.onopen = (e) => {
this.ws.send(JSON.stringify({ msg_type: 'testing_config', ...value }))
}
this.ws.onmessage = (e) => {
const data = JSON.parse(e.data)
if (data.ok) {
this.$message.success(data.msg)
} else {
this.$message.error(data.msg)
}
btn.loading = false
}
}.bind(this)
},
{
title: this.$t('LdapLoginTest'),
callback: function(value, form) {
this.dialogTest = true
}.bind(this)
},
{
title: this.$t('LdapBulkImport'),
callback: function(value, form) {
this.dialogLdapUserImport = true
}.bind(this)
},
{
title: this.$t('SyncSetting'),
callback: function(value, form) {
this.dialogSyncSetting = true
}.bind(this)
}
],
submitMethod: () => 'patch',
afterGetFormValue(obj) {
return obj
},
cleanFormValue(data) {
if (data['AUTH_LDAP_HA_BIND_PASSWORD'] === '') {
delete data['AUTH_LDAP_HA_BIND_PASSWORD']
}
return data
}
}
},
methods: {
enableWS() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws'
const port = document.location.port ? ':' + document.location.port : ''
const url = `/ws/ldap/?category=${this.category}`
const wsURL = scheme + '://' + document.location.hostname + port + url
this.ws = new WebSocket(wsURL)
}
}
}
</script>
<style scoped>
.listTable ::v-deep .table-action-right-side {
padding-top: 0 !important;
}
</style>

View File

@@ -40,12 +40,6 @@ export default {
components: {
Dialog
},
props: {
category: {
type: String,
required: true
}
},
data() {
return {
testLdapLoginStatus: false,
@@ -75,7 +69,7 @@ export default {
enableWS() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws'
const port = document.location.port ? ':' + document.location.port : ''
const url = `/ws/ldap/?category=${this.category}`
const url = '/ws/ldap/'
const wsURL = scheme + '://' + document.location.hostname + port + url
this.ws = new WebSocket(wsURL)
}

View File

@@ -1 +1,152 @@
<template>
<IBox>
<GenericCreateUpdateForm v-bind="$data" />
<ImportDialog v-if="dialogLdapUserImport" :visible.sync="dialogLdapUserImport" />
<TestLoginDialog :visible.sync="dialogTest" />
<SyncSettingDialog :visible.sync="dialogSyncSetting" />
</IBox>
</template>
<script>
import GenericCreateUpdateForm from '@/layout/components/GenericCreateUpdateForm/index.vue'
import ImportDialog from './ImportDialog.vue'
import TestLoginDialog from './TestLoginDialog.vue'
import SyncSettingDialog from './SyncSettingDialog.vue'
import { IBox } from '@/components'
import rules, { JsonRequired } from '@/components/Form/DataForm/rules'
import { JsonEditor, UpdateToken } from '@/components/Form/FormFields'
export default {
name: 'Ldap',
components: {
GenericCreateUpdateForm,
IBox,
ImportDialog,
TestLoginDialog,
SyncSettingDialog
},
data() {
return {
dialogTest: false,
dialogLdapUserImport: false,
dialogSyncSetting: false,
encryptedFields: ['AUTH_LDAP_BIND_PASSWORD'],
fields: [
[
this.$t('Basic'),
[
'AUTH_LDAP', 'AUTH_LDAP_SERVER_URI',
'AUTH_LDAP_BIND_DN', 'AUTH_LDAP_BIND_PASSWORD'
]
],
[
this.$t('Search'),
[
'AUTH_LDAP_SEARCH_OU', 'AUTH_LDAP_SEARCH_FILTER',
'AUTH_LDAP_USER_ATTR_MAP'
]
],
[
this.$t('Other'),
[
'AUTH_LDAP_CONNECT_TIMEOUT', 'AUTH_LDAP_SEARCH_PAGED_SIZE',
'AUTH_LDAP_CACHE_TIMEOUT'
]
]
],
fieldsMeta: {
AUTH_LDAP_BIND_DN: {
rules: [
rules.Required
]
},
AUTH_LDAP_BIND_PASSWORD: {
component: UpdateToken
},
AUTH_LDAP_SEARCH_OU: {
rules: [
rules.Required
]
},
AUTH_LDAP_USER_ATTR_MAP: {
component: JsonEditor,
rules: [JsonRequired]
}
},
url: '/api/v1/settings/setting/?category=ldap',
hasDetailInMsg: false,
moreButtons: [
{
title: this.$t('LdapConnectTest'),
loading: false,
callback: function(value, form, btn) {
if (value['AUTH_LDAP_BIND_PASSWORD'] === undefined) {
value['AUTH_LDAP_BIND_PASSWORD'] = ''
}
btn.loading = true
this.enableWS()
this.ws.onopen = (e) => {
this.ws.send(JSON.stringify({ msg_type: 'testing_config', ...value }))
}
this.ws.onmessage = (e) => {
const data = JSON.parse(e.data)
if (data.ok) {
this.$message.success(data.msg)
} else {
this.$message.error(data.msg)
}
btn.loading = false
}
}.bind(this)
},
{
title: this.$t('LdapLoginTest'),
callback: function(value, form) {
this.dialogTest = true
}.bind(this)
},
{
title: this.$t('LdapBulkImport'),
callback: function(value, form) {
this.dialogLdapUserImport = true
}.bind(this)
},
{
title: this.$t('SyncSetting'),
callback: function(value, form) {
this.dialogSyncSetting = true
}.bind(this)
}
],
submitMethod: () => 'patch',
afterGetFormValue(obj) {
return obj
},
cleanFormValue(data) {
if (data['AUTH_LDAP_BIND_PASSWORD'] === '') {
delete data['AUTH_LDAP_BIND_PASSWORD']
}
return data
}
}
},
mounted() {
// this.loading = false
},
methods: {
enableWS() {
const scheme = document.location.protocol === 'https:' ? 'wss' : 'ws'
const port = document.location.port ? ':' + document.location.port : ''
const url = '/ws/ldap/'
const wsURL = scheme + '://' + document.location.hostname + port + url
this.ws = new WebSocket(wsURL)
}
}
}
</script>
<style scoped>
.listTable ::v-deep .table-action-right-side {
padding-top: 0 !important;
}
</style>

View File

@@ -8,8 +8,7 @@
<script>
import TabPage from '@/layout/components/TabPage'
import LdapHA from './Ldap/LdapHA.vue'
import LDAP from './Ldap/Ldap.vue'
import LDAP from './Ldap'
import Base from './Base'
import Basic from './Basic'
import CAS from './CAS'
@@ -29,7 +28,6 @@ export default {
components: {
TabPage,
LDAP,
LdapHA,
Base,
Basic,
CAS,
@@ -47,7 +45,6 @@ export default {
},
data() {
let extraBackends = []
let ldapHABackends = []
if (this.$store.getters.hasValidLicense) {
extraBackends = [
{
@@ -96,13 +93,6 @@ export default {
key: 'AUTH_RADIUS'
}
]
ldapHABackends = [
{
title: this.$t('LDAP HA'),
name: 'LdapHA',
key: 'AUTH_LDAP_HA'
}
]
}
return {
loading: true,
@@ -117,7 +107,6 @@ export default {
name: 'LDAP',
key: 'AUTH_LDAP'
},
...ldapHABackends,
{
title: this.$t('CAS'),
name: 'CAS',

View File

@@ -33,7 +33,7 @@ export default {
fieldsMeta: {
ANNOUNCEMENT: {
fields: [
'SUBJECT', 'CONTENT', 'DATE_START', 'DATE_END', 'LINK'
'SUBJECT', 'CONTENT', 'LINK'
],
fieldsMeta: {
CONTENT: {

View File

@@ -32,8 +32,7 @@ export default {
this.$t('Database'),
[
'JOB_EXECUTION_KEEP_DAYS',
'CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS',
'ACCOUNT_CHANGE_SECRET_RECORD_KEEP_DAYS'
'CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS'
]
]
],

View File

@@ -30,11 +30,11 @@ export default {
detailCardItems() {
return [
{
key: this.$t('TaskPath'),
key: this.$t('Name'),
value: this.object.name
},
{
key: this.$t('Name'),
key: this.$t('Comment'),
value: this.object.meta.comment
},
{
@@ -44,10 +44,6 @@ export default {
{
key: this.$t('LastPublishedTime'),
value: this.object.last_published_time
},
{
key: this.$t('Description'),
value: this.object.meta.description
}
]
}

View File

@@ -32,7 +32,6 @@ export default {
role: { name: '', comment: '', users: [] },
config: {
titlePrefix: scope === 'org' ? vm.$t('OrgRole') : vm.$t('SystemRole'),
getObjectName: (obj) => { return obj.display_name },
url: `/api/v1/rbac/${scope}-roles`,
activeMenu: 'RoleInfo',
actions: {