Repository: octokit/oauth-app.js
Pull request #285 (2022-06-03 23:50:46)

build(deps): bump semver-regex from 3.1.3 to 3.1.4
Bumps [semver-regex](https://github.com/sindresorhus/semver-regex) from 3.1.3 to 3.1.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/sindresorhus/semver-regex/releases">semver-regex's releases</a>.</em></p>
<blockquote>
<h2>v3.1.4</h2>
<ul>
<li>Backport of <a href="https://github.com/sindresorhus/semver-regex/releases/tag/v4.0.3">ReDoS fix</a> <a href="https://github.com/sindresorhus/semver-regex/commit/7712ba564d40da101cf2b2b33e6a910d9f2f57f4">https://github.com/sindresorhus/semver-regex/commit/7712ba564d40da101cf2b2b33e6a910d9f2f57f4</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a href="https://github.com/sindresorhus/semver-regex/commits/v3.1.4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=semver-regex&package-manager=npm_and_yarn&previous-version=3.1.3&new-version=3.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/octokit/oauth-app.js/network/alerts).

</details>


Patch:
diff --git a/README.md b/README.md
index dea9403..f20ee87 100644
--- a/README.md
+++ b/README.md
@@ -442,7 +442,6 @@ For the web flow, you have to pass the `code` from URL redirect described in [st
 
 ```js
 const { token } = await app.createToken({
-  state: "state123",
   code: "code123",
 });
 ```
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..0605b07
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,12 @@
+# Security Policy
+
+Thanks for helping make GitHub Open Source Software safe for everyone.
+
+GitHub takes the security of our software products and services seriously, including all of the open source code repositories managed through our GitHub organizations, such as [Octokit](https://github.com/octokit).
+
+Even though [open source repositories are outside of the scope of our bug bounty program](https://bounty.github.com/index.html#scope) and therefore not eligible for bounty rewards, we want to make sure that your finding gets passed along to the maintainers of this project for remediation. 
+
+
+## Reporting a Vulnerability
+
+Since this source is part of [Octokit](https://github.com/octokit) (a GitHub organization) we ask that you follow the guidelines [here](https://github.com/github/.github/blob/master/SECURITY.md#reporting-security-issues) to report anything that you might've found.
diff --git a/package-lock.json b/package-lock.json
index d2eaa7d..69265c5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15115,9 +15115,9 @@
       }
     },
     "node_modules/semver-regex": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz",
-      "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==",
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz",
+      "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==",
       "dev": true,
       "engines": {
         "node": ">=8"
@@ -28242,9 +28242,9 @@
       }
     },
     "semver-regex": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz",
-      "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==",
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz",
+      "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==",
       "dev": true
     },
     "send": {
diff --git a/src/middleware/cloudflare/index.ts b/src/middleware/cloudflare/index.ts
index b1295e1..d79a64b 100644
--- a/src/middleware/cloudflare/index.ts
+++ b/src/middleware/cloudflare/index.ts
@@ -13,8 +13,8 @@ async function onUnhandledRequestDefaultCloudflare(
   return sendResponse(octokitResponse);
 }
 
-export function createCloudflareHandler(
-  app: OAuthApp,
+export function createCloudflareHandler<T>(
+  app: OAuthApp<T>,
   {
     pathPrefix,
     onUnhandledRequest = onUnhandledRequestDefaultCloudflare,
diff --git a/src/middleware/handle-request.ts b/src/middleware/handle-request.ts
index 87f7ca4..671133a 100644
--- a/src/middleware/handle-request.ts
+++ b/src/middleware/handle-request.ts
@@ -1,5 +1,5 @@
 import { OAuthApp } from "../index";
-import { OctokitRequest, OctokitResponse, HandlerOptions } from "./types";
+import { HandlerOptions, OctokitRequest, OctokitResponse } from "./types";
 import { ClientType, Options } from "../types";
 // @ts-ignore - requires esModuleInterop flag
 import fromEntries from "fromentries";
@@ -89,16 +89,13 @@ export async function handleRequest(
           `[@octokit/oauth-app] ${query.error} ${query.error_description}`
         );
       }
-      if (!query.state || !query.code) {
-        throw new Error(
-          '[@octokit/oauth-app] Both "code" & "state" parameters are required'
-        );
+      if (!query.code) {
+        throw new Error('[@octokit/oauth-app] "code" parameter is required');
       }
 
       const {
         authentication: { token },
       } = await app.createToken({
-        state: query.state,
         code: query.code,
       });
 
@@ -114,16 +111,13 @@ export async function handleRequest(
     }
 
     if (route === routes.createToken) {
-      const { state: oauthState, code, redirectUrl } = json;
+      const { code, redirectUrl } = json;
 
-      if (!oauthState || !code) {
-        throw new Error(
-          '[@octokit/oauth-app] Both "code" & "state" parameters are required'
-        );
+      if (!code) {
+        throw new Error('[@octokit/oauth-app] "code" parameter is required');
       }
 
       const result = await app.createToken({
-        state: oauthState,
         code,
         redirectUrl,
       });


Test patch:
diff --git a/test/app.test.ts b/test/app.test.ts
index 1100614..d7a925e 100644
--- a/test/app.test.ts
+++ b/test/app.test.ts
@@ -92,9 +92,7 @@ describe("app", () => {
       clientId: "0123",
       clientSecret: "0123secret",
     });
-    const { url } = app.getWebFlowAuthorizationUrl({
-      state: "state123",
-    });
+    const { url } = app.getWebFlowAuthorizationUrl({ state: "state123" });
     expect(url).toStrictEqual(
       "https://github.com/login/oauth/authorize?allow_signup=true&client_id=0123&state=state123"
     );
@@ -105,9 +103,7 @@ describe("app", () => {
       clientId: "lv1.0123",
       clientSecret: "0123secret",
     });
-    const { url } = app.getWebFlowAuthorizationUrl({
-      state: "state123",
-    });
+    const { url } = app.getWebFlowAuthorizationUrl({ state: "state123" });
     expect(url).toStrictEqual(
       "https://github.com/login/oauth/authorize?allow_signup=true&client_id=lv1.0123&state=state123"
     );
@@ -128,7 +124,6 @@ describe("app", () => {
             client_id: "0123",
             client_secret: "0123secret",
             code: "code123",
-            state: "state123",
           },
         }
       )
@@ -158,7 +153,6 @@ describe("app", () => {
     app.on("token.created", onTokenCallback);
 
     const result = await app.createToken({
-      state: "state123",
       code: "code123",
     });
 
@@ -195,7 +189,6 @@ describe("app", () => {
   it("app.createToken(options) for device flow", async () => {
     const mock = fetchMock
       .sandbox()
-
       .postOnce(
         "https://github.com/login/device/code",
         {
@@ -944,7 +937,6 @@ describe("app", () => {
             client_id: "0123",
             client_secret: "0123secret",
             code: "code123",
-            state: "state123",
           },
         }
       )
@@ -985,7 +977,6 @@ describe("app", () => {
     app.on("token.created", onTokenCallback2);
 
     await app.createToken({
-      state: "state123",
       code: "code123",
     });
 
diff --git a/test/cloudflare-handler.test.ts b/test/cloudflare-handler.test.ts
index 2912054..461c9b4 100644
--- a/test/cloudflare-handler.test.ts
+++ b/test/cloudflare-handler.test.ts
@@ -1,7 +1,7 @@
 import { URL } from "url";
 import * as nodeFetch from "node-fetch";
 import fromEntries from "fromentries";
-import { OAuthApp, createCloudflareHandler } from "../src/";
+import { createCloudflareHandler, OAuthApp } from "../src/";
 
 describe("createCloudflareHandler(app)", () => {
   beforeAll(() => {
@@ -15,6 +15,22 @@ describe("createCloudflareHandler(app)", () => {
     delete (global as any).Response;
   });
 
+  it("support both oauth-app and github-app", () => {
+    const oauthApp = new OAuthApp({
+      clientType: "oauth-app",
+      clientId: "0123",
+      clientSecret: "0123secret",
+    });
+    createCloudflareHandler(oauthApp);
+
+    const githubApp = new OAuthApp({
+      clientType: "github-app",
+      clientId: "0123",
+      clientSecret: "0123secret",
+    });
+    createCloudflareHandler(githubApp);
+  });
+
   it("allow pre-flight requests", async () => {
     const app = new OAuthApp({
       clientId: "0123",
@@ -118,7 +134,6 @@ describe("createCloudflareHandler(app)", () => {
 
     expect(appMock.createToken.mock.calls.length).toEqual(1);
     expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({
-      state: "state123",
       code: "012345",
     });
   });
@@ -141,7 +156,6 @@ describe("createCloudflareHandler(app)", () => {
       method: "POST",
       body: JSON.stringify({
         code: "012345",
-        state: "state123",
         redirectUrl: "http://example.com",
       }),
     });
@@ -154,7 +168,6 @@ describe("createCloudflareHandler(app)", () => {
 
     expect(appMock.createToken.mock.calls.length).toEqual(1);
     expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({
-      state: "state123",
       code: "012345",
       redirectUrl: "http://example.com",
     });
@@ -446,8 +459,7 @@ describe("createCloudflareHandler(app)", () => {
 
     expect(response.status).toEqual(400);
     expect(await response.json()).toStrictEqual({
-      error:
-        '[@octokit/oauth-app] Both "code" & "state" parameters are required',
+      error: '[@octokit/oauth-app] "code" parameter is required',
     });
   });
 
@@ -483,8 +495,7 @@ describe("createCloudflareHandler(app)", () => {
 
     expect(response.status).toEqual(400);
     expect(await response.json()).toStrictEqual({
-      error:
-        '[@octokit/oauth-app] Both "code" & "state" parameters are required',
+      error: '[@octokit/oauth-app] "code" parameter is required',
     });
   });
 
diff --git a/test/node-middleware.test.ts b/test/node-middleware.test.ts
index b2c6db7..bb9fbff 100644
--- a/test/node-middleware.test.ts
+++ b/test/node-middleware.test.ts
@@ -2,7 +2,7 @@ import { createServer } from "http";
 import { URL } from "url";
 
 import fetch from "node-fetch";
-import { OAuthApp, createNodeMiddleware } from "../src/";
+import { createNodeMiddleware, OAuthApp } from "../src/";
 
 // import without types
 const express = require("express");
@@ -152,7 +152,6 @@ describe("createNodeMiddleware(app)", () => {
 
     expect(appMock.createToken.mock.calls.length).toEqual(1);
     expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({
-      state: "state123",
       code: "012345",
     });
   });
@@ -180,7 +179,6 @@ describe("createNodeMiddleware(app)", () => {
         method: "POST",
         body: JSON.stringify({
           code: "012345",
-          state: "state123",
           redirectUrl: "http://example.com",
         }),
       }
@@ -195,7 +193,6 @@ describe("createNodeMiddleware(app)", () => {
 
     expect(appMock.createToken.mock.calls.length).toEqual(1);
     expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({
-      state: "state123",
       code: "012345",
       redirectUrl: "http://example.com",
     });
@@ -571,8 +568,7 @@ describe("createNodeMiddleware(app)", () => {
 
     expect(response.status).toEqual(400);
     expect(await response.json()).toStrictEqual({
-      error:
-        '[@octokit/oauth-app] Both "code" & "state" parameters are required',
+      error: '[@octokit/oauth-app] "code" parameter is required',
     });
   });
 
@@ -619,8 +615,7 @@ describe("createNodeMiddleware(app)", () => {
 
     expect(response.status).toEqual(400);
     expect(await response.json()).toStrictEqual({
-      error:
-        '[@octokit/oauth-app] Both "code" & "state" parameters are required',
+      error: '[@octokit/oauth-app] "code" parameter is required',
     });
   });