Repository: gatsbyjs/gatsby
File: packages/gatsby-source-drupal/src/gatsby-node.js (JavaScript)

Code before:
  disallowedLinkTypes = disallowedLinkTypes || [`self`, `describedby`]

  // Default concurrentFileRequests to `20`
  concurrentFileRequests = concurrentFileRequests || 20

  // Default skipFileDownloads to false.
  skipFileDownloads = skipFileDownloads || false

  // Determine what entities can be translated and what languages are enabled.
  let languageConfig = store.getState().status.plugins?.[`gatsby-source-drupal`]
    ?.languageConfig

  if (!languageConfig) {
    languageConfig = await fetchLanguageConfig({
      translation,
      baseUrl,
      apiBase,
      basicAuth,
      headers,
      params,
      reporter,
    })

    if (translation && !languageConfig.enabledLanguages.length) {
      reporter.warn(
        `The translation option is enabled but no enabled languages were retrieved from Drupal. Make sure your basicAuth credentials in the Gatsby config file are populated with a user that has the "administer languages" permission.`
      )
    }
  }

  setOptions({ languageConfig, ...getOptions() })

  setPluginStatus({ languageConfig })

  if (webhookBody && Object.keys(webhookBody).length) {
    const changesActivity = reporter.activityTimer(
      `loading Drupal content changes`,
      {
        parentSpan,
      }
    )
    changesActivity.start()

    try {
      const { secret, action, id, data } = webhookBody
      if (pluginOptions.secret && pluginOptions.secret !== secret) {
        reporter.warn(
          `The secret in this request did not match your plugin options secret.`
        )
        changesActivity.end()
        return

Review comment (security):
It's important to note that because of this automatic language resolution devs are required to either:
- add `administer languages` permission to the anonymous user role which is not recommended
- add `basicAuth` parameter on the Gatsby side for a Drupal user who has a role with `administer languages`

Both of these are suboptimal but make the plugin a bit more plug and play. We could instead allow the dev a way to provide a list of languages and entity types for translation. What do you think? @KyleAMathews

Dropping the automatic language settings resolution would mean less code too which is always nice :)

Code after:
  disallowedLinkTypes = disallowedLinkTypes || [`self`, `describedby`]

  // Default concurrentFileRequests to `20`
  concurrentFileRequests = concurrentFileRequests || 20

  // Default skipFileDownloads to false.
  skipFileDownloads = skipFileDownloads || false

  if (webhookBody && Object.keys(webhookBody).length) {
    const changesActivity = reporter.activityTimer(
      `loading Drupal content changes`,
      {
        parentSpan,
      }
    )
    changesActivity.start()

    try {
      const { secret, action, id, data } = webhookBody
      if (pluginOptions.secret && pluginOptions.secret !== secret) {
        reporter.warn(
          `The secret in this request did not match your plugin options secret.`
        )
        changesActivity.end()
        return
      }
      if (action === `delete`) {
        actions.deleteNode(getNode(createNodeId(id)))
        reporter.log(`Deleted node: ${id}`)
        changesActivity.end()
        return
      }

      let nodesToUpdate = data
      if (!Array.isArray(data)) {
        nodesToUpdate = [data]
      }

      for (const nodeToUpdate of nodesToUpdate) {
        await handleWebhookUpdate(
          {
            nodeToUpdate,
            actions,
            cache,
            createNodeId,
            createContentDigest,
            getCache,
            getNode,
            reporter,
            store,
            languageConfig,