@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorMetaMTAPostmarkReceiveController
4 extends PhabricatorMetaMTAController {
5
6 public function shouldRequireLogin() {
7 return false;
8 }
9
10 /**
11 * @phutil-external-symbol class PhabricatorStartup
12 */
13 public function handleRequest(AphrontRequest $request) {
14 // Don't process requests if we don't have a configured Postmark adapter.
15 $mailers = PhabricatorMetaMTAMail::newMailers(
16 array(
17 'inbound' => true,
18 'types' => array(
19 PhabricatorMailPostmarkAdapter::ADAPTERTYPE,
20 ),
21 ));
22 if (!$mailers) {
23 return new Aphront404Response();
24 }
25
26 $remote_address = $request->getRemoteAddress();
27 $any_remote_match = false;
28 foreach ($mailers as $mailer) {
29 $inbound_addresses = $mailer->getOption('inbound-addresses');
30 $cidr_list = PhutilCIDRList::newList($inbound_addresses);
31 if ($cidr_list->containsAddress($remote_address)) {
32 $any_remote_match = true;
33 break;
34 }
35 }
36
37 if (!$any_remote_match) {
38 return new Aphront400Response();
39 }
40
41 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
42 $raw_input = PhabricatorStartup::getRawInput();
43
44 try {
45 $data = phutil_json_decode($raw_input);
46 } catch (Exception $ex) {
47 return new Aphront400Response();
48 }
49
50 $raw_headers = array();
51 $header_items = idx($data, 'Headers', array());
52 foreach ($header_items as $header_item) {
53 $name = idx($header_item, 'Name');
54 $value = idx($header_item, 'Value');
55 $raw_headers[$name] = $value;
56 }
57
58 $headers = array(
59 'to' => idx($data, 'To'),
60 'from' => idx($data, 'From'),
61 'cc' => idx($data, 'Cc'),
62 'subject' => idx($data, 'Subject'),
63 ) + $raw_headers;
64
65
66 $received = id(new PhabricatorMetaMTAReceivedMail())
67 ->setHeaders($headers)
68 ->setBodies(
69 array(
70 'text' => idx($data, 'TextBody'),
71 'html' => idx($data, 'HtmlBody'),
72 ));
73
74 $file_phids = array();
75 $attachments = idx($data, 'Attachments', array());
76 foreach ($attachments as $attachment) {
77 $file_data = idx($attachment, 'Content');
78 $file_data = base64_decode($file_data);
79
80 try {
81 $file = PhabricatorFile::newFromFileData(
82 $file_data,
83 array(
84 'name' => idx($attachment, 'Name'),
85 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
86 ));
87 $file_phids[] = $file->getPHID();
88 } catch (Exception $ex) {
89 phlog($ex);
90 }
91 }
92 $received->setAttachments($file_phids);
93
94 try {
95 $received->save();
96 $received->processReceivedMail();
97 } catch (Exception $ex) {
98 phlog($ex);
99 }
100
101 return id(new AphrontWebpageResponse())
102 ->setContent(pht("Got it! Thanks, Postmark!\n"));
103 }
104
105}