@salesforce/core
Version:
Core libraries to interact with SFDX projects, orgs, and APIs.
252 lines • 9.62 kB
JavaScript
;
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthRemover = void 0;
const path = require("path");
const kit_1 = require("@salesforce/kit");
const authInfo_1 = require("./authInfo");
const aliases_1 = require("./config/aliases");
const authInfoConfig_1 = require("./config/authInfoConfig");
const config_1 = require("./config/config");
const configAggregator_1 = require("./config/configAggregator");
const logger_1 = require("./logger");
const messages_1 = require("./messages");
const sfdxError_1 = require("./sfdxError");
messages_1.Messages.importMessagesDirectory(__dirname);
const messages = messages_1.Messages.loadMessages('@salesforce/core', 'auth');
/**
* Handles the removing of authorizations, which includes deleting the auth file
* in the global .sfdx folder, deleting any configs that are associated with the username/alias,
* and deleting any aliases associated with the username
*
* ```
* const remover = await AuthRemover.create();
* await remover.removeAuth('example@mycompany.com');
* ```
*
* ```
* const remover = await AuthRemover.create();
* await remover.removeAllAuths();
* ```
*
* ```
* const remover = await AuthRemover.create();
* const authConfigs = await remover.findAuthConfigs(
* example@mycompany.com
* );
* const usernames = [...authConfigs.keys()];
* for (const username of usernames) {
* await remover.removeAuth(username);
* }
* ```
*/
class AuthRemover extends kit_1.AsyncOptionalCreatable {
constructor() {
super(...arguments);
this.authConfigs = new Map();
}
/**
* Removes the authentication and any configs or aliases associated with it
*
* @param usernameOrAlias the username or alias that you want to remove
*/
async removeAuth(usernameOrAlias) {
const username = await this.resolveUsername(usernameOrAlias);
this.logger.debug(`Removing authorization for user ${username}`);
authInfo_1.AuthInfo.clearCache(username);
await this.unsetConfigValues(username);
await this.unsetAliases(username);
await this.unlinkConfigFile(username);
}
/**
* Removes all authentication files and any configs or aliases associated with them
*/
async removeAllAuths() {
const authConfigs = await this.findAllAuthConfigs();
const usernames = [...authConfigs.keys()];
for (const username of usernames) {
await this.removeAuth(username);
}
}
/**
* Finds authorization files for username/alias in the global .sfdx folder
* **Throws** *{@link SfdxError}{ name: 'NoOrgFound' }* if no username, alias, or defaultusername
*
* @param usernameOrAlias username or alias of the auth you want to find, defaults to the configured defaultusername
* @returns {Promise<AuthConfigs>}
*/
async findAuthConfigs(usernameOrAlias) {
const authFiles = await authInfo_1.AuthInfo.listAllAuthFiles();
let filenames = [];
if (usernameOrAlias) {
const authFileName = `${await this.resolveUsername(usernameOrAlias)}.json`;
filenames = authFiles.filter((f) => f === authFileName);
if (filenames.length === 0) {
filenames = await this.filterAuthFilesForDefaultUsername(authFiles);
}
}
else {
filenames = await this.filterAuthFilesForDefaultUsername(authFiles);
}
await this.initAuthInfoConfigs(filenames);
return this.authConfigs;
}
/**
* Finds all authorization files in the global .sfdx folder
*
* @returns {Promise<AuthConfigs>}
*/
async findAllAuthConfigs() {
const authFiles = await authInfo_1.AuthInfo.listAllAuthFiles();
await this.initAuthInfoConfigs(authFiles);
return this.authConfigs;
}
async init() {
this.logger = await logger_1.Logger.child(this.constructor.name);
this.globalConfig = await this.getConfig(true);
this.localConfig = await this.getConfig(false);
this.aliases = await aliases_1.Aliases.create(aliases_1.Aliases.getDefaultOptions());
}
/**
* Returns the username for a given alias if the alias exists.
*
* @param usernameOrAlias username or alias
* @returns {Promise<string>}
*/
async resolveUsername(usernameOrAlias) {
const aliasedValue = this.aliases.get(usernameOrAlias);
return (aliasedValue || usernameOrAlias);
}
/**
* Instantiates config class
*
* @param isGlobal
* @returns {Promise<Nullable<Config>>}
*/
async getConfig(isGlobal) {
let config;
try {
config = await config_1.Config.create({ isGlobal });
}
catch {
config = null;
}
return config;
}
/**
* Filters the provided authorization file names for ones that belong to the
* the configured defaultusername
* **Throws** *{@link SfdxError}{ name: 'NoOrgFound' }* if no defaultusername is not configured
*
* @param authFiles array of authorization file names
* @returns {Promise<string[]>}
*/
async filterAuthFilesForDefaultUsername(authFiles) {
let filenames = [];
const configAggregator = await configAggregator_1.ConfigAggregator.create();
const defaultUsername = configAggregator.getInfo(config_1.Config.DEFAULT_USERNAME).value;
if (!defaultUsername) {
const message = messages.getMessage('defaultOrgNotFound', ['defaultusername']);
const action = messages.getMessage('defaultOrgNotFoundActions');
throw new sfdxError_1.SfdxError(message, 'NoOrgFound', [action]);
}
else {
const authFileName = `${await this.resolveUsername(defaultUsername)}.json`;
filenames = authFiles.filter((f) => f === authFileName);
}
return filenames;
}
/**
* Instantiates the AuthInfoConfig class for each auth file
*
* @param filenames array of authorizaiton file names
* @returns {Promise<AuthConfigs>}
*/
async initAuthInfoConfigs(filenames) {
for (const filename of filenames) {
try {
const username = path.basename(filename, '.json');
const config = await authInfoConfig_1.AuthInfoConfig.create({
...authInfoConfig_1.AuthInfoConfig.getOptions(username),
throwOnNotFound: true,
});
this.authConfigs.set(username, config);
}
catch {
this.logger.debug(`Problem reading file: ${filename} skipping`);
}
}
return this.authConfigs;
}
/**
* Returns aliases for provided username
*
* @param username username that's been aliased
* @returns {Promise<string[]>}
*/
getAliases(username) {
return this.aliases.getKeysByValue(username) || [];
}
/**
* Unsets any configured values (both global and local) for provided username
*
* @param username username that you want to remove from config files
*/
async unsetConfigValues(username) {
const aliases = this.getAliases(username);
this.logger.debug(`Clearing config keys for username ${username} and aliases: ${aliases}`);
for (const config of [this.globalConfig, this.localConfig]) {
if (config) {
const keysWithUsername = config.getKeysByValue(username) || [];
const keysWithAlias = aliases
.map((alias) => config.getKeysByValue(alias))
.filter((k) => !!k)
.reduce((x, y) => x.concat(y), []);
const allKeys = keysWithUsername.concat(keysWithAlias);
this.logger.debug(`Found these config keys to remove: ${allKeys}`);
allKeys.forEach((key) => {
try {
config.unset(key);
}
catch {
this.logger.debug(`Failed to remove ${key}`);
}
});
await config.write();
}
}
}
/**
* Unsets any aliases for provided username
*
* @param username username that you want to remove from aliases
*/
async unsetAliases(username) {
this.logger.debug(`Clearing aliases for username: ${username}`);
const existingAliases = this.aliases.getKeysByValue(username);
this.logger.debug(`Found these aliases to remove: ${existingAliases}`);
existingAliases.forEach((alias) => this.aliases.unset(alias));
await this.aliases.write();
}
/**
* Deletes the authtorizaton file for provided username
*
* @param username username that you want to delete
*/
async unlinkConfigFile(username) {
const configFile = this.authConfigs.has(username)
? this.authConfigs.get(username)
: (await this.findAuthConfigs(username)).get(username);
if (configFile && (await configFile.exists())) {
this.logger.debug(`Deleting auth file for username ${username}`);
await configFile.unlink();
}
}
}
exports.AuthRemover = AuthRemover;
//# sourceMappingURL=authRemover.js.map