import "typings-global"; import plugins = require("./cflare.plugins"); import helpers = require("./cflare.classes.helpers"); import * as interfaces from './cflare.interfaces' export class CflareAccount { private authEmail: string; private authKey: string; private authCheck() { return (this.authEmail && this.authKey); //check if auth is available } constructor() { }; auth(optionsArg: { email: string, key: string }) { this.authEmail = optionsArg.email; this.authKey = optionsArg.key; } getZoneId(domainName: string) { let done = plugins.q.defer(); this.listZones(domainName) .then(zoneArrayArg => { let filteredResponse = zoneArrayArg.filter((zoneArg) => { return zoneArg.name === domainName; }); if (filteredResponse.length >= 1) { done.resolve(filteredResponse[0].id); } else { plugins.beautylog.error(`the domain ${domainName} does not appear to be in this account!`); done.reject(undefined); } }); return done.promise; } getRecord(domainNameArg: string, typeArg: string): Promise { let done = plugins.q.defer(); let result: interfaces.ICflareRecord let domain = new plugins.smartstring.Domain(domainNameArg); this.listRecords(domain.zoneName) .then((recordArrayArg) => { let filteredResponse = recordArrayArg.filter((recordArg) => { return (recordArg.type == typeArg && recordArg.name == domainNameArg); }) done.resolve(filteredResponse[0]); }) return done.promise; }; createRecord(domainNameArg: string, typeArg: string, contentArg: string) { let done = plugins.q.defer(); let domain = new plugins.smartstring.Domain(domainNameArg); this.getZoneId(domain.zoneName) .then((domainIdArg) => { let dataObject = { name: domain.fullName, type: typeArg, content: contentArg }; this.request("POST", "/zones/" + domainIdArg + "/dns_records", dataObject) .then(function (responseArg) { done.resolve(responseArg); }); }); return done.promise; }; removeRecord(domainNameArg: string, typeArg: string) { let done = plugins.q.defer(); let domain = new plugins.smartstring.Domain(domainNameArg); this.getRecord(domain.fullName, typeArg) .then((responseArg) => { if (responseArg) { let requestRoute: string = "/zones/" + responseArg.zone_id + "/dns_records/" + responseArg.id; this.request("DELETE", requestRoute) .then((responseArg) => { done.resolve(responseArg); }); } else { done.reject(); } }); return done.promise; }; updateRecord(domainNameArg: string, typeArg: string, valueArg) { let done = plugins.q.defer(); let domain = new plugins.smartstring.Domain(domainNameArg); return done.promise; }; listRecords(domainNameArg: string): Promise { let done = plugins.q.defer(); let result: interfaces.ICflareRecord[] = [] let domain = new plugins.smartstring.Domain(domainNameArg); this.getZoneId(domain.zoneName) .then((domainIdArg) => { this.request("GET", "/zones/" + domainIdArg + "/dns_records?per_page=100") .then(function (responseArg: any) { result = responseArg.result done.resolve(result); }); }); return done.promise; } listZones(domainName?: string): Promise { // TODO: handle pagination let done = plugins.q.defer(); let requestRoute = "/zones?per_page=50" if (domainName) requestRoute = requestRoute + "&name=" + domainName; let result = []; this.request("GET", requestRoute) .then((responseArg: any) => { result = responseArg.result; done.resolve(result); }); return done.promise; }; request(methodArg: string, routeArg: string, dataArg = {}) { let done = plugins.q.defer(); let jsonArg: string = JSON.stringify(dataArg); let options = { method: methodArg, url: "https://api.cloudflare.com/client/v4" + routeArg, headers: { "Content-Type": "application/json", "X-Auth-Email": this.authEmail, "X-Auth-Key": this.authKey }, body: jsonArg }; //console.log(options); let retryCount = 0 let makeRequest = () => { plugins.request(options, function (err, res, body) { let responseObj try { responseObj = JSON.parse(body); } catch (err) { console.log(res.statusCode) retryRequest() return } if (!err && res.statusCode === 200) { done.resolve(responseObj); } else if (!err && res.statusCode === 429) { console.log('rate limited! Waiting for retry!') retryRequest() return } else { console.log(res.statusCode) console.log(responseObj.messages); console.log(responseObj.errors); done.reject(err); }; }); } let retryRequest = async (delayTimeArg = 15000) => { console.log(`retry started and waiting for ${delayTimeArg} ms`) await plugins.smartdelay.delayFor(delayTimeArg) if (retryCount < 3) { retryCount++ makeRequest() return } } makeRequest() return done.promise; } };