diff --git a/nodejs/models/dns_provider.js b/nodejs/models/dns_provider.js index 105bdf8..7d1eefc 100644 --- a/nodejs/models/dns_provider.js +++ b/nodejs/models/dns_provider.js @@ -96,12 +96,15 @@ class DnsProvider extends Table{ }catch(error){ if(error.name === 'UnauthorizedDnsApi'){ let keys = []; - console.log('Provider', Provider) for(let key in Provider._keyMap){ keys.push({'key': key, message: 'Invalid Key'}) } throw this.errors.ObjectValidateError(keys, "API rejected key"); } + // Don't swallow other failures (e.g. a domain-sync validation error): + // returning undefined here made the route crash on `item.id` with an + // opaque message. Surface the real error to the caller instead. + throw error; } } @@ -145,7 +148,11 @@ class DnsProvider extends Table{ created_by: this.created_by, domain: domain.domain, dnsProvider_id: this.id, - zoneId: domain.zoneId, + // Only providers with a zone concept (e.g. Cloudflare) return a + // zoneId. Porkbun/DigitalOcean don't, and passing an explicit + // `undefined` trips model-redis' type check ("zoneId is not string + // type") and aborts the whole sync — so omit it when absent. + ...(domain.zoneId !== undefined ? {zoneId: domain.zoneId} : {}), }); } console.log('currentDomains:', currentDomains) diff --git a/nodejs/models/dns_provider/digitalocean.js b/nodejs/models/dns_provider/digitalocean.js index 264c827..fc3cad8 100644 --- a/nodejs/models/dns_provider/digitalocean.js +++ b/nodejs/models/dns_provider/digitalocean.js @@ -40,9 +40,17 @@ class DigitalOcean extends DnsApi{ } async listDomains(){ - let res = await this.axios('get', '/domains'); + // DO returns {domains:[{name, ttl, zone_file}]} keyed by `name` and has no + // zone id (API paths use the domain name directly). Map name -> domain the + // way CloudFlare.listDomains does; do NOT run this through __parseRes, which + // rewrites `.name` to its subdomain and would leave no usable domain name. + let res = await this.axios('get', '/domains?per_page=200'); - return this.__parseRes(res.data.domains); + for(let domain of res.data.domains){ + domain.domain = domain.name; + } + + return res.data.domains; } async getRecords(domain, options){