-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit adb5443
Showing
11 changed files
with
8,516 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.DS_Store | ||
*.log | ||
.idea | ||
node_modules | ||
coverage | ||
.nyc_output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
test/snapshots/**/*.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
language: node_js | ||
node_js: | ||
- '8' | ||
- '10' | ||
- '12' | ||
script: | ||
npm run test-coverage | ||
after_success: | ||
npm run coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2019 Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/) | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# koa-redirect-loop | ||
|
||
[![build status](https://img.shields.io/travis/com/niftylettuce/koa-redirect-loop.svg)](https://travis-ci.com/niftylettuce/koa-redirect-loop) | ||
[![code coverage](https://img.shields.io/codecov/c/github/niftylettuce/koa-redirect-loop.svg)](https://codecov.io/gh/niftylettuce/koa-redirect-loop) | ||
[![code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) | ||
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) | ||
[![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org) | ||
[![license](https://img.shields.io/github/license/niftylettuce/koa-redirect-loop.svg)](LICENSE) | ||
[![npm downloads](https://img.shields.io/npm/dt/koa-redirect-loop.svg)](https://npm.im/koa-redirect-loop) | ||
|
||
> Prevent redirect loops with sessions since HTTP referrer header is unreliable | ||
> Note that this package only supports `koa-generic-session`, since other packages do not expose a save method used in `res.end` override. | ||
|
||
## Table of Contents | ||
|
||
* [Install](#install) | ||
* [Usage](#usage) | ||
* [Options](#options) | ||
* [Contributors](#contributors) | ||
* [License](#license) | ||
|
||
|
||
## Install | ||
|
||
[npm][]: | ||
|
||
```sh | ||
npm install koa-redirect-loop | ||
``` | ||
|
||
[yarn][]: | ||
|
||
```sh | ||
yarn add koa-redirect-loop | ||
``` | ||
|
||
|
||
## Usage | ||
|
||
```js | ||
const Koa = require('koa'); | ||
const session = require('koa-generic-session'); | ||
const RedirectLoop = require('koa-redirect-loop'); | ||
|
||
const redirectLoop = new RedirectLoop({ | ||
defaultPath: '/', | ||
maxRedirects: 5, | ||
logger: console | ||
}); | ||
|
||
const app = new Koa(); | ||
app.keys = [ 'secret' ]; | ||
|
||
app.use(session()); | ||
app.use(redirectLoop.middleware); | ||
``` | ||
|
||
|
||
## Options | ||
|
||
* `defaultPath` (String) - path to fallback to, defaults to `'/'` | ||
* `maxRedirects` (Number) - maximum number of redirects to allow, defaults to `5` | ||
|
||
|
||
## Contributors | ||
|
||
| Name | Website | | ||
| -------------- | -------------------------- | | ||
| **Nick Baugh** | <http://niftylettuce.com/> | | ||
|
||
|
||
## License | ||
|
||
[MIT](LICENSE) © [Nick Baugh](http://niftylettuce.com/) | ||
|
||
|
||
## | ||
|
||
[npm]: https://www.npmjs.com/ | ||
|
||
[yarn]: https://yarnpkg.com/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const { callbackify } = require('util'); | ||
|
||
const Url = require('url-parse'); | ||
const isSANB = require('is-string-and-not-blank'); | ||
|
||
class RedirectLoop { | ||
constructor(config) { | ||
this.config = { | ||
defaultPath: '/', | ||
maxRedirects: 5, | ||
logger: console, | ||
...config | ||
}; | ||
if (!isSANB(this.config.defaultPath)) | ||
throw new Error('defaultPath must be a String'); | ||
if ( | ||
typeof this.config.maxRedirects !== 'number' || | ||
this.config.maxRedirects <= 0 | ||
) | ||
throw new Error('maxRedirects must be a Number greater than zero'); | ||
this.middleware = this.middleware.bind(this); | ||
} | ||
|
||
middleware(ctx, next) { | ||
if (!ctx.session) return ctx.throw(new Error('Sessions required')); | ||
if (typeof ctx.saveSession !== 'function') | ||
throw new Error( | ||
'Please use koa-generic-session v2.0.3+ which exposes a `ctx.saveSession()` method' | ||
); | ||
|
||
const { config } = this; | ||
const { redirect } = ctx; | ||
const { end } = ctx.res; | ||
|
||
ctx.res.end = function(chunk, encoding) { | ||
// instead of `!req.xhr` we need to use !accepts HTML | ||
// because Fetch does not provide XMLHttpRequest | ||
if (ctx.accepts('html')) { | ||
ctx.session.prevPrevPath = ctx.session.prevPath; | ||
ctx.session.prevPath = ctx.originalUrl; | ||
ctx.session.prevMethod = ctx.method; | ||
// if it was a redirect then store how many times | ||
// so that we can limit the max number of redirects | ||
if ([301, 302].includes(ctx.res.statusCode)) | ||
ctx.session.maxRedirects = | ||
typeof ctx.session.maxRedirects === 'number' | ||
? ctx.session.maxRedirects + 1 | ||
: 1; | ||
else ctx.session.maxRedirects = 0; | ||
} | ||
|
||
callbackify(ctx.saveSession)(err => { | ||
if (err) { | ||
if (ctx.logger && ctx.logger.error) ctx.logger.error(err); | ||
else config.logger.error(err); | ||
} | ||
|
||
end.call(ctx.res, chunk, encoding); | ||
}); | ||
}; | ||
|
||
ctx.redirect = function(url, alt) { | ||
let address = url; | ||
|
||
if (url === 'address') address = ctx.get('Referrer') || alt || '/'; | ||
|
||
const prevPrevPath = ctx.session.prevPrevPath || config.defaultPath; | ||
const prevPath = ctx.session.prevPath || config.defaultPath; | ||
const prevMethod = ctx.session.prevMethod || ctx.method; | ||
const maxRedirects = ctx.session.maxRedirects || 1; | ||
|
||
if (prevPath && address === prevPath && ctx.method === prevMethod) { | ||
if ( | ||
prevPrevPath && | ||
address !== prevPrevPath && | ||
maxRedirects <= config.maxRedirects | ||
) { | ||
address = prevPrevPath; | ||
} else { | ||
// if the prevPrevPath w/o querystring is !== prevPrevPath | ||
// then redirect then to prevPrevPath w/o querystring | ||
const { pathname } = new Url(prevPrevPath, {}); | ||
if (pathname === prevPrevPath) address = '/'; | ||
else address = pathname; | ||
} | ||
} else if (maxRedirects > config.maxRedirects) { | ||
address = config.defaultPath; | ||
} | ||
|
||
redirect.call(this, address, alt); | ||
}; | ||
|
||
return next(); | ||
} | ||
} | ||
|
||
module.exports = RedirectLoop; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
{ | ||
"name": "koa-redirect-loop", | ||
"description": "Prevent redirect loops with sessions since HTTP referrer header is unreliable", | ||
"version": "0.0.0", | ||
"author": "Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)", | ||
"ava": { | ||
"serial": true, | ||
"failFast": true, | ||
"verbose": true | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/niftylettuce/koa-redirect-loop/issues", | ||
"email": "niftylettuce@gmail.com" | ||
}, | ||
"commitlint": { | ||
"extends": [ | ||
"@commitlint/config-conventional" | ||
] | ||
}, | ||
"contributors": [ | ||
"Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)" | ||
], | ||
"dependencies": { | ||
"is-string-and-not-blank": "^0.0.2", | ||
"url-parse": "^1.4.7" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "latest", | ||
"@commitlint/config-conventional": "latest", | ||
"@koa/router": "^8.0.5", | ||
"ava": "latest", | ||
"cabin": "^5.0.13", | ||
"codecov": "latest", | ||
"cross-env": "latest", | ||
"eslint": "latest", | ||
"eslint-config-xo-lass": "latest", | ||
"fetch-cookie": "^0.7.3", | ||
"fixpack": "latest", | ||
"husky": "latest", | ||
"koa": "^2.11.0", | ||
"koa-better-error-handler": "^3.0.3", | ||
"koa-generic-session": "^2.0.3", | ||
"lint-staged": "latest", | ||
"node-fetch": "^2.6.0", | ||
"nyc": "latest", | ||
"remark-cli": "latest", | ||
"remark-preset-github": "latest", | ||
"xo": "latest" | ||
}, | ||
"engines": { | ||
"node": ">=8.3" | ||
}, | ||
"homepage": "https://github.com/niftylettuce/koa-redirect-loop", | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged && npm test", | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"keywords": [ | ||
"back", | ||
"bug", | ||
"connect", | ||
"endless", | ||
"express", | ||
"fix", | ||
"header", | ||
"helper", | ||
"hotfix", | ||
"http", | ||
"koa", | ||
"loop", | ||
"middleware", | ||
"patch", | ||
"plugin", | ||
"prevent", | ||
"prevention", | ||
"recursive", | ||
"redirect", | ||
"redirecting", | ||
"redirection", | ||
"referer", | ||
"referrer", | ||
"route", | ||
"session" | ||
], | ||
"license": "MIT", | ||
"lint-staged": { | ||
"*.js": [ | ||
"xo --fix", | ||
"git add" | ||
], | ||
"*.md": [ | ||
"remark . -qfo", | ||
"git add" | ||
], | ||
"package.json": [ | ||
"fixpack", | ||
"git add" | ||
] | ||
}, | ||
"main": "index.js", | ||
"prettier": { | ||
"singleQuote": true, | ||
"bracketSpacing": true, | ||
"trailingComma": "none" | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-github" | ||
] | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/niftylettuce/koa-redirect-loop" | ||
}, | ||
"scripts": { | ||
"ava": "cross-env NODE_ENV=test ava", | ||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", | ||
"lint": "xo && remark . -qfo", | ||
"nyc": "cross-env NODE_ENV=test nyc ava", | ||
"test": "npm run lint && npm run ava", | ||
"test-coverage": "npm run lint && npm run nyc" | ||
}, | ||
"xo": { | ||
"prettier": true, | ||
"space": true, | ||
"extends": [ | ||
"xo-lass" | ||
] | ||
} | ||
} |
Oops, something went wrong.