Skip to content

Commit

Permalink
Refactor and remove requireRefresh from getAccessToken (#37)
Browse files Browse the repository at this point in the history
* Update dependencies

* Refactor and remove requireRefresh from getAccessToken
  • Loading branch information
KyleJune authored Apr 3, 2022
1 parent 8936c23 commit 86c5435
Show file tree
Hide file tree
Showing 38 changed files with 904 additions and 1,024 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# OAuth2 Server

[![version](https://img.shields.io/badge/release-0.11.1-success)](https://deno.land/x/oauth2_server@0.11.1)
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/oauth2_server@0.11.1/authorization_server.ts)
[![version](https://img.shields.io/badge/release-0.12.0-success)](https://deno.land/x/oauth2_server@0.12.0)
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/oauth2_server@0.12.0/authorization_server.ts)
[![CI](https://github.com/udibo/oauth2_server/workflows/CI/badge.svg)](https://github.com/udibo/oauth2_server/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/udibo/oauth2_server/branch/main/graph/badge.svg?token=8Q7TSUFWUY)](https://codecov.io/gh/udibo/oauth2_server)
[![license](https://img.shields.io/github/license/udibo/oauth2_server)](https://github.com/udibo/oauth2_server/blob/master/LICENSE)
Expand Down Expand Up @@ -44,19 +44,19 @@ also acting as an authorization server.

```ts
// Import from Deno's third party module registry
import { ResourceServer } from "https://deno.land/x/oauth2_server@0.11.1/resource_server.ts";
import { ResourceServer } from "https://deno.land/x/oauth2_server@0.12.0/resource_server.ts";
// Import from GitHub
import { ResourceServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.11.1/resource_server.ts";
import { ResourceServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.12.0/resource_server.ts";
```

The AuthorizationServer is an extension of the ResourceServer, adding methods
used by the authorize and token endpoints.

```ts
// Import from Deno's third party module registry
import { AuthorizationServer } from "https://deno.land/x/oauth2_server@0.11.1/authorization_server.ts";
import { AuthorizationServer } from "https://deno.land/x/oauth2_server@0.12.0/authorization_server.ts";
// Import from GitHub
import { AuthorizationServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.11.1/authorization_server.ts";
import { AuthorizationServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.12.0/authorization_server.ts";
```

## Usage
Expand All @@ -66,7 +66,7 @@ An example of how to use this module can be found
but it should give you an idea of how to use this module.

See
[deno docs](https://doc.deno.land/https/deno.land/x/oauth2_server@0.11.1/authorization_server.ts)
[deno docs](https://doc.deno.land/https/deno.land/x/oauth2_server@0.12.0/authorization_server.ts)
for more information.

### Grants
Expand Down
10 changes: 5 additions & 5 deletions adapters/oak/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ also acting as an authorization server.

```ts
// Import from Deno's third party module registry
import { OakResourceServer } from "https://deno.land/x/oauth2_server@0.11.1/adapters/oak/resource_server.ts";
import { OakResourceServer } from "https://deno.land/x/oauth2_server@0.12.0/adapters/oak/resource_server.ts";
// Import from GitHub
import { OakResourceServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.11.1/adapters/oak/resource_server.ts";
import { OakResourceServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.12.0/adapters/oak/resource_server.ts";
```

The AuthorizationServer is an extension of the ResourceServer, adding methods
used by the authorize and token endpoints.

```ts
// Import from Deno's third party module registry
import { OakAuthorizationServer } from "https://deno.land/x/oauth2_server@0.11.1/adapters/oak/authorization_server.ts";
import { OakAuthorizationServer } from "https://deno.land/x/oauth2_server@0.12.0/adapters/oak/authorization_server.ts";
// Import from GitHub
import { OakAuthorizationServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.11.1/adapters/oak/authorization_server.ts";
import { OakAuthorizationServer } from "https://raw.githubusercontent.com/udibo/oauth2_server/0.12.0/adapters/oak/authorization_server.ts";
```

## Usage
Expand All @@ -42,5 +42,5 @@ An example of how to use this adapter module can be found
but it should give you an idea of how to use this module.

See
[deno docs](https://doc.deno.land/https/deno.land/x/oauth2_server@0.11.1/adapters/oak/authorization_server.ts)
[deno docs](https://doc.deno.land/https/deno.land/x/oauth2_server@0.12.0/adapters/oak/authorization_server.ts)
for more information.
26 changes: 13 additions & 13 deletions adapters/oak/context_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import {
assertSpyCall,
assertSpyCalls,
assertStrictEquals,
describe,
it,
Spy,
spy,
test,
TestSuite,
} from "../../test_deps.ts";
import { BodyForm, Context, Request, Response } from "./deps.ts";
import { OakOAuth2Request, OakOAuth2Response } from "./context.ts";

const requestTests = new TestSuite({ name: "OakOAuth2Request" });
const requestTests = describe("OakOAuth2Request");

test(requestTests, "get", async () => {
it(requestTests, "get", async () => {
const expectedBody = new URLSearchParams();
const original: Request = {
url: new URL("https://example.com/resource/1"),
Expand All @@ -35,7 +35,7 @@ test(requestTests, "get", async () => {
assertStrictEquals(await wrapped.body, expectedBody);
});

test(requestTests, "post", async () => {
it(requestTests, "post", async () => {
const expectedBody: URLSearchParams = new URLSearchParams({
grant_type: "client_credentials",
});
Expand All @@ -58,7 +58,7 @@ test(requestTests, "post", async () => {
assertStrictEquals(await wrapped.body, expectedBody);
});

test(requestTests, "post with sync body error", async () => {
it(requestTests, "post with sync body error", async () => {
const original: Request = {
url: new URL("https://example.com/token"),
method: "POST",
Expand All @@ -77,7 +77,7 @@ test(requestTests, "post with sync body error", async () => {
assertEquals(await wrapped.body, new URLSearchParams());
});

test(requestTests, "post with async body error", async () => {
it(requestTests, "post with async body error", async () => {
const original: Request = {
url: new URL("https://example.com/token"),
method: "POST",
Expand All @@ -97,9 +97,9 @@ test(requestTests, "post with async body error", async () => {
await assertRejects(() => wrapped.body, Error, "failed");
});

const responseTests = new TestSuite({ name: "OakOAuth2Response" });
const responseTests = describe("OakOAuth2Response");

test(responseTests, "redirect", () => {
it(responseTests, "redirect", () => {
const original: Response = {
redirect: (_url: string | URL) => undefined,
} as Response;
Expand All @@ -123,7 +123,7 @@ test(responseTests, "redirect", () => {
assertSpyCalls(redirect, 2);
});

test(responseTests, "without body", () => {
it(responseTests, "without body", () => {
const headers: Headers = new Headers({ "Content-Type": `application/json` });
const original: Response = {
status: 404,
Expand All @@ -149,7 +149,7 @@ test(responseTests, "without body", () => {
assertStrictEquals(original.body, undefined);
});

test(responseTests, "with sync body value", () => {
it(responseTests, "with sync body value", () => {
const headers: Headers = new Headers({ "Content-Type": `application/json` });
const original: Response = {
status: 200,
Expand All @@ -168,7 +168,7 @@ test(responseTests, "with sync body value", () => {
assertStrictEquals(original.body, body);
});

test(responseTests, "with async body value", () => {
it(responseTests, "with async body value", () => {
const headers: Headers = new Headers({ "Content-Type": `application/json` });
const original: Response = {
status: 200,
Expand All @@ -189,7 +189,7 @@ test(responseTests, "with async body value", () => {
assertStrictEquals(result, body);
});

test(responseTests, "with body function", () => {
it(responseTests, "with body function", () => {
const headers: Headers = new Headers({ "Content-Type": `application/json` });
const original: Response = {
status: 200,
Expand Down
4 changes: 2 additions & 2 deletions adapters/oak/deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ export {
Cookies,
Request,
Response,
} from "https://deno.land/x/oak@v10.1.0/mod.ts";
} from "https://deno.land/x/oak@v10.5.1/mod.ts";
export type {
BodyForm,
Middleware,
} from "https://deno.land/x/oak@v10.1.0/mod.ts";
} from "https://deno.land/x/oak@v10.5.1/mod.ts";
12 changes: 7 additions & 5 deletions adapters/oak/resource_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export class OakResourceServer<
private stateKey: string;
private getAccessToken: (
request: OakOAuth2Request<Client, User, Scope>,
requireRefresh?: boolean,
) => Promise<string | null>;

constructor(options: OakResourceServerOptions<Client, User, Scope>) {
Expand All @@ -59,16 +58,19 @@ export class OakResourceServer<
return state;
}

async getToken(accessToken: string): Promise<Token<Client, User, Scope>> {
return await this.server.getToken(accessToken);
}

async getTokenForRequest(
request: OakOAuth2Request<Client, User, Scope>,
): Promise<Token<Client, User, Scope> | undefined> {
return await this.server.getTokenForRequest(request, this.getAccessToken)
.catch(() => undefined);
): Promise<Token<Client, User, Scope>> {
return await this.server.getTokenForRequest(request, this.getAccessToken);
}

async getTokenForContext(
context: Context,
): Promise<Token<Client, User, Scope> | undefined> {
): Promise<Token<Client, User, Scope>> {
const state = this.getState(context);
const { request } = state;
return await this.getTokenForRequest(request);
Expand Down
46 changes: 26 additions & 20 deletions asserts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@ import {
assertSpyCall,
assertStrictEquals,
Spy,
SpyCall,
Stub,
} from "./test_deps.ts";
import { ClientInterface } from "./models/client.ts";
import { ScopeInterface } from "./models/scope.ts";
import { Token } from "./models/token.ts";
import { AuthorizationCode } from "./models/authorization_code.ts";

export function assertScope<Scope extends ScopeInterface>(
actual: Scope | null | undefined,
actual: unknown,
expected: Scope | null | undefined,
): void {
try {
if (expected && actual) {
assert(expected.equals(actual));
assert(expected.equals(actual as Scope));
} else {
assertEquals(actual, expected);
}
} catch {
assertEquals(
actual ? [...actual].sort() : actual,
actual ? [...actual as Scope].sort() : actual,
expected ? [...expected].sort() : expected,
);
}
Expand All @@ -35,14 +33,17 @@ function assertWithoutScope<
User,
Scope extends ScopeInterface,
>(
actual:
| Partial<AuthorizationCode<Client, User, Scope>>
| Partial<Token<Client, User, Scope>>,
actual: unknown,
expected:
| Partial<AuthorizationCode<Client, User, Scope>>
| Partial<Token<Client, User, Scope>>,
): void {
const actualWithoutScope = { ...actual };
const actualWithoutScope = {
...(actual as (
| Partial<AuthorizationCode<Client, User, Scope>>
| Partial<Token<Client, User, Scope>>
)),
};
delete actualWithoutScope.scope;
const expectedWithoutScope = { ...expected };
delete expectedWithoutScope.scope;
Expand All @@ -54,15 +55,18 @@ export function assertToken<
User,
Scope extends ScopeInterface,
>(
actual: Partial<Token<Client, User, Scope>> | null | undefined,
actual: unknown,
expected: Partial<Token<Client, User, Scope>> | null | undefined,
): void {
assert(
!!actual === !!expected,
actual ? "did not expect token" : "expected token",
);
if (actual && expected) {
assertScope(actual.scope, expected.scope);
assertScope(
(actual as Partial<Token<Client, User, Scope>>).scope,
expected.scope,
);
assertWithoutScope(actual, expected);
}
}
Expand All @@ -72,7 +76,7 @@ export function assertAuthorizationCode<
User,
Scope extends ScopeInterface,
>(
actual: Partial<AuthorizationCode<Client, User, Scope>> | null | undefined,
actual: unknown,
expected: Partial<AuthorizationCode<Client, User, Scope>> | null | undefined,
): void {
assert(
Expand All @@ -82,7 +86,10 @@ export function assertAuthorizationCode<
: "expected authorization code",
);
if (actual && expected) {
assertScope(actual.scope, expected.scope);
assertScope(
(actual as Partial<AuthorizationCode<Client, User, Scope>>).scope,
expected.scope,
);
assertWithoutScope(actual, expected);
}
}
Expand All @@ -92,18 +99,17 @@ export function assertClientUserScopeCall<
User,
Scope extends ScopeInterface,
>(
// deno-lint-ignore no-explicit-any
spy: Spy<any> | Stub<any>,
spy: Spy,
callIndex: number,
// deno-lint-ignore no-explicit-any
self: any,
self: unknown,
client: Client,
user: User,
expectedScope?: Scope | null,
scope?: Scope | null,
): void {
const call: SpyCall = assertSpyCall(spy, callIndex);
assertSpyCall(spy, callIndex);
const call = spy.calls[callIndex];
assertStrictEquals(call.self, self);
assertEquals(call.args.slice(0, 2), [client, user]);
const actualScope: ScopeInterface | undefined = call.args[2];
assertScope(actualScope, expectedScope);
assertScope(actualScope, scope);
}
12 changes: 5 additions & 7 deletions asserts_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ import {
assertScope,
assertToken,
} from "./asserts.ts";
import { AssertionError, assertThrows, test, TestSuite } from "./test_deps.ts";
import { AssertionError, assertThrows, describe, it } from "./test_deps.ts";
import { Client } from "./models/client.ts";
import { Scope } from "./models/scope.ts";
import { Token } from "./models/token.ts";
import { AuthorizationCode } from "./models/authorization_code.ts";
import { User } from "./models/user.ts";

const assertsTests: TestSuite<void> = new TestSuite({
name: "asserts",
});
const assertsTests = describe("asserts");

test(assertsTests, "assertScope", () => {
it(assertsTests, "assertScope", () => {
assertScope(undefined, undefined);
assertScope(new Scope(), new Scope());
assertScope(new Scope("read"), new Scope("read"));
Expand Down Expand Up @@ -56,7 +54,7 @@ test(assertsTests, "assertScope", () => {
const client: Client = { id: "1", grants: [] };
const user: User = { username: "kyle" };

test(assertsTests, "assertToken", () => {
it(assertsTests, "assertToken", () => {
const expectedToken: Token<Client, User, Scope> = {
accessToken: "x",
client: { id: "1", grants: [] },
Expand Down Expand Up @@ -169,7 +167,7 @@ test(assertsTests, "assertToken", () => {
);
});

test(assertsTests, "assertAuthorizationCode", () => {
it(assertsTests, "assertAuthorizationCode", () => {
const expiresAt = new Date(Date.now() + 60000);
const expectedAuthorizationCode: AuthorizationCode<Client, User, Scope> = {
code: "x",
Expand Down
3 changes: 2 additions & 1 deletion authorization_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ export {
UNICODECHARNOCRLF,
UnsupportedGrantTypeError,
UnsupportedResponseTypeError,
UnsupportedTokenTypeError,
VSCHAR,
} from "./resource_server.ts";
export type {
Expand All @@ -381,7 +382,7 @@ export type {
OAuth2AuthenticatedRequest,
OAuth2AuthorizedRequest,
OAuth2AuthorizeRequest,
OAuth2ErrorInit,
OAuth2ErrorOptions,
OAuth2Request,
OAuth2Response,
RefreshToken,
Expand Down
Loading

0 comments on commit 86c5435

Please sign in to comment.