mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Move OIDC library behaviour to separate path
This commit is contained in:
parent
11192ed4df
commit
520e4fe42f
@ -15,6 +15,9 @@ The following changes are relevant for v2 custom configs that replaced certain f
|
|||||||
- `/util/representation-conversion/default.json`
|
- `/util/representation-conversion/default.json`
|
||||||
- The IDP settings have changed to support the latest Solid-OIDC draft.
|
- The IDP settings have changed to support the latest Solid-OIDC draft.
|
||||||
- `/identity/handler/provider-factory/identity.json`
|
- `/identity/handler/provider-factory/identity.json`
|
||||||
|
- Requests targeting the OIDC library now use a separate handler.
|
||||||
|
- `/http/handler/default.json`
|
||||||
|
- `/identity/handler/default.json`
|
||||||
|
|
||||||
### Interface changes
|
### Interface changes
|
||||||
These changes are relevant if you wrote custom modules for the server that depend on existing interfaces.
|
These changes are relevant if you wrote custom modules for the server that depend on existing interfaces.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^2.0.0/components/context.jsonld",
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^2.0.0/components/context.jsonld",
|
||||||
"import": [
|
"import": [
|
||||||
"files-scs:config/app/init/initializers/root.json"
|
"files-scs:config/http/handler/handlers/oidc.json"
|
||||||
],
|
],
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
@ -15,6 +15,7 @@
|
|||||||
"handlers": [
|
"handlers": [
|
||||||
{ "@id": "urn:solid-server:default:StaticAssetHandler" },
|
{ "@id": "urn:solid-server:default:StaticAssetHandler" },
|
||||||
{ "@id": "urn:solid-server:default:SetupHandler" },
|
{ "@id": "urn:solid-server:default:SetupHandler" },
|
||||||
|
{ "@id": "urn:solid-server:default:OidcHandler" },
|
||||||
{ "@id": "urn:solid-server:default:AuthResourceHttpHandler" },
|
{ "@id": "urn:solid-server:default:AuthResourceHttpHandler" },
|
||||||
{ "@id": "urn:solid-server:default:IdentityProviderHandler" },
|
{ "@id": "urn:solid-server:default:IdentityProviderHandler" },
|
||||||
{ "@id": "urn:solid-server:default:LdpHandler" }
|
{ "@id": "urn:solid-server:default:LdpHandler" }
|
||||||
|
18
config/http/handler/handlers/oidc.json
Normal file
18
config/http/handler/handlers/oidc.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^2.0.0/components/context.jsonld",
|
||||||
|
"@graph": [
|
||||||
|
{
|
||||||
|
"comment": "Routes all OIDC related requests to the OIDC library.",
|
||||||
|
"@id": "urn:solid-server:default:OidcHandler",
|
||||||
|
"@type": "RouterHandler",
|
||||||
|
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
|
"args_targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
|
||||||
|
"args_allowedMethods": [ "*" ],
|
||||||
|
"args_allowedPathNames": [ "^/.oidc/.*", "^/\\.well-known/openid-configuration" ],
|
||||||
|
"args_handler": {
|
||||||
|
"@type": "OidcHttpHandler",
|
||||||
|
"providerFactory": { "@id": "urn:solid-server:default:IdentityProviderFactory" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
"args_targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
|
"args_targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
|
||||||
"args_allowedMethods": [ "*" ],
|
"args_allowedMethods": [ "*" ],
|
||||||
"args_allowedPathNames": [ "^/idp/.*", "^/\\.well-known/openid-configuration" ],
|
"args_allowedPathNames": [ "^/idp/.*" ],
|
||||||
"args_handler": { "@id": "urn:solid-server:default:IdentityProviderParsingHandler" }
|
"args_handler": { "@id": "urn:solid-server:default:IdentityProviderParsingHandler" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"@type": "IdentityProviderFactory",
|
"@type": "IdentityProviderFactory",
|
||||||
"args_adapterFactory": { "@id": "urn:solid-server:default:IdpAdapterFactory" },
|
"args_adapterFactory": { "@id": "urn:solid-server:default:IdpAdapterFactory" },
|
||||||
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
|
"args_oidcPath": "/.oidc",
|
||||||
"args_idpPath": "/idp",
|
"args_idpPath": "/idp",
|
||||||
"args_storage": { "@id": "urn:solid-server:default:IdpKeyStorage" },
|
"args_storage": { "@id": "urn:solid-server:default:IdpKeyStorage" },
|
||||||
"args_errorHandler": { "@id": "urn:solid-server:default:ErrorHandler" },
|
"args_errorHandler": { "@id": "urn:solid-server:default:ErrorHandler" },
|
||||||
|
@ -10,6 +10,7 @@ import { OperationHttpHandler } from '../server/OperationHttpHandler';
|
|||||||
import type { RepresentationConverter } from '../storage/conversion/RepresentationConverter';
|
import type { RepresentationConverter } from '../storage/conversion/RepresentationConverter';
|
||||||
import { APPLICATION_JSON } from '../util/ContentTypes';
|
import { APPLICATION_JSON } from '../util/ContentTypes';
|
||||||
import { BadRequestHttpError } from '../util/errors/BadRequestHttpError';
|
import { BadRequestHttpError } from '../util/errors/BadRequestHttpError';
|
||||||
|
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||||
import { joinUrl, trimTrailingSlashes } from '../util/PathUtil';
|
import { joinUrl, trimTrailingSlashes } from '../util/PathUtil';
|
||||||
import { addTemplateMetadata, cloneRepresentation } from '../util/ResourceUtil';
|
import { addTemplateMetadata, cloneRepresentation } from '../util/ResourceUtil';
|
||||||
import { readJsonStream } from '../util/StreamUtil';
|
import { readJsonStream } from '../util/StreamUtil';
|
||||||
@ -77,8 +78,6 @@ export class IdentityProviderHttpHandler extends OperationHttpHandler {
|
|||||||
private readonly controls: Record<string, string>;
|
private readonly controls: Record<string, string>;
|
||||||
|
|
||||||
public constructor(args: IdentityProviderHttpHandlerArgs) {
|
public constructor(args: IdentityProviderHttpHandlerArgs) {
|
||||||
// It is important that the RequestParser does not read out the Request body stream.
|
|
||||||
// Otherwise we can't pass it anymore to the OIDC library when needed.
|
|
||||||
super();
|
super();
|
||||||
// Trimming trailing slashes so the relative URL starts with a slash after slicing this off
|
// Trimming trailing slashes so the relative URL starts with a slash after slicing this off
|
||||||
this.baseUrl = trimTrailingSlashes(joinUrl(args.baseUrl, args.idpPath));
|
this.baseUrl = trimTrailingSlashes(joinUrl(args.baseUrl, args.idpPath));
|
||||||
@ -97,29 +96,19 @@ export class IdentityProviderHttpHandler extends OperationHttpHandler {
|
|||||||
/**
|
/**
|
||||||
* Finds the matching route and resolves the operation.
|
* Finds the matching route and resolves the operation.
|
||||||
*/
|
*/
|
||||||
public async handle({ operation, request, response }: OperationHttpHandlerInput):
|
public async handle({ operation, request, response }: OperationHttpHandlerInput): Promise<ResponseDescription> {
|
||||||
Promise<ResponseDescription | undefined> {
|
|
||||||
// This being defined means we're in an OIDC session
|
// This being defined means we're in an OIDC session
|
||||||
let oidcInteraction: Interaction | undefined;
|
let oidcInteraction: Interaction | undefined;
|
||||||
try {
|
try {
|
||||||
const provider = await this.providerFactory.getProvider();
|
const provider = await this.providerFactory.getProvider();
|
||||||
// This being defined means we're in an OIDC session
|
|
||||||
oidcInteraction = await provider.interactionDetails(request, response);
|
oidcInteraction = await provider.interactionDetails(request, response);
|
||||||
} catch {
|
} catch {
|
||||||
// Just a regular request
|
// Just a regular request
|
||||||
}
|
}
|
||||||
|
|
||||||
// If our own interaction handler does not support the input, it is either invalid or a request for the OIDC library
|
|
||||||
const route = await this.findRoute(operation, oidcInteraction);
|
const route = await this.findRoute(operation, oidcInteraction);
|
||||||
|
|
||||||
if (!route) {
|
if (!route) {
|
||||||
const provider = await this.providerFactory.getProvider();
|
throw new NotFoundHttpError();
|
||||||
this.logger.debug(`Sending request to oidc-provider: ${request.url}`);
|
|
||||||
// Even though the typings do not indicate this, this is a Promise that needs to be awaited.
|
|
||||||
// Otherwise the `BaseHttpServerFactory` will write a 404 before the OIDC library could handle the response.
|
|
||||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
||||||
await provider.callback(request, response);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cloning input data so it can be sent back in case of errors
|
// Cloning input data so it can be sent back in case of errors
|
||||||
@ -149,7 +138,7 @@ export class IdentityProviderHttpHandler extends OperationHttpHandler {
|
|||||||
*/
|
*/
|
||||||
private async findRoute(operation: Operation, oidcInteraction?: Interaction): Promise<InteractionRoute | undefined> {
|
private async findRoute(operation: Operation, oidcInteraction?: Interaction): Promise<InteractionRoute | undefined> {
|
||||||
if (!operation.target.path.startsWith(this.baseUrl)) {
|
if (!operation.target.path.startsWith(this.baseUrl)) {
|
||||||
// This is either an invalid request or a call to the .well-known configuration
|
// This is an invalid request
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const pathName = operation.target.path.slice(this.baseUrl.length);
|
const pathName = operation.target.path.slice(this.baseUrl.length);
|
||||||
|
27
src/identity/OidcHttpHandler.ts
Normal file
27
src/identity/OidcHttpHandler.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { getLoggerFor } from '../logging/LogUtil';
|
||||||
|
import type { HttpHandlerInput } from '../server/HttpHandler';
|
||||||
|
import { HttpHandler } from '../server/HttpHandler';
|
||||||
|
import type { ProviderFactory } from './configuration/ProviderFactory';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP handler that redirects all requests to the OIDC library.
|
||||||
|
*/
|
||||||
|
export class OidcHttpHandler extends HttpHandler {
|
||||||
|
protected readonly logger = getLoggerFor(this);
|
||||||
|
|
||||||
|
private readonly providerFactory: ProviderFactory;
|
||||||
|
|
||||||
|
public constructor(providerFactory: ProviderFactory) {
|
||||||
|
super();
|
||||||
|
this.providerFactory = providerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async handle({ request, response }: HttpHandlerInput): Promise<void> {
|
||||||
|
const provider = await this.providerFactory.getProvider();
|
||||||
|
this.logger.debug(`Sending request to oidc-provider: ${request.url}`);
|
||||||
|
// Even though the typings do not indicate this, this is a Promise that needs to be awaited.
|
||||||
|
// Otherwise the `BaseHttpServerFactory` will write a 404 before the OIDC library could handle the response.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||||
|
await provider.callback(request, response);
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,11 @@ export interface IdentityProviderFactoryArgs {
|
|||||||
*/
|
*/
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
/**
|
/**
|
||||||
* Path of the IDP component in the server.
|
* Path for all requests targeting the OIDC library.
|
||||||
|
*/
|
||||||
|
oidcPath: string;
|
||||||
|
/**
|
||||||
|
* The entry point for the custom IDP handlers of the server.
|
||||||
* Should start with a slash.
|
* Should start with a slash.
|
||||||
*/
|
*/
|
||||||
idpPath: string;
|
idpPath: string;
|
||||||
@ -62,6 +66,7 @@ export class IdentityProviderFactory implements ProviderFactory {
|
|||||||
private readonly config: Configuration;
|
private readonly config: Configuration;
|
||||||
private readonly adapterFactory!: AdapterFactory;
|
private readonly adapterFactory!: AdapterFactory;
|
||||||
private readonly baseUrl!: string;
|
private readonly baseUrl!: string;
|
||||||
|
private readonly oidcPath!: string;
|
||||||
private readonly idpPath!: string;
|
private readonly idpPath!: string;
|
||||||
private readonly storage!: KeyValueStorage<string, unknown>;
|
private readonly storage!: KeyValueStorage<string, unknown>;
|
||||||
private readonly errorHandler!: ErrorHandler;
|
private readonly errorHandler!: ErrorHandler;
|
||||||
@ -107,6 +112,7 @@ export class IdentityProviderFactory implements ProviderFactory {
|
|||||||
// Allow provider to interpret reverse proxy headers
|
// Allow provider to interpret reverse proxy headers
|
||||||
const provider = new Provider(this.baseUrl, config);
|
const provider = new Provider(this.baseUrl, config);
|
||||||
provider.proxy = true;
|
provider.proxy = true;
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,11 +216,11 @@ export class IdentityProviderFactory implements ProviderFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the route string as required by the `oidc-provider` library.
|
* Creates the route string as required by the `oidc-provider` library.
|
||||||
* In case base URL is `http://test.com/foo/`, `idpPath` is `/idp` and `relative` is `device/auth`,
|
* In case base URL is `http://test.com/foo/`, `oidcPath` is `/idp` and `relative` is `device/auth`,
|
||||||
* this would result in `/foo/idp/device/auth`.
|
* this would result in `/foo/idp/device/auth`.
|
||||||
*/
|
*/
|
||||||
private createRoute(relative: string): string {
|
private createRoute(relative: string): string {
|
||||||
return new URL(joinUrl(this.baseUrl, this.idpPath, relative)).pathname;
|
return new URL(joinUrl(this.baseUrl, this.oidcPath, relative)).pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,6 +165,7 @@ export * from './identity/storage/WebIdAdapterFactory';
|
|||||||
|
|
||||||
// Identity
|
// Identity
|
||||||
export * from './identity/IdentityProviderHttpHandler';
|
export * from './identity/IdentityProviderHttpHandler';
|
||||||
|
export * from './identity/OidcHttpHandler';
|
||||||
|
|
||||||
// Init/Final
|
// Init/Final
|
||||||
export * from './init/final/Finalizable';
|
export * from './init/final/Finalizable';
|
||||||
|
@ -58,7 +58,7 @@ export class AuthorizingHttpHandler extends OperationHttpHandler {
|
|||||||
this.operationHandler = args.operationHandler;
|
this.operationHandler = args.operationHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle(input: OperationHttpHandlerInput): Promise<ResponseDescription | undefined> {
|
public async handle(input: OperationHttpHandlerInput): Promise<ResponseDescription> {
|
||||||
const { request, operation } = input;
|
const { request, operation } = input;
|
||||||
const credentials: CredentialSet = await this.credentialsExtractor.handleSafe(request);
|
const credentials: CredentialSet = await this.credentialsExtractor.handleSafe(request);
|
||||||
this.logger.verbose(`Extracted credentials: ${JSON.stringify(credentials)}`);
|
this.logger.verbose(`Extracted credentials: ${JSON.stringify(credentials)}`);
|
||||||
|
@ -9,8 +9,6 @@ export interface OperationHttpHandlerInput extends HttpHandlerInput {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An HTTP handler that makes use of an already parsed Operation.
|
* An HTTP handler that makes use of an already parsed Operation.
|
||||||
* Can either return a ResponseDescription to be resolved by the calling class,
|
|
||||||
* or undefined if this class handles the response itself.
|
|
||||||
*/
|
*/
|
||||||
export abstract class OperationHttpHandler
|
export abstract class OperationHttpHandler
|
||||||
extends AsyncHandler<OperationHttpHandlerInput, ResponseDescription | undefined> {}
|
extends AsyncHandler<OperationHttpHandlerInput, ResponseDescription> {}
|
||||||
|
@ -378,7 +378,7 @@ describe('A Solid server with IDP', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return correct error output.', async(): Promise<void> => {
|
it('should return correct error output.', async(): Promise<void> => {
|
||||||
const res = await fetch(`${baseUrl}idp/auth`);
|
const res = await fetch(`${baseUrl}.oidc/auth`);
|
||||||
expect(res.status).toBe(400);
|
expect(res.status).toBe(400);
|
||||||
await expect(res.text()).resolves.toContain('InvalidRequest: invalid_request');
|
await expect(res.text()).resolves.toContain('InvalidRequest: invalid_request');
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"files-scs:config/app/main/default.json",
|
"files-scs:config/app/main/default.json",
|
||||||
"files-scs:config/app/init/initialize-root.json",
|
"files-scs:config/app/init/initialize-root.json",
|
||||||
"files-scs:config/app/setup/disabled.json",
|
"files-scs:config/app/setup/disabled.json",
|
||||||
"files-scs:config/http/handler/default.json",
|
"files-scs:config/http/handler/simple.json",
|
||||||
"files-scs:config/http/middleware/websockets.json",
|
"files-scs:config/http/middleware/websockets.json",
|
||||||
"files-scs:config/http/server-factory/websockets.json",
|
"files-scs:config/http/server-factory/websockets.json",
|
||||||
"files-scs:config/http/static/default.json",
|
"files-scs:config/http/static/default.json",
|
||||||
@ -26,9 +26,5 @@
|
|||||||
"files-scs:config/util/variables/default.json"
|
"files-scs:config/util/variables/default.json"
|
||||||
],
|
],
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
|
||||||
"@id": "urn:solid-server:default:IdentityProviderHandler",
|
|
||||||
"@type": "UnsupportedAsyncHandler"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import type {
|
|||||||
RepresentationConverter,
|
RepresentationConverter,
|
||||||
RepresentationConverterArgs,
|
RepresentationConverterArgs,
|
||||||
} from '../../../src/storage/conversion/RepresentationConverter';
|
} from '../../../src/storage/conversion/RepresentationConverter';
|
||||||
|
import { NotFoundHttpError } from '../../../src/util/errors/NotFoundHttpError';
|
||||||
import { joinUrl } from '../../../src/util/PathUtil';
|
import { joinUrl } from '../../../src/util/PathUtil';
|
||||||
import { guardedStreamFrom, readableToString } from '../../../src/util/StreamUtil';
|
import { guardedStreamFrom, readableToString } from '../../../src/util/StreamUtil';
|
||||||
import { CONTENT_TYPE, SOLID_HTTP, SOLID_META } from '../../../src/util/Vocabularies';
|
import { CONTENT_TYPE, SOLID_HTTP, SOLID_META } from '../../../src/util/Vocabularies';
|
||||||
@ -46,7 +47,6 @@ describe('An IdentityProviderHttpHandler', (): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
provider = {
|
provider = {
|
||||||
callback: jest.fn(),
|
|
||||||
interactionDetails: jest.fn(),
|
interactionDetails: jest.fn(),
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
@ -113,11 +113,9 @@ describe('An IdentityProviderHttpHandler', (): void => {
|
|||||||
handler = new IdentityProviderHttpHandler(args);
|
handler = new IdentityProviderHttpHandler(args);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls the provider if there is no matching route.', async(): Promise<void> => {
|
it('throws a 404 if there is no matching route.', async(): Promise<void> => {
|
||||||
operation.target.path = joinUrl(baseUrl, 'invalid');
|
operation.target.path = joinUrl(baseUrl, 'invalid');
|
||||||
await expect(handler.handle({ request, response, operation })).resolves.toBeUndefined();
|
await expect(handler.handle({ request, response, operation })).rejects.toThrow(NotFoundHttpError);
|
||||||
expect(provider.callback).toHaveBeenCalledTimes(1);
|
|
||||||
expect(provider.callback).toHaveBeenLastCalledWith(request, response);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates Representations for InteractionResponseResults.', async(): Promise<void> => {
|
it('creates Representations for InteractionResponseResults.', async(): Promise<void> => {
|
||||||
|
31
test/unit/identity/OidcHttpHandler.test.ts
Normal file
31
test/unit/identity/OidcHttpHandler.test.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import type { Provider } from 'oidc-provider';
|
||||||
|
import type { ProviderFactory } from '../../../src/identity/configuration/ProviderFactory';
|
||||||
|
import { OidcHttpHandler } from '../../../src/identity/OidcHttpHandler';
|
||||||
|
import type { HttpRequest } from '../../../src/server/HttpRequest';
|
||||||
|
import type { HttpResponse } from '../../../src/server/HttpResponse';
|
||||||
|
|
||||||
|
describe('An OidcHttpHandler', (): void => {
|
||||||
|
const request: HttpRequest = {} as any;
|
||||||
|
const response: HttpResponse = {} as any;
|
||||||
|
let provider: jest.Mocked<Provider>;
|
||||||
|
let providerFactory: jest.Mocked<ProviderFactory>;
|
||||||
|
let handler: OidcHttpHandler;
|
||||||
|
|
||||||
|
beforeEach(async(): Promise<void> => {
|
||||||
|
provider = {
|
||||||
|
callback: jest.fn(),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
providerFactory = {
|
||||||
|
getProvider: jest.fn().mockResolvedValue(provider),
|
||||||
|
};
|
||||||
|
|
||||||
|
handler = new OidcHttpHandler(providerFactory);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends all requests to the OIDC library.', async(): Promise<void> => {
|
||||||
|
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
||||||
|
expect(provider.callback).toHaveBeenCalledTimes(1);
|
||||||
|
expect(provider.callback).toHaveBeenLastCalledWith(request, response);
|
||||||
|
});
|
||||||
|
});
|
@ -12,23 +12,24 @@ jest.mock('oidc-provider', (): any => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const routes = {
|
const routes = {
|
||||||
authorization: '/foo/idp/auth',
|
authorization: '/foo/oidc/auth',
|
||||||
check_session: '/foo/idp/session/check',
|
check_session: '/foo/oidc/session/check',
|
||||||
code_verification: '/foo/idp/device',
|
code_verification: '/foo/oidc/device',
|
||||||
device_authorization: '/foo/idp/device/auth',
|
device_authorization: '/foo/oidc/device/auth',
|
||||||
end_session: '/foo/idp/session/end',
|
end_session: '/foo/oidc/session/end',
|
||||||
introspection: '/foo/idp/token/introspection',
|
introspection: '/foo/oidc/token/introspection',
|
||||||
jwks: '/foo/idp/jwks',
|
jwks: '/foo/oidc/jwks',
|
||||||
pushed_authorization_request: '/foo/idp/request',
|
pushed_authorization_request: '/foo/oidc/request',
|
||||||
registration: '/foo/idp/reg',
|
registration: '/foo/oidc/reg',
|
||||||
revocation: '/foo/idp/token/revocation',
|
revocation: '/foo/oidc/token/revocation',
|
||||||
token: '/foo/idp/token',
|
token: '/foo/oidc/token',
|
||||||
userinfo: '/foo/idp/me',
|
userinfo: '/foo/oidc/me',
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('An IdentityProviderFactory', (): void => {
|
describe('An IdentityProviderFactory', (): void => {
|
||||||
let baseConfig: Configuration;
|
let baseConfig: Configuration;
|
||||||
const baseUrl = 'http://test.com/foo/';
|
const baseUrl = 'http://test.com/foo/';
|
||||||
|
const oidcPath = '/oidc';
|
||||||
const idpPath = '/idp';
|
const idpPath = '/idp';
|
||||||
const webId = 'http://alice.test.com/card#me';
|
const webId = 'http://alice.test.com/card#me';
|
||||||
let adapterFactory: jest.Mocked<AdapterFactory>;
|
let adapterFactory: jest.Mocked<AdapterFactory>;
|
||||||
@ -59,6 +60,7 @@ describe('An IdentityProviderFactory', (): void => {
|
|||||||
factory = new IdentityProviderFactory(baseConfig, {
|
factory = new IdentityProviderFactory(baseConfig, {
|
||||||
adapterFactory,
|
adapterFactory,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
oidcPath,
|
||||||
idpPath,
|
idpPath,
|
||||||
storage,
|
storage,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
@ -70,6 +72,7 @@ describe('An IdentityProviderFactory', (): void => {
|
|||||||
expect((): any => new IdentityProviderFactory(baseConfig, {
|
expect((): any => new IdentityProviderFactory(baseConfig, {
|
||||||
adapterFactory,
|
adapterFactory,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
oidcPath,
|
||||||
idpPath: 'idp',
|
idpPath: 'idp',
|
||||||
storage,
|
storage,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
@ -127,6 +130,7 @@ describe('An IdentityProviderFactory', (): void => {
|
|||||||
factory = new IdentityProviderFactory(baseConfig, {
|
factory = new IdentityProviderFactory(baseConfig, {
|
||||||
adapterFactory,
|
adapterFactory,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
oidcPath,
|
||||||
idpPath,
|
idpPath,
|
||||||
storage,
|
storage,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
@ -148,6 +152,7 @@ describe('An IdentityProviderFactory', (): void => {
|
|||||||
const factory2 = new IdentityProviderFactory(baseConfig, {
|
const factory2 = new IdentityProviderFactory(baseConfig, {
|
||||||
adapterFactory,
|
adapterFactory,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
oidcPath,
|
||||||
idpPath,
|
idpPath,
|
||||||
storage,
|
storage,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user