feat: init and fork some code from angular-auth-oidc-client
Some checks are pending
Build, Lint & Test Lib / Built, Lint and Test Library (push) Waiting to run
Build, Lint & Test Lib / Angular latest (push) Blocked by required conditions
Build, Lint & Test Lib / Angular latest & Schematics Job (push) Blocked by required conditions
Build, Lint & Test Lib / Angular latest Standalone & Schematics Job (push) Blocked by required conditions
Build, Lint & Test Lib / Angular 16 & RxJs 6 (push) Blocked by required conditions
Build, Lint & Test Lib / Angular V16 (push) Blocked by required conditions
Docs / Build and Deploy Docs Job (push) Waiting to run
Docs / Close Pull Request Job (push) Waiting to run
Some checks are pending
Build, Lint & Test Lib / Built, Lint and Test Library (push) Waiting to run
Build, Lint & Test Lib / Angular latest (push) Blocked by required conditions
Build, Lint & Test Lib / Angular latest & Schematics Job (push) Blocked by required conditions
Build, Lint & Test Lib / Angular latest Standalone & Schematics Job (push) Blocked by required conditions
Build, Lint & Test Lib / Angular 16 & RxJs 6 (push) Blocked by required conditions
Build, Lint & Test Lib / Angular V16 (push) Blocked by required conditions
Docs / Build and Deploy Docs Job (push) Waiting to run
Docs / Close Pull Request Job (push) Waiting to run
This commit is contained in:
289
src/interceptor/auth.interceptor.spec.ts
Normal file
289
src/interceptor/auth.interceptor.spec.ts
Normal file
@@ -0,0 +1,289 @@
|
||||
import {
|
||||
HTTP_INTERCEPTORS,
|
||||
HttpClient,
|
||||
provideHttpClient,
|
||||
withInterceptors,
|
||||
withInterceptorsFromDi,
|
||||
} from '@angular/common/http';
|
||||
import {
|
||||
HttpTestingController,
|
||||
provideHttpClientTesting,
|
||||
} from '@angular/common/http/testing';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||
import { ConfigurationService } from '../config/config.service';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { AuthInterceptor, authInterceptor } from './auth.interceptor';
|
||||
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
||||
|
||||
describe(`AuthHttpInterceptor`, () => {
|
||||
let httpTestingController: HttpTestingController;
|
||||
let configurationService: ConfigurationService;
|
||||
let httpClient: HttpClient;
|
||||
let authStateService: AuthStateService;
|
||||
let closestMatchingRouteService: ClosestMatchingRouteService;
|
||||
|
||||
describe(`with Class Interceptor`, () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
providers: [
|
||||
ClosestMatchingRouteService,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: AuthInterceptor,
|
||||
multi: true,
|
||||
},
|
||||
mockProvider(AuthStateService),
|
||||
mockProvider(LoggerService),
|
||||
mockProvider(ConfigurationService),
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideHttpClientTesting(),
|
||||
],
|
||||
});
|
||||
|
||||
httpClient = TestBed.inject(HttpClient);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
configurationService = TestBed.inject(ConfigurationService);
|
||||
authStateService = TestBed.inject(AuthStateService);
|
||||
closestMatchingRouteService = TestBed.inject(ClosestMatchingRouteService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
httpTestingController.verify();
|
||||
});
|
||||
|
||||
runTests();
|
||||
});
|
||||
|
||||
describe(`with Functional Interceptor`, () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
ClosestMatchingRouteService,
|
||||
provideHttpClient(withInterceptors([authInterceptor()])),
|
||||
provideHttpClientTesting(),
|
||||
mockProvider(AuthStateService),
|
||||
mockProvider(LoggerService),
|
||||
mockProvider(ConfigurationService),
|
||||
],
|
||||
});
|
||||
|
||||
httpClient = TestBed.inject(HttpClient);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
configurationService = TestBed.inject(ConfigurationService);
|
||||
authStateService = TestBed.inject(AuthStateService);
|
||||
closestMatchingRouteService = TestBed.inject(ClosestMatchingRouteService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
httpTestingController.verify();
|
||||
});
|
||||
|
||||
runTests();
|
||||
});
|
||||
|
||||
function runTests(): void {
|
||||
it('should add an Authorization header when route matches and token is present', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
secureRoutes: [actionUrl],
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
|
||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(true);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when `secureRoutes` is not given', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when no routes configured', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
secureRoutes: [],
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when no routes configured', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
secureRoutes: [],
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when route is configured but no token is present', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
secureRoutes: [actionUrl],
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
spyOn(authStateService, 'getAccessToken').and.returnValue('');
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when no config is present', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(false);
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should not add an Authorization header when no configured route is matching the request', waitForAsync(() => {
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{
|
||||
secureRoutes: [actionUrl],
|
||||
configId: 'configId1',
|
||||
},
|
||||
]);
|
||||
spyOn(
|
||||
closestMatchingRouteService,
|
||||
'getConfigIdForClosestMatchingRoute'
|
||||
).and.returnValue({
|
||||
matchingRoute: null,
|
||||
matchingConfig: null,
|
||||
});
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(false);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
|
||||
it('should add an Authorization header when multiple routes are configured and token is present', waitForAsync(() => {
|
||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||
const actionUrl2 = `https://some-other-url.com/`;
|
||||
|
||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
||||
{ secureRoutes: [actionUrl, actionUrl2], configId: 'configId1' },
|
||||
]);
|
||||
|
||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
||||
|
||||
httpClient.get(actionUrl).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
httpClient.get(actionUrl2).subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
const httpRequest = httpTestingController.expectOne(actionUrl);
|
||||
|
||||
expect(httpRequest.request.headers.has('Authorization')).toEqual(true);
|
||||
|
||||
const httpRequest2 = httpTestingController.expectOne(actionUrl2);
|
||||
|
||||
expect(httpRequest2.request.headers.has('Authorization')).toEqual(true);
|
||||
|
||||
httpRequest.flush('something');
|
||||
httpRequest2.flush('something');
|
||||
httpTestingController.verify();
|
||||
}));
|
||||
}
|
||||
});
|
||||
121
src/interceptor/auth.interceptor.ts
Normal file
121
src/interceptor/auth.interceptor.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
HttpEvent,
|
||||
HttpHandler,
|
||||
HttpHandlerFn,
|
||||
HttpInterceptor,
|
||||
HttpInterceptorFn,
|
||||
HttpRequest,
|
||||
} from '@ngify/http';
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||
import { ConfigurationService } from '../config/config.service';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { flattenArray } from '../utils/collections/collections.helper';
|
||||
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthInterceptor implements HttpInterceptor {
|
||||
private readonly authStateService = inject(AuthStateService);
|
||||
|
||||
private readonly configurationService = inject(ConfigurationService);
|
||||
|
||||
private readonly loggerService = inject(LoggerService);
|
||||
|
||||
private readonly closestMatchingRouteService = inject(
|
||||
ClosestMatchingRouteService
|
||||
);
|
||||
|
||||
intercept(
|
||||
req: HttpRequest<any>,
|
||||
next: HttpHandler
|
||||
): Observable<HttpEvent<any>> {
|
||||
return interceptRequest(req, next.handle, {
|
||||
configurationService: this.configurationService,
|
||||
authStateService: this.authStateService,
|
||||
closestMatchingRouteService: this.closestMatchingRouteService,
|
||||
loggerService: this.loggerService,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function authInterceptor(): HttpInterceptorFn {
|
||||
return (req, next) => {
|
||||
return interceptRequest(req, next, {
|
||||
configurationService: inject(ConfigurationService),
|
||||
authStateService: inject(AuthStateService),
|
||||
closestMatchingRouteService: inject(ClosestMatchingRouteService),
|
||||
loggerService: inject(LoggerService),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function interceptRequest(
|
||||
req: HttpRequest<any>,
|
||||
next: HttpHandlerFn,
|
||||
deps: {
|
||||
authStateService: AuthStateService;
|
||||
configurationService: ConfigurationService;
|
||||
loggerService: LoggerService;
|
||||
closestMatchingRouteService: ClosestMatchingRouteService;
|
||||
}
|
||||
): Observable<HttpEvent<unknown>> {
|
||||
if (!deps.configurationService.hasAtLeastOneConfig()) {
|
||||
return next(req);
|
||||
}
|
||||
|
||||
const allConfigurations = deps.configurationService.getAllConfigurations();
|
||||
const allRoutesConfigured = allConfigurations.map(
|
||||
(x) => x.secureRoutes || []
|
||||
);
|
||||
const allRoutesConfiguredFlat = flattenArray(allRoutesConfigured);
|
||||
|
||||
if (allRoutesConfiguredFlat.length === 0) {
|
||||
deps.loggerService.logDebug(
|
||||
allConfigurations[0],
|
||||
`No routes to check configured`
|
||||
);
|
||||
|
||||
return next(req);
|
||||
}
|
||||
|
||||
const { matchingConfig, matchingRoute } =
|
||||
deps.closestMatchingRouteService.getConfigIdForClosestMatchingRoute(
|
||||
req.url,
|
||||
allConfigurations
|
||||
);
|
||||
|
||||
if (!matchingConfig) {
|
||||
deps.loggerService.logDebug(
|
||||
allConfigurations[0],
|
||||
`Did not find any configured route for route ${req.url}`
|
||||
);
|
||||
|
||||
return next(req);
|
||||
}
|
||||
|
||||
deps.loggerService.logDebug(
|
||||
matchingConfig,
|
||||
`'${req.url}' matches configured route '${matchingRoute}'`
|
||||
);
|
||||
const token = deps.authStateService.getAccessToken(matchingConfig);
|
||||
|
||||
if (!token) {
|
||||
deps.loggerService.logDebug(
|
||||
matchingConfig,
|
||||
`Wanted to add token to ${req.url} but found no token: '${token}'`
|
||||
);
|
||||
|
||||
return next(req);
|
||||
}
|
||||
|
||||
deps.loggerService.logDebug(
|
||||
matchingConfig,
|
||||
`'${req.url}' matches configured route '${matchingRoute}', adding token`
|
||||
);
|
||||
req = req.clone({
|
||||
headers: req.headers.set('Authorization', 'Bearer ' + token),
|
||||
});
|
||||
|
||||
return next(req);
|
||||
}
|
||||
180
src/interceptor/closest-matching-route.service.spec.ts
Normal file
180
src/interceptor/closest-matching-route.service.spec.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
||||
|
||||
describe('ClosestMatchingRouteService', () => {
|
||||
let service: ClosestMatchingRouteService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [ClosestMatchingRouteService, mockProvider(LoggerService)],
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(ClosestMatchingRouteService);
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('getConfigForClosestMatchingRoute', () => {
|
||||
it('gets best match for configured routes', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://my-secure-url.com/',
|
||||
'https://my-second-secure-url.com/',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://my-third-secure-url.com/',
|
||||
'https://my-fourth-second-secure-url.com/',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'https://my-secure-url.com/',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toEqual(allConfigs[0]);
|
||||
});
|
||||
|
||||
it('gets best match for configured routes - same route prefix', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://my-secure-url.com/',
|
||||
'https://my-secure-url.com/test',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://my-third-secure-url.com/',
|
||||
'https://my-fourth-second-secure-url.com/',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'https://my-secure-url.com/',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toEqual(allConfigs[0]);
|
||||
});
|
||||
|
||||
it('gets best match for configured routes - main route', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://first-route.com/',
|
||||
'https://second-route.com/test',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://third-route.com/test2',
|
||||
'https://fourth-route.com/test3',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'https://first-route.com/',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toEqual(allConfigs[0]);
|
||||
});
|
||||
|
||||
it('gets best match for configured routes - request route with params', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://first-route.com/',
|
||||
'https://second-route.com/test',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://third-route.com/test2',
|
||||
'https://fourth-route.com/test3',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'https://first-route.com/anyparam',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toEqual(allConfigs[0]);
|
||||
});
|
||||
|
||||
it('gets best match for configured routes - configured route with params', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://first-route.com/',
|
||||
'https://second-route.com/test',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://third-route.com/test2',
|
||||
'https://fourth-route.com/test3',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'https://third-route.com/',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toBeNull();
|
||||
});
|
||||
|
||||
it('gets best match for configured routes - no config Id', () => {
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
secureRoutes: [
|
||||
'https://my-secure-url.com/',
|
||||
'https://my-secure-url.com/test',
|
||||
],
|
||||
},
|
||||
{
|
||||
configId: 'configId2',
|
||||
secureRoutes: [
|
||||
'https://my-secure-url.com/test2',
|
||||
'https://my-secure-url.com/test2/test',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { matchingConfig } = service.getConfigIdForClosestMatchingRoute(
|
||||
'blabla',
|
||||
allConfigs
|
||||
);
|
||||
|
||||
expect(matchingConfig).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
33
src/interceptor/closest-matching-route.service.ts
Normal file
33
src/interceptor/closest-matching-route.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from 'injection-js';
|
||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
|
||||
@Injectable()
|
||||
export class ClosestMatchingRouteService {
|
||||
getConfigIdForClosestMatchingRoute(
|
||||
route: string,
|
||||
configurations: OpenIdConfiguration[]
|
||||
): ClosestMatchingRouteResult {
|
||||
for (const config of configurations) {
|
||||
const { secureRoutes } = config;
|
||||
|
||||
for (const configuredRoute of secureRoutes ?? []) {
|
||||
if (route.startsWith(configuredRoute)) {
|
||||
return {
|
||||
matchingRoute: configuredRoute,
|
||||
matchingConfig: config,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
matchingRoute: null,
|
||||
matchingConfig: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface ClosestMatchingRouteResult {
|
||||
matchingRoute: string | null;
|
||||
matchingConfig: OpenIdConfiguration | null;
|
||||
}
|
||||
Reference in New Issue
Block a user