From 45661dd8013bad006c009faed7fa7920e759ac2f Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Mon, 25 Mar 2019 11:05:03 -0700 Subject: [PATCH] Make API key less likely to be logged (#83) Before this change: const at = new Airtable({ apiKey: 'keyXyz' }) console.log(at) // => Class { _apiKey: 'keyXyz', ... } After this change: const at = new Airtable({ apiKey: 'keyXyz' }) console.log(at) // => Class { ... } This is accomplished with `Object.defineProperties`. By default, properties defined this way aren't enumerable, making it more difficult to accidentally log them. Addresses . --- lib/airtable.js | 35 ++++++++++++++++++++++++++--------- test/airtable.test.js | 13 +++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 test/airtable.test.js diff --git a/lib/airtable.js b/lib/airtable.js index 0ad93315..60e71f09 100644 --- a/lib/airtable.js +++ b/lib/airtable.js @@ -12,15 +12,32 @@ var Airtable = Class.extend({ init: function(opts) { opts = opts || {}; - var default_config = Airtable.default_config(); - - this._apiKey = opts.apiKey || Airtable.apiKey || default_config.apiKey; - this._endpointUrl = opts.endpointUrl || Airtable.endpointUrl || default_config.endpointUrl; - this._apiVersion = opts.apiVersion || Airtable.apiVersion || default_config.apiVersion; - this._apiVersionMajor = this._apiVersion.split('.')[0]; - this._allowUnauthorizedSsl = opts.allowUnauthorizedSsl || Airtable.allowUnauthorizedSsl || default_config.allowUnauthorizedSsl; - this._noRetryIfRateLimited = opts.noRetryIfRateLimited || Airtable.noRetryIfRateLimited || default_config.noRetryIfRateLimited; - this.requestTimeout = opts.requestTimeout || default_config.requestTimeout; + var defaultConfig = Airtable.default_config(); + + var apiVersion = opts.apiVersion || Airtable.apiVersion || defaultConfig.apiVersion; + + Object.defineProperties(this, { + _apiKey: { + value: opts.apiKey || Airtable.apiKey || defaultConfig.apiKey, + }, + _endpointUrl: { + value: opts.endpointUrl || Airtable.endpointUrl || defaultConfig.endpointUrl, + }, + _apiVersion: { + value: apiVersion, + }, + _apiVersionMajor: { + value: apiVersion.split('.')[0], + }, + _allowUnauthorizedSsl: { + value: opts.allowUnauthorizedSsl || Airtable.allowUnauthorizedSsl || defaultConfig.allowUnauthorizedSsl, + }, + _noRetryIfRateLimited: { + value: opts.noRetryIfRateLimited || Airtable.noRetryIfRateLimited || defaultConfig.noRetryIfRateLimited, + }, + }); + + this.requestTimeout = opts.requestTimeout || defaultConfig.requestTimeout; assert(this._apiKey, 'API key is required to connect to Airtable'); }, diff --git a/test/airtable.test.js b/test/airtable.test.js new file mode 100644 index 00000000..c0cd131e --- /dev/null +++ b/test/airtable.test.js @@ -0,0 +1,13 @@ +'use strict'; + +var Airtable = require('../lib/airtable'); + +describe('Airtable', function () { + it("doesn't include the API key as an enumerable property", function () { + var fakeAirtable = new Airtable({apiKey: 'keyXyz'}); + + Object.values(fakeAirtable).forEach(function (value) { + expect(value).not.toEqual('keyXyz'); + }); + }); +});