diff --git a/src/app/components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component.ts b/src/app/components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component.ts index b2db1704..b5ae982a 100644 --- a/src/app/components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component.ts +++ b/src/app/components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component.ts @@ -1,4 +1,5 @@ import { Component, Input } from '@angular/core'; +import { DeviceDetectorService } from 'ngx-device-detector'; import { Node } from '../../../../../cartography/models/node'; import{ Controller } from '../../../../../models/controller'; import { NodeService } from '../../../../../services/node.service'; @@ -12,7 +13,7 @@ export class ConsoleDeviceActionBrowserComponent { @Input() controller:Controller ; @Input() node: Node; - constructor(private toasterService: ToasterService, private nodeService: NodeService) {} + constructor(private toasterService: ToasterService, private nodeService: NodeService, private deviceService: DeviceDetectorService) {} openConsole() { this.nodeService.getNode(this.controller, this.node).subscribe((node: Node) => { @@ -21,6 +22,31 @@ export class ConsoleDeviceActionBrowserComponent { }); } + createHiddenIframe(target: Element, uri: string) { + const iframe = document.createElement("iframe"); + iframe.src = uri; + iframe.id = "hiddenIframe"; + iframe.style.display = "none"; + target.appendChild(iframe); + return iframe; + } + + openUriUsingFirefox(uri: string) { + var iframe = (document.querySelector("#hiddenIframe") as HTMLIFrameElement); + + if (!iframe) { + iframe = this.createHiddenIframe(document.body, "about:blank"); + } + + try { + iframe.contentWindow.location.href = uri; + } catch (e) { + if (e.name === "NS_ERROR_UNKNOWN_PROTOCOL") { + this.toasterService.error('Protocol handler does not exist'); + } + } + } + startConsole() { if (this.node.status !== 'started') { this.toasterService.error('This node must be started before a console can be opened'); @@ -33,20 +59,30 @@ export class ConsoleDeviceActionBrowserComponent { this.node.console_host = this.controller.host; } - if ( - this.node.console_type === 'telnet' || - this.node.console_type === 'vnc' || - this.node.console_type === 'spice' - ) { - try { - location.assign( - `gns3+${this.node.console_type}://${this.node.console_host}:${this.node.console}?name=${this.node.name}&project_id=${this.node.project_id}&node_id=${this.node.node_id}` - ); - } catch (e) { - this.toasterService.error(e); + const device = this.deviceService.getDeviceInfo(); + + try { + var uri; + if (this.node.console_type === 'telnet') { + uri = `gns3+telnet://${this.node.console_host}:${this.node.console}?name=${this.node.name}&project_id=${this.node.project_id}&node_id=${this.node.node_id}`; + } else if (this.node.console_type === 'vnc') { + uri = `gns3+vnc://${this.node.console_host}:${this.node.console}?name=${this.node.name}&project_id=${this.node.project_id}&node_id=${this.node.node_id}`; + } else if (this.node.console_type.startsWith('spice')) { + uri = `gns3+spice://${this.node.console_host}:${this.node.console}?name=${this.node.name}&project_id=${this.node.project_id}&node_id=${this.node.node_id}` + } else { + this.toasterService.error('Supported console types are: telnet, vnc, spice and spice+agent.'); } - } else { - this.toasterService.error('Supported console types: telnet, vnc, spice.'); + + if (device.browser === "Firefox") { + // Use a hidden iframe otherwise Firefox will disconnect + // from the GNS3 controller websocket if we use location.assign() + this.openUriUsingFirefox(uri); + } else { + location.assign(uri); + } + + } catch (e) { + this.toasterService.error(e); } } }