(options: MongoOptions)
| 75 | * @param options - Optional user provided connection string options |
| 76 | */ |
| 77 | export async function resolveSRVRecord(options: MongoOptions): Promise<HostAddress[]> { |
| 78 | if (typeof options.srvHost !== 'string') { |
| 79 | throw new MongoAPIError('Option "srvHost" must not be empty'); |
| 80 | } |
| 81 | |
| 82 | // Asynchronously start TXT resolution so that we do not have to wait until |
| 83 | // the SRV record is resolved before starting a second DNS query. |
| 84 | const lookupAddress = options.srvHost; |
| 85 | const txtResolutionPromise = resolveTxt(lookupAddress); |
| 86 | |
| 87 | txtResolutionPromise.then(undefined, squashError); // rejections will be handled later |
| 88 | |
| 89 | const hostname = `_${options.srvServiceName}._tcp.${lookupAddress}`; |
| 90 | // Resolve the SRV record and use the result as the list of hosts to connect to. |
| 91 | const addresses = await resolveSrv(hostname); |
| 92 | |
| 93 | if (addresses.length === 0) { |
| 94 | throw new MongoAPIError('No addresses found at host'); |
| 95 | } |
| 96 | |
| 97 | for (const { name } of addresses) { |
| 98 | checkParentDomainMatch(name, lookupAddress); |
| 99 | } |
| 100 | |
| 101 | const hostAddresses = addresses.map(r => HostAddress.fromString(`${r.name}:${r.port ?? 27017}`)); |
| 102 | |
| 103 | validateLoadBalancedOptions(hostAddresses, options, true); |
| 104 | |
| 105 | // Use the result of resolving the TXT record and add options from there if they exist. |
| 106 | let record; |
| 107 | try { |
| 108 | record = await txtResolutionPromise; |
| 109 | } catch (error) { |
| 110 | if (error.code !== 'ENODATA' && error.code !== 'ENOTFOUND') { |
| 111 | throw error; |
| 112 | } |
| 113 | return hostAddresses; |
| 114 | } |
| 115 | |
| 116 | if (record.length > 1) { |
| 117 | throw new MongoParseError('Multiple text records not allowed'); |
| 118 | } |
| 119 | |
| 120 | const txtRecordOptions = new URLSearchParams(record[0].join('')); |
| 121 | const txtRecordOptionKeys = [...txtRecordOptions.keys()]; |
| 122 | if (txtRecordOptionKeys.some(key => !VALID_TXT_RECORDS.includes(key))) { |
| 123 | throw new MongoParseError(`Text record may only set any of: ${VALID_TXT_RECORDS.join(', ')}`); |
| 124 | } |
| 125 | |
| 126 | if (VALID_TXT_RECORDS.some(option => txtRecordOptions.get(option) === '')) { |
| 127 | throw new MongoParseError('Cannot have empty URI params in DNS TXT Record'); |
| 128 | } |
| 129 | |
| 130 | const source = txtRecordOptions.get('authSource') ?? undefined; |
| 131 | const replicaSet = txtRecordOptions.get('replicaSet') ?? undefined; |
| 132 | const loadBalanced = txtRecordOptions.get('loadBalanced') ?? undefined; |
| 133 | |
| 134 | if ( |
no test coverage detected