]> git.mxchange.org Git - friendica.git/blob - src/Module/Xrd.php
Move Activity/Namespaces defines to constants
[friendica.git] / src / Module / Xrd.php
1 <?php
2
3 namespace Friendica\Module;
4
5 use Friendica\BaseModule;
6 use Friendica\Core\Hook;
7 use Friendica\Database\DBA;
8 use Friendica\Core\Renderer;
9 use Friendica\Core\System;
10 use Friendica\Model\User;
11 use Friendica\Model\Photo;
12 use Friendica\Protocol\Activity\Namespaces;
13 use Friendica\Protocol\Salmon;
14 use Friendica\Util\Strings;
15
16 /**
17  * Prints responses to /.well-known/webfinger  or /xrd requests
18  */
19 class Xrd extends BaseModule
20 {
21         public static function rawContent()
22         {
23                 $app = self::getApp();
24
25                 // @TODO: Replace with parameter from router
26                 if ($app->argv[0] == 'xrd') {
27                         if (empty($_GET['uri'])) {
28                                 return;
29                         }
30
31                         $uri = urldecode(Strings::escapeTags(trim($_GET['uri'])));
32                         if (($_SERVER['HTTP_ACCEPT'] ?? '') == 'application/jrd+json') {
33                                 $mode = 'json';
34                         } else {
35                                 $mode = 'xml';
36                         }
37                 } else {
38                         if (empty($_GET['resource'])) {
39                                 return;
40                         }
41
42                         $uri = urldecode(Strings::escapeTags(trim($_GET['resource'])));
43                         if (($_SERVER['HTTP_ACCEPT'] ?? '') == 'application/xrd+xml') {
44                                 $mode = 'xml';
45                         } else {
46                                 $mode = 'json';
47                         }
48                 }
49
50                 if (substr($uri, 0, 4) === 'http') {
51                         $name = ltrim(basename($uri), '~');
52                 } else {
53                         $local = str_replace('acct:', '', $uri);
54                         if (substr($local, 0, 2) == '//') {
55                                 $local = substr($local, 2);
56                         }
57
58                         $name = substr($local, 0, strpos($local, '@'));
59                 }
60
61                 $user = User::getByNickname($name);
62
63                 if (empty($user)) {
64                         throw new \Friendica\Network\HTTPException\NotFoundException();
65                 }
66
67                 $owner = User::getOwnerDataById($user['uid']);
68
69                 $alias = str_replace('/profile/', '/~', $owner['url']);
70
71                 $avatar = Photo::selectFirst(['type'], ['uid' => $owner['uid'], 'profile' => true]);
72
73                 if (!DBA::isResult($avatar)) {
74                         $avatar = ['type' => 'image/jpeg'];
75                 }
76
77                 if ($mode == 'xml') {
78                         self::printXML($alias, $app->getBaseURL(), $user, $owner, $avatar);
79                 } else {
80                         self::printJSON($alias, $app->getBaseURL(), $owner, $avatar);
81                 }
82         }
83
84         private static function printJSON($alias, $baseURL, $owner, $avatar)
85         {
86                 $salmon_key = Salmon::salmonKey($owner['spubkey']);
87
88                 header('Access-Control-Allow-Origin: *');
89                 header('Content-type: application/json; charset=utf-8');
90
91                 $json = [
92                         'subject' => 'acct:' . $owner['addr'],
93                         'aliases' => [
94                                 $alias,
95                                 $owner['url'],
96                         ],
97                         'links'   => [
98                                 [
99                                         'rel'  => Namespaces::DFRN ,
100                                         'href' => $owner['url'],
101                                 ],
102                                 [
103                                         'rel'  => Namespaces::FEED,
104                                         'type' => 'application/atom+xml',
105                                         'href' => $owner['poll'],
106                                 ],
107                                 [
108                                         'rel'  => 'http://webfinger.net/rel/profile-page',
109                                         'type' => 'text/html',
110                                         'href' => $owner['url'],
111                                 ],
112                                 [
113                                         'rel'  => 'self',
114                                         'type' => 'application/activity+json',
115                                         'href' => $owner['url'],
116                                 ],
117                                 [
118                                         'rel'  => 'http://microformats.org/profile/hcard',
119                                         'type' => 'text/html',
120                                         'href' => $baseURL . '/hcard/' . $owner['nickname'],
121                                 ],
122                                 [
123                                         'rel'  => Namespaces::POCO,
124                                         'href' => $owner['poco'],
125                                 ],
126                                 [
127                                         'rel'  => 'http://webfinger.net/rel/avatar',
128                                         'type' => $avatar['type'],
129                                         'href' => $owner['photo'],
130                                 ],
131                                 [
132                                         'rel'  => 'http://joindiaspora.com/seed_location',
133                                         'type' => 'text/html',
134                                         'href' => $baseURL,
135                                 ],
136                                 [
137                                         'rel'  => 'salmon',
138                                         'href' => $baseURL . '/salmon/' . $owner['nickname'],
139                                 ],
140                                 [
141                                         'rel'  => 'http://salmon-protocol.org/ns/salmon-replies',
142                                         'href' => $baseURL . '/salmon/' . $owner['nickname'],
143                                 ],
144                                 [
145                                         'rel'  => 'http://salmon-protocol.org/ns/salmon-mention',
146                                         'href' => $baseURL . '/salmon/' . $owner['nickname'] . '/mention',
147                                 ],
148                                 [
149                                         'rel'      => 'http://ostatus.org/schema/1.0/subscribe',
150                                         'template' => $baseURL . '/follow?url={uri}',
151                                 ],
152                                 [
153                                         'rel'  => 'magic-public-key',
154                                         'href' => 'data:application/magic-public-key,' . $salmon_key,
155                                 ],
156                                 [
157                                         'rel'  => 'http://purl.org/openwebauth/v1',
158                                         'type' => 'application/x-zot+json',
159                                         'href' => $baseURL . '/owa',
160                                 ],
161                         ],
162                 ];
163
164                 echo json_encode($json);
165                 exit();
166         }
167
168         private static function printXML($alias, $baseURL, $user, $owner, $avatar)
169         {
170                 $salmon_key = Salmon::salmonKey($owner['spubkey']);
171
172                 header('Access-Control-Allow-Origin: *');
173                 header('Content-type: text/xml');
174
175                 $tpl = Renderer::getMarkupTemplate('xrd_person.tpl');
176
177                 $o = Renderer::replaceMacros($tpl, [
178                         '$nick'        => $owner['nickname'],
179                         '$accturi'     => 'acct:' . $owner['addr'],
180                         '$alias'       => $alias,
181                         '$profile_url' => $owner['url'],
182                         '$hcard_url'   => $baseURL . '/hcard/' . $owner['nickname'],
183                         '$atom'        => $owner['poll'],
184                         '$poco_url'    => $owner['poco'],
185                         '$photo'       => $owner['photo'],
186                         '$type'        => $avatar['type'],
187                         '$salmon'      => $baseURL . '/salmon/' . $owner['nickname'],
188                         '$salmen'      => $baseURL . '/salmon/' . $owner['nickname'] . '/mention',
189                         '$subscribe'   => $baseURL . '/follow?url={uri}',
190                         '$openwebauth' => $baseURL . '/owa',
191                         '$modexp'      => 'data:application/magic-public-key,' . $salmon_key
192                 ]);
193
194                 $arr = ['user' => $user, 'xml' => $o];
195                 Hook::callAll('personal_xrd', $arr);
196
197                 echo $arr['xml'];
198                 exit();
199         }
200 }