angular-simple-oidc
Version:
Angular Library implementing Open Id Connect specification. Code Flow, Refresh Tokens, Session Management, Discovery Document.
87 lines • 13.6 kB
JavaScript
import { Injectable, Inject } from '@angular/core';
import { TokenStorageService } from './token-storage.service';
import { map, tap, switchMap, take, shareReplay } from 'rxjs/operators';
import { OidcCodeFlowClient } from './oidc-code-flow-client.service';
import { TokenHelperService } from 'angular-simple-oidc/core';
import { RefreshTokenClient } from './refresh-token-client.service';
import { EndSessionClientService } from './end-session-client.service';
import { AUTH_CONFIG_SERVICE } from './providers';
import { ConfigService } from 'angular-simple-oidc/config';
import { EventsService } from 'angular-simple-oidc/events';
import { UserInfoClientService } from './user-info-client.service';
import { filterInstanceOf } from 'angular-simple-oidc/operators';
import { TokensReadyEvent } from './auth.events';
export class AuthService {
constructor(oidcClient, tokenHelper, tokenStorage, refreshTokenClient, endSessionClient, config, events, userInfoClient) {
this.oidcClient = oidcClient;
this.tokenHelper = tokenHelper;
this.tokenStorage = tokenStorage;
this.refreshTokenClient = refreshTokenClient;
this.endSessionClient = endSessionClient;
this.config = config;
this.events = events;
this.userInfoClient = userInfoClient;
this.userInfo$ = this.events$.pipe(filterInstanceOf(TokensReadyEvent), switchMap(() => this.userInfoClient.getUserInfo()), shareReplay());
}
get isLoggedIn$() {
return this.tokenStorage.currentState$
.pipe(map(({ accessToken, accessTokenExpiration }) => {
if (!accessToken || this.tokenHelper.isTokenExpired(accessTokenExpiration)) {
return false;
}
return true;
}));
}
get accessToken$() {
return this.tokenStorage.currentState$
.pipe(map(s => s.accessToken));
}
get tokenExpiration$() {
return this.tokenStorage.currentState$
.pipe(map(s => new Date(s.accessTokenExpiration)));
}
get refreshToken$() {
return this.tokenStorage.currentState$
.pipe(map(s => s.refreshToken));
}
get identityToken$() {
return this.tokenStorage.currentState$
.pipe(map(s => s.identityToken));
}
get identityTokenDecoded$() {
return this.tokenStorage.currentState$
.pipe(map(s => s.decodedIdentityToken));
}
get events$() {
return this.events.events$;
}
get errors$() {
return this.events.errors$;
}
startCodeFlow(options) {
return this.oidcClient.startCodeFlow(options)
.pipe(tap({ error: e => this.events.dispatchError(e) }));
}
refreshAccessToken() {
return this.refreshTokenClient.requestTokenWithRefreshCode()
.pipe(tap({ error: e => this.events.dispatchError(e) }));
}
endSession(postLogoutRedirectUri) {
return this.config.current$
.pipe(take(1), switchMap(config => this.endSessionClient.logoutWithRedirect(postLogoutRedirectUri || config.baseUrl)), tap({ error: e => this.events.dispatchError(e) }));
}
}
AuthService.decorators = [
{ type: Injectable }
];
AuthService.ctorParameters = () => [
{ type: OidcCodeFlowClient },
{ type: TokenHelperService },
{ type: TokenStorageService },
{ type: RefreshTokenClient },
{ type: EndSessionClientService },
{ type: ConfigService, decorators: [{ type: Inject, args: [AUTH_CONFIG_SERVICE,] }] },
{ type: EventsService },
{ type: UserInfoClientService }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1zaW1wbGUtb2lkYy9zcmMvbGliL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxrQkFBa0IsRUFBd0QsTUFBTSwwQkFBMEIsQ0FBQztBQUNwSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUV2RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNELE9BQU8sRUFBRSxhQUFhLEVBQXlDLE1BQU0sNEJBQTRCLENBQUM7QUFFbEcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR2pELE1BQU0sT0FBTyxXQUFXO0lBc0RwQixZQUN1QixVQUE4QixFQUM5QixXQUErQixFQUMvQixZQUFpQyxFQUNqQyxrQkFBc0MsRUFDdEMsZ0JBQXlDLEVBRXpDLE1BQWlDLEVBQ2pDLE1BQXFCLEVBQ3JCLGNB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dkQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFTSxVQUFVLENBQUMscUJBQThCO1FBQzVDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO2FBQ3RCLElBQUksQ0FDRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUN0RyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQ3BELENBQUM7SUFDVixDQUFDOzs7WUFwRkosVUFBVTs7O1lBZEYsa0JBQWtCO1lBQ2xCLGtCQUFrQjtZQUhsQixtQkFBbUI7WUFJbkIsa0JBQWtCO1lBQ2xCLHVCQUF1QjtZQUd2QixhQUFhLHVCQXFFYixNQUFNLFNBQUMsbUJBQW1CO1lBbkUxQixhQUFhO1lBRWIscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUb2tlblN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi90b2tlbi1zdG9yYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgbWFwLCB0YXAsIHN3aXRjaE1hcCwgdGFrZSwgc2hhcmVSZXBsYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPaWRjQ29kZUZsb3dDbGllbnQgfSBmcm9tICcuL29pZGMtY29kZS1mbG93LWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IFRva2VuSGVscGVyU2VydmljZSwgRGVjb2RlZElkZW50aXR5VG9rZW4sIExvY2FsU3RhdGUsIFRva2VuUmVxdWVzdFJlc3VsdCB9IGZyb20gJ2FuZ3VsYXItc2ltcGxlLW9pZGMvY29yZSc7XG5pbXBvcnQgeyBSZWZyZXNoVG9rZW5DbGllbnQgfSBmcm9tICcuL3JlZnJlc2gtdG9rZW4tY2xpZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgRW5kU2Vzc2lvbkNsaWVudFNlcnZpY2UgfSBmcm9tICcuL2VuZC1zZXNzaW9uLWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEFVVEhfQ09ORklHX1NFUlZJQ0UgfSBmcm9tICcuL3Byb3ZpZGVycyc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnYW5ndWxhci1zaW1wbGUtb2lkYy9jb25maWcnO1xuaW1wb3J0IHsgQXV0aENvbmZpZyB9IGZyb20gJy4vY29uZmlnL21vZGVscyc7XG5pbXBvcnQgeyBFdmVudHNTZXJ2aWNlLCBTaW1wbGVPaWRjRXZlbnQsIFNpbXBsZU9pZGNFcnJvckV2ZW50IH0gZnJvbSAnYW5ndWxhci1zaW1wbGUtb2lkYy9ldmVudHMnO1xuaW1wb3J0IHsgU3RhcnRDb2RlRmxvd1BhcmFtZXRlcnMsIENsYWltQ29sbGVjdGlvbiB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IFVzZXJJbmZvQ2xpZW50U2VydmljZSB9IGZyb20gJy4vdXNlci1pbmZvLWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IGZpbHRlckluc3RhbmNlT2YgfSBmcm9tICdhbmd1bGFyLXNpbXBsZS1vaWRjL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUb2tlbnNSZWFkeUV2ZW50IH0gZnJvbSAnLi9hdXRoLmV2ZW50cyc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSB7XG5cbiAgICBwdWJsaWMgZ2V0IGlzTG9nZ2VkSW4kKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlblN0b3JhZ2UuY3VycmVudFN0YXRlJFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgbWFwKCh7IGFjY2Vzc1Rva2VuLCBhY2Nlc3NUb2tlbkV4cGlyYXRpb24gfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFjY2Vzc1Rva2VuIHx8IHRoaXMudG9rZW5IZWxwZXIuaXNUb2tlbkV4cGlyZWQoYWNjZXNzVG9rZW5FeHBpcmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhY2Nlc3NUb2tlbiQoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9rZW5TdG9yYWdlLmN1cnJlbnRTdGF0ZSRcbiAgICAgICAgICAgIC5waXBlKG1hcChzID0+IHMuYWNjZXNzVG9rZW4pKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHRva2VuRXhwaXJhdGlvbiQoKTogT2JzZXJ2YWJsZTxEYXRlPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRva2VuU3RvcmFnZS5jdXJyZW50U3RhdGUkXG4gICAgICAgICAgICAucGlwZShtYXAocyA9PiBuZXcgRGF0ZShzLmFjY2Vzc1Rva2VuRXhwaXJhdGlvbikpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHJlZnJlc2hUb2tlbiQoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9rZW5TdG9yYWdlLmN1cnJlbnRTdGF0ZSRcbiAgICAgICAgICAgIC5waXBlKG1hcChzID0+IHMucmVmcmVzaFRva2VuKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpZGVudGl0eVRva2VuJCgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlblN0b3JhZ2UuY3VycmVudFN0YXRlJFxuICAgICAgICAgICAgLnBpcGUobWFwKHMgPT4gcy5pZGVudGl0eVRva2VuKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpZGVudGl0eVRva2VuRGVjb2RlZCQoKTogT2JzZXJ2YWJsZTxEZWNvZGVkSWRlbnRpdHlUb2tlbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlblN0b3JhZ2UuY3VycmVudFN0YXRlJFxuICAgICAgICAgICAgLnBpcGUobWFwKHMgPT4gcy5kZWNvZGVkSWRlbnRpdHlUb2tlbikpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWFkb25seSB1c2VySW5mbyQ6IE9ic2VydmFibGU8Q2xhaW1Db2xsZWN0aW9uPiA9IHRoaXMuZXZlbnRzJC5waXBlKFxuICAgICAgICBmaWx0ZXJJbnN0YW5jZU9mKFRva2Vuc1JlYWR5RXZlbnQpLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy51c2VySW5mb0NsaWVudC5nZXRVc2VySW5mbygpKSxcbiAgICAgICAgc2hhcmVSZXBsYXkoKVxuICAgICk7XG5cbiAgICBwdWJsaWMgZ2V0IGV2ZW50cyQoKTogT2JzZXJ2YWJsZTxTaW1wbGVPaWRjRXZlbnQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLmV2ZW50cyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBlcnJvcnMkKCk6IE9ic2VydmFibGU8U2ltcGxlT2lkY0Vycm9yRXZlbnQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLmVycm9ycyQ7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBvaWRjQ2xpZW50OiBPaWRjQ29kZUZsb3dDbGllbnQsXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSB0b2tlbkhlbHBlcjogVG9rZW5IZWxwZXJTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9rZW5TdG9yYWdlOiBUb2tlblN0b3JhZ2VTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVmcmVzaFRva2VuQ2xpZW50OiBSZWZyZXNoVG9rZW5DbGllbnQsXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBlbmRTZXNzaW9uQ2xpZW50OiBFbmRTZXNzaW9uQ2xpZW50U2VydmljZSxcbiAgICAgICAgQEluamVjdChBVVRIX0NPTkZJR19TRVJWSUNFKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29uZmlnOiBDb25maWdTZXJ2aWNlPEF1dGhDb25maWc+LFxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXZlbnRzOiBFdmVudHNTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgdXNlckluZm9DbGllbnQ6IFVzZXJJbmZvQ2xpZW50U2VydmljZVxuICAgICkgeyB9XG5cbiAgICBwdWJsaWMgc3RhcnRDb2RlRmxvdyhvcHRpb25zPzogU3RhcnRDb2RlRmxvd1BhcmFtZXRlcnMpOiBPYnNlcnZhYmxlPExvY2FsU3RhdGU+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMub2lkY0NsaWVudC5zdGFydENvZGVGbG93KG9wdGlvbnMpXG4gICAgICAgICAgICAucGlwZSh0YXAoeyBlcnJvcjogZSA9PiB0aGlzLmV2ZW50cy5kaXNwYXRjaEVycm9yKGUpIH0pKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaEFjY2Vzc1Rva2VuKCk6IE9ic2VydmFibGU8VG9rZW5SZXF1ZXN0UmVzdWx0PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hUb2tlbkNsaWVudC5yZXF1ZXN0VG9rZW5XaXRoUmVmcmVzaENvZGUoKVxuICAgICAgICAgICAgLnBpcGUodGFwKHsgZXJyb3I6IGUgPT4gdGhpcy5ldmVudHMuZGlzcGF0Y2hFcnJvcihlKSB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIGVuZFNlc3Npb24ocG9zdExvZ291dFJlZGlyZWN0VXJpPzogc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jdXJyZW50JFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoY29uZmlnID0+IHRoaXMuZW5kU2Vzc2lvbkNsaWVudC5sb2dvdXRXaXRoUmVkaXJlY3QocG9zdExvZ291dFJlZGlyZWN0VXJpIHx8IGNvbmZpZy5iYXNlVXJsKSksXG4gICAgICAgICAgICAgICAgdGFwKHsgZXJyb3I6IGUgPT4gdGhpcy5ldmVudHMuZGlzcGF0Y2hFcnJvcihlKSB9KSxcbiAgICAgICAgICAgICk7XG4gICAgfVxufVxuIl19