import type { NocoDBSettings } from '~/utils/types'; export default defineEventHandler(async (event) => { console.log('[api/admin/nocodb-test.post] ========================='); console.log('[api/admin/nocodb-test.post] POST /api/admin/nocodb-test'); console.log('[api/admin/nocodb-test.post] Request from:', getClientIP(event)); try { // Check admin authorization const sessionManager = createSessionManager(); const cookieHeader = getHeader(event, 'cookie'); const session = sessionManager.getSession(cookieHeader); if (!session?.user) { throw createError({ statusCode: 401, statusMessage: 'Authentication required' }); } // Check if user is admin if (session.user.tier !== 'admin') { throw createError({ statusCode: 403, statusMessage: 'Admin access required' }); } console.log('[api/admin/nocodb-test.post] Admin access confirmed for:', session.user.email); // Get request body - this contains the settings to test const body = await readBody(event) as NocoDBSettings; // Validate required fields if (!body.url || !body.apiKey || !body.baseId || !body.tables || Object.keys(body.tables).length === 0) { return { success: false, message: 'All fields are required to test connection (url, apiKey, baseId, and at least one table)' }; } // Validate URL format if (!body.url.startsWith('http://') && !body.url.startsWith('https://')) { return { success: false, message: 'URL must start with http:// or https://' }; } // Validate API token format - check for non-ASCII characters that would cause ByteString errors const apiKey = body.apiKey.trim(); if (!/^[\x00-\xFF]*$/.test(apiKey)) { return { success: false, message: 'API token contains invalid characters. Please ensure you copied the token correctly without any special formatting characters.' }; } // Additional validation for common token issues if (apiKey.includes('•') || apiKey.includes('…') || apiKey.includes('"') || apiKey.includes('"')) { return { success: false, message: 'API token contains formatting characters (bullets, quotes, etc.). Please copy the raw token from NocoDB without any formatting.' }; } console.log('[api/admin/nocodb-test.post] Testing NocoDB connection...'); console.log('[api/admin/nocodb-test.post] URL:', body.url); console.log('[api/admin/nocodb-test.post] Base ID:', body.baseId); console.log('[api/admin/nocodb-test.post] Tables:', Object.keys(body.tables)); try { // Test connection by making a simple request to NocoDB using the first table const firstTableName = Object.keys(body.tables)[0]; const firstTableId = body.tables[firstTableName]; const testUrl = `${body.url}/api/v2/tables/${firstTableId}/records?limit=1`; console.log('[api/admin/nocodb-test.post] Testing URL:', testUrl); const response = await $fetch(testUrl, { method: 'GET', headers: { 'xc-token': body.apiKey, 'Content-Type': 'application/json' }, // Add timeout to prevent hanging timeout: 10000 }); console.log('[api/admin/nocodb-test.post] ✅ Connection successful'); console.log('[api/admin/nocodb-test.post] Response received, type:', typeof response); return { success: true, message: 'Connection successful! NocoDB is responding.' }; } catch (connectionError: any) { console.error('[api/admin/nocodb-test.post] ❌ Connection failed:', connectionError); let errorMessage = 'Connection failed'; if (connectionError.statusCode === 401 || connectionError.status === 401) { errorMessage = 'Authentication failed - please check your API token'; } else if (connectionError.statusCode === 404 || connectionError.status === 404) { errorMessage = 'Table not found - please check your Base ID and Table ID'; } else if (connectionError.statusCode === 403 || connectionError.status === 403) { errorMessage = 'Access denied - please check your API token permissions'; } else if (connectionError.code === 'NETWORK_ERROR' || connectionError.message?.includes('fetch')) { errorMessage = 'Network error - please check the URL and ensure NocoDB is accessible'; } else if (connectionError.message?.includes('timeout')) { errorMessage = 'Connection timeout - NocoDB server may be unavailable'; } else if (connectionError.message) { errorMessage = connectionError.message; } return { success: false, message: errorMessage }; } } catch (error: any) { console.error('[api/admin/nocodb-test.post] ❌ Error:', error); if (error.statusCode) { throw error; // Re-throw HTTP errors } return { success: false, message: 'Failed to test connection due to server error' }; } });