-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathsecure-storage.js
81 lines (67 loc) · 2.13 KB
/
secure-storage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const { CLI_NAME } = require('./config');
const { TwilioCliError } = require('./error');
const { HELP_ENVIRONMENT_VARIABLES } = require('./messaging/help-messages');
const { logger } = require('./messaging/logging');
const STORAGE_LOCATIONS = {
KEYCHAIN: 'keychain',
WIN_CRED_VAULT: 'win_cred_vault',
LIBSECRET: 'libsecret'
};
const PLATFORM_TO_LOCATION = {
darwin: STORAGE_LOCATIONS.KEYCHAIN,
win32: STORAGE_LOCATIONS.WIN_CRED_VAULT,
linux: STORAGE_LOCATIONS.LIBSECRET
};
class SecureStorage {
constructor({ command, platform } = {}) {
this.command = command;
this.platform = platform || process.platform;
this.keytar = null;
}
async loadKeytar() {
if (!this.keytar) {
try {
this.keytar = await this.command.install('keytar');
// Also sanity-check that we can retrieve passwords (just use a dummy profile ID).
await this.keytar.getPassword(CLI_NAME, CLI_NAME);
} catch (error) {
logger.debug(`Error loading keytar: ${error}`);
// If we can't load up keytar, tell the user that maybe they should just stick to env vars.
throw new TwilioCliError('Secure credential storage failed to load.\n\n' + HELP_ENVIRONMENT_VARIABLES);
}
}
return this.keytar;
}
async saveCredentials(profileId, username, password) {
await this.loadKeytar();
await this.keytar.setPassword(CLI_NAME, profileId, username + '|' + password);
}
async removeCredentials(profileId) {
await this.loadKeytar();
return this.keytar.deletePassword(CLI_NAME, profileId);
}
async getCredentials(profileId) {
let credentials = null;
try {
await this.loadKeytar();
credentials = await this.keytar.getPassword(CLI_NAME, profileId);
} catch (e) {
if (e instanceof TwilioCliError) {
throw e;
}
return { apiKey: 'error', apiSecret: e.message };
}
const [apiKey, apiSecret] = credentials ? credentials.split('|') : ['error', 'error'];
return {
apiKey,
apiSecret
};
}
get storageLocation() {
return PLATFORM_TO_LOCATION[this.platform];
}
}
module.exports = {
SecureStorage,
STORAGE_LOCATIONS
};