misuzu/src/Redirects/SocialRedirectsRoutes.php

78 lines
3 KiB
PHP

<?php
namespace Misuzu\Redirects;
use Index\Config\Config;
use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
use Misuzu\AssetInfo;
class SocialRedirectsRoutes implements RouteHandler {
use RouteHandlerCommon;
private Config $config;
public function __construct(
RedirectsContext $redirectsCtx,
private AssetInfo $assetInfo
) {
$this->config = $redirectsCtx->config->scopeTo('social');
}
#[HttpGet('/bsky/((did:[a-z0-9]+:[A-Za-z0-9.\-_:%]+)|(([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])))')]
public function getBlueskyRedirect(HttpResponseBuilder $response, HttpRequest $request, string $handle): int|string {
$did = null;
if(str_starts_with($handle, 'did:'))
$did = $handle;
else {
$timeout = ini_get('default_socket_timeout');
try {
ini_set('default_socket_timeout', 3);
$records = dns_get_record(sprintf('_atproto.%s', $handle), DNS_TXT);
if(is_array($records))
foreach($records as $record)
if(array_key_exists('txt', $record) && str_starts_with($record['txt'], 'did=')) {
$did = trim(substr(trim($record['txt']), 4));
break;
}
} finally {
ini_set('default_socket_timeout', $timeout);
}
}
$format = $this->config->getString('bsky_profile', 'https://bsky.app/profile/%s');
if(is_string($did)) {
$response->redirect(sprintf($format, $did), true);
return 301;
}
$handle = rawurlencode($handle);
$script = $this->assetInfo->getAssetUrl('redir-bsky.js');
return <<<HTML
<!doctype html>
<meta charset=utf-8>
<title>Redirecting to Bluesky profile...</title>
<div class=js-status><noscript>Javascript must be enabled for Bluesky redirects to work.</noscript></div>
<script>const BSKY_FORMAT = '{$format}'; const BSKY_HANDLE = decodeURIComponent('{$handle}');</script>
<script src="{$script}"></script>
HTML;
}
#[HttpGet('/fedi/([A-Za-z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})')]
public function getFediverseRedirect(HttpResponseBuilder $response, HttpRequest $request, string $userName, string $instance): string {
$userName = rawurlencode($userName);
$instance = rawurlencode($instance);
$script = $this->assetInfo->getAssetUrl('redir-fedi.js');
return <<<HTML
<!doctype html>
<meta charset=utf-8>
<title>Redirecting to Fediverse profile...</title>
<div class=js-status><noscript>Javascript must be enabled for Fediverse redirects to work.</noscript></div>
<script>const FEDI_USERNAME = '{$userName}'; const FEDI_INSTANCE = decodeURIComponent('{$instance}');</script>
<script src="{$script}"></script>
HTML;
}
}