const EveAIApiClient = require('./api_client'); const handleError = (z, error) => { // Log the full error for debugging z.console.error('Authentication error:', { message: error.message, response: error.response ? { status: error.response.status, data: error.response.data, headers: error.response.headers } : 'No response', stack: error.stack }); // If we have a response with a message from the API, use it if (error.response) { if (error.response.status) { switch (error.response.status) { case 400: throw new Error('Invalid request. Please verify your Tenant ID and API Key format.'); case 401: throw new Error('Authentication failed. Please verify your credentials and ensure your API Key is active.'); case 403: throw new Error('Access forbidden. Your API Key may not have the required permissions.'); case 404: throw new Error('Authentication service not found. Please verify the API URL.'); case 429: throw new Error('Too many authentication attempts. Please try again later.'); case 500: throw new Error('EveAI server encountered an error. Please try again later.'); default: throw new Error(`Unexpected error (${error.response.status}). Please contact support if this persists.`); } } // If we have error data but no status, try to use the error message if (error.response.data) { if (error.response.data.message) { throw new Error(`API Error: ${error.response.data.message}`); } if (typeof error.response.data === 'string') { throw new Error(`API Error: ${error.response.data}`); } } } // Handle network errors if (error.message.includes('ECONNREFUSED')) { throw new Error('Unable to connect to EveAI. Please check your network connection.'); } if (error.message.includes('ETIMEDOUT')) { throw new Error('Connection to EveAI timed out. Please try again.'); } // Generic error for unhandled cases throw new Error(`Authentication failed: ${error.message}`); }; const testAuth = async (z, bundle) => { try { const client = new EveAIApiClient(z, bundle); await client.ensure_valid_token(); // Make a test request to verify the token works const response = await client.make_request('GET', '/auth/verify'); // Log successful authentication z.console.log('Authentication successful', { tenant_id: bundle.authData.tenant_id, token_prefix: bundle.authData.access_token.substring(0, 10) + '...', expiry: new Date(bundle.authData.token_expiry * 1000).toISOString() }); return response; } catch (error) { // Use our enhanced error handler handleError(z, error); } }; module.exports = { type: 'session', fields: [ { helpText: "The tenant_id provided to you by email, or to be created / retrieved in Evie's administrative interface (https://evie.askeveai.com/admin)", computed: false, key: 'tenant_id', required: true, label: 'Tenant ID', type: 'string', }, { helpText: "The api_key provided to you by email, or to be created / retrieved in Evie's administrative interface (https://evie.askeveai.com/admin)", computed: false, key: 'api_key', required: true, label: 'API Key', type: 'password', }, ], sessionConfig: { perform: async (z, bundle) => { try { const client = new EveAIApiClient(z, bundle); const token = await client.ensure_valid_token(); z.console.log('Session token obtained', { token_prefix: token.substring(0, 10) + '...', expiry: new Date(bundle.authData.token_expiry * 1000).toISOString() }); return { access_token: token, token_expiry: bundle.authData.token_expiry }; } catch (error) { handleError(z, error); } } }, test: testAuth, };