/** * Multi-Tenant SSO Manager * * Enables dynamic tenant routing for enterprise SSO * Supports Okta, Azure AD, Auth0, and any domain-based OAuth provider */ import type { OAuthProviderConfig, Logger } from '../types.ts'; export interface TenantConfig { /** Unique tenant identifier (e.g., 'acme-corp', 'globex') */ tenantId: string; /** Tenant display name */ name: string; /** OAuth provider type (okta, azure, auth0, etc.) */ provider: 'okta' | 'azure' | 'auth0' | string; /** Provider-specific domain (for Okta/Auth0) or tenant ID (for Azure) */ domain?: string; /** Azure AD specific tenant ID (alternative to domain) */ azureTenantId?: string; /** OAuth client ID for this tenant */ clientId: string; /** OAuth client secret for this tenant */ clientSecret: string; /** Optional: Email domains that belong to this tenant */ emailDomains?: string[]; /** Optional: Custom scopes */ scope?: string; /** Optional: Custom post-login redirect */ postLoginRedirect?: string; /** Optional: Additional provider-specific config */ additionalConfig?: Record; } export interface TenantRegistryEntry { config: TenantConfig; providerConfig: OAuthProviderConfig; } export declare class TenantManager { private tenants; private domainToTenant; private logger?; constructor(logger?: Logger); /** * Register a tenant with their OAuth provider configuration * Supports Okta, Azure AD, Auth0, and custom providers */ registerTenant(tenant: TenantConfig): void; /** * Register multiple tenants at once */ registerTenants(tenants: TenantConfig[]): void; /** * Get tenant by ID * * ⚠️ **Security Warning**: Returns full tenant configuration including clientSecret. * This method is intended for internal use (hooks, OAuth flows) only. * Never expose the returned TenantRegistryEntry directly in HTTP responses. * * @example * // ✅ Safe: Use in hooks/internal logic * const tenant = tenantManager.getTenant(provider); * return { tenantName: tenant?.config.name }; * * // ❌ Unsafe: Direct HTTP exposure * return { tenant: tenantManager.getTenant(id) }; // Leaks clientSecret! */ getTenant(tenantId: string): TenantRegistryEntry | undefined; /** * Get tenant by email domain * * ⚠️ **Security Warning**: Returns full tenant configuration including clientSecret. * This method is intended for internal use (hooks, OAuth flows) only. * Never expose the returned TenantRegistryEntry directly in HTTP responses. */ getTenantByEmail(email: string): TenantRegistryEntry | undefined; /** * Get all registered tenants * * Note: clientSecret is automatically redacted for security. * Secrets are only needed internally for OAuth flows. */ getAllTenants(): TenantConfig[]; /** * Convert tenant configurations to provider registry format * This can be merged with the standard provider registry * * ⚠️ **Security Warning**: Returns provider configurations including clientSecret. * This method is intended for OAuth plugin initialization only. * The returned configs are needed for OAuth token exchange flows. * Never expose these configurations in HTTP responses. */ toProviderRegistry(): Record; /** * Load tenants from configuration * Supports both static config and dynamic loading from database */ static fromConfig(config: { tenants?: TenantConfig[]; logger?: Logger; }): TenantManager; }