# @edirect/auth

Authentication and authorization module for eDirect NestJS applications. Supports two auth providers — **Keycloak** (OIDC/JWT) and a **custom Auth Service** — with guards, middleware, decorators, and multi-tenant realm support.

## Features

- Two provider strategies: Keycloak and custom Auth Service
- NestJS Guards and Middleware for request-level auth enforcement
- Role, Permission, and Resource decorators for fine-grained access control
- Token Exchange middleware for cross-service impersonation flows
- Multi-tenant support: per-realm environment variable overrides
- Token caching via `AuthCacheService`
- JWKS-based token validation with OIDC well-known discovery
- Type-safe request interfaces (`AuthenticatedRequestInterface`, `UserInterface`, `TokenInterface`)

## Installation

```sh
pnpm add @edirect/auth
# or
npm install @edirect/auth
```

## Provider Options

### Option A: Keycloak

```ts
import { Module } from '@nestjs/common';
import { KeycloakAuthModule } from '@edirect/auth';

@Module({
  imports: [KeycloakAuthModule],
})
export class AppModule {}
```

```ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { KeycloakAuthGuard, Permissions, Roles } from '@edirect/auth';

@Controller('policies')
export class PoliciesController {
  @Get()
  @UseGuards(KeycloakAuthGuard)
  @Roles('agent', 'admin')
  @Permissions('read:policy')
  findAll() {
    return [];
  }
}
```

### Option B: Custom Auth Service

```ts
import { Module } from '@nestjs/common';
import { AuthServiceAuthModule } from '@edirect/auth';

@Module({
  imports: [AuthServiceAuthModule],
})
export class AppModule {}
```

```ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard, Roles } from '@edirect/auth';

@Controller('quotes')
export class QuotesController {
  @Get()
  @UseGuards(AuthGuard)
  @Roles('agent')
  findAll() {
    return [];
  }
}
```

## Decorators

| Decorator                  | Description                              |
| -------------------------- | ---------------------------------------- |
| `@Roles(...roles)`         | Require one of the specified roles       |
| `@Permissions(...perms)`   | Require one of the specified permissions |
| `@Resources(...resources)` | Require access to specific resources     |

## Middleware

For Express/NestJS middleware usage (without guards):

```ts
// Keycloak
import { KeycloakAuthMiddleware } from '@edirect/auth';

consumer
  .apply(KeycloakAuthMiddleware)
  .forRoutes({ path: '/**', method: RequestMethod.ALL });
```

```ts
// Token Exchange (for service-to-service delegation)
import { KeycloakAuthTokenExchangeMiddleware } from '@edirect/auth';

consumer
  .apply(KeycloakAuthTokenExchangeMiddleware)
  .forRoutes({ path: '/internal/**', method: RequestMethod.ALL });
```

## Authenticated Request

Once authentication middleware or guard runs, `req.user` is populated:

```ts
import { AuthenticatedRequestInterface } from '@edirect/auth';

@Get('me')
@UseGuards(KeycloakAuthGuard)
getProfile(@Req() req: AuthenticatedRequestInterface) {
  return req.user; // UserInterface
}
```

## Environment Variables

### Keycloak

| Variable                 | Description                    |
| ------------------------ | ------------------------------ |
| `KEYCLOAK_BASE_URL`      | Keycloak server base URL       |
| `KEYCLOAK_REALM`         | Realm name                     |
| `KEYCLOAK_CLIENT_ID`     | Client ID                      |
| `KEYCLOAK_CLIENT_SECRET` | Client secret                  |
| `KEYCLOAK_TIMEOUT`       | Request timeout (ms, optional) |

### Multi-Tenant Realm Override

For multi-tenant deployments, override per realm using the pattern `KEYCLOAK_<REALM>_<VAR>`:

```env
KEYCLOAK_TH_BROKER_CLIENT_ID=my-client-th
KEYCLOAK_TH_BROKER_CLIENT_SECRET=secret-th
KEYCLOAK_TH_BROKER_BASE_URL=https://keycloak.th.example.com
```

### Custom Auth Service

| Variable             | Description                     |
| -------------------- | ------------------------------- |
| `AUTH_SERVICE_URL`   | Base URL of the auth service    |
| `AUTH_SERVICE_TOKEN` | Service token for internal auth |

## Exports

```ts
// Modules
export {
  AuthModule,
  AuthServiceAuthModule,
  KeycloakAuthModule,
} from '@edirect/auth';

// Guards
export { AuthGuard, KeycloakAuthGuard } from '@edirect/auth';

// Middleware
export {
  AuthMiddleware,
  KeycloakAuthMiddleware,
  KeycloakAuthTokenExchangeMiddleware,
} from '@edirect/auth';

// Decorators
export { Permissions, Roles, Resources } from '@edirect/auth';

// Services
export { AuthService, ServerAuthService } from '@edirect/auth';

// Interfaces
export type {
  UserInterface,
  TokenInterface,
  EntityInterface,
  AuthenticatedRequestInterface,
  AuthServiceInterface,
  ServerAuthServiceInterface,
} from '@edirect/auth';
```
