Skip to content

Commit 9f1c2d9

Browse files
authored
fix: cleanup keytar (#209)
1 parent b5150dd commit 9f1c2d9

10 files changed

+30
-195
lines changed

README.md

-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,3 @@ Manages the CLI configuration options, such as Twilio profiles and credentials.
4141
### Logger
4242

4343
Standardizes logging output of debug, info, warning, and error messages to stderr (all go to stderr to allow differentiation between command output and logging messages).
44-
45-
### SecureStorage
46-
47-
An abstraction around the keytar npm package which further abstracts platform-level data encryption services for storing Twilio credentials securely.

package.json

-3
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@
6464
"sinon": "^9.0.2",
6565
"tmp": "^0.2.1"
6666
},
67-
"optionalDependencies": {
68-
"keytar": "^7.6.0"
69-
},
7067
"engines": {
7168
"node": ">=14.0.0"
7269
}

src/base-commands/base-command.js

-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const { TwilioCliError } = require('../services/error');
88
const { logger, LoggingLevel } = require('../services/messaging/logging');
99
const { OutputFormats } = require('../services/output-formats');
1010
const { getCommandPlugin, requireInstall } = require('../services/require-install');
11-
const { SecureStorage } = require('../services/secure-storage');
1211
const { instanceOf } = require('../services/javascript-utilities');
1312

1413
let inquirer; // We'll lazy-load this only when it's needed.
@@ -21,7 +20,6 @@ class BaseCommand extends Command {
2120
super(argv, config);
2221
this.configFile = new Config('');
2322
this.userConfig = new ConfigData();
24-
this.secureStorage = new SecureStorage({ command: this });
2523
}
2624

2725
get inquirer() {

src/base-commands/twilio-client-command.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class TwilioClientCommand extends BaseCommand {
3131
);
3232
}
3333
this.currentProfile = this.userConfig.getProfileById(this.flags.profile);
34-
let keytarFlag = false;
3534
const pluginName = (this.config.userAgent || ' ').split(' ')[0];
3635

