An open API service indexing awesome lists of open source software.

https://github.com/octokit/oauth-methods.js

Request methods to create and refresh user access tokens for OAuth and GitHub Apps
https://github.com/octokit/oauth-methods.js

hacktoberfest oauth octokit-js plugin

Last synced: 7 months ago
JSON representation

Request methods to create and refresh user access tokens for OAuth and GitHub Apps

Awesome Lists containing this project

README

          

# oauth-methods.js

> Set of stateless request methods to create, check, reset, refresh, and delete user access tokens for OAuth and GitHub Apps

[![@latest](https://img.shields.io/npm/v/@octokit/oauth-methods.svg)](https://www.npmjs.com/package/@octokit/oauth-methods)
[![Build Status](https://github.com/octokit/oauth-methods.js/workflows/Test/badge.svg)](https://github.com/octokit/oauth-methods.js/actions?query=workflow%3ATest+branch%3Amain)

- [Usage](#usage)
- [OAuth Web Flow](#oauth-web-flow)
- [OAuth Device Flow](#oauth-device-flow)
- [Methods](#methods)
- [`getWebFlowAuthorizationUrl()`](#getwebflowauthorizationurl)
- [`exchangeWebFlowCode()`](#exchangewebflowcode)
- [`createDeviceCode()`](#createdevicecode)
- [`exchangeDeviceCode()`](#exchangedevicecode)
- [`checkToken()`](#checktoken)
- [`refreshToken()`](#refreshtoken)
- [`scopeToken()`](#scopetoken)
- [`resetToken()`](#resettoken)
- [`deleteToken()`](#deletetoken)
- [`deleteAuthorization()`](#deleteauthorization)
- [Authentication object](#authentication-object)
- [OAuth APP authentication](#oauth-app-authentication)
- [GitHub App with non-expiring user authentication](#github-app-with-non-expiring-user-authentication)
- [GitHub App with expiring user authentication](#github-app-with-expiring-user-authentication)
- [Types](#types)
- [Contributing](#contributing)
- [License](#license)

The OAuth endpoints related to user access tokens are not all part of GitHub's REST API and they behave slightly different. The methods exported by `@octokit/normalize the differences so you don't have to.

## Usage

Browsers

`@octokit/oauth-methods` is not meant for browser usage.

Some of the methods will work, but others do not have CORS headers enabled and will fail (`exchangeWebFlowCode()`, `createDeviceCode()`, `exchangeDeviceCode()`, `refreshToken()`). Also the Client Secret should not be exposed to clients as it can be used for a [Person-in-the-middle attack](https://en.wikipedia.org/wiki/Person-in-the-middle_attack).

Node

Install with `npm install @octokit/core @octokit/oauth-methods`

```js
import {
exchangeWebFlowCode,
createDeviceCode,
exchangeDeviceCode,
checkToken,
refreshToken,
scopeToken,
resetToken,
deleteToken,
deleteAuthorization,
} from "@octokit/oauth-methods";
```

> [!IMPORTANT]
> As we use [conditional exports](https://nodejs.org/api/packages.html#conditional-exports), you will need to adapt your `tsconfig.json` by setting `"moduleResolution": "node16", "module": "node16"`.
>
> See the TypeScript docs on [package.json "exports"](https://www.typescriptlang.org/docs/handbook/modules/reference.html#packagejson-exports).

> See this [helpful guide on transitioning to ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) from [@sindresorhus](https://github.com/sindresorhus)

### OAuth Web Flow

After a user granted access to an OAuth App or GitHub App on [Step 1 of GitHub's OAuth Web Flow](https://docs.github.com/en/developers/apps/identifying-and-authorizing-users-for-github-apps#1-request-a-users-github-identity), they get redirected to a URL controlled by your app with a `?code=...` query parameter.

You can exchange that code for a user access token as described in [Step 2 of GitHub's OAuth Web Flow](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#2-users-are-redirected-back-to-your-site-by-github).

Setting `clientType` is required because there are slight differences between `"oauth-app"` and `"github-app"`. Most importantly, GitHub Apps do not support scopes.

```js
const { data, authentication } = await exchangeWebFlowCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
code: "code123",
scopes: ["repo"],
});
```

`data` is the raw response data. `authentication` is a [User Authentication object](#authentication-object).

### OAuth Device Flow

In [step 1 of GitHub's OAuth Device Flow](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#step-1-app-requests-the-device-and-user-verification-codes-from-github), you need to create a device and user code

```js
const {
data: { device_code, user_code, verification_uri },
} = await createDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
scopes: ["repo"],
});
```

In [step 2 of GitHub's OAuth Device Flow](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#step-2-prompt-the-user-to-enter-the-user-code-in-a-browser), the user has to enter `user_code` on `verification_uri` (https://github.com/login/device unless you use GitHub Enterprise Server).

Once the user entered the code and granted access, you can exchange the `device_code` for a user access token in [step 3 of GitHub's OAuth Device Flow](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#step-3-app-polls-github-to-check-if-the-user-authorized-the-device)

```js
const { data, authentication } = await exchangeDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
code: device_code,
});
```

`data` is the raw response data. `authentication` is a [User Authentication object](#authentication-object).

## Methods

### `getWebFlowAuthorizationUrl()`

This is a wrapper around [`@octokit/oauth-authorization-url`](https://github.com/octokit/oauth-authorization-url.js#readme) that accepts a `request` option instead of `baseUrl` for consistency with the other OAuth methods. `getWebFlowAuthorizationUrl()` is a synchronous method and does not send any request.

```js
const { url } = getWebFlowAuthorizationUrl({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
scopes: ["repo"],
});
```

Options




name


type


description






clientId


string


Required. The client ID you received from GitHub when you registered.




clientType


string


Required. Must be set to either "oauth-app" or "github-app".




redirectUrl


string


The URL in your application where users will be sent after authorization. See Redirect URLs in GitHub’s Developer Guide.




login


string


Suggests a specific account to use for signing in and authorizing the app.




scopes


array of strings

Only relevant if `clientType` is set to `"oauth-app"`.

An array of scope names (or: space-delimited list of scopes). If not provided, scope defaults to an empty list for users that have not authorized any scopes for the application. For users who have authorized scopes for the application, the user won't be shown the OAuth authorization page with the list of scopes. Instead, this step of the flow will automatically complete with the set of scopes the user has authorized for the application. For example, if a user has already performed the web flow twice and has authorized one token with user scope and another token with repo scope, a third web flow that does not provide a scope will receive a token with user and repo scope.

Defaults to `[]`.




state


string


An unguessable random string. It is used to protect against cross-site request forgery attacks.
Defaults to Math.random().toString(36).substr(2).




allowSignup


boolean


Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. Use false in the case that a policy prohibits signups. Defaults to true.




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { url } = getWebFlowAuthorizationUrl({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
scopes: ["repo"],
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


The `getWebFlowAuthorizationUrl` method is synchronous and returns an object with the following properties.




name


type


description






allowSignup


boolean


Returns options.allowSignup if it was set. Defaults to true.




clientType


string


Returns options.clientType




clientId


string


Returns options.clientId.




login


string


Returns options.login if it was set. Defaults to null.




redirectUrl


string


Returns options.redirectUrl if it was set. Defaults to null.




scopes


array of strings

Only set if `options.clientType` is set to `"oauth-app"`.

Returns an array of strings. Returns options.scopes if it was set and turns the string into an array if a string was passed, otherwise [].




state


string


Returns options.state if it was set. Defaults to Math.random().toString(36).substr(2).




url


string


The authorization URL


### `exchangeWebFlowCode()`

```js
const { data, authentication } = await exchangeWebFlowCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
code: "code123",
});
```

Options




name


type


description






clientType


string


Required. Must be set to either "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




code


string


Required. The code from GitHub's OAuth flow redirect's ?code=... query parameter




redirectUrl


string


The redirectUrl option you passed to getWebFlowAuthorizationUrl()




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await exchangeWebFlowCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
code: "code123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST /login/oauth/access_token`](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#response) (JSON) with an additional `authentication` key which is the [authentication object](#authentication-object).

### `createDeviceCode()`

```js
const { data, authentication } = await createDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
scopes: ["repo"],
});
```

Options




name


type


description






clientType


string


Required. Must be set to either "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




scopes


array of strings

Only permitted if `clientType` is set to `"oauth-app"`. GitHub Apps do not support scopes.

Array of [scope names](https://docs.github.com/en/developers/apps/scopes-for-oauth-apps#available-scopes) you want to request for the user access token.




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data } = await createDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
scopes: ["repo"],
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST https://github.com/login/device/code`](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#response-1) (JSON).

### `exchangeDeviceCode()`

```js
const { data, authentication } = await exchangeDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
code: "code123",
});
```




name


type


description






clientType


string


Required. Must be set to either "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




code


string


Required. The device_code from the createDeviceCode() response




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await exchangeDeviceCode({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
code: "code123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


### `checkToken()`

```js
const { data, authentication } = await checkToken({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
});
```

Options




name


type


description






clientType


string


Required. Must be set to either "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




token


string


Required. The user access token to check




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await checkToken({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST /applications/{client_id}/token`](https://docs.github.com/en/rest/reference/apps#check-a-token) with an additional `authentication` key which is the [authentication object](#authentication-object). Note that the `authentication` object will not include the keys for expiring authentication.

### `refreshToken()`

Expiring user access tokens are currently in preview. You can [enable them for any of your GitHub apps](https://docs.github.com/en/developers/apps/refreshing-user-to-server-access-tokens#configuring-expiring-user-tokens-for-an-existing-github-app). OAuth Apps do not support expiring user access tokens

When a user access token expires it can be [refreshed using a refresh token](https://docs.github.com/en/developers/apps/refreshing-user-to-server-access-tokens). Refreshing a token invalidates the current user access token.

```js
const { data, authentication } = await refreshToken({
clientType: "github-app",
clientId: "lv1.1234567890abcdef",
clientSecret: "1234567890abcdef12347890abcdef12345678",
refreshToken: "r1.refreshtoken123",
});
```

Options




name


type


description






clientType


string


Must be set to "github-app"




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




refreshToken


string


Required. The refresh token that was received alongside the user access token.




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await refreshToken({
clientType: "github-app",
clientId: "lv1.1234567890abcdef",
clientSecret: "1234567890abcdef12347890abcdef12345678",
refreshToken: "r1.refreshtoken123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST /login/oauth/access_token`](https://docs.github.com/en/developers/apps/refreshing-user-to-server-access-tokens#response) with an additional `authentication` key which is the [GitHub App expiring user authentication](#github-app-with-expiring-user-authentication).

### `scopeToken()`

```js
const { data, authentication } = await scopeToken({
clientType: "github-app",
clientId: "lv1.1234567890abcdef",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
target: "octokit",
repositories: ["oauth-methods.js"],
permissions: {
issues: "write",
},
});
```

Options




name


type


description






clientType


string


Required. Must be set to "github-app".




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




target


string


Required unless targetId is set. The name of the user or organization to scope the user-to-server access token to.




targetId


integer


Required unless target is set. The ID of the user or organization to scope the user-to-server access token to.




repositories


array of strings


The list of repository names to scope the user-to-server access token to. repositories may not be specified if repository_ids is specified.




repository_ids


array of integers


The list of repository IDs to scope the user-to-server access token to. repositories may not be specified if repositories is specified.




permissions


object


The permissions granted to the user-to-server access token. See GitHub App Permissions.




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await scopeToken({
clientType: "github-app",
clientId: "lv1.1234567890abcdef",
token: "usertoken123",
target: "octokit",
repositories: ["oauth-methods.js"],
permissions: {
issues: "write",
},
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST /applications/{client_id}/token/scoped`](https://docs.github.com/en/rest/reference/apps#create-a-scoped-access-token) with an additional `authentication` key which is the new [authentication object](#authentication-object).

### `resetToken()`

```js
const { data, authentication } = await resetToken({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
});
```

Options




name


type


description






clientType


string


Must be set to "oauth-app" or "github-app".




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




token


string


Required. The user access token to reset




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await resetToken({
clientId: "1234567890abcdef1234",
clientSecret: "secret",
token: "usertoken123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`POST /applications/{client_id}/token`](https://docs.github.com/en/rest/reference/apps#reset-a-token) with an additional `authentication` key which is the new [authentication object](#authentication-object).

### `deleteToken()`

```js
const { status } = await deleteToken({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
});
```

Options




name


type


description






clientType


string


Must be set to "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




token


string


Required. The user access token to delete




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await deleteToken({
clientId: "1234567890abcdef1234",
clientSecret: "secret",
token: "usertoken123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`DELETE /applications/{client_id}/token`](https://docs.github.com/en/rest/reference/apps#delete-an-app-token) (which is an empty `204` response).

### `deleteAuthorization()`

```js
const { status } = await deleteAuthorization({
clientType: "oauth-app",
clientId: "1234567890abcdef1234",
clientSecret: "1234567890abcdef12347890abcdef12345678",
token: "usertoken123",
});
```

Options




name


type


description






clientType


string


Must be set to "oauth-app" or "github-app"




clientId


string


Required. Your app's client ID




clientSecret


string


Required. One of your app's client secrets




token


string


Required. A valid user access token for the authorization




request


function


You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:

```js
import { request } from "@octokit/request";
const { data, authentication } = await deleteAuthorization({
clientId: "1234567890abcdef1234",
clientSecret: "secret",
token: "usertoken123",
request: request.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});
```


Resolves with an [`@octokit/request` response object](https://github.com/octokit/request.js/#request) for [`DELETE /applications/{client_id}/grant`](https://docs.github.com/en/rest/reference/apps#delete-an-app-authorization) (which is an empty `204` response).

## Authentication object

The `authentication` object returned by the methods have one of three formats.

1. [OAuth APP authentication token](#oauth-app-authentication-token)
1. [GitHub APP non-expiring user authentication token with expiring disabled](#github-app-user-authentication-token-with-expiring-disabled)
1. [GitHub APP user authentication token with expiring enabled](#github-app-user-authentication-token-with-expiring-enabled)

The differences are

1. `scopes` is only present for OAuth Apps
2. `refreshToken`, `expiresAt`, `refreshTokenExpiresAt` are only present for GitHub Apps, and only if token expiration is enabled

Note that the `clientSecret` may not be set when using [`exchangeDeviceCode()`](#exchangedevicecode) as `clientSecret` is not required for the OAuth device flow.

### OAuth APP authentication




name


type


description






clientType


string


"oauth-app"




clientId


string


The app's Client ID




token


string


The user access token




scopes


array of strings


array of scope names enabled for the token


### GitHub App with non-expiring user authentication




name


type


description






clientType


string


"github-app"




clientId


string


The app's Client ID




token


string


The user access token


### GitHub App with expiring user authentication




name


type


description






clientType


string


"github-app"




clientId


string


The app's Client ID




token


string


The user access token




refreshToken


string


The refresh token




expiresAt


string


Date timestamp in ISO 8601 standard. Example: 2022-01-01T08:00:0.000Z




refreshTokenExpiresAt


string


Date timestamp in ISO 8601 standard. Example: 2021-07-01T00:00:0.000Z


## Types

```ts
import {
OAuthAppAuthentication,
GitHubAppAuthentication,
GitHubAppAuthenticationWithExpiration,
GetWebFlowAuthorizationUrlOAuthAppOptions,
GetWebFlowAuthorizationUrlGitHubAppOptions,
GetWebFlowAuthorizationUrlOAuthAppResult,
GetWebFlowAuthorizationUrlGitHubAppResult,
CheckTokenOAuthAppOptions,
CheckTokenGitHubAppOptions,
CheckTokenOAuthAppResponse,
CheckTokenGitHubAppResponse,
ExchangeWebFlowCodeOAuthAppOptions,
ExchangeWebFlowCodeGitHubAppOptions,
ExchangeWebFlowCodeOAuthAppResponse,
ExchangeWebFlowCodeGitHubAppResponse,
CreateDeviceCodeOAuthAppOptions,
CreateDeviceCodeGitHubAppOptions,
CreateDeviceCodeDeviceTokenResponse,
ExchangeDeviceCodeOAuthAppOptionsWithoutClientSecret,
ExchangeDeviceCodeOAuthAppOptions,
ExchangeDeviceCodeGitHubAppOptionsWithoutClientSecret,
ExchangeDeviceCodeGitHubAppOptions,
ExchangeDeviceCodeOAuthAppResponse,
ExchangeDeviceCodeOAuthAppResponseWithoutClientSecret,
ExchangeDeviceCodeGitHubAppResponse,
ExchangeDeviceCodeGitHubAppResponseWithoutClientSecret,
RefreshTokenOptions,
RefreshTokenResponse,
ScopeTokenOptions,
ScopeTokenResponse,
ResetTokenOAuthAppOptions,
ResetTokenGitHubAppOptions,
ResetTokenOAuthAppResponse,
ResetTokenGitHubAppResponse,
DeleteTokenOAuthAppOptions,
DeleteTokenGitHubAppOptions,
DeleteTokenResponse,
DeleteAuthorizationOAuthAppOptions,
DeleteAuthorizationGitHubAppOptions,
DeleteAuthorizationResponse,
} from "@octokit/oauth-methods";
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)

## License

[MIT](LICENSE)