@universis/janitor
TypeScript icon, indicating that this package has built-in type declarations

1.6.1 • Public • Published

@universis/janitor

@universis/janitor logo

Universis api plugin for rate limiting requests or slowing down service responses.

Usage

npm i @universis/janitor

RateLimitService

RateLimitService is a configurable extension of express-rate-limit for limiting service requests.

Register service under application services:

{
    "services": [
        {
            "serviceType": "@universis/janitor#RateLimitService"
        }
    ]
}

and start configuring rate limited endpoints under settings/universis/rateLimit:

    {
        "settings": {
            "universis": {
                "rateLimit": {
                    "profiles": [
                        [
                            "userRateLimitProfile",
                            {
                                "windowMs": 300000,
                                "limit": 50,
                                "legacyHeaders": true
                            }
                        ]
                    ],
                    "paths": [
                            [
                                "/users/me",
                                {
                                    "profile": "userRateLimitProfile"
                                }
                            ]
                        ]
                }
            }
        }
    }

RateLimitService service configuration consists of a collection of rate limit profiles that are going to used as options during request validation and a collection of paths for defining rate limited route paths.

Read more about rate limit configuration at express-rate-limit documentation

Enable rate limit headers over CORS

Each RateLimitService profile has an option to include a set of headers in the response. This can be done by setting the headers option to true in the profile configuration. This operation will add the following headers to the response:

  • X-RateLimit-Limit - the maximum number of requests allowed in the current window
  • X-RateLimit-Remaining - the number of requests remaining in the current window
  • X-RateLimit-Reset - the number of milliseconds remaining until the window resets

Rate limit headers will be available only if the request is made from the same origin. If the request is made from a different origin, the headers will not be included in the response and should be configured to be exposed by CORS.

{
    "settings": {
        "cors": {
            "exposedHeaders": [
                "X-Rate-Limit",
                "X-Rate-Remaining",
                "X-Rate-Reset"
            ]
        }
    }
}

SpeedLimitService

SpeedLimitService is a configurable extension of express-slow-down for slowing down service responses.

Register service under application services:

{
    "services": [
        {
            "serviceType": "@universis/janitor#SpeedLimitService"
        }
    ]
}

and start configuring speed limited endpoints under settings/universis/speedLimit:

    {
        "settings": {
            "universis": {
                "speedLimit": {
                    "profiles": [
                        [
                            "userSpeedLimitProfile",
                            {
                                "windowMs": 300000,
                                "delayAfter": 5,
                                "delayMs": 500,
                                "maxDelayMs": 20000,
                                "headers": true
                            }
                        ]
                    ],
                    "paths": [
                            [
                                "/users/me",
                                {
                                    "profile": "userSpeedLimitProfile"
                                }
                            ]
                        ]
                }
            }
        }
    }

SpeedLimitService configuration consists of a collection of speed limit profiles that are going to used as options during request validation and a collection of paths for defining speed limited route paths.

Read more about speed limit configuration at express-slow-down documentation

SpeedLimitService offers two additional options for delaying response: randomDelayMs and randomMaxDelayMs. These options are used for adding random delay to the response. They define the range of random delay in milliseconds.

    {
        "settings": {
            "universis": {
                "speedLimit": {
                    "profiles": [
                        [
                            "userSpeedLimitProfile",
                            {
                                "windowMs": 120000,
                                "delayAfter": 5,
                                "randomDelayMs": [
                                    500,
                                    1000
                                ],
                                "headers": false
                            }
                        ]
                    ],
                    "paths": [
                            [
                                "/users/me",
                                {
                                    "profile": "userSpeedLimitProfile"
                                }
                            ]
                        ]
                }
            }
        }
    }

If randomDelayMs is set, delayMs is ignored.

