import type { TSecretResolver } from './interfaces.js'; /** * RADIUS Shared Secrets Manager * Manages per-client shared secrets for RADIUS authentication */ export class RadiusSecrets { private readonly secrets: Map = new Map(); private defaultSecret?: string; private customResolver?: TSecretResolver; /** * Create a new secrets manager */ constructor(options?: { defaultSecret?: string; secrets?: Record; resolver?: TSecretResolver; }) { if (options?.defaultSecret) { this.defaultSecret = options.defaultSecret; } if (options?.secrets) { for (const [ip, secret] of Object.entries(options.secrets)) { this.secrets.set(ip, secret); } } if (options?.resolver) { this.customResolver = options.resolver; } } /** * Set secret for a specific client IP */ public setClientSecret(clientIp: string, secret: string): void { this.secrets.set(clientIp, secret); } /** * Remove secret for a specific client IP */ public removeClientSecret(clientIp: string): boolean { return this.secrets.delete(clientIp); } /** * Set the default secret */ public setDefaultSecret(secret: string): void { this.defaultSecret = secret; } /** * Set a custom resolver */ public setResolver(resolver: TSecretResolver): void { this.customResolver = resolver; } /** * Get secret for a client IP * Priority: 1. Custom resolver, 2. Per-client secret, 3. Default secret */ public getSecret(clientIp: string): string | undefined { // Try custom resolver first if (this.customResolver) { const resolved = this.customResolver(clientIp); if (resolved !== undefined) { return resolved; } } // Try per-client secret const clientSecret = this.secrets.get(clientIp); if (clientSecret !== undefined) { return clientSecret; } // Fall back to default secret return this.defaultSecret; } /** * Check if a client is known (has a secret) */ public isKnownClient(clientIp: string): boolean { return this.getSecret(clientIp) !== undefined; } /** * Get all registered client IPs */ public getClientIps(): string[] { return Array.from(this.secrets.keys()); } /** * Clear all per-client secrets */ public clearClientSecrets(): void { this.secrets.clear(); } /** * Set secrets from a CIDR range (simplified - just IP addresses) * For actual CIDR support, use a custom resolver */ public setSecretsForNetwork(network: string, secret: string): void { // For simplicity, this just sets a single IP // Real CIDR support would require a resolver this.secrets.set(network, secret); } } export default RadiusSecrets;