115 lines
3.7 KiB
PHP
115 lines
3.7 KiB
PHP
<?php
|
|
namespace Misuzu\WebFinger;
|
|
|
|
use Index\XArray;
|
|
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
|
use Index\Http\Routing\{HttpGet,HttpOptions,RouteHandler,RouteHandlerCommon};
|
|
|
|
class WebFingerRoutes implements RouteHandler {
|
|
use RouteHandlerCommon;
|
|
|
|
public function __construct(
|
|
private WebFingerRegistry $registry
|
|
) {}
|
|
|
|
/**
|
|
* @param WebFingerProperty[] $propInfos
|
|
* @return array<string, ?string>
|
|
*/
|
|
private static function extractProps(array $propInfos): array {
|
|
$props = [];
|
|
foreach($propInfos as $propInfo)
|
|
$props[$propInfo->name] = $propInfo->value;
|
|
return $props;
|
|
}
|
|
|
|
/**
|
|
* @param WebFingerTitle[] $titleInfos
|
|
* @return array<string, string>
|
|
*/
|
|
private static function extractTitles(array $titleInfos): array {
|
|
$titles = [];
|
|
foreach($titleInfos as $titleInfo)
|
|
$titles[$titleInfo->lang] = $titleInfo->value;
|
|
return $titles;
|
|
}
|
|
|
|
/**
|
|
* @param WebFingerLink[] $linkInfos
|
|
* @return array{rel: string, type?: string, href?: string, titles?: array<string, string>, properties?: array<string, ?string>}[]
|
|
*/
|
|
private static function extractLinks(array $linkInfos): array {
|
|
$links = [];
|
|
foreach($linkInfos as $linkInfo) {
|
|
$link = ['rel' => $linkInfo->relation];
|
|
if($linkInfo->type !== null)
|
|
$link['type'] = $linkInfo->type;
|
|
if($linkInfo->href !== null)
|
|
$link['href'] = $linkInfo->href;
|
|
if(!empty($linkInfo->titles))
|
|
$link['titles'] = self::extractTitles($linkInfo->titles);
|
|
if(!empty($linkInfo->properties))
|
|
$link['properties'] = self::extractProps($linkInfo->properties);
|
|
$links[] = $link;
|
|
}
|
|
return $links;
|
|
}
|
|
|
|
/**
|
|
* @return int|array{
|
|
* subject?: string,
|
|
* aliases?: string[],
|
|
* properties?: array<string, ?string>,
|
|
* links?: array{
|
|
* rel: string,
|
|
* type?: string,
|
|
* href?: string,
|
|
* titles?: array<string, string>,
|
|
* properties?: array<string, ?string>
|
|
* }[]
|
|
* }
|
|
*/
|
|
#[HttpOptions('/.well-known/webfinger')]
|
|
#[HttpGet('/.well-known/webfinger')]
|
|
public function getWebFinger(HttpResponseBuilder $response, HttpRequest $request): array|int {
|
|
$response->setHeader('Access-Control-Allow-Origin', '*');
|
|
if($request->method === 'OPTIONS')
|
|
return 204;
|
|
|
|
$resInfos = $this->registry->resolve(trim((string)$request->getParam('resource')));
|
|
if(empty($resInfos))
|
|
return 404;
|
|
|
|
$subject = null;
|
|
$aliases = [];
|
|
$properties = [];
|
|
$links = [];
|
|
|
|
foreach($resInfos as $resInfo) {
|
|
if($resInfo->subject !== null && $subject === null)
|
|
$subject = $resInfo->subject;
|
|
if(!empty($resInfo->aliases))
|
|
$aliases = array_unique(array_merge($aliases, $resInfo->aliases));
|
|
if(!empty($resInfo->properties))
|
|
$properties = array_merge($properties, self::extractProps($resInfo->properties));
|
|
if(!empty($resInfo->links))
|
|
$links = array_merge($links, self::extractLinks($resInfo->links));
|
|
}
|
|
|
|
$result = [];
|
|
if($subject !== null)
|
|
$result['subject'] = $subject;
|
|
if(!empty($aliases))
|
|
$result['aliases'] = $aliases;
|
|
if(!empty($properties))
|
|
$result['properties'] = $properties;
|
|
if(!empty($links))
|
|
$result['links'] = $links;
|
|
|
|
if(empty($result))
|
|
return 404;
|
|
|
|
$response->setContentType('application/jrd+json');
|
|
return $result;
|
|
}
|
|
}
|