# hapi-oidc-auth

OpenID Connect auth plugin for [hapi](https://hapijs.com/).

Uses token introspection to verify tokens and get their details.

```sh
npm install @boundstate/hapi-oidc-auth
```

## Usage

```typescript
import * as Hapi from '@hapi/hapi';
import {hapiOidcAuth} from '@boundstate/hapi-oidc-auth';

const server = new Hapi.Server();

await server.register({
  plugin: hapiOidcAuth,
  options: {
    issuer: 'https://sso.example.com',
    clientMetadata: {
      client_id: 'my-app-id',
      client_secret: 'my-app-secret',
    },
  },
});
```

### Dynamic client registration

Instead of specifying the client id and secret, you may provide configuration for dynamic registration:

```typescript
await server.register({
  plugin: hapiOidcAuth,
  options: {
    issuer: 'https://sso.example.com',
    clientMetadata: fs.existsSync(oidcMetadataPath)
      ? JSON.parse(fs.readFileSync(oidcMetadataPath, {encoding: 'utf8'}))
      : undefined,
    dynamicRegistration: {
      initialAccessToken: 'secret',
      clientMetadata: {
        grant_types: […],
        redirect_uris: […],
        response_types: […],
      },
      onRegistered: (metadata: HapiOidcClientMetadata) => {
        fs.writeFileSync(oidcMetadataPath, JSON.stringify(metadata, null, 2));
      },
    },
  },
});
```

### Plugin options

- `issuer`: OpenID provider URL (used for discovery)
- `allowQueryToken`: (*optional*, default: `false`) accept token via query parameter 
- `clientMetadata`: (*optional*) Client metadata
  - `client_id`: Client ID
  - `client_secret`: Client secret
- `dynamicRegistration`: (*optional*) dynamic registration options
  - `initialAccessToken`: access token used for registration
  - `clientMetadata`: Client metadata for registration
  - `verify`: (*optional*, default: `false`) verify client when server starts and attempt registration if necessary
  - `onRegistered`: callback when registration succeeds
