@salesforce/core 6.6.0 → 6.7.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.
@@ -21,6 +21,7 @@ export declare class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
21
21
  * @ignore
22
22
  */
23
23
  constructor(options?: CryptoOptions);
24
+ private static unsetCryptoVersion;
24
25
  /**
25
26
  * Encrypts text. Returns the encrypted string or undefined if no string was passed.
26
27
  *
@@ -45,10 +46,15 @@ export declare class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
45
46
  * Clears the crypto state. This should be called in a finally block.
46
47
  */
47
48
  close(): void;
49
+ isV2Crypto(): boolean;
48
50
  /**
49
51
  * Initialize async components.
50
52
  */
51
53
  protected init(): Promise<void>;
54
+ private encryptV1;
55
+ private encryptV2;
56
+ private decryptV1;
57
+ private decryptV2;
52
58
  private getKeyChain;
53
59
  }
54
60
  export {};
@@ -37,23 +37,96 @@ const node_path_1 = require("node:path");
37
37
  const ts_types_1 = require("@salesforce/ts-types");
38
38
  const kit_1 = require("@salesforce/kit");
39
39
  const logger_1 = require("../logger/logger");
40
+ const lifecycleEvents_1 = require("../lifecycleEvents");
40
41
  const messages_1 = require("../messages");
41
42
  const cache_1 = require("../util/cache");
42
43
  const global_1 = require("../global");
44
+ const sfError_1 = require("../sfError");
43
45
  const keyChain_1 = require("./keyChain");
44
46
  const secureBuffer_1 = require("./secureBuffer");
45
47
  const TAG_DELIMITER = ':';
46
- const BYTE_COUNT_FOR_IV = 6;
48
+ const IV_BYTES = {
49
+ v1: 6,
50
+ v2: 12,
51
+ };
52
+ const ENCODING = {
53
+ v1: 'utf8',
54
+ v2: 'hex',
55
+ };
56
+ const KEY_SIZE = {
57
+ v1: 16,
58
+ v2: 32,
59
+ };
47
60
  const ALGO = 'aes-256-gcm';
48
61
  const AUTH_TAG_LENGTH = 32;
49
62
  const ENCRYPTED_CHARS = /[a-f0-9]/;
50
63
  const KEY_NAME = 'sfdx';
51
64
  const ACCOUNT = 'local';
65
+ let cryptoLogger;
66
+ const getCryptoLogger = () => {
67
+ cryptoLogger ??= logger_1.Logger.childFromRoot('crypto');
68
+ return cryptoLogger;
69
+ };
70
+ const getCryptoV2EnvVar = () => {
71
+ let sfCryptoV2 = process.env.SF_CRYPTO_V2?.toLowerCase();
72
+ if (sfCryptoV2 !== undefined) {
73
+ getCryptoLogger().debug(`SF_CRYPTO_V2=${sfCryptoV2}`);
74
+ // normalize all values that aren't "true" to be "false"
75
+ if (sfCryptoV2 !== 'true') {
76
+ sfCryptoV2 = 'false';
77
+ }
78
+ }
79
+ return sfCryptoV2;
80
+ };
81
+ let cryptoVersion;
82
+ const getCryptoVersion = () => {
83
+ if (!cryptoVersion) {
84
+ // This only happens when generating a new key, so use the env var
85
+ // and (for now) default to 'v1'.
86
+ cryptoVersion = getCryptoV2EnvVar() === 'true' ? 'v2' : 'v1';
87
+ }
88
+ return cryptoVersion;
89
+ };
90
+ // Detect the crypto version based on the password (key) length.
91
+ // This happens once per process.
92
+ const detectCryptoVersion = (pwd) => {
93
+ if (!cryptoVersion) {
94
+ // check the env var to see if it's set
95
+ const sfCryptoV2 = getCryptoV2EnvVar();
96
+ // Password length of 64 is v2 crypto and uses hex encoding.
97
+ // Password length of 32 is v1 crypto and uses utf8 encoding.
98
+ if (pwd?.length === KEY_SIZE.v2 * 2) {
99
+ cryptoVersion = 'v2';
100
+ getCryptoLogger().debug('Using v2 crypto');
101
+ if (sfCryptoV2 === 'false') {
102
+ getCryptoLogger().warn(messages.getMessage('v1CryptoWithV2KeyWarning'));
103
+ }
104
+ }
105
+ else if (pwd?.length === KEY_SIZE.v1 * 2) {
106
+ cryptoVersion = 'v1';
107
+ getCryptoLogger().debug('Using v1 crypto');
108
+ if (sfCryptoV2 === 'true') {
109
+ getCryptoLogger().warn(messages.getMessage('v2CryptoWithV1KeyWarning'));
110
+ }
111
+ }
112
+ else {
113
+ getCryptoLogger().debug("crypto key doesn't match v1 or v2. using SF_CRYPTO_V2.");
114
+ getCryptoVersion();
115
+ }
116
+ void lifecycleEvents_1.Lifecycle.getInstance().emitTelemetry({
117
+ eventName: 'crypto_version',
118
+ library: 'sfdx-core',
119
+ function: 'detectCryptoVersion',
120
+ cryptoVersion, // 'v1' or 'v2'
121
+ cryptoEnvVar: sfCryptoV2, // 'true' or 'false' or 'undefined'
122
+ });
123
+ }
124
+ };
52
125
  ;
