Add configuration files and update imports for sk-az-tools integration
This commit is contained in:
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"node_modules": true
|
||||||
|
}
|
||||||
|
}
|
||||||
16
azure-node-playground.code-workspace
Normal file
16
azure-node-playground.code-workspace
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../sk-az-tools"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../docs-harvester-node"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env node
|
#! /usr/bin/env node
|
||||||
import { loginInteractive } from "../src/azure.js";
|
import { loginInteractive } from "sk-az-tools/azure";
|
||||||
import { Client } from "@microsoft/microsoft-graph-client";
|
import { Client } from "@microsoft/microsoft-graph-client";
|
||||||
|
|
||||||
const scopes = [
|
const scopes = [
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { parseArgs } from "util";
|
import { parseArgs } from "util";
|
||||||
import { getCredential } from "../src/azure.js";
|
import { getCredential } from "sk-az-tools/azure";
|
||||||
|
|
||||||
let config = {};
|
let config = {};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const args = parseArgs({
|
|||||||
"app-name": { type: "string", short: "a" },
|
"app-name": { type: "string", short: "a" },
|
||||||
help: { type: "boolean", short: "h" },
|
help: { type: "boolean", short: "h" },
|
||||||
"generate-client-secret": { type: "boolean", short: "s" },
|
"generate-client-secret": { type: "boolean", short: "s" },
|
||||||
"config": { type: "string", short: "c", default: "config.js" },
|
"config": { type: "string", short: "c", default: "config.json" },
|
||||||
"write-config": { type: "string", short: "w" },
|
"write-config": { type: "string", short: "w" },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
45
package-lock.json
generated
45
package-lock.json
generated
@@ -10,7 +10,28 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/identity": "^4.13.0",
|
"@azure/identity": "^4.13.0",
|
||||||
"@azure/msal-node": "^5.0.2",
|
"@azure/msal-node": "^5.0.2",
|
||||||
"@microsoft/microsoft-graph-client": "^3.0.7"
|
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||||
|
"docs-harvester": "file:../docs-harvester-node",
|
||||||
|
"sk-az-tools": "file:../sk-az-tools"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=24.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"../docs-harvester-node": {
|
||||||
|
"name": "docs-harvester",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"bin": {
|
||||||
|
"docs-harvester": "src/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"../sk-az-tools": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/identity": "^4.13.0",
|
||||||
|
"@azure/msal-node": "^5.0.3",
|
||||||
|
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||||
|
"azure-devops-node-api": "^15.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24.0.0"
|
"node": ">=24.0.0"
|
||||||
@@ -175,12 +196,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/msal-node": {
|
"node_modules/@azure/msal-node": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.0.3.tgz",
|
||||||
"integrity": "sha512-3tHeJghckgpTX98TowJoXOjKGuds0L+FKfeHJtoZFl2xvwE6RF65shZJzMQ5EQZWXzh3sE1i9gE+m3aRMachjA==",
|
"integrity": "sha512-DTiu9SEblUVbgiuXWtCXFS2OoIVZPNbPFfK7AVhsWCD4bCHqvHcnDz9uCxk5wnUYJX9Ik0KxjGDFLwH9/lrE+w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/msal-common": "16.0.2",
|
"@azure/msal-common": "16.0.3",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"uuid": "^8.3.0"
|
"uuid": "^8.3.0"
|
||||||
},
|
},
|
||||||
@@ -189,9 +210,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/msal-node/node_modules/@azure/msal-common": {
|
"node_modules/@azure/msal-node/node_modules/@azure/msal-common": {
|
||||||
"version": "16.0.2",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.0.3.tgz",
|
||||||
"integrity": "sha512-ZJ/UR7lyqIntURrIJCyvScwJFanM9QhJYcJCheB21jZofGKpP9QxWgvADANo7UkresHKzV+6YwoeZYP7P7HvUg==",
|
"integrity": "sha512-3aedNnM0CHVuVZ+BqembdZWgovqe96BJ4YxGoIK0+qhoBZQsAhfwXdhjen72K94pkSQHtzlJ7fAq6w7knFZsng==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
@@ -334,6 +355,10 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/docs-harvester": {
|
||||||
|
"resolved": "../docs-harvester-node",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/ecdsa-sig-formatter": {
|
"node_modules/ecdsa-sig-formatter": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
@@ -570,6 +595,10 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sk-az-tools": {
|
||||||
|
"resolved": "../sk-az-tools",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/identity": "^4.13.0",
|
"@azure/identity": "^4.13.0",
|
||||||
"@azure/msal-node": "^5.0.2",
|
"@azure/msal-node": "^5.0.2",
|
||||||
"@microsoft/microsoft-graph-client": "^3.0.7"
|
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||||
|
"docs-harvester": "file:../docs-harvester-node",
|
||||||
|
"sk-az-tools": "file:../sk-az-tools"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/prototypes/devops.mjs
Executable file
27
src/prototypes/devops.mjs
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// The current Node.js Azure DevOps client uses old deprecated APIs.
|
||||||
|
|
||||||
|
import { config } from "../../public-config.js";
|
||||||
|
import { getDevOpsClients } from "sk-az-tools/devops";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const { coreClient, gitClient } = await getDevOpsClients(
|
||||||
|
'https://dev.azure.com/skoszewski',
|
||||||
|
config.tenantId,
|
||||||
|
config.clientId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const orgUrl = 'https://dev.azure.com/skoszewski';
|
||||||
|
const projects = await coreClient.getProjects();
|
||||||
|
console.log(`Projects in organization '${orgUrl}':`);
|
||||||
|
projects.forEach((project) => {
|
||||||
|
console.log(`- ${project.name} (ID: ${project.id})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await main().catch((e) => {
|
||||||
|
console.error("Error in main:", e);
|
||||||
|
console.error(e.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -1,42 +1,27 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { loginInteractive } from "sk-az-tools/azure";
|
import { config } from "../../public-config.js";
|
||||||
import { config } from "../public-config.js";
|
import { getGraphClient } from "sk-az-tools/graph";
|
||||||
import { createHash } from "crypto";
|
|
||||||
import { Client } from "@microsoft/microsoft-graph-client";
|
|
||||||
|
|
||||||
// const scopes = ["https://management.azure.com/.default"];
|
async function main() {
|
||||||
const scopes = ["https://graph.microsoft.com/.default"];
|
const { client } = await getGraphClient({
|
||||||
|
|
||||||
let token;
|
|
||||||
|
|
||||||
try {
|
|
||||||
token = await loginInteractive({
|
|
||||||
tenantId: config.tenantId,
|
tenantId: config.tenantId,
|
||||||
clientId: config.clientId,
|
clientId: config.clientId,
|
||||||
scopes,
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Login failed:", e);
|
|
||||||
console.error(e.stack);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Access token acquired.");
|
|
||||||
|
|
||||||
// Print SHA-256 hash of the access token for verification purposes
|
|
||||||
const hash = createHash("sha256").update(token.accessToken).digest("hex");
|
|
||||||
console.log("SHA-256 hash of access token:", hash);
|
|
||||||
console.log("Token expires on:", token.expiresOn);
|
|
||||||
|
|
||||||
const client = Client.init({
|
|
||||||
authProvider: (done) => {
|
|
||||||
done(null, token.accessToken);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Let's find the application by its display name
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
|
// First get info about me.
|
||||||
|
result = await client.api("/me").get();
|
||||||
|
console.log("Logged in as:");
|
||||||
|
console.log(` Display Name: ${result.displayName}`);
|
||||||
|
console.log(` User Principal Name: ${result.userPrincipalName}`);
|
||||||
|
console.log(` ID: ${result.id}`);
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
// Now let's find the application by its display name
|
||||||
|
|
||||||
result = await client
|
result = await client
|
||||||
.api("/applications")
|
.api("/applications")
|
||||||
.filter("displayName eq 'Azure Node Playground Public'")
|
.filter("displayName eq 'Azure Node Playground Public'")
|
||||||
@@ -63,9 +48,7 @@ result = await client
|
|||||||
.get();
|
.get();
|
||||||
|
|
||||||
const sps = result.value ?? [];
|
const sps = result.value ?? [];
|
||||||
console.log(
|
console.log(`Service principals for the application (${sps.length}):`);
|
||||||
`Service principals for the application (${sps.length}):`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sps.length === 0) {
|
if (sps.length === 0) {
|
||||||
console.error(
|
console.error(
|
||||||
@@ -80,3 +63,10 @@ sps.forEach((sp, index) => {
|
|||||||
console.log(` App ID: ${sp.appId}`);
|
console.log(` App ID: ${sp.appId}`);
|
||||||
console.log(` Display Name: ${sp.displayName}`);
|
console.log(` Display Name: ${sp.displayName}`);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await main().catch((e) => {
|
||||||
|
console.error("Error in main:", e);
|
||||||
|
console.error(e.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user