0.1.0 • Published 2 years ago

@baoshan/octokit_auth-oauth-user-client.js v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

auth-oauth-user-client.js

Authentication strategy for Octokit without exposing client secret.

Backend service

auth-oauth-user-client.js requires a backend service to function. @octokit/oauth-app provides the compatible Node.js/Express.js/Cloudflare Worker/Deno middlewares to interact with auth-oauth-user-client.js.

Browsers

Load directly from CDNs:

  • jsdelivr: https://cdn.jsdelivr.net/gh/octokit/auth-oauth-user-client.js@v0.1.0/dist/index.min.js
<script type="module">
  import { createOAuthUserClientAuth } from "https://cdn.jsdelivr.net/gh/octokit/auth-oauth-user-client.js@v0.1.0/dist/index.min.js";
</script>

Create An Authenticator Instance

const authenticator = createOAuthUserClientAuth({
  clientId: "client_id", // get client id from https://github.com/settings/apps
  clientType: "github-app", // "github-app" | "oauth-app"
  expirationEnabled: true, // true | false
});

Get Token

Use { type: "getToken" } method to get authentication object from localStorage. Returns null when there is no authentication object found in localStorage.

When both code and state search parameters are present (user being redirected from GitHub login url), "getToken" method will automatically exchange the code search parameter for an authentication object using the backend service.

const auth = await authenticator(); // ≡ ({ type: "getToken" })

Sign In

Use signIn method to clear authentication object from localStorage and redirect user to GitHub login url.

if (!auth) await authenticator({ type: "signIn" });

All Methods

{ type: ? }MeaningNote
"getToken"Get tokenSee Get token.
"signIn"Sign inSee Sign in.
"createToken"Exchange code in url parameters for tokenNormally the getToken method will exchange code for an access token automatically when both code and state search parameters are present (user being redirected from GitHub login url).
"checkToken"Check a token
"createScopedToken"Create a scoped access tokenFor OAuth app only. Specify extra parameters like { type: "createScopedToken", target: ... }.
"resetToken"Reset a token
"renewToken"Renewing a user token with a refresh tokenThe app should enable token expiration in settings (GitHub App only currently)
"deleteToken"Delete an app tokenUse { type = "deleteToken", offline: true } to delete authentication from localStorage without calling GitHub API via backend service.
"deleteAuthorization"Delete an app authorization

Usage with Octokit

To use @octokit/auth-oauth-user-client with @octokit/core-compatible modules, specify the authentication strategy and authentication strategy options.

<script type="module">
  import { Octokit } from "https://cdn.skypack.dev/@octokit/octokit";
  import { createOAuthUserClientAuth } from "https://cdn.jsdelivr.net/gh/octokit/auth-oauth-user-client.js@v0.1.0/dist/index.min.js";

  const octokit = new Octokit({
    authStrategy: createOAuthUserClientAuth,
    auth: {
      clientId: "client_id", // get client id from https://github.com/settings/apps
      clientType: "github-app", // "github-app" | "oauth-app"
      expirationEnabled: true, // true | false
    },
  });

  const auth = await octokit.auth();
  if (!auth) await octokit.auth({ type: "signIn" });
  else console.log(await octokit.rest.users.getAuthenticated());
</script>

Or

<script type="module">
  import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
  import { createOAuthUserClientAuth } from "https://cdn.jsdelivr.net/gh/octokit/auth-oauth-user-client.js@v0.1.0/dist/index.min.js";

  const octokit = new Octokit({
    authStrategy: createOAuthUserClientAuth,
    auth: {
      clientId: "client_id", // get client id from https://github.com/settings/apps
      clientType: "github-app", // "github-app" | "oauth-app"
      expirationEnabled: true, // true | false
    },
  });

  const auth = await octokit.auth();
  if (!auth) await octokit.auth({ type: "signIn" });
  else console.log(await octokit.request("GET /user"));
</script>

createOAuthUserClientAuth(options) or new Octokit({auth})

The createOAuthUserClientAuth method accepts a single options object as argument:

nametypedescription
clientIdstringRequired. Find Client ID on the app’s about page in settings.
clientTypestringRequired. Either "oauth-app" or "github-app".
expirationEnabledbooleanRequired. true or false for GitHub App. false for OAuth App. Set according to app settings.
authobjectInitial authentication object, defaults to null. See authentication object.
defaultScopesstringOnly relevant for OAuth App. See available scopes.
serviceOriginstringDefaults to location.origin. Required only when the @octokit/oauth-app Node.js/Express.js/Cloudflare middleware is deployed at a different origin.
servicePathPrefixstringDefaults to "/api/github/oauth". Required only when the @octokit/oauth-app Node.js/Express.js/Cloudflare middleware is created with custom pathPrefix.
authStoreobject or falseCustom store to get/set authentication object, false to disable persistence of authentication object. See custom store.
stateStoreobject or falseCustom store to get/set state string, false to disable persistence of state string.
requestfunctionYou can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the API root endpoint. See custom request

Custom Store

By default, auth-oauth-user-client.js uses localStorage to store JSON serialized authentication object and state string.

Pass authStore or stateStore in createOAuthUserClientAuth(options) (or new Octokit({auth})) to use your custom code to persist authentication object or state string.

For example:

const authStore = {
  get: async() => {
  // return persisted authentication object when user is signed in;
  // returns `null` when user is signed out
  }
  set: async(auth) => {
    if (auth == null) { /* delete persisted authentication object */ }
    else { /* create or update persisted authentication object */ }
  }
}

const auth = createOAuthUserClientAuth({
  clientId: "client_id",
  authStore
});

Authentication Object

The async auth(options) method returns to an authentication object. There are three possible types of authentication object:

  1. OAuth APP authentication token
  2. GitHub APP user authentication token with expiring disabled
  3. 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

OAuth APP Authentication Object

nametypedescription
typestring"token"
tokenTypestring"oauth"
clientTypestring"oauth-app"
clientIdstringClient id of the app
tokenstringThe user access token
scopesarray of stringsArray of scope names enabled for the token

GitHub APP Authentication Object (Expiring Disabled)

nametypedescription
typestring"token"
tokenTypestring"oauth"
clientTypestring"github-app"
clientIdstringClient id of the app
tokenstringThe user access token

GitHub APP Authentication Object (Expiring Enabled)

nametypedescription
typestring"token"
tokenTypestring"oauth"
clientTypestring"github-app"
clientIdstringClient id of the app
tokenstringThe user access token
refreshTokenstringThe refresh token
expiresAtstringDate in ISO 8601 format, e.g: 2011-10-05T14:48:00.000Z
refreshTokenExpiresAtstringDate in ISO 8601 format, e.g: 2011-10-05T14:48:00.000Z

Development

Although targeting browsers, this module is written, tested, and bundled using Deno for its simplicity.

  • test: deno test --location=https://acme.com/search?q=octokit --coverage=cov_profile
  • show coverage: deno coverage cov_profile
  • bundle: deno bundle src/index.ts dist/index.bundle.js
  • minify: esbuild dist/index.bundle.js --minify --outfile=dist/index.min.js

Contributing

See CONTRIBUTING.md

License

MIT