# @applica-software-guru/iam-client

TypeScript client for the Applica IAM service. Provides a centralized, framework-agnostic `IamClient` with dedicated services for each entity, plus a React Admin adapter.

| Info       | Details                                      |
| ---------- | -------------------------------------------- |
| Version    | 5.0.\*                                       |
| Author     | Roberto Conte Rosito (Applica)               |
| Repository | https://bitbucket.org/applicaguru/iam-client |
| License    | MIT                                          |

## Installation

```bash
npm install @applica-software-guru/iam-client
```

## Quick Start

```typescript
import { createIamClient } from '@applica-software-guru/iam-client';

const iam = createIamClient({
  apiUrl: 'https://server.com/api',
  apiKey: 'your-system-api-key' // optional, see "Authentication" below
});

await iam.auth.login({ username: 'user@test.com', password: 'secret' });
const tenants = await iam.tenants.search({ keyword: 'test' });
const { user } = await iam.users.getById('user-id');
await iam.roles.register({ code: 'EDITOR', name: 'Editor', permissions: ['read', 'write'] });
```

## Authentication

The IAM backend uses three security chains with different authentication requirements:

| Endpoints                                               | Auth required               | Notes                                                                                                |
| ------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------- |
| `/auth/**`                                              | None                        | Public endpoints (login, register, activate, recover)                                                |
| `/tenants/**`                                           | **System API key only**     | Requires `x-api-key` header matching the server's `iam.api-key`. Bearer tokens are **not** accepted. |
| `/users/**`, `/roles/**`, `/projects/**`, `/devices/**` | Bearer token **or** API key | Any of these methods works: JWT from login, system API key, or tenant API key                        |

### How authentication works in the client

When you set `apiKey` on the client, the `x-api-key` header is sent on **every** request. When a user is logged in, the `Authorization: Bearer <token>` header is also sent. The API key takes priority if both are present.

**Scenario 1 — Server-side / admin scripts (no user login):**

Use the system API key. This grants `ROLE_SYSTEM` and gives access to all endpoints including `/tenants/**`:

```typescript
const iam = createIamClient({
  apiUrl: 'https://server.com/api',
  apiKey: 'your-system-api-key'
});

// No login needed — the API key authenticates all requests
await iam.tenants.register({ code: 'new-tenant', name: 'New Tenant' });
await iam.users.search({});
await iam.roles.register({ code: 'EDITOR', name: 'Editor' });
```

**Scenario 2 — Browser app with logged-in user:**

After login, the Bearer token authenticates requests to `/users/**`, `/roles/**`, `/projects/**`, `/devices/**`. No API key needed for these endpoints:

```typescript
const iam = createIamClient({ apiUrl: 'https://server.com/api' });

await iam.auth.login({ username: 'admin@test.com', password: 'secret' });

// These work with the Bearer token from login
await iam.users.search({});
await iam.roles.register({ code: 'EDITOR', name: 'Editor' });
await iam.projects.search({});

// This will FAIL — /tenants/** requires the system API key, not a Bearer token
await iam.tenants.search({}); // ❌ 403
```

**Scenario 3 — Browser app that also needs tenant management:**

Provide both. The API key handles `/tenants/**`, the Bearer token handles everything else (or the API key handles everything):

```typescript
const iam = createIamClient({
  apiUrl: 'https://server.com/api',
  apiKey: 'your-system-api-key'
});

await iam.auth.login({ username: 'admin@test.com', password: 'secret' });

// All endpoints work
await iam.tenants.search({});
await iam.users.search({});
```

### What is the system API key and where to find it

The system API key is configured server-side in the IAM backend's `application.yaml`:

```yaml
iam:
  api-key: 'your-secret-key-here'
```

This is the master key that grants `ROLE_SYSTEM` access. It is set by the server administrator and should be treated as a secret. The `GodAuthenticationFilter` on the backend reads the `x-api-key` header from incoming requests and compares it against this configured value.

There is no API endpoint to generate or rotate this key — it is a static configuration value managed at deployment time. To change it, update the `iam.api-key` property in the server configuration and restart the IAM service.

> **Important:** The system API key gives unrestricted access to all endpoints. Never expose it in client-side browser code in production. It is intended for server-to-server communication, admin scripts, and development environments.

### Tenant API keys

In addition to the system API key, each tenant can have its own API key (configured via `setup.tenants[].api-key` in `application.yaml`). A tenant API key authenticates requests to `/users/**`, `/roles/**`, `/projects/**`, `/devices/**` with the tenant's configured roles, but does **not** grant access to `/tenants/**`.

## Architecture

```
IamClient
  ├── auth: AuthService          → /auth/*
  ├── users: UserService         → /users/*
  ├── tenants: TenantService     → /tenants/*
  ├── projects: ProjectService   → /projects/*
  ├── roles: RoleService         → /roles/*
  └── devices: DeviceService     → /devices/*
```

## Documentation

| Topic                                                 | Description                                       |
| ----------------------------------------------------- | ------------------------------------------------- |
| [Getting Started](docs/getting-started.md)            | Installation, configuration, entry points         |
| [Architecture](docs/architecture.md)                  | IamClient structure, HttpClient, project layout   |
| [AuthService](docs/auth-service.md)                   | Authentication, session, impersonation, PIN login |
| [UserService](docs/user-service.md)                   | User CRUD, roles, tenant/project assignment       |
| [TenantService](docs/tenant-service.md)               | Tenant CRUD (requires system API key)             |
| [ProjectService](docs/project-service.md)             | Project CRUD within tenants                       |
| [RoleService](docs/role-service.md)                   | Role and permission management                    |
| [DeviceService](docs/device-service.md)               | Device management for PIN authentication          |
| [Error Handling & Pagination](docs/error-handling.md) | FailureResponse, error codes, pagination          |
| [Storage](docs/storage.md)                            | LocalStorage, MemoryStorage, custom IStorage      |
| [React Admin](docs/react-admin.md)                    | ApplicaAuthProvider, getClient()                  |
| [Type Reference](docs/types.md)                       | All TypeScript types and DTOs                     |

## Scripts

```bash
npm run build     # Build with Vite
npm test          # Run tests with Vitest
npm run eslint    # Lint with ESLint
npm run format    # Format with Prettier
```

## License

MIT
