Skip to content

Commit

Permalink
feat: unauthenticated strategy (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
gr2m authored Oct 28, 2020
1 parent 78e2d41 commit 87d6062
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 10 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ const octokit = new ProbotOctokit({
});
```

### Unauthenticated

```js
const octokit = new ProbotOctokit();
```

This is useful if you need to send a request without access to authentication. Probot's use case here is [Create a GitHub App from a manifest](https://docs.github.com/en/free-pro-team@latest/rest/reference/apps#create-a-github-app-from-a-manifest) (`POST /app-manifests/{code}/conversions`), which is used to register a GitHub app and retrieve the credentials in return.

### Get authenticated octokit instance based on event

```js
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "octokit-auth-probot",
"version": "1.0.0",
"version": "0.0.0-development",
"description": "Octokit authentication strategy that supports token, app (JWT), and event-based installation authentication",
"main": "index.js",
"scripts": {
Expand All @@ -19,7 +19,7 @@
"dependencies": {
"@octokit/auth-app": "^2.10.0",
"@octokit/auth-token": "^2.4.2",
"@octokit/auth-unauthenticated": "^1.0.0",
"@octokit/auth-unauthenticated": "^2.0.0",
"@octokit/types": "^5.5.0"
},
"peerDependencies": {
Expand Down
4 changes: 3 additions & 1 deletion src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export async function auth(state: State, options: AuthOptions) {
return state.auth(options);
}

if (state.type === "token") {
// unless the internal event type is "app", return the octokit
// instance passed as strategy option
if (state.type !== "app") {
return state.octokit;
}

Expand Down
15 changes: 13 additions & 2 deletions src/get-state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createTokenAuth } from "@octokit/auth-token";
import { createAppAuth } from "@octokit/auth-app";
import { createUnauthenticatedAuth } from "@octokit/auth-unauthenticated";

import { State, StrategyOptions } from "./types";

Expand All @@ -17,9 +18,19 @@ export function getState(options: StrategyOptions): State {
};
}

if ("appId" in options && "privateKey" in options) {
return {
type: "app",
auth: createAppAuth(options),
...common,
};
}

return {
type: "app",
auth: createAppAuth(options),
type: "unauthenticated",
auth: createUnauthenticatedAuth({
reason: `Neither "appId"/"privateKey" nor "token" have been set as auth options`,
}),
...common,
};
}
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Octokit } from "@octokit/core";
import { createTokenAuth, Types as TokenAuthTypes } from "@octokit/auth-token";
import { createAppAuth, Types as AppAuthTypes } from "@octokit/auth-app";
import { createUnauthenticatedAuth } from "@octokit/auth-unauthenticated";

type OctokitStrategyOptions = {
octokit: InstanceType<typeof Octokit>;
Expand Down Expand Up @@ -33,4 +34,8 @@ type AppState = OctokitStrategyOptions & {
type: "app";
auth: ReturnType<typeof createAppAuth>;
};
export type State = TokenState | AppState;
type UnauthenticatedState = OctokitStrategyOptions & {
type: "unauthenticated";
auth: ReturnType<typeof createUnauthenticatedAuth>;
};
export type State = TokenState | AppState | UnauthenticatedState;
23 changes: 23 additions & 0 deletions test/readme-examples.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,29 @@ describe("README examples", () => {
expect(data).toStrictEqual({ ok: true });
});

it("Unauthenticated", async () => {
const mock = sandbox().postOnce("path:/app-manifests/123/conversions", {
status: 201,
body: {
id: 1,
},
});

const octokit = new ProbotOctokit({
request: {
fetch: mock,
},
});

const { data } = await octokit.request(
"POST /app-manifests/{code}/conversions",
{
code: 123,
}
);
expect(data).toStrictEqual({ id: 1 });
});

describe("Get authenticated octokit instance based on event", () => {
test("with token auth", async () => {
const mock = sandbox().get(
Expand Down

0 comments on commit 87d6062

Please sign in to comment.