Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0.10 #27

Merged
merged 3 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"root": true,
"plugins": [
"@typescript-eslint"
],
"extends": [
"airbnb",
"airbnb-typescript",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"ignorePatterns": [
],
"rules": {
"max-classes-per-file": "off",
"max-len": "off",
"no-await-in-loop": "off",
"no-restricted-syntax": "off",
"no-underscore-dangle": "off",
"object-curly-newline": "off"
}
}
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: ci

on:
pull_request:
branches:
- '**'

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm install
- run: pnpm lint

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm install
- run: pnpm test run

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm install
- run: pnpm build
27 changes: 27 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: publish

on:
push:
tags:
- '**'

jobs:
publish:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm install
- run: pnpm build
- run: pnpm publish --no-git-checks --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
File renamed without changes.
52 changes: 42 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Edge-CSRF is CSRF protection for [Next.js](https://nextjs.org/) that runs in mid

This library uses the cookie strategy from [expressjs/csurf](https://github.com/expressjs/csurf) and the crypto logic from [pillarjs/csrf](https://github.com/pillarjs/csrf) except it only uses Next.js edge runtime dependencies so it can be used in [Next.js middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware).

# Features
## Features

- Supports app-router and pages-router Next.js 13 and Next.js 14
- Runs in edge runtime
Expand All @@ -16,11 +16,11 @@ This library uses the cookie strategy from [expressjs/csurf](https://github.com/

**Note: There's an issue with Next.js middleware in v13.3.X and v13.4.X that prevents edge-csrf from working properly with the pages-router in a dev environment (https://github.com/vercel/next.js/issues/48083, https://github.com/vercel/next.js/issues/48546)**

# Quickstart
## Quickstart

To use Edge-CSRF, first add it as a dependency to your app:

```bash
```console
npm install edge-csrf
# or
pnpm add edge-csrf
Expand Down Expand Up @@ -61,7 +61,7 @@ export async function middleware(request: NextRequest) {

Now, all HTTP submission requests (e.g. POST, PUT, DELETE, PATCH) will be rejected if they do not include a valid CSRF token. To add the CSRF token to your forms, you can fetch it from the `X-CSRF-Token` HTTP response header server-side or client-side. For example:

## App Router
### App Router

```typescript
// app/page.tsx
Expand Down Expand Up @@ -91,7 +91,7 @@ export async function POST() {
}
```

## Pages Router
### Pages Router

```typescript
// pages/form.ts
Expand Down Expand Up @@ -136,7 +136,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse<Data>)
}
```

# Examples
## Examples

See more examples in the [examples](examples) directory in this repository:

Expand All @@ -154,11 +154,11 @@ See more examples in the [examples](examples) directory in this repository:
| 14 | app | [Server action (non-form)](examples/next14-approuter-server-action-non-form-submission) |
| 14 | pages | [HTML form](examples/next14-pagesrouter-html-submission) |

# Server Actions
## Server Actions

Edge-CSRF supports server actions with both form and non-form submission in the latest version of Next.js (14).

## Form Submission
### Form Submission

With server actions that get executed via form submission, you can add the CSRF token as a hidden field to the form ([see example](examples/next14-approuter-server-action-form-submission)):

Expand Down Expand Up @@ -188,7 +188,7 @@ export default function Page() {
}
```

## Non-Form Submission
### Non-Form Submission

With server actions that get executed by JavaScript calls (non-form), you can pass the CSRF token as the first argument to the function ([see example](examples/next14-approuter-server-action-non-form-submission)):

Expand Down Expand Up @@ -231,7 +231,7 @@ export default function Page() {
}
```

# Configuration
## Configuration

To configure the CSRF middleware function just pass an object containing your options to the initialization method:

Expand Down Expand Up @@ -269,3 +269,35 @@ Here are the default configuration values:
}
}
```

## Development

### Get the code

To develop edge-csrf, first clone the repository then install the dependencies:

```console
git clone [email protected]:kubetail-org/edge-csrf.git
cd edge-csrf
pnpm install
```

### Run the unit tests

Edge-CSRF uses jest for testing (via vitest). To run the tests, use the `test` command:

```console
pnpm test
```

The test files are colocated with the source code in the `src/` directory, with the filename format `{name}.test.ts`.

### Build for production

To build Edge-CSRF for production, run the `build` command:

```console
pnpm build
```

The production files will be located in the `dist/` directory.
48 changes: 22 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,39 @@
{
"name": "edge-csrf",
"description": "CSRF protection for Next.js middleware",
"version": "1.0.9",
"version": "1.0.10-rc1",
"author": "Andres Morey",
"license": "MIT",
"repository": "kubetail-org/edge-csrf",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/cjs/index.d.ts",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.js",
"files": [
"/dist"
],
"scripts": {
"bench": "node --experimental-specifier-resolution=node",
"build": "rm -rf dist && tsc && tsc --build tsconfig.cjs.json",
"lint": "eslint",
"test": "jest --env @edge-runtime/jest-environment"
"build": "tsc && vite build",
"lint": "eslint \"./src/**/*.ts{,x}\"",
"test": "vitest"
},
"devDependencies": {
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@edge-runtime/jest-environment": "^2.3.6",
"@edge-runtime/primitives": "^4.0.4",
"@jest/types": "^29.6.3",
"@types/jest": "^29.5.6",
"@types/node": "^20.8.9",
"@types/react": "^18.2.33",
"@types/react-dom": "^18.2.14",
"babel-jest": "^29.7.0",
"beautify-benchmark": "^0.2.4",
"benchmark": "^2.1.4",
"eslint": "^8.52.0",
"jest": "^29.7.0",
"next": "^14.0.1",
"@edge-runtime/vm": "^3.2.0",
"@rollup/plugin-typescript": "^11.1.6",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.5",
"@types/react": "^18.2.74",
"@types/react-dom": "^18.2.24",
"@typescript-eslint/eslint-plugin": "^7.6.0",
"@typescript-eslint/parser": "^7.6.0",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^18.0.0",
"next": "^14.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
"typescript": "^5.4.4",
"vite": "^5.2.8",
"vitest": "^1.4.0"
},
"peerDependencies": {
"next": "^13.0.0 || ^14.0.0"
Expand Down
Loading