Authentication refactoring.
This commit is contained in:
@@ -1 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -1,48 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getAccessToken } from "../../azure/index.ts";
|
||||
import { getDevOpsApiToken } from "../../devops/index.ts";
|
||||
import { loadAuthConfig } from "../../index.ts";
|
||||
|
||||
type GetTokenOptions = {
|
||||
type?: string;
|
||||
};
|
||||
import { RESOURCE_SCOPE_BY_NAME, ResourceName, supportedResourceNames, getTokenCredential } from "../../azure/index.ts";
|
||||
|
||||
export async function runGetTokenCommand(
|
||||
options: GetTokenOptions,
|
||||
): Promise<unknown> {
|
||||
const tokenType = (options.type ?? "").toString().trim().toLowerCase();
|
||||
if (!tokenType) {
|
||||
throw new Error(
|
||||
"--type is required for get-token (allowed: azurerm, devops)",
|
||||
);
|
||||
type: ResourceName,
|
||||
): Promise<void> {
|
||||
if (!type || !supportedResourceNames().includes(type)) {
|
||||
throw new Error(`Token type is required for get-token (allowed: ${supportedResourceNames().join(", ")})`);
|
||||
}
|
||||
|
||||
const config = await loadAuthConfig("public-config");
|
||||
const credential = await getTokenCredential();
|
||||
|
||||
if (tokenType === "azurerm") {
|
||||
const accessToken = await getAccessToken(config.tenantId, config.clientId, ["arm"]);
|
||||
|
||||
if (!accessToken) {
|
||||
throw new Error("Failed to obtain AzureRM token");
|
||||
}
|
||||
|
||||
return {
|
||||
tokenType,
|
||||
accessToken,
|
||||
};
|
||||
const accessToken = await credential.getToken(RESOURCE_SCOPE_BY_NAME[type]);
|
||||
if (!accessToken) {
|
||||
throw new Error("Failed to obtain access token.");
|
||||
}
|
||||
|
||||
if (tokenType === "devops") {
|
||||
const accessToken = await getDevOpsApiToken(
|
||||
config.tenantId,
|
||||
config.clientId,
|
||||
);
|
||||
return {
|
||||
tokenType,
|
||||
accessToken,
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Invalid --type '${options.type}'. Allowed: azurerm, devops`);
|
||||
// Output only the token string for easy consumption in scripts
|
||||
console.log(accessToken.token);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { login } from "../../azure/index.ts";
|
||||
import type { ResourceName } from "../../azure/index.ts";
|
||||
import { loadAuthConfig } from "../../index.ts";
|
||||
|
||||
type LoginOptions = {
|
||||
resources?: string;
|
||||
useDeviceCode?: boolean;
|
||||
noBrowser?: boolean;
|
||||
browser?: string;
|
||||
browserName?: string;
|
||||
browserProfile?: string;
|
||||
};
|
||||
|
||||
export async function runLoginCommand(options: LoginOptions): Promise<unknown> {
|
||||
type LoginResult = {
|
||||
accountUpn: string | null;
|
||||
resources: Array<{ resource: string; expiresOn: string | null }>;
|
||||
flow: "device-code" | "interactive";
|
||||
browserLaunchAttempted: boolean;
|
||||
};
|
||||
|
||||
export async function runLoginCommand(resources: ResourceName[], options: LoginOptions): Promise<void> {
|
||||
const config = await loadAuthConfig("public-config");
|
||||
return login(
|
||||
|
||||
const result = await login(
|
||||
config.tenantId,
|
||||
config.clientId,
|
||||
options.resources,
|
||||
resources,
|
||||
Boolean(options.useDeviceCode),
|
||||
Boolean(options.noBrowser),
|
||||
options.browser,
|
||||
options.browserName,
|
||||
options.browserProfile,
|
||||
);
|
||||
) as LoginResult;
|
||||
|
||||
console.log(`Logged in as ${result.accountUpn ?? "<unknown>"} using ${result.flow} flow for resources: ${resources.join(",")}`);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,28 @@ type LogoutOptions = {
|
||||
all?: boolean;
|
||||
};
|
||||
|
||||
export async function runLogoutCommand(options: LogoutOptions): Promise<unknown> {
|
||||
type LogoutResult = {
|
||||
clearedAll: boolean;
|
||||
signedOut: string[];
|
||||
};
|
||||
|
||||
export async function runLogoutCommand(options: LogoutOptions): Promise<void> {
|
||||
const config = await loadAuthConfig("public-config");
|
||||
return logout(config.tenantId, config.clientId, Boolean(options.all));
|
||||
const result = await logout(config.tenantId, config.clientId, Boolean(options.all)) as LogoutResult;
|
||||
|
||||
if (result.signedOut.length === 0) {
|
||||
console.log(
|
||||
result.clearedAll
|
||||
? "Cleared all cached accounts."
|
||||
: "No active account to sign out.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.clearedAll) {
|
||||
console.log(`Cleared all cached accounts: ${result.signedOut.join(", ")}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Signed out: ${result.signedOut.join(", ")}`);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getAccessToken } from "../../azure/index.ts";
|
||||
import { getDevOpsApiToken } from "../../devops/index.ts";
|
||||
import { loadAuthConfig } from "../../index.ts";
|
||||
import { RESOURCE_SCOPE_BY_NAME, ResourceName, getTokenCredential } from "../../azure/index.ts";
|
||||
|
||||
function parseHeaderLine(
|
||||
header?: string,
|
||||
@@ -35,24 +33,39 @@ function hasAuthorizationHeader(headers: Headers): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolveResourceNameForHost(host: string): ResourceName | null {
|
||||
switch (host) {
|
||||
case "management.azure.com":
|
||||
return "azurerm";
|
||||
case "dev.azure.com":
|
||||
return "devops";
|
||||
case "graph.microsoft.com":
|
||||
return "graph";
|
||||
case "cognitiveservices.azure.com":
|
||||
return "openai";
|
||||
default:
|
||||
if (host.endsWith(".openai.azure.com")) {
|
||||
return "openai";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function getAutoAuthorizationHeader(url: URL): Promise<string | null> {
|
||||
const host = url.hostname.toLowerCase();
|
||||
if (host !== "management.azure.com" && host !== "dev.azure.com") {
|
||||
const resourceName = resolveResourceNameForHost(host);
|
||||
if (!resourceName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const config = await loadAuthConfig("public-config");
|
||||
const credential = await getTokenCredential();
|
||||
|
||||
if (host === "management.azure.com") {
|
||||
const accessToken = await getAccessToken(config.tenantId, config.clientId, ["arm"]);
|
||||
if (!accessToken) {
|
||||
throw new Error("Failed to obtain AzureRM token");
|
||||
}
|
||||
return `Bearer ${accessToken}`;
|
||||
const accessToken = await credential.getToken(RESOURCE_SCOPE_BY_NAME[resourceName]);
|
||||
if (!accessToken?.token) {
|
||||
throw new Error(`Failed to obtain ${resourceName} token`);
|
||||
}
|
||||
|
||||
const accessToken = await getDevOpsApiToken(config.tenantId, config.clientId);
|
||||
return `Bearer ${accessToken}`;
|
||||
return `Bearer ${accessToken.token}`;
|
||||
}
|
||||
|
||||
type httpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
||||
|
||||
6
src/cli/commands/test-command.ts
Normal file
6
src/cli/commands/test-command.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Hidden test command for development purposes
|
||||
export async function runTestCommand(): Promise<void> {
|
||||
console.log("Test command executed.");
|
||||
}
|
||||
Reference in New Issue
Block a user