UNPKG

bc-webclient-mcp

Version:

Model Context Protocol (MCP) server for Microsoft Dynamics 365 Business Central via WebUI protocol. Enables AI assistants to interact with BC through the web client protocol, supporting Card, List, and Document pages with full line item support and server

65 lines 2.45 kB
/** * NavUserPassword Authentication * * Implements HTTP Basic Authentication for Business Central WebSocket connections * Based on decompiled code analysis from ClientServiceAuthenticationHandler.cs */ /** * Create HTTP Basic Authentication header for NavUserPassword * * Format: Authorization: Basic <base64-encoded-credentials> * Credentials: username:password (or tenantId\username:password for multi-tenant) */ export function createNavUserPasswordAuthHeader(credentials) { // Multi-tenant format: TenantId\Username // Single tenant format: Username const username = credentials.tenantId ? `${credentials.tenantId}\\${credentials.username}` : credentials.username; // Create credentials string: username:password const credentialsString = `${username}:${credentials.password}`; // Base64 encode (UTF-8 -> Base64) // BC uses ISO-8859-1 encoding, but UTF-8 is compatible for most cases const encoded = Buffer.from(credentialsString, 'utf-8').toString('base64'); // Return Basic Auth header value return `Basic ${encoded}`; } /** * Parse NavUserPassword username to extract tenant ID if present */ export function parseNavUsername(username) { const backslashIndex = username.indexOf('\\'); if (backslashIndex < 0) { // Single tenant format return { username }; } // Multi-tenant format: TenantId\Username return { tenantId: username.substring(0, backslashIndex), username: username.substring(backslashIndex + 1) }; } /** * Validate NavUserPassword credentials format */ export function validateNavCredentials(credentials) { if (!credentials.username || credentials.username.trim().length === 0) { return { valid: false, error: 'Username is required' }; } if (!credentials.password || credentials.password.length === 0) { return { valid: false, error: 'Password is required' }; } // Check for invalid characters in username (besides backslash for tenant separator) const usernameWithoutTenant = credentials.username.split('\\').pop() || ''; if (usernameWithoutTenant.includes(':')) { return { valid: false, error: 'Username cannot contain colon (:)' }; } return { valid: true }; } /** * Check if credentials appear to include tenant ID */ export function hasTenantInUsername(username) { return username.includes('\\'); } //# sourceMappingURL=navauth.js.map