npm package: @revas-hq/kit-auth
Description: The `@revas-hq/kit-auth` package provides middleware and utilities for handling Bearer token authentication within the Revas Kit ecosystem. It integrates with `@revas-hq/kit-context`, `@revas-hq/kit-http`, `@revas-hq/kit-endpoint`, and `@revas-hq/kit-fetc
Latest version: 0.0.16

# Revas Kit: Auth (`@revas-hq/kit-auth`)

The `@revas-hq/kit-auth` package provides middleware and utilities for handling Bearer token authentication within the Revas Kit ecosystem. It integrates with `@revas-hq/kit-context`, `@revas-hq/kit-http`, `@revas-hq/kit-endpoint`, and `@revas-hq/kit-fetch`.

## Features

- **HTTP Header Capture:** Middleware (`RequestFunction`) to extract Bearer tokens from the `Authorization` header and store them in the `Context`.
- **Context-Based Token Retrieval:** A `ContextTokenFunction` factory to retrieve stored tokens from the `Context`.
- **Endpoint Authorization:** Middleware (`EndpointMiddleware`) to protect endpoints, ensuring a valid token is present before executing business logic.
- **Fetch Middleware:** Middleware (`ContextFetchMiddleware`) to automatically add the `Authorization: Bearer <token>` header to outgoing `fetch` requests made via `kit-fetch`.
- **Type Safety:** Uses discriminated unions (`TokenResult`) for safe handling of token retrieval outcomes.
- **Observability:** Includes basic OpenTelemetry span creation for authorization checks and authorized fetch requests.

## Installation

```bash
npm install @revas-hq/kit-auth @revas-hq/kit-context @revas-hq/kit-endpoint @revas-hq/kit-http @revas-hq/kit-fetch
# or
yarn add @revas-hq/kit-auth @revas-hq/kit-context @revas-hq/kit-endpoint @revas-hq/kit-http @revas-hq/kit-fetch
```
> Requires other Revas Kit packages it integrates with

## Core Concepts

### Token Source (`TokenFunction` / `ContextTokenFunction`)

An abstraction for how authentication tokens are obtained (e.g., read from context, refreshed via API call). This package provides a source for reading tokens captured from the Authorization header.

### Token Result (`TokenResult`)

A discriminated union indicating the success (`{ success: true, accessToken, tokenType }`) or failure (`{ success: false, error }`) of retrieving a token.

### HTTP Request Capture

A kit-http `RequestFunction` (`captureAuthorizationHeader`) runs early in the request lifecycle to parse the Authorization header and populate the context.

### Endpoint Protection

A kit-endpoint `EndpointMiddleware` (`createAuthorizeMiddleware`) uses a `TokenFunction` to guard access to specific endpoints.

### Outgoing Request Enhancement

A kit-fetch `ContextFetchMiddleware` (`createAuthorizedFetchMiddleware`) uses a `TokenFunction` to add the auth header to client-side or server-to-server requests.

## Key Types

```typescript
import type { Context } from '@revas-hq/kit-context';

// --- Token Retrieval Outcome (Discriminated Union) ---
export interface TokenSuccessResult { success: true; accessToken: string; tokenType: string; error?: undefined; }
export interface TokenFailureResult { success: false; error: Error; accessToken?: undefined; tokenType?: undefined; }
export type TokenResult = TokenSuccessResult | TokenFailureResult;

