Skip to content

Commit 87b22d0

Browse files
authored
Merge pull request #1209 from jumpserver/dev
v4.5.0
2 parents a4bd420 + 7881cb8 commit 87b22d0

23 files changed

+586
-94
lines changed

proxy.conf.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,18 @@
6363
"ws": true,
6464
"changeOrigin": true
6565
},
66-
"/kael": {
66+
"/facelive": {
6767
"target": "http://localhost:5173",
6868
"secure": false,
6969
"ws": true,
7070
"changeOrigin": true
7171
},
72+
"/kael": {
73+
"target": "http://localhost:5172",
74+
"secure": false,
75+
"ws": true,
76+
"changeOrigin": true
77+
},
7278
"/ui/": {
7379
"target": "http://localhost:9528",
7480
"secure": false,

src/app/elements/chat/chat.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export class ElementChatComponent implements OnInit, OnDestroy {
139139

140140
elements.forEach(element => {
141141
element.addEventListener('mousedown', (event: MouseEvent) => {
142+
if (event.button !== 0) return;
142143
event.preventDefault();
143144
startDrag(event);
144145
}, false);

src/app/elements/connect/connect-dialog/advanced-option/advanced-option.component.ts

+14
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ export class ElementAdvancedOptionComponent implements OnChanges, OnInit {
120120
}
121121
return true;
122122
}
123+
},
124+
{
125+
type: 'select',
126+
field: 'rdp_connection_speed',
127+
label: 'RDP connection speed',
128+
hidden: () => {
129+
return this.connectMethod && this.connectMethod.component !== 'razor';
130+
},
131+
value: 'auto',
132+
options: [
133+
{label: 'Auto', value: 'auto'},
134+
{label: 'Low Speed Broadband (256 Kbps - 2 Mbps)', value: 'low_speed_broadband'},
135+
{label: 'High-speed broadband (2 Mbps – 10 Mbps )', value: 'high_speed_broadband'},
136+
]
123137
}
124138
];
125139
}

src/app/elements/connect/connect-dialog/connect-dialog.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ <h3>{{ "Connect" | translate }} - {{ asset.name | truncatechars:30 }}</h3>
7373
type="submit"
7474
>
7575
{{ "CONNECT"| translate }}
76-
<span *ngIf="protocol && protocol.name === 'rdp'" class="online-num">
76+
<span *ngIf="protocol && protocol.name === 'rdp' && viewAssetOnlineSessionInfo" class="online-num">
7777
({{ 'Current online' | translate }}: {{ onlineNum === null ? '- ' : onlineNum }})
7878
</span>
7979
</button>

src/app/elements/connect/connect-dialog/connect-dialog.component.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class ElementConnectDialogComponent implements OnInit {
2525
public accountSelected: Account = null;
2626
public connectOption: Object;
2727
public outputData: ConnectData = new ConnectData();
28+
public viewAssetOnlineSessionInfo: boolean = true;
2829
public manualAuthInfo: AuthInfo = new AuthInfo();
2930
public connectMethod: ConnectMethod = new ConnectMethod('Null', '', 'null', 'null');
3031
public preConnectData: ConnectData = new ConnectData();
@@ -92,6 +93,7 @@ export class ElementConnectDialogComponent implements OnInit {
9293
this.connectMethod = connectMethods[0];
9394
}
9495
}
96+
this.viewAssetOnlineSessionInfo = this._settingSvc.globalSetting.VIEW_ASSET_ONLINE_SESSION_INFO
9597
}
9698