randomMaxDelayMs is used for setting the maximum random delay. If randomMaxDelayMs is not set, the maximum delay is set to maxDelayMs is ignored e.g.

    {
        "settings": {
            "universis": {
                "speedLimit": {
                    "profiles": [
                        [
                            "userSpeedLimitProfile",
                            {
                                "windowMs": 120000,
                                "delayAfter": 5,
                                "delayMs": 500,
                                "randomMaxDelayMs": [
                                    7000,
                                    12000
                                ],
                                "headers": false
                            }
                        ]
                    ],
                    "paths": [
                            [
                                "/users/me",
                                {
                                    "profile": "userSpeedLimitProfile"
                                }
                            ]
                        ]
                }
            }
        }
    }

Enable speed limit headers over CORS

Each SpeedLimitService profile has an option to include a set of headers in the response. This can be done by setting the headers option to true in the profile configuration. This operation will add the following headers to the response:

  • X-SlowDown-Limit - the maximum number of requests allowed in the current window
  • X-SlowDown-Remaining - the number of requests remaining in the current window
  • X-SlowDown-Reset - the number of milliseconds remaining until the window resets

Speed limit headers will be available only if the request is made from the same origin. If the request is made from a different origin, the headers will not be included in the response and should be configured to be exposed by CORS.

{
    "settings": {
        "cors": {
            "exposedHeaders": [
                "X-SlowDown-Limit",
                "X-SlowDown-Remaining",
                "X-SlowDown-Reset"
            ]
        }
    }
}

ScopeAccessConfiguration

ScopeAccessConfiguration is a configurable application service for limiting access to service endpoints based on user scopes.

Register service under application services:

{
    "services": [
        {
            "serviceType": "@universis/janitor#ScopeAccessConfiguration"
        }
    ]
}

add <config directory>/scope.access.json and start configuring scope limited endpoints:

[
  {
    "scope": [
      "registrar"
    ],
    "resource": "/api/",
    "access": [
      "read",
      "write"
    ]
  },
  {
    "scope": [
      "students",
      "teachers",
      "registrar"
    ],
    "resource": "/api/workspaces/locales",
    "access": [
      "read"
    ]
  }
]

Each configuration element consists of scope array, resource string and access array. If the user has at least one of the scopes from the scope array, and the user has at least one of the access array, the user will be granted access to the resource.

There are two different access types:

  • read - grants access to read the resource (GET, HEAD, OPTIONS)
  • write - grants access to write the resource (POST, PUT, PATCH, DELETE)

The resource string can be a path or a regular expression e.g. /api/instructors/me/exams/(\d+)/types

validateScope express.js middleware is available for validating user scope access to the resource:

import { validateScope } from '@universis/janitor';
app.use('/api', passport.authenticate('bearer', {session: false}), validateScope(), (req, res) => {
    res.send('Hello World!')
});

A 403 - Access denied due to authorization scopes error will be thrown if the user does not have access to the resource.

RemoteAddressValidator

RemoteAddressValidator is a configurable application service for validating access to service endpoints based on remote address provided by OAuth2 token.

Register service under application services:

{
    "services": [
        {
            "serviceType": "@universis/janitor#RemoteAddressValidator"
        }
    ]
}

RemoteAddressValidator validates the remote address of the request with the remote address provided by the OAuth2 token. If the addresses do not match, a 403 - Access denied due to remote address error will be thrown. Token remote address is provided by the remoteAddress claim in the token payload. It can be configured in the OAuth2 server configuration and may have a different name. This name may be configured in the settings/universis/janitor/remoteAddress configuration e.g.

{
    "settings": {
        "universis": {
            "janitor": {
                "remoteAddress": {
                    "claim": "ipAddress"
                }
            }
        }
    }
}

where claim is the name of the remote address claim in the token payload.

Important Note: If api server is served by a proxy, the remote address may be different from the client address. In this case, the proxy should be configured to forward the client address to the server. This scenario should be configured in application settings under settings/universis/api/ section e.g.

{
    "settings": {
        "universis": {
            "api": {
                "proxyAddressForwarding": true
            }
        }
    }
}

Package Sidebar

Install

npm i @universis/janitor

Weekly Downloads

37

Version

1.6.1

License

LGPL-3.0-or-later

Unpacked Size

204 kB

Total Files

54

Last publish

Collaborators

  • universis