@okta/okta-angular
Version:
Angular support for Okta
122 lines • 17 kB
JavaScript
/*
* Copyright (c) 2017-Present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/
import { Injectable, Injector, Inject } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { filter } from 'rxjs/operators';
import { OktaAuth } from '@okta/okta-auth-js';
import { OktaAuthConfigService } from './services/auth-config.serice';
import { OKTA_AUTH } from './models/okta.config';
import * as i0 from "@angular/core";
import * as i1 from "./services/auth-config.serice";
import * as i2 from "@okta/okta-auth-js";
export class OktaAuthGuard {
oktaAuth;
injector;
configService;
state;
routeData;
onAuthRequired;
constructor(oktaAuth, injector, configService) {
this.oktaAuth = oktaAuth;
this.injector = injector;
this.configService = configService;
const config = this.configService.getConfig();
if (!config) {
throw new Error('Okta config is not provided');
}
this.onAuthRequired = config.onAuthRequired;
// Unsubscribe updateAuthStateListener when route change
const router = injector.get(Router);
router.events.pipe(filter((e) => e instanceof NavigationStart && this.state && this.state.url !== e.url)).subscribe(() => {
this.oktaAuth.authStateManager.unsubscribe(this.updateAuthStateListener);
});
}
async canLoad(route) {
this.onAuthRequired = route.data?.onAuthRequired || this.onAuthRequired;
const isAuthenticated = await this.isAuthenticated(route.data);
if (isAuthenticated) {
return true;
}
const router = this.injector.get(Router);
const nav = router.getCurrentNavigation();
const originalUri = nav ? nav.extractedUrl.toString() : undefined;
await this.handleLogin(originalUri, route.data);
return false;
}
/**
* Gateway for protected route. Returns true if there is a valid idToken,
* otherwise it will cache the route and start the login flow.
* @param route
* @param state
*/
async canActivate(route, state) {
// Track states for current route
this.state = state;
this.routeData = route.data;
this.onAuthRequired = route.data && route.data.onAuthRequired || this.onAuthRequired;
// Protect the route after accessing
this.oktaAuth.authStateManager.subscribe(this.updateAuthStateListener);
const isAuthenticated = await this.isAuthenticated(route.data);
if (isAuthenticated) {
return true;
}
await this.handleLogin(state.url, route.data);
return false;
}
async canActivateChild(route, state) {
return this.canActivate(route, state);
}
async isAuthenticated(routeData, authState) {
const isAuthenticated = authState ? authState?.isAuthenticated : await this.oktaAuth.isAuthenticated();
let res = isAuthenticated;
if (routeData?.okta?.acrValues) {
if (!authState) {
authState = this.oktaAuth.authStateManager.getAuthState();
}
res = authState?.idToken?.claims.acr === routeData?.okta?.acrValues;
}
return res;
}
async handleLogin(originalUri, routeData) {
// Store the current path
if (originalUri) {
this.oktaAuth.setOriginalUri(originalUri);
}
const options = {};
if (routeData?.okta?.acrValues) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore Supports auth-js >= 7.1.0
options.acrValues = routeData.okta.acrValues;
}
if (this.onAuthRequired) {
this.onAuthRequired(this.oktaAuth, this.injector, options);
}
else {
this.oktaAuth.signInWithRedirect(options);
}
}
updateAuthStateListener = async (authState) => {
const isAuthenticated = await this.isAuthenticated(this.routeData, authState);
if (!isAuthenticated) {
this.handleLogin(this.state.url, this.routeData);
}
};
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OktaAuthGuard, deps: [{ token: OKTA_AUTH }, { token: i0.Injector }, { token: i1.OktaAuthConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OktaAuthGuard });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OktaAuthGuard, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i2.OktaAuth, decorators: [{
type: Inject,
args: [OKTA_AUTH]
}] }, { type: i0.Injector }, { type: i1.OktaAuthConfigService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2t0YS5ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9zcmMvb2t0YS9va3RhLmd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUtMLE1BQU0sRUFDTixlQUFlLEVBS2hCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXhDLE9BQU8sRUFBRSxRQUFRLEVBQTBCLE1BQU0sb0JBQW9CLENBQUM7QUFDdEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdEUsT0FBTyxFQUF3QixTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7OztBQUd2RSxNQUFNLE9BQU8sYUFBYTtJQU1LO0lBQ25CO0lBQ0E7SUFQRixLQUFLLENBQXNCO0lBQzNCLFNBQVMsQ0FBTztJQUNoQixjQUFjLENBQXdCO0lBRTlDLFlBQzZCLFFBQWtCLEVBQ3JDLFFBQWtCLEVBQ2xCLGFBQW9DO1FBRmpCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDckMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixrQkFBYSxHQUFiLGFBQWEsQ0FBdUI7UUFFNUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM5QyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1NBQ2hEO1FBQ0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO1FBRTVDLHdEQUF3RDtRQUN4RCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLE1BQU0s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RkFBYixhQUFhO2tCQUR6QixVQUFVOzswQkFPTixNQUFNOzJCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LVByZXNlbnQsIE9rdGEsIEluYy4gYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhlIE9rdGEgc29mdHdhcmUgYWNjb21wYW5pZWQgYnkgdGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgcHVyc3VhbnQgdG8gdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZS5cIilcbiAqXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wLlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUXG4gKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBDYW5BY3RpdmF0ZSxcbiAgQ2FuQWN0aXZhdGVDaGlsZCxcbiAgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcbiAgUm91dGVyU3RhdGVTbmFwc2hvdCxcbiAgUm91dGVyLFxuICBOYXZpZ2F0aW9uU3RhcnQsIFxuICBFdmVudCxcbiAgQ2FuTG9hZCxcbiAgUm91dGUsXG4gIERhdGFcbn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgT2t0YUF1dGgsIEF1dGhTdGF0ZSwgVG9rZW5QYXJhbXMgfSBmcm9tICdAb2t0YS9va3RhLWF1dGgtanMnO1xuaW1wb3J0IHsgT2t0YUF1dGhDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9hdXRoLWNvbmZpZy5zZXJpY2UnO1xuaW1wb3J0IHsgQXV0aFJlcXVpcmVkRnVuY3Rpb24sIE9LVEFfQVVUSCB9IGZyb20gJy4vbW9kZWxzL29rdGEuY29uZmlnJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE9rdGFBdXRoR3VhcmQgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCwgQ2FuTG9hZCB7XG4gIHByaXZhdGUgc3RhdGU6IFJvdXRlclN0YXRlU25hcHNob3Q7XG4gIHByaXZhdGUgcm91dGVEYXRhOiBEYXRhO1xuICBwcml2YXRlIG9uQXV0aFJlcXVpcmVkPzogQXV0aFJlcXVpcmVkRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChPS1RBX0FVVEgpIHByaXZhdGUgb2t0YUF1dGg6IE9rdGFBdXRoLCBcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIGNvbmZpZ1NlcnZpY2U6IE9rdGFBdXRoQ29uZmlnU2VydmljZVxuICApIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZ1NlcnZpY2UuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT2t0YSBjb25maWcgaXMgbm90IHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIHRoaXMub25BdXRoUmVxdWlyZWQgPSBjb25maWcub25BdXRoUmVxdWlyZWQ7XG5cbiAgICAvLyBVbnN1YnNjcmliZSB1cGRhdGVBdXRoU3RhdGVMaXN0ZW5lciB3aGVuIHJvdXRlIGNoYW5nZVxuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdG9yLmdldChSb3V0ZXIpO1xuICAgIHJvdXRlci5ldmVudHMucGlwZShcbiAgICAgIGZpbHRlcigoZTogRXZlbnQpID0+IGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQgJiYgdGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLnVybCAhPT0gZS51cmwpXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5va3RhQXV0aC5hdXRoU3RhdGVNYW5hZ2VyLnVuc3Vic2NyaWJlKHRoaXMudXBkYXRlQXV0aFN0YXRlTGlzdGVuZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY2FuTG9hZChyb3V0ZTogUm91dGUpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0aGlzLm9uQXV0aFJlcXVpcmVkID0gcm91dGUuZGF0YT8ub25BdXRoUmVxdWlyZWQgfHwgdGhpcy5vbkF1dGhSZXF1aXJlZDtcblxuICAgIGNvbnN0IGlzQXV0aGVudGljYXRlZCA9IGF3YWl0IHRoaXMuaXNBdXRoZW50aWNhdGVkKHJvdXRlLmRhdGEpO1xuICAgIGlmIChpc0F1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHJvdXRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFJvdXRlcik7XG4gICAgY29uc3QgbmF2ID0gcm91dGVyLmdldEN1cnJlbnROYXZpZ2F0aW9uKCk7XG4gICAgY29uc3Qgb3JpZ2luYWxVcmkgPSBuYXYgPyBuYXYuZXh0cmFjdGVkVXJsLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG4gICAgYXdhaXQgdGhpcy5oYW5kbGVMb2dpbihvcmlnaW5hbFVyaSwgcm91dGUuZGF0YSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogR2F0ZXdheSBmb3IgcHJvdGVjdGVkIHJvdXRlLiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgYSB2YWxpZCBpZFRva2VuLFxuICAgKiBvdGhlcndpc2UgaXQgd2lsbCBjYWNoZSB0aGUgcm91dGUgYW5kIHN0YXJ0IHRoZSBsb2dpbiBmbG93LlxuICAgKiBAcGFyYW0gcm91dGVcbiAgICogQHBhcmFtIHN0YXRlXG4gICAqL1xuICBhc3luYyBjYW5BY3RpdmF0ZShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgc3RhdGU6IFJvdXRlclN0YXRlU25hcHNob3QpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBUcmFjayBzdGF0ZXMgZm9yIGN1cnJlbnQgcm91dGVcbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgdGhpcy5yb3V0ZURhdGEgPSByb3V0ZS5kYXRhO1xuICAgIHRoaXMub25BdXRoUmVxdWlyZWQgPSByb3V0ZS5kYXRhICYmIHJvdXRlLmRhdGEub25BdXRoUmVxdWlyZWQgfHwgdGhpcy5vbkF1dGhSZXF1aXJlZDtcblxuICAgIC8vIFByb3RlY3QgdGhlIHJvdXRlIGFmdGVyIGFjY2Vzc2luZ1xuICAgIHRoaXMub2t0YUF1dGguYXV0aFN0YXRlTWFuYWdlci5zdWJzY3JpYmUodGhpcy51cGRhdGVBdXRoU3RhdGVMaXN0ZW5lcik7XG4gICAgY29uc3QgaXNBdXRoZW50aWNhdGVkID0gYXdhaXQgdGhpcy5pc0F1dGhlbnRpY2F0ZWQocm91dGUuZGF0YSk7XG4gICAgaWYgKGlzQXV0aGVudGljYXRlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5oYW5kbGVMb2dpbihzdGF0ZS51cmwsIHJvdXRlLmRhdGEpO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgY2FuQWN0aXZhdGVDaGlsZChcbiAgICByb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcbiAgICBzdGF0ZTogUm91dGVyU3RhdGVTbmFwc2hvdFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5jYW5BY3RpdmF0ZShyb3V0ZSwgc3RhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpc0F1dGhlbnRpY2F0ZWQocm91dGVEYXRhPzogRGF0YSwgYXV0aFN0YXRlPzogQXV0aFN0YXRlIHwgbnVsbCkge1xuICAgIGNvbnN0IGlzQXV0aGVudGljYXRlZCA9IGF1dGhTdGF0ZSA/IGF1dGhTdGF0ZT8uaXNBdXRoZW50aWNhdGVkIDogYXdhaXQgdGhpcy5va3RhQXV0aC5pc0F1dGhlbnRpY2F0ZWQoKTtcbiAgICBsZXQgcmVzID0gaXNBdXRoZW50aWNhdGVkO1xuICAgIGlmIChyb3V0ZURhdGE/Lm9rdGE/LmFjclZhbHVlcykge1xuICAgICAgaWYgKCFhdXRoU3RhdGUpIHtcbiAgICAgICAgYXV0aFN0YXRlID0gdGhpcy5va3RhQXV0aC5hdXRoU3RhdGVNYW5hZ2VyLmdldEF1dGhTdGF0ZSgpO1xuICAgICAgfVxuICAgICAgcmVzID0gYXV0aFN0YXRlPy5pZFRva2VuPy5jbGFpbXMuYWNyID09PSByb3V0ZURhdGE/Lm9rdGE/LmFjclZhbHVlcztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlTG9naW4ob3JpZ2luYWxVcmk/OiBzdHJpbmcsIHJvdXRlRGF0YT86IERhdGEpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBTdG9yZSB0aGUgY3VycmVudCBwYXRoXG4gICAgaWYgKG9yaWdpbmFsVXJpKSB7XG4gICAgICB0aGlzLm9rdGFBdXRoLnNldE9yaWdpbmFsVXJpKG9yaWdpbmFsVXJpKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zOiBUb2tlblBhcmFtcyA9IHt9O1xuICAgIGlmIChyb3V0ZURhdGE/Lm9rdGE/LmFjclZhbHVlcykge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuICAgICAgLy8gQHRzLWlnbm9yZSBTdXBwb3J0cyBhdXRoLWpzID49IDcuMS4wXG4gICAgICBvcHRpb25zLmFjclZhbHVlcyA9IHJvdXRlRGF0YS5va3RhLmFjclZhbHVlcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vbkF1dGhSZXF1aXJlZCkge1xuICAgICAgdGhpcy5vbkF1dGhSZXF1aXJlZCh0aGlzLm9rdGFBdXRoLCB0aGlzLmluamVjdG9yLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5va3RhQXV0aC5zaWduSW5XaXRoUmVkaXJlY3Qob3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVBdXRoU3RhdGVMaXN0ZW5lciA9IGFzeW5jIChhdXRoU3RhdGU6IEF1dGhTdGF0ZSkgPT4ge1xuICAgIGNvbnN0IGlzQXV0aGVudGljYXRlZCA9IGF3YWl0IHRoaXMuaXNBdXRoZW50aWNhdGVkKHRoaXMucm91dGVEYXRhLCBhdXRoU3RhdGUpO1xuICAgIGlmICghaXNBdXRoZW50aWNhdGVkKSB7XG4gICAgICB0aGlzLmhhbmRsZUxvZ2luKHRoaXMuc3RhdGUudXJsLCB0aGlzLnJvdXRlRGF0YSk7XG4gICAgfVxuICB9O1xuXG59XG4iXX0=