53
- 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."]]));
54
- const makeSecureBuffer = (password) => {
126
+ 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."], ["v1CryptoWithV2KeyWarning", "The SF_CRYPTO_V2 environment variable was set to \"false\" but a v2 crypto key was detected. v1 crypto can only be used with a v1 key. Unset the SF_CRYPTO_V2 environment variable."], ["v2CryptoWithV1KeyWarning", "SF_CRYPTO_V2 was set to \"true\" but a v1 crypto key was detected. v2 crypto can only be used with a v2 key. To generate a v2 key:\n\n1. Logout of all orgs: `sf org logout --all`\n2. Delete the sfdx keychain entry (account: local, service: sfdx). If `SF_USE_GENERIC_UNIX_KEYCHAIN=true` env var is set, you can delete the `key.json` file.\n3. Set `SF_CRYPTO_V2=true` env var.\n4. Re-Authenticate with your orgs using the CLI org login commands."]]));
127
+ const makeSecureBuffer = (password, encoding) => {
55
128
  const newSb = new secureBuffer_1.SecureBuffer();
56
- newSb.consume(Buffer.from((0, ts_types_1.ensure)(password), 'utf8'));
129
+ newSb.consume(Buffer.from(password, encoding));
57
130
  return newSb;
58
131
  };
59
132
  /**
@@ -74,14 +147,19 @@ const keychainPromises = {
74
147
  return new Promise((resolve, reject) => _keychain.getPassword({ service, account }, (err, password) => {
75
148
  if (err)
76
149
  return reject(err);
77
- cache_1.Cache.set(cacheKey, makeSecureBuffer(password));
78
- return resolve({ username: account, password: (0, ts_types_1.ensure)(password) });
150
+ const pwd = (0, ts_types_1.ensure)(password, 'Expected the keychain password to be set');
151
+ detectCryptoVersion(pwd);
152
+ cache_1.Cache.set(cacheKey, makeSecureBuffer(pwd, ENCODING[getCryptoVersion()]));
153
+ return resolve({ username: account, password: pwd });
79
154
  }));
80
155
  }
81
156
  else {
82
- const pw = sb.value((buffer) => buffer.toString('utf8'));
83
- cache_1.Cache.set(cacheKey, makeSecureBuffer(pw));
84
- return new Promise((resolve) => resolve({ username: account, password: (0, ts_types_1.ensure)(pw) }));
157
+ // If the password is cached, we know the crypto version and encoding because it was
158
+ // detected by the non-cache code path just above this.
159
+ const encoding = ENCODING[getCryptoVersion()];
160
+ const pwd = (0, ts_types_1.ensure)(sb.value((buffer) => buffer.toString(encoding)), 'Expected the keychain password to be set');
161
+ cache_1.Cache.set(cacheKey, makeSecureBuffer(pwd, encoding));
162
+ return new Promise((resolve) => resolve({ username: account, password: pwd }));
85
163
  }
86
164
  },
87
165
  /**
@@ -116,6 +194,11 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
116
194
  this.key = new secureBuffer_1.SecureBuffer();
117
195
  this.options = options ?? {};
118
196
  }
197
+ // @ts-expect-error only for test access
198
+ // eslint-disable-next-line class-methods-use-this
199
+ static unsetCryptoVersion() {
200
+ cryptoVersion = undefined;
201
+ }
119
202
  encrypt(text) {
120
203
  if (text == null) {
121
204
  return;
@@ -123,14 +206,13 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
123
206
  if (this.key == null) {
124
207
  throw messages.createError('keychainPasswordCreationError');
125
208
  }
126
- const iv = crypto.randomBytes(BYTE_COUNT_FOR_IV).toString('hex');
127
- return this.key.value((buffer) => {
128
- const cipher = crypto.createCipheriv(ALGO, buffer.toString('utf8'), iv);
129
- let encrypted = cipher.update(text, 'utf8', 'hex');
130
- encrypted += cipher.final('hex');
131
- const tag = cipher.getAuthTag().toString('hex');
132
- return `${iv}${encrypted}${TAG_DELIMITER}${tag}`;
133
- });
209
+ // When everything is v2, we can remove the else
210
+ if (this.isV2Crypto()) {
211
+ return this.encryptV2(text);
212
+ }
213
+ else {
214
+ return this.encryptV1(text);
215
+ }
134
216
  }
135
217
  decrypt(text) {
136
218
  if (text == null) {
@@ -140,27 +222,13 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
140
222
  if (tokens.length !== 2) {
141
223
  throw messages.createError('invalidEncryptedFormatError');
142
224
  }
143
- const tag = tokens[1];
144
- const iv = tokens[0].substring(0, BYTE_COUNT_FOR_IV * 2);
145
- const secret = tokens[0].substring(BYTE_COUNT_FOR_IV * 2, tokens[0].length);
146
- return this.key.value((buffer) => {
147
- const decipher = crypto.createDecipheriv(ALGO, buffer.toString('utf8'), iv);
148
- let dec;
149
- try {
150
- decipher.setAuthTag(Buffer.from(tag, 'hex'));
151
- dec = decipher.update(secret, 'hex', 'utf8');
152
- dec += decipher.final('utf8');
153
- }
154
- catch (err) {
155
- const error = messages.createError('authDecryptError', [err.message], [], err);
156
- const useGenericUnixKeychain = kit_1.env.getBoolean('SF_USE_GENERIC_UNIX_KEYCHAIN') || kit_1.env.getBoolean('USE_GENERIC_UNIX_KEYCHAIN');
157
- if (os.platform() === 'darwin' && !useGenericUnixKeychain) {
158
- error.actions = [messages.getMessage('macKeychainOutOfSync')];
159
- }
160
- throw error;
161
- }
162
- return dec;
163
- });
225
+ // When everything is v2, we can remove the else
226
+ if (this.isV2Crypto()) {
227
+ return this.decryptV2(tokens);
228
+ }
229
+ else {
230
+ return this.decryptV1(tokens);
231
+ }
164
232
  }
165
233
  /**
166
234
  * Takes a best guess if the value provided was encrypted by {@link Crypto.encrypt} by
@@ -181,7 +249,7 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
181
249
  const tag = tokens[1];
182
250
  const value = tokens[0];
183
251
  return (tag.length === AUTH_TAG_LENGTH &&
184
- value.length >= BYTE_COUNT_FOR_IV &&
252
+ value.length >= IV_BYTES[getCryptoVersion()] &&
185
253
  ENCRYPTED_CHARS.test(tag) &&
186
254
  ENCRYPTED_CHARS.test(tokens[0]));
187
255
  }
@@ -193,33 +261,39 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
193
261
  this.key.clear();
194
262
  }
195
263
  }
264
+ // eslint-disable-next-line class-methods-use-this
265
+ isV2Crypto() {
266
+ return getCryptoVersion() === 'v2';
267
+ }
196
268
  /**
197
269
  * Initialize async components.
198
270
  */
