UNPKG

angular-auth-oidc-client

Version:
113 lines 16.2 kB
import { DOCUMENT } from '@angular/common'; import { Injectable, inject } from '@angular/core'; import { LoggerService } from '../../logging/logger.service'; import * as i0 from "@angular/core"; const PARTS_OF_TOKEN = 3; export class TokenHelperService { constructor() { this.loggerService = inject(LoggerService); this.document = inject(DOCUMENT); } getTokenExpirationDate(dataIdToken) { if (!Object.prototype.hasOwnProperty.call(dataIdToken, 'exp')) { return new Date(new Date().toUTCString()); } const date = new Date(0); // The 0 here is the key, which sets the date to the epoch date.setUTCSeconds(dataIdToken.exp); return date; } getSigningInputFromToken(token, encoded, configuration) { if (!this.tokenIsValid(token, configuration)) { return ''; } const header = this.getHeaderFromToken(token, encoded, configuration); const payload = this.getPayloadFromToken(token, encoded, configuration); return [header, payload].join('.'); } getHeaderFromToken(token, encoded, configuration) { if (!this.tokenIsValid(token, configuration)) { return {}; } return this.getPartOfToken(token, 0, encoded); } getPayloadFromToken(token, encoded, configuration) { if (!configuration) { return {}; } if (!this.tokenIsValid(token, configuration)) { return {}; } return this.getPartOfToken(token, 1, encoded); } getSignatureFromToken(token, encoded, configuration) { if (!this.tokenIsValid(token, configuration)) { return {}; } return this.getPartOfToken(token, 2, encoded); } getPartOfToken(token, index, encoded) { const partOfToken = this.extractPartOfToken(token, index); if (encoded) { return partOfToken; } const result = this.urlBase64Decode(partOfToken); return JSON.parse(result); } 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 Error('Illegal base64url string!'); } const decoded = typeof this.document.defaultView !== 'undefined' ? this.document.defaultView?.atob(output) : Buffer.from(output, 'base64').toString('binary'); if (!decoded) { return ''; } try { // Going backwards: from byte stream, to percent-encoding, to original string. return decodeURIComponent(decoded .split('') .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)) .join('')); } catch (err) { return decoded; } } tokenIsValid(token, configuration) { if (!token) { this.loggerService.logError(configuration, `token '${token}' is not valid --> token falsy`); return false; } if (!token.includes('.')) { this.loggerService.logError(configuration, `token '${token}' is not valid --> no dots included`); return false; } const parts = token.split('.'); if (parts.length !== PARTS_OF_TOKEN) { this.loggerService.logError(configuration, `token '${token}' is not valid --> token has to have exactly ${PARTS_OF_TOKEN - 1} dots`); return false; } return true; } extractPartOfToken(token, index) { return token.split('.')[index]; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: TokenHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: TokenHelperService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: TokenHelperService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4taGVscGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWF1dGgtb2lkYy1jbGllbnQvc3JjL2xpYi91dGlscy90b2tlbkhlbHBlci90b2tlbi1oZWxwZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDOztBQUU3RCxNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFHekIsTUFBTSxPQUFPLGtCQUFrQjtJQUQvQjtRQUVtQixrQkFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUV0QyxhQUFRLEdBQUcsTUFBTSxDQUFXLFFBQVEsQ0FBQyxDQUFDO0tBMEt4RDtJQXhLQyxzQkFBc0IsQ0FBQyxXQUFnQjtRQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlELE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLDBEQUEwRDtRQUVwRixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVwQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCx3QkFBd0IsQ0FDdEIsS0FBZ0MsRUFDaEMsT0FBZ0IsRUFDaEIsYUFBa0M7UUFFbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENB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RUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUN6QixhQUFhLEVBQ2IsVUFBVSxLQUFLLGdEQUNiLGNBQWMsR0FBRyxDQUNuQixPQUFPLENBQ1IsQ0FBQztZQUVGLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLGtCQUFrQixDQUFDLEtBQWEsRUFBRSxLQUFhO1FBQ3JELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDOzhHQTVLVSxrQkFBa0I7a0hBQWxCLGtCQUFrQixjQURMLE1BQU07OzJGQUNuQixrQkFBa0I7a0JBRDlCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT3BlbklkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uLy4uL2NvbmZpZy9vcGVuaWQtY29uZmlndXJhdGlvbic7XHJcbmltcG9ydCB7IExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9sb2dnaW5nL2xvZ2dlci5zZXJ2aWNlJztcclxuXHJcbmNvbnN0IFBBUlRTX09GX1RPS0VOID0gMztcclxuXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBUb2tlbkhlbHBlclNlcnZpY2Uge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyU2VydmljZSA9IGluamVjdChMb2dnZXJTZXJ2aWNlKTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBkb2N1bWVudCA9IGluamVjdDxEb2N1bWVudD4oRE9DVU1FTlQpO1xyXG5cclxuICBnZXRUb2tlbkV4cGlyYXRpb25EYXRlKGRhdGFJZFRva2VuOiBhbnkpOiBEYXRlIHtcclxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGRhdGFJZFRva2VuLCAnZXhwJykpIHtcclxuICAgICAgcmV0dXJuIG5ldyBEYXRlKG5ldyBEYXRlKCkudG9VVENTdHJpbmcoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKDApOyAvLyBUaGUgMCBoZXJlIGlzIHRoZSBrZXksIHdoaWNoIHNldHMgdGhlIGRhdGUgdG8gdGhlIGVwb2NoXHJcblxyXG4gICAgZGF0ZS5zZXRVVENTZWNvbmRzKGRhdGFJZFRva2VuLmV4cCk7XHJcblxyXG4gICAgcmV0dXJuIGRhdGU7XHJcbiAgfVxyXG5cclxuICBnZXRTaWduaW5nSW5wdXRGcm9tVG9rZW4oXHJcbiAgICB0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICAgIGVuY29kZWQ6IGJvb2xlYW4sXHJcbiAgICBjb25maWd1cmF0aW9uOiBPcGVuSWRDb25maWd1cmF0aW9uXHJcbiAgKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy50b2tlbklzVmFsaWQodG9rZW4sIGNvbmZpZ3VyYXRpb24pKSB7XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBoZWFkZXI6IHN0cmluZyA9IHRoaXMuZ2V0SGVhZGVyRnJvbVRva2VuKFxyXG4gICAgICB0b2tlbixcclxuICAgICAgZW5jb2RlZCxcclxuICAgICAgY29uZmlndXJhdGlvblxyXG4gICAgKTtcclxuICAgIGNvbnN0IHBheWxvYWQ6IHN0cmluZyA9IHRoaXMuZ2V0UGF5bG9hZEZyb21Ub2tlbihcclxuICAgICAgdG9rZW4sXHJcbiAgICAgIGVuY29kZWQsXHJcbiAgICAgIGNvbmZpZ3VyYXRpb25cclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIFtoZWFkZXIsIHBheWxvYWRdLmpvaW4oJy4nKTtcclxuICB9XHJcblxyXG4gIGdldEhlYWRlckZyb21Ub2tlbihcclxuICAgIHRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsLFxyXG4gICAgZW5jb2RlZDogYm9vbGVhbixcclxuICAgIGNvbmZpZ3VyYXRpb246IE9wZW5JZENvbmZpZ3VyYXRpb25cclxuICApOiBhbnkge1xyXG4gICAgaWYgKCF0aGlzLnRva2VuSXNWYWxpZCh0b2tlbiwgY29uZmlndXJhdGlvbikpIHtcclxuICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmdldFBhcnRPZlRva2VuKHRva2VuLCAwLCBlbmNvZGVkKTtcclxuICB9XHJcblxyXG4gIGdldFBheWxvYWRGcm9tVG9rZW4oXHJcbiAgICB0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICAgIGVuY29kZWQ6IGJvb2xlYW4sXHJcbiAgICBjb25maWd1cmF0aW9uOiBPcGVuSWRDb25maWd1cmF0aW9uIHwgbnVsbFxyXG4gICk6IGFueSB7XHJcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcclxuICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy50b2tlbklzVmFsaWQodG9rZW4sIGNvbmZpZ3VyYXRpb24pKSB7XHJcbiAgICAgIHJldHVybiB7fTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXRQYXJ0T2ZUb2tlbih0b2tlbiwgMSwgZW5jb2RlZCk7XHJcbiAgfVxyXG5cclxuICBnZXRTaWduYXR1cmVGcm9tVG9rZW4oXHJcbiAgICB0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICAgIGVuY29kZWQ6IGJvb2xlYW4sXHJcbiAgICBjb25maWd1cmF0aW9uOiBPcGVuSWRDb25maWd1cmF0aW9uXHJcbiAgKTogYW55IHtcclxuICAgIGlmICghdGhpcy50b2tlbklzVmFsaWQodG9rZW4sIGNvbmZpZ3VyYXRpb24pKSB7XHJcbiAgICAgIHJldHVybiB7fTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXRQYXJ0T2ZUb2tlbih0b2tlbiwgMiwgZW5jb2RlZCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFBhcnRPZlRva2VuKHRva2VuOiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIGVuY29kZWQ6IGJvb2xlYW4pOiBhbnkge1xyXG4gICAgY29uc3QgcGFydE9mVG9rZW4gPSB0aGlzLmV4dHJhY3RQYXJ0T2ZUb2tlbih0b2tlbiwgaW5kZXgpO1xyXG5cclxuICAgIGlmIChlbmNvZGVkKSB7XHJcbiAgICAgIHJldHVybiBwYXJ0T2ZUb2tlbjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnVybEJhc2U2NERlY29kZShwYXJ0T2ZUb2tlbik7XHJcblxyXG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzdWx0KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXJsQmFzZTY0RGVjb2RlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGxldCBvdXRwdXQgPSBzdHIucmVwbGFjZSgvLS9nLCAnKycpLnJlcGxhY2UoL18vZywgJy8nKTtcclxuXHJcbiAgICBzd2l0Y2ggKG91dHB1dC5sZW5ndGggJSA0KSB7XHJcbiAgICAgIGNhc2UgMDpcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAyOlxyXG4gICAgICAgIG91dHB1dCArPSAnPT0nO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIDM6XHJcbiAgICAgICAgb3V0cHV0ICs9ICc9JztcclxuICAgICAgICBicmVhaztcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICB0aHJvdyBFcnJvcignSWxsZWdhbCBiYXNlNjR1cmwgc3RyaW5nIScpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGRlY29kZWQgPVxyXG4gICAgICB0eXBlb2YgdGhpcy5kb2N1bWVudC5kZWZhdWx0VmlldyAhPT0gJ3VuZGVmaW5lZCdcclxuICAgICAgICA/IHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXc/LmF0b2Iob3V0cHV0KVxyXG4gICAgICAgIDogQnVmZmVyLmZyb20ob3V0cHV0LCAnYmFzZTY0JykudG9TdHJpbmcoJ2JpbmFyeScpO1xyXG5cclxuICAgIGlmICghZGVjb2RlZCkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gR29pbmcgYmFja3dhcmRzOiBmcm9tIGJ5dGUgc3RyZWFtLCB0byBwZXJjZW50LWVuY29kaW5nLCB0byBvcmlnaW5hbCBzdHJpbmcuXHJcbiAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoXHJcbiAgICAgICAgZGVjb2RlZFxyXG4gICAgICAgICAgLnNwbGl0KCcnKVxyXG4gICAgICAgICAgLm1hcChcclxuICAgICAgICAgICAgKGM6IHN0cmluZykgPT4gJyUnICsgKCcwMCcgKyBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpKS5zbGljZSgtMilcclxuICAgICAgICAgIClcclxuICAgICAgICAgIC5qb2luKCcnKVxyXG4gICAgICApO1xyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgIHJldHVybiBkZWNvZGVkO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB0b2tlbklzVmFsaWQoXHJcbiAgICB0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICAgIGNvbmZpZ3VyYXRpb246IE9wZW5JZENvbmZpZ3VyYXRpb25cclxuICApOiB0b2tlbiBpcyBzdHJpbmcge1xyXG4gICAgaWYgKCF0b2tlbikge1xyXG4gICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nRXJyb3IoXHJcbiAgICAgICAgY29uZmlndXJhdGlvbixcclxuICAgICAgICBgdG9rZW4gJyR7dG9rZW59JyBpcyBub3QgdmFsaWQgLS0+IHRva2VuIGZhbHN5YFxyXG4gICAgICApO1xyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghKHRva2VuIGFzIHN0cmluZykuaW5jbHVkZXMoJy4nKSkge1xyXG4gICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nRXJyb3IoXHJcbiAgICAgICAgY29uZmlndXJhdGlvbixcclxuICAgICAgICBgdG9rZW4gJyR7dG9rZW59JyBpcyBub3QgdmFsaWQgLS0+IG5vIGRvdHMgaW5jbHVkZWRgXHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcGFydHMgPSB0b2tlbi5zcGxpdCgnLicpO1xyXG5cclxuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IFBBUlRTX09GX1RPS0VOKSB7XHJcbiAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihcclxuICAgICAgICBjb25maWd1cmF0aW9uLFxyXG4gICAgICAgIGB0b2tlbiAnJHt0b2tlbn0nIGlzIG5vdCB2YWxpZCAtLT4gdG9rZW4gaGFzIHRvIGhhdmUgZXhhY3RseSAke1xyXG4gICAgICAgICAgUEFSVFNfT0ZfVE9LRU4gLSAxXHJcbiAgICAgICAgfSBkb3RzYFxyXG4gICAgICApO1xyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBleHRyYWN0UGFydE9mVG9rZW4odG9rZW46IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdG9rZW4uc3BsaXQoJy4nKVtpbmRleF07XHJcbiAgfVxyXG59XHJcbiJdfQ==