@salesforce/plugin-user
Version:
Commands to interact with Users and Permission Sets
106 lines • 4.78 kB
JavaScript
/*
* Copyright 2026, Salesforce, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { envVars, Messages, StateAggregator } from '@salesforce/core';
import { loglevel, orgApiVersionFlagWithDeprecations, requiredOrgFlagWithDeprecations, SfCommand, } from '@salesforce/sf-plugins-core';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-user', 'list');
const secretsMessages = Messages.loadMessages('@salesforce/plugin-user', 'secrets-redacted');
export class ListUsersCommand extends SfCommand {
static aliases = ['force:user:list'];
static deprecateAliases = true;
static summary = messages.getMessage('summary');
static description = messages.getMessage('description');
static examples = messages.getMessages('examples');
static flags = {
'target-org': requiredOrgFlagWithDeprecations,
'api-version': orgApiVersionFlagWithDeprecations,
loglevel,
};
async run() {
const { flags } = await this.parse(ListUsersCommand);
const org = flags['target-org'];
const conn = flags['target-org'].getConnection(flags['api-version']);
// parallelize 2 org queries and 2 fs operations
const [userInfos, profileInfos, userAuthData, aliases] = await Promise.all([
buildUserInfos(conn),
buildProfileInfos(conn),
org.readUserAuthFiles(),
(await StateAggregator.getInstance()).aliases,
]);
// TODO: Remove env var workaround
const showSecretsEnvVarIsSet = envVars.getBoolean('SF_TEMP_SHOW_SECRETS', false);
const accessTokenRedacted = secretsMessages.getMessage('redacted.accessToken');
const authList = userAuthData.map((authData) => {
const username = authData.getUsername();
// if they passed in an alias see if it maps to an Alias.
const alias = aliases.get(username);
const userInfo = userInfos.get(username);
const profileName = userInfo && profileInfos.get(userInfo.ProfileId)?.Name;
return {
defaultMarker: flags['target-org']?.getUsername() === username ? '(A)' : '',
alias: alias ?? '',
username,
profileName,
orgId: flags['target-org']?.getOrgId(),
accessToken: showSecretsEnvVarIsSet ? authData.getFields().accessToken : accessTokenRedacted,
instanceUrl: authData.getFields().instanceUrl,
loginUrl: authData.getFields().loginUrl,
userId: userInfos.get(username)?.Id,
};
});
this.table({
data: authList.map((authData) => ({
Default: authData.defaultMarker,
Alias: authData.alias,
Username: authData.username,
'Profile Name': authData.profileName,
'User Id': authData.userId,
})),
title: `Users in org ${flags['target-org']?.getOrgId()}`,
});
// TODO: Remove after env var workaround is removed
if (this.jsonEnabled()) {
if (showSecretsEnvVarIsSet) {
this.warn(secretsMessages.getMessage('temp.envVarIsSet', ['sf org list users']));
}
else {
this.warn(secretsMessages.getMessage('temp.envVarWorkaround', ['sf org list users']));
}
}
return authList;
}
}
/**
* Build a map of { [ProfileId]: ProfileName } for all profiles in the org
*
* @private
* @return Promise<ProfileInfo>
*/
const buildProfileInfos = async (conn) => {
const profileRecords = await conn.query('SELECT id, name FROM Profile');
return new Map((profileRecords.records ?? []).map((profileInfo) => [profileInfo.Id, profileInfo]));
};
/**
* query the user table and build a map of Username: { ProfileId, Id } } for all users in the org
*
* @private
* @return Promise<UserInfo>
*/
const buildUserInfos = async (conn) => {
const userRecords = await conn.query('SELECT username, profileid, id FROM User');
return new Map((userRecords.records ?? []).map((userInfo) => [userInfo.Username, userInfo]));
};
//# sourceMappingURL=users.js.map