You are here

function reroute_email_check in Reroute Email 2.x

Same name and namespace in other branches
  1. 8 reroute_email.module \reroute_email_check()
  2. 7 reroute_email.module \reroute_email_check()

Helper function to determine a need to reroute.

Parameters

array &$message: A message array, as described in hook_mail_alter().

Return value

bool Return TRUE if should be rerouted, FALSE otherwise.

1 call to reroute_email_check()
reroute_email_mail_alter in ./reroute_email.module
Implements hook_mail_alter().

File

./reroute_email.module, line 207
Intercepts all outgoing emails to be rerouted to a configurable destination.

Code

function reroute_email_check(array &$message) {

  // Disable rerouting according to admin settings.
  $config = \Drupal::config('reroute_email.settings');
  if (empty($config
    ->get(REROUTE_EMAIL_ENABLE))) {
    return FALSE;
  }

  // Check configured mail keys filters.
  $keys = reroute_email_split_string($config
    ->get(REROUTE_EMAIL_MAILKEYS, ''));
  if (!empty($keys) && !(in_array($message['id'], $keys, TRUE) || in_array($message['module'], $keys, TRUE))) {
    $message['headers']['X-Reroute-Status'] = 'MAILKEY-IGNORED';
    return FALSE;
  }

  // Split addresses into arrays.
  $original_addresses = reroute_email_extract_addresses($message['to']);
  $allowlisted_addresses = reroute_email_split_string($config
    ->get(REROUTE_EMAIL_ALLOWLIST));
  $allowlisted_domains = [];

  // Split allowed domains from allowed addresses.
  foreach ($allowlisted_addresses as $key => $email) {
    if (preg_match('/^\\*@(.*)$/', $email, $matches)) {

      // The part after the @ sign is the domain and according to RFC 1035,
      // section 3.1: "Name servers and resolvers must compare [domains] in a
      // case-insensitive manner".
      $domain = mb_strtolower($matches[1]);
      $allowlisted_domains[$domain] = $domain;
      unset($allowlisted_addresses[$key]);
    }
  }

  // Compare original addresses with the allow list.
  $invalid = 0;
  foreach ($original_addresses as $email) {

    // Just ignore all invalid email addresses.
    if (\Drupal::service('email.validator')
      ->isValid($email) === FALSE) {
      $invalid++;
      continue;
    }

    // Check emails and domains in the allowed list.
    $domain = mb_strtolower((new EmailParser(new EmailLexer()))
      ->parse($email)['domain']);
    if (in_array($email, $allowlisted_addresses, TRUE) || in_array($domain, $allowlisted_domains, TRUE)) {
      continue;
    }

    // No need to continue if at least one address should be rerouted.
    $message['headers']['X-Reroute-Status'] = 'REROUTED';
    return TRUE;
  }

  // Reroute if all addresses are invalid.
  if (count($original_addresses) === $invalid) {
    $message['headers']['X-Reroute-Status'] = 'INVALID-ADDRESSES';
    return TRUE;
  }

  // All email addresses are in the allowed list.
  $message['headers']['X-Reroute-Status'] = 'ALLOWLISTED';
  return FALSE;
}