@salesforce/core 3.30.14 → 3.31.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/LICENSE.txt +11 -11
  2. package/README.md +222 -227
  3. package/lib/config/aliasesConfig.d.ts +12 -12
  4. package/lib/config/aliasesConfig.js +27 -27
  5. package/lib/config/authInfoConfig.d.ts +19 -19
  6. package/lib/config/authInfoConfig.js +34 -34
  7. package/lib/config/config.d.ts +311 -311
  8. package/lib/config/config.js +574 -574
  9. package/lib/config/configAggregator.d.ts +232 -232
  10. package/lib/config/configAggregator.js +379 -379
  11. package/lib/config/configFile.d.ts +199 -199
  12. package/lib/config/configFile.js +340 -340
  13. package/lib/config/configGroup.d.ts +141 -141
  14. package/lib/config/configGroup.js +224 -224
  15. package/lib/config/configStore.d.ts +241 -241
  16. package/lib/config/configStore.js +352 -352
  17. package/lib/config/envVars.d.ts +101 -101
  18. package/lib/config/envVars.js +456 -456
  19. package/lib/config/orgUsersConfig.d.ts +31 -31
  20. package/lib/config/orgUsersConfig.js +41 -41
  21. package/lib/config/sandboxOrgConfig.d.ts +37 -37
  22. package/lib/config/sandboxOrgConfig.js +50 -50
  23. package/lib/config/sandboxProcessCache.d.ts +16 -16
  24. package/lib/config/sandboxProcessCache.js +37 -37
  25. package/lib/config/tokensConfig.d.ts +10 -10
  26. package/lib/config/tokensConfig.js +28 -28
  27. package/lib/config/ttlConfig.d.ts +34 -34
  28. package/lib/config/ttlConfig.js +54 -54
  29. package/lib/crypto/crypto.d.ts +54 -54
  30. package/lib/crypto/crypto.js +220 -220
  31. package/lib/crypto/keyChain.d.ts +8 -8
  32. package/lib/crypto/keyChain.js +61 -61
  33. package/lib/crypto/keyChainImpl.d.ts +116 -116
  34. package/lib/crypto/keyChainImpl.js +486 -486
  35. package/lib/crypto/secureBuffer.d.ts +46 -46
  36. package/lib/crypto/secureBuffer.js +82 -82
  37. package/lib/deviceOauthService.d.ts +71 -71
  38. package/lib/deviceOauthService.js +191 -191
  39. package/lib/exported.d.ts +38 -38
  40. package/lib/exported.js +118 -118
  41. package/lib/global.d.ts +70 -70
  42. package/lib/global.js +109 -109
  43. package/lib/lifecycleEvents.d.ts +93 -93
  44. package/lib/lifecycleEvents.js +188 -188
  45. package/lib/logger.d.ts +381 -381
  46. package/lib/logger.js +734 -734
  47. package/lib/messages.d.ts +291 -291
  48. package/lib/messages.js +543 -543
  49. package/lib/org/authInfo.d.ts +344 -344
  50. package/lib/org/authInfo.js +892 -892
  51. package/lib/org/authRemover.d.ts +88 -88
  52. package/lib/org/authRemover.js +182 -182
  53. package/lib/org/connection.d.ts +197 -197
  54. package/lib/org/connection.js +395 -395
  55. package/lib/org/index.d.ts +6 -6
  56. package/lib/org/index.js +28 -28
  57. package/lib/org/org.d.ts +558 -558
  58. package/lib/org/org.js +1267 -1267
  59. package/lib/org/orgConfigProperties.d.ts +69 -69
  60. package/lib/org/orgConfigProperties.js +136 -136
  61. package/lib/org/permissionSetAssignment.d.ts +35 -35
  62. package/lib/org/permissionSetAssignment.js +125 -125
  63. package/lib/org/scratchOrgCache.d.ts +20 -20
  64. package/lib/org/scratchOrgCache.js +32 -32
  65. package/lib/org/scratchOrgCreate.d.ts +54 -54
  66. package/lib/org/scratchOrgCreate.js +216 -216
  67. package/lib/org/scratchOrgErrorCodes.d.ts +10 -10
  68. package/lib/org/scratchOrgErrorCodes.js +88 -88
  69. package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -26
  70. package/lib/org/scratchOrgFeatureDeprecation.js +109 -109
  71. package/lib/org/scratchOrgInfoApi.d.ts +68 -68
  72. package/lib/org/scratchOrgInfoApi.js +413 -413
  73. package/lib/org/scratchOrgInfoGenerator.d.ts +64 -64
  74. package/lib/org/scratchOrgInfoGenerator.js +241 -241
  75. package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -10
  76. package/lib/org/scratchOrgLifecycleEvents.js +40 -40
  77. package/lib/org/scratchOrgSettingsGenerator.d.ts +78 -78
  78. package/lib/org/scratchOrgSettingsGenerator.js +276 -276
  79. package/lib/org/scratchOrgTypes.d.ts +43 -43
  80. package/lib/org/scratchOrgTypes.js +8 -8
  81. package/lib/org/user.d.ts +187 -187
  82. package/lib/org/user.js +448 -448
  83. package/lib/schema/printer.d.ts +79 -79
  84. package/lib/schema/printer.js +260 -260
  85. package/lib/schema/validator.d.ts +70 -70
  86. package/lib/schema/validator.js +169 -169
  87. package/lib/sfError.d.ts +73 -73
  88. package/lib/sfError.js +136 -136
  89. package/lib/sfProject.d.ts +357 -357
  90. package/lib/sfProject.js +671 -671
  91. package/lib/stateAggregator/accessors/aliasAccessor.d.ts +98 -98
  92. package/lib/stateAggregator/accessors/aliasAccessor.js +145 -145
  93. package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -101
  94. package/lib/stateAggregator/accessors/orgAccessor.js +240 -240
  95. package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -8
  96. package/lib/stateAggregator/accessors/sandboxAccessor.js +27 -27
  97. package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -63
  98. package/lib/stateAggregator/accessors/tokenAccessor.js +79 -79
  99. package/lib/stateAggregator/index.d.ts +4 -4
  100. package/lib/stateAggregator/index.js +26 -26
  101. package/lib/stateAggregator/stateAggregator.d.ts +25 -25
  102. package/lib/stateAggregator/stateAggregator.js +45 -45
  103. package/lib/status/myDomainResolver.d.ts +66 -66
  104. package/lib/status/myDomainResolver.js +124 -124
  105. package/lib/status/pollingClient.d.ts +85 -85
  106. package/lib/status/pollingClient.js +115 -115
  107. package/lib/status/streamingClient.d.ts +244 -244
  108. package/lib/status/streamingClient.js +436 -436
  109. package/lib/status/types.d.ts +89 -89
  110. package/lib/status/types.js +17 -17
  111. package/lib/testSetup.d.ts +553 -530
  112. package/lib/testSetup.js +871 -727
  113. package/lib/util/cache.d.ts +11 -11
  114. package/lib/util/cache.js +69 -69
  115. package/lib/util/checkLightningDomain.d.ts +1 -1
  116. package/lib/util/checkLightningDomain.js +28 -28
  117. package/lib/util/directoryWriter.d.ts +12 -12
  118. package/lib/util/directoryWriter.js +53 -53
  119. package/lib/util/getJwtAudienceUrl.d.ts +4 -4
  120. package/lib/util/getJwtAudienceUrl.js +18 -18
  121. package/lib/util/internal.d.ts +58 -58
  122. package/lib/util/internal.js +118 -118
  123. package/lib/util/jsonXmlTools.d.ts +14 -14
  124. package/lib/util/jsonXmlTools.js +38 -38
  125. package/lib/util/mapKeys.d.ts +14 -14
  126. package/lib/util/mapKeys.js +51 -51
  127. package/lib/util/sfdc.d.ts +52 -52
  128. package/lib/util/sfdc.js +85 -85
  129. package/lib/util/sfdcUrl.d.ts +72 -72
  130. package/lib/util/sfdcUrl.js +215 -215
  131. package/lib/util/structuredWriter.d.ts +9 -9
  132. package/lib/util/structuredWriter.js +2 -2
  133. package/lib/util/zipWriter.d.ts +16 -16
  134. package/lib/util/zipWriter.js +67 -67
  135. package/lib/webOAuthServer.d.ts +156 -156
  136. package/lib/webOAuthServer.js +388 -388
  137. package/messages/auth.md +37 -37
  138. package/messages/config.md +156 -156
  139. package/messages/connection.md +30 -30
  140. package/messages/core.json +20 -20
  141. package/messages/core.md +67 -67
  142. package/messages/encryption.md +85 -85
  143. package/messages/envVars.md +303 -303
  144. package/messages/org.md +63 -63
  145. package/messages/permissionSetAssignment.md +31 -31
  146. package/messages/scratchOrgCreate.md +23 -23
  147. package/messages/scratchOrgErrorCodes.md +115 -115
  148. package/messages/scratchOrgFeatureDeprecation.md +11 -11
  149. package/messages/scratchOrgInfoApi.md +15 -15
  150. package/messages/scratchOrgInfoGenerator.md +23 -23
  151. package/messages/streaming.md +23 -23
  152. package/messages/user.md +35 -35
  153. package/package.json +97 -97
