@salesforce/core 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +93 -44
  3. package/lib/config/authInfoConfig.d.ts +19 -0
  4. package/lib/config/authInfoConfig.js +35 -0
  5. package/lib/config/config.d.ts +87 -22
  6. package/lib/config/config.js +117 -65
  7. package/lib/config/configAggregator.d.ts +41 -35
  8. package/lib/config/configAggregator.js +102 -73
  9. package/lib/config/configFile.d.ts +2 -2
  10. package/lib/config/configFile.js +38 -29
  11. package/lib/config/configStore.d.ts +9 -9
  12. package/lib/config/configStore.js +17 -15
  13. package/lib/config/envVars.d.ts +15 -9
  14. package/lib/config/envVars.js +71 -47
  15. package/lib/config/orgUsersConfig.js +2 -0
  16. package/lib/config/sandboxOrgConfig.js +2 -0
  17. package/lib/config/sandboxProcessCache.d.ts +16 -0
  18. package/lib/config/sandboxProcessCache.js +38 -0
  19. package/lib/config/tokensConfig.d.ts +10 -0
  20. package/lib/config/tokensConfig.js +29 -0
  21. package/lib/config/ttlConfig.d.ts +34 -0
  22. package/lib/config/ttlConfig.js +50 -0
  23. package/lib/crypto/crypto.js +15 -22
  24. package/lib/crypto/keyChain.js +2 -3
  25. package/lib/crypto/keyChainImpl.d.ts +5 -3
  26. package/lib/crypto/keyChainImpl.js +58 -61
  27. package/lib/crypto/secureBuffer.d.ts +1 -1
  28. package/lib/deviceOauthService.d.ts +3 -3
  29. package/lib/deviceOauthService.js +27 -25
  30. package/lib/exported.d.ts +15 -12
  31. package/lib/exported.js +28 -16
  32. package/lib/global.d.ts +11 -3
  33. package/lib/global.js +39 -12
  34. package/lib/lifecycleEvents.d.ts +1 -1
  35. package/lib/lifecycleEvents.js +3 -0
  36. package/lib/logger.d.ts +19 -9
  37. package/lib/logger.js +112 -86
  38. package/lib/messages.d.ts +53 -36
  39. package/lib/messages.js +81 -91
  40. package/lib/org/authInfo.d.ts +56 -20
  41. package/lib/org/authInfo.js +232 -131
  42. package/lib/org/authRemover.d.ts +8 -7
  43. package/lib/org/authRemover.js +32 -28
  44. package/lib/org/connection.d.ts +13 -37
  45. package/lib/org/connection.js +78 -124
  46. package/lib/org/index.js +5 -1
  47. package/lib/org/org.d.ts +151 -48
  48. package/lib/org/org.js +468 -225
  49. package/lib/org/orgConfigProperties.d.ts +64 -3
  50. package/lib/org/orgConfigProperties.js +96 -4
  51. package/lib/org/permissionSetAssignment.js +4 -13
  52. package/lib/org/scratchOrgCache.d.ts +20 -0
  53. package/lib/org/scratchOrgCache.js +33 -0
  54. package/lib/org/scratchOrgCreate.d.ts +28 -17
  55. package/lib/org/scratchOrgCreate.js +125 -53
  56. package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
  57. package/lib/org/scratchOrgErrorCodes.js +34 -17
  58. package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
  59. package/lib/org/scratchOrgInfoApi.d.ts +21 -47
  60. package/lib/org/scratchOrgInfoApi.js +129 -63
  61. package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
  62. package/lib/org/scratchOrgInfoGenerator.js +76 -62
  63. package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
  64. package/lib/org/scratchOrgLifecycleEvents.js +41 -0
  65. package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
  66. package/lib/org/scratchOrgSettingsGenerator.js +165 -98
  67. package/lib/org/scratchOrgTypes.d.ts +43 -0
  68. package/lib/org/scratchOrgTypes.js +9 -0
  69. package/lib/org/user.d.ts +1 -1
  70. package/lib/org/user.js +25 -34
  71. package/lib/schema/printer.d.ts +6 -0
  72. package/lib/schema/printer.js +34 -31
  73. package/lib/schema/validator.d.ts +12 -10
  74. package/lib/schema/validator.js +56 -76
  75. package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
  76. package/lib/{sfdxError.js → sfError.js} +40 -30
  77. package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
  78. package/lib/sfProject.js +651 -0
  79. package/lib/stateAggregator/accessors/aliasAccessor.d.ts +129 -0
  80. package/lib/stateAggregator/accessors/aliasAccessor.js +263 -0
  81. package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
  82. package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
  83. package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
  84. package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
  85. package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
  86. package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
  87. package/lib/stateAggregator/index.d.ts +4 -0
  88. package/lib/stateAggregator/index.js +27 -0
  89. package/lib/stateAggregator/stateAggregator.d.ts +25 -0
  90. package/lib/stateAggregator/stateAggregator.js +46 -0
  91. package/lib/status/myDomainResolver.d.ts +1 -1
  92. package/lib/status/myDomainResolver.js +4 -4
  93. package/lib/status/pollingClient.js +4 -4
  94. package/lib/status/streamingClient.d.ts +2 -2
  95. package/lib/status/streamingClient.js +58 -63
  96. package/lib/status/types.d.ts +2 -2
  97. package/lib/testSetup.d.ts +204 -75
  98. package/lib/testSetup.js +468 -164
  99. package/lib/util/cache.d.ts +2 -2
  100. package/lib/util/cache.js +6 -6
  101. package/lib/util/checkLightningDomain.js +3 -4
  102. package/lib/util/directoryWriter.d.ts +12 -0
  103. package/lib/util/directoryWriter.js +54 -0
  104. package/lib/util/getJwtAudienceUrl.js +1 -1
  105. package/lib/util/internal.d.ts +28 -2
  106. package/lib/util/internal.js +65 -8
  107. package/lib/util/jsonXmlTools.js +2 -4
  108. package/lib/util/mapKeys.d.ts +9 -9
  109. package/lib/util/mapKeys.js +13 -9
  110. package/lib/util/sfdc.d.ts +51 -51
  111. package/lib/util/sfdc.js +74 -79
  112. package/lib/util/sfdcUrl.d.ts +5 -19
  113. package/lib/util/sfdcUrl.js +40 -49
  114. package/lib/util/structuredWriter.d.ts +9 -0
  115. package/lib/util/structuredWriter.js +3 -0
  116. package/lib/util/zipWriter.d.ts +8 -6
  117. package/lib/util/zipWriter.js +13 -13
  118. package/lib/webOAuthServer.d.ts +20 -6
  119. package/lib/webOAuthServer.js +102 -56
  120. package/messageTransformer/messageTransformer.ts +93 -0
  121. package/messages/auth.md +9 -1
  122. package/messages/config.md +42 -6
  123. package/messages/connection.md +8 -0
  124. package/messages/core.md +10 -0
  125. package/messages/envVars.md +37 -3
  126. package/messages/org.md +21 -1
  127. package/messages/scratchOrgCreate.md +2 -6
  128. package/messages/scratchOrgErrorCodes.md +17 -1
  129. package/messages/scratchOrgInfoApi.md +9 -0
  130. package/messages/scratchOrgInfoGenerator.md +9 -1
  131. package/package.json +123 -46
  132. package/CHANGELOG.md +0 -1244
  133. package/lib/config/keychainConfig.d.ts +0 -19
  134. package/lib/config/keychainConfig.js +0 -43
  135. package/lib/globalInfo/accessors/aliasAccessor.d.ts +0 -83
  136. package/lib/globalInfo/accessors/aliasAccessor.js +0 -130
  137. package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
  138. package/lib/globalInfo/accessors/orgAccessor.js +0 -45
  139. package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
  140. package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
  141. package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
  142. package/lib/globalInfo/globalInfoConfig.js +0 -105
  143. package/lib/globalInfo/index.d.ts +0 -6
  144. package/lib/globalInfo/index.js +0 -29
  145. package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
  146. package/lib/globalInfo/sfdxDataHandler.js +0 -217
  147. package/lib/globalInfo/types.d.ts +0 -39
  148. package/lib/globalInfo/types.js +0 -10
  149. package/lib/sfdxProject.js +0 -557
  150. package/lib/util/fs.d.ts +0 -201
  151. package/lib/util/fs.js +0 -378
