UNPKG

@fairmint/canton-node-sdk

Version:
118 lines 4.97 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthenticationManager = void 0; const axios_1 = __importDefault(require("axios")); const url_1 = require("url"); const errors_1 = require("../errors"); /** Manages OAuth2 authentication and token lifecycle */ class AuthenticationManager { constructor(authUrl, authConfig) { this.authUrl = authUrl; this.authConfig = authConfig; this.bearerToken = null; this.tokenExpiry = null; } async authenticate() { // Check if we have a valid token if (this.isTokenValid()) { return this.bearerToken; } // Check if authentication credentials are provided if (!this.authConfig.clientId || this.authConfig.clientId.trim() === '') { // No authentication credentials provided, skip authentication this.bearerToken = null; return ''; } // Validate required auth configuration this.validateAuthConfig(); const formData = new url_1.URLSearchParams(); formData.append('grant_type', this.authConfig.grantType); formData.append('client_id', this.authConfig.clientId); if (this.authConfig.clientSecret) { formData.append('client_secret', this.authConfig.clientSecret); } if (this.authConfig.audience) { formData.append('audience', this.authConfig.audience); } if (this.authConfig.scope) { formData.append('scope', this.authConfig.scope); } if (this.authConfig.username) { formData.append('username', this.authConfig.username); } if (this.authConfig.password) { formData.append('password', this.authConfig.password); } try { const response = await axios_1.default.post(this.authUrl + '/', formData.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }); if (!response.data.access_token) { throw new errors_1.AuthenticationError(`Authentication response missing access_token. Response: ${JSON.stringify(response.data, null, 2)}`); } this.bearerToken = response.data.access_token; // Set token expiry if provided if (response.data.expires_in) { this.tokenExpiry = Date.now() + (response.data.expires_in * 1000); } return this.bearerToken; } catch (error) { if (axios_1.default.isAxiosError(error)) { const status = error.response?.status; const statusText = error.response?.statusText; const errorData = error.response?.data ? JSON.stringify(error.response.data, null, 2) : error.message; throw new errors_1.ApiError(`Authentication failed with status ${status} ${statusText}: ${errorData}`); } throw new errors_1.AuthenticationError(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`); } } async getBearerToken() { return this.authenticate(); } clearToken() { this.bearerToken = null; this.tokenExpiry = null; } validateAuthConfig() { const missingConfig = []; if (!this.authConfig.clientId) missingConfig.push('clientId'); if (!this.authConfig.grantType) missingConfig.push('grantType'); // Check for grant type specific requirements if (this.authConfig.grantType === 'password') { if (!this.authConfig.username) missingConfig.push('username'); if (!this.authConfig.password) missingConfig.push('password'); } // Note: client_credentials grant type may not always require client_secret // Some providers allow client_credentials without secret for public clients if (missingConfig.length > 0) { throw new errors_1.AuthenticationError(`Authentication configuration incomplete. Missing required fields: ${missingConfig.join(', ')}. ` + `Grant Type: ${this.authConfig.grantType}`); } } isTokenValid() { if (!this.bearerToken) { return false; } // If no expiry is set, assume token is valid if (!this.tokenExpiry) { return true; } // Check if token has expired (with 5 minute buffer) const bufferTime = 5 * 60 * 1000; // 5 minutes return Date.now() < (this.tokenExpiry - bufferTime); } } exports.AuthenticationManager = AuthenticationManager; //# sourceMappingURL=AuthenticationManager.js.map