import * as i0 from '@angular/core'; import { InjectionToken, Injectable, Inject, NgModule, Optional, SkipSelf } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { map, mergeMap } from 'rxjs/operators'; import { defer, of } from 'rxjs'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; const JWT_OPTIONS = new InjectionToken('JWT_OPTIONS'); /* eslint-disable no-bitwise */ class JwtHelperService { constructor(config = null) { this.tokenGetter = (config && config.tokenGetter) || function () { }; } urlBase64Decode(str) { let output = str.replace(/-/g, '+').replace(/_/g, '/'); switch (output.length % 4) { case 0: { break; } case 2: { output += '=='; break; } case 3: { output += '='; break; } default: { throw new Error('Illegal base64url string!'); } } return this.b64DecodeUnicode(output); } // credits for decoder goes to https://github.com/atk b64decode(str) { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; let output = ''; str = String(str).replace(/=+$/, ''); if (str.length % 4 === 1) { throw new Error(`'atob' failed: The string to be decoded is not correctly encoded.`); } for ( // initialize result and counters let bc = 0, bs, buffer, idx = 0; // get next character (buffer = str.charAt(idx++)); // character found in table? initialize bit storage and add its ascii value; ~buffer && ((bs = bc % 4 ? bs * 64 + buffer : buffer), // and if not first of each 4 characters, // convert the first 8 bits to one ascii character bc++ % 4) ? (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) : 0) { // try to find character in table (0-63, not found => -1) buffer = chars.indexOf(buffer); } return output; } b64DecodeUnicode(str) { return decodeURIComponent(Array.prototype.map .call(this.b64decode(str), (c) => { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }) .join('')); } decodeToken(token = this.tokenGetter()) { if (token instanceof Promise) { return token.then(t => this._decodeToken(t)); } return this._decodeToken(token); } _decodeToken(token) { if (!token || token === '') { return null; } const parts = token.split('.'); if (parts.length !== 3) { throw new Error(`The inspected token doesn't appear to be a JWT. Check to make sure it has three parts and see https://jwt.io for more.`); } const decoded = this.urlBase64Decode(parts[1]); if (!decoded) { throw new Error('Cannot decode the token.'); } return JSON.parse(decoded); } getTokenExpirationDate(token = this.tokenGetter()) { if (token instanceof Promise) { return token.then(t => this._getTokenExpirationDate(t)); } return this._getTokenExpirationDate(token); } _getTokenExpirationDate(token) { let decoded; decoded = this.decodeToken(token); if (!decoded || !decoded.hasOwnProperty('exp')) { return null; } const date = new Date(0); date.setUTCSeconds(decoded.exp); return date; } isTokenExpired(token = this.tokenGetter(), offsetSeconds) { if (token instanceof Promise) { return token.then(t => this._isTokenExpired(t, offsetSeconds)); } return this._isTokenExpired(token, offsetSeconds); } _isTokenExpired(token, offsetSeconds) { if (!token || token === '') { return true; } const date = this.getTokenExpirationDate(token); offsetSeconds = offsetSeconds || 0; if (date === null) { return false; } return !(date.valueOf() > new Date().valueOf() + offsetSeconds * 1000); } getAuthScheme(authScheme, request) { if (typeof authScheme === 'function') { return authScheme(request); } return authScheme; } } JwtHelperService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtHelperService, deps: [{ token: JWT_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable }); JwtHelperService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtHelperService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtHelperService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [JWT_OPTIONS] }] }]; } }); const fromPromiseOrValue = (input) => { if (input instanceof Promise) { return defer(() => input); } return of(input); }; class JwtInterceptor { constructor(config, jwtHelper, document) { this.jwtHelper = jwtHelper; this.document = document; this.standardPorts = ['80', '443']; this.tokenGetter = config.tokenGetter; this.headerName = config.headerName || 'Authorization'; this.authScheme = config.authScheme || config.authScheme === '' ? config.authScheme : 'Bearer '; this.allowedDomains = config.allowedDomains || []; this.disallowedRoutes = config.disallowedRoutes || []; this.throwNoTokenError = config.throwNoTokenError || false; this.skipWhenExpired = config.skipWhenExpired; } isAllowedDomain(request) { const requestUrl = new URL(request.url, this.document.location.origin); // If the host equals the current window origin, // the domain is allowed by default if (requestUrl.host === this.document.location.host) { return true; } // If not the current domain, check the allowed list const hostName = `${requestUrl.hostname}${requestUrl.port && !this.standardPorts.includes(requestUrl.port) ? ':' + requestUrl.port : ''}`; return (this.allowedDomains.findIndex((domain) => typeof domain === 'string' ? domain === hostName : domain instanceof RegExp ? domain.test(hostName) : false) > -1); } isDisallowedRoute(request) { const requestedUrl = new URL(request.url, this.document.location.origin); return (this.disallowedRoutes.findIndex((route) => { if (typeof route === 'string') { const parsedRoute = new URL(route, this.document.location.origin); return (parsedRoute.hostname === requestedUrl.hostname && parsedRoute.pathname === requestedUrl.pathname); } if (route instanceof RegExp) { return route.test(request.url); } return false; }) > -1); } handleInterception(token, request, next) { const authScheme = this.jwtHelper.getAuthScheme(this.authScheme, request); if (!token && this.throwNoTokenError) { throw new Error('Could not get token from tokenGetter function.'); } let tokenIsExpired = of(false); if (this.skipWhenExpired) { tokenIsExpired = token ? fromPromiseOrValue(this.jwtHelper.isTokenExpired(token)) : of(true); } if (token) { return tokenIsExpired.pipe(map((isExpired) => isExpired && this.skipWhenExpired ? request.clone() : request.clone({ setHeaders: { [this.headerName]: `${authScheme}${token}`, }, })), mergeMap((innerRequest) => next.handle(innerRequest))); } return next.handle(request); } intercept(request, next) { if (!this.isAllowedDomain(request) || this.isDisallowedRoute(request)) { return next.handle(request); } const token = this.tokenGetter(request); return fromPromiseOrValue(token).pipe(mergeMap((asyncToken) => { return this.handleInterception(asyncToken, request, next); })); } } JwtInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtInterceptor, deps: [{ token: JWT_OPTIONS }, { token: JwtHelperService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); JwtInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtInterceptor }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtInterceptor, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [JWT_OPTIONS] }] }, { type: JwtHelperService }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; } }); class JwtModule { constructor(parentModule) { if (parentModule) { throw new Error(`JwtModule is already loaded. It should only be imported in your application's main module.`); } } static forRoot(options) { return { ngModule: JwtModule, providers: [ { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true, }, options.jwtOptionsProvider || { provide: JWT_OPTIONS, useValue: options.config, }, JwtHelperService, ], }; } } JwtModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtModule, deps: [{ token: JwtModule, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.NgModule }); JwtModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: JwtModule }); JwtModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtModule }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: JwtModule, decorators: [{ type: NgModule }], ctorParameters: function () { return [{ type: JwtModule, decorators: [{ type: Optional }, { type: SkipSelf }] }]; } }); /* * Public API Surface of angular-jwt */ /** * Generated bundle index. Do not edit. */ export { JWT_OPTIONS, JwtHelperService, JwtInterceptor, JwtModule }; //# sourceMappingURL=auth0-angular-jwt.mjs.map