import type { IAuthConfig, IAuthToken, ICredentials, TRegistryProtocol } from './interfaces.core.js'; import type { IAuthProvider, ITokenOptions } from './interfaces.auth.js'; import { DefaultAuthProvider } from './classes.defaultauthprovider.js'; /** * Unified authentication manager for all registry protocols. * Delegates to a pluggable IAuthProvider for actual auth operations. * * @example * ```typescript * // Use default in-memory provider * const auth = new AuthManager(config); * * // Use custom provider (LDAP, OAuth, etc.) * const auth = new AuthManager(config, new LdapAuthProvider(ldapClient)); * ``` */ export class AuthManager { private provider: IAuthProvider; constructor( private config: IAuthConfig, provider?: IAuthProvider ) { // Use provided provider or default in-memory implementation this.provider = provider || new DefaultAuthProvider(config); } /** * Initialize the auth manager */ public async init(): Promise { if (this.provider.init) { await this.provider.init(); } } // ======================================================================== // UNIFIED AUTHENTICATION (Delegated to Provider) // ======================================================================== /** * Authenticate user credentials * @param credentials - Username and password * @returns User ID or null */ public async authenticate(credentials: ICredentials): Promise { return this.provider.authenticate(credentials); } /** * Validate any token (NPM, Maven, OCI, PyPI, RubyGems, Composer, Cargo) * @param tokenString - Token string (UUID or JWT) * @param protocol - Expected protocol type (optional, improves performance) * @returns Auth token object or null */ public async validateToken( tokenString: string, protocol?: TRegistryProtocol ): Promise { return this.provider.validateToken(tokenString, protocol); } /** * Check if token has permission for an action * @param token - Auth token (or null for anonymous) * @param resource - Resource being accessed (e.g., "npm:package:foo") * @param action - Action being performed (read, write, push, pull, delete) * @returns true if authorized */ public async authorize( token: IAuthToken | null, resource: string, action: string ): Promise { return this.provider.authorize(token, resource, action); } // ======================================================================== // NPM AUTHENTICATION // ======================================================================== /** * Create an NPM token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns NPM UUID token */ public async createNpmToken(userId: string, readonly: boolean = false): Promise { if (!this.config.npmTokens.enabled) { throw new Error('NPM tokens are not enabled'); } return this.provider.createToken(userId, 'npm', { readonly }); } /** * Validate an NPM token * @param token - NPM UUID token * @returns Auth token object or null */ public async validateNpmToken(token: string): Promise { return this.provider.validateToken(token, 'npm'); } /** * Revoke an NPM token * @param token - NPM UUID token */ public async revokeNpmToken(token: string): Promise { return this.provider.revokeToken(token); } /** * List all tokens for a user * @param userId - User ID * @returns List of token info (without actual token values) */ public async listUserTokens(userId: string): Promise> { if (this.provider.listUserTokens) { return this.provider.listUserTokens(userId); } return []; } // ======================================================================== // OCI AUTHENTICATION (JWT) // ======================================================================== /** * Create an OCI JWT token * @param userId - User ID * @param scopes - Permission scopes * @param expiresIn - Expiration time in seconds * @returns JWT token string */ public async createOciToken( userId: string, scopes: string[], expiresIn: number = 3600 ): Promise { if (!this.config.ociTokens?.enabled) { throw new Error('OCI tokens are not enabled'); } return this.provider.createToken(userId, 'oci', { scopes, expiresIn }); } /** * Validate an OCI JWT token * @param jwt - JWT token string * @returns Auth token object or null */ public async validateOciToken(jwt: string): Promise { return this.provider.validateToken(jwt, 'oci'); } // ======================================================================== // MAVEN AUTHENTICATION // ======================================================================== /** * Create a Maven token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns Maven UUID token */ public async createMavenToken(userId: string, readonly: boolean = false): Promise { return this.provider.createToken(userId, 'maven', { readonly }); } /** * Validate a Maven token * @param token - Maven UUID token * @returns Auth token object or null */ public async validateMavenToken(token: string): Promise { return this.provider.validateToken(token, 'maven'); } /** * Revoke a Maven token * @param token - Maven UUID token */ public async revokeMavenToken(token: string): Promise { return this.provider.revokeToken(token); } // ======================================================================== // COMPOSER TOKEN MANAGEMENT // ======================================================================== /** * Create a Composer token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns Composer UUID token */ public async createComposerToken(userId: string, readonly: boolean = false): Promise { return this.provider.createToken(userId, 'composer', { readonly }); } /** * Validate a Composer token * @param token - Composer UUID token * @returns Auth token object or null */ public async validateComposerToken(token: string): Promise { return this.provider.validateToken(token, 'composer'); } /** * Revoke a Composer token * @param token - Composer UUID token */ public async revokeComposerToken(token: string): Promise { return this.provider.revokeToken(token); } // ======================================================================== // CARGO TOKEN MANAGEMENT // ======================================================================== /** * Create a Cargo token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns Cargo UUID token */ public async createCargoToken(userId: string, readonly: boolean = false): Promise { return this.provider.createToken(userId, 'cargo', { readonly }); } /** * Validate a Cargo token * @param token - Cargo UUID token * @returns Auth token object or null */ public async validateCargoToken(token: string): Promise { return this.provider.validateToken(token, 'cargo'); } /** * Revoke a Cargo token * @param token - Cargo UUID token */ public async revokeCargoToken(token: string): Promise { return this.provider.revokeToken(token); } // ======================================================================== // PYPI AUTHENTICATION // ======================================================================== /** * Create a PyPI token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns PyPI UUID token */ public async createPypiToken(userId: string, readonly: boolean = false): Promise { return this.provider.createToken(userId, 'pypi', { readonly }); } /** * Validate a PyPI token * @param token - PyPI UUID token * @returns Auth token object or null */ public async validatePypiToken(token: string): Promise { return this.provider.validateToken(token, 'pypi'); } /** * Revoke a PyPI token * @param token - PyPI UUID token */ public async revokePypiToken(token: string): Promise { return this.provider.revokeToken(token); } // ======================================================================== // RUBYGEMS AUTHENTICATION // ======================================================================== /** * Create a RubyGems token * @param userId - User ID * @param readonly - Whether the token is readonly * @returns RubyGems UUID token */ public async createRubyGemsToken(userId: string, readonly: boolean = false): Promise { return this.provider.createToken(userId, 'rubygems', { readonly }); } /** * Validate a RubyGems token * @param token - RubyGems UUID token * @returns Auth token object or null */ public async validateRubyGemsToken(token: string): Promise { return this.provider.validateToken(token, 'rubygems'); } /** * Revoke a RubyGems token * @param token - RubyGems UUID token */ public async revokeRubyGemsToken(token: string): Promise { return this.provider.revokeToken(token); } }