integratedhub/services/graphAuth.ts
2026-01-20 09:02:26 -06:00

63 lines
1.6 KiB
TypeScript
Executable File

import { ConfidentialClientApplication, type Configuration } from "msal-node";
import { Client } from "@GraphClient";
import "@IsomorphicFetch";
let app: ConfidentialClientApplication | null = null;
function getMsalApp() {
if (app) return app;
const tenantId = Deno.env.get("TENANT_ID")!;
const clientId = Deno.env.get("CLIENT_ID")!;
const clientSecret = Deno.env.get("CLIENT_SECRET")!;
const config: Configuration = {
auth: {
clientId,
authority: `https://login.microsoftonline.com/${tenantId}`,
clientSecret,
},
system: {
loggerOptions: { loggerCallback: () => {} },
},
};
app = new ConfidentialClientApplication(config);
return app;
}
export async function getToken(
scopes: string[],
userAssertion?: string,
): Promise<string> {
const msal = getMsalApp();
if (userAssertion) {
const result = await msal.acquireTokenOnBehalfOf({
scopes,
oboAssertion: userAssertion,
});
if (!result || !result.accessToken) throw new Error("No OBO access token");
return result.accessToken;
} else {
const result = await msal.acquireTokenByClientCredential({ scopes });
if (!result || !result.accessToken) {
throw new Error("No app-only access token");
}
return result.accessToken;
}
}
export function getGraphClient(userAssertion?: string) {
return Client.init({
authProvider: async (done) => {
try {
const token = await getToken(
["https://graph.microsoft.com/.default"],
userAssertion,
);
done(null, token);
} catch (e) {
done(e as Error, null as unknown as string);
}
},
});
}