import { SecretClient } from '@azure/keyvault-secrets'; import { DefaultAzureCredential, ClientSecretCredential } from '@azure/identity'; import { config } from './config.js'; import { getAzureConfig as getStoredAzureConfig } from '../modules/azure-config/repository.js'; let keyVaultClient: SecretClient | null = null; export async function getKeyVaultClient(): Promise { if (keyVaultClient) { return keyVaultClient; } try { let credential; let keyVaultUrl = config.AZURE_KEY_VAULT_URL; // Try to get configuration from database first const storedConfig = await getStoredAzureConfig(); if (storedConfig && storedConfig.isActive) { keyVaultUrl = storedConfig.keyVaultUrl; if (storedConfig.tenantId && storedConfig.clientId && storedConfig.clientSecret) { credential = new ClientSecretCredential( storedConfig.tenantId, storedConfig.clientId, storedConfig.clientSecret ); } } // Fall back to environment variables if no stored config if (!credential && config.AZURE_TENANT_ID && config.AZURE_CLIENT_ID && config.AZURE_CLIENT_SECRET) { credential = new ClientSecretCredential( config.AZURE_TENANT_ID, config.AZURE_CLIENT_ID, config.AZURE_CLIENT_SECRET ); } // Use DefaultAzureCredential as last resort if (!credential) { credential = new DefaultAzureCredential(); } if (!keyVaultUrl) { return null; } keyVaultClient = new SecretClient(keyVaultUrl, credential); return keyVaultClient; } catch (error) { console.error('Failed to initialize Azure Key Vault client:', error); return null; } } export async function getAzureSecret(secretName: string): Promise { const client = await getKeyVaultClient(); if (!client) { return null; } try { const secret = await client.getSecret(secretName); return secret.value || null; } catch (error) { console.error(`Failed to get secret ${secretName} from Azure Key Vault:`, error); return null; } } export async function setAzureSecret(secretName: string, secretValue: string): Promise { const client = await getKeyVaultClient(); if (!client) { return false; } try { await client.setSecret(secretName, secretValue); return true; } catch (error) { console.error(`Failed to set secret ${secretName} in Azure Key Vault:`, error); return false; } } export async function deleteAzureSecret(secretName: string): Promise { const client = await getKeyVaultClient(); if (!client) { return false; } try { await client.beginDeleteSecret(secretName); return true; } catch (error) { console.error(`Failed to delete secret ${secretName} from Azure Key Vault:`, error); return false; } } export async function listAzureSecrets(): Promise { const client = await getKeyVaultClient(); if (!client) { return []; } try { const secrets: string[] = []; for await (const secretProperties of client.listPropertiesOfSecrets()) { if (secretProperties.name) { secrets.push(secretProperties.name); } } return secrets; } catch (error) { console.error('Failed to list secrets from Azure Key Vault:', error); return []; } }