9799
onProtocolChange(protocol) {
@@ -100,6 +102,9 @@ export class ElementConnectDialogComponent implements OnInit {
100102
}
101103

102104
getOnlineNum() {
105+
if (!this.viewAssetOnlineSessionInfo) {
106+
return;
107+
}
103108
if (this.protocol.name !== 'rdp') {
104109
return;
105110
}

src/app/elements/content/send-command-with-variable-dialog/send-command-with-variable-dialog.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class ElementSendCommandWithVariableDialogComponent implements OnInit {
1919
}
2020
async getVariableFormMeta() {
2121
const adhoc = this.data.command.id
22-
const url=`/api/v1/ops/variable/form_data/?t=${new Date().getTime()}&adhoc=${adhoc}`
22+
const url=`/api/v1/ops/variables/form-data/?t=${new Date().getTime()}&adhoc=${adhoc}`
2323
const res: any = await this._http.options(url).toPromise();
2424
this.formConfig = res.actions.GET;
2525
this.command = this.data.command;

src/app/elements/elements.component.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ import {ElementConnectorGuideComponent} from '@app/elements/content/content-wind
3131
import {ElementCommandDialogComponent} from '@app/elements/content/command-dialog/command-dialog.component';
3232
import {ElementSendCommandDialogComponent} from '@app/elements/content/send-command-dialog/send-command-dialog.component';
3333
// tslint:disable-next-line:max-line-length
34-
import {ElementSendCommandWithVariableDialogComponent} from '@app/elements/content/send-command-with-variable-dialog/send-command-with-variable-dialog.component';
34+
import {
35+
ElementSendCommandWithVariableDialogComponent
36+
} from '@app/elements/content/send-command-with-variable-dialog/send-command-with-variable-dialog.component';
3537
import {DynamicFormComponent} from '@app/elements/content/variable-dynamic-form/variable-dynamic-form.component';
3638
import {ElementChatComponent} from '@app/elements/chat/chat.component';
3739
import {ElementsPartsComponent} from './replay/parts/parts.component';
3840
import {ElementConnectorNecComponent} from '@app/elements/content/content-window/nec/nec.component';
41+
import {ElementFaceMonitorComponent} from '@app/elements/face-monitor/face-monitor.component';
3942

4043

4144
export const ElementComponents = [
@@ -51,6 +54,7 @@ export const ElementComponents = [
5154
ElementNavComponent,
5255
ElementChatComponent,
5356
ElementIframeComponent,
57+
ElementFaceMonitorComponent,
5458
ElementDialogAlertComponent,
5559
ElementAssetTreeComponent,
5660
ElementConnectorKokoComponent,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div class="box" [class.minimized]="isMinimized" *ngIf="isVisible">
2+
<div class="box-header">
3+
<span class="box-title" style="color: red" *ngIf="monitoringTabCount">●&nbsp;[{{ monitoringTabCount }}]个会话正在被监控中</span>
4+
<div class="box-controls">
5+
<button (click)="minimizeBox()">
6+
<i *ngIf="!isMinimized" class="fa fa-window-minimize"></i>
7+
<i *ngIf="isMinimized" class="fa fa-window-maximize"></i>
8+
</button>
9+
<button (click)="closeBox()">
10+
<i class="fa fa-window-close"></i>
11+
</button>
12+
</div>
13+
</div>
14+
<div class="box-content" [hidden]="isMinimized">
15+
<iframe
16+
*ngIf="faceMonitorUrl"
17+
[src]="faceMonitorUrl"
18+
allow="camera"
19+
sandbox="allow-scripts allow-same-origin"
20+
style="width: 100%; height: 400px;border: none;"></iframe>
21+
</div>
22+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
.box {
2+
position: absolute;
3+
width: 400px;
4+
height: 460px;
5+
bottom: 0;
6+
right: 0;
7+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
8+
display: flex;
9+
flex-direction: column;
10+
overflow: hidden;
11+
z-index: 99999;
12+
}
13+
14+
.box.minimized {
15+
height: 40px;
16+
}
17+
18+
.box-header {
19+
height: 40px;
20+
background-color: #3a3433;
21+
color: white;
22+
display: flex;
23+
align-items: center;
24+
justify-content: space-between;
25+
padding: 0 10px;
26+
}
27+
28+
.box-title {
29+
font-weight: bold;
30+
}
31+
32+
.box-controls button {
33+
background: none;
34+
border: none;
35+
color: white;
36+
font-size: 14px;
37+
margin-left: 5px;
38+
cursor: pointer;
39+
}
40+
41+
.box-controls button:hover {
42+
text-decoration: underline;
43+
}
44+
45+
.box-content {
46+
flex: 1;
47+
padding: 8px;
48+
background-color: #2f2a2a;
49+
overflow: auto;
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {Component, OnInit} from '@angular/core';
2+
import {FaceService} from '@app/services/face';
3+
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
4+
5+
@Component({
6+
selector: 'app-face-monitor',
7+
templateUrl: './face-monitor.component.html',
8+
styleUrls: ['./face-monitor.component.scss']
9+
})
10+
export class ElementFaceMonitorComponent implements OnInit {
11+
12+
constructor(
13+
private faceMonitorService: FaceService,
14+
private sanitizer: DomSanitizer
15+
) {
16+
this.faceMonitorService.isVisible$.subscribe(status => {
17+
this.isVisible = status;
18+
});
19+
this.faceMonitorService.monitoringTabCount$.subscribe(count => {
20+
if (count > 0) {
21+
this.ready = true;
22+
}
23+
this.monitoringTabCount = count;
24+
if (this.ready && this.monitoringTabCount === 0) {
25+
this.isVisible = false;
26+
}
27+
});
28+
}
29+
30+
public faceMonitorUrl: SafeResourceUrl;
31+
public isMinimized = false;
32+
public isVisible = true;
33+
public monitoringTabCount = 0;
34+
public ready = false;
35+
36+
ngOnInit() {
37+
this.faceMonitorUrl = this.sanitizer.bypassSecurityTrustResourceUrl('/facelive/monitor?token=' + this.faceMonitorService.getToken());
38+
}
39+
40+
minimizeBox() {
41+
this.isMinimized = !this.isMinimized;
42+
}
43+
44+
closeBox() {
45+
this.isVisible = false;
46+
}
47+
}

src/app/elements/iframe/iframe.component.ts

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {MatDialog} from '@angular/material';
55
import {Subject} from 'rxjs';
66
import {debounceTime} from 'rxjs/operators';
77
import {environment} from '@src/environments/environment';
8+
import {FaceService} from '@app/services/face';
89

910
@Component({
1011
selector: 'elements-iframe',
@@ -32,6 +33,7 @@ export class ElementIframeComponent implements OnInit, AfterViewInit, OnDestroy
3233
private _http: HttpService,
3334
private _dialog: MatDialog,
3435
public viewSrv: ViewService,
36+
private faceService: FaceService
3537
) {
3638
}
3739

@@ -67,9 +69,15 @@ export class ElementIframeComponent implements OnInit, AfterViewInit, OnDestroy
6769
break;
6870
case 'CLOSE':
6971
this.view.connected = false;
72+
if (this.view.connectToken.face_monitor_token) {
73+
this.faceService.removeMonitoringTab(this.view.id);
74+
}
7075
break;
7176
case 'CONNECTED':
7277
this.view.connected = true;
78+
if (this.view.connectToken.face_monitor_token) {
79+
this.faceService.addMonitoringTab(this.view.id);
80+
}
7381
break;
7482
case 'CLICK':
7583
document.body.click();

src/app/elements/nav/nav.component.ts

+19-34
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ export class ElementNavComponent implements OnInit {
4646
this.viewIds = this._viewSrv.viewIds;
4747
}
4848

49-
refreshNav() {
50-
this.navs = this.getNav();
51-
}
52-
5349
getNav() {
5450
return [
5551
{
@@ -97,36 +93,7 @@ export class ElementNavComponent implements OnInit {
9793
{
9894
id: 'Language',
9995
name: 'Language',
100-
children: [
101-
{
102-
id: 'English',
103-
click: () => {
104-
this._i18n.use('en');
105-
},
106-
name: 'English'
107-
},
108-
{
109-
id: 'Chinese',
110-
click: () => {
111-
this._i18n.use('zh');
112-
},
113-
name: '中文'
114-
},
115-
{
116-
id: 'Chinese-hant',
117-
click: () => {
118-
this._i18n.use('zh_hant');
119-
},
120-
name: '中文(繁體)'
121-
},
122-
{
123-
id: 'Japanese',
124-
click: () => {
125-
this._i18n.use('ja');
126-
},
127-
name: '日本語'
128-
}
129-
]
96+
children: this.getLanguageOptions(),
13097
},
13198
{
13299
id: 'Setting',
@@ -232,6 +199,24 @@ export class ElementNavComponent implements OnInit {
232199
];
233200
}
234201

202+
getLanguageOptions() {
203+
const langOptions = [];
204+
this._settingSvc.afterInited().then((state) => {
205+
const languages = this._settingSvc.globalSetting.LANGUAGES;
206+
for (const langObj of languages) {
207+
langOptions.push({
208+
id: langObj.code,
209+
click: () => {
210+
this._i18n.use(langObj.code);
211+
window.location.reload();
212+
},
213+
name: langObj.name
214+
});
215+
}
216+
});
217+
return langOptions;
218+
}
219+
235220
onJumpUi() {
236221
window.open('/ui/', '_blank');
237222
}

0 commit comments

Comments
 (0)