mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Rewrite request with a root path to OIDC Provider
* fix(oidc): rewrite requests with rootpath * fix: respect query parameters
This commit is contained in:
parent
e7ba2d49f8
commit
0a84230307
@ -18,6 +18,13 @@ export class OidcHttpHandler extends HttpHandler {
|
|||||||
|
|
||||||
public async handle({ request, response }: HttpHandlerInput): Promise<void> {
|
public async handle({ request, response }: HttpHandlerInput): Promise<void> {
|
||||||
const provider = await this.providerFactory.getProvider();
|
const provider = await this.providerFactory.getProvider();
|
||||||
|
|
||||||
|
// Rewrite requests to allow hosting on root paths
|
||||||
|
const path = new URL(provider.issuer).pathname;
|
||||||
|
if (path.length > 1 && request.url!.startsWith(`${path}.well-known/openid-configuration`)) {
|
||||||
|
request.url = request.url!.replace(path, '/');
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.debug(`Sending request to oidc-provider: ${request.url}`);
|
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.
|
// 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.
|
// Otherwise, the `BaseHttpServerFactory` will write a 404 before the OIDC library could handle the response.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<a href="/"><img src="/.well-known/css/images/solid.svg" alt="[Solid logo]" /></a>
|
<a href="./"><img src="/.well-known/css/images/solid.svg" alt="[Solid logo]" /></a>
|
||||||
<h1>Community Solid Server</h1>
|
<h1>Community Solid Server</h1>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
<h2 id="users">Getting started as a <em>user</em></h2>
|
<h2 id="users">Getting started as a <em>user</em></h2>
|
||||||
<p>
|
<p>
|
||||||
<a href="/idp/register/">Sign up for an account</a>
|
<a href="./idp/register/">Sign up for an account</a>
|
||||||
to get started with your own Pod and WebID.
|
to get started with your own Pod and WebID.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -5,7 +5,9 @@ import type { HttpRequest } from '../../../src/server/HttpRequest';
|
|||||||
import type { HttpResponse } from '../../../src/server/HttpResponse';
|
import type { HttpResponse } from '../../../src/server/HttpResponse';
|
||||||
|
|
||||||
describe('An OidcHttpHandler', (): void => {
|
describe('An OidcHttpHandler', (): void => {
|
||||||
const request: HttpRequest = {} as any;
|
const request: HttpRequest = {
|
||||||
|
url: '/.well-known/openid-configuration',
|
||||||
|
} as any;
|
||||||
const response: HttpResponse = {} as any;
|
const response: HttpResponse = {} as any;
|
||||||
let provider: jest.Mocked<Provider>;
|
let provider: jest.Mocked<Provider>;
|
||||||
let providerFactory: jest.Mocked<ProviderFactory>;
|
let providerFactory: jest.Mocked<ProviderFactory>;
|
||||||
@ -14,11 +16,12 @@ describe('An OidcHttpHandler', (): void => {
|
|||||||
beforeEach(async(): Promise<void> => {
|
beforeEach(async(): Promise<void> => {
|
||||||
provider = {
|
provider = {
|
||||||
callback: jest.fn().mockReturnValue(jest.fn()),
|
callback: jest.fn().mockReturnValue(jest.fn()),
|
||||||
|
issuer: 'http://localhost:3000/',
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
providerFactory = {
|
providerFactory = {
|
||||||
getProvider: jest.fn().mockResolvedValue(provider),
|
getProvider: jest.fn().mockResolvedValue(provider),
|
||||||
};
|
} as any;
|
||||||
|
|
||||||
handler = new OidcHttpHandler(providerFactory);
|
handler = new OidcHttpHandler(providerFactory);
|
||||||
});
|
});
|
||||||
@ -29,4 +32,24 @@ describe('An OidcHttpHandler', (): void => {
|
|||||||
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
|
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
|
||||||
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
|
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('rewrites the request when using base URL with root path.', async(): Promise<void> => {
|
||||||
|
Object.assign(provider, { issuer: 'http://localhost:3000/path/' });
|
||||||
|
request.url = '/path/.well-known/openid-configuration';
|
||||||
|
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
||||||
|
expect(request.url).toBe('/.well-known/openid-configuration');
|
||||||
|
expect(provider.callback).toHaveBeenCalledTimes(1);
|
||||||
|
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
|
||||||
|
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects query parameters when rewriting requests.', async(): Promise<void> => {
|
||||||
|
Object.assign(provider, { issuer: 'http://localhost:3000/path/' });
|
||||||
|
request.url = '/path/.well-known/openid-configuration?param1=value1';
|
||||||
|
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
||||||
|
expect(request.url).toBe('/.well-known/openid-configuration?param1=value1');
|
||||||
|
expect(provider.callback).toHaveBeenCalledTimes(1);
|
||||||
|
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
|
||||||
|
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user