@@ -16,6 +16,7 @@ const kit_1 = require("@salesforce/kit");
16
16
  const logger_1 = require("../logger");
17
17
  const messages_1 = require("../messages");
18
18
  const cache_1 = require("../util/cache");
19
+ const global_1 = require("../global");
19
20
  const keyChain_1 = require("./keyChain");
20
21
  const secureBuffer_1 = require("./secureBuffer");
21
22
  const TAG_DELIMITER = ':';
@@ -25,13 +26,7 @@ const AUTH_TAG_LENGTH = 32;
25
26
  const ENCRYPTED_CHARS = /[a-f0-9]/;
26
27
  const KEY_NAME = 'sfdx';
27
28
  const ACCOUNT = 'local';
28
- messages_1.Messages.importMessagesDirectory((0, path_1.join)(__dirname));
29
- const messages = messages_1.Messages.load('@salesforce/core', 'encryption', [
30
- 'keychainPasswordCreationError',
31
- 'invalidEncryptedFormatError',
32
- 'authDecryptError',
33
- 'macKeychainOutOfSync',
34
- ]);
29
+ const messages = new messages_1.Messages('@salesforce/core', 'encryption', new Map([["invalidEncryptedFormatError", "The encrypted data is not properly formatted."], ["invalidEncryptedFormatError.actions", ["If attempting to create a scratch org then re-authorize. Otherwise create a new scratch org."]], ["authDecryptError", "Failed to decipher auth data. reason: %s."], ["unsupportedOperatingSystemError", "Unsupported Operating System: %s"], ["missingCredentialProgramError", "Unable to find required security software: %s"], ["credentialProgramAccessError", "Unable to execute security software: %s"], ["passwordRetryError", "Failed to get the password after %i retries."], ["passwordRequiredError", "A password is required."], ["keyChainServiceRequiredError", "Unable to get or set a keychain value without a service name."], ["keyChainAccountRequiredError", "Unable to get or set a keychain value without an account name."], ["keyChainUserCanceledError", "User canceled authentication."], ["keychainPasswordCreationError", "Failed to create a password in the keychain."], ["genericKeychainServiceError", "The service and account specified in %s do not match the version of the toolbelt."], ["genericKeychainServiceError.actions", ["Check your toolbelt version and re-auth."]], ["genericKeychainInvalidPermsError", "Invalid file permissions for secret file"], ["genericKeychainInvalidPermsError.actions", ["Ensure the file %s has the file permission octal value of %s."]], ["passwordNotFoundError", "Could not find password.\n%s"], ["passwordNotFoundError.actions", ["Ensure a valid password is returned with the following command: [%s]"]], ["setCredentialError", "Command failed with response:\n%s"], ["setCredentialError.actions", ["Determine why this command failed to set an encryption key for user %s: [%s]."]], ["macKeychainOutOfSync", "We\u2019ve encountered an error with the Mac keychain being out of sync with your `sfdx` credentials. To fix the problem, sync your credentials by authenticating into your org again using the auth commands."]]));
35
30
  const makeSecureBuffer = (password) => {
36
31
  const newSb = new secureBuffer_1.SecureBuffer();
37
32
  newSb.consume(Buffer.from((0, ts_types_1.ensure)(password), 'utf8'));
@@ -49,23 +44,20 @@ const keychainPromises = {
49
44
  * @param account The keychain account name.
50
45
  */
51
46
  getPassword(_keychain, service, account) {
52
- const sb = cache_1.Cache.get(`${service}:${account}`);
47
+ const cacheKey = `${global_1.Global.DIR}:${service}:${account}`;
48
+ const sb = cache_1.Cache.get(cacheKey);
53
49
  if (!sb) {
54
- return new Promise((resolve, reject) => {
55
- return _keychain.getPassword({ service, account }, (err, password) => {
56
- if (err)
57
- return reject(err);
58
- cache_1.Cache.set(`${service}:${account}`, makeSecureBuffer(password));
59
- return resolve({ username: account, password: (0, ts_types_1.ensure)(password) });
60
- });
61
- });
50
+ return new Promise((resolve, reject) => _keychain.getPassword({ service, account }, (err, password) => {
51
+ if (err)
52
+ return reject(err);
53
+ cache_1.Cache.set(cacheKey, makeSecureBuffer(password));
54
+ return resolve({ username: account, password: (0, ts_types_1.ensure)(password) });
55
+ }));
62
56
  }
63
57
  else {
64
58
  const pw = sb.value((buffer) => buffer.toString('utf8'));
65
- cache_1.Cache.set(`${service}:${account}`, makeSecureBuffer(pw));
66
- return new Promise((resolve) => {
67
- return resolve({ username: account, password: (0, ts_types_1.ensure)(pw) });
68
- });
59
+ cache_1.Cache.set(cacheKey, makeSecureBuffer(pw));
60
+ return new Promise((resolve) => resolve({ username: account, password: (0, ts_types_1.ensure)(pw) }));
69
61
  }
70
62
  },
71
63
  /**
@@ -98,7 +90,7 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
98
90
  constructor(options) {
99
91
  super(options);
100
92
  this.key = new secureBuffer_1.SecureBuffer();
101
- this.options = options || {};
93
+ this.options = options ?? {};
102
94
  }
103
95
  encrypt(text) {
104
96
  if (text == null) {
@@ -137,7 +129,7 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
137
129
  }
138
130
  catch (err) {
139
131
  const error = messages.createError('authDecryptError', [err.message], [], err);
140
- const useGenericUnixKeychain = kit_1.env.getBoolean('SFDX_USE_GENERIC_UNIX_KEYCHAIN') || kit_1.env.getBoolean('USE_GENERIC_UNIX_KEYCHAIN');
132
+ const useGenericUnixKeychain = kit_1.env.getBoolean('SF_USE_GENERIC_UNIX_KEYCHAIN') || kit_1.env.getBoolean('USE_GENERIC_UNIX_KEYCHAIN');
141
133
  if (os.platform() === 'darwin' && !useGenericUnixKeychain) {
142
134
  error.actions = [messages.getMessage('macKeychainOutOfSync')];
143
135
  }
@@ -153,6 +145,7 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
153
145
  * @param text The text
154
146
  * @returns true if the text is encrypted, false otherwise.
155
147
  */
148
+ // eslint-disable-next-line class-methods-use-this
156
149
  isEncrypted(text) {
157
150
  if (text == null) {
158
151
  return false;
@@ -11,8 +11,7 @@ const kit_1 = require("@salesforce/kit");
11
11
  const logger_1 = require("../logger");
12
12
  const messages_1 = require("../messages");
13
13
  const keyChainImpl_1 = require("./keyChainImpl");
14
- messages_1.Messages.importMessagesDirectory(__dirname);
15
- const messages = messages_1.Messages.load('@salesforce/core', 'encryption', ['unsupportedOperatingSystemError']);
14
+ const messages = new messages_1.Messages('@salesforce/core', 'encryption', new Map([["invalidEncryptedFormatError", "The encrypted data is not properly formatted."], ["invalidEncryptedFormatError.actions", ["If attempting to create a scratch org then re-authorize. Otherwise create a new scratch org."]], ["authDecryptError", "Failed to decipher auth data. reason: %s."], ["unsupportedOperatingSystemError", "Unsupported Operating System: %s"], ["missingCredentialProgramError", "Unable to find required security software: %s"], ["credentialProgramAccessError", "Unable to execute security software: %s"], ["passwordRetryError", "Failed to get the password after %i retries."], ["passwordRequiredError", "A password is required."], ["keyChainServiceRequiredError", "Unable to get or set a keychain value without a service name."], ["keyChainAccountRequiredError", "Unable to get or set a keychain value without an account name."], ["keyChainUserCanceledError", "User canceled authentication."], ["keychainPasswordCreationError", "Failed to create a password in the keychain."], ["genericKeychainServiceError", "The service and account specified in %s do not match the version of the toolbelt."], ["genericKeychainServiceError.actions", ["Check your toolbelt version and re-auth."]], ["genericKeychainInvalidPermsError", "Invalid file permissions for secret file"], ["genericKeychainInvalidPermsError.actions", ["Ensure the file %s has the file permission octal value of %s."]], ["passwordNotFoundError", "Could not find password.\n%s"], ["passwordNotFoundError.actions", ["Ensure a valid password is returned with the following command: [%s]"]], ["setCredentialError", "Command failed with response:\n%s"], ["setCredentialError.actions", ["Determine why this command failed to set an encryption key for user %s: [%s]."]], ["macKeychainOutOfSync", "We\u2019ve encountered an error with the Mac keychain being out of sync with your `sfdx` credentials. To fix the problem, sync your credentials by authenticating into your org again using the auth commands."]]));
16
15
  /**
17
16
  * Gets the os level keychain impl.
18
17
  *
@@ -22,7 +21,7 @@ const messages = messages_1.Messages.load('@salesforce/core', 'encryption', ['un
22
21
  const retrieveKeychain = async (platform) => {
23
22
  const logger = await logger_1.Logger.child('keyChain');
24
23
  logger.debug(`platform: ${platform}`);
25
- const useGenericUnixKeychainVar = kit_1.env.getBoolean('SFDX_USE_GENERIC_UNIX_KEYCHAIN');
24
+ const useGenericUnixKeychainVar = kit_1.env.getBoolean('SF_USE_GENERIC_UNIX_KEYCHAIN');
26
25
  const shouldUseGenericUnixKeychain = useGenericUnixKeychainVar && useGenericUnixKeychainVar;
27
26
  if (platform.startsWith('win')) {
28
27
  return keyChainImpl_1.keyChainImpl.generic_windows;
@@ -1,8 +1,10 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
2
4
  import * as childProcess from 'child_process';
3
5
  import * as nodeFs from 'fs';
4
6
  import { Nullable } from '@salesforce/ts-types';
5
- export declare type FsIfc = Pick<typeof nodeFs, 'statSync'>;
7
+ export type FsIfc = Pick<typeof nodeFs, 'statSync'>;
6
8
  /**
7
9
  * Basic keychain interface.
8
10
  */
@@ -75,7 +77,7 @@ declare enum SecretField {
75
77
  ACCOUNT = "account",
76
78
  KEY = "key"
77
79
  }
78
- declare type SecretContents = {
80
+ type SecretContents = {
79
81
  [SecretField.ACCOUNT]: string;
80
82
  [SecretField.KEY]?: string;
81
83
  [SecretField.SERVICE]: string;
@@ -110,5 +112,5 @@ export declare const keyChainImpl: {
110
112
  linux: KeychainAccess;
111
113
  validateProgram: (programPath: string, fsIfc: FsIfc, isExeIfc: (mode: number, gid: number, uid: number) => boolean) => Promise<void>;
112
114
  };
113
- export declare type KeyChain = GenericUnixKeychainAccess | GenericWindowsKeychainAccess | KeychainAccess;
115
+ export type KeyChain = GenericUnixKeychainAccess | GenericWindowsKeychainAccess | KeychainAccess;
114
116
  export {};
@@ -9,36 +9,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.keyChainImpl = exports.GenericWindowsKeychainAccess = exports.GenericUnixKeychainAccess = exports.GenericKeychainAccess = exports.KeychainAccess = void 0;
10
10
  const childProcess = require("child_process");
11
11
  const nodeFs = require("fs");
12
+ const fs = require("fs");
12
13
  const os = require("os");
13
- const path = require("path");
14
14
  const os_1 = require("os");
15
+ const path = require("path");
15
16
  const ts_types_1 = require("@salesforce/ts-types");
17
+ const kit_1 = require("@salesforce/kit");
16
18
  const global_1 = require("../global");
17
- const fs_1 = require("../util/fs");
18
19
  const messages_1 = require("../messages");
19
- messages_1.Messages.importMessagesDirectory(__dirname);
20
- const messages = messages_1.Messages.load('@salesforce/core', 'encryption', [
21
- 'missingCredentialProgramError',
22
- 'credentialProgramAccessError',
23
- 'keyChainServiceRequiredError',
24
- 'keyChainAccountRequiredError',
25
- 'passwordRetryError',
26
- 'passwordRequiredError',
27
- 'passwordNotFoundError',
28
- 'setCredentialError',
29
- 'keyChainUserCanceledError',
30
- 'genericKeychainServiceError',
31
- 'genericKeychainInvalidPermsError',
32
- ]);
20
+ const messages = new messages_1.Messages('@salesforce/core', 'encryption', new Map([["invalidEncryptedFormatError", "The encrypted data is not properly formatted."], ["invalidEncryptedFormatError.actions", ["If attempting to create a scratch org then re-authorize. Otherwise create a new scratch org."]], ["authDecryptError", "Failed to decipher auth data. reason: %s."], ["unsupportedOperatingSystemError", "Unsupported Operating System: %s"], ["missingCredentialProgramError", "Unable to find required security software: %s"], ["credentialProgramAccessError", "Unable to execute security software: %s"], ["passwordRetryError", "Failed to get the password after %i retries."], ["passwordRequiredError", "A password is required."], ["keyChainServiceRequiredError", "Unable to get or set a keychain value without a service name."], ["keyChainAccountRequiredError", "Unable to get or set a keychain value without an account name."], ["keyChainUserCanceledError", "User canceled authentication."], ["keychainPasswordCreationError", "Failed to create a password in the keychain."], ["genericKeychainServiceError", "The service and account specified in %s do not match the version of the toolbelt."], ["genericKeychainServiceError.actions", ["Check your toolbelt version and re-auth."]], ["genericKeychainInvalidPermsError", "Invalid file permissions for secret file"], ["genericKeychainInvalidPermsError.actions", ["Ensure the file %s has the file permission octal value of %s."]], ["passwordNotFoundError", "Could not find password.\n%s"], ["passwordNotFoundError.actions", ["Ensure a valid password is returned with the following command: [%s]"]], ["setCredentialError", "Command failed with response:\n%s"], ["setCredentialError.actions", ["Determine why this command failed to set an encryption key for user %s: [%s]."]], ["macKeychainOutOfSync", "We\u2019ve encountered an error with the Mac keychain being out of sync with your `sfdx` credentials. To fix the problem, sync your credentials by authenticating into your org again using the auth commands."]]));
33
21
  const GET_PASSWORD_RETRY_COUNT = 3;
34
22
  /**
35
23
  * Helper to reduce an array of cli args down to a presentable string for logging.
36
24
  *
37
25
  * @param optionsArray CLI command args.
38
26
  */
39
- function _optionsToString(optionsArray) {
40
- return optionsArray.reduce((accum, element) => `${accum} ${element}`);
41
- }
27
+ const optionsToString = (optionsArray) => optionsArray.join(' ');
42
28
  /**
43
29
  * Helper to determine if a program is executable. Returns `true` if the program is executable for the user. For
44
30
  * Windows true is always returned.
@@ -47,7 +33,7 @@ function _optionsToString(optionsArray) {
47
33
  * @param gid Unix group id.
48
34
  * @param uid Unix user id.
49
35
  */
50
- const _isExe = (mode, gid, uid) => {
36
+ const isExe = (mode, gid, uid) => {
51
37
  if (process.platform === 'win32') {
52
38
  return true;
53
39
  }
@@ -58,15 +44,18 @@ const _isExe = (mode, gid, uid) => {
58
44
  /**
59
45
  * Private helper to validate that a program exists on the file system and is executable.
60
46
  *
61
- * **Throws** *{@link SfdxError}{ name: 'MissingCredentialProgramError' }* When the OS credential program isn't found.
47
+ * **Throws** *{@link SfError}{ name: 'MissingCredentialProgramError' }* When the OS credential program isn't found.
62
48
  *
63
- * **Throws** *{@link SfdxError}{ name: 'CredentialProgramAccessError' }* When the OS credential program isn't accessible.
49
+ * **Throws** *{@link SfError}{ name: 'CredentialProgramAccessError' }* When the OS credential program isn't accessible.
64
50
  *
65
51
  * @param programPath The absolute path of the program.
66
52
  * @param fsIfc The file system interface.
67
53
  * @param isExeIfc Executable validation function.
68
54
  */
69
- const _validateProgram = async (programPath, fsIfc, isExeIfc) => {
55
+ // eslint-disable-next-line no-underscore-dangle
56
+ const _validateProgram = async (programPath, fsIfc, isExeIfc
57
+ // eslint-disable-next-line @typescript-eslint/require-await
58
+ ) => {
70
59
  let noPermission;
71
60
  try {
72
61
  const stats = fsIfc.statSync(programPath);
@@ -97,7 +86,7 @@ class KeychainAccess {
97
86
  * Validates the os level program is executable.
98
87
  */
99
88
  async validateProgram() {
100
- await _validateProgram(this.osImpl.getProgram(), this.fsIfc, _isExe);
89
+ await _validateProgram(this.osImpl.getProgram(), this.fsIfc, isExe);
101
90
  }
102
91
  /**
103
92
  * Returns a password using the native program for credential management.
@@ -135,6 +124,7 @@ class KeychainAccess {
135
124
  return await this.osImpl.onGetCommandClose(code, stdout, stderr, opts, fn);
136
125
  }
137
126
  catch (e) {
127
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
138
128
  // @ts-ignore
139
129
  if (e.retry) {
140
130
  if (retryCount >= GET_PASSWORD_RETRY_COUNT) {
@@ -171,7 +161,7 @@ class KeychainAccess {
171
161
  fn(messages.createError('passwordRequiredError'));
172
162
  return;
173
163
  }
174
- await _validateProgram(this.osImpl.getProgram(), this.fsIfc, _isExe);
164
+ await _validateProgram(this.osImpl.getProgram(), this.fsIfc, isExe);
175
165
  const credManager = this.osImpl.setCommandFunc(opts, childProcess.spawn);
176
166
  let stdout = '';
177
167
  let stderr = '';
@@ -187,7 +177,7 @@ class KeychainAccess {
187
177
  }
188
178
  credManager.on('close',
189
179
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
190
- async (code) => await this.osImpl.onSetCommandClose(code, stdout, stderr, opts, fn));
180
+ async (code) => this.osImpl.onSetCommandClose(code, stdout, stderr, opts, fn));
191
181
  if (credManager.stdin) {
192
182
  credManager.stdin.end();
193
183
  }
@@ -199,23 +189,25 @@ exports.KeychainAccess = KeychainAccess;
199
189
  *
200
190
  * Uses libsecret.
201
191
  */
202
- const _linuxImpl = {
192
+ const linuxImpl = {
203
193
  getProgram() {
204
- return process.env.SFDX_SECRET_TOOL_PATH || path.join(path.sep, 'usr', 'bin', 'secret-tool');
194
+ return process.env.SFDX_SECRET_TOOL_PATH ?? path.join(path.sep, 'usr', 'bin', 'secret-tool');
205
195
  },
206
196
  getProgramOptions(opts) {
207
197
  return ['lookup', 'user', opts.account, 'domain', opts.service];
208
198
  },
209
199
  getCommandFunc(opts, fn) {
210
- return fn(_linuxImpl.getProgram(), _linuxImpl.getProgramOptions(opts));
200
+ return fn(linuxImpl.getProgram(), linuxImpl.getProgramOptions(opts));
211
201
  },
202
+ // eslint-disable-next-line @typescript-eslint/require-await
212
203
  async onGetCommandClose(code, stdout, stderr, opts, fn) {
213
204
  if (code === 1) {
214
- const command = `${_linuxImpl.getProgram()} ${_optionsToString(_linuxImpl.getProgramOptions(opts))}`;
205
+ const command = `${linuxImpl.getProgram()} ${optionsToString(linuxImpl.getProgramOptions(opts))}`;
215
206
  const error = messages.createError('passwordNotFoundError', [], [command]);
216
207
  // This is a workaround for linux.
217
208
  // Calling secret-tool too fast can cause it to return an unexpected error. (below)
218
- if (stderr != null && stderr.includes('invalid or unencryptable secret')) {
209
+ if (stderr?.includes('invalid or unencryptable secret')) {
210
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
219
211
  // @ts-ignore TODO: make an error subclass with this field
220
212
  error.retry = true;
221
213
  // Throwing here allows us to perform a retry in KeychainAccess
@@ -232,15 +224,16 @@ const _linuxImpl = {
232
224
  return ['store', "--label='salesforce.com'", 'user', opts.account, 'domain', opts.service];
233
225
  },
234
226
  setCommandFunc(opts, fn) {
235
- const secretTool = fn(_linuxImpl.getProgram(), _linuxImpl.setProgramOptions(opts));
227
+ const secretTool = fn(linuxImpl.getProgram(), linuxImpl.setProgramOptions(opts));
236
228
  if (secretTool.stdin) {
237
229
  secretTool.stdin.write(`${opts.password}\n`);
238
230
  }
239
231
  return secretTool;
240
232
  },
233
+ // eslint-disable-next-line @typescript-eslint/require-await
241
234
  async onSetCommandClose(code, stdout, stderr, opts, fn) {
242
235
  if (code !== 0) {
243
- const command = `${_linuxImpl.getProgram()} ${_optionsToString(_linuxImpl.setProgramOptions(opts))}`;
236
+ const command = `${linuxImpl.getProgram()} ${optionsToString(linuxImpl.setProgramOptions(opts))}`;
244
237
  fn(messages.createError('setCredentialError', [`${stdout} - ${stderr}`], [os.userInfo().username, command]));
245
238
  }
246
239
  else {
@@ -253,7 +246,7 @@ const _linuxImpl = {
253
246
  *
254
247
  * /usr/bin/security is a cli front end for OSX keychain.
255
248
  */
256
- const _darwinImpl = {
249
+ const darwinImpl = {
257
250
  getProgram() {
258
251
  return path.join(path.sep, 'usr', 'bin', 'security');
259
252
  },
@@ -261,8 +254,9 @@ const _darwinImpl = {
261
254
  return ['find-generic-password', '-a', opts.account, '-s', opts.service, '-g'];
262
255
  },
263
256
  getCommandFunc(opts, fn) {
264
- return fn(_darwinImpl.getProgram(), _darwinImpl.getProgramOptions(opts));
257
+ return fn(darwinImpl.getProgram(), darwinImpl.getProgramOptions(opts));
265
258
  },
259
+ // eslint-disable-next-line @typescript-eslint/require-await
266
260
  async onGetCommandClose(code, stdout, stderr, opts, fn) {
267
261
  let err;
268
262
  if (code !== 0) {
@@ -272,7 +266,7 @@ const _darwinImpl = {
272
266
  break;
273
267
  }
274
268
  default: {
275
- const command = `${_darwinImpl.getProgram()} ${_optionsToString(_darwinImpl.getProgramOptions(opts))}`;
269
+ const command = `${darwinImpl.getProgram()} ${optionsToString(darwinImpl.getProgramOptions(opts))}`;
276
270
  err = messages.createError('passwordNotFoundError', [`${stdout} - ${stderr}`], [command]);
277
271
  }
278
272
  }
@@ -283,7 +277,7 @@ const _darwinImpl = {
283
277
  // stdout. Reference: http://blog.macromates.com/2006/keychain-access-from-shell/
284
278
  if (stderr.includes('password')) {
285
279
  const match = RegExp(/"(.*)"/).exec(stderr);
286
- if (!match || !match[1]) {
280
+ if (!match?.[1]) {
287
281
  fn(messages.createError('passwordNotFoundError', [`${stdout} - ${stderr}`]));
288
282
  }
289
283
  else {
@@ -291,7 +285,7 @@ const _darwinImpl = {
291
285
  }
292
286
  }
293
287
  else {
294
- const command = `${_darwinImpl.getProgram()} ${_optionsToString(_darwinImpl.getProgramOptions(opts))}`;
288
+ const command = `${darwinImpl.getProgram()} ${optionsToString(darwinImpl.getProgramOptions(opts))}`;
295
289
  fn(messages.createError('passwordNotFoundError', [`${stdout} - ${stderr}`], [command]));
296
290
  }
297
291
  },
@@ -303,11 +297,12 @@ const _darwinImpl = {
303
297
  return result;
304
298
  },
305
299
  setCommandFunc(opts, fn) {
306
- return fn(_darwinImpl.getProgram(), _darwinImpl.setProgramOptions(opts));
300
+ return fn(darwinImpl.getProgram(), darwinImpl.setProgramOptions(opts));
307
301
  },
302
+ // eslint-disable-next-line @typescript-eslint/require-await
308
303
  async onSetCommandClose(code, stdout, stderr, opts, fn) {
309
304
  if (code !== 0) {
310
- const command = `${_darwinImpl.getProgram()} ${_optionsToString(_darwinImpl.setProgramOptions(opts))}`;
305
+ const command = `${darwinImpl.getProgram()} ${optionsToString(darwinImpl.setProgramOptions(opts))}`;
311
306
  fn(messages.createError('setCredentialError', [`${stdout} - ${stderr}`], [os.userInfo().username, command]));
312
307
  }
313
308
  else {
@@ -315,31 +310,32 @@ const _darwinImpl = {
315
310
  }
316
311
  },
317
312
  };
318
- const secretFile = path.join((0, os_1.homedir)(), global_1.Global.SFDX_STATE_FOLDER, 'key.json');
313
+ const getSecretFile = () => path.join(global_1.Global.DIR, 'key.json');
319
314
  var SecretField;
320
315
  (function (SecretField) {
321
316
  SecretField["SERVICE"] = "service";
322
317
  SecretField["ACCOUNT"] = "account";
323
318
  SecretField["KEY"] = "key";
324
319
  })(SecretField || (SecretField = {}));
325
- async function _writeFile(opts, fn) {
320
+ async function writeFile(opts, fn) {
326
321
  try {
327
322
  const contents = {
328
323
  [SecretField.ACCOUNT]: opts.account,
329
324
  [SecretField.KEY]: opts.password,
330
325
  [SecretField.SERVICE]: opts.service,
331
326
  };
332
- await fs_1.fs.mkdirp(path.dirname(secretFile));
333
- await fs_1.fs.writeFile(secretFile, JSON.stringify(contents, null, 4), { mode: '600' });
327
+ const secretFile = getSecretFile();
328
+ await fs.promises.mkdir(path.dirname(secretFile), { recursive: true });
329
+ await fs.promises.writeFile(secretFile, JSON.stringify(contents, null, 4), { mode: '600' });
334
330
  fn(null, contents);
335
331
  }
336
332
  catch (err) {
337
333
  fn(err);
338
334
  }
339
335
  }
340
- async function _readFile() {
336
+ async function readFile() {
341
337
  // The file and access is validated before this method is called
342
- const fileContents = await fs_1.fs.readJsonMap(secretFile);
338
+ const fileContents = (0, kit_1.parseJsonMap)(await fs.promises.readFile(getSecretFile(), 'utf8'));
343
339
  return {
344
340
  account: (0, ts_types_1.ensureString)(fileContents[SecretField.ACCOUNT]),
345
341
  password: (0, ts_types_1.asString)(fileContents[SecretField.KEY]),
@@ -358,7 +354,7 @@ class GenericKeychainAccess {
358
354
  if (fileAccessError == null) {
359
355
  // read it's contents
360
356
  try {
361
- const { service, account, password } = await _readFile();
357
+ const { service, account, password } = await readFile();
362
358
  // validate service name and account just because
363
359
  if (opts.service === service && opts.account === account) {
364
360
  fn(null, password);
@@ -366,20 +362,18 @@ class GenericKeychainAccess {
366
362
  else {
367
363
  // if the service and account names don't match then maybe someone or something is editing
368
364
  // that file. #donotallow
369
- fn(messages.createError('genericKeychainServiceError', [secretFile]));
365
+ fn(messages.createError('genericKeychainServiceError', [getSecretFile()]));
370
366
  }
371
367
  }
372
368
  catch (readJsonErr) {
373
369
  fn(readJsonErr);
374
370
  }
375
371
  }
372
+ else if (fileAccessError.code === 'ENOENT') {
373
+ fn(messages.createError('passwordNotFoundError'));
374
+ }
376
375
  else {
377
- if (fileAccessError.code === 'ENOENT') {
378
- fn(messages.createError('passwordNotFoundError'));
379
- }
380
- else {
381
- fn(fileAccessError);
382
- }
376
+ fn(fileAccessError);
383
377
  }
384
378
  });
385
379
  }
@@ -391,7 +385,7 @@ class GenericKeychainAccess {
391
385
  // file not found
392
386
  if (fileAccessError.code === 'ENOENT') {
393
387
  // create the file
394
- await _writeFile.call(this, opts, fn);
388
+ await writeFile.call(this, opts, fn);
395
389
  }
396
390
  else {
397
391
  fn(fileAccessError);
@@ -399,14 +393,15 @@ class GenericKeychainAccess {
399
393
  }
400
394
  else {
401
395
  // the existing file validated. we can write the updated key
402
- await _writeFile.call(this, opts, fn);
396
+ await writeFile.call(this, opts, fn);
403
397
  }
404
398
  });
405
399
  }
400
+ // eslint-disable-next-line class-methods-use-this
406
401
  async isValidFileAccess(cb) {
407
402
  try {
408
403
  const root = (0, os_1.homedir)();
409
- await fs_1.fs.access(path.join(root, global_1.Global.SFDX_STATE_FOLDER), fs_1.fs.constants.R_OK | fs_1.fs.constants.X_OK | fs_1.fs.constants.W_OK);
404
+ await fs.promises.access(path.join(root, global_1.Global.SFDX_STATE_FOLDER), fs.constants.R_OK | fs.constants.X_OK | fs.constants.W_OK);
410
405
  await cb(null);
411
406
  }
412
407
  catch (err) {
@@ -426,13 +421,15 @@ class GenericUnixKeychainAccess extends GenericKeychainAccess {
426
421
  await cb(err);
427
422
  }
428
423
  else {
429
- const stats = await fs_1.fs.stat(secretFile);
424
+ const secretFile = getSecretFile();
425
+ const stats = await fs.promises.stat(secretFile);
430
426
  const octalModeStr = (stats.mode & 0o777).toString(8);
431
427
  const EXPECTED_OCTAL_PERM_VALUE = '600';
432
428
  if (octalModeStr === EXPECTED_OCTAL_PERM_VALUE) {
433
429
  await cb(null);
434
430
  }
435
431
  else {
432
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
436
433
  cb(messages.createError('genericKeychainInvalidPermsError', [secretFile], [secretFile, EXPECTED_OCTAL_PERM_VALUE]));
437
434
  }
438
435
  }
@@ -451,7 +448,7 @@ class GenericWindowsKeychainAccess extends GenericKeychainAccess {
451
448
  }
452
449
  else {
453
450
  try {
454
- await fs_1.fs.access(secretFile, fs_1.fs.constants.R_OK | fs_1.fs.constants.W_OK);
451
+ await fs.promises.access(getSecretFile(), fs.constants.R_OK | fs.constants.W_OK);
455
452
  await cb(null);
456
453
  }
457
454
  catch (e) {
@@ -470,8 +467,8 @@ exports.keyChainImpl = {
470
467
  generic_unix: new GenericUnixKeychainAccess(),
471
468
  // eslint-disable-next-line camelcase
472
469
  generic_windows: new GenericWindowsKeychainAccess(),
473
- darwin: new KeychainAccess(_darwinImpl, nodeFs),
474
- linux: new KeychainAccess(_linuxImpl, nodeFs),
470
+ darwin: new KeychainAccess(darwinImpl, nodeFs),
471
+ linux: new KeychainAccess(linuxImpl, nodeFs),
475
472
  validateProgram: _validateProgram,
476
473
  };
477
474
  //# sourceMappingURL=keyChainImpl.js.map
@@ -5,7 +5,7 @@ import { Optional } from '@salesforce/ts-types';
5
5
  *
6
6
  * @param buffer A buffer containing the decrypted secret.
7
7
  */
8
- export declare type DecipherCallback<T> = (buffer: Buffer) => T;
8
+ export type DecipherCallback<T> = (buffer: Buffer) => T;
9
9
  /**
10
10
  * Used to store and retrieve a sensitive information in memory. This is not meant for at rest encryption.
11
11
  *
@@ -1,7 +1,7 @@
1
1
  import { AsyncCreatable } from '@salesforce/kit';
2
- import { OAuth2Config } from 'jsforce/lib/oauth2';
3
- import { Nullable, JsonMap } from '@salesforce/ts-types';
4
- import { AuthInfo } from './org/authInfo';
2
+ import { OAuth2Config } from 'jsforce';
3
+ import { JsonMap, Nullable } from '@salesforce/ts-types';
4
+ import { AuthInfo } from './org';
5
5
  export interface DeviceCodeResponse extends JsonMap {
6
6
  device_code: string;
7
7
  interval: number;