I have an Angular app which requires session authorization from an OIDC service. With the normal/happy path, a separate NodeJS/Express app checks for session authorization and redirects to the OIDC authorization/authentication service and attaches the relevant headers. If everything passes, the middleware routes to the Angular app.
At a point though, the Angular app runs with a token that is expired. The Angular app gets the username and at that point I could check for expiration. However, if it is expired, I need the Angular way to react to the error condition by re-routing the whole Angular app to the relevant middleware page. Because the indicator will go to a component nested within the app, I don't know how to get the little component to redirect the bigger/encompassing app.
I'm not an Angular person, so I don't even know what part of Angular to look up. Because of my lack of knowledge, I'm including source files that might or might not be relevant.
header.component.ts is where it gets the username and could return a bad token indicator
import { Component, OnInit } from '@angular/core';
import { ProfileService } from '../../../core/services/profile.service';
@Component({
selector: 'header-comp',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
userName: string = 'No Session';
constructor(private profileService: ProfileService) { }
ngOnInit() {
this.onDisplayUserLogged();
}
onDisplayUserLogged() {
this.profileService.getUsername().subscribe(data => {
this.userName = 'Welcome: ' + data;
});
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { APP_BASE_HREF } from '@angular/common';
import { Router } from '@angular/router';
//Services
import { ProfileService } from './core/services/profile.service';
import { FinanceService } from './core/services/finance.service';
import { CmasService } from './core/services/cmas.service';
import { SoftlayerService } from './core/services/softlayer.service';
import { DashboardService } from './core/services/dashboard.service';
import { LowDollarExceptionService } from './core/services/lowDollarException.service';
//Components
import { AppComponent } from './app.component';
import { CmasComponent } from './modules/cmas/cmas.component';
import { SoftlayerComponent } from './modules/softlayer/softlayer.component';
import { FinanceComponent } from './modules/finance/finance.component';
import { ErrorComponent } from './modules/error/error/error.component';
import { LowDollarExceptionComponent } from './modules/lowDollarException/lowDollarException.component'
import { MenuComponent } from './shared/layout/menu/menu.component';
import { BasicComponent } from './shared/modals/basic/basic.component';
import { HeaderComponent } from './shared/layout/header/header.component';
import { PreProcessedPipe } from './shared/components/file-listing/file-listing.component';
import { ProcessedPipe } from './shared/components/softlayer-file-list/softlayer-file-list.component';
//Routing
import { AppRoutingModule } from './app-routing.module';
//Libs
import { AuthInterceptor } from 'auth-lib';
import { TermsComponent } from './modules/terms/terms.component';
import { FileListingComponent } from './shared/components/file-listing/file-listing.component';
import { ConfirmCancelComponent } from './shared/modals/confirm-cancel/confirm-cancel.component';
import { ErrorDisplayComponent } from './shared/components/error-display/error-display.component';
import { AboutComponent } from './modules/about/about.component';
import { ResultsComponent } from './modules/cmas/results/results.component';
import { SoftlayerFileListComponent } from './shared/components/softlayer-file-list/softlayer-file-list.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
import { ReviewResultsComponent } from './modules/softlayer/review-results/review-results.component';
import { InvoiceDetailsComponent } from './modules/dashboard/invoice-details/invoice-details.component';
import { FormsModule } from '@angular/forms';
import { LowDollarNewRecordComponent } from './modules/lowDollarException/lowDollarNewRecord.component';
@NgModule({
declarations: [
AppComponent,
CmasComponent,
FinanceComponent,
ErrorComponent,
MenuComponent,
BasicComponent,
HeaderComponent,
TermsComponent,
FileListingComponent,
PreProcessedPipe,
ProcessedPipe,
ConfirmCancelComponent,
ErrorDisplayComponent,
AboutComponent,
ResultsComponent,
SoftlayerComponent,
SoftlayerFileListComponent,
DashboardComponent,
ReviewResultsComponent,
InvoiceDetailsComponent,
LowDollarExceptionComponent,
LowDollarNewRecordComponent
],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, FormsModule],
providers: [
ProfileService,
FinanceService,
CmasService,
SoftlayerService,
DashboardService,
LowDollarExceptionService,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
deps: [Router],
multi: true,
},
{ provide: APP_BASE_HREF, useValue: '/sprint-cost-recovery' },
],
bootstrap: [AppComponent],
})
export class AppModule {}
app.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import listadeTerms from '../assets/config/properties.json';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
constructor() {}
ngOnInit() {
this.openOverlay();
}
openOverlay() {
var sheet = document.createElement('style');
sheet.innerHTML =
'.ds-full-width {visibility: hidden;} .usabilla_live_button_container{visibility: hidden;}';
document.body.appendChild(sheet);
if (document.getElementById('termsDialog')) {
var overlayElement = document.querySelector('#termsDialog');
overlayElement.classList.add('ds-open');
document
.querySelector('#termsDialogCloseBtn')
.addEventListener('click', load);
}
function load() {
var div = document.getElementById('termsDialog');
sheet.innerHTML = '.usabilla_live_button_container{visibility: true;}';
var parent = div.parentElement;
parent.removeChild(div);
var node = sheet.parentNode;
node.removeChild(sheet);
}
}
}
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// Components
import { CmasComponent } from './modules/cmas/cmas.component';
import { FinanceComponent } from './modules/finance/finance.component';
import { ErrorComponent } from './modules/error/error/error.component';
import { AboutComponent } from './modules/about/about.component';
import { SoftlayerComponent } from './modules/softlayer/softlayer.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
import { LowDollarExceptionComponent } from './modules/lowDollarException/lowDollarException.component';
import { LowDollarNewRecordComponent } from './modules/lowDollarException/lowDollarNewRecord.component';
const appRoutes: Routes = [
{ path: 'finance', component: FinanceComponent },
{ path: 'cmas-process', component: CmasComponent },
{ path: 'about', component: AboutComponent },
{ path: 'softlayer-process', component: SoftlayerComponent },
{ path: 'cost-dashboard', component: DashboardComponent },
{ path: 'low-dollar', component: LowDollarExceptionComponent },
{ path: 'low-dollar/create', component: LowDollarNewRecordComponent },
{ path: 'error/auth', component: ErrorComponent, data: { forbidden: true } },
{ path: '', redirectTo: '/finance', pathMatch: 'full' },
{
path: 'error/badgateway',
component: ErrorComponent,
data: { badgateway: true },
},
];
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule],
})
export class AppRoutingModule {}