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 { 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); } }, }); }