@salesforce/core 8.6.1 → 8.6.3
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.
- package/lib/config/ttlConfig.js +5 -0
- package/lib/crypto/crypto.js +1 -1
- package/lib/crypto/keyChain.js +1 -1
- package/lib/crypto/keyChainImpl.js +1 -1
- package/lib/logger/logger.js +1 -0
- package/lib/messages.d.ts +2 -0
- package/lib/messages.js +8 -15
- package/lib/org/authInfo.js +1 -1
- package/lib/org/scratchOrgCache.d.ts +1 -0
- package/lib/org/scratchOrgCache.js +2 -0
- package/lib/org/scratchOrgCreate.js +14 -6
- package/lib/org/scratchOrgInfoApi.d.ts +2 -2
- package/lib/org/scratchOrgInfoApi.js +47 -15
- package/messages/core.md +1 -1
- package/messages/encryption.md +1 -1
- package/package.json +7 -2
package/lib/config/ttlConfig.js
CHANGED
|
@@ -37,6 +37,11 @@ class TTLConfig extends configFile_1.ConfigFile {
|
|
|
37
37
|
return dateTime - new Date(value.timestamp).getTime() > this.options.ttl.milliseconds;
|
|
38
38
|
}
|
|
39
39
|
async init() {
|
|
40
|
+
// Normally, this is done in super.init() but we don't call it to prevent
|
|
41
|
+
// redundant read() calls.
|
|
42
|
+
if (this.hasEncryption()) {
|
|
43
|
+
await this.initCrypto();
|
|
44
|
+
}
|
|
40
45
|
const contents = await this.read(this.options.throwOnNotFound);
|
|
41
46
|
const date = new Date().getTime();
|
|
42
47
|
// delete all the expired entries
|
package/lib/crypto/crypto.js
CHANGED
|
@@ -123,7 +123,7 @@ const detectCryptoVersion = (pwd) => {
|
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
125
|
;
|
|
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."]]));
|
|
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: %s"], ["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
127
|
const makeSecureBuffer = (password, encoding) => {
|
|
128
128
|
const newSb = new secureBuffer_1.SecureBuffer();
|
|
129
129
|
newSb.consume(Buffer.from(password, encoding));
|
package/lib/crypto/keyChain.js
CHANGED
|
@@ -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."], ["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."]]));
|
|
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: %s"], ["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."], ["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."]]));
|
|
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: %s"], ["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.
|
package/lib/logger/logger.js
CHANGED
|
@@ -145,6 +145,7 @@ class Logger {
|
|
|
145
145
|
transport: {
|
|
146
146
|
pipeline: [
|
|
147
147
|
{
|
|
148
|
+
// WARNING: Please make sure to bundle transformStream by referencing the correct path. Reach out to IDEx Foundations Team.
|
|
148
149
|
target: path.join('..', '..', 'lib', 'logger', 'transformStream'),
|
|
149
150
|
},
|
|
150
151
|
getWriteStream(level),
|
package/lib/messages.d.ts
CHANGED
|
@@ -204,6 +204,7 @@ export declare class Messages<T extends string> {
|
|
|
204
204
|
* @param tokens The values to substitute in the message.
|
|
205
205
|
*
|
|
206
206
|
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
|
|
207
|
+
* **Note** Unlike util.format(), specifiers are required for a token to be rendered.
|
|
207
208
|
*/
|
|
208
209
|
getMessage(key: T, tokens?: Tokens): string;
|
|
209
210
|
/**
|
|
@@ -227,6 +228,7 @@ export declare class Messages<T extends string> {
|
|
|
227
228
|
* @param tokens The values to substitute in the message.
|
|
228
229
|
*
|
|
229
230
|
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
|
|
231
|
+
* **Note** Unlike util.format(), specifiers are required for a token to be rendered.
|
|
230
232
|
*/
|
|
231
233
|
getMessages(key: T, tokens?: Tokens): string[];
|
|
232
234
|
/**
|
package/lib/messages.js
CHANGED
|
@@ -37,7 +37,7 @@ const util = __importStar(require("node:util"));
|
|
|
37
37
|
const node_url_1 = require("node:url");
|
|
38
38
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
39
39
|
const kit_1 = require("@salesforce/kit");
|
|
40
|
-
const
|
|
40
|
+
const logger_1 = require("./logger/logger");
|
|
41
41
|
const sfError_1 = require("./sfError");
|
|
42
42
|
const getKey = (packageName, bundleName) => `${packageName}:${bundleName}`;
|
|
43
43
|
const REGEXP_NO_CONTENT = /^\s*$/g;
|
|
@@ -394,6 +394,7 @@ class Messages {
|
|
|
394
394
|
* @param tokens The values to substitute in the message.
|
|
395
395
|
*
|
|
396
396
|
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
|
|
397
|
+
* **Note** Unlike util.format(), specifiers are required for a token to be rendered.
|
|
397
398
|
*/
|
|
398
399
|
getMessage(key, tokens = []) {
|
|
399
400
|
return this.getMessageWithMap(key, tokens, this.messages).join(os.EOL);
|
|
@@ -419,6 +420,7 @@ class Messages {
|
|
|
419
420
|
* @param tokens The values to substitute in the message.
|
|
420
421
|
*
|
|
421
422
|
* **See** https://nodejs.org/api/util.html#util_util_format_format_args
|
|
423
|
+
* **Note** Unlike util.format(), specifiers are required for a token to be rendered.
|
|
422
424
|
*/
|
|
423
425
|
getMessages(key, tokens = []) {
|
|
424
426
|
return this.getMessageWithMap(key, tokens, this.messages);
|
|
@@ -528,21 +530,12 @@ class Messages {
|
|
|
528
530
|
// https://nodejs.org/api/util.html#utilformatformat-args
|
|
529
531
|
// https://regex101.com/r/8Hf8Z6/1
|
|
530
532
|
const specifierRegex = new RegExp('%[sdifjoO]{1}', 'gm');
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
void lifecycleEvents_1.Lifecycle.getInstance().emitTelemetry({
|
|
536
|
-
eventName: 'missing_message_specifier',
|
|
537
|
-
library: 'sfdx-core',
|
|
538
|
-
function: 'getMessageWithMap',
|
|
539
|
-
messagesLength: messages.length,
|
|
540
|
-
message: msgStr,
|
|
541
|
-
tokensLength: tokens.length,
|
|
542
|
-
});
|
|
533
|
+
const specifierFound = specifierRegex.test(msgStr);
|
|
534
|
+
if (!specifierFound && tokens.length > 0) {
|
|
535
|
+
const logger = logger_1.Logger.childFromRoot('core:messages');
|
|
536
|
+
logger.warn(`Unable to render tokens in message. Ensure a specifier (e.g. %s) exists in the message:\n${msgStr}`);
|
|
543
537
|
}
|
|
544
|
-
|
|
545
|
-
return util.format(msgStr, ...tokens);
|
|
538
|
+
return specifierFound ? util.format(msgStr, ...tokens) : msgStr;
|
|
546
539
|
});
|
|
547
540
|
}
|
|
548
541
|
}
|
package/lib/org/authInfo.js
CHANGED
|
@@ -880,7 +880,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
880
880
|
// Exchange the auth code for an access token and refresh token.
|
|
881
881
|
let authFields;
|
|
882
882
|
try {
|
|
883
|
-
this.logger.
|
|
883
|
+
this.logger.debug(`Exchanging auth code for access token using loginUrl: ${options.loginUrl}`);
|
|
884
884
|
authFields = await oauth2.requestToken((0, ts_types_1.ensure)(options.authCode));
|
|
885
885
|
}
|
|
886
886
|
catch (err) {
|
|
@@ -14,6 +14,7 @@ export type CachedOptions = {
|
|
|
14
14
|
tracksSource?: boolean;
|
|
15
15
|
};
|
|
16
16
|
export declare class ScratchOrgCache extends TTLConfig<TTLConfig.Options, CachedOptions> {
|
|
17
|
+
protected static readonly encryptedKeys: string[];
|
|
17
18
|
static getFileName(): string;
|
|
18
19
|
static getDefaultOptions(): TTLConfig.Options;
|
|
19
20
|
static unset(key: string): Promise<void>;
|
|
@@ -11,6 +11,7 @@ const kit_1 = require("@salesforce/kit");
|
|
|
11
11
|
const global_1 = require("../global");
|
|
12
12
|
const ttlConfig_1 = require("../config/ttlConfig");
|
|
13
13
|
class ScratchOrgCache extends ttlConfig_1.TTLConfig {
|
|
14
|
+
static encryptedKeys = ['clientSecret'];
|
|
14
15
|
static getFileName() {
|
|
15
16
|
return 'scratch-create-cache.json';
|
|
16
17
|
}
|
|
@@ -20,6 +21,7 @@ class ScratchOrgCache extends ttlConfig_1.TTLConfig {
|
|
|
20
21
|
isState: true,
|
|
21
22
|
filename: ScratchOrgCache.getFileName(),
|
|
22
23
|
stateFolder: global_1.Global.SF_STATE_FOLDER,
|
|
24
|
+
encryptedKeys: ScratchOrgCache.encryptedKeys,
|
|
23
25
|
ttl: kit_1.Duration.days(1),
|
|
24
26
|
};
|
|
25
27
|
}
|
|
@@ -56,11 +56,15 @@ const scratchOrgResume = async (jobId) => {
|
|
|
56
56
|
(0, scratchOrgLifecycleEvents_1.emit)({ stage: 'send request' }),
|
|
57
57
|
]);
|
|
58
58
|
logger.debug(`resuming scratch org creation for jobId: ${jobId}`);
|
|
59
|
-
const cached = cache.get(jobId);
|
|
59
|
+
const cached = cache.get(jobId, true);
|
|
60
60
|
if (!cached) {
|
|
61
61
|
throw messages.createError('CacheMissError', [jobId]);
|
|
62
62
|
}
|
|
63
63
|
const { hubUsername, apiVersion, clientSecret, signupTargetLoginUrlConfig, definitionjson, alias, setDefault, tracksSource, } = cached;
|
|
64
|
+
const signupTargetLoginUrl = signupTargetLoginUrlConfig ?? (await getSignupTargetLoginUrl());
|
|
65
|
+
if (signupTargetLoginUrl) {
|
|
66
|
+
logger.debug(`resuming org create with LoginUrl override= ${signupTargetLoginUrl}`);
|
|
67
|
+
}
|
|
64
68
|
const hubOrg = await org_1.Org.create({ aliasOrUsername: hubUsername });
|
|
65
69
|
const soi = await (0, scratchOrgInfoApi_1.queryScratchOrgInfo)(hubOrg, jobId);
|
|
66
70
|
await (0, scratchOrgErrorCodes_1.validateScratchOrgInfoForResume)({ jobId, scratchOrgInfo: soi, cache, hubUsername });
|
|
@@ -75,7 +79,7 @@ const scratchOrgResume = async (jobId) => {
|
|
|
75
79
|
scratchOrgInfoComplete: soi,
|
|
76
80
|
hubOrg,
|
|
77
81
|
clientSecret,
|
|
78
|
-
|
|
82
|
+
signupTargetLoginUrl,
|
|
79
83
|
retry: 0,
|
|
80
84
|
});
|
|
81
85
|
await setExitCodeIfError(68)(scratchOrgAuthInfo.handleAliasAndDefaultSettings({
|
|
@@ -114,7 +118,7 @@ const scratchOrgCreate = async (options) => {
|
|
|
114
118
|
const logger = await logger_1.Logger.child('scratchOrgCreate');
|
|
115
119
|
/** epoch milliseconds */
|
|
116
120
|
const startTimestamp = Date.now();
|
|
117
|
-
logger.debug('
|
|
121
|
+
logger.debug('preparing scratch org signup request...');
|
|
118
122
|
await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'prepare request' });
|
|
119
123
|
const { hubOrg, connectedAppConsumerKey, durationDays = 1, nonamespace, noancestors, wait = kit_1.Duration.minutes(exports.DEFAULT_STREAM_TIMEOUT_MINUTES), retry = 0, apiversion, definitionjson, definitionfile, orgConfig, clientSecret = undefined, alias, setDefault = false, tracksSource = true, } = options;
|
|
120
124
|
validateDuration(durationDays);
|
|
@@ -141,7 +145,7 @@ const scratchOrgCreate = async (options) => {
|
|
|
141
145
|
});
|
|
142
146
|
const settings = await settingsGenerator.extract(scratchOrgInfo);
|
|
143
147
|
logger.debug(`the scratch org def file has settings: ${settingsGenerator.hasSettings()}`);
|
|
144
|
-
const [scratchOrgInfoRequestResult,
|
|
148
|
+
const [scratchOrgInfoRequestResult, signupTargetLoginUrl] = await Promise.all([
|
|
145
149
|
// creates the scratch org info in the devhub
|
|
146
150
|
(0, scratchOrgInfoApi_1.requestScratchOrgCreation)(hubOrg, scratchOrgInfo, settingsGenerator),
|
|
147
151
|
getSignupTargetLoginUrl(),
|
|
@@ -174,7 +178,7 @@ const scratchOrgCreate = async (options) => {
|
|
|
174
178
|
scratchOrgInfoComplete: soi,
|
|
175
179
|
hubOrg,
|
|
176
180
|
clientSecret,
|
|
177
|
-
|
|
181
|
+
signupTargetLoginUrl,
|
|
178
182
|
retry: retry || 0,
|
|
179
183
|
});
|
|
180
184
|
// anything after this point (org is created and auth'd) is potentially recoverable with the resume scratch command.
|
|
@@ -216,7 +220,11 @@ const getSignupTargetLoginUrl = async () => {
|
|
|
216
220
|
try {
|
|
217
221
|
const project = await sfProject_1.SfProject.resolve();
|
|
218
222
|
const projectJson = await project.resolveProjectConfig();
|
|
219
|
-
|
|
223
|
+
const signupTargetLoginUrl = projectJson.signupTargetLoginUrl;
|
|
224
|
+
if (signupTargetLoginUrl) {
|
|
225
|
+
logger_1.Logger.childFromRoot('getSignupTargetLoginUrl').debug(`Found signupTargetLoginUrl in project file: ${signupTargetLoginUrl}`);
|
|
226
|
+
return signupTargetLoginUrl;
|
|
227
|
+
}
|
|
220
228
|
}
|
|
221
229
|
catch {
|
|
222
230
|
// a project isn't required for org:create
|
|
@@ -21,7 +21,7 @@ export declare const queryScratchOrgInfo: (hubOrg: Org, id: string) => Promise<S
|
|
|
21
21
|
* scratchOrgInfoComplete - The completed ScratchOrgInfo which should contain an access token.
|
|
22
22
|
* hubOrg - the environment hub org
|
|
23
23
|
* clientSecret - The OAuth client secret. May be null for JWT OAuth flow.
|
|
24
|
-
*
|
|
24
|
+
* signupTargetLoginUrl - Login url override
|
|
25
25
|
* retry - auth retry attempts
|
|
26
26
|
*
|
|
27
27
|
* @returns {Promise<AuthInfo>}
|
|
@@ -30,7 +30,7 @@ export declare const authorizeScratchOrg: (options: {
|
|
|
30
30
|
scratchOrgInfoComplete: ScratchOrgInfo;
|
|
31
31
|
hubOrg: Org;
|
|
32
32
|
clientSecret?: string;
|
|
33
|
-
|
|
33
|
+
signupTargetLoginUrl?: string;
|
|
34
34
|
retry?: number;
|
|
35
35
|
}) => Promise<AuthInfo>;
|
|
36
36
|
/**
|
|
@@ -10,6 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.updateRevisionCounterToZero = exports.resolveUrl = exports.deploySettings = exports.pollForScratchOrgInfo = exports.requestScratchOrgCreation = exports.authorizeScratchOrg = exports.queryScratchOrgInfo = void 0;
|
|
13
|
+
const node_util_1 = require("node:util");
|
|
13
14
|
const kit_1 = require("@salesforce/kit");
|
|
14
15
|
const ts_retry_promise_1 = require("ts-retry-promise");
|
|
15
16
|
const logger_1 = require("../logger/logger");
|
|
@@ -32,10 +33,10 @@ const errorCodes = new messages_1.Messages('@salesforce/core', 'scratchOrgErrorC
|
|
|
32
33
|
*
|
|
33
34
|
* @param scratchOrgInfoComplete The completed ScratchOrgInfo
|
|
34
35
|
* @param hubOrgLoginUrl the hun org login url
|
|
35
|
-
* @param
|
|
36
|
+
* @param signupTargetLoginUrl the login url
|
|
36
37
|
* @returns {string}
|
|
37
38
|
*/
|
|
38
|
-
const getOrgInstanceAuthority = function (scratchOrgInfoComplete, hubOrgLoginUrl,
|
|
39
|
+
const getOrgInstanceAuthority = function (scratchOrgInfoComplete, hubOrgLoginUrl, signupTargetLoginUrl) {
|
|
39
40
|
const createdOrgInstance = scratchOrgInfoComplete.SignupInstance;
|
|
40
41
|
if (createdOrgInstance === 'utf8') {
|
|
41
42
|
return hubOrgLoginUrl;
|
|
@@ -49,7 +50,7 @@ const getOrgInstanceAuthority = function (scratchOrgInfoComplete, hubOrgLoginUrl
|
|
|
49
50
|
// For Falcon sandboxes, try the LoginURL instead; createdOrgInstance will not yield a valid URL
|
|
50
51
|
altUrl = scratchOrgInfoComplete.LoginUrl;
|
|
51
52
|
}
|
|
52
|
-
return
|
|
53
|
+
return signupTargetLoginUrl ?? altUrl;
|
|
53
54
|
};
|
|
54
55
|
/**
|
|
55
56
|
* Returns OAuth2Options object
|
|
@@ -61,9 +62,10 @@ const buildOAuth2Options = async (options) => {
|
|
|
61
62
|
const logger = await logger_1.Logger.child('buildOAuth2Options');
|
|
62
63
|
const isJwtFlow = !!options.hubOrg.getConnection().getAuthInfoFields().privateKey;
|
|
63
64
|
const oauth2Options = {
|
|
64
|
-
loginUrl: getOrgInstanceAuthority(options.scratchOrgInfoComplete, options.hubOrg.getField(org_1.Org.Fields.LOGIN_URL), options.
|
|
65
|
+
loginUrl: getOrgInstanceAuthority(options.scratchOrgInfoComplete, options.hubOrg.getField(org_1.Org.Fields.LOGIN_URL), options.signupTargetLoginUrl),
|
|
65
66
|
};
|
|
66
67
|
logger.debug(`isJwtFlow: ${isJwtFlow}`);
|
|
68
|
+
logger.debug(`using resolved loginUrl: ${oauth2Options.loginUrl}`);
|
|
67
69
|
if (isJwtFlow && !process.env.SFDX_CLIENT_SECRET) {
|
|
68
70
|
oauth2Options.privateKeyFile = options.hubOrg.getConnection().getAuthInfoFields().privateKey;
|
|
69
71
|
const retries = options?.retry ?? kit_1.env.getNumber('SFDX_JWT_AUTH_RETRY_ATTEMPTS') ?? 0;
|
|
@@ -148,13 +150,13 @@ exports.queryScratchOrgInfo = queryScratchOrgInfo;
|
|
|
148
150
|
* scratchOrgInfoComplete - The completed ScratchOrgInfo which should contain an access token.
|
|
149
151
|
* hubOrg - the environment hub org
|
|
150
152
|
* clientSecret - The OAuth client secret. May be null for JWT OAuth flow.
|
|
151
|
-
*
|
|
153
|
+
* signupTargetLoginUrl - Login url override
|
|
152
154
|
* retry - auth retry attempts
|
|
153
155
|
*
|
|
154
156
|
* @returns {Promise<AuthInfo>}
|
|
155
157
|
*/
|
|
156
158
|
const authorizeScratchOrg = async (options) => {
|
|
157
|
-
const { scratchOrgInfoComplete, hubOrg, clientSecret,
|
|
159
|
+
const { scratchOrgInfoComplete, hubOrg, clientSecret, signupTargetLoginUrl, retry } = options;
|
|
158
160
|
await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'authenticate', scratchOrgInfo: scratchOrgInfoComplete });
|
|
159
161
|
const logger = await logger_1.Logger.child('authorizeScratchOrg');
|
|
160
162
|
logger.debug(`scratchOrgInfoComplete: ${JSON.stringify(scratchOrgInfoComplete, null, 4)}`);
|
|
@@ -167,16 +169,46 @@ const authorizeScratchOrg = async (options) => {
|
|
|
167
169
|
clientSecret,
|
|
168
170
|
scratchOrgInfoComplete,
|
|
169
171
|
retry,
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
const authInfo = await getAuthInfo({
|
|
173
|
-
hubOrg,
|
|
174
|
-
username: scratchOrgInfoComplete.SignupUsername,
|
|
175
|
-
oauth2Options: oAuth2Options.options,
|
|
176
|
-
retries: oAuth2Options.retries,
|
|
177
|
-
timeout: oAuth2Options.timeout,
|
|
178
|
-
delay: oAuth2Options.delay,
|
|
172
|
+
signupTargetLoginUrl,
|
|
179
173
|
});
|
|
174
|
+
let authInfo;
|
|
175
|
+
try {
|
|
176
|
+
// This will use the authCode from the scratch org signup to exchange for an auth token via OAuth.
|
|
177
|
+
authInfo = await getAuthInfo({
|
|
178
|
+
hubOrg,
|
|
179
|
+
username: scratchOrgInfoComplete.SignupUsername,
|
|
180
|
+
oauth2Options: oAuth2Options.options,
|
|
181
|
+
retries: oAuth2Options.retries,
|
|
182
|
+
timeout: oAuth2Options.timeout,
|
|
183
|
+
delay: oAuth2Options.delay,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
catch (err1) {
|
|
187
|
+
// If we didn't already try authenticating with the LoginUrl from ScratchOrgInfo object,
|
|
188
|
+
// try the oauth flow again using it now.
|
|
189
|
+
if (scratchOrgInfoComplete.LoginUrl && oAuth2Options.options.loginUrl !== scratchOrgInfoComplete.LoginUrl) {
|
|
190
|
+
logger.debug(`Auth failed with loginUrl ${oAuth2Options.options.loginUrl} so trying with ${scratchOrgInfoComplete.LoginUrl}`);
|
|
191
|
+
oAuth2Options.options = { ...oAuth2Options.options, ...{ loginUrl: scratchOrgInfoComplete.LoginUrl } };
|
|
192
|
+
try {
|
|
193
|
+
authInfo = await getAuthInfo({
|
|
194
|
+
hubOrg,
|
|
195
|
+
username: scratchOrgInfoComplete.SignupUsername,
|
|
196
|
+
oauth2Options: oAuth2Options.options,
|
|
197
|
+
retries: oAuth2Options.retries,
|
|
198
|
+
timeout: oAuth2Options.timeout,
|
|
199
|
+
delay: oAuth2Options.delay,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch (err2) {
|
|
203
|
+
// Log this error but throw the original error
|
|
204
|
+
logger.debug(`Auth failed with ScratchOrgInfo.LoginUrl ${scratchOrgInfoComplete.LoginUrl}\n${(0, node_util_1.inspect)(err2)}`);
|
|
205
|
+
throw err1;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
throw err1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
180
212
|
await authInfo.save({
|
|
181
213
|
devHubUsername: hubOrg.getUsername(),
|
|
182
214
|
created: new Date(scratchOrgInfoComplete.CreatedDate ?? new Date()).valueOf().toString(),
|
package/messages/core.md
CHANGED
|
@@ -36,7 +36,7 @@ Error authenticating with the refresh token due to: %s
|
|
|
36
36
|
|
|
37
37
|
# invalidSfdxAuthUrlError
|
|
38
38
|
|
|
39
|
-
Invalid SFDX authorization URL. Must be in the format "force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>". Note that the "instanceUrl" inside the SFDX authorization URL doesn\'t include the protocol ("https://"). Run "org display --target-org" on an org to see an example of an SFDX authorization URL.
|
|
39
|
+
Invalid SFDX authorization URL. Must be in the format "force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>". Note that the "instanceUrl" inside the SFDX authorization URL doesn\'t include the protocol ("https://"). Run "org display --target-org" on an org to see an example of an SFDX authorization URL.
|
|
40
40
|
|
|
41
41
|
# orgDataNotAvailableError
|
|
42
42
|
|
package/messages/encryption.md
CHANGED
|
@@ -56,7 +56,7 @@ The service and account specified in %s do not match the version of the toolbelt
|
|
|
56
56
|
|
|
57
57
|
# genericKeychainInvalidPermsError
|
|
58
58
|
|
|
59
|
-
Invalid file permissions for secret file
|
|
59
|
+
Invalid file permissions for secret file: %s
|
|
60
60
|
|
|
61
61
|
# genericKeychainInvalidPermsError.actions
|
|
62
62
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "8.6.
|
|
3
|
+
"version": "8.6.3",
|
|
4
4
|
"description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"messageTransformer/messageTransformer.ts"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@jsforce/jsforce-node": "^3.
|
|
56
|
+
"@jsforce/jsforce-node": "^3.6.1",
|
|
57
57
|
"@salesforce/kit": "^3.2.2",
|
|
58
58
|
"@salesforce/schemas": "^1.9.0",
|
|
59
59
|
"@salesforce/ts-types": "^2.0.10",
|
|
@@ -81,6 +81,11 @@
|
|
|
81
81
|
"@types/proper-lockfile": "^4.1.4",
|
|
82
82
|
"@types/semver": "^7.5.8",
|
|
83
83
|
"benchmark": "^2.1.4",
|
|
84
|
+
"esbuild": "^0.23.1",
|
|
85
|
+
"esbuild-plugin-pino": "^2.2.0",
|
|
86
|
+
"esbuild-plugin-tsc": "^0.4.0",
|
|
87
|
+
"npm-dts": "^1.3.13",
|
|
88
|
+
"ts-morph": "^23.0.0",
|
|
84
89
|
"ts-node": "^10.9.2",
|
|
85
90
|
"ts-patch": "^3.2.1",
|
|
86
91
|
"typescript": "^5.5.4"
|