3736
const reportUnconfigured = (verb, message = '', commandName = 'create') => {
@@ -55,17 +54,11 @@ class TwilioClientCommand extends BaseCommand {
5554
this.logger.debug(`Using profile: ${this.currentProfile.id}`);
5655

5756
if (!this.currentProfile.apiKey || !this.currentProfile.apiSecret) {
58-
const creds = await this.secureStorage.getCredentials(this.currentProfile.id);
59-
if (creds.apiKey === 'error') {
60-
this.logger.error(`Could not get credentials for profile "${this.currentProfile.id}".`);
61-
reportUnconfigured('reconfigure');
62-
}
63-
this.currentProfile.apiKey = creds.apiKey;
64-
this.currentProfile.apiSecret = creds.apiSecret;
65-
keytarFlag = true;
57+
this.logger.error(`Could not get credentials for profile "${this.currentProfile.id}".`);
58+
reportUnconfigured('reconfigure');
6659
}
6760

68-
this.httpClient = new CliRequestClient(this.id, this.logger, undefined, keytarFlag, pluginName);
61+
this.httpClient = new CliRequestClient(this.id, this.logger, undefined, pluginName);
6962
}
7063

7164
async catch(error) {

src/index.js

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ module.exports = {
1313
templating: require('./services/messaging/templating'),
1414
namingConventions: require('./services/naming-conventions'),
1515
outputFormats: require('./services/output-formats'),
16-
secureStorage: require('./services/secure-storage'),
1716
},
1817
configureEnv: require('./services/env'),
1918
releaseScripts: {

src/services/cli-http-client.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const NETWORK_ERROR_CODES = new Set(['ETIMEDOUT', 'ESOCKETTIMEDOUT', 'ECONNABORT
1414
const STANDARD_HEADERS = ['user-agent', 'accept-charset', 'connection', 'authorization', 'accept', 'content-type'];
1515

1616
class CliRequestClient {
17-
constructor(commandName, logger, http, keytarFlag = false, extensions = ' ') {
17+
constructor(commandName, logger, http, extensions = ' ') {
1818
this.commandName = commandName;
1919
this.logger = logger;
2020
this.pluginName = extensions;
@@ -27,7 +27,6 @@ class CliRequestClient {
2727
this.http.defaults.proxy = false;
2828
this.http.defaults.httpsAgent = new HttpsProxyAgent(process.env.HTTP_PROXY);
2929
}
30-
this.keytarWord = keytarFlag ? 'keytar' : '';
3130
}
3231

3332
/**
@@ -72,7 +71,6 @@ class CliRequestClient {
7271
componentInfo.push(userAgentArr[0]); // Api client version
7372
componentInfo.push(userAgentArr[3]); // nodejs version
7473
componentInfo.push(this.commandName); // cli-command
75-
componentInfo.push(this.keytarWord); // keytar flag
7674
headers['User-Agent'] = `${this.pluginName} ${pkg.name}/${pkg.version} ${componentInfo.filter(Boolean).join(' ')}`;
7775

7876
const options = {

src/services/secure-storage.js

-81
This file was deleted.

test/base-commands/twilio-client-command.test.js

+19-16
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ describe('base-commands', () => {
3636
args = [],
3737
{
3838
setUpUserConfig = undefined,
39-
mockSecureStorage = true,
4039
commandClass: CommandClass = TestClientCommand,
4140
envRegion,
4241
envEdge,
@@ -64,24 +63,28 @@ describe('base-commands', () => {
6463
if (setUpUserConfig) {
6564
setUpUserConfig(ctx.userConfig);
6665
} else {
67-
ctx.userConfig.addProfile('MyFirstProfile', constants.FAKE_ACCOUNT_SID);
68-
ctx.userConfig.addProfile('region-edge-testing', constants.FAKE_ACCOUNT_SID, configRegion);
66+
ctx.userConfig.addProfile(
67+
'MyFirstProfile',
68+
constants.FAKE_ACCOUNT_SID,
69+
undefined,
70+
constants.FAKE_API_KEY,
71+
`${constants.FAKE_API_SECRET}MyFirstProfile`,
72+
);
73+
ctx.userConfig.addProfile(
74+
'region-edge-testing',
75+
constants.FAKE_ACCOUNT_SID,
76+
configRegion,
77+
constants.FAKE_API_KEY,
78+
`${constants.FAKE_API_SECRET}region-edge-testing`,
79+
);
80+
ctx.userConfig.addProfile('no-credentials-profile', constants.FAKE_ACCOUNT_SID, configRegion);
6981
ctx.userConfig.setActiveProfile('MyFirstProfile');
7082
}
7183
})
7284
.twilioCliEnv(Config)
7385
.stderr()
7486
.do(async (ctx) => {
7587
ctx.testCmd = new CommandClass(args, ctx.fakeConfig);
76-
ctx.testCmd.secureStorage = {
77-
async getCredentials(profileId) {
78-
return {
79-
apiKey: mockSecureStorage ? constants.FAKE_API_KEY : 'error',
80-
apiSecret: constants.FAKE_API_SECRET + profileId,
81-
};
82-
},
83-
};
84-
8588
// This is essentially what oclif does behind the scenes.
8689
try {
8790
await ctx.testCmd.run();
@@ -169,12 +172,12 @@ describe('base-commands', () => {
169172
expect(ctx.testCmd.twilioClient.region).to.equal('configRegion');
170173
});
171174

172-
setUpTest(['-p', 'region-edge-testing'], { mockSecureStorage: false })
175+
setUpTest(['-p', 'no-credentials-profile'])
173176
.exit(1)
174-
.it('should handle a secure storage error', (ctx) => {
175-
expect(ctx.stderr).to.contain('Could not get credentials for profile "region-edge-testing"');
177+
.it('should handle no profile error', (ctx) => {
178+
expect(ctx.stderr).to.contain('Could not get credentials for profile "no-credentials-profile"');
176179
expect(ctx.stderr).to.contain('To reconfigure the profile, run:');
177-
expect(ctx.stderr).to.contain('twilio profiles:create --profile "region-edge-testing"');
180+
expect(ctx.stderr).to.contain('twilio profiles:create --profile "no-credentials-profile"');
178181
});
179182

180183
setUpTest([], { commandClass: ThrowingUnknownClientCommand })

test/services/cli-http-client.test.js

+7-13
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ describe('services', () => {
2121
expect(options.url).to.equal('https://foo.com/bar');
2222
return { status: 200, data: 'foo', headers: {} };
2323
},
24-
true,
2524
'blah',
2625
);
2726
expect(client.commandName).to.equal('blah');
28-
expect(client.keytarWord).to.equal('keytar');
2927
expect(client.pluginName).to.equal('blah');
3028
const response = await client.request({
3129
method: 'POST',
@@ -43,9 +41,8 @@ describe('services', () => {
4341

4442
test.it('should add the correct http agent for proxy', async () => {
4543
process.env.HTTP_PROXY = 'http://someproxy.com:8080';
46-
const client = new CliRequestClient('blah', logger, { defaults: {} }, false, 'blah');
44+
const client = new CliRequestClient('blah', logger, { defaults: {} }, 'blah');
4745
const httpAgent = client.http.defaults.httpsAgent;
48-
expect(client.keytarWord).to.equal('');
4946
expect(client.pluginName).to.equal('blah');
5047
expect(httpAgent.proxy.host).to.equal('someproxy.com');
5148
expect(httpAgent.proxy.port).to.equal(8080);
@@ -74,38 +71,35 @@ describe('services', () => {
7471
test
7572
.nock('https://foo.com', (api) => {
7673
api.get('/bar').reply(200, '', {
77-
'User-Agent': `twilio-cli/2.27.1 ${pkg.name}\/${
78-
pkg.version
79-
} \(${os.platform()} ${os.arch()}\) dummyCommand keytar`,
74+
'User-Agent': `twilio-cli/2.27.1 ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand`,
8075
});
8176
})
8277
.it('correctly sets user-agent', async () => {
83-
const client = new CliRequestClient('dummyCommand', logger, '', true, 'twilio-cli/2.27.1');
78+
const client = new CliRequestClient('dummyCommand', logger, '', 'twilio-cli/2.27.1');
8479
const response = await client.request({
8580
method: 'GET',
8681
uri: 'https://foo.com/bar',
8782
});
88-
expect(client.keytarWord).to.equal('keytar');
8983
expect(client.lastRequest.headers['User-Agent']).to.equal(
90-
`twilio-cli/2.27.1 ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand keytar`,
84+
`twilio-cli/2.27.1 ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand`,
9185
);
9286
expect(response.statusCode).to.equal(200);
9387
});
9488

9589
test
9690
.nock('https://foo.com', (api) => {
9791
api.get('/bar').reply(200, '', {
98-
'User-Agent': ` ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand keytar`,
92+
'User-Agent': ` ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand`,
9993
});
10094
})
10195
.it('correctly sets user-agent with empty plugin value', async () => {
102-
const client = new CliRequestClient('dummyCommand', logger, '', true, '');
96+
const client = new CliRequestClient('dummyCommand', logger, '', '');
10397
const response = await client.request({
10498
method: 'GET',
10599
uri: 'https://foo.com/bar',
106100
});
107101
expect(client.lastRequest.headers['User-Agent']).to.equal(
108-
` ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand keytar`,
102+
` ${pkg.name}\/${pkg.version} \(${os.platform()} ${os.arch()}\) dummyCommand`,
109103
);
110104
expect(response.statusCode).to.equal(200);
111105
});

test/services/secure-storage.test.js

-62
This file was deleted.

0 commit comments

Comments
 (0)