Skip to content

Commit

Permalink
Merge branch 'main' into next
Browse files Browse the repository at this point in the history
* main:
  fix: move all crypto imports to import directly crypto not node:crypto
  fix: add vanilla adapters to jsr exports
  ops: bump pnpm setup
  docs: update adapter docs and improve homepage
  • Loading branch information
jasonraimondi committed Jul 5, 2024
2 parents 64337a2 + c7052ab commit e376727
Show file tree
Hide file tree
Showing 35 changed files with 513 additions and 289 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ jobs:
node-version: [ 18.x, 20.x ]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v4
with:
version: "9.x"
version: 9
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
Expand Down Expand Up @@ -62,9 +62,9 @@ jobs:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v4
with:
version: "9.x"
version: 9
- uses: actions/setup-node@v2
with:
node-version: 20.x
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v4
with:
version: "9.x"
version: 9
- uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ Before initializing [Part One](#part-one) of the authorization code flow, the cl
We can do this in Node using the native crypto package and a `base64urlencode` function:

```typescript
import crypto from "node:crypto";
import crypto from "crypto";

const code_verifier = crypto.randomBytes(43).toString("hex");
```
Expand Down
1 change: 1 addition & 0 deletions docs/.idea/docs.iml

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

54 changes: 35 additions & 19 deletions docs/docs/adapters/express.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
# Express

[Express](https://expressjs.com/)
:::info

Adapts the [Express.Request](https://expressjs.com/en/api.html#req) and [Express.Response](https://expressjs.com/en/api.html#res) for use with `@jmondi/oauth2-server`.
Available in >2.0.0

```typescript
import {
requestFromExpress,
handleExpressResponse,
handleExpressError,
} from "@jmondi/oauth2-server/express";
```
:::

```typescript
requestFromExpress(req: Express.Request): OAuthRequest;
```
This adapter provides utility functions to convert between Express [Request](https://expressjs.com/en/api.html#req) and [Response](https://expressjs.com/en/api.html#res) objects and the `OAuthRequest`/`OAuthResponse` objects used by this package.

Helper function to return an OAuthRequest from an `Express.Request`.
## Functions

```typescript
handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void;
```ts
requestFromExpress(req: Express.Request): OAuthRequest
```

Helper function that handles the express response after authorization.
```ts
handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void
```

```typescript
handleExpressError(res: Express.Response, e: unknown | OAuthException): void;
```ts
handleExpressError(res: Express.Response, e: unknown | OAuthException): void
```

Helper function that handles the express response if an error was thrown.
## Example

```ts
import { requestFromExpress, handleExpressResponse, handleExpressError } from "@jmondi/oauth2-server/express";
import express from 'express';

const app = express();

// ...

app.post('/oauth2/token', async (req: express.Request, res: express.Response) => {
const authorizationServer = req.app.get('authorization_server');

try {
const oauthResponse = await authorizationServer
.respondToAccessTokenRequest(requestFromExpress(req));

handleExpressResponse(res, oauthResponse);
} catch (e) {
handleExpressError(res, e);
}
});
```
57 changes: 37 additions & 20 deletions docs/docs/adapters/fastify.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
# Fastify

Adapts the [Fastify.Request](https://fastify.dev/docs/latest/Reference/Request/) and [Fastify.Reply](https://fastify.dev/docs/latest/Reference/Reply/) for use with `@jmondi/oauth2-server`.

```typescript
import {
requestFromFastify,
handleFastifyReply,
handleFastifyError,
} from "@jmondi/oauth2-server/fastify";
```
:::info

The following functions are imported directly from the adapter instead of the root package.
Available in >2.0.0

:::

```typescript
requestFromFastify(req: FastifyRequest): OAuthRequest;
```

Helper function to return an OAuthRequest from an `FastifyRequest`.
This adapter provides utility functions to convert between Fastify [Request](https://fastify.dev/docs/latest/Reference/Request/) and [Reply](https://fastify.dev/docs/latest/Reference/Reply/) objects and the `OAuthRequest`/`OAuthResponse` objects used by this package.

```typescript
handleFastifyReply(fastifyReply: FasitfyReply, oauthResponse: OAuthResponse): void;
## Functions

```ts
requestFromFastify(req: FastifyRequest): OAuthRequest
```

Helper function that handles the express response after authorization.
```ts
handleFastifyReply(fastifyReply: FastifyReply, oauthResponse: OAuthResponse): void
```

```typescript
handleFastifyError(reply: FasitfyReply, e: unknown | OAuthException): void;
```ts
handleFastifyError(reply: FastifyReply, e: unknown | OAuthException): void
```

Helper function that handles the express response if an error was thrown.
## Example

```ts
import { requestFromFastify, handleFastifyReply, handleFastifyError } from "@jmondi/oauth2-server/fastify";
import fastify from 'fastify'

const app = fastify()

// ...

app.post('/oauth2/token', async (request: fastify.Request, reply: fastify.Reply) => {
const authorizationServer = request.server.authorizationServer;

try {
const oauthResponse = await authorizationServer
.respondToAccessTokenRequest(requestFromFastify(request));

handleFastifyReply(reply, oauthResponse);
} catch (e) {
handleFastifyError(reply, e);
}
});
```
2 changes: 1 addition & 1 deletion docs/docs/adapters/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Adapters are a set of helper functions to provide framework specific integration

- [Express](./express) - If you're using Express, you can use the `@jmondi/oauth2-server/express` adapter.
- [Fastify](./fastify) - If you're using Fastify, you can use the `@jmondi/oauth2-server/fastify` adapter.
- [VanillaJS](./vanilla) - If you're using Honojs, Sveltekit or Nextjs, you can use the `@jmondi/oauth2-server/vanilla` adapter.
- [VanillaJS](./vanilla) - Adapts the Fetch [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) so you can use Honojs, Sveltekit, Nextjs or whatever tool your using that uses the native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) `@jmondi/oauth2-server/vanilla` adapter.
51 changes: 31 additions & 20 deletions docs/docs/adapters/vanilla.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,43 @@ Available in >3.4.0

:::

Adapts the Fetch [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) for use with `@jmondi/oauth2-server`.

```typescript
import {
requestFromVanilla,
handleVanillaReply,
handleVanillaError,
} from "@jmondi/oauth2-server/vanilla";
```
This adapter provides utility functions to convert between vanilla JavaScript [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects and the `OAuthRequest`/`OAuthResponse` objects used by the this package.

The following functions are imported directly from the adapter instead of the root package.
## Functions

```typescript
requestFromVanilla(req: Request): OAuthRequest;
```ts
responseFromVanilla(res: Response): OAuthResponse
```

Helper function to return an OAuthRequest from an `VanillaRequest`.
```ts
requestFromVanilla(req: Request): OAuthRequest
```

```typescript
handleVanillaReply(res: Response, oauthResponse: OAuthResponse): void;
```ts
responseToVanilla(oauthResponse: OAuthResponse): Response
```

Helper function that handles the express response after authorization.
## Example

```typescript
handleVanillaError(res: Response, e: unknown | OAuthException): void;
```
```ts
import { requestFromVanilla, responseToVanilla } from "@jmondi/oauth2-server/vanilla";

import { Hono } from 'hono'
const app = new Hono()

// ...

Helper function that handles the express response if an error was thrown.
app.post('/oauth2/token', async (c) => {
const authorizationServer = c.get("authorization_server");

const oauthResponse = await authorizationServer
.respondToAccessTokenRequest(requestFromVanilla(request))
.catch(e => {
error(400, e.message);
});

return responseToVanilla(oauthResponse);
});

export default app
```
2 changes: 1 addition & 1 deletion docs/docs/authorization_server/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type AuthorizationServerOptions = {

To configure these options, pass the value in as the last argument:

```typescript
```ts
const authorizationServer = new AuthorizationServer(
clientRepository,
accessTokenRepository,
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/authorization_server/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The `AuthorizationServer` is a core component of the OAuth 2.0 framework, respon

To create an instance of the `AuthorizationServer`, use the following constructor:

```typescript
```ts
const authorizationServer = new AuthorizationServer(
clientRepository,
accessTokenRepository,
Expand All @@ -32,7 +32,7 @@ Parameters:

By default, no grant types are enabled when creating an `AuthorizationServer`. Each grant type must be explicitly enabled using the `enableGrantType` method. This approach allows for fine-grained control over which OAuth 2.0 flows your server supports.

```typescript
```ts
authorizationServer.enableGrantType("client_credentials");
authorizationServer.enableGrantType("refresh_token");
authorizationServer.enableGrantType({
Expand All @@ -49,7 +49,7 @@ Note that the Authorization Code grant requires additional repositories: `userRe

You can enable multiple grant types on the same server:

```typescript
```ts
const authorizationServer = new AuthorizationServer(
clientRepository,
accessTokenRepository,
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/getting_started/endpoints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sidebar_position: 4

The `/token` endpoint is a back channel endpoint that issues a usable access token.

```typescript
```ts
app.post("/token", async (req: Express.Request, res: Express.Response) => {
try {
const oauthResponse = await authorizationServer.respondToAccessTokenRequest(req);
Expand All @@ -26,7 +26,7 @@ The `/authorize` endpoint is a front channel endpoint that issues an authorizati

The endpoint should redirect the user to login, and then to accept the scopes requested by the application, and only when the user accepts, should it send the user back to the clients redirect uri.

```typescript
```ts
import { requestFromExpress } from "@jmondi/oauth2-server/express";

app.get("/authorize", async (req: Express.Request, res: Express.Response) => {
Expand Down Expand Up @@ -75,15 +75,15 @@ app.get("/authorize", async (req: Express.Request, res: Express.Response) => {

## The Revoke Endpoint

:::tip Note
:::info Note

Implementing this endpoint is optional, but recommended. RFC7009 “OAuth 2.0 Token Revocation”

:::

The `/token/revoke` endpoint is a back channel endpoint that revokes an existing token.

```typescript
```ts
app.post("/token/revoke", async (req: Express.Request, res: Express.Response) => {
try {
const oauthResponse = await authorizationServer.revoke(req);
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/getting_started/entities.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The Client Entity represents an application that requests access to protected re

:::

```typescript
```ts
interface OAuthClient {
id: string;
name: string;
Expand Down Expand Up @@ -50,7 +50,7 @@ type CodeChallengeMethod = "S256" | "plain";

The Token Entity represents access and refresh tokens issued to clients.

```typescript
```ts
interface OAuthToken {
accessToken: string;
accessTokenExpiresAt: Date;
Expand All @@ -67,7 +67,7 @@ interface OAuthToken {

The User Entity represents the resource owner - typically the end-user who authorizes an application to access their account.

```typescript
```ts
interface OAuthUser {
id: string;
[key: string]: any;
Expand All @@ -80,7 +80,7 @@ Scopes are used to define and limit the extent of access granted to a client app

For more information on OAuth 2.0 scopes, visit: https://www.oauth.com/oauth2-servers/scope/

```typescript
```ts
interface OAuthScope {
name: string;
[key: string]: any;
Expand Down
12 changes: 9 additions & 3 deletions docs/docs/getting_started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ This section provides a high-level overview of setting up the OAuth2 server.
1. Set up the [AuthorizationServer](#the-authorization-server) with desired grant types
1. Implement the [Endpoints](./endpoints)

## Installation
### Installation

Choose your preferred package manager to install @jmondi/oauth2-server:

<Installation />

## Basic Setup
### Implement Entities

### The Authorization Server
You are going to need to setup the entities that the OAuth2 server uses to store data. See the [full list of entities](./entities.md).

### Implement Repositories

Next you need to implement the repositories that the OAuth2 server uses to interact with the entities. See the [full list of repositories](./repositories).

### Setup the Authorization Server

The AuthorizationServer is the core component of the OAuth2 implementation. It requires repositories for managing clients, access tokens, and scopes. Grant types are opt-in and must be explicitly enabled.

Expand Down
Loading

0 comments on commit e376727

Please sign in to comment.