Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' of github.com:poef/metrojs
Browse files Browse the repository at this point in the history
  • Loading branch information
poef committed Feb 18, 2024
2 parents 80f1ec8 + ce9318b commit 6b8d7d7
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 4 deletions.
15 changes: 15 additions & 0 deletions docs/middleware/echomock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Echo Middleware

The `echomw` middleware is a mock middleware. It doesn't actually call `fetch()`, instead it copies the incoming request directly to a response. It doesn't call `next()`, so any other middleware is skipped.

The `echomw` middleware is only useful for testing purposes and should never be used in production.

## Usage

```javascript
import * as metro from '@muze-nl/metro'
import echomw from '@muze-nl/metro/src/mw/echo.mock.mjs'

const client = metro.client().with( echomw() )
```

40 changes: 40 additions & 0 deletions docs/middleware/json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# JSON middleware

The `jsonmw()` middleware allows you to automatically parse and stringify javascript data when sending or receiving data.

## Usage

```javascript
import * as metro from '@muze-nl/metro'
import jsonmw from '@muze-nl/metro/src/mw/json.mjs'

const client = metro.client().with( jsonmw({
space: "\t"
}) )
```

Then to send and receive data:

```javascript
let response = await client.post(url, {
some: 'data'
})
let result
if (response.ok) {
result = response.body.something
}
```

The `jsonmw` middelware will automatically add the `Accept: application/json` header to your requests.

If the HTTP request supports a body, as in `POST`, `PUT`, `PATCH` and `QUERY`, it will also add the `Content-Type: application/json` header. Any data send as the body of the request, will be turned into json.

The body of the response is automatically parsed as json.

## Configuration Options

The JSON middleware allows you to set the options to use when parsing or stringifying JSON:

- `reviver`: A function to use when parsing JSON, just like [JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter)
- `replaced`: A function to use when stringifying JSON, just like [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter)
- `space`: The indentation to use when stringifying JSON, just like [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#space)
46 changes: 46 additions & 0 deletions docs/middleware/oauth2.md
Original file line number Diff line number Diff line change
@@ -1 +1,47 @@
# OAuth2 middleware

The Oauth2 middleware allows you to configure the metro client to handle OAuth2 connections, fetching and refreshing tokens automatically:

```javascript
import oauth2mw from '@muze-nl/metro/src/mw/oauth2.mjs'
const client = metro.client('https://oauth2api.example.com')
.with( oauth2mw({
client_id: myClientId,
client_secret: myClientSecret
}) )
````

You pass the OAuth2 configuration options to the `oauth2mw()` function. This returns the middleware function for the metro client.

## Configuration

Valid configuration options are:

- `access_token` - if you've stored an OAuth2 access token, you can set it here
- `authorization_code` - if you've retrieved an OAuth2 authorization code, set it here
- `refresh_token` - sets the refresh token to use when the access token must be refreshed
- `client` - sets the base metro client to use by the OAuth2 middleware
- `client_id` - the OAuth2 client id
- `client_secret` - the OAuth2 client secret
- `grant_type` - currently only `authorization_code` is implemented
- `force_authorization` - if not set or `false`, the OAuth2 middleware will only use OAuth2 if a normal--unauthorized--fetch doesn't work. If set to `true`, all requests will use OAuth2.
- `redirect_uri` - The URL the OAuth2 authorization server will redirect back to
- `state` - How to store the state parameter, defaults to `localStorage`
- `tokens` - How to store tokens. Either a normal object, or a Map-like object.
- `endpoints` - Allows you to set the specific OAuth2 endpoints for `authorization` and getting the access token (`token`)
- `callbacks` - Allows you to set a callback function for the `authorize` step, e.g. by doing a full page redirect or using a new window. The callback function takes one parameter, the authorization URL to use.

## Defaults

Only the `client_id` and `client_secret` don't have valid defaults. The defaults are:

- `grant_type`: `authorization_code`
- `force_authorization`: false
- `redirect_uri`: `document.location`
- `state`:`localStorage`
- `tokens`: `localStorage`
- `client`: `metro.client().with(jsonmw())`
- `callbacks.authorize`: `url => document.location = url`
- `endpoints.authorize`: `/authorize`
- `endpoints.token`: `/token`

22 changes: 21 additions & 1 deletion docs/middleware/oauth2mock.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# OAuth2 mock middleware
# OAuth2 Mock Middleware

The `oauth2mock` middleware implements a mock of an OAuth2 server. It doesn't actually call `fetch()` or `next()`, so no network requests are made. Instead it parses the request and implements a very basic OAuth2 authorization_code flow.

The `oauth2mock` server handles requests with the following pathnames--regardless of the domain used.

- `/authorize/` - returns an authorization_code
- `/token/` - returns an access_token
- `/protected/` - requires an access_token, or returns 401 Forbidden
- `/public/` - doesn't require an access_token

Any other requests will return a 404 Not Found response.

The OAuth2 mock server expects/provides the following values for the OAuth2 settings:

- `client_id`: `mockClientId`
- `client_secret`: `mockClientSecret`
- `authorization_code`: `mockAuthorizeToken`
- `refresh_token`: `mockRefreshToken`
- `access_token`: `mockAccessToken`

2 changes: 1 addition & 1 deletion src/mw/oauth2.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function oauth2mw(options) {
}

const oauth2 = {
tokens: new Map(),
tokens: localStorage,
state: localState,
endpoints: {
authorize: '/authorize',
Expand Down
4 changes: 2 additions & 2 deletions src/mw/oauth2.mock.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function oauth2mock(req, next) {
case '/authorize/':
if (error = assert.fails(url.searchParams, {
response_type: 'code',
client_id: 'clientId',
client_id: 'mockClientId',
state: assert.optional(/.*/)
})) {
return metro.response(badRequest(error))
Expand All @@ -52,7 +52,7 @@ export default function oauth2mock(req, next) {
switch(url.searchParams.grant_type) {
case 'refresh_token':
if (error = assert.fails(url.searchParams, {
refresh_token: 'mockRefresh',
refresh_token: 'mockRefreshToken',
client_id: 'mockClientId',
client_secret: 'mockClientSecret'
})) {
Expand Down

0 comments on commit 6b8d7d7

Please sign in to comment.