@rushstack/rush-azure-storage-build-cache-plugin
Advanced tools
Comparing version
@@ -23,3 +23,5 @@ import { AzureAuthorityHosts } from '@azure/identity'; | ||
protected readonly _loginFlow: LoginFlowType; | ||
protected readonly _failoverOrder: Record<LoginFlowType, LoginFlowType | undefined>; | ||
protected readonly _failoverOrder: { | ||
[key in LoginFlowType]?: LoginFlowType; | ||
} | undefined; | ||
private __credentialCacheId; | ||
@@ -90,9 +92,15 @@ protected get _credentialCacheId(): string; | ||
* { | ||
* "AdoCodespacesAuth": "InteractiveBrowser", | ||
* "AdoCodespacesAuth": "VisualStudioCode", | ||
* "VisualStudioCode": "AzureCli", | ||
* "AzureCli": "AzureDeveloperCli", | ||
* "AzureDeveloperCli": "AzurePowerShell", | ||
* "AzurePowerShell": "InteractiveBrowser", | ||
* "InteractiveBrowser": "DeviceCode", | ||
* "DeviceCode": null | ||
* "DeviceCode": undefined | ||
* } | ||
* ``` | ||
*/ | ||
loginFlowFailover?: Record<LoginFlowType, LoginFlowType | undefined>; | ||
loginFlowFailover?: { | ||
[key in LoginFlowType]?: LoginFlowType; | ||
}; | ||
} | ||
@@ -163,3 +171,3 @@ | ||
*/ | ||
export declare type LoginFlowType = 'DeviceCode' | 'InteractiveBrowser' | 'AdoCodespacesAuth'; | ||
export declare type LoginFlowType = 'DeviceCode' | 'InteractiveBrowser' | 'AdoCodespacesAuth' | 'VisualStudioCode' | 'AzureCli' | 'AzureDeveloperCli' | 'AzurePowerShell'; | ||
@@ -166,0 +174,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import type { AccessToken, GetTokenOptions, TokenCredential } from '@azure/identity'; | ||
import { type AccessToken, type GetTokenOptions, type TokenCredential } from '@azure/identity'; | ||
/** | ||
@@ -3,0 +3,0 @@ * AdoCodespacesAuthCredential uses "Azure Devops Codespaces Authentication" VSCode extension to get the access |
@@ -7,2 +7,3 @@ "use strict"; | ||
const node_core_library_1 = require("@rushstack/node-core-library"); | ||
const identity_1 = require("@azure/identity"); | ||
/** | ||
@@ -17,36 +18,41 @@ * AdoCodespacesAuthCredential uses "Azure Devops Codespaces Authentication" VSCode extension to get the access | ||
var _a; | ||
let scope; | ||
if (Array.isArray(scopes)) { | ||
if (scopes.length > 1) { | ||
throw new Error('Only one scope is supported'); | ||
try { | ||
let scope; | ||
if (Array.isArray(scopes)) { | ||
if (scopes.length > 1) { | ||
throw new Error('Only one scope is supported'); | ||
} | ||
else if (scopes.length === 0) { | ||
throw new Error('A scope must be provided.'); | ||
} | ||
else { | ||
scope = scopes[0]; | ||
} | ||
} | ||
else if (scopes.length === 0) { | ||
throw new Error('A scope must be provided.'); | ||
} | ||
else { | ||
scope = scopes[0]; | ||
scope = scopes; | ||
} | ||
} | ||
else { | ||
scope = scopes; | ||
} | ||
const azureAuthHelperExec = 'azure-auth-helper'; | ||
const token = node_core_library_1.Executable.spawnSync(azureAuthHelperExec, ['get-access-token', scope]).stdout; | ||
let expiresOnTimestamp; | ||
try { | ||
const decodedToken = this._decodeToken(token); | ||
if ((_a = decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.payload) === null || _a === void 0 ? void 0 : _a.exp) { | ||
expiresOnTimestamp = decodedToken.payload.exp * 1000; | ||
const azureAuthHelperExec = 'azure-auth-helper'; | ||
const token = node_core_library_1.Executable.spawnSync(azureAuthHelperExec, ['get-access-token', scope]).stdout; | ||
let expiresOnTimestamp; | ||
try { | ||
const decodedToken = this._decodeToken(token); | ||
if ((_a = decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.payload) === null || _a === void 0 ? void 0 : _a.exp) { | ||
expiresOnTimestamp = decodedToken.payload.exp * 1000; | ||
} | ||
else { | ||
expiresOnTimestamp = Date.now() + 3600000; | ||
} | ||
} | ||
else { | ||
expiresOnTimestamp = Date.now() + 3600000; | ||
catch (error) { | ||
throw new Error(`Failed to decode the token: ${error}`); | ||
} | ||
return { | ||
token, | ||
expiresOnTimestamp | ||
}; | ||
} | ||
catch (error) { | ||
throw new Error(`Failed to decode the token: ${error}`); | ||
throw new identity_1.CredentialUnavailableError(`Failed to get token from Azure DevOps Codespaces Authentication: ${error.message}`); | ||
} | ||
return { | ||
token, | ||
expiresOnTimestamp | ||
}; | ||
} | ||
@@ -53,0 +59,0 @@ _decodeToken(token) { |
@@ -56,3 +56,3 @@ import { AzureAuthorityHosts, type DeviceCodeCredentialOptions, type InteractiveBrowserCredentialNodeOptions, type TokenCredential } from '@azure/identity'; | ||
*/ | ||
export type LoginFlowType = 'DeviceCode' | 'InteractiveBrowser' | 'AdoCodespacesAuth'; | ||
export type LoginFlowType = 'DeviceCode' | 'InteractiveBrowser' | 'AdoCodespacesAuth' | 'VisualStudioCode' | 'AzureCli' | 'AzureDeveloperCli' | 'AzurePowerShell'; | ||
/** | ||
@@ -73,9 +73,15 @@ * @public | ||
* { | ||
* "AdoCodespacesAuth": "InteractiveBrowser", | ||
* "AdoCodespacesAuth": "VisualStudioCode", | ||
* "VisualStudioCode": "AzureCli", | ||
* "AzureCli": "AzureDeveloperCli", | ||
* "AzureDeveloperCli": "AzurePowerShell", | ||
* "AzurePowerShell": "InteractiveBrowser", | ||
* "InteractiveBrowser": "DeviceCode", | ||
* "DeviceCode": null | ||
* "DeviceCode": undefined | ||
* } | ||
* ``` | ||
*/ | ||
loginFlowFailover?: Record<LoginFlowType, LoginFlowType | undefined>; | ||
loginFlowFailover?: { | ||
[key in LoginFlowType]?: LoginFlowType; | ||
}; | ||
} | ||
@@ -100,3 +106,5 @@ /** | ||
protected readonly _loginFlow: LoginFlowType; | ||
protected readonly _failoverOrder: Record<LoginFlowType, LoginFlowType | undefined>; | ||
protected readonly _failoverOrder: { | ||
[key in LoginFlowType]?: LoginFlowType; | ||
} | undefined; | ||
private __credentialCacheId; | ||
@@ -103,0 +111,0 @@ protected get _credentialCacheId(): string; |
@@ -7,5 +7,5 @@ "use strict"; | ||
const identity_1 = require("@azure/identity"); | ||
const AdoCodespacesAuthCredential_1 = require("./AdoCodespacesAuthCredential"); | ||
const rush_sdk_1 = require("@rushstack/rush-sdk"); | ||
const terminal_1 = require("@rushstack/terminal"); | ||
const AdoCodespacesAuthCredential_1 = require("./AdoCodespacesAuthCredential"); | ||
/** | ||
@@ -27,3 +27,3 @@ * @public | ||
constructor(options) { | ||
const { azureEnvironment = 'AzurePublicCloud', loginFlow = process.env.CODESPACES === 'true' ? 'AdoCodespacesAuth' : 'InteractiveBrowser' } = options; | ||
const { azureEnvironment = 'AzurePublicCloud', loginFlow = process.env.CODESPACES === 'true' ? 'AdoCodespacesAuth' : 'VisualStudioCode' } = options; | ||
this._azureEnvironment = azureEnvironment; | ||
@@ -33,3 +33,7 @@ this._credentialUpdateCommandForLogging = options.credentialUpdateCommandForLogging; | ||
this._failoverOrder = options.loginFlowFailover || { | ||
AdoCodespacesAuth: 'InteractiveBrowser', | ||
AdoCodespacesAuth: 'VisualStudioCode', | ||
VisualStudioCode: 'AzureCli', | ||
AzureCli: 'AzureDeveloperCli', | ||
AzureDeveloperCli: 'AzurePowerShell', | ||
AzurePowerShell: 'InteractiveBrowser', | ||
InteractiveBrowser: 'DeviceCode', | ||
@@ -116,2 +120,3 @@ DeviceCode: undefined | ||
async _getCredentialAsync(terminal, loginFlow, credentialsCache) { | ||
var _a; | ||
const authorityHost = identity_1.AzureAuthorityHosts[this._azureEnvironment]; | ||
@@ -121,3 +126,2 @@ if (!authorityHost) { | ||
} | ||
let tokenCredential; | ||
const interactiveCredentialOptions = { | ||
@@ -127,24 +131,39 @@ ...this._additionalInteractiveCredentialOptions, | ||
}; | ||
switch (loginFlow) { | ||
case 'AdoCodespacesAuth': { | ||
tokenCredential = new AdoCodespacesAuthCredential_1.AdoCodespacesAuthCredential(); | ||
break; | ||
const deviceCodeCredentialOptions = { | ||
...this._additionalDeviceCodeCredentialOptions, | ||
...interactiveCredentialOptions, | ||
userPromptCallback: (deviceCodeInfo) => { | ||
terminal_1.PrintUtilities.printMessageInBox(deviceCodeInfo.message, terminal); | ||
} | ||
case 'InteractiveBrowser': { | ||
tokenCredential = new identity_1.InteractiveBrowserCredential(interactiveCredentialOptions); | ||
break; | ||
}; | ||
const options = { authorityHost }; | ||
const priority = new Set([loginFlow]); | ||
for (const credType of priority) { | ||
const next = (_a = this._failoverOrder) === null || _a === void 0 ? void 0 : _a[credType]; | ||
if (next) { | ||
priority.add(next); | ||
} | ||
case 'DeviceCode': { | ||
tokenCredential = new identity_1.DeviceCodeCredential({ | ||
...interactiveCredentialOptions, | ||
userPromptCallback: (deviceCodeInfo) => { | ||
terminal_1.PrintUtilities.printMessageInBox(deviceCodeInfo.message, terminal); | ||
} | ||
}); | ||
break; | ||
} | ||
default: { | ||
throw new Error(`Unsupported login flow: ${loginFlow}`); | ||
} | ||
} | ||
const knownCredentialTypes = { | ||
DeviceCode: class extends identity_1.DeviceCodeCredential { | ||
new(credentialOptions) { | ||
return new identity_1.DeviceCodeCredential({ | ||
...deviceCodeCredentialOptions, | ||
...credentialOptions | ||
}); | ||
} | ||
}, | ||
InteractiveBrowser: class extends identity_1.InteractiveBrowserCredential { | ||
new(credentialOptions) { | ||
return new identity_1.InteractiveBrowserCredential({ ...interactiveCredentialOptions, ...credentialOptions }); | ||
} | ||
}, | ||
AdoCodespacesAuth: AdoCodespacesAuthCredential_1.AdoCodespacesAuthCredential, | ||
VisualStudioCode: identity_1.VisualStudioCodeCredential, | ||
AzureCli: identity_1.AzureCliCredential, | ||
AzureDeveloperCli: identity_1.AzureDeveloperCliCredential, | ||
AzurePowerShell: identity_1.AzurePowerShellCredential | ||
}; | ||
const credentials = Array.from(priority, (credType) => new knownCredentialTypes[credType](options)); | ||
const tokenCredential = new identity_1.ChainedTokenCredential(...credentials); | ||
try { | ||
@@ -155,10 +174,3 @@ return await this._getCredentialFromTokenAsync(terminal, tokenCredential, credentialsCache); | ||
terminal.writeVerbose(`Failed to get credentials with ${loginFlow}: ${error}`); | ||
const fallbackFlow = this._failoverOrder[loginFlow]; | ||
if (fallbackFlow) { | ||
terminal.writeVerbose(`Falling back to ${fallbackFlow} login flow`); | ||
return this._getCredentialAsync(terminal, fallbackFlow, credentialsCache); | ||
} | ||
else { | ||
throw error; | ||
} | ||
throw error; | ||
} | ||
@@ -165,0 +177,0 @@ } |
@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard. | ||
"packageName": "@microsoft/api-extractor", | ||
"packageVersion": "7.52.2" | ||
"packageVersion": "7.52.3" | ||
} | ||
] | ||
} |
{ | ||
"name": "@rushstack/rush-azure-storage-build-cache-plugin", | ||
"version": "5.151.0", | ||
"version": "5.152.0", | ||
"description": "Rush plugin for Azure storage cloud build cache", | ||
@@ -17,10 +17,10 @@ "repository": { | ||
"@azure/storage-blob": "~12.26.0", | ||
"@rushstack/rush-sdk": "5.151.0", | ||
"@rushstack/node-core-library": "5.13.0", | ||
"@rushstack/rush-sdk": "5.152.0", | ||
"@rushstack/terminal": "0.15.2" | ||
}, | ||
"devDependencies": { | ||
"@microsoft/rush-lib": "5.151.0", | ||
"local-node-rig": "1.0.0", | ||
"@rushstack/heft": "0.71.1" | ||
"@microsoft/rush-lib": "5.152.0", | ||
"@rushstack/heft": "0.71.2", | ||
"local-node-rig": "1.0.0" | ||
}, | ||
@@ -27,0 +27,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
118190
3.74%1164
3.01%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
Updated