Skip to content

Commit

Permalink
feat: add redirectUrl as a constructor option (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
SayakMukhopadhyay authored Dec 6, 2022
1 parent 22bf430 commit adb57e6
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 25 deletions.
63 changes: 38 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,33 @@

<!-- toc -->

- [Usage](#usage)
- [For OAuth Apps](#for-oauth-apps)
- [For GitHub Apps](#for-github-apps)
- [Examples](#examples)
- [`OAuthApp.defaults(options)`](#oauthappdefaultsoptions)
- [Constructor options](#constructor-options)
- [`app.on(eventName, eventHandler)`](#apponeventname-eventhandler)
- [`app.octokit`](#appoctokit)
- [`app.getUserOctokit(options)`](#appgetuseroctokitoptions)
- [`app.getWebFlowAuthorizationUrl(options)`](#appgetwebflowauthorizationurloptions)
- [`app.createToken(options)`](#appcreatetokenoptions)
- [For OAuth Web flow](#for-oauth-web-flow)
- [For OAuth Device flow](#for-oauth-device-flow)
- [`app.checkToken(options)`](#appchecktokenoptions)
- [`app.resetToken(options)`](#appresettokenoptions)
- [`app.refreshToken(options)`](#apprefreshtokenoptions)
- [`app.scopeToken(options)`](#appscopetokenoptions)
- [`app.deleteToken(options)`](#appdeletetokenoptions)
- [`app.deleteAuthorization(options)`](#appdeleteauthorizationoptions)
- [Middlewares](#middlewares)
- [`createNodeMiddleware(app, options)`](#createnodemiddlewareapp-options)
- [`createWebWorkerHandler(app, options)`](#createwebworkerhandlerapp-options)
- [`createAWSLambdaAPIGatewayV2Handler(app, options)`](#createawslambdaapigatewayv2handlerapp-options)
- [Contributing](#contributing)
- [License](#license)
- [oauth-app.js](#oauth-appjs)
- [Usage](#usage)
- [For OAuth Apps](#for-oauth-apps)
- [For GitHub Apps](#for-github-apps)
- [Examples](#examples)
- [`OAuthApp.defaults(options)`](#oauthappdefaultsoptions)
- [Constructor options](#constructor-options)
- [`app.on(eventName, eventHandler)`](#apponeventname-eventhandler)
- [`app.octokit`](#appoctokit)
- [`app.getUserOctokit(options)`](#appgetuseroctokitoptions)
- [`app.getWebFlowAuthorizationUrl(options)`](#appgetwebflowauthorizationurloptions)
- [`app.createToken(options)`](#appcreatetokenoptions)
- [For OAuth Web flow](#for-oauth-web-flow)
- [For OAuth Device flow](#for-oauth-device-flow)
- [`app.checkToken(options)`](#appchecktokenoptions)
- [`app.resetToken(options)`](#appresettokenoptions)
- [`app.refreshToken(options)`](#apprefreshtokenoptions)
- [`app.scopeToken(options)`](#appscopetokenoptions)
- [`app.deleteToken(options)`](#appdeletetokenoptions)
- [`app.deleteAuthorization(options)`](#appdeleteauthorizationoptions)
- [Middlewares](#middlewares)
- [`createNodeMiddleware(app, options)`](#createnodemiddlewareapp-options)
- [`createWebWorkerHandler(app, options)`](#createwebworkerhandlerapp-options)
- [`createAWSLambdaAPIGatewayV2Handler(app, options)`](#createawslambdaapigatewayv2handlerapp-options)
- [Build Custom Middlewares](#build-custom-middlewares)
- [Contributing](#contributing)
- [License](#license)

<!-- tocstop -->

Expand Down Expand Up @@ -188,6 +190,17 @@ const app = new MyOAuthApp({ clientId, clientSecret });
Sets the default value for <code>app.getWebFlowAuthorizationUrl(options)</code>.
</td>
</tr>
<tr>
<th>
<code>redirectUrl</code>
</th>
<th>
<code>string</code>
</th>
<td>
The URL in your application where users will be sent after authorization. See <a href="https://docs.github.com/en/developers/apps/authorizing-oauth-apps#redirect-urls">Redirect URLs</a> in GitHub’s Developer Guide.
</td>
</tr>
<tr>
<th>
<code>defaultScopes</code>
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class OAuthApp<
defaultScopes: options.defaultScopes || [],
allowSignup: options.allowSignup,
baseUrl: options.baseUrl,
redirectUrl: options.redirectUrl,
log: options.log,
Octokit,
octokit,
Expand Down
1 change: 1 addition & 0 deletions src/methods/get-web-flow-authorization-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function getWebFlowAuthorizationUrlWithState(
request: state.octokit.request,
...options,
allowSignup,
redirectUrl: options.redirectUrl || state.redirectUrl,
scopes: options.scopes || state.defaultScopes,
};

Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type CommonOptions<TOctokit extends OAuthAppOctokitClassType> = {
clientSecret?: ClientSecret;
allowSignup?: boolean;
baseUrl?: string;
redirectUrl?: string;
log?: typeof console;
Octokit?: TOctokit;
};
Expand Down Expand Up @@ -82,6 +83,7 @@ export type State = {
defaultScopes: Scope[];
allowSignup?: boolean;
baseUrl?: string;
redirectUrl?: string;
log?: typeof console;
Octokit: OAuthAppOctokitClassType;
octokit: OctokitInstance;
Expand Down
67 changes: 67 additions & 0 deletions test/node-middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1080,4 +1080,71 @@ describe("createNodeMiddleware(app)", () => {
expect(url.searchParams.get("state")).toMatch(/^\w+$/);
expect(url.searchParams.get("allow_signup")).toEqual("true");
});

it("GET /api/github/oauth/login?redirectUrl=http://localhost:12345 with redirectUrl option not set", async () => {
const app = new OAuthApp({
clientId: "0123",
clientSecret: "0123secret",
});

const server = createServer(createNodeMiddleware(app)).listen();
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
const { port } = server.address();

const { status, headers } = await fetch(
`http://localhost:${port}/api/github/oauth/login?redirectUrl=http://localhost:12345`,
{
redirect: "manual",
}
);

server.close();

expect(status).toEqual(302);

const url = new URL(headers.get("location") as string);
expect(url).toMatchObject({
origin: "https://github.com",
pathname: "/login/oauth/authorize",
});
expect(url.searchParams.get("client_id")).toEqual("0123");
expect(url.searchParams.get("state")).toMatch(/^\w+$/);
expect(url.searchParams.get("redirect_uri")).toEqual(
"http://localhost:12345"
);
});

it("GET /api/github/oauth/login with redirectUrl option set to http://localhost:1234", async () => {
const app = new OAuthApp({
clientId: "0123",
clientSecret: "0123secret",
redirectUrl: "http://localhost:12345",
});

const server = createServer(createNodeMiddleware(app)).listen();
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
const { port } = server.address();

const { status, headers } = await fetch(
`http://localhost:${port}/api/github/oauth/login`,
{
redirect: "manual",
}
);

server.close();

expect(status).toEqual(302);

const url = new URL(headers.get("location") as string);
expect(url).toMatchObject({
origin: "https://github.com",
pathname: "/login/oauth/authorize",
});
expect(url.searchParams.get("client_id")).toEqual("0123");
expect(url.searchParams.get("state")).toMatch(/^\w+$/);
expect(url.searchParams.get("redirect_uri")).toEqual(
"http://localhost:12345"
);
});
});

0 comments on commit adb57e6

Please sign in to comment.