<!DOCTYPE html>

<html>
  <head>
    <script src="./lib/main.ts"></script>
  </head>

  <body>
    <my-app>
      loading...
    </my-app>
  </body>
</html>
//our root app component
import { Component, NgModule, VERSION } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>Token Decoder</h1>
      <h3>Raw token</h3>
      {{token}}
      <h3>Decoded Token</h3>
      {{JSON.stringify(decodedToken)}}
      <h3>Expiration</h3>
      {{expiration}}
    </div>
  `,
})
export class App {
  token: string;
  decodedToken: any;
  expiration: Date;
  private JSON = JSON

  constructor() {
    this.token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTeW5lcmd5Iiwic3ViIjoibWFuYWdlciIsImF1ZCI6IjAwZGMwZDFkLTRkYWItNDM1ZS1hNzJjLTZiMjYxNWVmMmUzYyIsImV4cCI6IjE1ODk0NTg2NzgiLCJpYXQiOiIxNTg4ODUzODc4IiwicGlkIjoiZWVlMjhhNjgtYWYzMC00MTRhLTk4YzEtYTdmZjExMjliYmE3IiwiY29tcGFueUlkcyI6WyJFUElDMDEiLCJFUElDMDIiLCJFUElDMDMiLCJFUElDMDQiLCJFUElDMDUiLCJFUElDMDYiLCJFUElDMDciLCJFUElDMDgiLCJFUElDMTAwIiwiRVBJQzYwIiwiRVBJQzcwIiwiRVBJQzgwIiwiRVBJQzkwIiwiRVBJQ1BGIiwiR1BDIl0sImluc3RhbGxhdGlvbklkIjoiMWFmNzZhOTYtMDExYy00OGE5LTkwYjctODQ5Y2NmYzgwY2JmIiwibmFtZSI6Im1hbmFnZXIifQ.kcAJGBBvfRxc059jDueQ08YcgNqgqHcY3qgQy4alXk4';
    this.decodedToken = this.decodeToken(this.token);
    this.expiration = new Date(this.decodedToken.exp * 1000);
  }

  // token parsing from https://winsmarts.com/parse-jwt-tokens-using-typescript-9e9c1e186f3e
  private urlBase64Decode(str: string) {
        let output = str.replace(/-/g, '+').replace(/_/g, '/');
        switch (output.length % 4) {
            case 0:
                break;
            case 2:
                output += '==';
                break;
            case 3:
                output += '=';
                break;
            default:
                // tslint:disable-next-line:no-string-throw
                throw 'Illegal base64url string!';
        }
        return decodeURIComponent((<any>window).escape(window.atob(output)));
    }

    public decodeToken(token: string = '') {
        if (token === null || token === '') { return { 'upn': '' }; }
        const parts = token.split('.');
        if (parts.length !== 3) {

            throw new Error('JWT must have 3 parts');
        }
        const decoded = this.urlBase64Decode(parts[1]);
        if (!decoded) {
            throw new Error('Cannot decode the token');
        }
        return JSON.parse(decoded);
    }
};

@NgModule({
  imports: [BrowserModule],
  declarations: [App],
  bootstrap: [App],
})
export class AppModule {}
// Shim the environment
import 'core-js/client/shim';

// Angular requires Zones to be pre-configured in the environment
import 'zone.js/dist/zone';

//main entry point
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app';

import './style.css';

platformBrowserDynamic().bootstrapModule(AppModule);
h1,
p {
  font-family: sans-serif;
}
{
  "name": "@plnkr/starter-angular",
  "version": "1.0.3",
  "description": "Angular starter template",
  "dependencies": {
    "@angular/common": "^8.2.14",
    "@angular/compiler": "^8.2.14",
    "@angular/core": "^8.2.14",
    "@angular/platform-browser": "^8.2.14",
    "@angular/platform-browser-dynamic": "^8.2.14",
    "core-js": "2.6.11",
    "rxjs": "6.5.4",
    "zone.js": "0.10.2"
  },
  "main": "./lib/main.ts",
  "plnkr": {
    "runtime": "system",
    "useHotReload": true
  }
}
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}