// --- Token Retrieval Function ---
export type TokenFunction = () => Promise<TokenResult>;
export type ContextTokenFunction = (context: Context) => TokenFunction;
```

## Provided Utilities & Middleware

### `AUTH_TOKEN_CONTEXT_KEY`

The string key (`'authToken'`) used to store the parsed Bearer token value within the kit-context.

```typescript
import { AUTH_TOKEN_CONTEXT_KEY } from '@revas-hq/kit-auth';
// Use with context.getValue<string>(AUTH_TOKEN_CONTEXT_KEY) if needed directly
```

### `captureAuthorizationHeader`

A `RequestFunction` (for use with kit-http's `beforeFunctions`) that reads the `Authorization: Bearer <token>` header, validates the format, and stores the `<token>` part in the context under `AUTH_TOKEN_CONTEXT_KEY`. If the header is missing or invalid, it either passes through (no token) or returns a 400 `TransportError`.

```typescript
import { captureAuthorizationHeader } from '@revas-hq/kit-auth';
// Use in createLoader/createAction:
// beforeFunctions: [captureAuthorizationHeader, /* other functions... */]
```

### `hasToken(context: Context)`

A utility function to check if a non-empty token string exists in the context under `AUTH_TOKEN_CONTEXT_KEY`. Returns boolean.

```typescript
import { hasToken } from '@revas-hq/kit-auth';
// if (hasToken(context)) { /* ... */ }
```

### `createAuthorizationHeaderTokenSource()`

A factory that returns a `ContextTokenFunction`. The created function, when invoked, retrieves the token string stored by `captureAuthorizationHeader` from the context and returns a `TokenResult` (success with the token and type "Bearer", or failure if not found).

```typescript
import { createAuthorizationHeaderTokenSource } from '@revas-hq/kit-auth';
const contextTokenSource: ContextTokenFunction = createAuthorizationHeaderTokenSource();
// Usage: const tokenFunc = contextTokenSource(specificContext); const result = await tokenFunc();
```

### `createAuthorizeMiddleware(tokenSourceFactory: ContextTokenFunction)`

Creates an `EndpointMiddleware` that protects an endpoint. It uses the provided `tokenSourceFactory` to get a `TokenFunction` for the current request's context. It invokes the `TokenFunction`:

- If token retrieval fails (throws or returns `{ success: false }`), it returns an "Unauthenticated" `EndpointFailureResult` (code 16/401).
- If token retrieval succeeds, it calls the next endpoint in the chain.

```typescript
import { createAuthorizeMiddleware, createAuthorizationHeaderTokenSource } from '@revas-hq/kit-auth';
import type { Endpoint } from '@revas-hq/kit-endpoint';

const tokenSource = createAuthorizationHeaderTokenSource();
const authorize = createAuthorizeMiddleware(tokenSource); // Creates the EndpointMiddleware

// Apply to an endpoint:
// const myProtectedEndpoint = authorize(myOriginalEndpoint);
```

> Note: This middleware is generic and preserves the TRequest/TResponse types of the endpoint it wraps.

### `createAuthorizedFetchMiddleware(tokenSourceFactory: ContextTokenFunction)`

Creates a `ContextFetchMiddleware` factory (for use with kit-fetch). The resulting middleware enhances fetch calls:

- It uses the provided `tokenSourceFactory` to get a `TokenFunction` for the current context.
- It invokes the `TokenFunction` before the fetch call.
- If token retrieval fails (throws or returns `{ success: false }`), it throws an Error (mimicking native fetch failure during request preparation).
- If token retrieval succeeds, it adds the `Authorization: <tokenType> <accessToken>` header to the outgoing request before calling next(fetch).
- Includes OpenTelemetry client spans for the outgoing request.

```typescript
import { createAuthorizedFetchMiddleware, createAuthorizationHeaderTokenSource } from '@revas-hq/kit-auth';
import { createContextFetch } from '@revas-hq/kit-fetch';

const tokenSource = createAuthorizationHeaderTokenSource();
const addAuthHeader = createAuthorizedFetchMiddleware(tokenSource); // Creates the ContextFetchMiddleware factory

// Use with createContextFetch:
// const createApiFetch = createContextFetch(
//    addApiBaseUrl, // other middleware
//    addAuthHeader
// );
// const apiFetch = createApiFetch(specificContext);
// await apiFetch('/protected/resource'); // Auth header added automatically
```

## Usage Example (Putting it Together)

See the README for `@revas-hq/kit-http-react-router` for an example showing how `captureAuthorizationHeader` (as a beforeFunction) and `createAuthorizeMiddleware` (wrapping an Endpoint) are used within `createLoader`.

See the README for `@revas-hq/kit-fetch` for an example showing how `createAuthorizedFetchMiddleware` is used with `createContextFetch` to enhance client-side requests.

## License

This project is licensed under the MIT License. See the LICENSE file for details.