npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@universis/janitor

v1.6.1

Published

Universis api plugin for rate limiting requests

Downloads

236

Readme

@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
            }
        }
    }
}