const getOAuthToken = function()

in src/msha/auth/routes/auth-login-provider-callback.ts [143:214]


const getOAuthToken = function (authProvider: string, codeValue: string, authConfigs: Record<string, string>) {
  const redirectUri = `${SWA_CLI_APP_PROTOCOL}://${DEFAULT_CONFIG.host}:${DEFAULT_CONFIG.port}`;
  let tenantId;

  if (!Object.keys(CUSTOM_AUTH_TOKEN_ENDPOINT_MAPPING).includes(authProvider)) {
    return null;
  }

  if (authProvider === "aad") {
    tenantId = authConfigs?.openIdIssuer.split("/")[3];
  }

  const queryString: Record<string, string> = {
    code: codeValue,
    grant_type: "authorization_code",
    redirect_uri: `${redirectUri}/.auth/login/${authProvider}/callback`,
  };

  if (authProvider !== "twitter") {
    queryString.client_id = authConfigs?.clientIdSettingName || authConfigs?.appIdSettingName;
    queryString.client_secret = authConfigs?.clientSecretSettingName || authConfigs?.appSecretSettingName;
  } else {
    queryString.code_verifier = "challenge";
  }

  const data = querystring.stringify(queryString);

  let tokenPath = CUSTOM_AUTH_TOKEN_ENDPOINT_MAPPING?.[authProvider]?.path;
  if (authProvider === "aad" && tenantId !== undefined) {
    tokenPath = tokenPath.replace("tenantId", tenantId);
  }

  const headers: Record<string, string | number> = {
    "Content-Type": "application/x-www-form-urlencoded",
    "Content-Length": Buffer.byteLength(data),
  };

  if (authProvider === "twitter") {
    const keySecretString = `${authConfigs?.consumerKeySettingName}:${authConfigs?.consumerSecretSettingName}`;
    const encryptedCredentials = Buffer.from(keySecretString).toString("base64");
    headers.Authorization = `Basic ${encryptedCredentials}`;
  }

  const options = {
    host: CUSTOM_AUTH_TOKEN_ENDPOINT_MAPPING?.[authProvider]?.host,
    path: tokenPath,
    method: "POST",
    headers: headers,
  };

  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      res.setEncoding("utf8");
      let responseBody = "";

      res.on("data", (chunk) => {
        responseBody += chunk;
      });

      res.on("end", () => {
        resolve(responseBody);
      });
    });

    req.on("error", (err) => {
      reject(err);
    });

    req.write(data);
    req.end();
  });
};