From d5d459ccd62374b9093ffae7ea487a0c29466254 Mon Sep 17 00:00:00 2001 From: irving ou Date: Mon, 7 Oct 2024 16:10:58 -0400 Subject: [PATCH] chore(webapp): update web-ssh-gui (new Rust stack) --- webapp/package-lock.json | 187 +++++++++++++++++- webapp/package.json | 2 +- .../ssh/ssh-form.component.html | 13 +- .../password-control.component.ts | 19 +- .../ssh/web-client-ssh.component.ts | 50 ++--- 5 files changed, 233 insertions(+), 38 deletions(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index e01e8b936..b1df26ad6 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -20,7 +20,7 @@ "@devolutions/icons": "4.0.8", "@devolutions/iron-remote-gui": "^0.11.6", "@devolutions/iron-remote-gui-vnc": "^0.2.2", - "@devolutions/web-ssh-gui": "^0.2.18", + "@devolutions/web-ssh-gui": "^0.3.1", "@devolutions/web-telnet-gui": "^0.2.15", "primeflex": "3.3.1", "primeicons": "7.0.0", @@ -2990,15 +2990,28 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@devolutions/web-ssh-gui": { - "version": "0.2.18", - "resolved": "https://devolutions.jfrog.io/devolutions/api/npm/npm/@devolutions/web-ssh-gui/-/@devolutions/web-ssh-gui-0.2.18.tgz", - "integrity": "sha512-MoeE4yIWTDG/8v5LKsxgOeBDxixyzo/XdL4oZqnSlxGabD5Sv3fFLowrHoDv59Q131FmMx0a6vXCZC8/OhctrQ==", + "version": "0.3.1", + "resolved": "https://devolutions.jfrog.io/devolutions/api/npm/npm-local/@devolutions/web-ssh-gui/-/@devolutions/web-ssh-gui-0.3.1.tgz", + "integrity": "sha512-a5lYJvn/MYmbQjxL+NDOLevGFz+GPFx2vxBz+J7v13ASE/2MUozUzOKMS0lcIsr0NiKkJ4NWPHGJW/dl7fy0PQ==", "dependencies": { "@tsconfig/svelte": "^4.0.0", + "jquery": "^3.7.1", "rxjs": "^7.8.1", "svelte-preprocess": "^5.0.4", "xterm": "^5.2.1", "xterm-addon-fit": "^0.7.0" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "^1.7.4-nightly-20240729.1", + "@swc/core-darwin-x64": "^1.7.4-nightly-20240729.1", + "@swc/core-linux-arm-gnueabihf": "^1.7.4-nightly-20240729.1", + "@swc/core-linux-arm64-gnu": "^1.7.4-nightly-20240729.1", + "@swc/core-linux-arm64-musl": "^1.7.4-nightly-20240729.1", + "@swc/core-linux-x64-gnu": "^1.7.4-nightly-20240729.1", + "@swc/core-linux-x64-musl": "^1.7.4-nightly-20240729.1", + "@swc/core-win32-arm64-msvc": "^1.7.4-nightly-20240729.1", + "@swc/core-win32-ia32-msvc": "^1.7.4-nightly-20240729.1", + "@swc/core-win32-x64-msvc": "^1.7.4-nightly-20240729.1" } }, "node_modules/@devolutions/web-telnet-gui": { @@ -4688,6 +4701,166 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.28.tgz", + "integrity": "sha512-BNkj6enHo2pdzOpCtQGKZbXT2A/qWIr0CVtbTM4WkJ3MCK/glbFsyO6X59p1r8+gfaZG4bWYnTTu+RuUAcsL5g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.28.tgz", + "integrity": "sha512-96zQ+X5Fd6P/RNPkOyikTJgEc2M4TzznfYvjRd2hye5h22jhxCLL/csoauDgN7lYfd7mwsZ/sVXwJTMKl+vZSA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.28.tgz", + "integrity": "sha512-l2100Wx6LdXMOmOW3+KoHhBhyZrGdz8ylkygcVOC0QHp6YIATfuG+rRHksfyEWCSOdL3anM9MJZJX26KT/s+XQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.28.tgz", + "integrity": "sha512-03m6iQ5Bv9u2VPnNRyaBmE8eHi056eE39L0gXcqGoo46GAGuoqYHt9pDz8wS6EgoN4t85iBMUZrkCNqFKkN6ZQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.28.tgz", + "integrity": "sha512-vqVOpG/jc8mvTKQjaPBLhr7tnWyzuztOHsPnJqMWmg7zGcMeQC/2c5pU4uzRAfXMTp25iId6s4Y4wWfPS1EeDw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.28.tgz", + "integrity": "sha512-HGwpWuB83Kr+V0E+zT5UwIIY9OxiS8aLd0UVMRVWuO8SrQyKm9HKJ46+zoAb8tfJrpZftfxvbn2ayZWR7gqosA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.28.tgz", + "integrity": "sha512-q2Y2T8y8EgFtIiRyInnAXNe94aaHX74F0ha1Bl9VdRxE0u1/So+3VLbPvtp4V3Z6pj5pOePfCQJKifnllgAQ9A==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.28.tgz", + "integrity": "sha512-bCqh4uBT/59h3dWK1v91In6qzz8rKoWoFRxCtNQLIK4jP55K0U231ZK9oN7neZD6bzcOUeFvOGgcyMAgDfFWfA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.28.tgz", + "integrity": "sha512-XTHbHrksnrqK3JSJ2sbuMWvdJ6/G0roRpgyVTmNDfhTYPOwcVaL/mSrPGLwbksYUbq7ckwoKzrobhdxvQzPsDA==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.7.28", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.28.tgz", + "integrity": "sha512-jyXeoq6nX8abiCy2EpporsC5ywNENs4ocYuvxo1LSxDktWN1E2MTXq3cdJcEWB2Vydxq0rDcsGyzkRPMzFhkZw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@tsconfig/svelte": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-4.0.1.tgz", @@ -8647,6 +8820,12 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/webapp/package.json b/webapp/package.json index c147705f7..78db1874f 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -30,7 +30,7 @@ "@devolutions/icons": "4.0.8", "@devolutions/iron-remote-gui": "^0.11.6", "@devolutions/iron-remote-gui-vnc": "^0.2.2", - "@devolutions/web-ssh-gui": "^0.2.18", + "@devolutions/web-ssh-gui": "^0.3.1", "@devolutions/web-telnet-gui": "^0.2.15", "primeflex": "3.3.1", "primeicons": "7.0.0", diff --git a/webapp/src/client/app/modules/web-client/form/form-components/ssh/ssh-form.component.html b/webapp/src/client/app/modules/web-client/form/form-components/ssh/ssh-form.component.html index 33ee33e19..84292862d 100644 --- a/webapp/src/client/app/modules/web-client/form/form-components/ssh/ssh-form.component.html +++ b/webapp/src/client/app/modules/web-client/form/form-components/ssh/ssh-form.component.html @@ -17,12 +17,13 @@
- - +
@@ -30,4 +31,4 @@
- \ No newline at end of file + diff --git a/webapp/src/client/app/modules/web-client/form/form-controls/password-control/password-control.component.ts b/webapp/src/client/app/modules/web-client/form/form-controls/password-control/password-control.component.ts index e863f5a54..b67c12ce0 100644 --- a/webapp/src/client/app/modules/web-client/form/form-controls/password-control/password-control.component.ts +++ b/webapp/src/client/app/modules/web-client/form/form-controls/password-control/password-control.component.ts @@ -1,5 +1,5 @@ import { Component, Input, OnInit, SimpleChanges } from '@angular/core'; -import { AbstractControl, FormGroup } from '@angular/forms'; +import { AbstractControl, FormGroup, Validators } from '@angular/forms'; import { BaseComponent } from '@shared/bases/base.component'; import { WebFormService } from '@shared/services/web-form.service'; @@ -15,6 +15,7 @@ export class PasswordControlComponent extends BaseComponent implements OnInit { @Input() isEnabled = true; @Input() label = 'Password'; @Input() formKey = 'password'; + @Input() isRequired = true; showPasswordToggle = false; @@ -23,7 +24,8 @@ export class PasswordControlComponent extends BaseComponent implements OnInit { } ngOnInit(): void { - this.formService.addControlToForm(this.parentForm, this.formKey, this.inputFormData); + console.log('this is required', this.isRequired); + this.formService.addControlToForm(this.parentForm, this.formKey, this.inputFormData, this.isRequired); this.toggleControl(); } @@ -42,5 +44,18 @@ export class PasswordControlComponent extends BaseComponent implements OnInit { if (control) { this.isEnabled ? control.enable() : control.disable(); } + this.updateValidators(); + } + + private updateValidators(): void { + const control = this.parentForm.get(this.formKey); + if (control) { + if (this.isRequired) { + control.setValidators([Validators.required]); + } else { + control.clearValidators(); // Remove the 'required' validator + } + control.updateValueAndValidity(); // Ensure the form reflects new validation state + } } } diff --git a/webapp/src/client/app/modules/web-client/ssh/web-client-ssh.component.ts b/webapp/src/client/app/modules/web-client/ssh/web-client-ssh.component.ts index b2d95a1b8..f8e021060 100644 --- a/webapp/src/client/app/modules/web-client/ssh/web-client-ssh.component.ts +++ b/webapp/src/client/app/modules/web-client/ssh/web-client-ssh.component.ts @@ -157,7 +157,7 @@ export class WebClientSshComponent extends WebClientBaseComponent implements OnI return; } - this.remoteTerminal.status.subscribe((v) => { + this.remoteTerminal.onStatusChange((v) => { if (v === TerminalConnectionStatus.connected) { // connected only indicates connection to Gateway is successful this.remoteTerminal.writeToTerminal('connecting... \r\n'); @@ -180,15 +180,18 @@ export class WebClientSshComponent extends WebClientBaseComponent implements OnI private callConnect(connectionParameters: SshConnectionParameters) { return from( - this.remoteTerminal.connect( - connectionParameters.host, - connectionParameters.port, - connectionParameters.username, - connectionParameters.gatewayAddress + `?token=${connectionParameters.token}`, - connectionParameters.password, - connectionParameters.privateKey, - connectionParameters.privateKeyPassphrase, - ), + this.remoteTerminal.connect({ + hostname: connectionParameters.host, + port: connectionParameters.port, + username: connectionParameters.username, + proxyUrl: connectionParameters.gatewayAddress + `?token=${connectionParameters.token}`, + passpharse: connectionParameters.privateKeyPassphrase ?? '', + privateKey: connectionParameters.privateKey ?? '', + password: connectionParameters.password ?? '', + onHostKeyReceived: (serverName, fingerprint) => { + return Promise.resolve(true); + }, + }), ).pipe(catchError((error) => throwError(error))); } @@ -228,21 +231,18 @@ export class WebClientSshComponent extends WebClientBaseComponent implements OnI return; } - this.remoteTerminal.status.subscribe({ - next: (status): void => { - switch (status) { - case TerminalConnectionStatus.connected: - this.handleSessionStarted(); - break; - case TerminalConnectionStatus.failed: - case TerminalConnectionStatus.closed: - this.handleSessionEndedOrError(status); - break; - default: - break; - } - }, - error: (err) => this.handleSubscriptionError(err), + this.remoteTerminal.onStatusChange((status) => { + switch (status) { + case TerminalConnectionStatus.connected: + this.handleSessionStarted(); + break; + case TerminalConnectionStatus.failed: + case TerminalConnectionStatus.closed: + this.handleSessionEndedOrError(status); + break; + default: + break; + } }); }