From a2b9d72537d924d2d8f898fb5d7e0178dafb1dba Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Mon, 6 May 2019 17:16:44 -0300 Subject: [PATCH 1/8] update telemetry format --- src/auth/index.js | 6 ++---- src/management/index.js | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/auth/index.js b/src/auth/index.js index acb70f253..4797f22ce 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -119,11 +119,9 @@ AuthenticationClient.prototype.getClientInfo = function() { var clientInfo = { name: 'node-auth0', version: pkg.version, - dependencies: [], - environment: [ + env: [ { - name: 'node.js', - version: process.version.replace('v', '') + node: process.version.replace('v', '') } ] }; diff --git a/src/management/index.js b/src/management/index.js index 89b91340f..aa6cf6f2d 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -302,11 +302,9 @@ ManagementClient.prototype.getClientInfo = function() { var clientInfo = { name: 'node-auth0', version: pkg.version, - dependencies: [], - environment: [ + env: [ { - name: 'node.js', - version: process.version.replace('v', '') + node: process.version.replace('v', '') } ] }; From e08bc2a07760f430aacdb4f129fc85d3db02220d Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Mon, 6 May 2019 17:17:16 -0300 Subject: [PATCH 2/8] allow to customize telemetry from TokenProvider --- src/management/ManagementTokenProvider.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/management/ManagementTokenProvider.js b/src/management/ManagementTokenProvider.js index 59996fb2b..ade7b3be1 100644 --- a/src/management/ManagementTokenProvider.js +++ b/src/management/ManagementTokenProvider.js @@ -67,7 +67,8 @@ var ManagementTokenProvider = function(options) { domain: this.options.domain, clientId: this.options.clientId, clientSecret: this.options.clientSecret, - telemetry: this.options.telemetry + telemetry: this.options.telemetry, + clientInfo: this.options.clientInfo }; this.authenticationClient = new AuthenticationClient(authenticationClientOptions); }; From 16bbcd3faacaf796cfc67d70011af97a5dbb9399 Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Mon, 6 May 2019 17:22:12 -0300 Subject: [PATCH 3/8] remove unused dependencies logic --- src/auth/index.js | 12 +----------- src/management/index.js | 11 +---------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/auth/index.js b/src/auth/index.js index 4797f22ce..f5b434cf0 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -116,7 +116,7 @@ var AuthenticationClient = function(options) { * @return {Object} Object containing client information. */ AuthenticationClient.prototype.getClientInfo = function() { - var clientInfo = { + return { name: 'node-auth0', version: pkg.version, env: [ @@ -125,16 +125,6 @@ AuthenticationClient.prototype.getClientInfo = function() { } ] }; - - // Add the dependencies to the client info object. - Object.keys(pkg.dependencies).forEach(function(name) { - clientInfo.dependencies.push({ - name: name, - version: pkg.dependencies[name] - }); - }); - - return clientInfo; }; /** diff --git a/src/management/index.js b/src/management/index.js index aa6cf6f2d..b6745857e 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -299,7 +299,7 @@ var ManagementClient = function(options) { * @return {Object} Object containing client information. */ ManagementClient.prototype.getClientInfo = function() { - var clientInfo = { + return { name: 'node-auth0', version: pkg.version, env: [ @@ -308,15 +308,6 @@ ManagementClient.prototype.getClientInfo = function() { } ] }; - // Add the dependencies to the client info object. - Object.keys(pkg.dependencies).forEach(function(name) { - clientInfo.dependencies.push({ - name: name, - version: pkg.dependencies[name] - }); - }); - - return clientInfo; }; /** From ebe7db56674569acdfbcb25458fbe2357e9728ca Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Wed, 8 May 2019 18:26:58 -0300 Subject: [PATCH 4/8] add tests for telemetry headers --- package.json | 15 +- src/auth/DatabaseAuthenticator.js | 3 +- src/auth/OAuthAuthenticator.js | 3 +- src/auth/PasswordlessAuthenticator.js | 3 +- src/management/StatsManager.js | 10 +- src/management/TenantManager.js | 10 +- src/management/TicketsManager.js | 10 +- test/auth/authentication-client.tests.js | 68 +++- test/management/management-client.tests.js | 423 ++++++++++++++++++++- 9 files changed, 518 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index c9118d3e7..4dae031c7 100644 --- a/package.json +++ b/package.json @@ -3,14 +3,14 @@ "version": "2.17.0", "description": "SDK for Auth0 API v2", "main": "src/index.js", - "files": ["src"], + "files": [ + "src" + ], "scripts": { "test": "mocha -R spec ./test/**/*.tests.js ./test/*.tests.js", - "test:ci": - "istanbul cover _mocha --report lcovonly -R $(find ./test -name *.tests.js) -- -R mocha-multi --reporter-options spec=-,mocha-junit-reporter=-", + "test:ci": "istanbul cover _mocha --report lcovonly -R $(find ./test -name *.tests.js) -- -R mocha-multi --reporter-options spec=-,mocha-junit-reporter=-", "test:coverage": "codecov", - "test:watch": - "cross-env NODE_ENV=test mocha --timeout 5000 ./test/**/*.tests.js ./test/*.tests.js --watch", + "test:watch": "cross-env NODE_ENV=test mocha --timeout 5000 ./test/**/*.tests.js ./test/*.tests.js --watch", "jsdoc:generate": "jsdoc --configure .jsdoc.json --verbose", "release:clean": "node scripts/cleanup.js", "preversion": "node scripts/prepare.js", @@ -22,7 +22,10 @@ "type": "git", "url": "https://github.com/auth0/node-auth0" }, - "keywords": ["auth0", "api"], + "keywords": [ + "auth0", + "api" + ], "author": "Auth0", "license": "MIT", "bugs": { diff --git a/src/auth/DatabaseAuthenticator.js b/src/auth/DatabaseAuthenticator.js index 4f5dabc79..7f23f581d 100644 --- a/src/auth/DatabaseAuthenticator.js +++ b/src/auth/DatabaseAuthenticator.js @@ -30,7 +30,8 @@ var DatabaseAuthenticator = function(options, oauth) { * @type {Object} */ var clientOptions = { - errorFormatter: { message: 'message', name: 'error' } + errorFormatter: { message: 'message', name: 'error' }, + headers: options.headers }; this.oauth = oauth; diff --git a/src/auth/OAuthAuthenticator.js b/src/auth/OAuthAuthenticator.js index d8df93582..7aaa41465 100644 --- a/src/auth/OAuthAuthenticator.js +++ b/src/auth/OAuthAuthenticator.js @@ -33,7 +33,8 @@ var OAuthAuthenticator = function(options) { * @type {Object} */ var clientOptions = { - errorFormatter: { message: 'message', name: 'error' } + errorFormatter: { message: 'message', name: 'error' }, + headers: options.headers }; this.oauth = new RestClient(options.baseUrl + '/oauth/:type', clientOptions); diff --git a/src/auth/PasswordlessAuthenticator.js b/src/auth/PasswordlessAuthenticator.js index 99c124275..b0855714b 100644 --- a/src/auth/PasswordlessAuthenticator.js +++ b/src/auth/PasswordlessAuthenticator.js @@ -29,7 +29,8 @@ var PasswordlessAuthenticator = function(options, oauth) { * @type {Object} */ var clientOptions = { - errorFormatter: { message: 'message', name: 'error' } + errorFormatter: { message: 'message', name: 'error' }, + headers: options.headers }; this.oauth = oauth; diff --git a/src/management/StatsManager.js b/src/management/StatsManager.js index 9dafe9f94..2254a83be 100644 --- a/src/management/StatsManager.js +++ b/src/management/StatsManager.js @@ -49,7 +49,7 @@ var StatsManager = function(options) { clientOptions, options.tokenProvider ); - this.stats = new RetryRestClient(auth0RestClient, options.retry); + this.resource = new RetryRestClient(auth0RestClient, options.retry); }; /** @@ -84,10 +84,10 @@ StatsManager.prototype.getDaily = function(params, cb) { params.type = 'daily'; if (cb && cb instanceof Function) { - return this.stats.get(params, cb); + return this.resource.get(params, cb); } - return this.stats.get(params); + return this.resource.get(params); }; /** @@ -113,11 +113,11 @@ StatsManager.prototype.getActiveUsersCount = function(cb) { var options = { type: 'active-users' }; if (cb && cb instanceof Function) { - return this.stats.get(options, cb); + return this.resource.get(options, cb); } // Return a promise. - return this.stats.get(options); + return this.resource.get(options); }; module.exports = StatsManager; diff --git a/src/management/TenantManager.js b/src/management/TenantManager.js index a4ee9dbae..bbd86c7b8 100644 --- a/src/management/TenantManager.js +++ b/src/management/TenantManager.js @@ -49,7 +49,7 @@ var TenantManager = function(options) { clientOptions, options.tokenProvider ); - this.tenant = new RetryRestClient(auth0RestClient, options.retry); + this.resource = new RetryRestClient(auth0RestClient, options.retry); }; /** @@ -72,11 +72,11 @@ var TenantManager = function(options) { */ TenantManager.prototype.updateSettings = function(data, cb) { if (cb && cb instanceof Function) { - return this.tenant.patch({}, data, cb); + return this.resource.patch({}, data, cb); } // Return a promise. - return this.tenant.patch({}, data); + return this.resource.patch({}, data); }; /** @@ -100,11 +100,11 @@ TenantManager.prototype.updateSettings = function(data, cb) { */ TenantManager.prototype.getSettings = function(cb) { if (cb && cb instanceof Function) { - return this.tenant.get({}, cb); + return this.resource.get({}, cb); } // Return a promise. - return this.tenant.get({}); + return this.resource.get({}); }; module.exports = TenantManager; diff --git a/src/management/TicketsManager.js b/src/management/TicketsManager.js index d6e06c919..78a1383be 100644 --- a/src/management/TicketsManager.js +++ b/src/management/TicketsManager.js @@ -43,7 +43,7 @@ var TicketsManager = function(options) { clientOptions, options.tokenProvider ); - this.ticket = new RetryRestClient(auth0RestClient, options.retry); + this.resource = new RetryRestClient(auth0RestClient, options.retry); }; /** @@ -73,11 +73,11 @@ TicketsManager.prototype.changePassword = function(data, cb) { var params = { type: 'password-change' }; if (cb && cb instanceof Function) { - return this.ticket.create(params, data, cb); + return this.resource.create(params, data, cb); } // Return a promise. - return this.ticket.create(params, data); + return this.resource.create(params, data); }; /** @@ -105,11 +105,11 @@ TicketsManager.prototype.verifyEmail = function(data, cb) { var params = { type: 'email-verification' }; if (cb && cb instanceof Function) { - return this.ticket.create(params, data, cb); + return this.resource.create(params, data, cb); } // Return a promise. - return this.ticket.create(params, data); + return this.resource.create(params, data); }; module.exports = TicketsManager; diff --git a/test/auth/authentication-client.tests.js b/test/auth/authentication-client.tests.js index edb873936..57bc5a228 100644 --- a/test/auth/authentication-client.tests.js +++ b/test/auth/authentication-client.tests.js @@ -1,4 +1,5 @@ var expect = require('chai').expect; +var sinon = require('sinon'); var ArgumentError = require('rest-facade').ArgumentError; @@ -67,8 +68,73 @@ describe('AuthenticationClient', function() { } }); + describe('client info', function() { + it('should generate default telemetry value', function() { + var client = new AuthenticationClient({ token: 'token', domain: 'auth0.com' }); + var pkgVersion = require('../../package.json').version; + var nodeVersion = process.version.replace('v', ''); + expect(client.getClientInfo()).to.deep.equal({ + name: 'node-auth0', + version: pkgVersion, + env: [{ node: nodeVersion }] + }); + }); + + it('should configure instances with default telemetry header', function() { + sinon.stub(AuthenticationClient.prototype, 'getClientInfo', function() { + return { name: 'test-sdk', version: 'ver-123' }; + }); + var client = new AuthenticationClient({ token: 'token', domain: 'auth0.com' }); + + var requestHeaders = { + 'Auth0-Client': 'eyJuYW1lIjoidGVzdC1zZGsiLCJ2ZXJzaW9uIjoidmVyLTEyMyJ9', + 'Content-Type': 'application/json' + }; + expect(client.oauth.oauth.options.headers).to.contain(requestHeaders); + expect(client.database.dbConnections.options.headers).to.contain(requestHeaders); + expect(client.passwordless.passwordless.options.headers).to.contain(requestHeaders); + expect(client.users.headers).to.contain(requestHeaders); + expect(client.tokens.headers).to.contain(requestHeaders); + + AuthenticationClient.prototype.getClientInfo.restore(); + }); + + it('should configure instances with custom telemetry header', function() { + var customTelemetry = { name: 'custom', version: 'beta-01', env: { node: 'v10' } }; + var client = new AuthenticationClient({ + token: 'token', + domain: 'auth0.com', + clientInfo: customTelemetry + }); + + var requestHeaders = { + 'Auth0-Client': + 'eyJuYW1lIjoiY3VzdG9tIiwidmVyc2lvbiI6ImJldGEtMDEiLCJlbnYiOnsibm9kZSI6InYxMCJ9fQ', + 'Content-Type': 'application/json' + }; + expect(client.oauth.oauth.options.headers).to.contain(requestHeaders); + expect(client.database.dbConnections.options.headers).to.contain(requestHeaders); + expect(client.passwordless.passwordless.options.headers).to.contain(requestHeaders); + expect(client.users.headers).to.contain(requestHeaders); + expect(client.tokens.headers).to.contain(requestHeaders); + }); + + it('should configure instances without telemetry header when disabled', function() { + var client = new AuthenticationClient({ + token: 'token', + domain: 'auth0.com', + telemetry: false + }); + + expect(client.oauth.oauth.options.headers).to.not.have.property('Auth0-Client'); + expect(client.database.dbConnections.options.headers).to.not.have.property('Auth0-Client'); + expect(client.passwordless.passwordless.options.headers).to.not.have.property('Auth0-Client'); + expect(client.users.headers).to.not.have.property('Auth0-Client'); + expect(client.tokens.headers).to.not.have.property('Auth0-Client'); + }); + }); + describe('instance methods', function() { - var method; var methods = []; var client = new AuthenticationClient({ token: 'token', domain: 'auth0.com' }); diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js index 955fb6c2c..c200b40c8 100644 --- a/test/management/management-client.tests.js +++ b/test/management/management-client.tests.js @@ -1,4 +1,5 @@ var expect = require('chai').expect; +var sinon = require('sinon'); var assign = Object.assign || require('object.assign'); var ManagementClient = require('../../src/management'); @@ -144,12 +145,430 @@ describe('ManagementClient', function() { property: 'tenant', cls: TenantManager }, - 'RulesConfigsManager': { + RulesConfigsManager: { property: 'rulesConfigs', cls: RulesConfigsManager - }, + } }; + describe('client info', function() { + it('should generate default telemetry value', function() { + var client = new ManagementClient(withTokenConfig); + var pkgVersion = require('../../package.json').version; + var nodeVersion = process.version.replace('v', ''); + expect(client.getClientInfo()).to.deep.equal({ + name: 'node-auth0', + version: pkgVersion, + env: [{ node: nodeVersion }] + }); + }); + + it('should configure instances with default telemetry header', function() { + sinon.stub(ManagementClient.prototype, 'getClientInfo', function() { + return { name: 'test-sdk', version: 'ver-123' }; + }); + var client = new ManagementClient(withTokenConfig); + + var requestHeaders = { + 'Auth0-Client': 'eyJuYW1lIjoidGVzdC1zZGsiLCJ2ZXJzaW9uIjoidmVyLTEyMyJ9', + 'Content-Type': 'application/json' + }; + + expect(client.clients.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.clientGrants.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.grants.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.users.users.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.users.multifactor.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.identities.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.userLogs.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.enrollments.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.usersByEmail.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect( + client.users.recoveryCodeRegenerations.restClient.restClient.options.headers + ).to.contain(requestHeaders); + expect(client.users.roles.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.users.permissions.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.guardian.enrollments.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.tickets.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factors.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factorsTemplates.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factorsProviders.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.customDomains.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect( + client.customDomains.vefifyResource.restClient.restClient.options.headers + ).to.contain(requestHeaders); + + expect(client.connections.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.deviceCredentials.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.rules.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.blacklistedTokens.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.emailProvider.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.stats.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.tenant.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.jobs.jobs.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.jobs.usersExports.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.tickets.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.logs.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.resourceServers.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.emailTemplates.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.rulesConfigs.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.roles.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.roles.permissions.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.roles.users.restClient.restClient.options.headers).to.contain(requestHeaders); + + ManagementClient.prototype.getClientInfo.restore(); + }); + + it('should configure instances with custom telemetry header', function() { + var customTelemetry = { name: 'custom', version: 'beta-01', env: { node: 'v10' } }; + var client = new ManagementClient({ + token: 'token', + domain: 'auth0.com', + clientInfo: customTelemetry + }); + + var requestHeaders = { + 'Auth0-Client': + 'eyJuYW1lIjoiY3VzdG9tIiwidmVyc2lvbiI6ImJldGEtMDEiLCJlbnYiOnsibm9kZSI6InYxMCJ9fQ', + 'Content-Type': 'application/json' + }; + + expect(client.clients.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.clientGrants.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.grants.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.users.users.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.users.multifactor.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.identities.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.userLogs.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.enrollments.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.users.usersByEmail.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect( + client.users.recoveryCodeRegenerations.restClient.restClient.options.headers + ).to.contain(requestHeaders); + expect(client.users.roles.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.users.permissions.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.guardian.enrollments.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.tickets.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factors.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factorsTemplates.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.guardian.factorsProviders.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.customDomains.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect( + client.customDomains.vefifyResource.restClient.restClient.options.headers + ).to.contain(requestHeaders); + + expect(client.connections.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.deviceCredentials.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.rules.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.blacklistedTokens.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.emailProvider.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.stats.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.tenant.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.jobs.jobs.restClient.restClient.options.headers).to.contain(requestHeaders); + expect(client.jobs.usersExports.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.tickets.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.logs.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.resourceServers.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.emailTemplates.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.rulesConfigs.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + + expect(client.roles.resource.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.roles.permissions.restClient.restClient.options.headers).to.contain( + requestHeaders + ); + expect(client.roles.users.restClient.restClient.options.headers).to.contain(requestHeaders); + }); + + it('should configure instances without telemetry header when disabled', function() { + var client = new ManagementClient({ + token: 'token', + domain: 'auth0.com', + telemetry: false + }); + + expect(client.clients.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.clientGrants.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.grants.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.users.users.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.multifactor.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.identities.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.userLogs.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.enrollments.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect( + client.users.usersByEmail.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.users.recoveryCodeRegenerations.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect(client.users.roles.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.permissions.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.guardian.enrollments.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect(client.guardian.tickets.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.guardian.factors.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect( + client.guardian.factorsTemplates.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.guardian.factorsProviders.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.customDomains.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.customDomains.vefifyResource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.connections.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.deviceCredentials.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.rules.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.blacklistedTokens.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.emailProvider.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.stats.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.tenant.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.jobs.jobs.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.jobs.usersExports.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.tickets.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.logs.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.resourceServers.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.emailTemplates.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.rulesConfigs.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.roles.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.roles.permissions.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.roles.users.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + }); + }); + before(function() { var config = assign({}, withTokenConfig); this.client = new ManagementClient(config); From f186e9beedb8d7e05e2fea8d304fc7f183acc72c Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Fri, 10 May 2019 16:09:07 -0300 Subject: [PATCH 5/8] fix telemetry.env data type for default telemetry --- src/auth/index.js | 8 +++----- src/management/index.js | 8 +++----- test/auth/authentication-client.tests.js | 2 +- test/management/management-client.tests.js | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/auth/index.js b/src/auth/index.js index f5b434cf0..2280b42b7 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -119,11 +119,9 @@ AuthenticationClient.prototype.getClientInfo = function() { return { name: 'node-auth0', version: pkg.version, - env: [ - { - node: process.version.replace('v', '') - } - ] + env: { + node: process.version.replace('v', '') + } }; }; diff --git a/src/management/index.js b/src/management/index.js index b6745857e..c5ceabb54 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -302,11 +302,9 @@ ManagementClient.prototype.getClientInfo = function() { return { name: 'node-auth0', version: pkg.version, - env: [ - { - node: process.version.replace('v', '') - } - ] + env: { + node: process.version.replace('v', '') + } }; }; diff --git a/test/auth/authentication-client.tests.js b/test/auth/authentication-client.tests.js index 57bc5a228..af1727463 100644 --- a/test/auth/authentication-client.tests.js +++ b/test/auth/authentication-client.tests.js @@ -76,7 +76,7 @@ describe('AuthenticationClient', function() { expect(client.getClientInfo()).to.deep.equal({ name: 'node-auth0', version: pkgVersion, - env: [{ node: nodeVersion }] + env: { node: nodeVersion } }); }); diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js index c200b40c8..1dc2b2424 100644 --- a/test/management/management-client.tests.js +++ b/test/management/management-client.tests.js @@ -159,7 +159,7 @@ describe('ManagementClient', function() { expect(client.getClientInfo()).to.deep.equal({ name: 'node-auth0', version: pkgVersion, - env: [{ node: nodeVersion }] + env: { node: nodeVersion } }); }); From 7ecdf164a906617a0034c370bd9841bc79bf989d Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Fri, 10 May 2019 17:43:11 -0300 Subject: [PATCH 6/8] improve telemetry by moving logic into a common source --- src/auth/index.js | 27 +--- src/management/index.js | 28 +--- src/utils.js | 19 +++ test/auth/authentication-client.tests.js | 41 ++++-- test/management/management-client.tests.js | 163 ++++++++++++++++++--- test/utils.tests.js | 16 ++ 6 files changed, 217 insertions(+), 77 deletions(-) create mode 100644 test/utils.tests.js diff --git a/src/auth/index.js b/src/auth/index.js index 2280b42b7..8ee5d0903 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -1,8 +1,6 @@ /** @module auth **/ var util = require('util'); - -var pkg = require('../../package.json'); var utils = require('../utils'); var jsonToBase64 = utils.jsonToBase64; var ArgumentError = require('rest-facade').ArgumentError; @@ -67,8 +65,11 @@ var AuthenticationClient = function(options) { }; if (options.telemetry !== false) { - var telemetry = jsonToBase64(options.clientInfo || this.getClientInfo()); - managerOptions.headers['Auth0-Client'] = telemetry; + var clientInfo = options.clientInfo || utils.generateClientInfo(); + if ('string' === typeof clientInfo.name && clientInfo.name.length > 0) { + var telemetry = jsonToBase64(clientInfo); + managerOptions.headers['Auth0-Client'] = telemetry; + } } /** @@ -107,24 +108,6 @@ var AuthenticationClient = function(options) { this.tokens = new TokensManager(managerOptions); }; -/** - * Return an object with information about the current client, - * - * @method getClientInfo - * @memberOf module:auth.AuthenticationClient.prototype - * - * @return {Object} Object containing client information. - */ -AuthenticationClient.prototype.getClientInfo = function() { - return { - name: 'node-auth0', - version: pkg.version, - env: { - node: process.version.replace('v', '') - } - }; -}; - /** * Start passwordless flow sending an email. * diff --git a/src/management/index.js b/src/management/index.js index c5ceabb54..33a544ccc 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -1,10 +1,9 @@ /** @module management */ var util = require('util'); - -var pkg = require('../../package.json'); var utils = require('../utils'); var jsonToBase64 = utils.jsonToBase64; +var generateClientInfo = utils.generateClientInfo; var ArgumentError = require('rest-facade').ArgumentError; var assign = Object.assign || require('object.assign'); @@ -129,8 +128,11 @@ var ManagementClient = function(options) { } if (options.telemetry !== false) { - var telemetry = jsonToBase64(options.clientInfo || this.getClientInfo()); - managerOptions.headers['Auth0-Client'] = telemetry; + var clientInfo = options.clientInfo || generateClientInfo(); + if ('string' === typeof clientInfo.name && clientInfo.name.length > 0) { + var telemetry = jsonToBase64(clientInfo); + managerOptions.headers['Auth0-Client'] = telemetry; + } } managerOptions.retry = options.retry; @@ -290,24 +292,6 @@ var ManagementClient = function(options) { this.roles = new RolesManager(managerOptions); }; -/** - * Return an object with information about the current client, - * - * @method getClientInfo - * @memberOf module:management.ManagementClient.prototype - * - * @return {Object} Object containing client information. - */ -ManagementClient.prototype.getClientInfo = function() { - return { - name: 'node-auth0', - version: pkg.version, - env: { - node: process.version.replace('v', '') - } - }; -}; - /** * Get all connections. * diff --git a/src/utils.js b/src/utils.js index 8ba259f61..e0e934647 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,6 @@ var Promise = require('bluebird'); var request = require('request'); +var pkg = require('../package.json'); /** * @module utils @@ -22,6 +23,24 @@ utils.jsonToBase64 = function(json) { .replace(/=+$/, ''); }; +/** + * Return an object with information about the current client, + * + * @method generateClientInfo + * @memberOf module:utils + * + * @return {Object} Object containing client information. + */ +utils.generateClientInfo = function() { + return { + name: 'node-auth0', + version: pkg.version, + env: { + node: process.version.replace('v', '') + } + }; +}; + /** * Simple wrapper that, given a class, a property name and a method name, * creates a new method in the class that is a wrapper for the given diff --git a/test/auth/authentication-client.tests.js b/test/auth/authentication-client.tests.js index af1727463..7cb62e23f 100644 --- a/test/auth/authentication-client.tests.js +++ b/test/auth/authentication-client.tests.js @@ -1,5 +1,6 @@ var expect = require('chai').expect; var sinon = require('sinon'); +var proxyquire = require('proxyquire'); var ArgumentError = require('rest-facade').ArgumentError; @@ -69,22 +70,17 @@ describe('AuthenticationClient', function() { }); describe('client info', function() { - it('should generate default telemetry value', function() { - var client = new AuthenticationClient({ token: 'token', domain: 'auth0.com' }); - var pkgVersion = require('../../package.json').version; - var nodeVersion = process.version.replace('v', ''); - expect(client.getClientInfo()).to.deep.equal({ - name: 'node-auth0', - version: pkgVersion, - env: { node: nodeVersion } - }); - }); - it('should configure instances with default telemetry header', function() { - sinon.stub(AuthenticationClient.prototype, 'getClientInfo', function() { - return { name: 'test-sdk', version: 'ver-123' }; + var utilsStub = { + generateClientInfo: sinon.spy(function() { + return { name: 'test-sdk', version: 'ver-123' }; + }) + }; + var AuthenticationClientProxy = proxyquire('../../src/auth/', { + '../utils': utilsStub }); - var client = new AuthenticationClient({ token: 'token', domain: 'auth0.com' }); + + var client = new AuthenticationClientProxy({ token: 'token', domain: 'auth0.com' }); var requestHeaders = { 'Auth0-Client': 'eyJuYW1lIjoidGVzdC1zZGsiLCJ2ZXJzaW9uIjoidmVyLTEyMyJ9', @@ -95,8 +91,6 @@ describe('AuthenticationClient', function() { expect(client.passwordless.passwordless.options.headers).to.contain(requestHeaders); expect(client.users.headers).to.contain(requestHeaders); expect(client.tokens.headers).to.contain(requestHeaders); - - AuthenticationClient.prototype.getClientInfo.restore(); }); it('should configure instances with custom telemetry header', function() { @@ -119,6 +113,21 @@ describe('AuthenticationClient', function() { expect(client.tokens.headers).to.contain(requestHeaders); }); + it('should configure instances without telemetry when "name" property is empty', function() { + var customTelemetry = { name: '', version: 'beta-01', env: { node: 'v10' } }; + var client = new AuthenticationClient({ + token: 'token', + domain: 'auth0.com', + clientInfo: customTelemetry + }); + + expect(client.oauth.oauth.options.headers).to.not.have.property('Auth0-Client'); + expect(client.database.dbConnections.options.headers).to.not.have.property('Auth0-Client'); + expect(client.passwordless.passwordless.options.headers).to.not.have.property('Auth0-Client'); + expect(client.users.headers).to.not.have.property('Auth0-Client'); + expect(client.tokens.headers).to.not.have.property('Auth0-Client'); + }); + it('should configure instances without telemetry header when disabled', function() { var client = new AuthenticationClient({ token: 'token', diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js index 1dc2b2424..4b0f92fdd 100644 --- a/test/management/management-client.tests.js +++ b/test/management/management-client.tests.js @@ -1,6 +1,7 @@ var expect = require('chai').expect; var sinon = require('sinon'); var assign = Object.assign || require('object.assign'); +var proxyquire = require('proxyquire'); var ManagementClient = require('../../src/management'); @@ -17,7 +18,6 @@ var JobsManager = require('../../src/management/JobsManager'); var RulesManager = require('../../src/management/RulesManager'); var StatsManager = require('../../src/management/StatsManager'); var RulesConfigsManager = require('../../src/management/RulesConfigsManager'); - var TenantManager = require('../../src/management/TenantManager'); describe('ManagementClient', function() { @@ -152,22 +152,16 @@ describe('ManagementClient', function() { }; describe('client info', function() { - it('should generate default telemetry value', function() { - var client = new ManagementClient(withTokenConfig); - var pkgVersion = require('../../package.json').version; - var nodeVersion = process.version.replace('v', ''); - expect(client.getClientInfo()).to.deep.equal({ - name: 'node-auth0', - version: pkgVersion, - env: { node: nodeVersion } - }); - }); - it('should configure instances with default telemetry header', function() { - sinon.stub(ManagementClient.prototype, 'getClientInfo', function() { - return { name: 'test-sdk', version: 'ver-123' }; + var utilsStub = { + generateClientInfo: sinon.spy(function() { + return { name: 'test-sdk', version: 'ver-123' }; + }) + }; + var ManagementClientProxy = proxyquire('../../src/management/', { + '../utils': utilsStub }); - var client = new ManagementClient(withTokenConfig); + var client = new ManagementClientProxy(withTokenConfig); var requestHeaders = { 'Auth0-Client': 'eyJuYW1lIjoidGVzdC1zZGsiLCJ2ZXJzaW9uIjoidmVyLTEyMyJ9', @@ -293,8 +287,6 @@ describe('ManagementClient', function() { requestHeaders ); expect(client.roles.users.restClient.restClient.options.headers).to.contain(requestHeaders); - - ManagementClient.prototype.getClientInfo.restore(); }); it('should configure instances with custom telemetry header', function() { @@ -432,6 +424,143 @@ describe('ManagementClient', function() { expect(client.roles.users.restClient.restClient.options.headers).to.contain(requestHeaders); }); + it('should configure instances without telemetry when "name" property is empty', function() { + var customTelemetry = { name: '', version: 'beta-01', env: { node: 'v10' } }; + var client = new ManagementClient({ + token: 'token', + domain: 'auth0.com', + clientInfo: customTelemetry + }); + + expect(client.clients.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.clientGrants.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.grants.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.users.users.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.multifactor.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.identities.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.userLogs.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.enrollments.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect( + client.users.usersByEmail.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.users.recoveryCodeRegenerations.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect(client.users.roles.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.users.permissions.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.guardian.enrollments.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect(client.guardian.tickets.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.guardian.factors.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect( + client.guardian.factorsTemplates.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.guardian.factorsProviders.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.customDomains.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + expect( + client.customDomains.vefifyResource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.connections.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.deviceCredentials.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.rules.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.blacklistedTokens.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.emailProvider.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.stats.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.tenant.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.jobs.jobs.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.jobs.usersExports.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.tickets.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect(client.logs.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + + expect( + client.resourceServers.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.emailTemplates.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect( + client.rulesConfigs.resource.restClient.restClient.options.headers + ).to.not.have.property('Auth0-Client'); + + expect(client.roles.resource.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.roles.permissions.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + expect(client.roles.users.restClient.restClient.options.headers).to.not.have.property( + 'Auth0-Client' + ); + }); + it('should configure instances without telemetry header when disabled', function() { var client = new ManagementClient({ token: 'token', diff --git a/test/utils.tests.js b/test/utils.tests.js new file mode 100644 index 000000000..919b8ae01 --- /dev/null +++ b/test/utils.tests.js @@ -0,0 +1,16 @@ +var expect = require('chai').expect; +var utils = require('../src/utils.js'); + +describe('Utils', function() { + describe('client info', function() { + it('should generate default telemetry value', function() { + var pkgVersion = require('../package.json').version; + var nodeVersion = process.version.replace('v', ''); + expect(utils.generateClientInfo()).to.deep.equal({ + name: 'node-auth0', + version: pkgVersion, + env: { node: nodeVersion } + }); + }); + }); +}); From 73707a942ca8f92f63e9ad5bd2dfb161a7382c3f Mon Sep 17 00:00:00 2001 From: Josh Cunningham Date: Fri, 10 May 2019 14:49:50 -0700 Subject: [PATCH 7/8] Update src/auth/index.js --- src/auth/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/index.js b/src/auth/index.js index 8ee5d0903..c86921d57 100644 --- a/src/auth/index.js +++ b/src/auth/index.js @@ -66,7 +66,7 @@ var AuthenticationClient = function(options) { if (options.telemetry !== false) { var clientInfo = options.clientInfo || utils.generateClientInfo(); - if ('string' === typeof clientInfo.name && clientInfo.name.length > 0) { + if ('string' === typeof clientInfo.name && clientInfo.name) { var telemetry = jsonToBase64(clientInfo); managerOptions.headers['Auth0-Client'] = telemetry; } From ff39d25ff2fc0ec9cb578fcf35e33fe1e2f228a2 Mon Sep 17 00:00:00 2001 From: Josh Cunningham Date: Fri, 10 May 2019 14:50:40 -0700 Subject: [PATCH 8/8] Update src/utils.js --- src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index e0e934647..59ecb09b2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -24,7 +24,7 @@ utils.jsonToBase64 = function(json) { }; /** - * Return an object with information about the current client, + * Return an object with information about the current client. * * @method generateClientInfo * @memberOf module:utils