feat: Restrict channels to 2 weeks by default

This commit is contained in:
Joachim Van Herwegen 2023-04-21 10:40:36 +02:00
parent ac1e3093e6
commit f7e05ca31e
6 changed files with 33 additions and 7 deletions

View File

@ -44,7 +44,7 @@
"@id": "urn:solid-server:default:NotificationTypeHandler",
"@type": "WaterfallHandler",
"handlers": [
{ "@id": "urn:solid-server:default:WebHookSubscriber" },
{ "@id": "urn:solid-server:default:WebHookRouter" },
{ "@id": "urn:solid-server:default:WebHookUnsubscriber" },
{ "@id": "urn:solid-server:default:WebHookWebId" }
]

View File

@ -3,12 +3,13 @@
"@graph": [
{
"comment": "Handles the subscriptions targeting a WebHookSubscription2021.",
"@id": "urn:solid-server:default:WebHookSubscriber",
"@id": "urn:solid-server:default:WebHookRouter",
"@type": "OperationRouterHandler",
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
"allowedMethods": [ "HEAD", "GET", "POST" ],
"allowedPathNames": [ "/WebHookSubscription2021/$" ],
"handler": {
"@id": "urn:solid-server:default:WebHookSubscriber",
"@type": "NotificationSubscriber",
"channelType": { "@id": "urn:solid-server:default:WebHookSubscription2021" },
"converter": { "@id": "urn:solid-server:default:RepresentationConverter" },

View File

@ -3,12 +3,13 @@
"@graph": [
{
"comment": "Handles the subscriptions targeting a WebSocketChannel2023.",
"@id": "urn:solid-server:default:WebSocket2023Subscriber",
"@id": "urn:solid-server:default:WebSocket2023Router",
"@type": "OperationRouterHandler",
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
"allowedMethods": [ "HEAD", "GET", "POST" ],
"allowedPathNames": [ "/WebSocketChannel2023/$" ],
"handler": {
"@id": "urn:solid-server:default:WebSocket2023Subscriber",
"@type": "NotificationSubscriber",
"channelType": { "@id": "urn:solid-server:default:WebSocketChannel2023Type" },
"converter": { "@id": "urn:solid-server:default:RepresentationConverter" },
@ -35,7 +36,7 @@
"@id": "urn:solid-server:default:NotificationTypeHandler",
"@type": "WaterfallHandler",
"handlers": [
{ "@id": "urn:solid-server:default:WebSocket2023Subscriber" }
{ "@id": "urn:solid-server:default:WebSocket2023Router" }
]
},

View File

@ -200,3 +200,27 @@ The available fields are:
A new notification will only be sent out after this much time has passed since the previous notification.
* **`accept`**: A description of the `content-type(s)` in which the client would want to receive the notifications.
Expects the same values as an `Accept` HTTP header.
## Important note for server owners
There is not much restriction on who can create a new notification channel,
only `Read` permissions on the target resource are required.
It is therefore possible for the server to accumulate created channels.
As these channels still get used every time their corresponding resource changes,
this could degrade server performance.
For this reason, the server is by default configured to always remove notification channels after 2 weeks.
You can modify this behaviour by adding the following block to your configuration:
```json
{
"@id": "urn:solid-server:default:WebSocket2023Subscriber",
"@type": "NotificationSubscriber",
"maxDuration": 20160
}
```
`maxDuration` defines after how many minutes every channel will be removed.
Setting this value to 0 will allow channels to exist forever.
Similarly, for changing the maximum duration of webhook channels you can use the identifier
`urn:solid-server:default:WebHookSubscriber`.

View File

@ -60,13 +60,12 @@ export class ListeningActivityHandler extends StaticHandler {
// No need to wait on this to resolve before going to the next channel.
// Prevent failed notification from blocking other notifications.
this.handler.handleSafe({ channel, activity, topic, metadata })
.then((): Promise<void> => {
.then(async(): Promise<void> => {
// Update the `lastEmit` value if the channel has a rate limit
if (channel.rate) {
channel.lastEmit = Date.now();
return this.storage.update(channel);
}
return Promise.resolve();
})
.catch((error): void => {
this.logger.error(`Error trying to handle notification for ${id}: ${createErrorMessage(error)}`);

View File

@ -46,6 +46,7 @@ export interface NotificationSubscriberArgs {
* Overrides the expiration feature of channels, by making sure they always expire after the `maxDuration` value.
* If the expiration of the channel is shorter than `maxDuration`, the original value will be kept.
* Value is set in minutes. 0 is infinite.
* Defaults to 20160 minutes, which is 2 weeks.
*/
maxDuration?: number;
}
@ -76,7 +77,7 @@ export class NotificationSubscriber extends OperationHttpHandler {
this.permissionReader = args.permissionReader;
this.authorizer = args.authorizer;
this.storage = args.storage;
this.maxDuration = (args.maxDuration ?? 0) * 60 * 1000;
this.maxDuration = (args.maxDuration ?? 20160) * 60 * 1000;
}
public async handle({ operation, request }: OperationHttpHandlerInput): Promise<ResponseDescription> {