UNPKG

@universis/common

Version:

Universis - common directives and services

114 lines (113 loc) 16.3 kB
import { Component, Input, ViewEncapsulation } from '@angular/core'; import { AngularDataContext } from '@themost/angular'; import { ActivatedUser } from '../../services/activated-user.service'; import { AuthenticationService } from '../../services/authentication.service'; export class RefreshTokenComponent { constructor(activatedUser, authService, context) { this.activatedUser = activatedUser; this.authService = authService; this.context = context; this.refreshErrors = 0; /** * Gets or sets the validation interval. The default value is 60000 ms. */ this.timerInterval = 60000; /** * Sets the number of milliseconds -before expiration- for refreshing an access token. * The default value is 60000 ms. */ this.refreshBefore = 60000; } ngOnDestroy() { if (this.userSubscription) { this.userSubscription.unsubscribe(); } this.resetTimer(); } resetTimer() { if (this.refreshTimer) { clearInterval(this.refreshTimer); this.refreshTimer = null; } } ngOnInit() { this.userSubscription = this.activatedUser.user.subscribe((user) => { if (user) { // reset timer this.resetTimer(); const token = user.token; if (token && token.refresh_token) { // get expiration const expires_in = token.expires_in; if (Number.isInteger(expires_in) && expires_in > 0) { if (token.created_at !== null) { // get date created const createdAt = new Date(token.created_at); // get expiration date and time const willBeExpiredAt = new Date(createdAt.getTime() + expires_in * 1000); this.refreshTimer = setInterval(() => { if (new Date().getTime() + this.refreshBefore >= willBeExpiredAt.getTime()) { // do refresh const service = this.authService; if (typeof service.refresh === 'function') { service.refresh().then((result) => { // clone result and refresh token user.token = JSON.parse(JSON.stringify(Object.assign(result, { created_at: new Date() }))); // clear interval this.resetTimer(); // store user to storage sessionStorage.setItem('currentUser', JSON.stringify(user)); // set bearer authorization this.context.setBearerAuthorization(user.token.access_token); // and notify components for change this.activatedUser.user.next(user); }).catch((err) => { this.refreshErrors += 1; if (this.refreshErrors > 3) { return; } console.error('An error occurred while trying to refresh token'); console.error(err); }); } } }, this.timerInterval); } else { console.warn('REFRESH_TOKEN', 'Refresh token operation cannot be completed' + ' because token timestamp cannot be determined.'); } } else { console.warn('REFRESH_TOKEN', 'Refresh token operation cannot be completed' + ' because expiration timeout has not been set.'); } } } else { // clear interval because user is null this.resetTimer(); } }); } } RefreshTokenComponent.decorators = [ { type: Component, args: [{ selector: 'universis-refresh-token', template: `<div></div>`, encapsulation: ViewEncapsulation.None }] } ]; /** @nocollapse */ RefreshTokenComponent.ctorParameters = () => [ { type: ActivatedUser }, { type: AuthenticationService }, { type: AngularDataContext } ]; RefreshTokenComponent.propDecorators = { timerInterval: [{ type: Input }], refreshBefore: [{ type: Input }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmcmVzaC10b2tlbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdW5pdmVyc2lzL2NvbW1vbi8iLCJzb3VyY2VzIjpbImF1dGgvY29tcG9uZW50cy9yZWZyZXNoL3JlZnJlc2gtdG9rZW4uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDdEUsT0FBTyxFQUFFLHFCQUFxQixFQUFrQixNQUFNLHVDQUF1QyxDQUFDO0FBUTlGLE1BQU07SUFnQkYsWUFBb0IsYUFBNEIsRUFDcEMsV0FBa0MsRUFDbEMsT0FBMkI7UUFGbkIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDcEMsZ0JBQVcsR0FBWCxXQUFXLENBQXVCO1FBQ2xDLFlBQU8sR0FBUCxPQUFPLENBQW9CO1FBZC9CLGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBRTFCOztXQUVHO1FBQ00sa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDL0I7OztXQUdHO1FBQ00sa0JBQWEsR0FBRyxLQUFLLENBQUM7SUFLL0IsQ0FBQztJQUNELFdBQVc7UUFDUCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN2QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDdkM7UUFDRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVPLFVBQVU7UUFDZCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDbkIsYUFBYSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztTQUM1QjtJQUNMLENBQUM7SUFFRCxRQUFRO1FB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RSwrQ0FBK0MsQ0FBQyxDQUFDO3FCQUN4RDtpQkFDSjthQUNKO2lCQUFNO2dCQUNILHNDQUFzQztnQkFDdEMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2FBQ3JCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOzs7WUF2R0osU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSx5QkFBeUI7Z0JBQ25DLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTthQUN4Qzs7OztZQVBRLGFBQWE7WUFDYixxQkFBcUI7WUFIckIsa0JBQWtCOzs7NEJBb0J0QixLQUFLOzRCQUtMLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFuZ3VsYXJEYXRhQ29udGV4dCB9IGZyb20gJ0B0aGVtb3N0L2FuZ3VsYXInO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRVc2VyIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYWN0aXZhdGVkLXVzZXIuc2VydmljZSc7XG5pbXBvcnQgeyBBdXRoZW50aWNhdGlvblNlcnZpY2UsIE9uUmVmcmVzaFRva2VuIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXV0aGVudGljYXRpb24uc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAndW5pdmVyc2lzLXJlZnJlc2gtdG9rZW4nLFxuICAgIHRlbXBsYXRlOiBgPGRpdj48L2Rpdj5gLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuXG5leHBvcnQgY2xhc3MgUmVmcmVzaFRva2VuQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSB1c2VyU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSByZWZyZXNoVGltZXI6IGFueTtcbiAgICBwcml2YXRlIHJlZnJlc2hFcnJvcnMgPSAwO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSB2YWxpZGF0aW9uIGludGVydmFsLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA2MDAwMCBtcy5cbiAgICAgKi9cbiAgICBASW5wdXQoKSB0aW1lckludGVydmFsID0gNjAwMDA7XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyAtYmVmb3JlIGV4cGlyYXRpb24tIGZvciByZWZyZXNoaW5nIGFuIGFjY2VzcyB0b2tlbi5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA2MDAwMCBtcy5cbiAgICAgKi9cbiAgICBASW5wdXQoKSByZWZyZXNoQmVmb3JlID0gNjAwMDA7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFjdGl2YXRlZFVzZXI6IEFjdGl2YXRlZFVzZXIsXG4gICAgICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhlbnRpY2F0aW9uU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb250ZXh0OiBBbmd1bGFyRGF0YUNvbnRleHQpIHtcbiAgICB9XG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnVzZXJTdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMudXNlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRUaW1lcigpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaFRpbWVyKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMucmVmcmVzaFRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaFRpbWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnVzZXJTdWJzY3JpcHRpb24gPSB0aGlzLmFjdGl2YXRlZFVzZXIudXNlci5zdWJzY3JpYmUoKHVzZXIpID0+IHtcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVzZXQgdGltZXJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0VGltZXIoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB0b2tlbjoge1xuICAgICAgICAgICAgICAgICAgICBleHBpcmVzX2luPzogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuPzogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgICByZWZyZXNoX2V4cGlyZXNfaW4/OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRfYXQ/OiBEYXRlO1xuICAgICAgICAgICAgICAgIH0gPSB1c2VyLnRva2VuO1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbiAmJiB0b2tlbi5yZWZyZXNoX3Rva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCBleHBpcmF0aW9uXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cGlyZXNfaW4gPSB0b2tlbi5leHBpcmVzX2luO1xuICAgICAgICAgICAgICAgICAgICBpZiAoTnVtYmVyLmlzSW50ZWdlcihleHBpcmVzX2luKSAmJiBleHBpcmVzX2luID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmNyZWF0ZWRfYXQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgZGF0ZSBjcmVhdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3JlYXRlZEF0ID0gbmV3IERhdGUodG9rZW4uY3JlYXRlZF9hdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IGV4cGlyYXRpb24gZGF0ZSBhbmQgdGltZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpbGxCZUV4cGlyZWRBdCA9IG5ldyBEYXRlKGNyZWF0ZWRBdC5nZXRUaW1lKCkgKyBleHBpcmVzX2luICogMTAwMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSArIHRoaXMucmVmcmVzaEJlZm9yZSA+PSB3aWxsQmVFeHBpcmVkQXQuZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyByZWZyZXNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXJ2aWNlID0gdGhpcy5hdXRoU2VydmljZSBhcyBhbnkgYXMgT25SZWZyZXNoVG9rZW47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNlcnZpY2UucmVmcmVzaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2UucmVmcmVzaCgpLnRoZW4oKHJlc3VsdDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsb25lIHJlc3VsdCBhbmQgcmVmcmVzaCB0b2tlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VyLnRva2VuID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShPYmplY3QuYXNzaWduKHJlc3VsdCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZF9hdDogbmV3IERhdGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbGVhciBpbnRlcnZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0VGltZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgdXNlciB0byBzdG9yYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2N1cnJlbnRVc2VyJywgSlNPTi5zdHJpbmdpZnkodXNlcikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgYmVhcmVyIGF1dGhvcml6YXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldEJlYXJlckF1dGhvcml6YXRpb24odXNlci50b2tlbi5hY2Nlc3NfdG9rZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgbm90aWZ5IGNvbXBvbmVudHMgZm9yIGNoYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2YXRlZFVzZXIudXNlci5uZXh0KHVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoRXJyb3JzICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlZnJlc2hFcnJvcnMgPiAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIHJlZnJlc2ggdG9rZW4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpcy50aW1lckludGVydmFsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdSRUZSRVNIX1RPS0VOJywgJ1JlZnJlc2ggdG9rZW4gb3BlcmF0aW9uIGNhbm5vdCBiZSBjb21wbGV0ZWQnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBiZWNhdXNlIHRva2VuIHRpbWVzdGFtcCBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUkVGUkVTSF9UT0tFTicsICdSZWZyZXNoIHRva2VuIG9wZXJhdGlvbiBjYW5ub3QgYmUgY29tcGxldGVkJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBiZWNhdXNlIGV4cGlyYXRpb24gdGltZW91dCBoYXMgbm90IGJlZW4gc2V0LicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBjbGVhciBpbnRlcnZhbCBiZWNhdXNlIHVzZXIgaXMgbnVsbFxuICAgICAgICAgICAgICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iXX0=