misuzu/src/Users/UsersApiRoutes.php

106 lines
3.6 KiB
PHP
Raw Normal View History

2025-03-24 22:15:37 +00:00
<?php
namespace Misuzu\Users;
use RuntimeException;
use Misuzu\SiteInfo;
use Misuzu\Auth\AuthInfo;
use Misuzu\Users\Assets\UserAvatarAsset;
use Index\XArray;
use Index\Colour\{Colour,ColourRgb};
use Index\Http\{HttpRequest,HttpResponseBuilder};
2025-03-25 13:51:39 +00:00
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
use Index\Http\Routing\AccessControl\AccessControl;
use Index\Http\Routing\Routes\ExactRoute;
2025-03-24 22:15:37 +00:00
use Index\Urls\UrlRegistry;
final class UsersApiRoutes implements RouteHandler {
use RouteHandlerCommon;
public function __construct(
private SiteInfo $siteInfo,
private UrlRegistry $urls,
private UsersContext $usersCtx,
private AuthInfo $authInfo,
) {}
/** @return int|mixed[] */
2025-03-25 13:51:39 +00:00
#[AccessControl]
#[ExactRoute('GET', '/api/v1/me')]
public function getMe(HttpResponseBuilder $response, HttpRequest $request): int|array {
$response->setHeader('Cache-Control', 'no-store');
2025-03-24 22:15:37 +00:00
$openid = $this->authInfo->hasScope('openid');
if(!$openid
&& !$this->authInfo->hasScope('identify')
&& !$this->authInfo->hasScope('beans'))
return 403;
$includeProfile = !$openid || $this->authInfo->hasScope('profile');
$includeEMail = $openid
? $this->authInfo->hasScope('email')
: $this->authInfo->hasScope('identify:email');
try {
$userInfo = $this->usersCtx->getUserInfo($this->authInfo->userId, UsersData::GET_USER_ID);
} catch(RuntimeException) {
return 404;
}
// TODO: there should be some kinda privacy controls for users
$output = ['id' => $userInfo->id];
if($includeProfile) {
$output['name'] = $userInfo->name;
$colour = $this->usersCtx->getUserColour($userInfo);
if($colour->inherits) {
$colourRaw = null;
$colourCSS = (string)$colour;
} else {
$colourRaw = Colour::toRawRgb($colour);
$colourCSS = (string)ColourRgb::convert($colour);
}
$output['colour_raw'] = $colourRaw;
$output['colour_css'] = $colourCSS;
$output['country_code'] = $userInfo->countryCode;
if($this->usersCtx->hasActiveBan($userInfo)) {
$output['rank'] = 0;
$output['roles'] = ['x-banned'];
} else {
$roles = XArray::select(
$this->usersCtx->roles->getRoles(userInfo: $userInfo, hasString: true, orderByRank: true),
fn($roleInfo) => $roleInfo->string,
);
$output['rank'] = $this->usersCtx->getUserRank($userInfo);
if(!empty($roles))
$output['roles'] = $roles;
if($userInfo->super)
$output['is_super'] = true;
}
if(!empty($userInfo->title))
$output['title'] = $userInfo->title;
$output['created_at'] = $userInfo->createdAt->toIso8601ZuluString();
if($userInfo->lastActiveTime !== null)
$output['last_active_at'] = $userInfo->lastActiveAt->toIso8601ZuluString();
$baseUrl = $this->siteInfo->url;
$output['profile_url'] = $baseUrl . $this->urls->format('user-profile', ['user' => $userInfo->id]);
$output['avatar_url'] = $baseUrl . $this->urls->format('user-avatar', ['user' => $userInfo->id]);
if($userInfo->deleted)
$output['is_deleted'] = true;
}
if($includeEMail)
$output['email'] = $userInfo->emailAddress;
return $output;
}
}