misuzu/src/Satori/SatoriRoutes.php

125 lines
4.5 KiB
PHP

<?php
namespace Misuzu\Satori;
use RuntimeException;
use Index\Colour\Colour;
use Index\Http\Routing\{HttpGet,HttpMiddleware,RouteHandler};
use Syokuhou\IConfig;
use Misuzu\Pagination;
use Misuzu\RoutingContext;
use Misuzu\Forum\ForumContext;
use Misuzu\Profile\ProfileFields;
use Misuzu\Users\UsersContext;
final class SatoriRoutes extends RouteHandler {
public function __construct(
private IConfig $config,
private UsersContext $usersCtx,
private ForumContext $forumCtx,
private ProfileFields $profileFields
) {}
#[HttpMiddleware('/_satori')]
public function verifyRequest($response, $request) {
$secretKey = $this->config->getString('secret');
if(!empty($secretKey)) {
$userTime = (int)$request->getHeaderLine('X-Satori-Time');
$userHash = base64_decode((string)$request->getHeaderLine('X-Satori-Hash'));
$currentTime = time();
if(empty($userHash) || $userTime < $currentTime - 60 || $userTime > $currentTime + 60)
return 403;
$verifyText = (string)$userTime . '#' . $request->getPath() . '?' . $request->getParamString();
$verifyHash = hash_hmac('sha256', $verifyText, $secretKey, true);
if(!hash_equals($verifyHash, $userHash))
return 403;
}
}
#[HttpGet('/_satori/get-profile-field')]
public function getProfileField($response, $request): array {
$userId = (string)$request->getParam('user', FILTER_SANITIZE_NUMBER_INT);
$fieldId = (string)$request->getParam('field', FILTER_SANITIZE_NUMBER_INT);
try {
$fieldValue = $this->profileFields->getFieldValue($fieldId, $userId);
} catch(RuntimeException $ex) {
return ['error' => 105];
}
return [
'field_value' => $fieldValue->getValue(),
];
}
#[HttpGet('/_satori/get-recent-forum-posts')]
public function getRecentForumPosts($response, $request): array {
$categoryIds = $this->config->getArray('forum.categories');
if(empty($categoryIds))
return [];
$batchSize = $this->config->getInteger('forum.batch', 6);
$backlogDays = $this->config->getInteger('forum.backlog', 7);
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
$posts = [];
$postInfos = $this->forumCtx->getPosts()->getPosts(
categoryInfo: $categoryIds,
afterPostInfo: $startId,
newerThanDays: $backlogDays,
pagination: new Pagination($batchSize),
deleted: false,
);
foreach($postInfos as $postInfo) {
$topicInfo = $this->forumCtx->getTopics()->getTopic(postInfo: $postInfo);
$firstPostInfo = $this->forumCtx->getPosts()->getPost(topicInfo: $topicInfo);
$categoryInfo = $this->forumCtx->getCategories()->getCategory(topicInfo: $topicInfo);
$userInfo = $postInfo->hasUserId() ? $this->usersCtx->getUserInfo($postInfo->getUserId()) : null;
$userColour = $this->usersCtx->getUserColour($userInfo);
$posts[] = [
'post_id' => (int)$postInfo->getId(),
'topic_id' => (int)$topicInfo->getId(),
'topic_title' => $topicInfo->getTitle(),
'forum_id' => (int)$categoryInfo->getId(),
'forum_name' => $categoryInfo->getName(),
'user_id' => (int)$userInfo->getId(),
'username' => $userInfo->getName(),
'user_colour' => Colour::toMisuzu($userColour),
'is_opening_post' => $postInfo->getId() === $firstPostInfo->getId() ? 1 : 0,
];
}
return $posts;
}
#[HttpGet('/_satori/get-recent-registrations')]
public function getRecentRegistrations($response, $request) {
$batchSize = $this->config->getInteger('users.batch', 10);
$backlogDays = $this->config->getInteger('users.backlog', 7);
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
$userInfos = $this->usersCtx->getUsers()->getUsers(
after: $startId,
newerThanDays: $backlogDays,
orderBy: 'id',
pagination: new Pagination($batchSize),
deleted: false
);
$users = [];
foreach($userInfos as $userInfo)
$users[] = [
'user_id' => (int)$userInfo->getId(),
'username' => $userInfo->getName(),
];
return $users;
}
}