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);
25 if (phutil_nonempty_string($prefix)) {
26 $prefix = $prefix.'+';
27 $len = strlen($prefix);
29 if (!strncasecmp($raw_address, $prefix, $len)) {
30 $raw_address = substr($raw_address, $len);
34 return id(clone $address)
35 ->setAddress($raw_address);
39 * Determine if two inbound email addresses are effectively identical.
41 * This method strips and normalizes addresses so that equivalent variations
42 * are correctly detected as identical. For example, these addresses are all
43 * considered to match one another:
45 * "Abraham Lincoln" <alincoln@example.com>
46 * alincoln@example.com
47 * <ALincoln@example.com>
48 * "Abraham" <phabricator+ALINCOLN@EXAMPLE.COM> # With configured prefix.
50 * @param PhutilEmailAddress Email address.
51 * @param PhutilEmailAddress Another email address.
52 * @return bool True if addresses are effectively the same address.
54 public static function matchAddresses(
55 PhutilEmailAddress
$u,
56 PhutilEmailAddress
$v) {
58 $u = self
::normalizeAddress($u);
59 $v = self
::normalizeAddress($v);
61 return ($u->getAddress() === $v->getAddress());
64 public static function isReservedAddress(PhutilEmailAddress
$address) {
65 $address = self
::normalizeAddress($address);
66 $local = $address->getLocalPart();
89 $reserved = array_fuse($reserved);
91 if (isset($reserved[$local])) {
95 $default_address = id(new PhabricatorMailEmailEngine())
96 ->newDefaultEmailAddress();
97 if (self
::matchAddresses($address, $default_address)) {
101 $void_address = id(new PhabricatorMailEmailEngine())
102 ->newVoidEmailAddress();
103 if (self
::matchAddresses($address, $void_address)) {
110 public static function isUserAddress(PhutilEmailAddress
$address) {
111 $user_email = id(new PhabricatorUserEmail())->loadOneWhere(
113 $address->getAddress());
115 return (bool)$user_email;