Skip to content

Commit

Permalink
Merge pull request #24 from aiji42/fail-safe-option-on-ip-inspect
Browse files Browse the repository at this point in the history
Fail safe option on ip inspect
  • Loading branch information
aiji42 authored Aug 6, 2021
2 parents 70e6042 + 90b01da commit 3ec80c8
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ module.exports = withPlugins([
### When controlling by IP
Control by IP of access source (x-forwarded-for).
Control by IP of request source (x-forwarded-for).
Specify the IPs to be allowed as a string or an array of strings, which can be written in CIDR format.
```js
Expand All @@ -89,12 +89,19 @@ const withFortress = require('next-fortress')({
{
inspectBy: 'ip',
ips: ['11.22.33.0/24', '111.222.0.0/16'], // It can be written in CIDR format.
failSafe: true, // See description below.
// ...controlMode
}
]
})
```
It uses `x-forwarded-for` to get the IP of the requestor. Therefore, it is not possible to control by IP in the development environment.
You can use `failSafe` to control whether the request is controlled or passed through in the case that such an IP could not be gotten.
- `failSafe?: boolean`: The default value is `process.env.NODE_ENV === 'production'`.
- `true`: If it fails to get the IP, it must control the request according to the control mode.
- `false`: If it fails to get the IP, the request will be passed through.
#### Redirect
```js
const withFortress = require('next-fortress')({
Expand All @@ -113,7 +120,7 @@ const withFortress = require('next-fortress')({
})
```
#### Access Block
#### Request Block
```js
const withFortress = require('next-fortress')({
forts: [
Expand Down Expand Up @@ -173,7 +180,7 @@ const withFortress = require('next-fortress')({
**Control Mode**
- `redirect`: See [Redirect](#redirect)
- `block`: See [Access Block](#access-block)
- `block`: See [Request Block](#request-block)
- `rewrite`: See [Rewrite](#rewrite)
Put useFortressWithFirebase in your page/_app.jsx.
Expand Down Expand Up @@ -211,7 +218,7 @@ const withFortress = require('next-fortress')({
**Control Mode**
- `redirect`: See [Redirect](#redirect)
- `block`: See [Access Block](#access-block)
- `block`: See [Request Block](#request-block)
- `rewrite`: See [Rewrite](#rewrite)
Add `ssr: true` to the client side `Amplify.configure`.
Expand Down Expand Up @@ -243,7 +250,7 @@ const withFortress = require('next-fortress')({
**Control Mode**
- `redirect`: See [Redirect](#redirect)
- `block`: See [Access Block](#access-block)
- `block`: See [Request Block](#request-block)
- `rewrite`: See [Rewrite](#rewrite)
---
Expand Down Expand Up @@ -307,7 +314,7 @@ const withFortress = require('next-fortress')({
## :construction: Caution
**Please do not use `next/link` to generate links to pages subject to access control.**
**Please do not use `next/link` to generate links to pages you want to control access to.**
The link tag generated by `next/link` will request the target page for a js file when clicked. Unfortunately, it is not possible to control access to that URL.
Expand Down
33 changes: 32 additions & 1 deletion src/__tests__/ip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { inspectIp, ip } from '../ip'
import { Fort } from '../types'
import { GetServerSidePropsContext } from 'next'

const OLD_ENV = { ...process.env }

describe('ip', () => {
test('inspectIp', () => {
expect(inspectIp('123.1.1.1', undefined)).toEqual(false)
Expand All @@ -18,6 +20,9 @@ describe('ip', () => {
})

describe('ip', () => {
beforeAll(() => {
process.env = { ...OLD_ENV }
})
test('"inspectBy" is not "ip"', () => {
return ip(
{ inspectBy: 'firebase' } as Fort,
Expand All @@ -34,13 +39,39 @@ describe('ip', () => {
} as unknown as GetServerSidePropsContext
).then((res) => expect(res).toEqual(true))
})
test('"headers" dose not have "x-forwarded-for"', () => {
test('"headers" dose not have "x-forwarded-for" and failSafe is set true', () => {
return ip(
{ inspectBy: 'ip', failSafe: true } as Fort,
{
req: { headers: {} }
} as unknown as GetServerSidePropsContext
).then((res) => expect(res).toEqual(false))
})
test('"headers" dose not have "x-forwarded-for" and failSafe is set false', () => {
return ip(
{ inspectBy: 'ip', failSafe: false } as Fort,
{
req: { headers: {} }
} as unknown as GetServerSidePropsContext
).then((res) => expect(res).toEqual(true))
})
test('"headers" dose not have "x-forwarded-for" and failSafe is Not set when runs on production', () => {
process.env.NODE_ENV = 'production'
return ip(
{ inspectBy: 'ip' } as Fort,
{
req: { headers: {} }
} as unknown as GetServerSidePropsContext
).then((res) => expect(res).toEqual(false))
})
test('"headers" dose not have "x-forwarded-for" and failSafe is Not set when runs on NOT production', () => {
process.env.NODE_ENV = 'development'
return ip(
{ inspectBy: 'ip' } as Fort,
{
req: { headers: {} }
} as unknown as GetServerSidePropsContext
).then((res) => expect(res).toEqual(true))
})
})
})
6 changes: 4 additions & 2 deletions src/ip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const inspectIp = (
}

export const ip: Operator = async (fort, ctx) => {
if (fort.inspectBy !== 'ip' || !ctx.req.headers['x-forwarded-for'])
return false
if (fort.inspectBy !== 'ip') return false
if (!ctx.req.headers['x-forwarded-for'])
return !(fort.failSafe ?? process.env.NODE_ENV === 'production')

return inspectIp(fort.ips, ctx.req.headers['x-forwarded-for'])
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GetServerSidePropsContext } from 'next'
export type InspectByIp = {
inspectBy: 'ip'
ips: string | Array<string>
failSafe?: boolean
}

export type InspectByFirebase = {
Expand Down

1 comment on commit 3ec80c8

@vercel
Copy link

@vercel vercel bot commented on 3ec80c8 Aug 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.