Verified Commit d2a5872d authored by Raphael Ochsenbein's avatar Raphael Ochsenbein
Browse files

Decode / show id and access tokens in browser

parent 6af5b11d
Pipeline #660 passed with stages
in 1 minute and 44 seconds
......@@ -6459,6 +6459,11 @@
"safe-buffer": "^5.0.1"
}
},
"jwt-decode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"karma": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz",
......
<div>
<h1>
Welcome to {{ title }}!
</h1>
<div class="bx--grid">
<div class="bx--row">
<div class="bx--col-xs-12">
<div>
<h1>
Welcome to {{ title }}!
</h1>
</div>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="loginPopup()">Log In</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="logoutPopup()">Log Out</button>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="call1FAAPI()">Call 1FA API</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="call2FAAPI()">Call 2FA API</button>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="check2FA()">Check 2FA</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="loginPopup2fA()">Login Request 2FA</button>
<hr/>
</div>
</div>
</div>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="loginPopup()">Log In</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="logoutPopup()">Log Out</button>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="call1FAAPI()">Call 1FA API</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="call2FAAPI()">Call 2FA API</button>
<hr/>
<button [ibmButton]="'primary'" [size]="'normal'" (click)="check2FA()">Check 2FA</button>
<button [ibmButton]="'danger--primary'" [size]="'normal'" (click)="loginPopup2fA()">Login Request 2FA</button>
<hr/>
<ng-container *ngIf="oidcError && (oidcError.signInError || oidcError.silentRenewError)">
<h2>OIDC Error</h2>
<ibm-code-snippet display="multi">{{ oidcError | json }}</ibm-code-snippet>
<hr/>
</ng-container>
<ng-container *ngIf="apiError">
<h2>API Error</h2>
<ibm-code-snippet display="multi">{{ apiError | json }}</ibm-code-snippet>
<div class="bx--grid">
<div class="bx--row">
<ng-container *ngIf="oidcError && (oidcError.signInError || oidcError.silentRenewError)">
<div class="bx--col-xs-12 bx--col-sm-6">
<h2>OIDC Error</h2>
<ibm-code-snippet display="multi">{{ oidcError | json }}</ibm-code-snippet>
</div>
</ng-container>
<ng-container *ngIf="apiError">
<div class="bx--col-xs-12 bx--col-sm-6">
<h2>API Error</h2>
<ibm-code-snippet display="multi">{{ apiError | json }}</ibm-code-snippet>
</div>
</ng-container>
</div>
<hr/>
</ng-container>
</div>
<ng-container *ngIf="identity">
<h2>Identity</h2>
<h3>Your Profile</h3>
<ibm-code-snippet display="multi">{{ identity.profile | json }}</ibm-code-snippet>
<h3>Scopes</h3>
<ibm-code-snippet display="multi">{{ identity.scope }}</ibm-code-snippet>
<h3>ID Token</h3>
<ibm-code-snippet display="multi">{{ identity.id_token }}</ibm-code-snippet>
<h3>Access Token</h3>
<ibm-code-snippet display="multi">{{ identity.access_token }}</ibm-code-snippet>
<div class="bx--grid">
<div class="bx--row">
<div class="bx--col-xs-12">
<h2>Identity</h2>
</div>
<div class="bx--col-xs-12 bx--col-sm-6">
<h3>Your Profile</h3>
<ibm-code-snippet display="multi">{{ identity.profile | json }}</ibm-code-snippet>
</div>
<div class="bx--col-xs-12 bx--col-sm-6">
<h3>Scopes</h3>
<ibm-code-snippet display="multi">{{ identity.scope }}</ibm-code-snippet>
</div>
<div class="bx--col-xs-12 bx--col-sm-6">
<h3>ID Token</h3>
<ibm-code-snippet display="multi">{{ identity.id_token }}</ibm-code-snippet>
</div>
<div class="bx--col-xs-12 bx--col-sm-6" *ngIf="decodedIdToken">
<h3>Decoded ID Token</h3>
<ibm-code-snippet display="multi">{{ decodedIdToken | json }}</ibm-code-snippet>
</div>
<div class="bx--col-xs-12 bx--col-sm-6">
<h3>Access Token</h3>
<ibm-code-snippet display="multi">{{ identity.access_token }}</ibm-code-snippet>
</div>
<div class="bx--col-xs-12 bx--col-sm-6" *ngIf="decodedAccessToken">
<h3>Decoded Access Token</h3>
<ibm-code-snippet display="multi">{{ decodedAccessToken | json }}</ibm-code-snippet>
</div>
</div>
</div>
<hr/>
</ng-container>
......@@ -2,11 +2,12 @@ import { Component, OnDestroy } from '@angular/core';
import { OidcFacade } from 'ng-oidc-client';
import { ToastService } from './toast';
import { Observable, of, Subscription } from 'rxjs';
import {catchError, tap} from 'rxjs/operators';
import { catchError, tap } from 'rxjs/operators';
import { environment } from '.././environments/environment';
import { HttpClient } from '@angular/common/http';
import { User as OidcUser } from 'oidc-client';
import { ErrorState } from 'ng-oidc-client/lib/reducers/oidc.reducer';
import * as jwt_decode from 'jwt-decode';
@Component({
selector: 'app-root',
......@@ -21,6 +22,9 @@ export class AppComponent implements OnDestroy {
identity: OidcUser;
oidcError: ErrorState;
apiError: any;
decodeError: object;
decodedIdToken: object;
decodedAccessToken: string;
loadingSub: Subscription;
expiringSub: Subscription;
......@@ -69,12 +73,18 @@ export class AppComponent implements OnDestroy {
this.identitySub = this.oidcFacade.identity$.subscribe((data) => {
this.identity = data;
try {
this.decodedIdToken = jwt_decode(data.id_token);
this.decodedAccessToken = jwt_decode(data.access_token);
} catch (e) {
this.decodeError = e;
}
});
}
loginPopup() {
this.apiError = null;
this.oidcError = null;
this.reset();
this.toast.show({
type: 'info',
......@@ -88,8 +98,7 @@ export class AppComponent implements OnDestroy {
}
logoutPopup() {
this.apiError = null;
this.oidcError = null;
this.reset();
this.toast.show({
type: 'warn',
......@@ -145,8 +154,7 @@ export class AppComponent implements OnDestroy {
}
loginPopup2fA() {
this.apiError = null;
this.oidcError = null;
this.reset();
this.toast.show({
type: 'warn',
......@@ -225,5 +233,10 @@ export class AppComponent implements OnDestroy {
this.loggedInSub.unsubscribe();
this.identitySub.unsubscribe();
}
reset() {
this.apiError = null;
this.oidcError = null;
}
}
......@@ -41,7 +41,7 @@ export const rootStore: ActionReducerMap<State> = {
CodeSnippetModule,
ToastModule.forRoot(),
StoreModule.forRoot(rootStore, { metaReducers}),
StoreDevtoolsModule.instrument(), // could be like configured oidc module to only import in dev
StoreDevtoolsModule.instrument(),
EffectsModule.forRoot([OidcEffectsService]),
ConfiguredOidcModuleModule.forRoot(environment),
],
......
......@@ -47,6 +47,10 @@ export class ConfiguredOidcModuleForDev {}
})
export class ConfiguredOidcModuleModule {
public static forRoot( environment ) {
return { ngModule: ( environment.production ? ConfiguredOidcModuleForProd : ConfiguredOidcModuleForDev ) };
return { ngModule: (
environment.production
? ConfiguredOidcModuleForProd
: ConfiguredOidcModuleForDev
) };
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment