mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-13 11:24:17 +00:00
Compare commits
22 Commits
pr@dev@fix
...
repr@v3@a9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a048edf24f | ||
|
|
a9ba931bba | ||
|
|
23fae59411 | ||
|
|
320613d15d | ||
|
|
57ea32e785 | ||
|
|
3e3f80c59b | ||
|
|
c15ba5b078 | ||
|
|
651888faab | ||
|
|
d220047fe2 | ||
|
|
bbe80f0292 | ||
|
|
41e73a2c9b | ||
|
|
7d89cf9f45 | ||
|
|
8a048f692f | ||
|
|
800317346c | ||
|
|
4a1e2db7ca | ||
|
|
6702d94ba1 | ||
|
|
a87d04fb9d | ||
|
|
367db0daf1 | ||
|
|
583b28a6c4 | ||
|
|
ec5f2e69eb | ||
|
|
d058f0e777 | ||
|
|
89befaad43 |
28
.github/workflows/.github/workflows/llm-code-review.yml
vendored
Normal file
28
.github/workflows/.github/workflows/llm-code-review.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: LLM Code Review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
llm-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: fit2cloud/LLM-CodeReview-Action@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
|
||||
LANGUAGE: English
|
||||
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
MODEL: qwen2-1.5b-instruct
|
||||
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
|
||||
top_p: 1
|
||||
temperature: 1
|
||||
# max_tokens: 10000
|
||||
MAX_PATCH_LENGTH: 10000
|
||||
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
|
||||
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"
|
||||
@@ -225,7 +225,7 @@ export default {
|
||||
})
|
||||
},
|
||||
startFaceCapture() {
|
||||
const url = '/api/v1/authentication/mfa/face/context/'
|
||||
const url = '/api/v1/authentication/face/context/'
|
||||
this.$axios.post(url).then(data => {
|
||||
const token = data['token']
|
||||
this.faceCaptureUrl = '/facelive/capture?token=' + token
|
||||
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
formatterData = data
|
||||
}
|
||||
return (
|
||||
<span style={{ whiteSpace: 'pre-wrap', lineHeight: '1.2' }}>{formatterData}</span>
|
||||
<span style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word', lineHeight: '1.2' }}>{formatterData}</span>
|
||||
)
|
||||
}
|
||||
if (this.value instanceof Array) {
|
||||
|
||||
@@ -202,9 +202,10 @@ export default {
|
||||
label: current.label,
|
||||
value: valueDecode
|
||||
}
|
||||
|
||||
if (curChildren.length > 0) {
|
||||
for (const item of curChildren) {
|
||||
if (valueDecode === item.value) {
|
||||
if (valueDecode === String(item.value)) {
|
||||
searchFieldOption.valueLabel = item.label
|
||||
break
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
},
|
||||
async logout() {
|
||||
const currentOrg = this.$store.getters.currentOrg
|
||||
if (currentOrg.autoEnter) {
|
||||
if (currentOrg.autoEnter || currentOrg.is_system) {
|
||||
await this.$store.dispatch('users/setCurrentOrg', this.$store.getters.preOrg)
|
||||
}
|
||||
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
|
||||
|
||||
@@ -2,7 +2,6 @@ import i18n from '@/i18n/i18n'
|
||||
import empty from '@/layout/empty'
|
||||
import XPackRoutes from './xpack'
|
||||
|
||||
const globalSubmenu = () => import('@/layout/globalOrg.vue')
|
||||
export default [
|
||||
{
|
||||
path: 'assets',
|
||||
@@ -294,12 +293,11 @@ export default [
|
||||
},
|
||||
{
|
||||
path: 'platforms',
|
||||
component: globalSubmenu,
|
||||
component: empty,
|
||||
meta: {
|
||||
permissions: ['assets.view_platform'],
|
||||
resource: 'platform',
|
||||
icon: 'platform',
|
||||
disableOrgsChange: true
|
||||
icon: 'platform'
|
||||
},
|
||||
redirect: '',
|
||||
children: [
|
||||
|
||||
@@ -71,10 +71,11 @@ const mutations = {
|
||||
state.consoleOrgs = state.consoleOrgs.filter(i => i.id !== org.id)
|
||||
},
|
||||
SET_CURRENT_ORG(state, org) {
|
||||
// 系统组织和全局组织不设置成 Pre org
|
||||
if (!state.currentOrg?.autoEnter && !state.currentOrg?.is_root) {
|
||||
state.preOrg = state.currentOrg
|
||||
setPreOrgLocal(state.username, state.currentOrg)
|
||||
// 系统组织不设置成 Pre org
|
||||
const currentOrg = state.currentOrg
|
||||
if (currentOrg && !currentOrg.autoEnter && !currentOrg.is_system) {
|
||||
state.preOrg = currentOrg
|
||||
setPreOrgLocal(state.username, currentOrg)
|
||||
}
|
||||
state.currentOrg = org
|
||||
saveCurrentOrgLocal(state.username, org)
|
||||
@@ -144,6 +145,7 @@ const actions = {
|
||||
const systemOrg = {
|
||||
id: orgUtil.SYSTEM_ORG_ID,
|
||||
name: 'SystemSetting',
|
||||
is_system: true,
|
||||
autoEnter: new Date().getTime()
|
||||
}
|
||||
commit('SET_CURRENT_ORG', systemOrg)
|
||||
|
||||
@@ -42,8 +42,13 @@ export function getCurrentOrgLocal(username) {
|
||||
|
||||
export function saveCurrentOrgLocal(username, org) {
|
||||
const key = CURRENT_ORG_KEY + ':' + username
|
||||
localStorage.setItem(key, JSON.stringify(org))
|
||||
VueCookie.set('X-JMS-ORG', org.id)
|
||||
if (org) {
|
||||
localStorage.setItem(key, JSON.stringify(org))
|
||||
VueCookie.set('X-JMS-ORG', org.id)
|
||||
} else {
|
||||
localStorage.removeItem(key)
|
||||
VueCookie.delete('X-JMS-ORG')
|
||||
}
|
||||
}
|
||||
|
||||
export function setPreOrgLocal(username, org) {
|
||||
|
||||
@@ -222,16 +222,32 @@ export function download(downloadUrl, filename) {
|
||||
const iframe = document.createElement('iframe')
|
||||
iframe.style.display = 'none'
|
||||
document.body.appendChild(iframe)
|
||||
const a = document.createElement('a')
|
||||
a.href = downloadUrl
|
||||
const timeout = 1000 * 60 * 30
|
||||
|
||||
if (filename) {
|
||||
a.download = filename
|
||||
fetch(downloadUrl)
|
||||
.then(response => response.blob())
|
||||
.then(blob => {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = iframe.contentWindow.document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
iframe.contentWindow.document.body.appendChild(a)
|
||||
a.click()
|
||||
setTimeout(() => {
|
||||
URL.revokeObjectURL(url)
|
||||
document.body.removeChild(iframe)
|
||||
}, timeout) // If you can't download it in half an hour, don't download it.
|
||||
})
|
||||
.catch(() => {
|
||||
document.body.removeChild(iframe)
|
||||
})
|
||||
} else {
|
||||
iframe.src = downloadUrl
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(iframe)
|
||||
}, timeout) // If you can't download it in half an hour, don't download it.
|
||||
}
|
||||
iframe.contentWindow.document.body.appendChild(a)
|
||||
a.click()
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(iframe)
|
||||
}, 1000 * 60 * 30) // If you can't download it in half an hour, don't download it.
|
||||
}
|
||||
|
||||
export function diffObject(object, base) {
|
||||
|
||||
@@ -17,7 +17,7 @@ function getPropOrg() {
|
||||
if (defaultOrg) {
|
||||
return defaultOrg
|
||||
}
|
||||
return orgs.filter(item => !item['is_root'] && item.id !== SYSTEM_ORG_ID)[0]
|
||||
return orgs.filter(item => !item['is_root'] && !item['is_system'])[0]
|
||||
}
|
||||
|
||||
async function change2PropOrg() {
|
||||
|
||||
@@ -89,10 +89,18 @@ function ifBadRequest({ response, error }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${router.fullPath}`
|
||||
}
|
||||
|
||||
export function flashErrorMsg({ response, error }) {
|
||||
if (!response.config.disableFlashErrorMsg) {
|
||||
const responseErrorMsg = getErrorResponseMsg(error)
|
||||
const msg = responseErrorMsg || error.message
|
||||
|
||||
if (response.status === 403 && msg === 'CSRF Failed: CSRF token missing.') {
|
||||
setTimeout(() => { logout() }, 1000)
|
||||
}
|
||||
message({
|
||||
message: msg,
|
||||
type: 'error',
|
||||
|
||||
@@ -8,7 +8,10 @@ import orgs from '@/api/orgs'
|
||||
import { getPropView, isViewHasOrgs } from '@/utils/jms'
|
||||
|
||||
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
|
||||
const autoEnterOrgs = ['00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000000']
|
||||
const autoEnterOrgs = [
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'00000000-0000-0000-0000-000000000000'
|
||||
]
|
||||
|
||||
function reject(msg) {
|
||||
return new Promise((resolve, reject) => reject(msg))
|
||||
@@ -170,19 +173,24 @@ export async function startup({ to, from, next }) {
|
||||
if (store.getters.inited) {
|
||||
return true
|
||||
}
|
||||
await store.dispatch('app/init')
|
||||
|
||||
// set page title
|
||||
// await getOpenPublicSetting({ to, from, next })
|
||||
await getPublicSetting({ to, from, next }, true)
|
||||
await checkLogin({ to, from, next })
|
||||
await onI18nLoaded()
|
||||
await getPublicSetting({ to, from, next }, false)
|
||||
await changeCurrentViewIfNeed({ to, from, next })
|
||||
await changeCurrentOrgIfNeed({ to, from, next })
|
||||
await generatePageRoutes({ to, from, next })
|
||||
await checkUserFirstLogin({ to, from, next })
|
||||
await store.dispatch('assets/getAssetCategories')
|
||||
try {
|
||||
await store.dispatch('app/init')
|
||||
|
||||
// set page title
|
||||
// await getOpenPublicSetting({ to, from, next })
|
||||
await getPublicSetting({ to, from, next }, true)
|
||||
await checkLogin({ to, from, next })
|
||||
await onI18nLoaded()
|
||||
await getPublicSetting({ to, from, next }, false)
|
||||
await changeCurrentViewIfNeed({ to, from, next })
|
||||
await changeCurrentOrgIfNeed({ to, from, next })
|
||||
await generatePageRoutes({ to, from, next })
|
||||
await checkUserFirstLogin({ to, from, next })
|
||||
await store.dispatch('assets/getAssetCategories')
|
||||
} catch (e) {
|
||||
Vue.$log.error('Startup error: ', e)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
url: '/api/v1/assets/domains/',
|
||||
columnsExclude: ['gateway'],
|
||||
columnsExtra: ['gateways'],
|
||||
columns: ['name', 'assets_amount', 'gateways', 'comment', 'actions'],
|
||||
columns: ['name', 'assets_amount', 'gateways', 'labels', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'assets_amount', 'gateways', 'comment', 'actions']
|
||||
|
||||
@@ -122,7 +122,7 @@ export default {
|
||||
},
|
||||
onCanSetting() {
|
||||
const filterField = Object.keys(this.remoteMeta)
|
||||
this.canSetting = filterField.includes(this.method)
|
||||
this.canSetting = filterField.includes(this.method) && this.$hasPerm('assets.change_platform')
|
||||
this.$emit('canSetting', this.canSetting)
|
||||
return this.canSetting
|
||||
},
|
||||
|
||||
@@ -27,6 +27,7 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const canEdit = !this.object['internal'] && this.$hasPerm('assets.change_platform')
|
||||
return {
|
||||
loading: true,
|
||||
initial: {
|
||||
@@ -35,14 +36,14 @@ export default {
|
||||
}
|
||||
},
|
||||
url: `/api/v1/assets/platforms/`,
|
||||
disabled: this.object.internal,
|
||||
disabled: !canEdit,
|
||||
hasReset: false,
|
||||
hasDetailInMsg: false,
|
||||
submitMethod: () => 'patch',
|
||||
fields: [['', ['automation']]],
|
||||
fieldsMeta: platformFieldsMeta(this),
|
||||
onSubmit: this.submit,
|
||||
canSubmit: !this.object.internal,
|
||||
canSubmit: canEdit,
|
||||
defaultOptions: {},
|
||||
afterGetFormValue: (obj) => {
|
||||
updateAutomationParams(this, obj)
|
||||
@@ -65,7 +66,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
submit(validValues) {
|
||||
if (!this.$hasPerm('assets.change_platform') || !this.isSystemAdmin) {
|
||||
if (!this.canSubmit || !this.isSystemAdmin) {
|
||||
return this.$message.error(this.$tc('NoPermission'))
|
||||
}
|
||||
this.$axios.patch(`${this.url}${this.object.id}/`, validValues).then(() => {
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
v-if="protocolChoices"
|
||||
v-model="object.protocols"
|
||||
:choices="protocolChoices"
|
||||
:readonly="object['internal']"
|
||||
:readonly="!canEdit"
|
||||
/>
|
||||
<el-button
|
||||
v-if="!object.internal"
|
||||
v-if="canEdit"
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
type="primary"
|
||||
@@ -71,7 +71,8 @@ export default {
|
||||
],
|
||||
|
||||
protocolChoices: null,
|
||||
constraints: {}
|
||||
constraints: {},
|
||||
canEdit: !this.object['internal'] && this.$hasPerm('assets.change_platform')
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
@@ -103,7 +104,7 @@ export default {
|
||||
attrs: {
|
||||
label: this.$t('Update'),
|
||||
model: object['domain_enabled'],
|
||||
disabled: object['internal'] || this.constraints['domain_enabled'] === false
|
||||
disabled: !this.canEdit || this.constraints['domain_enabled'] === false
|
||||
},
|
||||
callbacks: Object.freeze({
|
||||
change: (val) => {
|
||||
@@ -120,7 +121,7 @@ export default {
|
||||
type: 'switch',
|
||||
attrs: {
|
||||
model: object['su_enabled'],
|
||||
disabled: object['internal'] || this.constraints['su_enabled'] === false
|
||||
disabled: !this.canEdit || this.constraints['su_enabled'] === false
|
||||
},
|
||||
callbacks: Object.freeze({
|
||||
change: (val) => {
|
||||
@@ -136,7 +137,8 @@ export default {
|
||||
title: this.$t('SyncProtocolToAsset'),
|
||||
attrs: {
|
||||
type: 'primary',
|
||||
label: this.$t('Sync')
|
||||
label: this.$t('Sync'),
|
||||
disabled: !this.canEdit
|
||||
},
|
||||
callbacks: Object.freeze({
|
||||
click: () => {
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
columnsExtra: ['action'],
|
||||
columns: [
|
||||
'name', 'users_amount', 'user_groups_amount', 'assets_amount', 'nodes_amount',
|
||||
'accounts', 'is_valid', 'is_expired', 'from_ticket', 'is_active', 'actions'
|
||||
'accounts', 'labels', 'is_valid', 'is_expired', 'from_ticket', 'is_active', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
currentEdit: '',
|
||||
biometricFeaturesActions: [
|
||||
{
|
||||
title: this.$t('Face'),
|
||||
title: this.$t('FacialFeatures'),
|
||||
attrs: {
|
||||
type: 'primary',
|
||||
label: this.$store.state.users.profile.is_face_code_set ? this.$t('Unbind') : this.$t('Bind')
|
||||
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
omnidb: 'OmniDB',
|
||||
guacamole: 'Guacamole',
|
||||
lion: 'Lion',
|
||||
xrdp: 'XRDP',
|
||||
xrdp: 'Xrdp',
|
||||
razor: 'Razor',
|
||||
core: 'Core',
|
||||
celery: 'Celery',
|
||||
@@ -100,7 +100,7 @@ export default {
|
||||
kael: 'Kael',
|
||||
video_worker: 'Video-Worker',
|
||||
panda: 'Panda',
|
||||
nec: 'NEC',
|
||||
nec: 'Nec',
|
||||
facelive: 'Facelive'
|
||||
}
|
||||
return nameMapper[this.componentMetric.type]
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
v-model="requestForm.accounts"
|
||||
:assets="requestForm.assets"
|
||||
:nodes="requestForm.nodes"
|
||||
:oid="requestForm.oid"
|
||||
:show-add-template="false"
|
||||
style="width: 50% !important"
|
||||
/>
|
||||
@@ -82,6 +83,7 @@ export default {
|
||||
assets: this.object.apply_assets?.map(i => i.id),
|
||||
accounts: this.object.apply_accounts,
|
||||
actions: this.object.apply_actions,
|
||||
oid: this.object.org_id,
|
||||
apply_date_expired: this.object.apply_date_expired,
|
||||
apply_date_start: this.object.apply_date_start
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/users/groups/',
|
||||
columns: ['name', 'users_amount', 'comment', 'actions'],
|
||||
columns: ['name', 'users_amount', 'comment', 'actions', 'labels'],
|
||||
columnsShow: {
|
||||
default: ['name', 'users_amount', 'comment', 'actions'],
|
||||
min: ['name', 'action']
|
||||
|
||||
Reference in New Issue
Block a user