npm package: @raddiamond/nexauth-core
Description: Core authentication plugin supporting Local, AD authentication
Author: Raddiamond LTD
Latest version: 0.2.1

# NexAuth Core

A pluggable authentication core supporting **Local**, **Active Directory (AD/LDAP)**, and **UI-based** login strategies. Designed for multi-tenant or flexible backend environments using TypeScript and TypeORM.

---

## 🔧 Installation

```bash
npm install @raddiamond/nexauth-core
```

---

## ✨ Features

- 🔐 Local database-backed authentication
- 🧑‍💼 Active Directory (LDAP) login support
- 🖥️ React UI components for authentication
- 🏢 Multi-tenant support with client secrets
- ⚡ Custom user entity support
- 🔄 Full control over how users and roles are resolved
- 🧪 Drop-in compatibility with `passport` via a custom strategy

---

## 🧠 Overview

This library expects a `TenantContext` object to define the authentication method (local, AD, or UI) and its required configuration. It supports:

- Your own user entity via `LocalUserLookupOptions`
- External LDAP servers via `ADUserLookupOptions`
- UI-based authentication via `UIProviderConfig`
- Client secrets for secure communication
- Custom password field and logic
- Custom role mapping

---

## 🔄 TenantContext Interface

```ts
import { DataSource } from 'typeorm';

export interface TenantContext {
  identityProviderType: 'local' | 'ad' | 'ui';
  dbConnection?: DataSource;
  tenantId?: string;
  clientSecret?: string;

  localUser?: LocalUserLookupOptions<any>;
  adConfig?: {
    url: string;
    bindDN: string;
    bindCredentials: string;
    baseDN: string;
    userLookup: ADUserLookupOptions;
  };
  uiConfig?: UIProviderConfig;
}
```

---

## 🔐 LocalUserLookupOptions

Used when `identityProviderType = 'local'`. This allows authentication against a custom entity (e.g., `User`) in your database.

```ts
export interface LocalUserLookupOptions<T> {
  entity: new () => T;
  matchField: keyof T;
  passwordField?: string; // Defaults to "passwordHash"
  comparePassword?: (plain: string, hashed: string) => Promise<boolean>; // Defaults to bcrypt.compare
  extractRoles?: (user: T) => string[];
}
```

### Example

```ts
import { createIdentityProvider } from '@raddiamond/nexauth-core';
import { User } from './entities/User';
import dataSource from './db';

const provider = createIdentityProvider({
  identityProviderType: 'local',
  dbConnection: dataSource,
  localUser: {
    entity: User,
    matchField: 'email',
    passwordField: 'encrypted_password',
    extractRoles: (user) => user.roles || [],
  },
});
```

---

## 🧑‍💼 ADUserLookupOptions

Used when `identityProviderType = 'ad'`. This performs authentication via LDAP/AD bind + user search.

```ts
export interface ADUserLookupOptions {
  matchField: string; // e.g., "mail", "sAMAccountName"
  extractRoles?: (ldapUser: Record<string, string>) => string[];
  additionalAttributes?: string[]; // Extra LDAP fields to fetch
}
```

### Example

```ts
import { createIdentityProvider } from '@raddiamond/nexauth-core';

const provider = createIdentityProvider({
  identityProviderType: 'ad',
  adConfig: {
    url: 'ldap://your-ad-server:389',
    bindDN: 'cn=admin,dc=example,dc=org',
    bindCredentials: 'password',
    baseDN: 'dc=example,dc=org',
    userLookup: {
      matchField: 'mail',
      extractRoles: (user) => user.memberOf ? user.memberOf.split(',') : [],
      additionalAttributes: ['memberOf'],
    },
  },
});
```

---

## 🖥️ UI Components

NexAuth Core now includes React components for authentication UIs:

```tsx
import { AuthUI } from '@raddiamond/nexauth-core';

function App() {
  return (
    <AuthUI
      clientId="your-client-id"
      clientSecret="your-client-secret"
      tenantId="your-tenant-id"
      apiUrl="https://your-backend.com/api"
      logo="/path/to/logo.png"
      theme="light"
      showRegister={true}
    />
  );
}
```

See [UI_COMPONENTS.md](./UI_COMPONENTS.md) for full documentation on UI components.

---

## 🏢 Tenant Management

The `TenantManager` class helps manage multiple tenants and client secrets:

```ts
import { TenantManager } from '@raddiamond/nexauth-core';

// Initialize tenant manager
const tenantManager = new TenantManager();

// Register a tenant
tenantManager.registerTenant('tenant1', {
  identityProviderType: 'local',
  dbConnection: dataSource,
  localUser: {
    entity: User,
    matchField: 'email',
  }
});

// Configure UI provider
const uiConfig = tenantManager.configureUIProvider(
  'tenant1',        // tenantId
  'my-client',      // clientId
  '/auth/callback', // redirectUrl
  ['https://myapp.com'] // allowedOrigins
);

console.log(`Client Secret: ${uiConfig.clientSecret}`);
```

---

## 🧪 Passport Integration

A `NexAuthStrategy` is provided for Passport.js integration:

```ts
import passport from 'passport';
import { NexAuthStrategy } from '@raddiamond/nexauth-core';
import { User } from './entities/User';
import dataSource from './db';

passport.use(
  new NexAuthStrategy(
    {
      field: 'username', // form field name
      providerOptions: {
        identityProviderType: 'local',
        dbConnection: dataSource,
        localUser: {
          entity: User,
          matchField: 'email',
          passwordField: 'password',
        },
      },
    },
    (user, done) => {
      done(null, user); // Passport user session
    }
  )
);
```

---

## 🧱 Session Example

```ts
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((user, done) => {
  done(null, user);
});
```

---

## 📄 License

MIT – © Raddiamond LTD