Files
sap-erp/node_modules/@azure/identity/dist-esm/src/credentials/azurePowerShellCredential.js
T
John 69b4e68baf
SAP-ERP Portal CI/CD / build (push) Failing after 5m20s
first commit
2026-09-23 17:31:02 +05:30

173 lines
7.1 KiB
JavaScript

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CredentialUnavailableError } from "../errors";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { ensureValidScope, getScopeResource } from "../util/scopeUtils";
import { processUtils } from "../util/processUtils";
import { processMultiTenantRequest } from "../util/validateMultiTenant";
import { checkTenantId } from "../util/checkTenantId";
const logger = credentialLogger("AzurePowerShellCredential");
const isWindows = process.platform === "win32";
/**
* Returns a platform-appropriate command name by appending ".exe" on Windows.
*
* @internal
*/
export function formatCommand(commandName) {
if (isWindows) {
return `${commandName}.exe`;
}
else {
return commandName;
}
}
/**
* Receives a list of commands to run, executes them, then returns the outputs.
* If anything fails, an error is thrown.
* @internal
*/
async function runCommands(commands) {
const results = [];
for (const command of commands) {
const [file, ...parameters] = command;
const result = (await processUtils.execFile(file, parameters, { encoding: "utf8" }));
results.push(result);
}
return results;
}
/**
* Known PowerShell errors
* @internal
*/
export const powerShellErrors = {
login: "Run Connect-AzAccount to login",
installed: "The specified module 'Az.Accounts' with version '2.2.0' was not loaded because no valid module file was found in any module directory",
};
/**
* Messages to use when throwing in this credential.
* @internal
*/
export const powerShellPublicErrorMessages = {
login: "Please run 'Connect-AzAccount' from PowerShell to authenticate before using this credential.",
installed: `The 'Az.Account' module >= 2.2.0 is not installed. Install the Azure Az PowerShell module with: "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force".`,
troubleshoot: `To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot.`,
};
// PowerShell Azure User not logged in error check.
const isLoginError = (err) => err.message.match(`(.*)${powerShellErrors.login}(.*)`);
// Az Module not Installed in Azure PowerShell check.
const isNotInstalledError = (err) => err.message.match(powerShellErrors.installed);
/**
* The PowerShell commands to be tried, in order.
*
* @internal
*/
export const commandStack = [formatCommand("pwsh")];
if (isWindows) {
commandStack.push(formatCommand("powershell"));
}
/**
* This credential will use the currently logged-in user information from the
* Azure PowerShell module. To do so, it will read the user access token and
* expire time with Azure PowerShell command `Get-AzAccessToken -ResourceUrl {ResourceScope}`
*/
export class AzurePowerShellCredential {
/**
* Creates an instance of the {@link AzurePowerShellCredential}.
*
* To use this credential:
* - Install the Azure Az PowerShell module with:
* `Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force`.
* - You have already logged in to Azure PowerShell using the command
* `Connect-AzAccount` from the command line.
*
* @param options - Options, to optionally allow multi-tenant requests.
*/
constructor(options) {
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
}
/**
* Gets the access token from Azure PowerShell
* @param resource - The resource to use when getting the token
*/
async getAzurePowerShellAccessToken(resource, tenantId) {
// Clone the stack to avoid mutating it while iterating
for (const powerShellCommand of [...commandStack]) {
try {
await runCommands([[powerShellCommand, "/?"]]);
}
catch (e) {
// Remove this credential from the original stack so that we don't try it again.
commandStack.shift();
continue;
}
let tenantSection = "";
if (tenantId) {
tenantSection = `-TenantId "${tenantId}"`;
}
const results = await runCommands([
[
powerShellCommand,
"-Command",
"Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru",
],
[
powerShellCommand,
"-Command",
`Get-AzAccessToken ${tenantSection} -ResourceUrl "${resource}" | ConvertTo-Json`,
],
]);
const result = results[1];
try {
return JSON.parse(result);
}
catch (e) {
throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
}
}
throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
const tenantId = processMultiTenantRequest(this.tenantId, options);
if (tenantId) {
checkTenantId(logger, tenantId);
}
const scope = typeof scopes === "string" ? scopes : scopes[0];
ensureValidScope(scope, logger);
logger.getToken.info(`Using the scope ${scope}`);
const resource = getScopeResource(scope);
try {
const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
logger.getToken.info(formatSuccess(scopes));
return {
token: response.Token,
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
};
}
catch (err) {
if (isNotInstalledError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
logger.getToken.info(formatError(scope, error));
throw error;
}
else if (isLoginError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
logger.getToken.info(formatError(scope, error));
throw error;
}
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
logger.getToken.info(formatError(scope, error));
throw error;
}
});
}
}
//# sourceMappingURL=azurePowerShellCredential.js.map