@salesforce/core 4.0.0 → 4.0.1
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/LICENSE.txt +1 -1
- package/README.md +93 -44
- package/lib/config/aliasesConfig.d.ts +12 -0
- package/lib/config/aliasesConfig.js +28 -0
- package/lib/config/authInfoConfig.d.ts +19 -0
- package/lib/config/authInfoConfig.js +35 -0
- package/lib/config/config.d.ts +87 -22
- package/lib/config/config.js +117 -65
- package/lib/config/configAggregator.d.ts +41 -35
- package/lib/config/configAggregator.js +102 -73
- package/lib/config/configFile.d.ts +2 -2
- package/lib/config/configFile.js +38 -29
- package/lib/config/configGroup.d.ts +141 -0
- package/lib/config/configGroup.js +225 -0
- package/lib/config/configStore.d.ts +9 -9
- package/lib/config/configStore.js +17 -15
- package/lib/config/envVars.d.ts +15 -9
- package/lib/config/envVars.js +71 -47
- package/lib/config/orgUsersConfig.js +2 -0
- package/lib/config/sandboxOrgConfig.js +2 -0
- package/lib/config/sandboxProcessCache.d.ts +16 -0
- package/lib/config/sandboxProcessCache.js +38 -0
- package/lib/config/tokensConfig.d.ts +10 -0
- package/lib/config/tokensConfig.js +29 -0
- package/lib/config/ttlConfig.d.ts +34 -0
- package/lib/config/ttlConfig.js +50 -0
- package/lib/crypto/crypto.js +15 -22
- package/lib/crypto/keyChain.js +2 -3
- package/lib/crypto/keyChainImpl.d.ts +5 -3
- package/lib/crypto/keyChainImpl.js +58 -61
- package/lib/crypto/secureBuffer.d.ts +1 -1
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +27 -25
- package/lib/exported.d.ts +15 -12
- package/lib/exported.js +28 -16
- package/lib/global.d.ts +11 -3
- package/lib/global.js +39 -12
- package/lib/lifecycleEvents.d.ts +1 -1
- package/lib/lifecycleEvents.js +3 -0
- package/lib/logger.d.ts +19 -9
- package/lib/logger.js +112 -86
- package/lib/messages.d.ts +53 -36
- package/lib/messages.js +81 -91
- package/lib/org/authInfo.d.ts +56 -20
- package/lib/org/authInfo.js +232 -131
- package/lib/org/authRemover.d.ts +8 -7
- package/lib/org/authRemover.js +32 -28
- package/lib/org/connection.d.ts +13 -37
- package/lib/org/connection.js +78 -124
- package/lib/org/index.js +5 -1
- package/lib/org/org.d.ts +151 -48
- package/lib/org/org.js +466 -220
- package/lib/org/orgConfigProperties.d.ts +64 -3
- package/lib/org/orgConfigProperties.js +96 -4
- package/lib/org/permissionSetAssignment.js +4 -13
- package/lib/org/scratchOrgCache.d.ts +20 -0
- package/lib/org/scratchOrgCache.js +33 -0
- package/lib/org/scratchOrgCreate.d.ts +28 -17
- package/lib/org/scratchOrgCreate.js +125 -53
- package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
- package/lib/org/scratchOrgErrorCodes.js +34 -17
- package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
- package/lib/org/scratchOrgInfoApi.d.ts +21 -47
- package/lib/org/scratchOrgInfoApi.js +129 -63
- package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
- package/lib/org/scratchOrgInfoGenerator.js +76 -62
- package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
- package/lib/org/scratchOrgLifecycleEvents.js +41 -0
- package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
- package/lib/org/scratchOrgSettingsGenerator.js +165 -98
- package/lib/org/scratchOrgTypes.d.ts +43 -0
- package/lib/org/scratchOrgTypes.js +9 -0
- package/lib/org/user.d.ts +1 -1
- package/lib/org/user.js +25 -34
- package/lib/schema/printer.d.ts +6 -0
- package/lib/schema/printer.js +34 -31
- package/lib/schema/validator.d.ts +12 -10
- package/lib/schema/validator.js +56 -76
- package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
- package/lib/{sfdxError.js → sfError.js} +40 -30
- package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
- package/lib/sfProject.js +651 -0
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.d.ts +27 -12
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.js +47 -31
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
- package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
- package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
- package/lib/stateAggregator/index.d.ts +4 -0
- package/lib/stateAggregator/index.js +27 -0
- package/lib/stateAggregator/stateAggregator.d.ts +25 -0
- package/lib/stateAggregator/stateAggregator.js +46 -0
- package/lib/status/myDomainResolver.d.ts +1 -1
- package/lib/status/myDomainResolver.js +4 -4
- package/lib/status/pollingClient.js +4 -4
- package/lib/status/streamingClient.d.ts +2 -2
- package/lib/status/streamingClient.js +58 -63
- package/lib/status/types.d.ts +2 -2
- package/lib/testSetup.d.ts +206 -75
- package/lib/testSetup.js +463 -165
- package/lib/util/cache.d.ts +2 -2
- package/lib/util/cache.js +6 -6
- package/lib/util/checkLightningDomain.js +3 -4
- package/lib/util/directoryWriter.d.ts +12 -0
- package/lib/util/directoryWriter.js +54 -0
- package/lib/util/getJwtAudienceUrl.js +1 -1
- package/lib/util/internal.d.ts +28 -2
- package/lib/util/internal.js +65 -8
- package/lib/util/jsonXmlTools.js +2 -4
- package/lib/util/mapKeys.d.ts +9 -9
- package/lib/util/mapKeys.js +13 -9
- package/lib/util/sfdc.d.ts +51 -51
- package/lib/util/sfdc.js +74 -79
- package/lib/util/sfdcUrl.d.ts +5 -19
- package/lib/util/sfdcUrl.js +40 -49
- package/lib/util/structuredWriter.d.ts +9 -0
- package/lib/util/structuredWriter.js +3 -0
- package/lib/util/zipWriter.d.ts +8 -6
- package/lib/util/zipWriter.js +13 -13
- package/lib/webOAuthServer.d.ts +20 -6
- package/lib/webOAuthServer.js +102 -56
- package/messageTransformer/messageTransformer.ts +93 -0
- package/messages/auth.md +9 -1
- package/messages/config.md +42 -6
- package/messages/connection.md +8 -0
- package/messages/core.md +10 -0
- package/messages/envVars.md +37 -3
- package/messages/org.md +21 -1
- package/messages/scratchOrgCreate.md +2 -6
- package/messages/scratchOrgErrorCodes.md +17 -1
- package/messages/scratchOrgInfoApi.md +9 -0
- package/messages/scratchOrgInfoGenerator.md +9 -1
- package/package.json +121 -46
- package/CHANGELOG.md +0 -1244
- package/lib/config/keychainConfig.d.ts +0 -19
- package/lib/config/keychainConfig.js +0 -43
- package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/orgAccessor.js +0 -45
- package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
- package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
- package/lib/globalInfo/globalInfoConfig.js +0 -105
- package/lib/globalInfo/index.d.ts +0 -6
- package/lib/globalInfo/index.js +0 -29
- package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
- package/lib/globalInfo/sfdxDataHandler.js +0 -217
- package/lib/globalInfo/types.d.ts +0 -39
- package/lib/globalInfo/types.js +0 -10
- package/lib/sfdxProject.js +0 -557
- package/lib/util/fs.d.ts +0 -201
- package/lib/util/fs.js +0 -378
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
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
|
|
47
|
+
* **Throws** *{@link SfError}{ name: 'MissingCredentialProgramError' }* When the OS credential program isn't found.
|
|
62
48
|
*
|
|
63
|
-
* **Throws** *{@link
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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) =>
|
|
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
|
|
192
|
+
const linuxImpl = {
|
|
203
193
|
getProgram() {
|
|
204
|
-
return process.env.SFDX_SECRET_TOOL_PATH
|
|
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(
|
|
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 = `${
|
|
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
|
|
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(
|
|
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 = `${
|
|
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
|
|
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(
|
|
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 = `${
|
|
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
|
|
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 = `${
|
|
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(
|
|
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 = `${
|
|
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
|
|
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
|
|
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
|
-
|
|
333
|
-
await
|
|
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
|
|
336
|
+
async function readFile() {
|
|
341
337
|
// The file and access is validated before this method is called
|
|
342
|
-
const fileContents = await
|
|
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
|
|
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', [
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
474
|
-
linux: new KeychainAccess(
|
|
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
|
|
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
|
|
3
|
-
import {
|
|
4
|
-
import { AuthInfo } from './org
|
|
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;
|
|
@@ -9,17 +9,15 @@
|
|
|
9
9
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.DeviceOauthService = void 0;
|
|
12
|
-
const url_1 = require("url");
|
|
13
12
|
const transport_1 = require("jsforce/lib/transport");
|
|
14
13
|
const kit_1 = require("@salesforce/kit");
|
|
15
14
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
15
|
+
const FormData = require("form-data");
|
|
16
16
|
const logger_1 = require("./logger");
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const connection_1 = require("./org/connection");
|
|
17
|
+
const org_1 = require("./org");
|
|
18
|
+
const sfError_1 = require("./sfError");
|
|
20
19
|
const messages_1 = require("./messages");
|
|
21
|
-
messages_1.Messages.importMessagesDirectory(__dirname);
|
|
22
|
-
const messages = messages_1.Messages.load('@salesforce/core', 'auth', ['pollingTimeout']);
|
|
20
|
+
const messages = new messages_1.Messages('@salesforce/core', 'auth', new Map([["targetOrgNotSet", "A default user is not set."], ["targetOrgNotSet.actions", ["Run the \"sfdx auth\" commands with --setdefaultusername to connect to an org and set it as your default org.", "Run \"force:org:create\" with --setdefaultusername to create a scratch org and set it as your default org.", "Run \"sfdx config:set defaultusername=<username>\" to set your default username."]], ["portInUse", "Cannot start the OAuth redirect server on port %s."], ["portInUse.actions", ["Kill the process running on port %s or use a custom connected app and update OauthLocalPort in the sfdx-project.json file."]], ["invalidRequestMethod", "Invalid request method: %s"], ["invalidRequestUri", "Invalid request uri: %s"], ["pollingTimeout", "The device authorization request timed out. After executing force:auth:device:login, you must approve access to the device within 10 minutes. This can happen if the URL wasn\u2019t copied into the browser, login was not attempted, or the 2FA process was not completed within 10 minutes. Request authorization again."], ["serverErrorHTMLResponse", "<html><head><style>body {background-color:#F4F6F9; font-family: Arial, sans-serif; font-size: 0.8125rem; line-height: 1.5rem; color: #16325c;} #center {margin: auto; width: 370px; padding: 100px 0px 20px;} #logo-container {margin-left: auto; margin-right: auto; text-align: center;} #logo {max-width: 180px; max-height: 113px; margin-bottom: 2rem; border: 0;} #header {font-size: 1.5rem; text-align: center; margin-bottom: 1rem;} #message {background-color: #FFFFFF; margin: 0px auto; padding: 1.25rem; border-radius: 0.25rem; border: 1px solid #D8DDE6;} #footer {height: 24px; width: 370px; text-align: center; font-size: .75rem; position: absolute; bottom: 10;}</style></head><body><div id=\"center\"><div id=\"logo-container\"><img id=\"logo\" aria-hidden=\"true\" name=\"logo\" alt=\"Salesforce\" src=\"data:image/svg+xml;base64,%s\"></div><div id=\"header\">%s</div><div id=\"message\">%s<br/><br/>This is most likely <b>not</b> an error with the Salesforce CLI. Please ensure all information is accurate and try again.</div><div id=\"footer\">© %s Salesforce, Inc. All rights reserved.</div></div></body></html>"], ["missingAuthCode", "No authentication code found on login response."], ["serverSuccessHTMLResponse", "<html><head><style>body {background-color:#F4F6F9; font-family: Arial, sans-serif; font-size: 0.8125rem; line-height: 1.5rem; color: #16325c;} #center {margin: auto; width: 300px; padding: 100px 0px 20px;} #logo-container {margin-left: auto; margin-right: auto; text-align: center;} #logo {max-width: 180px; max-height: 113px; margin-bottom: 2rem; border: 0;} #header {font-size: 1.5rem; text-align: center; margin-bottom: 1rem;} #message {background-color: #FFFFFF; margin: 0px auto; padding: 1.25rem; border-radius: 0.25rem; border: 1px solid #D8DDE6;} #footer {height: 24px; width: 300px; text-align: center; font-size: .75rem; position: absolute; bottom: 10;}</style></head><body><div id=\"center\"><div id=\"logo-container\"><img id=\"logo\" aria-hidden=\"true\" name=\"logo\" alt=\"Salesforce\" src=\"data:image/svg+xml;base64,%s\"></div><div id=\"header\">Authentication Successful</div><div id=\"message\">You've successfully logged in. You can now close this browser tab or window.</div><div id=\"footer\">© %s Salesforce, Inc. All rights reserved.</div></div></body></html>"], ["serverSfdcImage", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIxLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAyNjIgMTg0IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNjIgMTg0OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzAwQTFFMDt9Cgkuc3Qxe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+Cjx0aXRsZT5sb2dvLXNhbGVzZm9yY2U8L3RpdGxlPgo8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KPGcgaWQ9IlRlc3QtQiI+Cgk8ZyBpZD0iTW9iaWxlLU5hdi0tLVRlc3QtQi1feDI4XzBfeDI5XyI+CgkJPGcgaWQ9Ikdyb3VwIj4KCQkJPGcgaWQ9ImxvZ28tc2FsZXNmb3JjZSI+CgkJCQk8cGF0aCBpZD0iRmlsbC0xIiBjbGFzcz0ic3QwIiBkPSJNMTA5LjIsMjAuOWM4LjQtOC43LDIwLjEtMTQuMiwzMy0xNC4yYzE3LjIsMCwzMi4xLDkuNiw0MC4xLDIzLjhjNi45LTMuMSwxNC42LTQuOCwyMi43LTQuOAoJCQkJCWMzMSwwLDU2LDI1LjMsNTYsNTYuNXMtMjUuMSw1Ni41LTU2LDU2LjVjLTMuOCwwLTcuNS0wLjQtMTEtMS4xYy03LDEyLjUtMjAuNCwyMS0zNS44LDIxYy02LjQsMC0xMi41LTEuNS0xNy45LTQuMQoJCQkJCWMtNy4xLDE2LjctMjMuNywyOC41LTQzLDI4LjVjLTIwLjEsMC0zNy4zLTEyLjctNDMuOS0zMC42Yy0yLjksMC42LTUuOSwwLjktOC45LDAuOWMtMjQsMC00My40LTE5LjYtNDMuNC00My45CgkJCQkJYzAtMTYuMiw4LjctMzAuNCwyMS43LTM4Yy0yLjctNi4xLTQuMi0xMi45LTQuMi0yMC4xQzE4LjUsMjMuNiw0MS4yLDEsNjksMUM4NS40LDEsMTAwLDguOCwxMDkuMiwyMC45Ii8+CgkJCQk8cGF0aCBpZD0iQ29tYmluZWQtU2hhcGUiIGNsYXNzPSJzdDEiIGQ9Ik0zOC43LDk1LjRsMS4xLTIuOWMwLjItMC41LDAuNS0wLjMsMC43LTAuMmMwLjMsMC4yLDAuNSwwLjMsMC45LDAuNmMzLjEsMiw2LDIsNi45LDIKCQkJCQljMi4zLDAsMy44LTEuMiwzLjgtMi45di0wLjFjMC0xLjgtMi4yLTIuNS00LjgtMy4zbC0wLjYtMC4yYy0zLjUtMS03LjMtMi41LTcuMy02Ljl2LTAuMWMwLTQuMiwzLjQtNy4yLDguMy03LjJsMC41LDAKCQkJCQljMi45LDAsNS42LDAuOCw3LjYsMi4xYzAuMiwwLjEsMC40LDAuMywwLjMsMC42Yy0wLjEsMC4zLTEsMi42LTEuMSwyLjljLTAuMiwwLjUtMC43LDAuMi0wLjcsMC4yYy0xLjgtMS00LjUtMS43LTYuOC0xLjcKCQkJCQljLTIuMSwwLTMuNCwxLjEtMy40LDIuNnYwLjFjMCwxLjcsMi4zLDIuNSw0LjksMy4zbDAuNSwwLjFjMy41LDEuMSw3LjIsMi42LDcuMiw2Ljl2MC4xYzAsNC42LTMuMyw3LjQtOC42LDcuNAoJCQkJCWMtMi42LDAtNS4xLTAuNC03LjgtMS44Yy0wLjUtMC4zLTEtMC41LTEuNS0wLjlDMzguNyw5NS45LDM4LjUsOTUuOCwzOC43LDk1LjR6IE0xMTYuNyw5NS40bDEuMS0yLjljMC4yLTAuNSwwLjYtMC4zLDAuNy0wLjIKCQkJCQljMC4zLDAuMiwwLjUsMC4zLDAuOSwwLjZjMy4xLDIsNiwyLDYuOSwyYzIuMywwLDMuOC0xLjIsMy44LTIuOXYtMC4xYzAtMS44LTIuMi0yLjUtNC44LTMuM2wtMC42LTAuMmMtMy41LTEtNy4zLTIuNS03LjMtNi45CgkJCQkJdi0wLjFjMC00LjIsMy40LTcuMiw4LjMtNy4ybDAuNSwwYzIuOSwwLDUuNiwwLjgsNy42LDIuMWMwLjIsMC4xLDAuNCwwLjMsMC4zLDAuNmMtMC4xLDAuMy0xLDIuNi0xLjEsMi45CgkJCQkJYy0wLjIsMC41LTAuNywwLjItMC43LDAuMmMtMS44LTEtNC41LTEuNy02LjgtMS43Yy0yLjEsMC0zLjQsMS4xLTMuNCwyLjZ2MC4xYzAsMS43LDIuMywyLjUsNC45LDMuM2wwLjUsMC4xCgkJCQkJYzMuNSwxLjEsNy4yLDIuNiw3LjIsNi45djAuMWMwLDQuNi0zLjMsNy40LTguNiw3LjRjLTIuNiwwLTUuMS0wLjQtNy44LTEuOGMtMC41LTAuMy0xLTAuNS0xLjUtMC45CgkJCQkJQzExNi44LDk1LjksMTE2LjYsOTUuOCwxMTYuNyw5NS40eiBNMTc0LjUsODEuN2MwLjQsMS41LDAuNywzLjEsMC43LDQuOHMtMC4yLDMuMy0wLjcsNC44Yy0wLjQsMS41LTEuMSwyLjgtMiwzLjkKCQkJCQljLTAuOSwxLjEtMi4xLDItMy40LDIuNmMtMS40LDAuNi0zLDAuOS00LjgsMC45Yy0xLjgsMC0zLjQtMC4zLTQuOC0wLjljLTEuNC0wLjYtMi41LTEuNS0zLjQtMi42Yy0wLjktMS4xLTEuNi0yLjQtMi0zLjkKCQkJCQljLTAuNC0xLjUtMC43LTMuMS0wLjctNC44YzAtMS43LDAuMi0zLjMsMC43LTQuOGMwLjQtMS41LDEuMS0yLjgsMi0zLjljMC45LTEuMSwyLjEtMiwzLjQtMi42YzEuNC0wLjYsMy0xLDQuOC0xCgkJCQkJYzEuOCwwLDMuNCwwLjMsNC44LDFjMS40LDAuNiwyLjUsMS41LDMuNCwyLjZDMTczLjQsNzguOSwxNzQuMSw4MC4yLDE3NC41LDgxLjd6IE0xNzAsODYuNGMwLTIuNi0wLjUtNC42LTEuNC02CgkJCQkJYy0wLjktMS40LTIuNC0yLjEtNC4zLTIuMWMtMiwwLTMuNCwwLjctNC4zLDIuMWMtMC45LDEuNC0xLjQsMy40LTEuNCw2YzAsMi42LDAuNSw0LjYsMS40LDYuMWMwLjksMS40LDIuMywyLjEsNC4zLDIuMQoJCQkJCWMyLDAsMy40LTAuNyw0LjMtMi4xQzE2OS42LDkxLjEsMTcwLDg5LDE3MCw4Ni40eiBNMjExLjEsOTMuOWwxLjEsM2MwLjEsMC40LTAuMiwwLjUtMC4yLDAuNWMtMS43LDAuNy00LDEuMS02LjMsMS4xCgkJCQkJYy0zLjksMC02LjgtMS4xLTguOC0zLjNjLTItMi4yLTMtNS4yLTMtOC45YzAtMS43LDAuMi0zLjMsMC43LTQuOGMwLjUtMS41LDEuMi0yLjgsMi4yLTMuOWMxLTEuMSwyLjItMiwzLjYtMi42CgkJCQkJYzEuNC0wLjYsMy4xLTEsNS0xYzEuMywwLDIuNCwwLjEsMy4zLDAuMmMxLDAuMiwyLjQsMC41LDMsMC44YzAuMSwwLDAuNCwwLjIsMC4zLDAuNWMtMC40LDEuMi0wLjcsMi0xLjEsMwoJCQkJCWMtMC4yLDAuNS0wLjUsMC4zLTAuNSwwLjNjLTEuNS0wLjUtMi45LTAuNy00LjctMC43Yy0yLjIsMC0zLjksMC43LTQuOSwyLjJjLTEuMSwxLjQtMS43LDMuMy0xLjcsNS45YzAsMi44LDAuNyw0LjgsMS45LDYuMQoJCQkJCWMxLjIsMS4zLDIuOSwxLjksNS4xLDEuOWMwLjksMCwxLjctMC4xLDIuNC0wLjJjMC43LTAuMSwxLjQtMC4zLDIuMS0wLjZDMjEwLjUsOTMuNiwyMTAuOSw5My41LDIxMS4xLDkzLjl6IE0yMzMuOCw4MC44CgkJCQkJYzEsMy40LDAuNSw2LjMsMC40LDYuNWMwLDAuNC0wLjQsMC40LTAuNCwwLjRsLTE1LjEsMGMwLjEsMi4zLDAuNiwzLjksMS44LDVjMS4xLDEuMSwyLjgsMS44LDUuMiwxLjhjMy42LDAsNS4xLTAuNyw2LjItMS4xCgkJCQkJYzAsMCwwLjQtMC4xLDAuNiwwLjNsMSwyLjhjMC4yLDAuNSwwLDAuNi0wLjEsMC43Yy0wLjksMC41LTMuMiwxLjUtNy42LDEuNWMtMi4xLDAtNC0wLjMtNS41LTAuOWMtMS41LTAuNi0yLjgtMS40LTMuOC0yLjUKCQkJCQljLTEtMS4xLTEuNy0yLjQtMi4yLTMuOGMtMC41LTEuNS0wLjctMy4xLTAuNy00LjhjMC0xLjcsMC4yLTMuMywwLjctNC44YzAuNC0xLjUsMS4xLTIuOCwyLTMuOWMwLjktMS4xLDIuMS0yLDMuNS0yLjYKCQkJCQljMS40LTAuNywzLjEtMSw1LTFjMS42LDAsMy4xLDAuMyw0LjMsMC45YzAuOSwwLjQsMS45LDEuMSwyLjksMi4yQzIzMi41LDc3LjksMjMzLjQsNzkuNCwyMzMuOCw4MC44eiBNMjE4LjgsODRoMTAuNwoJCQkJCWMtMC4xLTEuNC0wLjQtMi42LTEtMy42Yy0wLjktMS40LTIuMi0yLjItNC4yLTIuMmMtMiwwLTMuNCwwLjgtNC4zLDIuMkMyMTkuNCw4MS4zLDIxOS4xLDgyLjUsMjE4LjgsODR6IE0xMTMuMSw4MC44CgkJCQkJYzEsMy40LDAuNSw2LjMsMC41LDYuNWMwLDAuNC0wLjQsMC40LTAuNCwwLjRsLTE1LjEsMGMwLjEsMi4zLDAuNiwzLjksMS44LDVjMS4xLDEuMSwyLjgsMS44LDUuMiwxLjhjMy42LDAsNS4xLTAuNyw2LjItMS4xCgkJCQkJYzAsMCwwLjQtMC4xLDAuNiwwLjNsMSwyLjhjMC4yLDAuNSwwLDAuNi0wLjEsMC43Yy0wLjksMC41LTMuMiwxLjUtNy42LDEuNWMtMi4xLDAtNC0wLjMtNS41LTAuOWMtMS41LTAuNi0yLjgtMS40LTMuOC0yLjUKCQkJCQljLTEtMS4xLTEuNy0yLjQtMi4yLTMuOGMtMC41LTEuNS0wLjctMy4xLTAuNy00LjhjMC0xLjcsMC4yLTMuMywwLjctNC44YzAuNC0xLjUsMS4xLTIuOCwyLTMuOWMwLjktMS4xLDIuMS0yLDMuNS0yLjYKCQkJCQljMS40LTAuNywzLjEtMSw1LTFjMS42LDAsMy4xLDAuMyw0LjMsMC45YzAuOSwwLjQsMS45LDEuMSwyLjksMi4yQzExMS44LDc3LjksMTEyLjgsNzkuNCwxMTMuMSw4MC44eiBNOTguMSw4NGgxMC44CgkJCQkJYy0wLjEtMS40LTAuNC0yLjYtMS0zLjZjLTAuOS0xLjQtMi4yLTIuMi00LjItMi4yYy0yLDAtMy40LDAuOC00LjMsMi4yQzk4LjcsODEuMyw5OC40LDgyLjUsOTguMSw4NHogTTcxLjYsODMuMgoJCQkJCWMwLDAsMS4yLDAuMSwyLjUsMC4zdi0wLjZjMC0yLTAuNC0zLTEuMi0zLjZjLTAuOC0wLjYtMi4xLTEtMy43LTFjMCwwLTMuNywwLTYuNiwxLjVjLTAuMSwwLjEtMC4yLDAuMS0wLjIsMC4xCgkJCQkJcy0wLjQsMC4xLTAuNS0wLjJsLTEuMS0yLjljLTAuMi0wLjQsMC4xLTAuNiwwLjEtMC42YzEuNC0xLjEsNC42LTEuNyw0LjYtMS43YzEuMS0wLjIsMi45LTAuNCw0LTAuNGMzLDAsNS4zLDAuNyw2LjksMi4xCgkJCQkJYzEuNiwxLjQsMi40LDMuNiwyLjQsNi43bDAsMTMuOGMwLDAsMCwwLjQtMC4zLDAuNWMwLDAtMC42LDAuMi0xLjEsMC4zYy0wLjUsMC4xLTIuMywwLjUtMy44LDAuN2MtMS41LDAuMy0zLDAuNC00LjYsMC40CgkJCQkJYy0xLjUsMC0yLjgtMC4xLTQtMC40Yy0xLjItMC4zLTIuMi0wLjctMy4xLTEuM2MtMC44LTAuNi0xLjUtMS40LTItMi40Yy0wLjUtMC45LTAuNy0yLjEtMC43LTMuNGMwLTEuMywwLjMtMi41LDAuOC0zLjUKCQkJCQljMC41LTEsMS4zLTEuOCwyLjItMi41YzAuOS0wLjcsMi0xLjEsMy4xLTEuNWMxLjItMC4zLDIuNC0wLjUsMy43LTAuNUM3MC4yLDgzLjIsNzEsODMuMiw3MS42LDgzLjJ6IE02NS42LDkzLjgKCQkJCQljMCwwLDEuNCwxLjEsNC40LDAuOWMyLjItMC4xLDQuMS0wLjUsNC4xLTAuNXYtNi45YzAsMC0xLjktMC4zLTQuMS0wLjNjLTMuMSwwLTQuNCwxLjEtNC40LDEuMWMtMC45LDAuNi0xLjMsMS42LTEuMywyLjkKCQkJCQljMCwwLjgsMC4yLDEuNSwwLjUsMkM2NC45LDkzLjIsNjUsOTMuNCw2NS42LDkzLjh6IE0xOTMuMSw3NS41Yy0wLjEsMC40LTAuOSwyLjUtMS4xLDMuMmMtMC4xLDAuMy0wLjMsMC40LTAuNiwwLjQKCQkJCQljMCwwLTAuOS0wLjItMS43LTAuMmMtMC41LDAtMS4zLDAuMS0yLDAuM2MtMC43LDAuMi0xLjMsMC42LTEuOSwxLjFjLTAuNiwwLjUtMSwxLjMtMS4zLDIuMmMtMC4zLDAuOS0wLjUsMi40LTAuNSw0djExLjIKCQkJCQljMCwwLjMtMC4yLDAuNS0wLjUsMC41aC00Yy0wLjMsMC0wLjUtMC4yLTAuNS0wLjVWNzUuMmMwLTAuMywwLjItMC41LDAuNC0wLjVoMy45YzAuMywwLDAuNCwwLjIsMC40LDAuNVY3NwoJCQkJCWMwLjYtMC44LDEuNi0xLjUsMi41LTEuOWMwLjktMC40LDItMC43LDMuOS0wLjZjMSwwLjEsMi4zLDAuMywyLjUsMC40QzE5Myw3NSwxOTMuMiw3NS4xLDE5My4xLDc1LjV6IE0xNTYsNjUuMQoJCQkJCWMwLjEsMCwwLjQsMC4yLDAuMywwLjVsLTEuMiwzLjJjLTAuMSwwLjItMC4yLDAuNC0wLjcsMC4yYy0wLjEsMC0wLjMtMC4xLTAuOC0wLjJjLTAuMy0wLjEtMC44LTAuMS0xLjItMC4xCgkJCQkJYy0wLjYsMC0xLjEsMC4xLTEuNiwwLjJjLTAuNSwwLjEtMC45LDAuNC0xLjMsMC44Yy0wLjQsMC40LTAuOCwwLjktMS4xLDEuNmMtMC42LDEuNi0wLjgsMy4zLTAuOCwzLjRoNC44CgkJCQkJYzAuNCwwLDAuNSwwLjIsMC41LDAuNWwtMC42LDMuMWMtMC4xLDAuNS0wLjUsMC40LTAuNSwwLjRoLTVMMTQzLjYsOThjLTAuNCwyLTAuOCwzLjctMS4zLDUuMWMtMC41LDEuNC0xLjEsMi40LTIsMy40CgkJCQkJYy0wLjgsMC45LTEuNywxLjYtMi44LDEuOWMtMSwwLjQtMi4zLDAuNi0zLjcsMC42Yy0wLjcsMC0xLjQsMC0yLjItMC4yYy0wLjYtMC4xLTAuOS0wLjItMS40LTAuNGMtMC4yLTAuMS0wLjMtMC4zLTAuMi0wLjYKCQkJCQljMC4xLTAuMywxLTIuNywxLjEtMy4xYzAuMi0wLjQsMC41LTAuMiwwLjUtMC4yYzAuMywwLjEsMC41LDAuMiwwLjgsMC4zYzAuNCwwLjEsMC44LDAuMSwxLjIsMC4xYzAuNywwLDEuMy0wLjEsMS44LTAuMwoJCQkJCWMwLjYtMC4yLDEtMC42LDEuNC0xLjFjMC40LTAuNSwwLjctMS4yLDEuMS0yLjFjMC4zLTAuOSwwLjYtMi4yLDAuOS0zLjdsMy40LTE4LjloLTMuM2MtMC40LDAtMC41LTAuMi0wLjUtMC41bDAuNi0zLjEKCQkJCQljMC4xLTAuNSwwLjUtMC40LDAuNS0wLjRoMy40bDAuMi0xYzAuNS0zLDEuNS01LjMsMy02LjhjMS41LTEuNSwzLjctMi4zLDYuNC0yLjNjMC44LDAsMS41LDAuMSwyLjEsMC4yCgkJCQkJQzE1NSw2NC44LDE1NS41LDY0LjksMTU2LDY1LjF6IE04OC42LDk3LjZjMCwwLjMtMC4yLDAuNS0wLjQsMC41aC00Yy0wLjMsMC0wLjQtMC4yLTAuNC0wLjVWNjUuNWMwLTAuMiwwLjItMC41LDAuNC0wLjVoNAoJCQkJCWMwLjMsMCwwLjQsMC4yLDAuNCwwLjVWOTcuNnoiLz4KCQkJPC9nPgoJCTwvZz4KCTwvZz4KPC9nPgo8L3N2Zz4K"]]));
|
|
23
21
|
async function wait(ms = 1000) {
|
|
24
22
|
return new Promise((resolve) => {
|
|
25
23
|
setTimeout(resolve, ms);
|
|
@@ -29,7 +27,9 @@ async function makeRequest(options) {
|
|
|
29
27
|
const rawResponse = await new transport_1.default().httpRequest(options);
|
|
30
28
|
const response = (0, kit_1.parseJsonMap)(rawResponse.body);
|
|
31
29
|
if (response.error) {
|
|
32
|
-
const
|
|
30
|
+
const errorDescription = typeof response.error_description === 'string' ? response.error_description : '';
|
|
31
|
+
const error = typeof response.error === 'string' ? response.error : 'Unknown';
|
|
32
|
+
const err = new sfError_1.SfError(`Request Failed: ${error} ${errorDescription}`);
|
|
33
33
|
err.data = Object.assign(response, { status: rawResponse.statusCode });
|
|
34
34
|
throw err;
|
|
35
35
|
}
|
|
@@ -59,9 +59,9 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
59
59
|
this.pollingCount = 0;
|
|
60
60
|
this.options = options;
|
|
61
61
|
if (!this.options.clientId)
|
|
62
|
-
this.options.clientId =
|
|
62
|
+
this.options.clientId = org_1.DEFAULT_CONNECTED_APP_INFO.clientId;
|
|
63
63
|
if (!this.options.loginUrl)
|
|
64
|
-
this.options.loginUrl =
|
|
64
|
+
this.options.loginUrl = org_1.AuthInfo.getDefaultInstanceUrl();
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
67
|
* Begin the authorization flow by requesting the login
|
|
@@ -82,8 +82,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
82
82
|
const deviceFlowRequestUrl = this.getDeviceFlowRequestUrl();
|
|
83
83
|
const pollingOptions = this.getPollingOptions(deviceFlowRequestUrl, loginData.device_code);
|
|
84
84
|
const interval = kit_1.Duration.seconds(loginData.interval).milliseconds;
|
|
85
|
-
|
|
86
|
-
return response;
|
|
85
|
+
return this.pollForDeviceApproval(pollingOptions, interval);
|
|
87
86
|
}
|
|
88
87
|
/**
|
|
89
88
|
* Creates and saves new AuthInfo
|
|
@@ -91,7 +90,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
91
90
|
* @returns {Promise<AuthInfo>}
|
|
92
91
|
*/
|
|
93
92
|
async authorizeAndSave(approval) {
|
|
94
|
-
const authInfo = await
|
|
93
|
+
const authInfo = await org_1.AuthInfo.create({
|
|
95
94
|
oauth2Options: {
|
|
96
95
|
loginUrl: approval.instance_url,
|
|
97
96
|
refreshToken: approval.refresh_token,
|
|
@@ -108,27 +107,27 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
108
107
|
this.logger.debug(`this.options.loginUrl: ${this.options.loginUrl}`);
|
|
109
108
|
}
|
|
110
109
|
getLoginOptions(url) {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
const form = new FormData();
|
|
111
|
+
form.append('client_id', (0, ts_types_1.ensureString)(this.options.clientId));
|
|
112
|
+
form.append('response_type', DeviceOauthService.RESPONSE_TYPE);
|
|
113
|
+
form.append('scope', DeviceOauthService.SCOPE);
|
|
115
114
|
return {
|
|
116
115
|
url,
|
|
117
|
-
headers:
|
|
116
|
+
headers: { ...org_1.SFDX_HTTP_HEADERS, ...form.getHeaders() },
|
|
118
117
|
method: 'POST',
|
|
119
|
-
body,
|
|
118
|
+
body: form.getBuffer(),
|
|
120
119
|
};
|
|
121
120
|
}
|
|
122
121
|
getPollingOptions(url, code) {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
const form = new FormData();
|
|
123
|
+
form.append('client_id', (0, ts_types_1.ensureString)(this.options.clientId));
|
|
124
|
+
form.append('grant_type', DeviceOauthService.GRANT_TYPE);
|
|
125
|
+
form.append('code', code);
|
|
127
126
|
return {
|
|
128
127
|
url,
|
|
129
|
-
headers:
|
|
128
|
+
headers: { ...org_1.SFDX_HTTP_HEADERS, ...form.getHeaders() },
|
|
130
129
|
method: 'POST',
|
|
131
|
-
body,
|
|
130
|
+
body: form.getBuffer(),
|
|
132
131
|
};
|
|
133
132
|
}
|
|
134
133
|
getDeviceFlowRequestUrl() {
|
|
@@ -140,7 +139,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
140
139
|
return await makeRequest(httpRequest);
|
|
141
140
|
}
|
|
142
141
|
catch (e) {
|
|
143
|
-
|
|
142
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions */
|
|
144
143
|
const err = e.data;
|
|
145
144
|
if (err.error && err.status === 400 && err.error === 'authorization_pending') {
|
|
146
145
|
// do nothing because we're still waiting
|
|
@@ -155,6 +154,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
155
154
|
}
|
|
156
155
|
throw err;
|
|
157
156
|
}
|
|
157
|
+
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions */
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
shouldContinuePolling() {
|
|
@@ -164,6 +164,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
164
164
|
this.logger.debug('BEGIN POLLING FOR DEVICE APPROVAL');
|
|
165
165
|
let result;
|
|
166
166
|
while (this.shouldContinuePolling()) {
|
|
167
|
+
// eslint-disable-next-line no-await-in-loop
|
|
167
168
|
result = await this.poll(httpRequest);
|
|
168
169
|
if (result) {
|
|
169
170
|
this.logger.debug('POLLING FOR DEVICE APPROVAL SUCCESS');
|
|
@@ -171,6 +172,7 @@ class DeviceOauthService extends kit_1.AsyncCreatable {
|
|
|
171
172
|
}
|
|
172
173
|
else {
|
|
173
174
|
this.logger.debug(`waiting ${interval} ms...`);
|
|
175
|
+
// eslint-disable-next-line no-await-in-loop
|
|
174
176
|
await wait(interval);
|
|
175
177
|
this.pollingCount += 1;
|
|
176
178
|
}
|
package/lib/exported.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { OAuth2Config } from 'jsforce';
|
|
2
2
|
export { ConfigFile } from './config/configFile';
|
|
3
|
+
export { TTLConfig } from './config/ttlConfig';
|
|
3
4
|
export { envVars, EnvironmentVariable, SUPPORTED_ENV_VARS, EnvVars } from './config/envVars';
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
5
|
+
export { ConfigContents, ConfigEntry, ConfigStore, ConfigValue } from './config/configStore';
|
|
6
|
+
export { SfTokens, StateAggregator } from './stateAggregator';
|
|
6
7
|
export { DeviceOauthService, DeviceCodeResponse, DeviceCodePollingResponse } from './deviceOauthService';
|
|
7
8
|
export { OrgUsersConfig } from './config/orgUsersConfig';
|
|
8
|
-
export { ConfigPropertyMeta, ConfigPropertyMetaInput, Config, SfdxPropertyKeys, SFDX_ALLOWED_PROPERTIES, } from './config/config';
|
|
9
|
+
export { ConfigPropertyMeta, ConfigPropertyMetaInput, Config, SfdxPropertyKeys, SfConfigProperties, SFDX_ALLOWED_PROPERTIES, SF_ALLOWED_PROPERTIES, } from './config/config';
|
|
10
|
+
export { SandboxRequestCacheEntry, SandboxRequestCache } from './config/sandboxProcessCache';
|
|
9
11
|
export { ConfigInfo, ConfigAggregator } from './config/configAggregator';
|
|
10
|
-
export { AuthFields, AuthInfo, OrgAuthorization } from './org/authInfo';
|
|
12
|
+
export { AuthFields, AuthInfo, AuthSideEffects, OrgAuthorization } from './org/authInfo';
|
|
11
13
|
export { AuthRemover } from './org/authRemover';
|
|
12
14
|
export { Connection, SFDX_HTTP_HEADERS } from './org/connection';
|
|
13
15
|
export { Mode, Global } from './global';
|
|
@@ -16,20 +18,21 @@ export { WebOAuthServer } from './webOAuthServer';
|
|
|
16
18
|
export { SfdcUrl } from './util/sfdcUrl';
|
|
17
19
|
export { getJwtAudienceUrl } from './util/getJwtAudienceUrl';
|
|
18
20
|
export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptions, LoggerStream, Logger, } from './logger';
|
|
19
|
-
export { Messages } from './messages';
|
|
20
|
-
export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
|
|
21
|
+
export { Messages, StructuredMessage } from './messages';
|
|
22
|
+
export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, ResumeSandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
|
|
21
23
|
export { OrgConfigProperties, ORG_CONFIG_ALLOWED_PROPERTIES } from './org/orgConfigProperties';
|
|
22
|
-
export { PackageDir, NamedPackageDir, PackageDirDependency,
|
|
23
|
-
export { SchemaPrinter } from './schema/printer';
|
|
24
|
+
export { PackageDir, NamedPackageDir, PackageDirDependency, SfProject, SfProjectJson } from './sfProject';
|
|
24
25
|
export { SchemaValidator } from './schema/validator';
|
|
25
|
-
export {
|
|
26
|
+
export { SchemaPrinter } from './schema/printer';
|
|
27
|
+
export { SfError } from './sfError';
|
|
26
28
|
export { PollingClient } from './status/pollingClient';
|
|
27
29
|
export { CometClient, CometSubscription, StreamingClient, StatusResult } from './status/streamingClient';
|
|
28
30
|
export { MyDomainResolver } from './status/myDomainResolver';
|
|
29
31
|
export { DefaultUserFields, REQUIRED_FIELDS, User, UserFields } from './org/user';
|
|
30
32
|
export { PermissionSetAssignment, PermissionSetAssignmentFields } from './org/permissionSetAssignment';
|
|
31
|
-
export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate } from './org/scratchOrgCreate';
|
|
32
|
-
export { ScratchOrgInfo } from './org/
|
|
33
|
-
export
|
|
33
|
+
export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate, scratchOrgResume, } from './org/scratchOrgCreate';
|
|
34
|
+
export { ScratchOrgInfo } from './org/scratchOrgTypes';
|
|
35
|
+
export { ScratchOrgLifecycleEvent, scratchOrgLifecycleEventName, scratchOrgLifecycleStages, } from './org/scratchOrgLifecycleEvents';
|
|
36
|
+
export { ScratchOrgCache } from './org/scratchOrgCache';
|
|
34
37
|
export * from './util/sfdc';
|
|
35
38
|
export * from './util/sfdcUrl';
|