Skip to content

Commit

Permalink
fix: set iframe src correctly
Browse files Browse the repository at this point in the history
Signed-off-by: Tristan Bastian <tristan.bastian@softwareag.com>
  • Loading branch information
reey committed May 24, 2024
1 parent d638867 commit f4b10cf
Showing 1 changed file with 73 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { Component, ElementRef, OnDestroy, ViewChild } from '@angular/core';
import { AlertService, AppStateService, gettext, ModalService } from '@c8y/ngx-components';
import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core';
import {
AlertService,
AppStateService,
gettext,
ModalService,
} from '@c8y/ngx-components';
import { FetchClient, TenantOptionsService, UserService } from '@c8y/client';
import { Subscription } from 'rxjs';
import { ActivatedRoute } from '@angular/router';

@Component({
selector: 'app-node-red-iframe',
templateUrl: './node-red-iframe.component.html'
templateUrl: './node-red-iframe.component.html',
})
export class NodeRedIframeComponent implements OnDestroy {
export class NodeRedIframeComponent implements OnDestroy, AfterViewInit {
hasRequiredRoles = false;
currentUserSubscription: Subscription;
currentUserSubscription: Subscription | undefined;
private iframeURL: string;

@ViewChild('iframe') iframe: ElementRef | undefined;
Expand All @@ -25,19 +30,33 @@ export class NodeRedIframeComponent implements OnDestroy {
private modalService: ModalService
) {
this.iframeURL = this.route.snapshot.data['src'];
this.currentUserSubscription = this.appState.currentUser.subscribe((user) => {
if (user) {
if (this.userService.hasAnyRole(user, ['ROLE_NODE_RED_ADMIN', 'ROLE_NODE_RED_READ'])) {
this.hasRequiredRoles = true;
this.setupIframe();
}

ngAfterViewInit(): void {
this.currentUserSubscription = this.appState.currentUser.subscribe(
(user) => {
if (user) {
if (
this.userService.hasAnyRole(user, [
'ROLE_NODE_RED_ADMIN',
'ROLE_NODE_RED_READ',
])
) {
this.hasRequiredRoles = true;
this.setupIframe();
} else {
this.hasRequiredRoles = false;
this.alertService.warning(
gettext(
'You are missing the required roles to access the Node-RED backend.'
)
);
}
} else {
this.hasRequiredRoles = false;
this.alertService.warning(gettext('You are missing the required roles to access the Node-RED backend.'));
}
} else {
this.hasRequiredRoles = false;
}
});
);
}

ngOnDestroy(): void {
Expand All @@ -47,12 +66,11 @@ export class NodeRedIframeComponent implements OnDestroy {
}

private async setupIframe() {

// workaround to get rid of the basic auth login prompt
let preAuthSent = false;
const options = this.client.getFetchOptions();
if (options && options.headers) {
const headers: {[key: string]: string} = options.headers
const headers: { [key: string]: string } = options.headers;
const authString = headers['Authorization'] || headers['authorization'];
if (authString) {
if (authString.startsWith('Basic ')) {
Expand All @@ -73,17 +91,26 @@ export class NodeRedIframeComponent implements OnDestroy {
// using OAuth
if (!preAuthSent) {
try {
const { data } = await this.tenantOptions.detail({category: 'jwt', key: 'xsrf-validation.enabled'});
const { data } = await this.tenantOptions.detail({
category: 'jwt',
key: 'xsrf-validation.enabled',
});
if (data.value !== 'false') {
throw Error('');
}
} catch (e) {
this.alertService.add({
text: gettext(`To use Node-RED on a tenant that uses OAuth, you have to disable XSRF-Token validation. By closing this message we will try do this for you.`),
detailedData: gettext(`To disable XSRF-Token validation, you have to set the tenant option with the category: 'jwt', key: 'xsrf-validation.enabled' to the value: 'false'.`),
text: gettext(
`To use Node-RED on a tenant that uses OAuth, you have to disable XSRF-Token validation. By closing this message we will try do this for you.`
),
detailedData: gettext(
`To disable XSRF-Token validation, you have to set the tenant option with the category: 'jwt', key: 'xsrf-validation.enabled' to the value: 'false'.`
),
type: 'warning',
timeout: 0,
onClose: () => {this.disableXSRFTokenValidation()}
onClose: () => {
this.disableXSRFTokenValidation();
},
});
return;
}
Expand All @@ -94,23 +121,43 @@ export class NodeRedIframeComponent implements OnDestroy {

private async disableXSRFTokenValidation() {
try {
await this.modalService.confirm(gettext(`Disable XSRF-Token validation`), gettext(`Are you sure that you would like to disable XSRF-Token validation?`), 'warning', { ok: gettext('Disable XSRF-Token validation'), cancel: gettext('Cancel')});
await this.modalService.confirm(
gettext(`Disable XSRF-Token validation`),
gettext(
`Are you sure that you would like to disable XSRF-Token validation?`
),
'warning',
{
ok: gettext('Disable XSRF-Token validation'),
cancel: gettext('Cancel'),
}
);
} catch (e) {
// nothing to do, modal was canceled.
return;
}
try {
await this.tenantOptions.update({category: 'jwt', key: 'xsrf-validation.enabled', value: 'false'});
await this.tenantOptions.update({
category: 'jwt',
key: 'xsrf-validation.enabled',
value: 'false',
});
} catch (e) {
this.alertService.warning(gettext('Failed to disable XSRF-Token validation.'));
this.alertService.warning(
gettext('Failed to disable XSRF-Token validation.')
);
}

this.setIframeUrl();
}

private setIframeUrl() {
// set iFrame's SRC attribute
const iframe: HTMLIFrameElement = this.iframe?.nativeElement;
iframe.src = this.iframeURL;
const iframe: HTMLIFrameElement | undefined = this.iframe?.nativeElement;
if (iframe) {
iframe.src = this.iframeURL;
return;
}
console.warn('iFrame element not found');
}
}

0 comments on commit f4b10cf

Please sign in to comment.