Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dnsimple

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dnsimple - npm Package Compare versions

Comparing version 1.1.1 to 1.2.0

.eslintrc

190

dnsimple.js

@@ -15,4 +15,5 @@ /*

module.exports = function (setup) {
// ! Defaults
var http = require ('httpreq');
module.exports = function doSetup (setup) {
var api = {

@@ -23,4 +24,4 @@ hostname: setup.hostname || 'api.dnsimple.com',

domainToken: setup.domainToken || null,
twoFactorOTP: setup.twoFactorOTP || null, // one time password (ie. Authy)
twoFactorToken: setup.twoFactorToken || null, // OTP exchange token
twoFactorOTP: setup.twoFactorOTP || null,
twoFactorToken: setup.twoFactorToken || null,
password: setup.password || null,

@@ -31,3 +32,14 @@ timeout: setup.timeout || 30000

// ! API
return function (method, path, fields, callback) {
return function talk (method, path, fields, callback) {
var complete = false;
var options = {
url: 'https://' + api.hostname + '/v1' + path,
method: method || 'GET',
timeout: api.timeout,
headers: {
'Accept': 'application/json',
'User-Agent': 'Nodejs-DNSimple'
}
};
if (!callback && typeof fields === 'function') {

@@ -39,3 +51,2 @@ callback = fields;

// process callback data
var complete = false;
function doCallback (err, data, meta) {

@@ -60,3 +71,3 @@ if (!complete) {

// credentials set?
if (! (api.email && api.token) && ! (api.email && api.password) && ! api.domainToken && ! api.twoFactorToken) {
if (!(api.email && api.token) && !(api.email && api.password) && !api.domainToken && !api.twoFactorToken) {
doCallback (new Error ('credentials missing'));

@@ -66,16 +77,9 @@ return;

// prepare
var querystr = JSON.stringify (fields);
var headers = {
'Accept': 'application/json',
'User-Agent': 'Nodejs-DNSimple'
};
// token in headers
if (api.token) {
headers['X-DNSimple-Token'] = api.email +':'+ api.token;
options.headers['X-DNSimple-Token'] = api.email + ':' + api.token;
}
if (api.domainToken) {
headers['X-DNSimple-Domain-Token'] = api.domainToken;
options.headers['X-DNSimple-Domain-Token'] = api.domainToken;
}

@@ -85,22 +89,15 @@

if (method.match (/(POST|PUT|DELETE)/)) {
headers['Content-Type'] = 'application/json';
headers['Content-Length'] = querystr.length;
options.json = fields;
} else {
options.parameters = fields;
}
var options = {
host: api.hostname,
port: 443,
path: '/v1'+ path,
method: method,
headers: headers
};
// password authentication
if (! api.twoFactorToken && ! api.token && ! api.domainToken && api.password && api.email) {
options.auth = api.email +':'+ api.password;
if (!api.twoFactorToken && !api.token && !api.domainToken && api.password && api.email) {
options.auth = api.email + ':' + api.password;
// two-factor authentication (2FA)
if (api.twoFactorOTP) {
headers['X-DNSimple-2FA-Strict'] = 1;
headers['X-DNSimple-OTP'] = api.twoFactorOTP;
options.headers['X-DNSimple-2FA-Strict'] = 1;
options.headers['X-DNSimple-OTP'] = api.twoFactorOTP;
}

@@ -110,106 +107,61 @@ }

if (api.twoFactorToken) {
options.auth = api.twoFactorToken +':x-2fa-basic';
headers['X-DNSimple-2FA-Strict'] = 1;
options.auth = api.twoFactorToken + ':x-2fa-basic';
options.headers['X-DNSimple-2FA-Strict'] = 1;
}
// start request
var request = require ('https').request (options);
http.doRequest (options, function doResponse (err, response) {
var error = null;
var data = response && response.body || '';
var meta = {};
// response
request.on ('response', function (response) {
var meta = {statusCode: null};
var data = [];
var size = 0;
if (err) {
error = new Error ('request failed');
error.error = err;
doCallback (error);
return;
}
response.on ('data', function (chunk) {
data.push (chunk);
size += chunk.length;
});
try {
data = JSON.parse (data);
} catch (e) {
error = new Error ('invalid response');
error.error = e;
}
response.on ('close', function() {
doCallback (new Error('connection dropped'));
});
meta.statusCode = response.statusCode;
meta.request_id = response.headers ['x-request-id'];
meta.runtime = response.headers ['x-runtime'];
// request finished
response.on ('end', function() {
data = new Buffer.concat (data, size).toString ('utf8').trim ();
var failed = null;
if (typeof response.headers ['x-dnsimple-otp-token'] === 'string') {
meta.twoFactorToken = response.headers ['x-dnsimple-otp-token'];
}
meta.statusCode = response.statusCode;
meta.request_id = response.headers['x-request-id'];
meta.runtime = response.headers['x-runtime'];
// status ok, no data
if (!data && meta.statusCode < 300) {
error = null;
}
if (typeof response.headers['x-dnsimple-otp-token'] === 'string') {
meta.twoFactorToken = response.headers['x-dnsimple-otp-token'];
}
if (response.statusCode !== 204) {
try {
data = JSON.parse (data);
} catch (e) {
doCallback (new Error ('not json'), data);
}
}
// overrides
var noError = false;
var error = null;
// status ok, no data
if (data === '' && meta.statusCode < 300) {
noError = true;
}
// domain check 404 = free
if (path.match (/^domains\/.+\/check$/) && meta.statusCode === 404) {
noError = true;
}
// check HTTP status code
if (noError || (!failed && response.statusCode < 300)) {
doCallback (null, data, meta);
} else {
if (response.statusCode === 401 && response.headers['x-dnsimple-otp'] === 'required') {
error = new Error ('twoFactorOTP required');
} else {
error = failed || new Error ('API error');
}
error.code = response.statusCode;
error.error = data.message || data.error || (data.errors && data instanceof Object && Object.keys (data.errors)[0] ? data.errors[ Object.keys (data.errors)[0] ] : null) || null;
error.data = data;
doCallback (error, null, meta);
}
});
});
// timeout
request.on ('socket', function (socket) {
if (typeof api.timeout === 'number') {
socket.setTimeout (parseInt (api.timeout));
socket.on ('timeout', function () {
doCallback (new Error ('request timeout'));
request.abort ();
});
// domain check 404 = free
if (path.match (/^domains\/.+\/check$/) && meta.statusCode === 404) {
error = null;
}
});
// error
request.on ('error', function (error) {
var er = null;
if (error.code === 'ECONNRESET') {
er = new Error ('request timeout');
// check HTTP status code
if (!error && response.statusCode < 300) {
doCallback (null, data, meta);
return;
} else if (response.statusCode === 401 && response.headers ['x-dnsimple-otp'] === 'required') {
error = new Error ('twoFactorOTP required');
} else {
er = new Error ('request failed');
error = new Error ('API error');
}
er.error = error;
doCallback (er);
error.code = response.statusCode;
error.error = data.message || data.error || data.errors || null;
error.data = data;
doCallback (error, null, meta);
});
// run it
if (method.match (/(POST|PUT|DELETE)/)) {
request.end (querystr);
} else {
request.end ();
}
};
};
{
"author": {
"name": "Franklin van de Meent",
"email": "fr@nkl.in",
"url": "https://frankl.in"
"name": "Franklin van de Meent",
"email": "fr@nkl.in",
"url": "https://frankl.in"
},
"name": "dnsimple",
"description": "Wrapper for DNSimple API",
"version": "1.1.1",
"name": "dnsimple",
"description": "Wrapper for DNSimple API",
"version": "1.2.0",
"repository": {
"type": "git",
"url": "git://github.com/fvdm/nodejs-dnsimple.git"
"type": "git",
"url": "git://github.com/fvdm/nodejs-dnsimple.git"
},
"bugs": {
"url": "https://github.com/fvdm/nodejs-dnsimple/issues"
"url": "https://github.com/fvdm/nodejs-dnsimple/issues"
},
"main": "dnsimple.js",
"dependencies": {},
"devDependencies": {},
"optionalDependencies": {},
"main": "dnsimple.js",
"dependencies": {
"httpreq": "0.4.x"
},
"devDependencies": {},
"optionalDependencies": {},
"engines": {
"node": ">=0.8.0"
"node": ">=0.8.0"
},
"keywords": ["dnsimple", "domains", "dns", "api", "unlicense"],
"license": {
"type": "Public Domain",
"url": "https://github.com/fvdm/nodejs-dnsimple/raw/master/UNLICENSE"
},
"keywords": [
"dnsimple",
"domains",
"dns",
"api",
"unlicense"
],
"license": "Unlicense",
"scripts": {
"test": "node test.js"
"test": "node test.js"
}
}

@@ -11,3 +11,3 @@ dnsimple

[DNSimple](https://dnsimple.com/) -
[API documentation](http://developer.dnsimple.com/)
[API documentation](https://developer.dnsimple.com/)

@@ -30,3 +30,3 @@

```js
var dnsimple = new require('dnsimple')({ email: 'you@web.tld', token: 'abc123' });
var dnsimple = new require ('dnsimple') ({ email: 'you@web.tld', token: 'abc123' });

@@ -38,7 +38,7 @@ // Add a domain name

dnsimple( 'POST', '/domains', input, function( err, data ) {
if( err ) {
return console.log( err );
dnsimple ('POST', '/domains', input, function (err, data) {
if (err) {
return console.log (err);
}
console.log( data.domain.name +' created with ID '+ data.domain.id );
console.log (data.domain.name + ' created with ID ' + data.domain.id);
});

@@ -63,3 +63,3 @@ ```

```js
require('dnsimple')({ email: 'your@email.tld', token: '12345abcde' })
require ('dnsimple') ({ email: 'your@email.tld', token: '12345abcde' });
```

@@ -71,3 +71,3 @@

```js
require('dnsimple')({ email: 'your@email.tld', password: 'secret' })
require ('dnsimple') ({ email: 'your@email.tld', password: 'secret' });
```

@@ -81,3 +81,3 @@

```js
require('dnsimple')({ domainToken: 'abc123' })
require ('dnsimple') ({ domainToken: 'abc123' });
```

@@ -98,3 +98,3 @@

// Set the OTP code on load
var dnsimple = require('dnsimple')({
var dnsimple = require ('dnsimple') ({
email: 'my@mail.tld',

@@ -106,9 +106,9 @@ password: 'my-secret',

// Now call a random method to trade the OTP for a longterm token
dnsimple( 'GET', '/subscription', function( err, data, meta ) {
if( err ) { return console.log(err) }
console.log( 'Two-factor token: '+ meta.twoFactorToken );
dnsimple ('GET', '/subscription', function (err, data, meta) {
if (err) { return console.log (err); }
console.log ('Two-factor token: '+ meta.twoFactorToken);
});
// From now on only use this token - no email/password
var dnsimple = require('dnsimple')({
var dnsimple = require ('dnsimple') ({
twoFactorToken: '22596363b3de40b06f981fb85d82312e'

@@ -127,3 +127,3 @@ });

name | description | default
---------------|--------------------------------------|-----------------
:--------------|:-------------------------------------|:----------------
email | Account email address |

@@ -155,3 +155,3 @@ token | Account access token |

name | type | required | description
---------|----------|----------|--------------------------------------
:--------|:---------|:---------|:-------------------------------------
method | string | yes | GET, POST, PUT, DELETE

@@ -166,14 +166,12 @@ path | string | yes | i.e. `/domains/two.com`

The last argument `callback` receives three arguments: `err`, `data` and `meta`.
* When an error occurs `err` is an instance of `Error` and `data` is _null_.
When an error occurs `err` is an instance of _Error_ and `data` is _null_.
`err` can have additional properties.
When everything is good `err` will be _null_ and `data` will be the parsed result.
* When everything is good `err` will be _null_ and `data` will be the parsed result.
The `meta` parameter is always available and contains extra information from
the API, such as statusCode, request_id, runtime and twoFactorToken.
* DELETE result `data` is _true_ on success, _false_ otherwise.
* DELETE result `data` is boolean _true_ on success, _false_ otherwise.
* The `meta` parameter is always available and contains extra information from
the API, such as statusCode, request_id, runtime and twoFactorToken.
#### Errors

@@ -184,10 +182,8 @@

message | description
--------------------|---------------------------------------------------------
credentials missing | No authentication details set
connection dropped | Connection was closed too early
not json | Invalid API response, see `err.code` and `err.data`
API error | The API returned an error, see `err.code` and `err.data`
request timeout | The request took too long
request failed | The request cannot be made, see `err.error`
message | description | additional
:-------------------|:--------------------------------|:----------------------
credentials missing | No authentication details set |
request failed | The request cannot be made | `err.error`
invalid reponse | Invalid API response | `err.code`, `err.error`, `err.data`
API error | The API returned an error | `err.code`, `err.error`, `err.data`

@@ -194,0 +190,0 @@

@@ -1,3 +0,5 @@

var testStart = Date.now ();
var util = require ('util');
var pkg = require ('./package.json');
var errors = 0;
var queue = [];
var next = 0;

@@ -9,29 +11,24 @@ // Setup

timeout: process.env.DNSIMPLE_TIMEOUT || 30000,
email: process.env.DNSIMPLE_EMAIL || null
email: process.env.DNSIMPLE_EMAIL || null,
token: process.env.DNSIMPLE_TOKEN || null,
password: process.env.DNSIMPLE_PASS || null,
twoFactorOTP: process.env.DNSIMPLE_OTP || null
};
var token = process.env.DNSIMPLE_TOKEN || null;
var pass = process.env.DNSIMPLE_PASS || null;
var otp = process.env.DNSIMPLE_OTP || null;
// fake material to use
var bogus = {
domain: {
name: 'test-' + Date.now () + '-delete.me'
}
};
if (pass && otp) {
acc.password = pass;
acc.twoFactorOTP = otp;
} else if (token) {
acc.token = token;
}
var app = require ('./') (acc);
// handle exits
var errors = 0;
process.on ('exit', function () {
var testTime = Date.now () - testStart;
if (errors === 0) {
console.log ('\n\033[1mDONE, no errors.\033[0m');
console.log ('Timing: %s ms\n', testTime);
console.log ('\n\u001b[1mDONE, no errors.\u001b[0m\n');
process.exit (0);
} else {
console.log ('\n\033[1mFAIL, '+ errors +' error'+ (errors > 1 ? 's' : '') +' occurred!\033[0m');
console.log ('Timing: %s ms\n', testTime);
console.log ('\n\u001b[1mFAIL, ' + errors + ' error' + (errors > 1 ? 's' : '') + ' occurred!\u001b[0m\n');
process.exit (1);

@@ -44,5 +41,6 @@ }

console.log ();
console.error (err.stack);
console.trace ();
console.log (err);
console.log ();
console.log (err.stack);
console.log ();
errors++;

@@ -52,36 +50,35 @@ });

// Queue to prevent flooding
var queue = [];
var next = 0;
function doNext () {
next++;
if (queue[next]) {
queue[next] ();
if (queue [next]) {
queue [next] ();
}
}
// doTest (passErr, 'methods', [
// doTest( passErr, 'methods', [
// ['feeds', typeof feeds === 'object']
// ]);
// ])
function doTest (err, label, tests) {
var testErrors = [];
var i;
if (err instanceof Error) {
console.error (label +': \033[1m\033[31mERROR\033[0m\n');
console.error (util.inspect (err, false, 10, true));
console.log ('\u001b[1m\u001b[31mERROR\u001b[0m - ' + label + '\n');
console.dir (err, { depth: null, colors: true });
console.log ();
console.error (err.stack);
console.log (err.stack);
console.log ();
errors++;
} else {
var testErrors = [];
tests.forEach (function (test) {
if (test[1] !== true) {
testErrors.push (test[0]);
for (i = 0; i < tests.length; i++) {
if (tests [i] [1] !== true) {
testErrors.push (tests [i] [0]);
errors++;
}
});
}
if (testErrors.length === 0) {
console.log (label +': \033[1m\033[32mok\033[0m');
console.log ('\u001b[1m\u001b[32mgood\u001b[0m - ' + label);
} else {
console.error (label +': \033[1m\033[31mfailed\033[0m ('+ testErrors.join (', ') +')');
console.log ('\u001b[1m\u001b[31mFAIL\u001b[0m - ' + label + ' (' + testErrors.join (', ') + ')');
}

@@ -97,3 +94,3 @@ }

if (err) {
console.log ('API access: failed ('+ err.message +')');
console.log ('API access: failed (' + err.message + ')');
console.log (err.stack);

@@ -103,3 +100,3 @@ errors++;

} else {
console.log ('API access: \033[1m\033[32mok\033[0m');
console.log ('\u001b[1m\u001b[32mgood\u001b[0m - API access');
doNext ();

@@ -113,5 +110,6 @@ }

queue.push (function () {
app ('GET', '/domains/'+ bogus.domain.id, function (err) {
app ('GET', '/invalid-path', function (err) {
doTest (null, 'API error', [
['type', err && err.message === 'API error']
['type', err instanceof Error],
['message', err && err.message === 'API error']
]);

@@ -125,30 +123,17 @@ });

var tmp_acc = acc;
tmp_acc.timeout = 1;
var tmp_app = require ('./') (tmp_acc);
tmp_app ('GET', '/prices', function (err, data) {
if (err) {
doTest (null, 'Timeout error', [
['type', err instanceof Error],
['message', err.message && err.message === 'request timeout'],
['data', !data]
]);
}
require ('./') (tmp_acc) ('GET', '/prices', function (err, data) {
doTest (null, 'Timeout error', [
['type', err instanceof Error],
['code', err.error.code === 'TIMEOUT'],
['data', !data]
]);
});
delete tmp_app;
delete tmp_acc;
});
// fake material to use
var bogus = {
domain: {
name: 'test-'+ Date.now () +'-delete.me'
}
};
// ! POST object
queue.push (function () {
var works = null;
var input = {

@@ -159,8 +144,11 @@ domain: {

};
app ('POST', '/domains', input, function (err, data, meta) {
bogus.domain = data.domain;
if (data) {
bogus.domain = data.domain;
}
doTest (err, 'POST object', [
['code', meta.statusCode === 201],
['type', data && data.domain instanceof Object],
['item', data.domain.name === bogus.domain.name]
['type', works = data && data.domain instanceof Object],
['item', works && data.domain.name === bogus.domain.name]
]);

@@ -172,6 +160,8 @@ });

queue.push (function () {
app ('GET', '/domains/'+ bogus.domain.id, function (err, data) {
var works = null;
app ('GET', '/domains/' + bogus.domain.id, function (err, data) {
doTest (err, 'GET object', [
['type', data && data.domain instanceof Object],
['name', data && data.domain.name === bogus.domain.name]
['type', works = data && data.domain instanceof Object],
['name', works && data.domain.name === bogus.domain.name]
]);

@@ -184,7 +174,9 @@ });

app ('GET', '/domains', function (err, data) {
var works = null;
doTest (err, 'GET array object', [
['data type', data instanceof Array],
['data size', data && data.length >= 1],
['item type', data && data[0] && data[0].domain instanceof Object],
['item name', data && data[0] && data[0].domain && typeof data[0].domain.name === 'string']
['data type', works = data instanceof Array],
['data size', works = works && data.length >= 1],
['item type', works = works && data[0].domain instanceof Object],
['item name', works && typeof data[0].domain.name === 'string']
]);

@@ -196,3 +188,3 @@ });

queue.push (function () {
app ('DELETE', '/domains/'+ bogus.domain.id, function (err, data) {
app ('DELETE', '/domains/' + bogus.domain.id, function (err, data) {
doTest (err, 'DELETE', [

@@ -206,2 +198,6 @@ ['data', data === true]

// Start the tests
queue[0]();
console.log ('Running tests...');
console.log ('Node.js v' + process.versions.node);
console.log ('Module v' + pkg.version);
console.log ();
queue [0] ();

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc