{"version":3,"sources":["../src/index.ts","../src/authenticators/MsAuthenticator.ts"],"sourcesContent":["export * from './authenticators'\nexport * from './types'\n","import {\n  AuthenticationResult,\n  ConfidentialClientApplication,\n  Configuration,\n  LogLevel,\n  NodeAuthOptions,\n  PublicClientApplication,\n  UsernamePasswordRequest,\n} from '@azure/msal-node'\nimport { fetch } from 'cross-fetch'\nimport { IMSClientCredentialAuthInfo, IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index'\n\nimport hash from 'object-hash'\n\nconst EU = 'EU'\n\nconst HTTP_METHOD_GET = 'GET'\n\n// Event though there are many regions, MS has only 2 DID identity host names (EU and NON_EU)\n// https://docs.microsoft.com/en-us/azure/active-directory/verifiable-credentials/whats-new#are-there-any-changes-to-the-way-that-we-use-the-request-api-as-a-result-of-this-move\nexport const MS_DID_ENDPOINT_NON_EU = 'https://beta.did.msidentity.com/v1.0/'\nexport const MS_DID_ENDPOINT_EU = 'https://beta.eu.did.msidentity.com/v1.0/'\nconst MS_LOGIN_PREFIX = 'https://login.microsoftonline.com/'\nconst MS_LOGIN_OPENID_CONFIG_POSTFIX = '/v2.0/.well-known/openid-configuration'\nconst MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE = '3db474b9-6a0c-4840-96ac-1fceb342124f/.default'\n\nconst ERROR_CREDENTIAL_MANIFEST_REGION = `Error in config file. CredentialManifest URL configured for wrong tenant region. Should start with:`\nconst ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT = 'Could not acquire verifiableCredentials to access your Azure Key Vault:\\n'\nconst ERROR_FAILED_AUTHENTICATION = 'failed to authenticate: '\n\n// todo: This is a pretty heavy operation. Getting all the OIDC discovery data from a fetch only to return the region. Probably wise to add some caching and refactor so we can do more with the other OIDC info as well\nexport async function getMSOpenIDClientRegion(azTenantId: string): Promise<string> {\n  return fetch(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET })\n    .then((res) => res.json())\n    .then(async (resp) => {\n      return resp.tenant_region_scope ?? EU\n    })\n}\n\nexport async function getEntraDIDEndpoint(opts: { region?: string; azTenantId: string }) {\n  const region = opts?.region ?? (await getMSOpenIDClientRegion(opts.azTenantId))\n  return region === EU ? MS_DID_ENDPOINT_EU : MS_DID_ENDPOINT_NON_EU\n}\n\nexport async function assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise<string> {\n  const msDIDEndpoint = await getEntraDIDEndpoint(authenticationArgs)\n  // Check that the Credential Manifest URL is in the same tenant Region and throw an error if it's not\n  if (!authenticationArgs.credentialManifestUrl?.startsWith(msDIDEndpoint)) {\n    throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msDIDEndpoint + `. value: ${authenticationArgs.credentialManifestUrl}`)\n  }\n  return msDIDEndpoint\n}\n\n/**\n * necessary fields are:\n *   azClientId: clientId of the application you're trying to login\n *   azClientSecret: secret of the application you're trying to login\n *   azTenantId: your MS Azure tenantId\n * optional fields:\n *   credentialManifest: address of your credential manifest. usually in following format:\n *    https://beta.eu.did.msidentity.com/v1.0/<tenant_id>/verifiableCredential/contracts/<verifiable_credential_schema>\n * @param authenticationArgs\n * @constructor\n */\nexport async function getMSClientCredentialAccessToken(\n  authenticationArgs: IMsAuthenticationClientCredentialArgs,\n  opts?: {\n    confidentialClient?: ConfidentialClientApplication\n  },\n): Promise<AuthenticationResult> {\n  const confidentialClient =\n    opts?.confidentialClient ?? (await newMSClientCredentialAuthenticator(authenticationArgs).then((cca) => cca.confidentialClient))\n  if (!confidentialClient) {\n    throw Error('No Credential Client Authenticator could be constructed')\n  }\n  if (authenticationArgs?.credentialManifestUrl) {\n    await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs)\n  }\n\n  const msalClientCredentialRequest = {\n    scopes: authenticationArgs.scopes ?? (authenticationArgs?.credentialManifestUrl ? [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE] : []),\n    skipCache: authenticationArgs.skipCache ?? false,\n  }\n\n  // get the Access Token\n  try {\n    const result = await confidentialClient.acquireTokenByClientCredential(msalClientCredentialRequest)\n    if (result) {\n      return result\n    }\n  } catch (err) {\n    throw {\n      error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT + err,\n    }\n  }\n  throw {\n    error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT,\n  }\n}\n\nexport async function newMSClientCredentialAuthenticator(\n  authenticationArgs: IMsAuthenticationClientCredentialArgs,\n): Promise<IMSClientCredentialAuthInfo> {\n  const didEndpoint = authenticationArgs?.credentialManifestUrl\n    ? await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs)\n    : undefined\n  const auth = authOptions(authenticationArgs)\n  const id = hash(auth)\n  const msalConfig: Configuration = {\n    auth,\n    system: {\n      loggerOptions: {\n        piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false,\n        logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : LogLevel.Verbose,\n      },\n    },\n  }\n  const confidentialClientApp = new ConfidentialClientApplication(msalConfig)\n\n  return { confidentialClient: confidentialClientApp, msalConfig, authenticationArgs, didEndpoint, id }\n}\n\n/**\n * Logs in with provided authenticationArgs and returns access token\n * @param authenticationArgs\n * @constructor\n */\nexport async function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthenticationUsernamePasswordArgs): Promise<string> {\n  const msalConfig = {\n    auth: authOptions(authenticationArgs),\n  }\n  const pca = new PublicClientApplication(msalConfig)\n  return await pca\n    .acquireTokenByUsernamePassword(authenticationArgs as UsernamePasswordRequest)\n    .then((response: any) => {\n      return response\n    })\n    .catch((error: any) => {\n      throw new Error(ERROR_FAILED_AUTHENTICATION + error)\n    })\n}\n\nfunction authOptions(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): NodeAuthOptions {\n  return {\n    clientId: authenticationArgs.azClientId,\n    authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId,\n    ...(authenticationArgs && 'azClientSecret' in authenticationArgs && { clientSecret: authenticationArgs.azClientSecret }),\n  }\n}\n\nexport function determineMSAuthId(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): string {\n  return hash(authOptions(authenticationArgs))\n}\n"],"mappings":"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","names":["EU","HTTP_METHOD_GET","MS_DID_ENDPOINT_NON_EU","MS_DID_ENDPOINT_EU","MS_LOGIN_PREFIX","MS_LOGIN_OPENID_CONFIG_POSTFIX","MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE","ERROR_CREDENTIAL_MANIFEST_REGION","ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT","ERROR_FAILED_AUTHENTICATION","getMSOpenIDClientRegion","azTenantId","fetch","method","then","res","json","resp","tenant_region_scope","getEntraDIDEndpoint","opts","region","assertEntraCredentialManifestUrlInCorrectRegion","authenticationArgs","msDIDEndpoint","credentialManifestUrl","startsWith","Error","getMSClientCredentialAccessToken","confidentialClient","newMSClientCredentialAuthenticator","cca","msalClientCredentialRequest","scopes","skipCache","result","acquireTokenByClientCredential","err","error","didEndpoint","undefined","auth","authOptions","id","hash","msalConfig","system","loggerOptions","piiLoggingEnabled","logLevel","LogLevel","Verbose","confidentialClientApp","ConfidentialClientApplication","UsernamePasswordAuthenticator","pca","PublicClientApplication","acquireTokenByUsernamePassword","response","catch","clientId","azClientId","authority","clientSecret","azClientSecret","determineMSAuthId"]}