UNPKG

@gohcltech/bitbucket-mcp

Version:

Bitbucket integration for Claude via Model Context Protocol

214 lines 8.1 kB
/** * @fileoverview Authentication service for token-based Bitbucket API authentication. * * This module provides a simple, stateless authentication service that supports * two methods of authentication: * 1. API Token Authentication (HTTP Basic Auth with username + token) * 2. Repository Token Authentication (Bearer token) * * Unlike the v1.0 OAuth service, this implementation: * - Does not require token refresh (tokens don't expire) * - Uses simple HTTP Basic Auth or Bearer token authentication * - No persistent web server or callback handling needed * - Stateless and efficient */ import { AuthMethod } from './types.js'; import { AuthCapabilities } from './auth-capabilities.js'; /** * Simple, stateless authentication service for token-based Bitbucket API access. * * Supports dual authentication methods without needing token refresh or persistent storage. * All methods are pure functions that generate auth headers from the configured credentials. * * @example * ```typescript * const authConfig = ConfigManager.getInstance().getAuthConfig(); * const authService = new AuthService(authConfig); * const authHeader = authService.getAuthHeader(); * // Use authHeader in API requests: headers[authHeader.name] = authHeader.value * ``` */ export class AuthService { config; capabilities; /** * Creates a new AuthService instance. * * @param config - Authentication configuration (from ConfigManager) * @throws {Error} If configuration is invalid */ constructor(config) { if (!config) { throw new Error('Authentication configuration is required'); } this.config = config; this.capabilities = new AuthCapabilities(config); } /** * Gets the authentication header for API requests. * * Returns the appropriate header based on the configured authentication method: * - API Token: Returns HTTP Basic Auth header (username:token in base64) * - Repository Token: Returns Bearer token header * * @returns Authorization header object with name and value * @throws {Error} If authentication method is not properly configured */ getAuthHeader() { switch (this.config.method) { case AuthMethod.API_TOKEN: return this.getBasicAuthHeader(); case AuthMethod.REPOSITORY_TOKEN: return this.getBearerAuthHeader(); default: throw new Error(`Unknown authentication method: ${this.config.method}`); } } /** * Gets HTTP Basic Auth header for API Token authentication. * * API Token authentication uses HTTP Basic Auth with username and API token. * The format is: Authorization: Basic base64(username:apiToken) * * @private * @returns Authorization header with Basic auth value * @throws {Error} If API token credentials are missing */ getBasicAuthHeader() { if (this.config.method !== AuthMethod.API_TOKEN) { throw new Error('Invalid authentication method for Basic Auth'); } const username = this.config.username; const apiToken = this.config.apiToken; if (!username || !apiToken) { throw new Error('Username and API token are required for API Token authentication'); } // Create Basic Auth header: base64(username:apiToken) const credentials = `${username}:${apiToken}`; const encodedCredentials = Buffer.from(credentials).toString('base64'); return { name: 'Authorization', value: `Basic ${encodedCredentials}`, }; } /** * Gets Bearer token header for Repository Token authentication. * * Repository Token authentication uses Bearer token authentication. * The format is: Authorization: Bearer <repositoryToken> * * @private * @returns Authorization header with Bearer token value * @throws {Error} If repository token is missing */ getBearerAuthHeader() { if (this.config.method !== AuthMethod.REPOSITORY_TOKEN) { throw new Error('Invalid authentication method for Bearer Auth'); } const repositoryToken = this.config.repositoryToken; if (!repositoryToken) { throw new Error('Repository token is required for Repository Token authentication'); } return { name: 'Authorization', value: `Bearer ${repositoryToken}`, }; } /** * Gets the current authentication method being used. * * @returns The configured authentication method (API_TOKEN or REPOSITORY_TOKEN) */ getAuthMethod() { return this.config.method; } /** * Gets the configured workspace (if any). * * The workspace is an optional configuration that can be used as a default * workspace for API requests when not otherwise specified. * * @returns The configured workspace name, or undefined if not set */ getWorkspace() { return this.config.workspace; } /** * Gets a human-readable description of the current authentication configuration. * * Useful for logging and debugging without exposing sensitive credentials. * Credentials are masked in the output. * * @returns Description of authentication configuration (credentials redacted) */ getAuthDescription() { switch (this.config.method) { case AuthMethod.API_TOKEN: return `API Token (username: ${this.config.username}, token: [REDACTED])`; case AuthMethod.REPOSITORY_TOKEN: return 'Repository Token ([REDACTED])'; default: return 'Unknown authentication method'; } } /** * Validates that the authentication configuration is properly set up. * * This is a basic validation to ensure required fields are present. * More thorough validation (actual token validity) should be done by TokenValidator. * * @returns Object with isValid flag and error messages (if any) */ validate() { const errors = []; if (!this.config) { errors.push('Authentication configuration is missing'); return { isValid: false, errors }; } switch (this.config.method) { case AuthMethod.API_TOKEN: if (!this.config.username) { errors.push('Username is required for API Token authentication'); } if (!this.config.apiToken) { errors.push('API token is required for API Token authentication'); } if (this.config.apiToken && this.config.apiToken.length < 20) { errors.push('API token appears to be too short (minimum 20 characters)'); } break; case AuthMethod.REPOSITORY_TOKEN: if (!this.config.repositoryToken) { errors.push('Repository token is required for Repository Token authentication'); } break; default: errors.push(`Unknown authentication method: ${this.config.method}`); } return { isValid: errors.length === 0, errors, }; } /** * Gets the authentication capabilities for this service. * * Capabilities determine which tools and features are available based on * the authentication method and its associated permissions. * * @returns AuthCapabilities instance with available capabilities and tool access */ getCapabilities() { return this.capabilities; } } /** * Convenience function to create an AuthService from configuration. * * @param config - Authentication configuration * @returns Initialized AuthService instance */ export function createAuthService(config) { return new AuthService(config); } //# sourceMappingURL=auth-service.js.map