{"id":22253361,"url":"https://github.com/indr/adonis-rate-limiter","last_synced_at":"2025-10-14T13:33:17.171Z","repository":{"id":57173591,"uuid":"71015534","full_name":"indr/adonis-rate-limiter","owner":"indr","description":"Rate limiter for AdonisJs framework using Redis","archived":false,"fork":false,"pushed_at":"2016-10-16T14:23:17.000Z","size":12,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T13:33:02.178Z","etag":null,"topics":["adonisjs-framework","middleware","rate-limiting","redis"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/indr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-15T21:54:08.000Z","updated_at":"2022-05-08T12:45:38.000Z","dependencies_parsed_at":"2022-08-24T14:40:45.348Z","dependency_job_id":null,"html_url":"https://github.com/indr/adonis-rate-limiter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/indr/adonis-rate-limiter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indr%2Fadonis-rate-limiter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indr%2Fadonis-rate-limiter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indr%2Fadonis-rate-limiter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indr%2Fadonis-rate-limiter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/indr","download_url":"https://codeload.github.com/indr/adonis-rate-limiter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indr%2Fadonis-rate-limiter/sbom","scorecard":{"id":487505,"data":{"date":"2025-08-11","repo":{"name":"github.com/indr/adonis-rate-limiter","commit":"73fd0b6b619bba4334e32a40b9ee1592b8b92105"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-19T18:10:54.300Z","repository_id":57173591,"created_at":"2025-08-19T18:10:54.300Z","updated_at":"2025-08-19T18:10:54.300Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018707,"owners_count":26086609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adonisjs-framework","middleware","rate-limiting","redis"],"created_at":"2024-12-03T07:18:01.374Z","updated_at":"2025-10-14T13:33:17.153Z","avatar_url":"https://github.com/indr.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# adonis-rate-limiter\n\n[![npm version](https://badge.fury.io/js/adonis-rate-limiter.svg)](https://badge.fury.io/js/adonis-rate-limiter)\n[![Build Status](https://travis-ci.org/indr/adonis-rate-limiter.svg?branch=master)](https://travis-ci.org/indr/adonis-rate-limiter)\n[![dependencies Status](https://david-dm.org/indr/adonis-rate-limiter/status.svg)](https://david-dm.org/indr/adonis-rate-limiter)\n[![devDependencies Status](https://david-dm.org/indr/adonis-rate-limiter/dev-status.svg)](https://david-dm.org/indr/adonis-rate-limiter?type=dev)\n[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n\nRate limiter for AdonisJs framework using Redis.\n\n## Installation\n\nIn order to use adonis-rate-limiter you need to have [adonis-redis](https://github.com/adonisjs/adonis-redis) installed and configured.\n\n```\nnpm install adonis-rate-limiter --save\n```\n\nAfter installation, you need to register the provider and an optional alias inside `bootstrap/app.js` file.\n\n```javascript\n// bootstrap/app.js\n\nconst providers = [\n  ...,\n  'adonis-rate-limiter/providers/RateLimiterProvider'\n]\n\nconst aliases = [\n  ...,\n  RateLimiter: 'Adonis/Addons/RateLimiter',\n]\n```\n\n## Usage\n\n### Rate limit a specific action\n\nUse the `RateLimiter` provider to limit an action for a given subject (eg. IP address, user id) and period.\n\nThe following example mitigates brute force attacks by limiting the number of login attempts for an IP address to 6 attempts per minute and 30 attempts per hour.\n\n```javascript\n// app/Http/Controllers/AuthController.js\n\nconst RateLimiter = use('RateLimiter')\n\nclass AuthController {\n\n  * login (request, response) {\n    const ipAddress = request.request.socket.remoteAddress\n    yield RateLimiter.perform(ipAddress, 'login-min', 6, 60)\n    yield RateLimiter.perform(ipAddress, 'login-hr', 30, 3600)\n    \n    ...\n  }\n}\n```\n\nIf the subject exceeds the maximum number a `RateLimitExceededException` is thrown. The exception contains these properties:\n\n * `message`: The action key in the format `{key}-rate-limit-exceeded`, eg. `login-min-rate-limit-exceeded`\n * `secondsToWait`: The number of seconds the subject has to wait until it can perform the action again\n * `status`: 429 (HTTP status code for too many requests)\n \nYou can conveniently handle this exception in your HTTP exception handler like this:\n\n```javascript\n  RateLimitExceededException: function (error, request, response) {\n    const status = error.status || 429\n    const message = error.message || 'Rate limit exceeded'\n    return { status, message }\n  }\n```\n\nHave a look at [app/Services/ExceptionParser.js](https://github.com/adonisjs/adonis-rally/blob/develop/app/Services/ExceptionParser.js) of the Adonis Rally project.\n\n### Auto IP ban\n\nThe following middleware automatically blocks an IP address after a number of requests that resulted in a response status code equal to or above 400.\n\n```javascript\n// app/Http/Middleware/AutoIpBan.js\n\nconst RateLimiter = use('RateLimiter')\n\nclass AutoIpBan {\n  * handle (request, response, next) {\n    const ipAddress = request.request.socket.remoteAddress\n    const minuteLimiter = RateLimiter.make(ipAddress, 'auto-ip-ban-min', 10, 60)\n    const hourLimiter = RateLimiter.make(ipAddress, 'auto-ip-ban-hr', 60, 3600)\n\n    if ((yield minuteLimiter.isUnderLimit()) \u0026\u0026 (yield hourLimiter.isUnderLimit())) {\n      yield next\n    } else {\n      response.tooManyRequests({ status: 429, message: 'Too many suspicious requests' })\n      return\n    }\n\n    if (response.response.statusCode \u003e= 400) {\n      yield minuteLimiter.add()\n      yield hourLimiter.add()\n    }\n  }\n}\n\nmodule.exports = AutoIpBan\n```\n\nYou might want to add this middleware to your list of global middlware before `Cors`:\n\n```javascript\n// app/Http/kernel.js\n\nconst globalMiddleware = [\n  'App/Http/Middleware/AutoIpBan',\n  'Adonis/Middleware/Cors',\n  ...\n]\n```\n\n## Changelog\n\n[CHANGELOG](CHANGELOG.md)\n\n## Credits\n\nThanks to the guys behind [discourse](https://github.com/discourse/discourse) and their implementation of a rate limiter from which I have borrowed a great part.\n\n## Copyright and License\n\nCopyright (c) 2016 Reto Inderbitzin, [MIT](LICENSE.md) License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findr%2Fadonis-rate-limiter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Findr%2Fadonis-rate-limiter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findr%2Fadonis-rate-limiter/lists"}