# Koas Security

Koas security checks if a request matches the security requirement of an operation. For example,
given the following partial OpenAPI document:

```yaml
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
    cookieAuth:
      type: apiKey
      in: cookie
      name: key
    oauth2:
      type: oauth2
      scopes:
        email: Read the user’s email address.
        profile: Get the user’s profile.
paths:
  /me:
    get:
      security:
        - basicAuth: []
          cookieAuth: []
        - oauth2:
            - profile
```

Koas security will make sure the user is either authenticated using HTTP basic authentication
**and** a cookie named `key`, **or** using OAuth2. The first authentication requirement specified in
the document wins.

## Installation

```sh
npm install koa koas-core koas-security
```

## Usage

```js
const Koa = require('koa');
const { koas } = require('koas-core');
const { security } = require('koas-security');

const api = require('./api.json');

const app = new Koa();
app.use(
  koas(api, [
    security({
      // User getters
    }),
  ]),
);
```

This middleware sets the `users` and `clients` variables in the Koa context. These are mappings of
security requirements to authenticated users and OAuth2 clients respectively. Also `user` and
`client` are set to match a single user and client. Since most API calls only require a single
authentication method at a time, this can be used for convenience.

## Options

Koas security takes a mapping of security requirement keys to user get functions. The signature
depends on the type of authentication.

### `apiKey`

The function accepts the API key, and should return the user that is authenticated using that key.

### `http`

| scheme   | Description                                                                                                |
| -------- | ---------------------------------------------------------------------------------------------------------- |
| `basic`  | The function accepts the username and password, and should return the user that matches these credentials. |
| `bearer` | The function accepts the bearer access token, and should return the user that matches these credentials.   |

### `oauth2` / `openIdConnect`

The function accepts the access token, and should return a tuple which consists of the user and the
authenticated OAuth2 client.

## Declaring clients and users

When using TypeScript, the `Clients` and `Users` interfaces can be augmented to map security scheme
to custom types. For example:

```typescript
declare module 'koas-security' {
  interface Users {
    basicAuth: User;
    cookieAuth: User;
    oauth2: User;
  }

  interface Clients {
    oauth2: {
      type: 'oauth2';
      scopes: ('email' | 'profile')[];
    };
  }
}
```
