mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Use correct type for Webhook notifications
This commit is contained in:
parent
9584ab7549
commit
c0a881b980
@ -2,10 +2,10 @@
|
|||||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld",
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld",
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"comment": "Handles the generation and serialization of notifications for WebHookChannel2023.",
|
"comment": "Handles the generation and serialization of notifications for WebhookChannel2023.",
|
||||||
"@id": "urn:solid-server:default:WebHookNotificationHandler",
|
"@id": "urn:solid-server:default:WebHookNotificationHandler",
|
||||||
"@type": "TypedNotificationHandler",
|
"@type": "TypedNotificationHandler",
|
||||||
"type": "http://www.w3.org/ns/solid/notifications#WebHookChannel2023",
|
"type": "http://www.w3.org/ns/solid/notifications#WebhookChannel2023",
|
||||||
"source": {
|
"source": {
|
||||||
"@type": "ComposedNotificationHandler",
|
"@type": "ComposedNotificationHandler",
|
||||||
"generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" },
|
"generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" },
|
||||||
@ -14,7 +14,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"comment": "Emits serialized notifications through HTTP requests to the WebHook.",
|
"comment": "Emits serialized notifications through HTTP requests to the Webhook.",
|
||||||
"@id": "urn:solid-server:default:WebHookEmitter",
|
"@id": "urn:solid-server:default:WebHookEmitter",
|
||||||
"@type": "WebHookEmitter",
|
"@type": "WebHookEmitter",
|
||||||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"@id": "urn:solid-server:default:WebHookRoute",
|
"@id": "urn:solid-server:default:WebHookRoute",
|
||||||
"@type": "RelativePathInteractionRoute",
|
"@type": "RelativePathInteractionRoute",
|
||||||
"base": { "@id": "urn:solid-server:default:NotificationRoute" },
|
"base": { "@id": "urn:solid-server:default:NotificationRoute" },
|
||||||
"relativePath": "/WebHookChannel2023/"
|
"relativePath": "/WebhookChannel2023/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:WebHookWebIdRoute",
|
"@id": "urn:solid-server:default:WebHookWebIdRoute",
|
||||||
@ -15,11 +15,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"comment": "Handles the WebHookChannel2023 WebID.",
|
"comment": "Handles the WebhookChannel2023 WebID.",
|
||||||
"@id": "urn:solid-server:default:WebHookWebId",
|
"@id": "urn:solid-server:default:WebHookWebId",
|
||||||
"@type": "OperationRouterHandler",
|
"@type": "OperationRouterHandler",
|
||||||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
"allowedPathNames": [ "/WebHookChannel2023/webId$" ],
|
"allowedPathNames": [ "/WebhookChannel2023/webId$" ],
|
||||||
"handler": {
|
"handler": {
|
||||||
"@type": "WebHookWebId",
|
"@type": "WebHookWebId",
|
||||||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }
|
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld",
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld",
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"comment": "Handles the subscriptions targeting a WebHookChannel2023.",
|
"comment": "Handles the subscriptions targeting a WebhookChannel2023.",
|
||||||
"@id": "urn:solid-server:default:WebHookRouter",
|
"@id": "urn:solid-server:default:WebHookRouter",
|
||||||
"@type": "OperationRouterHandler",
|
"@type": "OperationRouterHandler",
|
||||||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
"allowedMethods": [ "HEAD", "GET", "POST" ],
|
"allowedMethods": [ "HEAD", "GET", "POST" ],
|
||||||
"allowedPathNames": [ "/WebHookChannel2023/$" ],
|
"allowedPathNames": [ "/WebhookChannel2023/$" ],
|
||||||
"handler": {
|
"handler": {
|
||||||
"@id": "urn:solid-server:default:WebHookSubscriber",
|
"@id": "urn:solid-server:default:WebHookSubscriber",
|
||||||
"@type": "NotificationSubscriber",
|
"@type": "NotificationSubscriber",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"comment": "Contains all the metadata relevant for a WebHookChannel2023.",
|
"comment": "Contains all the metadata relevant for a WebhookChannel2023.",
|
||||||
"@id": "urn:solid-server:default:WebHookChannel2023Type",
|
"@id": "urn:solid-server:default:WebHookChannel2023Type",
|
||||||
"@type": "WebhookChannel2023Type",
|
"@type": "WebhookChannel2023Type",
|
||||||
"route": { "@id": "urn:solid-server:default:WebHookRoute" },
|
"route": { "@id": "urn:solid-server:default:WebHookRoute" },
|
||||||
|
@ -27,7 +27,7 @@ Doing a GET to `http://localhost:3000/.well-known/solid` then gives the followin
|
|||||||
<http://localhost:3000/.well-known/solid>
|
<http://localhost:3000/.well-known/solid>
|
||||||
a <http://www.w3.org/ns/pim/space#Storage> ;
|
a <http://www.w3.org/ns/pim/space#Storage> ;
|
||||||
notify:subscription <http://localhost:3000/.notifications/WebSocketChannel2023/> ,
|
notify:subscription <http://localhost:3000/.notifications/WebSocketChannel2023/> ,
|
||||||
<http://localhost:3000/.notifications/WebHookChannel2023/> .
|
<http://localhost:3000/.notifications/WebhookChannel2023/> .
|
||||||
<http://localhost:3000/.notifications/WebSocketChannel2023/>
|
<http://localhost:3000/.notifications/WebSocketChannel2023/>
|
||||||
notify:channelType notify:WebSocketChannel2023 ;
|
notify:channelType notify:WebSocketChannel2023 ;
|
||||||
notify:feature notify:accept ,
|
notify:feature notify:accept ,
|
||||||
@ -35,8 +35,8 @@ Doing a GET to `http://localhost:3000/.well-known/solid` then gives the followin
|
|||||||
notify:rate ,
|
notify:rate ,
|
||||||
notify:startAt ,
|
notify:startAt ,
|
||||||
notify:state .
|
notify:state .
|
||||||
<http://localhost:3000/.notifications/WebSocketChannel2023/>
|
<http://localhost:3000/.notifications/WebhookChannel2023/>
|
||||||
notify:channelType notify:WebHookChannel2023;
|
notify:channelType notify:WebhookChannel2023;
|
||||||
notify:feature notify:accept ,
|
notify:feature notify:accept ,
|
||||||
notify:endAt ,
|
notify:endAt ,
|
||||||
notify:rate ,
|
notify:rate ,
|
||||||
@ -61,7 +61,7 @@ Requests without `Read` permission will be rejected.
|
|||||||
|
|
||||||
There are currently up to two supported ways to get notifications in CSS, depending on your configuration:
|
There are currently up to two supported ways to get notifications in CSS, depending on your configuration:
|
||||||
the notification channel types [`WebSocketChannel2023`](https://solid.github.io/notifications/websocket-channel-2023);
|
the notification channel types [`WebSocketChannel2023`](https://solid.github.io/notifications/websocket-channel-2023);
|
||||||
and [`WebHookChannel2023`](https://solid.github.io/notifications/webhook-channel-2023).
|
and [`WebhookChannel2023`](https://solid.github.io/notifications/webhook-channel-2023).
|
||||||
|
|
||||||
### WebSockets
|
### WebSockets
|
||||||
|
|
||||||
@ -98,30 +98,30 @@ const ws = new WebSocket(receiveFrom);
|
|||||||
ws.on('message', (notification) => console.log(notification));
|
ws.on('message', (notification) => console.log(notification));
|
||||||
```
|
```
|
||||||
|
|
||||||
### WebHooks
|
### Webhooks
|
||||||
|
|
||||||
Similar to the WebSocket subscription, below is sample JSON-LD
|
Similar to the WebSocket subscription, below is sample JSON-LD
|
||||||
that would be sent to `http://localhost:3000/.notifications/WebHookChannel2023/`:
|
that would be sent to `http://localhost:3000/.notifications/WebhookChannel2023/`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"@context": [ "https://www.w3.org/ns/solid/notification/v1" ],
|
"@context": [ "https://www.w3.org/ns/solid/notification/v1" ],
|
||||||
"type": "http://www.w3.org/ns/solid/notifications#WebHookChannel2023",
|
"type": "http://www.w3.org/ns/solid/notifications#WebhookChannel2023",
|
||||||
"topic": "http://localhost:3000/foo",
|
"topic": "http://localhost:3000/foo",
|
||||||
"sendTo": "https://example.com/webhook"
|
"sendTo": "https://example.com/webhook"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this document has an additional `sendTo` field.
|
Note that this document has an additional `sendTo` field.
|
||||||
This is the WebHook URL of your server, the URL to which you want the notifications to be sent.
|
This is the Webhook URL of your server, the URL to which you want the notifications to be sent.
|
||||||
|
|
||||||
The response would then be something like this:
|
The response would then be something like this:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"@context": [ "https://www.w3.org/ns/solid/notification/v1" ],
|
"@context": [ "https://www.w3.org/ns/solid/notification/v1" ],
|
||||||
"id": "http://localhost:3000/.notifications/WebHookChannel2023/eeaf2c17-699a-4e53-8355-e91d13807e5f",
|
"id": "http://localhost:3000/.notifications/WebhookChannel2023/eeaf2c17-699a-4e53-8355-e91d13807e5f",
|
||||||
"type": "http://www.w3.org/ns/solid/notifications#WebHookChannel2023",
|
"type": "http://www.w3.org/ns/solid/notifications#WebhookChannel2023",
|
||||||
"topic": "http://localhost:3000/foo",
|
"topic": "http://localhost:3000/foo",
|
||||||
"sendTo": "https://example.com/webhook"
|
"sendTo": "https://example.com/webhook"
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ export interface WebhookChannel2023 extends NotificationChannel {
|
|||||||
/**
|
/**
|
||||||
* The "WebHookChannel2023" type.
|
* The "WebHookChannel2023" type.
|
||||||
*/
|
*/
|
||||||
type: typeof NOTIFY.WebHookChannel2023;
|
type: typeof NOTIFY.WebhookChannel2023;
|
||||||
/**
|
/**
|
||||||
* Where the notifications have to be sent.
|
* Where the notifications have to be sent.
|
||||||
*/
|
*/
|
||||||
@ -22,7 +22,7 @@ export interface WebhookChannel2023 extends NotificationChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isWebHook2023Channel(channel: NotificationChannel): channel is WebhookChannel2023 {
|
export function isWebHook2023Channel(channel: NotificationChannel): channel is WebhookChannel2023 {
|
||||||
return channel.type === NOTIFY.WebHookChannel2023;
|
return channel.type === NOTIFY.WebhookChannel2023;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +47,7 @@ export class WebhookChannel2023Type extends BaseChannelType {
|
|||||||
*/
|
*/
|
||||||
public constructor(route: InteractionRoute, webIdRoute: InteractionRoute, stateHandler: StateHandler,
|
public constructor(route: InteractionRoute, webIdRoute: InteractionRoute, stateHandler: StateHandler,
|
||||||
features?: string[]) {
|
features?: string[]) {
|
||||||
super(NOTIFY.terms.WebHookChannel2023,
|
super(NOTIFY.terms.WebhookChannel2023,
|
||||||
route,
|
route,
|
||||||
features,
|
features,
|
||||||
[{ path: NOTIFY.sendTo, minCount: 1, maxCount: 1 }]);
|
[{ path: NOTIFY.sendTo, minCount: 1, maxCount: 1 }]);
|
||||||
@ -62,7 +62,7 @@ export class WebhookChannel2023Type extends BaseChannelType {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...channel,
|
...channel,
|
||||||
type: NOTIFY.WebHookChannel2023,
|
type: NOTIFY.WebhookChannel2023,
|
||||||
sendTo: sendTo.value,
|
sendTo: sendTo.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ export const NOTIFY = createVocabulary('http://www.w3.org/ns/solid/notifications
|
|||||||
'topic',
|
'topic',
|
||||||
'webhookAuth',
|
'webhookAuth',
|
||||||
|
|
||||||
'WebHookChannel2023',
|
'WebhookChannel2023',
|
||||||
'WebSocketChannel2023',
|
'WebSocketChannel2023',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -21,14 +21,13 @@ import {
|
|||||||
removeFolder,
|
removeFolder,
|
||||||
} from './Config';
|
} from './Config';
|
||||||
import quad = DataFactory.quad;
|
import quad = DataFactory.quad;
|
||||||
import namedNode = DataFactory.namedNode;
|
|
||||||
|
|
||||||
const port = getPort('WebHookChannel2023');
|
const port = getPort('WebHookChannel2023');
|
||||||
const baseUrl = `http://localhost:${port}/`;
|
const baseUrl = `http://localhost:${port}/`;
|
||||||
const clientPort = getPort('WebHookChannel2023-client');
|
const clientPort = getPort('WebHookChannel2023-client');
|
||||||
const target = `http://localhost:${clientPort}/`;
|
const target = `http://localhost:${clientPort}/`;
|
||||||
const webId = 'http://example.com/card/#me';
|
const webId = 'http://example.com/card/#me';
|
||||||
const notificationType = NOTIFY.WebHookChannel2023;
|
const notificationType = NOTIFY.WebhookChannel2023;
|
||||||
|
|
||||||
const rootFilePath = getTestFolder('WebHookChannel2023');
|
const rootFilePath = getTestFolder('WebHookChannel2023');
|
||||||
const stores: [string, any][] = [
|
const stores: [string, any][] = [
|
||||||
@ -99,7 +98,7 @@ describe.each(stores)('A server supporting WebHookChannel2023 using %s', (name,
|
|||||||
// Find the notification channel for websockets
|
// Find the notification channel for websockets
|
||||||
const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null);
|
const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null);
|
||||||
const webhookSubscriptions = subscriptions.filter((channel): boolean => quads.has(
|
const webhookSubscriptions = subscriptions.filter((channel): boolean => quads.has(
|
||||||
quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebHookChannel2023`)),
|
quad(channel as NamedNode, NOTIFY.terms.channelType, NOTIFY.terms.WebhookChannel2023),
|
||||||
));
|
));
|
||||||
expect(webhookSubscriptions).toHaveLength(1);
|
expect(webhookSubscriptions).toHaveLength(1);
|
||||||
subscriptionUrl = webhookSubscriptions[0].value;
|
subscriptionUrl = webhookSubscriptions[0].value;
|
||||||
|
@ -88,7 +88,7 @@ describe.each(stores)('A server supporting WebSocketChannel2023 using %s', (name
|
|||||||
// Find the notification channel for websockets
|
// Find the notification channel for websockets
|
||||||
const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null);
|
const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null);
|
||||||
const websocketSubscriptions = subscriptions.filter((channel): boolean => quads.has(
|
const websocketSubscriptions = subscriptions.filter((channel): boolean => quads.has(
|
||||||
quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketChannel2023`)),
|
quad(channel as NamedNode, NOTIFY.terms.channelType, NOTIFY.terms.WebSocketChannel2023),
|
||||||
));
|
));
|
||||||
expect(websocketSubscriptions).toHaveLength(1);
|
expect(websocketSubscriptions).toHaveLength(1);
|
||||||
subscriptionUrl = websocketSubscriptions[0].value;
|
subscriptionUrl = websocketSubscriptions[0].value;
|
||||||
|
@ -43,14 +43,14 @@ describe('A WebhookChannel2023Type', (): void => {
|
|||||||
|
|
||||||
beforeEach(async(): Promise<void> => {
|
beforeEach(async(): Promise<void> => {
|
||||||
data = new Store();
|
data = new Store();
|
||||||
data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebHookChannel2023));
|
data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebhookChannel2023));
|
||||||
data.addQuad(quad(subject, NOTIFY.terms.topic, namedNode(topic)));
|
data.addQuad(quad(subject, NOTIFY.terms.topic, namedNode(topic)));
|
||||||
data.addQuad(quad(subject, NOTIFY.terms.sendTo, namedNode(sendTo)));
|
data.addQuad(quad(subject, NOTIFY.terms.sendTo, namedNode(sendTo)));
|
||||||
|
|
||||||
const id = 'http://example.com/webhooks/4c9b88c1-7502-4107-bb79-2a3a590c7aa3';
|
const id = 'http://example.com/webhooks/4c9b88c1-7502-4107-bb79-2a3a590c7aa3';
|
||||||
channel = {
|
channel = {
|
||||||
id,
|
id,
|
||||||
type: NOTIFY.WebHookChannel2023,
|
type: NOTIFY.WebhookChannel2023,
|
||||||
topic: 'https://storage.example/resource',
|
topic: 'https://storage.example/resource',
|
||||||
sendTo,
|
sendTo,
|
||||||
};
|
};
|
||||||
@ -79,7 +79,7 @@ describe('A WebhookChannel2023Type', (): void => {
|
|||||||
CONTEXT_NOTIFICATION,
|
CONTEXT_NOTIFICATION,
|
||||||
],
|
],
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
type: NOTIFY.WebHookChannel2023,
|
type: NOTIFY.WebhookChannel2023,
|
||||||
sendTo,
|
sendTo,
|
||||||
topic,
|
topic,
|
||||||
sender: 'http://example.com/webhooks/webid',
|
sender: 'http://example.com/webhooks/webid',
|
||||||
|
@ -45,7 +45,7 @@ describe('A WebHookEmitter', (): void => {
|
|||||||
const channel: WebhookChannel2023 = {
|
const channel: WebhookChannel2023 = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
topic: 'http://example.com/foo',
|
topic: 'http://example.com/foo',
|
||||||
type: NOTIFY.WebHookChannel2023,
|
type: NOTIFY.WebhookChannel2023,
|
||||||
sendTo: 'http://example.org/somewhere-else',
|
sendTo: 'http://example.org/somewhere-else',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { fetch } from 'cross-fetch';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to a notification channel.
|
* Subscribes to a notification channel.
|
||||||
* @param type - The type of the notification channel, e.g., "NOTIFY.WebHookChannel2023".
|
* @param type - The type of the notification channel, e.g., "NOTIFY.WebhookChannel2023".
|
||||||
* @param webId - The WebID to spoof in the authorization header. This assumes the config uses the debug auth import.
|
* @param webId - The WebID to spoof in the authorization header. This assumes the config uses the debug auth import.
|
||||||
* @param subscriptionUrl - The subscription URL to which the request needs to be sent.
|
* @param subscriptionUrl - The subscription URL to which the request needs to be sent.
|
||||||
* @param topic - The topic to subscribe to.
|
* @param topic - The topic to subscribe to.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user