package/lib/org/user.js CHANGED
@@ -1,449 +1,449 @@
1
- "use strict";
2
- /*
3
- * Copyright (c) 2020, salesforce.com, inc.
4
- * All rights reserved.
5
- * Licensed under the BSD 3-Clause license.
6
- * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.User = exports.DefaultUserFields = exports.REQUIRED_FIELDS = void 0;
10
- const os_1 = require("os");
11
- const kit_1 = require("@salesforce/kit");
12
- const ts_types_1 = require("@salesforce/ts-types");
13
- const http_api_1 = require("jsforce/lib/http-api");
14
- const logger_1 = require("../logger");
15
- const messages_1 = require("../messages");
16
- const secureBuffer_1 = require("../crypto/secureBuffer");
17
- const sfError_1 = require("../sfError");
18
- const sfdc_1 = require("../util/sfdc");
19
- const connection_1 = require("./connection");
20
- const permissionSetAssignment_1 = require("./permissionSetAssignment");
21
- const authInfo_1 = require("./authInfo");
22
- const rand = (len) => Math.floor(Math.random() * len.length);
23
- const CHARACTERS = {
24
- LOWER: 'abcdefghijklmnopqrstuvwxyz',
25
- UPPER: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
26
- NUMBERS: '1234567890',
27
- SYMBOLS: ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '[', ']', '|', '-'],
28
- };
29
- const PASSWORD_COMPLEXITY = {
30
- '0': { LOWER: true },
31
- '1': { LOWER: true, NUMBERS: true },
32
- '2': { LOWER: true, SYMBOLS: true },
33
- '3': { LOWER: true, UPPER: true, NUMBERS: true },
34
- '4': { LOWER: true, NUMBERS: true, SYMBOLS: true },
35
- '5': { LOWER: true, UPPER: true, NUMBERS: true, SYMBOLS: true },
36
- };
37
- const scimEndpoint = '/services/scim/v1/Users';
38
- const scimHeaders = { 'auto-approve-user': 'true' };
39
- messages_1.Messages.importMessagesDirectory(__dirname);
40
- const messages = messages_1.Messages.load('@salesforce/core', 'user', [
41
- 'invalidHttpResponseCreatingUser',
42
- 'userQueryFailed',
43
- 'missingId',
44
- 'permsetNamesAreRequired',
45
- 'missingFields',
46
- 'lengthOutOfBound',
47
- 'complexityOutOfBound',
48
- ]);
49
- /**
50
- * A Map of Required Salesforce User fields.
51
- */
52
- exports.REQUIRED_FIELDS = {
53
- id: 'id',
54
- username: 'username',
55
- lastName: 'lastName',
56
- alias: 'alias',
57
- timeZoneSidKey: 'timeZoneSidKey',
58
- localeSidKey: 'localeSidKey',
59
- emailEncodingKey: 'emailEncodingKey',
60
- profileId: 'profileId',
61
- languageLocaleKey: 'languageLocaleKey',
62
- email: 'email',
63
- };
64
- /**
65
- * Helper method to lookup UserFields.
66
- *
67
- * @param logger
68
- * @param username The username.
69
- */
70
- async function retrieveUserFields(logger, username) {
71
- const connection = await connection_1.Connection.create({
72
- authInfo: await authInfo_1.AuthInfo.create({ username }),
73
- });
74
- if (sfdc_1.sfdc.matchesAccessToken(username)) {
75
- logger.debug('received an accessToken for the username. Converting...');
76
- username = (await connection.identity()).username;
77
- logger.debug(`accessToken converted to ${username}`);
78
- }
79
- else {
80
- logger.debug('not a accessToken');
81
- }
82
- const fromFields = Object.keys(exports.REQUIRED_FIELDS).map(kit_1.upperFirst);
83
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
84
- const requiredFieldsFromAdminQuery = `SELECT ${fromFields} FROM User WHERE Username='${username}'`;
85
- const result = await connection.query(requiredFieldsFromAdminQuery);
86
- logger.debug('Successfully retrieved the admin user for this org.');
87
- if (result.totalSize === 1) {
88
- const results = (0, kit_1.mapKeys)(result.records[0], (value, key) => (0, kit_1.lowerFirst)(key));
89
- const fields = {
90
- id: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.id]),
91
- username,
92
- alias: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.alias]),
93
- email: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.email]),
94
- emailEncodingKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.emailEncodingKey]),
95
- languageLocaleKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.languageLocaleKey]),
96
- localeSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.localeSidKey]),
97
- profileId: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.profileId]),
98
- lastName: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.lastName]),
99
- timeZoneSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.timeZoneSidKey]),
100
- };
101
- return fields;
102
- }
103
- else {
104
- throw messages.createError('userQueryFailed', [username]);
105
- }
106
- }
107
- /**
108
- * Gets the profile id associated with a profile name.
109
- *
110
- * @param name The name of the profile.
111
- * @param connection The connection for the query.
112
- */
113
- async function retrieveProfileId(name, connection) {
114
- if (!sfdc_1.sfdc.validateSalesforceId(name)) {
115
- const profileQuery = `SELECT Id FROM Profile WHERE name='${name}'`;
116
- const result = await connection.query(profileQuery);
117
- if (result.records.length > 0) {
118
- return result.records[0].Id;
119
- }
120
- }
121
- return name;
122
- }
123
- /**
124
- * Provides a default set of fields values that can be used to create a user. This is handy for
125
- * software development purposes.
126
- *
127
- * ```
128
- * const connection: Connection = await Connection.create({
129
- * authInfo: await AuthInfo.create({ username: 'user@example.com' })
130
- * });
131
- * const org: Org = await Org.create({ connection });
132
- * const options: DefaultUserFields.Options = {
133
- * templateUser: org.getUsername()
134
- * };
135
- * const fields = (await DefaultUserFields.create(options)).getFields();
136
- * ```
137
- */
138
- class DefaultUserFields extends kit_1.AsyncCreatable {
139
- /**
140
- * @ignore
141
- */
142
- constructor(options) {
143
- super(options);
144
- this.options = options || { templateUser: '' };
145
- }
146
- /**
147
- * Get user fields.
148
- */
149
- getFields() {
150
- return this.userFields;
151
- }
152
- /**
153
- * Initialize asynchronous components.
154
- */
155
- async init() {
156
- this.logger = await logger_1.Logger.child('DefaultUserFields');
157
- this.userFields = await retrieveUserFields(this.logger, this.options.templateUser);
158
- this.userFields.profileId = await retrieveProfileId('Standard User', await connection_1.Connection.create({
159
- authInfo: await authInfo_1.AuthInfo.create({ username: this.options.templateUser }),
160
- }));
161
- this.logger.debug(`Standard User profileId: ${this.userFields.profileId}`);
162
- if (this.options.newUserName) {
163
- this.userFields.username = this.options.newUserName;
164
- }
165
- else {
166
- this.userFields.username = `${Date.now()}_${this.userFields.username}`;
167
- }
168
- }
169
- }
170
- exports.DefaultUserFields = DefaultUserFields;
171
- /**
172
- * A class for creating a User, generating a password for a user, and assigning a user to one or more permission sets.
173
- * See methods for examples.
174
- */
175
- class User extends kit_1.AsyncCreatable {
176
- /**
177
- * @ignore
178
- */
179
- constructor(options) {
180
- super(options);
181
- this.org = options.org;
182
- }
183
- /**
184
- * Generate default password for a user. Returns An encrypted buffer containing a utf8 encoded password.
185
- */
186
- static generatePasswordUtf8(passwordCondition = { length: 13, complexity: 5 }) {
187
- if (!PASSWORD_COMPLEXITY[passwordCondition.complexity]) {
188
- const msg = messages.getMessage('complexityOutOfBound');
189
- throw new sfError_1.SfError(msg, 'complexityOutOfBound');
190
- }
191
- if (passwordCondition.length < 8 || passwordCondition.length > 1000) {
192
- const msg = messages.getMessage('lengthOutOfBound');
193
- throw new sfError_1.SfError(msg, 'lengthOutOfBound');
194
- }
195
- let password = [];
196
- ['SYMBOLS', 'NUMBERS', 'UPPER', 'LOWER'].forEach((charSet) => {
197
- if (PASSWORD_COMPLEXITY[passwordCondition.complexity][charSet]) {
198
- password.push(CHARACTERS[charSet][rand(CHARACTERS[charSet])]);
199
- }
200
- });
201
- // Concatinating remaining length randomly with all lower characters
202
- password = password.concat(Array(Math.max(passwordCondition.length - password.length, 0))
203
- .fill('0')
204
- .map(() => CHARACTERS['LOWER'][rand(CHARACTERS['LOWER'])]));
205
- password = password.sort(() => Math.random() - 0.5);
206
- const secureBuffer = new secureBuffer_1.SecureBuffer();
207
- secureBuffer.consume(Buffer.from(password.join(''), 'utf8'));
208
- return secureBuffer;
209
- }
210
- /**
211
- * Initialize a new instance of a user and return it.
212
- */
213
- async init() {
214
- this.logger = await logger_1.Logger.child('User');
215
- await this.org.refreshAuth();
216
- this.logger.debug('Auth refresh ok');
217
- }
218
- /**
219
- * Assigns a password to a user. For a user to have the ability to assign their own password, the org needs the
220
- * following org feature: EnableSetPasswordInApi.
221
- *
222
- * @param info The AuthInfo object for user to assign the password to.
223
- * @param password [throwWhenRemoveFails = User.generatePasswordUtf8()] A SecureBuffer containing the new password.
224
- */
225
- async assignPassword(info, password = User.generatePasswordUtf8()) {
226
- this.logger.debug(`Attempting to set password for userId: ${info.getFields().userId} username: ${info.getFields().username}`);
227
- const userConnection = await connection_1.Connection.create({ authInfo: info });
228
- return new Promise((resolve, reject) => {
229
- // no promises in async method
230
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
231
- password.value(async (buffer) => {
232
- try {
233
- const soap = userConnection.soap;
234
- await soap.setPassword((0, ts_types_1.ensureString)(info.getFields().userId), buffer.toString('utf8'));
235
- this.logger.debug(`Set password for userId: ${info.getFields().userId}`);
236
- resolve();
237
- }
238
- catch (e) {
239
- reject(e);
240
- }
241
- });
242
- });
243
- }
244
- /**
245
- * Methods to assign one or more permission set names to a user.
246
- *
247
- * @param id The Salesforce id of the user to assign the permission set to.
248
- * @param permsetNames An array of permission set names.
249
- *
250
- * ```
251
- * const username = 'user@example.com';
252
- * const connection: Connection = await Connection.create({
253
- * authInfo: await AuthInfo.create({ username })
254
- * });
255
- * const org = await Org.create({ connection });
256
- * const user: User = await User.create({ org });
257
- * const fields: UserFields = await user.retrieve(username);
258
- * await user.assignPermissionSets(fields.id, ['sfdx', 'approver']);
259
- * ```
260
- */
261
- async assignPermissionSets(id, permsetNames) {
262
- if (!id) {
263
- throw messages.createError('missingId');
264
- }
265
- if (!permsetNames) {
266
- throw messages.createError('permsetNamesAreRequired');
267
- }
268
- const assignments = await permissionSetAssignment_1.PermissionSetAssignment.init(this.org);
269
- await Promise.all(permsetNames.map((permsetName) => assignments.create(id, permsetName)));
270
- }
271
- /**
272
- * Method for creating a new User.
273
- *
274
- * By default scratch orgs only allow creating 2 additional users. Work with Salesforce Customer Service to increase
275
- * user limits.
276
- *
277
- * The Org Preferences required to increase the number of users are:
278
- * Standard User Licenses
279
- * Salesforce CRM Content User
280
- *
281
- * @param fields The required fields for creating a user.
282
- *
283
- * ```
284
- * const connection: Connection = await Connection.create({
285
- * authInfo: await AuthInfo.create({ username: 'user@example.com' })
286
- * });
287
- * const org = await Org.create({ connection });
288
- *
289
- * const defaultUserFields = await DefaultUserFields.create({ templateUser: 'devhub_user@example.com' });
290
- * const user: User = await User.create({ org });
291
- * const info: AuthInfo = await user.createUser(defaultUserFields.getFields());
292
- * ```
293
- */
294
- async createUser(fields) {
295
- // Create a user and get a refresh token
296
- const refreshTokenSecret = await this.createUserInternal(fields);
297
- // Create the initial auth info
298
- const authInfo = await authInfo_1.AuthInfo.create({ username: this.org.getUsername() });
299
- const adminUserAuthFields = authInfo.getFields(true);
300
- // Setup oauth options for the new user
301
- const oauthOptions = {
302
- // Communities users require the instance for auth
303
- loginUrl: adminUserAuthFields.instanceUrl ?? adminUserAuthFields.loginUrl,
304
- refreshToken: refreshTokenSecret.buffer.value((buffer) => buffer.toString('utf8')),
305
- clientId: adminUserAuthFields.clientId,
306
- clientSecret: adminUserAuthFields.clientSecret,
307
- privateKey: adminUserAuthFields.privateKey,
308
- };
309
- // Create an auth info object for the new user
310
- const newUserAuthInfo = await authInfo_1.AuthInfo.create({
311
- username: fields.username,
312
- oauth2Options: oauthOptions,
313
- });
314
- // Update the auth info object with created user id.
315
- const newUserAuthFields = newUserAuthInfo.getFields();
316
- newUserAuthFields.userId = refreshTokenSecret.userId;
317
- // Make sure we can connect and if so save the auth info.
318
- await this.describeUserAndSave(newUserAuthInfo);
319
- // Let the org know there is a new user. See $HOME/.sfdx/[orgid].json for the mapping.
320
- await this.org.addUsername(newUserAuthInfo);
321
- return newUserAuthInfo;
322
- }
323
- /**
324
- * Method to retrieve the UserFields for a user.
325
- *
326
- * @param username The username of the user.
327
- *
328
- * ```
329
- * const username = 'boris@thecat.com';
330
- * const connection: Connection = await Connection.create({
331
- * authInfo: await AuthInfo.create({ username })
332
- * });
333
- * const org = await Org.create({ connection });
334
- * const user: User = await User.create({ org });
335
- * const fields: UserFields = await user.retrieve(username);
336
- * ```
337
- */
338
- async retrieve(username) {
339
- return retrieveUserFields(this.logger, username);
340
- }
341
- /**
342
- * Helper method that verifies the server's User object is available and if so allows persisting the Auth information.
343
- *
344
- * @param newUserAuthInfo The AuthInfo for the new user.
345
- */
346
- async describeUserAndSave(newUserAuthInfo) {
347
- const connection = await connection_1.Connection.create({ authInfo: newUserAuthInfo });
348
- this.logger.debug(`Created connection for user: ${newUserAuthInfo.getUsername()}`);
349
- const userDescribe = await connection.describe('User');
350
- if (userDescribe?.fields) {
351
- await newUserAuthInfo.save();
352
- return newUserAuthInfo;
353
- }
354
- else {
355
- throw messages.createError('permsetNamesAreRequired');
356
- }
357
- }
358
- /**
359
- * Helper that makes a REST request to create the user, and update additional required fields.
360
- *
361
- * @param fields The configuration the new user should have.
362
- */
363
- async createUserInternal(fields) {
364
- if (!fields) {
365
- throw messages.createError('missingFields');
366
- }
367
- const conn = this.org.getConnection();
368
- const body = JSON.stringify({
369
- username: fields.username,
370
- emails: [fields.email],
371
- name: {
372
- familyName: fields.lastName,
373
- },
374
- nickName: fields.username.substring(0, 40),
375
- entitlements: [
376
- {
377
- value: fields.profileId,
378
- },
379
- ],
380
- });
381
- this.logger.debug(`user create request body: ${body}`);
382
- const scimUrl = conn.normalizeUrl(scimEndpoint);
383
- this.logger.debug(`scimUrl: ${scimUrl}`);
384
- const info = {
385
- method: 'POST',
386
- url: scimUrl,
387
- headers: scimHeaders,
388
- body,
389
- };
390
- const response = await this.rawRequest(conn, info);
391
- const responseBody = (0, kit_1.parseJsonMap)((0, ts_types_1.ensureString)(response['body']));
392
- const statusCode = (0, ts_types_1.asNumber)(response.statusCode);
393
- this.logger.debug(`user create response.statusCode: ${response.statusCode}`);
394
- if (!(statusCode === 201 || statusCode === 200)) {
395
- let message = messages.getMessage('invalidHttpResponseCreatingUser', [statusCode]);
396
- if (responseBody) {
397
- const errors = (0, ts_types_1.asJsonArray)(responseBody.Errors);
398
- if (errors && errors.length > 0) {
399
- message = `${message} causes:${os_1.EOL}`;
400
- errors.forEach((singleMessage) => {
401
- if (!(0, ts_types_1.isJsonMap)(singleMessage))
402
- return;
403
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
404
- message = `${message}${os_1.EOL}${singleMessage.description}`;
405
- });
406
- }
407
- }
408
- this.logger.debug(message);
409
- throw new sfError_1.SfError(message, 'UserCreateHttpError');
410
- }
411
- fields.id = (0, ts_types_1.ensureString)(responseBody.id);
412
- await this.updateRequiredUserFields(fields);
413
- const buffer = new secureBuffer_1.SecureBuffer();
414
- const headers = (0, ts_types_1.ensureJsonMap)(response.headers);
415
- const autoApproveUser = (0, ts_types_1.ensureString)(headers['auto-approve-user']);
416
- buffer.consume(Buffer.from(autoApproveUser));
417
- return {
418
- buffer,
419
- userId: fields.id,
420
- };
421
- }
422
- // eslint-disable-next-line class-methods-use-this
423
- async rawRequest(conn, options) {
424
- return new Promise((resolve, reject) => {
425
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
426
- const httpApi = new http_api_1.HttpApi(conn, options);
427
- httpApi.on('response', (response) => resolve(response));
428
- httpApi.request(options).catch(reject);
429
- });
430
- }
431
- /**
432
- * Update the remaining required fields for the user.
433
- *
434
- * @param fields The fields for the user.
435
- */
436
- async updateRequiredUserFields(fields) {
437
- const leftOverRequiredFields = (0, kit_1.omit)(fields, [
438
- exports.REQUIRED_FIELDS.username,
439
- exports.REQUIRED_FIELDS.email,
440
- exports.REQUIRED_FIELDS.lastName,
441
- exports.REQUIRED_FIELDS.profileId,
442
- ]);
443
- const object = (0, kit_1.mapKeys)(leftOverRequiredFields, (value, key) => (0, kit_1.upperFirst)(key));
444
- await this.org.getConnection().sobject('User').update(object);
445
- this.logger.debug(`Successfully Updated additional properties for user: ${fields.username}`);
446
- }
447
- }
448
- exports.User = User;
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2020, salesforce.com, inc.
4
+ * All rights reserved.
5
+ * Licensed under the BSD 3-Clause license.
6
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.User = exports.DefaultUserFields = exports.REQUIRED_FIELDS = void 0;
10
+ const os_1 = require("os");
11
+ const kit_1 = require("@salesforce/kit");
12
+ const ts_types_1 = require("@salesforce/ts-types");
13
+ const http_api_1 = require("jsforce/lib/http-api");
14
+ const logger_1 = require("../logger");
15
+ const messages_1 = require("../messages");
16
+ const secureBuffer_1 = require("../crypto/secureBuffer");
17
+ const sfError_1 = require("../sfError");
18
+ const sfdc_1 = require("../util/sfdc");
19
+ const connection_1 = require("./connection");
20
+ const permissionSetAssignment_1 = require("./permissionSetAssignment");
21
+ const authInfo_1 = require("./authInfo");
22
+ const rand = (len) => Math.floor(Math.random() * len.length);
23
+ const CHARACTERS = {
24
+ LOWER: 'abcdefghijklmnopqrstuvwxyz',
25
+ UPPER: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
26
+ NUMBERS: '1234567890',
27
+ SYMBOLS: ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '[', ']', '|', '-'],
28
+ };
29
+ const PASSWORD_COMPLEXITY = {
30
+ '0': { LOWER: true },
31
+ '1': { LOWER: true, NUMBERS: true },
32
+ '2': { LOWER: true, SYMBOLS: true },
33
+ '3': { LOWER: true, UPPER: true, NUMBERS: true },
34
+ '4': { LOWER: true, NUMBERS: true, SYMBOLS: true },
35
+ '5': { LOWER: true, UPPER: true, NUMBERS: true, SYMBOLS: true },
36
+ };
37
+ const scimEndpoint = '/services/scim/v1/Users';
38
+ const scimHeaders = { 'auto-approve-user': 'true' };
39
+ messages_1.Messages.importMessagesDirectory(__dirname);
40
+ const messages = messages_1.Messages.load('@salesforce/core', 'user', [
41
+ 'invalidHttpResponseCreatingUser',
42
+ 'userQueryFailed',
43
+ 'missingId',
44
+ 'permsetNamesAreRequired',
45
+ 'missingFields',
46
+ 'lengthOutOfBound',
47
+ 'complexityOutOfBound',
48
+ ]);
49
+ /**
50
+ * A Map of Required Salesforce User fields.
51
+ */
52
+ exports.REQUIRED_FIELDS = {
53
+ id: 'id',
54
+ username: 'username',
55
+ lastName: 'lastName',
56
+ alias: 'alias',
57
+ timeZoneSidKey: 'timeZoneSidKey',
58
+ localeSidKey: 'localeSidKey',
59
+ emailEncodingKey: 'emailEncodingKey',
60
+ profileId: 'profileId',
61
+ languageLocaleKey: 'languageLocaleKey',
62
+ email: 'email',
63
+ };
64
+ /**
65
+ * Helper method to lookup UserFields.
66
+ *
67
+ * @param logger
68
+ * @param username The username.
69
+ */
70
+ async function retrieveUserFields(logger, username) {
71
+ const connection = await connection_1.Connection.create({
72
+ authInfo: await authInfo_1.AuthInfo.create({ username }),
73
+ });
74
+ if (sfdc_1.sfdc.matchesAccessToken(username)) {
75
+ logger.debug('received an accessToken for the username. Converting...');
76
+ username = (await connection.identity()).username;
77
+ logger.debug(`accessToken converted to ${username}`);
78
+ }
79
+ else {
80
+ logger.debug('not a accessToken');
81
+ }
82
+ const fromFields = Object.keys(exports.REQUIRED_FIELDS).map(kit_1.upperFirst);
83
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
84
+ const requiredFieldsFromAdminQuery = `SELECT ${fromFields} FROM User WHERE Username='${username}'`;
85
+ const result = await connection.query(requiredFieldsFromAdminQuery);
86
+ logger.debug('Successfully retrieved the admin user for this org.');
87
+ if (result.totalSize === 1) {
88
+ const results = (0, kit_1.mapKeys)(result.records[0], (value, key) => (0, kit_1.lowerFirst)(key));
89
+ const fields = {
90
+ id: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.id]),
91
+ username,
92
+ alias: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.alias]),
93
+ email: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.email]),
94
+ emailEncodingKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.emailEncodingKey]),
95
+ languageLocaleKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.languageLocaleKey]),
96
+ localeSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.localeSidKey]),
97
+ profileId: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.profileId]),
98
+ lastName: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.lastName]),
99
+ timeZoneSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.timeZoneSidKey]),
100
+ };
101
+ return fields;
102
+ }
103
+ else {
104
+ throw messages.createError('userQueryFailed', [username]);
105
+ }
106
+ }
107
+ /**
108
+ * Gets the profile id associated with a profile name.
109
+ *
110
+ * @param name The name of the profile.
111
+ * @param connection The connection for the query.
112
+ */
113
+ async function retrieveProfileId(name, connection) {
114
+ if (!sfdc_1.sfdc.validateSalesforceId(name)) {
115
+ const profileQuery = `SELECT Id FROM Profile WHERE name='${name}'`;
116
+ const result = await connection.query(profileQuery);
117
+ if (result.records.length > 0) {
118
+ return result.records[0].Id;
119
+ }
120
+ }
121
+ return name;
122
+ }
123
+ /**
124
+ * Provides a default set of fields values that can be used to create a user. This is handy for
125
+ * software development purposes.
126
+ *
127
+ * ```
128
+ * const connection: Connection = await Connection.create({
129
+ * authInfo: await AuthInfo.create({ username: 'user@example.com' })
130
+ * });
131
+ * const org: Org = await Org.create({ connection });
132
+ * const options: DefaultUserFields.Options = {
133
+ * templateUser: org.getUsername()
134
+ * };
135
+ * const fields = (await DefaultUserFields.create(options)).getFields();
136
+ * ```
137
+ */
138
+ class DefaultUserFields extends kit_1.AsyncCreatable {
139
+ /**
140
+ * @ignore
141
+ */
142
+ constructor(options) {
143
+ super(options);
144
+ this.options = options || { templateUser: '' };
145
+ }
146
+ /**
147
+ * Get user fields.
148
+ */
149
+ getFields() {
150
+ return this.userFields;
151
+ }
152
+ /**
153
+ * Initialize asynchronous components.
154
+ */
155
+ async init() {
156
+ this.logger = await logger_1.Logger.child('DefaultUserFields');
157
+ this.userFields = await retrieveUserFields(this.logger, this.options.templateUser);
158
+ this.userFields.profileId = await retrieveProfileId('Standard User', await connection_1.Connection.create({
159
+ authInfo: await authInfo_1.AuthInfo.create({ username: this.options.templateUser }),
160
+ }));
161
+ this.logger.debug(`Standard User profileId: ${this.userFields.profileId}`);
162
+ if (this.options.newUserName) {
163
+ this.userFields.username = this.options.newUserName;
164
+ }
165
+ else {
166
+ this.userFields.username = `${Date.now()}_${this.userFields.username}`;
167
+ }
168
+ }
169
+ }
170
+ exports.DefaultUserFields = DefaultUserFields;
171
+ /**
172
+ * A class for creating a User, generating a password for a user, and assigning a user to one or more permission sets.
173
+ * See methods for examples.
174
+ */
175
+ class User extends kit_1.AsyncCreatable {
176
+ /**
177
+ * @ignore
178
+ */
179
+ constructor(options) {
180
+ super(options);
181
+ this.org = options.org;
182
+ }
183
+ /**
184
+ * Generate default password for a user. Returns An encrypted buffer containing a utf8 encoded password.
185
+ */
186
+ static generatePasswordUtf8(passwordCondition = { length: 13, complexity: 5 }) {
187
+ if (!PASSWORD_COMPLEXITY[passwordCondition.complexity]) {
188
+ const msg = messages.getMessage('complexityOutOfBound');
189
+ throw new sfError_1.SfError(msg, 'complexityOutOfBound');
190
+ }
191
+ if (passwordCondition.length < 8 || passwordCondition.length > 1000) {
192
+ const msg = messages.getMessage('lengthOutOfBound');
193
+ throw new sfError_1.SfError(msg, 'lengthOutOfBound');
194
+ }
195
+ let password = [];
196
+ ['SYMBOLS', 'NUMBERS', 'UPPER', 'LOWER'].forEach((charSet) => {
197
+ if (PASSWORD_COMPLEXITY[passwordCondition.complexity][charSet]) {
198
+ password.push(CHARACTERS[charSet][rand(CHARACTERS[charSet])]);
199
+ }
200
+ });
201
+ // Concatinating remaining length randomly with all lower characters
202
+ password = password.concat(Array(Math.max(passwordCondition.length - password.length, 0))
203
+ .fill('0')
204
+ .map(() => CHARACTERS['LOWER'][rand(CHARACTERS['LOWER'])]));
205
+ password = password.sort(() => Math.random() - 0.5);
206
+ const secureBuffer = new secureBuffer_1.SecureBuffer();
207
+ secureBuffer.consume(Buffer.from(password.join(''), 'utf8'));
208
+ return secureBuffer;
209
+ }
210
+ /**
211
+ * Initialize a new instance of a user and return it.
212
+ */
213
+ async init() {
214
+ this.logger = await logger_1.Logger.child('User');
215
+ await this.org.refreshAuth();
216
+ this.logger.debug('Auth refresh ok');
217
+ }
218
+ /**
219
+ * Assigns a password to a user. For a user to have the ability to assign their own password, the org needs the
220
+ * following org feature: EnableSetPasswordInApi.
221
+ *
222
+ * @param info The AuthInfo object for user to assign the password to.
223
+ * @param password [throwWhenRemoveFails = User.generatePasswordUtf8()] A SecureBuffer containing the new password.
224
+ */
225
+ async assignPassword(info, password = User.generatePasswordUtf8()) {
226
+ this.logger.debug(`Attempting to set password for userId: ${info.getFields().userId} username: ${info.getFields().username}`);
227
+ const userConnection = await connection_1.Connection.create({ authInfo: info });
228
+ return new Promise((resolve, reject) => {
229
+ // no promises in async method
230
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
231
+ password.value(async (buffer) => {
232
+ try {
233
+ const soap = userConnection.soap;
234
+ await soap.setPassword((0, ts_types_1.ensureString)(info.getFields().userId), buffer.toString('utf8'));
235
+ this.logger.debug(`Set password for userId: ${info.getFields().userId}`);
236
+ resolve();
237
+ }
238
+ catch (e) {
239
+ reject(e);
240
+ }
241
+ });
242
+ });
243
+ }
244
+ /**
245
+ * Methods to assign one or more permission set names to a user.
246
+ *
247
+ * @param id The Salesforce id of the user to assign the permission set to.
248
+ * @param permsetNames An array of permission set names.
249
+ *
250
+ * ```
251
+ * const username = 'user@example.com';
252
+ * const connection: Connection = await Connection.create({
253
+ * authInfo: await AuthInfo.create({ username })
254
+ * });
255
+ * const org = await Org.create({ connection });
256
+ * const user: User = await User.create({ org });
257
+ * const fields: UserFields = await user.retrieve(username);
258
+ * await user.assignPermissionSets(fields.id, ['sfdx', 'approver']);
259
+ * ```
260
+ */
261
+ async assignPermissionSets(id, permsetNames) {
262
+ if (!id) {
263
+ throw messages.createError('missingId');
264
+ }
265
+ if (!permsetNames) {
266
+ throw messages.createError('permsetNamesAreRequired');
267
+ }
268
+ const assignments = await permissionSetAssignment_1.PermissionSetAssignment.init(this.org);
269
+ await Promise.all(permsetNames.map((permsetName) => assignments.create(id, permsetName)));
270
+ }
271
+ /**
272
+ * Method for creating a new User.
273
+ *
274
+ * By default scratch orgs only allow creating 2 additional users. Work with Salesforce Customer Service to increase
275
+ * user limits.
276
+ *
277
+ * The Org Preferences required to increase the number of users are:
278
+ * Standard User Licenses
279
+ * Salesforce CRM Content User
280
+ *
281
+ * @param fields The required fields for creating a user.
282
+ *
283
+ * ```
284
+ * const connection: Connection = await Connection.create({
285
+ * authInfo: await AuthInfo.create({ username: 'user@example.com' })
286
+ * });
287
+ * const org = await Org.create({ connection });
288
+ *
289
+ * const defaultUserFields = await DefaultUserFields.create({ templateUser: 'devhub_user@example.com' });
290
+ * const user: User = await User.create({ org });
291
+ * const info: AuthInfo = await user.createUser(defaultUserFields.getFields());
292
+ * ```
293
+ */
294
+ async createUser(fields) {
295
+ // Create a user and get a refresh token
296
+ const refreshTokenSecret = await this.createUserInternal(fields);
297
+ // Create the initial auth info
298
+ const authInfo = await authInfo_1.AuthInfo.create({ username: this.org.getUsername() });
299
+ const adminUserAuthFields = authInfo.getFields(true);
300
+ // Setup oauth options for the new user
301
+ const oauthOptions = {
302
+ // Communities users require the instance for auth
303
+ loginUrl: adminUserAuthFields.instanceUrl ?? adminUserAuthFields.loginUrl,
304
+ refreshToken: refreshTokenSecret.buffer.value((buffer) => buffer.toString('utf8')),
305
+ clientId: adminUserAuthFields.clientId,
306
+ clientSecret: adminUserAuthFields.clientSecret,
307
+ privateKey: adminUserAuthFields.privateKey,
308
+ };
309
+ // Create an auth info object for the new user
310
+ const newUserAuthInfo = await authInfo_1.AuthInfo.create({
311
+ username: fields.username,
312
+ oauth2Options: oauthOptions,
313
+ });
314
+ // Update the auth info object with created user id.
315
+ const newUserAuthFields = newUserAuthInfo.getFields();
316
+ newUserAuthFields.userId = refreshTokenSecret.userId;
317
+ // Make sure we can connect and if so save the auth info.
318
+ await this.describeUserAndSave(newUserAuthInfo);
319
+ // Let the org know there is a new user. See $HOME/.sfdx/[orgid].json for the mapping.
320
+ await this.org.addUsername(newUserAuthInfo);
321
+ return newUserAuthInfo;
322
+ }
323
+ /**
324
+ * Method to retrieve the UserFields for a user.
325
+ *
326
+ * @param username The username of the user.
327
+ *
328
+ * ```
329
+ * const username = 'boris@thecat.com';
330
+ * const connection: Connection = await Connection.create({
331
+ * authInfo: await AuthInfo.create({ username })
332
+ * });
333
+ * const org = await Org.create({ connection });
334
+ * const user: User = await User.create({ org });
335
+ * const fields: UserFields = await user.retrieve(username);
336
+ * ```
337
+ */
338
+ async retrieve(username) {
339
+ return retrieveUserFields(this.logger, username);
340
+ }
341
+ /**
342
+ * Helper method that verifies the server's User object is available and if so allows persisting the Auth information.
343
+ *
344
+ * @param newUserAuthInfo The AuthInfo for the new user.
345
+ */
346
+ async describeUserAndSave(newUserAuthInfo) {
347
+ const connection = await connection_1.Connection.create({ authInfo: newUserAuthInfo });
348
+ this.logger.debug(`Created connection for user: ${newUserAuthInfo.getUsername()}`);
349
+ const userDescribe = await connection.describe('User');
350
+ if (userDescribe?.fields) {
351
+ await newUserAuthInfo.save();
352
+ return newUserAuthInfo;
353
+ }
354
+ else {
355
+ throw messages.createError('permsetNamesAreRequired');
356
+ }
357
+ }
358
+ /**
359
+ * Helper that makes a REST request to create the user, and update additional required fields.
360
+ *
361
+ * @param fields The configuration the new user should have.
362
+ */
363
+ async createUserInternal(fields) {
364
+ if (!fields) {
365
+ throw messages.createError('missingFields');
366
+ }
367
+ const conn = this.org.getConnection();
368
+ const body = JSON.stringify({
369
+ username: fields.username,
370
+ emails: [fields.email],
371
+ name: {
372
+ familyName: fields.lastName,
373
+ },
374
+ nickName: fields.username.substring(0, 40),
375
+ entitlements: [
376
+ {
377
+ value: fields.profileId,
378
+ },
379
+ ],
380
+ });
381
+ this.logger.debug(`user create request body: ${body}`);
382
+ const scimUrl = conn.normalizeUrl(scimEndpoint);
383
+ this.logger.debug(`scimUrl: ${scimUrl}`);
384
+ const info = {
385
+ method: 'POST',
386
+ url: scimUrl,
387
+ headers: scimHeaders,
388
+ body,
389
+ };
390
+ const response = await this.rawRequest(conn, info);
391
+ const responseBody = (0, kit_1.parseJsonMap)((0, ts_types_1.ensureString)(response['body']));
392
+ const statusCode = (0, ts_types_1.asNumber)(response.statusCode);
393
+ this.logger.debug(`user create response.statusCode: ${response.statusCode}`);
394
+ if (!(statusCode === 201 || statusCode === 200)) {
395
+ let message = messages.getMessage('invalidHttpResponseCreatingUser', [statusCode]);
396
+ if (responseBody) {
397
+ const errors = (0, ts_types_1.asJsonArray)(responseBody.Errors);
398
+ if (errors && errors.length > 0) {
399
+ message = `${message} causes:${os_1.EOL}`;
400
+ errors.forEach((singleMessage) => {
401
+ if (!(0, ts_types_1.isJsonMap)(singleMessage))
402
+ return;
403
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
404
+ message = `${message}${os_1.EOL}${singleMessage.description}`;
405
+ });
406
+ }
407
+ }
408
+ this.logger.debug(message);
409
+ throw new sfError_1.SfError(message, 'UserCreateHttpError');
410
+ }
411
+ fields.id = (0, ts_types_1.ensureString)(responseBody.id);
412
+ await this.updateRequiredUserFields(fields);
413
+ const buffer = new secureBuffer_1.SecureBuffer();
414
+ const headers = (0, ts_types_1.ensureJsonMap)(response.headers);
415
+ const autoApproveUser = (0, ts_types_1.ensureString)(headers['auto-approve-user']);
416
+ buffer.consume(Buffer.from(autoApproveUser));
417
+ return {
418
+ buffer,
419
+ userId: fields.id,
420
+ };
421
+ }
422
+ // eslint-disable-next-line class-methods-use-this
423
+ async rawRequest(conn, options) {
424
+ return new Promise((resolve, reject) => {
425
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
426
+ const httpApi = new http_api_1.HttpApi(conn, options);
427
+ httpApi.on('response', (response) => resolve(response));
428
+ httpApi.request(options).catch(reject);
429
+ });
430
+ }
431
+ /**
432
+ * Update the remaining required fields for the user.
433
+ *
434
+ * @param fields The fields for the user.
435
+ */
436
+ async updateRequiredUserFields(fields) {
437
+ const leftOverRequiredFields = (0, kit_1.omit)(fields, [
438
+ exports.REQUIRED_FIELDS.username,
439
+ exports.REQUIRED_FIELDS.email,
440
+ exports.REQUIRED_FIELDS.lastName,
441
+ exports.REQUIRED_FIELDS.profileId,
442
+ ]);
443
+ const object = (0, kit_1.mapKeys)(leftOverRequiredFields, (value, key) => (0, kit_1.upperFirst)(key));
444
+ await this.org.getConnection().sobject('User').update(object);
445
+ this.logger.debug(`Successfully Updated additional properties for user: ${fields.username}`);
446
+ }
447
+ }
448
+ exports.User = User;
449
449
  //# sourceMappingURL=user.js.map