199
271
  async init() {
200
- const logger = await logger_1.Logger.child('crypto');
201
272
  if (!this.options.platform) {
202
273
  this.options.platform = os.platform();
203
274
  }
204
- logger.debug(`retryStatus: ${this.options.retryStatus}`);
205
275
  this.noResetOnClose = !!this.options.noResetOnClose;
206
276
  try {
207
- this.key.consume(Buffer.from((await keychainPromises.getPassword(await this.getKeyChain(this.options.platform), KEY_NAME, ACCOUNT))
208
- .password, 'utf8'));
277
+ const keyChain = await this.getKeyChain(this.options.platform);
278
+ const pwd = (await keychainPromises.getPassword(keyChain, KEY_NAME, ACCOUNT)).password;
279
+ // The above line ensures the crypto version is detected and set so we can rely on it now.
280
+ this.key.consume(Buffer.from(pwd, ENCODING[getCryptoVersion()]));
209
281
  }
210
282
  catch (err) {
211
283
  // No password found
212
284
  if (err.name === 'PasswordNotFoundError') {
213
285
  // If we already tried to create a new key then bail.
214
286
  if (this.options.retryStatus === 'KEY_SET') {
215
- logger.debug('a key was set but the retry to get the password failed.');
287
+ getCryptoLogger().debug('a key was set but the retry to get the password failed.');
216
288
  throw err;
217
289
  }
218
290
  else {
219
- logger.debug('password not found in keychain attempting to created one and re-init.');
291
+ getCryptoLogger().debug(`password not found in keychain. Creating new one (Crypto ${getCryptoVersion()}) and re-init.`);
220
292
  }
221
- const key = crypto.randomBytes(Math.ceil(16)).toString('hex');
222
- // Create a new password in the KeyChain.
293
+ // 2/6/2024: This generates a new key using the crypto version based on the SF_CRYPTO_V2 env var.
294
+ // Sometime in the future we could hardcode this to be `KEY_SIZE.v2` so that it becomes the default.
295
+ const key = crypto.randomBytes(KEY_SIZE[getCryptoVersion()]).toString('hex');
296
+ // Set the new password in the KeyChain.
223
297
  await keychainPromises.setPassword((0, ts_types_1.ensure)(this.options.keychain), KEY_NAME, ACCOUNT, key);
224
298
  return this.init();
225
299
  }
@@ -228,6 +302,68 @@ class Crypto extends kit_1.AsyncOptionalCreatable {
228
302
  }
229
303
  }
230
304
  }
