@graphql-yoga/plugin-csrf-prevention 3.0.2 → 3.1.1-alpha-20240101184114-61b4f2f6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.js CHANGED
@@ -2,6 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCSRFPrevention = void 0;
4
4
  const graphql_yoga_1 = require("graphql-yoga");
5
+ const NON_PREFLIGHTED_CONTENT_TYPES = [
6
+ 'application/x-www-form-urlencoded',
7
+ 'multipart/form-data',
8
+ 'text/plain',
9
+ ];
5
10
  /**
6
11
  * If you have CORS enabled, almost all requests coming from the browser will have a
7
12
  * preflight request - however, some requests are deemed "simple" and don't make a preflight.
@@ -17,16 +22,26 @@ function useCSRFPrevention(options = {}) {
17
22
  const { requestHeaders = ['x-graphql-yoga-csrf'] } = options;
18
23
  return {
19
24
  async onRequestParse({ request }) {
20
- if (!requestHeaders.some(headerName => request.headers.has(headerName))) {
21
- throw (0, graphql_yoga_1.createGraphQLError)('Required CSRF header(s) not present', {
22
- extensions: {
23
- http: {
24
- status: 403,
25
- },
26
- },
27
- });
25
+ if (wasTheRequestAlreadyPreflightChecked(request.headers?.get('content-type'))) {
26
+ return;
27
+ }
28
+ if (requestHeaders.some(headerName => request.headers.has(headerName))) {
29
+ return;
28
30
  }
31
+ throw (0, graphql_yoga_1.createGraphQLError)('Required CSRF header(s) not present', {
32
+ extensions: {
33
+ http: {
34
+ status: 403,
35
+ },
36
+ },
37
+ });
29
38
  },
30
39
  };
31
40
  }
32
41
  exports.useCSRFPrevention = useCSRFPrevention;
42
+ const wasTheRequestAlreadyPreflightChecked = (contentType) => {
43
+ if (!contentType) {
44
+ return false;
45
+ }
46
+ return !NON_PREFLIGHTED_CONTENT_TYPES.some(nonPreflightContentType => contentType.toLowerCase().startsWith(nonPreflightContentType));
47
+ };
package/esm/index.js CHANGED
@@ -1,4 +1,9 @@
1
1
  import { createGraphQLError } from 'graphql-yoga';
2
+ const NON_PREFLIGHTED_CONTENT_TYPES = [
3
+ 'application/x-www-form-urlencoded',
4
+ 'multipart/form-data',
5
+ 'text/plain',
6
+ ];
2
7
  /**
3
8
  * If you have CORS enabled, almost all requests coming from the browser will have a
4
9
  * preflight request - however, some requests are deemed "simple" and don't make a preflight.
@@ -14,15 +19,25 @@ export function useCSRFPrevention(options = {}) {
14
19
  const { requestHeaders = ['x-graphql-yoga-csrf'] } = options;
15
20
  return {
16
21
  async onRequestParse({ request }) {
17
- if (!requestHeaders.some(headerName => request.headers.has(headerName))) {
18
- throw createGraphQLError('Required CSRF header(s) not present', {
19
- extensions: {
20
- http: {
21
- status: 403,
22
- },
23
- },
24
- });
22
+ if (wasTheRequestAlreadyPreflightChecked(request.headers?.get('content-type'))) {
23
+ return;
24
+ }
25
+ if (requestHeaders.some(headerName => request.headers.has(headerName))) {
26
+ return;
25
27
  }
28
+ throw createGraphQLError('Required CSRF header(s) not present', {
29
+ extensions: {
30
+ http: {
31
+ status: 403,
32
+ },
33
+ },
34
+ });
26
35
  },
27
36
  };
28
37
  }
38
+ const wasTheRequestAlreadyPreflightChecked = (contentType) => {
39
+ if (!contentType) {
40
+ return false;
41
+ }
42
+ return !NON_PREFLIGHTED_CONTENT_TYPES.some(nonPreflightContentType => contentType.toLowerCase().startsWith(nonPreflightContentType));
43
+ };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@graphql-yoga/plugin-csrf-prevention",
3
- "version": "3.0.2",
3
+ "version": "3.1.1-alpha-20240101184114-61b4f2f6",
4
4
  "description": "CSRF prevention plugin for GraphQL Yoga that requires the clients to have a specific header set.",
5
5
  "peerDependencies": {
6
- "graphql-yoga": "^5.0.2"
6
+ "graphql-yoga": "^5.1.0"
7
7
  },
8
8
  "repository": {
9
9
  "type": "git",