mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Use WebSocket2023Channel identifier for WebSocket URL
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import type { Server } from 'http';
|
||||
import type { WebSocket } from 'ws';
|
||||
import {
|
||||
AbsolutePathInteractionRoute,
|
||||
} from '../../../../../src/identity/interaction/routing/AbsolutePathInteractionRoute';
|
||||
|
||||
import type { HttpRequest } from '../../../../../src/server/HttpRequest';
|
||||
import type { NotificationChannel } from '../../../../../src/server/notifications/NotificationChannel';
|
||||
import type {
|
||||
@@ -32,13 +30,12 @@ describe('A WebSocket2023Listener', (): void => {
|
||||
topic: 'http://example.com/foo',
|
||||
type: 'type',
|
||||
};
|
||||
const auth = '123456';
|
||||
let server: Server;
|
||||
let webSocket: WebSocket;
|
||||
let upgradeRequest: HttpRequest;
|
||||
let storage: jest.Mocked<NotificationChannelStorage>;
|
||||
let handler: jest.Mocked<WebSocket2023Handler>;
|
||||
const route = new AbsolutePathInteractionRoute('http://example.com/foo');
|
||||
const baseUrl = 'http://example.com/';
|
||||
let listener: WebSocket2023Listener;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
@@ -47,7 +44,7 @@ describe('A WebSocket2023Listener', (): void => {
|
||||
webSocket.send = jest.fn();
|
||||
webSocket.close = jest.fn();
|
||||
|
||||
upgradeRequest = { url: `/foo?auth=${auth}` } as any;
|
||||
upgradeRequest = { url: `/foo/123456` } as any;
|
||||
|
||||
storage = {
|
||||
get: jest.fn().mockResolvedValue(channel),
|
||||
@@ -57,47 +54,11 @@ describe('A WebSocket2023Listener', (): void => {
|
||||
handleSafe: jest.fn(),
|
||||
} as any;
|
||||
|
||||
listener = new WebSocket2023Listener(storage, handler, route);
|
||||
listener = new WebSocket2023Listener(storage, handler, baseUrl);
|
||||
await listener.handle(server);
|
||||
});
|
||||
|
||||
it('rejects request targeting an unknown path.', async(): Promise<void> => {
|
||||
upgradeRequest.url = '/wrong';
|
||||
server.emit('upgrade', upgradeRequest, webSocket);
|
||||
|
||||
await flushPromises();
|
||||
|
||||
expect(webSocket.send).toHaveBeenCalledTimes(1);
|
||||
expect(webSocket.send).toHaveBeenLastCalledWith('Unknown WebSocket target.');
|
||||
expect(webSocket.close).toHaveBeenCalledTimes(1);
|
||||
expect(handler.handleSafe).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('rejects request with no url.', async(): Promise<void> => {
|
||||
delete upgradeRequest.url;
|
||||
server.emit('upgrade', upgradeRequest, webSocket);
|
||||
|
||||
await flushPromises();
|
||||
|
||||
expect(webSocket.send).toHaveBeenCalledTimes(1);
|
||||
expect(webSocket.send).toHaveBeenLastCalledWith('Unknown WebSocket target.');
|
||||
expect(webSocket.close).toHaveBeenCalledTimes(1);
|
||||
expect(handler.handleSafe).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('rejects requests without an auth parameter.', async(): Promise<void> => {
|
||||
upgradeRequest.url = '/foo';
|
||||
server.emit('upgrade', upgradeRequest, webSocket);
|
||||
|
||||
await flushPromises();
|
||||
|
||||
expect(webSocket.send).toHaveBeenCalledTimes(1);
|
||||
expect(webSocket.send).toHaveBeenLastCalledWith('Missing auth parameter from WebSocket URL.');
|
||||
expect(webSocket.close).toHaveBeenCalledTimes(1);
|
||||
expect(handler.handleSafe).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('rejects requests with an unknown auth parameter.', async(): Promise<void> => {
|
||||
it('rejects requests with an unknown target.', async(): Promise<void> => {
|
||||
storage.get.mockResolvedValue(undefined);
|
||||
server.emit('upgrade', upgradeRequest, webSocket);
|
||||
|
||||
|
||||
@@ -2,26 +2,32 @@ import type { IncomingMessage } from 'http';
|
||||
import {
|
||||
generateWebSocketUrl, parseWebSocketRequest,
|
||||
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Util';
|
||||
import { BadRequestHttpError } from '../../../../../src/util/errors/BadRequestHttpError';
|
||||
|
||||
describe('WebSocket2023Util', (): void => {
|
||||
describe('#generateWebSocketUrl', (): void => {
|
||||
it('generates a WebSocket link with a query parameter.', async(): Promise<void> => {
|
||||
expect(generateWebSocketUrl('http://example.com/', '123456')).toBe('ws://example.com/?auth=123456');
|
||||
it('generates a WebSocket link.', async(): Promise<void> => {
|
||||
expect(generateWebSocketUrl('http://example.com/123456')).toBe('ws://example.com/123456');
|
||||
|
||||
expect(generateWebSocketUrl('https://example.com/foo/bar', '123456'))
|
||||
.toBe('wss://example.com/foo/bar?auth=123456');
|
||||
expect(generateWebSocketUrl('https://example.com/foo/bar/123456'))
|
||||
.toBe('wss://example.com/foo/bar/123456');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#parseWebSocketRequest', (): void => {
|
||||
it('parses the request.', async(): Promise<void> => {
|
||||
const request: IncomingMessage = { url: '/foo/bar?auth=123%24456' } as any;
|
||||
expect(parseWebSocketRequest(request)).toEqual({ path: '/foo/bar', id: '123$456' });
|
||||
const request: IncomingMessage = { url: '/foo/bar/123%24456' } as any;
|
||||
expect(parseWebSocketRequest('http://example.com/', request)).toBe('http://example.com/foo/bar/123%24456');
|
||||
});
|
||||
|
||||
it('returns an empty path and no id if the url parameter is undefined.', async(): Promise<void> => {
|
||||
it('throws an error if the url parameter is not defined.', async(): Promise<void> => {
|
||||
const request: IncomingMessage = {} as any;
|
||||
expect(parseWebSocketRequest(request)).toEqual({ path: '/' });
|
||||
expect((): string => parseWebSocketRequest('http://example.com/', request)).toThrow(BadRequestHttpError);
|
||||
});
|
||||
|
||||
it('can handle non-root base URLs.', async(): Promise<void> => {
|
||||
const request: IncomingMessage = { url: '/foo/bar/123%24456' } as any;
|
||||
expect(parseWebSocketRequest('http://example.com/foo/bar/', request)).toBe('http://example.com/foo/bar/123%24456');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('A WebSocketChannel2023', (): void => {
|
||||
id,
|
||||
type: NOTIFY.WebSocketChannel2023,
|
||||
topic,
|
||||
receiveFrom: generateWebSocketUrl(route.getPath(), id),
|
||||
receiveFrom: generateWebSocketUrl(id),
|
||||
};
|
||||
|
||||
channelType = new WebSocketChannel2023Type(route);
|
||||
|
||||
Reference in New Issue
Block a user