305
+ encryptV1(text) {
306
+ const iv = crypto.randomBytes(IV_BYTES.v1).toString('hex');
307
+ return this.key.value((buffer) => {
308
+ const cipher = crypto.createCipheriv(ALGO, buffer.toString('utf8'), iv);
309
+ let encrypted = cipher.update(text, 'utf8', 'hex');
310
+ encrypted += cipher.final('hex');
311
+ const tag = cipher.getAuthTag().toString('hex');
312
+ return `${iv}${encrypted}${TAG_DELIMITER}${tag}`;
313
+ });
314
+ }
315
+ encryptV2(text) {
316
+ const iv = crypto.randomBytes(IV_BYTES.v2);
317
+ return this.key.value((buffer) => {
318
+ const cipher = crypto.createCipheriv(ALGO, buffer, iv);
319
+ const ivHex = iv.toString('hex');
320
+ let encrypted = cipher.update(text, 'utf8', 'hex');
321
+ encrypted += cipher.final('hex');
322
+ const tag = cipher.getAuthTag().toString('hex');
323
+ return `${ivHex}${encrypted}${TAG_DELIMITER}${tag}`;
324
+ });
325
+ }
326
+ decryptV1(tokens) {
327
+ const tag = tokens[1];
328
+ const iv = tokens[0].substring(0, IV_BYTES.v1 * 2);
329
+ const secret = tokens[0].substring(IV_BYTES.v1 * 2, tokens[0].length);
330
+ return this.key.value((buffer) => {
331
+ const decipher = crypto.createDecipheriv(ALGO, buffer.toString('utf8'), iv);
332
+ try {
333
+ decipher.setAuthTag(Buffer.from(tag, 'hex'));
334
+ return `${decipher.update(secret, 'hex', 'utf8')}${decipher.final('utf8')}`;
335
+ }
336
+ catch (err) {
337
+ const error = messages.createError('authDecryptError', [err.message], [], err);
338
+ const useGenericUnixKeychain = kit_1.env.getBoolean('SF_USE_GENERIC_UNIX_KEYCHAIN') || kit_1.env.getBoolean('USE_GENERIC_UNIX_KEYCHAIN');
339
+ if (os.platform() === 'darwin' && !useGenericUnixKeychain) {
340
+ error.actions = [messages.getMessage('macKeychainOutOfSync')];
341
+ }
342
+ throw error;
343
+ }
344
+ });
345
+ }
346
+ decryptV2(tokens) {
347
+ const tag = tokens[1];
348
+ const iv = tokens[0].substring(0, IV_BYTES.v2 * 2);
349
+ const secret = tokens[0].substring(IV_BYTES.v2 * 2, tokens[0].length);
350
+ return this.key.value((buffer) => {
351
+ const decipher = crypto.createDecipheriv(ALGO, buffer, Buffer.from(iv, 'hex'));
352
+ try {
353
+ decipher.setAuthTag(Buffer.from(tag, 'hex'));
354
+ return `${decipher.update(secret, 'hex', 'utf8')}${decipher.final('utf8')}`;
355
+ }
356
+ catch (_err) {
357
+ const err = ((0, ts_types_1.isString)(_err) ? sfError_1.SfError.wrap(_err) : _err);
358
+ const error = messages.createError('authDecryptError', [err.message], [], err);
359
+ const useGenericUnixKeychain = kit_1.env.getBoolean('SF_USE_GENERIC_UNIX_KEYCHAIN') || kit_1.env.getBoolean('USE_GENERIC_UNIX_KEYCHAIN');
360
+ if (os.platform() === 'darwin' && !useGenericUnixKeychain) {
361
+ error.actions = [messages.getMessage('macKeychainOutOfSync')];
362
+ }
363
+ throw error;
364
+ }
365
+ });
366
+ }
231
367
  async getKeyChain(platform) {
232
368
  if (!this.options.keychain) {
233
369
  this.options.keychain = await (0, keyChain_1.retrieveKeychain)(platform);
@@ -12,7 +12,7 @@ const logger_1 = require("../logger/logger");
12
12
  const messages_1 = require("../messages");
13
13
  const keyChainImpl_1 = require("./keyChainImpl");
14
14
  ;
15
- 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."]]));
15
+ 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."], ["v1CryptoWithV2KeyWarning", "The SF_CRYPTO_V2 environment variable was set to \"false\" but a v2 crypto key was detected. v1 crypto can only be used with a v1 key. Unset the SF_CRYPTO_V2 environment variable."], ["v2CryptoWithV1KeyWarning", "SF_CRYPTO_V2 was set to \"true\" but a v1 crypto key was detected. v2 crypto can only be used with a v2 key. To generate a v2 key:\n\n1. Logout of all orgs: `sf org logout --all`\n2. Delete the sfdx keychain entry (account: local, service: sfdx). If `SF_USE_GENERIC_UNIX_KEYCHAIN=true` env var is set, you can delete the `key.json` file.\n3. Set `SF_CRYPTO_V2=true` env var.\n4. Re-Authenticate with your orgs using the CLI org login commands."]]));
16
16
  /**
17
17
  * Gets the os level keychain impl.
18
18
  *
@@ -41,7 +41,7 @@ const kit_1 = require("@salesforce/kit");
41
41
  const global_1 = require("../global");
42
42
  const messages_1 = require("../messages");
43
43
  ;
44
- 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."]]));
44
+ 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."], ["v1CryptoWithV2KeyWarning", "The SF_CRYPTO_V2 environment variable was set to \"false\" but a v2 crypto key was detected. v1 crypto can only be used with a v1 key. Unset the SF_CRYPTO_V2 environment variable."], ["v2CryptoWithV1KeyWarning", "SF_CRYPTO_V2 was set to \"true\" but a v1 crypto key was detected. v2 crypto can only be used with a v2 key. To generate a v2 key:\n\n1. Logout of all orgs: `sf org logout --all`\n2. Delete the sfdx keychain entry (account: local, service: sfdx). If `SF_USE_GENERIC_UNIX_KEYCHAIN=true` env var is set, you can delete the `key.json` file.\n3. Set `SF_CRYPTO_V2=true` env var.\n4. Re-Authenticate with your orgs using the CLI org login commands."]]));
45
45
  const GET_PASSWORD_RETRY_COUNT = 3;
46
46
  /**
47
47
  * Helper to reduce an array of cli args down to a presentable string for logging.
@@ -83,3 +83,16 @@ Command failed with response:
83
83
  # macKeychainOutOfSync
84
84
 
85
85
  We’ve 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.
86
+
87
+ # v1CryptoWithV2KeyWarning
88
+
89
+ The SF_CRYPTO_V2 environment variable was set to "false" but a v2 crypto key was detected. v1 crypto can only be used with a v1 key. Unset the SF_CRYPTO_V2 environment variable.
90
+
91
+ # v2CryptoWithV1KeyWarning
92
+
93
+ SF_CRYPTO_V2 was set to "true" but a v1 crypto key was detected. v2 crypto can only be used with a v2 key. To generate a v2 key:
94
+
95
+ 1. Logout of all orgs: `sf org logout --all`
96
+ 2. Delete the sfdx keychain entry (account: local, service: sfdx). If `SF_USE_GENERIC_UNIX_KEYCHAIN=true` env var is set, you can delete the `key.json` file.
97
+ 3. Set `SF_CRYPTO_V2=true` env var.
98
+ 4. Re-Authenticate with your orgs using the CLI org login commands.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "6.6.0",
3
+ "version": "6.7.0",
4
4
  "description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
5
5
  "main": "lib/exported",
6
6
  "types": "lib/exported.d.ts",