'use strict'; const axios = require('axios'); const {DnsApi} = require('./common'); class DigitalOcean extends DnsApi{ static _keyMap = { token: {isRequired: true, type: 'string', isPrivate: true, displayName: 'API Token'}, } static displayName = 'DigitalOcean' static displayIconHtml = ` ` // '' static displayIconUni = '' constructor(token){ super() this.token = token.token || token; } async axios(method, ...args){ try{ let a = axios.create({ baseURL: 'https://api.digitalocean.com/v2/', headers: {Authorization: `Bearer ${this.token}`} }); return await a[method](...args); }catch(error){ if(!error.response) throw error; if(error.response.data && error.response.data.id === 'Unauthorized'){ throw this.errors.unauthorized(); } throw this.errors.other(error.response.status, error.response.data.message); } } async listDomains(){ // 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'); for(let domain of res.data.domains){ domain.domain = domain.name; } return res.data.domains; } async getRecords(domain, options){ options = this.__parseOptions(options); let res = await this.axios('get', `/domains/${domain.domain}/records`, {params: options}) let records = this.__parseRes(res.data.domain_records); if(!options) return records; return records.filter((record)=>{ let matchCount = 0 for(let key in options){ if(record[key] === options[key] && ++matchCount === Object.keys(options).length){ return true; } } }); } async createRecord(domain, options){ // DigitalOcean names an apex record '@' (the base apexName default). if(options.name === '@') options.name = this.apexName(domain.domain); options = this.__parseOptions(options, ['type', 'name', 'data']); let res = await this.axios('post', `/domains/${domain.domain}/records`, options); return this.__parseRes([res.data.domain_record])[0]; } async deleteRecordById(domain, id){ let res = await this.axios('delete', `/domains/${domain.domain}/records/${id}`); } async deleteRecords(domain, options){ let records = await this.getRecords(domain, options) for(let record of records){ let res = await this.deleteRecordById(domain, record.id); } return true; } } module.exports = DigitalOcean;