3 final class PhabricatorMailUtil
7 * Normalize an email address for comparison or lookup.
9 * Phabricator can be configured to prepend a prefix to all reply addresses,
10 * which can make forwarding rules easier to write. This method strips the
11 * prefix if it is present, and normalizes casing and whitespace.
13 * @param PhutilEmailAddress Email address.
14 * @return PhutilEmailAddress Normalized address.
16 public static function normalizeAddress(PhutilEmailAddress
$address) {
17 $raw_address = $address->getAddress();
18 $raw_address = phutil_utf8_strtolower($raw_address);
19 $raw_address = trim($raw_address);
21 // If a mailbox prefix is configured and present, strip it off.
22 $prefix_key = 'metamta.single-reply-handler-prefix';
23 $prefix = PhabricatorEnv
::getEnvConfig($prefix_key);
24 $len = strlen($prefix);
27 $prefix = $prefix.'+';
30 if (!strncasecmp($raw_address, $prefix, $len)) {
31 $raw_address = substr($raw_address, $len);
35 return id(clone $address)
36 ->setAddress($raw_address);
40 * Determine if two inbound email addresses are effectively identical.
42 * This method strips and normalizes addresses so that equivalent variations
43 * are correctly detected as identical. For example, these addresses are all
44 * considered to match one another:
46 * "Abraham Lincoln" <alincoln@example.com>
47 * alincoln@example.com
48 * <ALincoln@example.com>
49 * "Abraham" <phabricator+ALINCOLN@EXAMPLE.COM> # With configured prefix.
51 * @param PhutilEmailAddress Email address.
52 * @param PhutilEmailAddress Another email address.
53 * @return bool True if addresses are effectively the same address.
55 public static function matchAddresses(
56 PhutilEmailAddress
$u,
57 PhutilEmailAddress
$v) {
59 $u = self
::normalizeAddress($u);
60 $v = self
::normalizeAddress($v);
62 return ($u->getAddress() === $v->getAddress());
65 public static function isReservedAddress(PhutilEmailAddress
$address) {
66 $address = self
::normalizeAddress($address);
67 $local = $address->getLocalPart();
90 $reserved = array_fuse($reserved);
92 if (isset($reserved[$local])) {
96 $default_address = id(new PhabricatorMailEmailEngine())
97 ->newDefaultEmailAddress();
98 if (self
::matchAddresses($address, $default_address)) {
102 $void_address = id(new PhabricatorMailEmailEngine())
103 ->newVoidEmailAddress();
104 if (self
::matchAddresses($address, $void_address)) {
111 public static function isUserAddress(PhutilEmailAddress
$address) {
112 $user_email = id(new PhabricatorUserEmail())->loadOneWhere(
114 $address->getAddress());
116 return (bool)$user_email;