155 lines
5.6 KiB
PHP
155 lines
5.6 KiB
PHP
<?php
|
|
namespace Misuzu\Users;
|
|
|
|
use RuntimeException;
|
|
use Index\XArray;
|
|
use Index\Colour\{Colour,ColourRgb};
|
|
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
|
use Index\Http\Routing\AccessControl\AccessControl;
|
|
use Index\Http\Routing\Processors\Before;
|
|
use Index\Http\Routing\Routes\ExactRoute;
|
|
use Index\Urls\UrlRegistry;
|
|
use Misuzu\{FieldTransformer,SiteInfo};
|
|
use Misuzu\Auth\AuthInfo;
|
|
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
|
use Misuzu\Users\UserInfo;
|
|
use Misuzu\Users\Assets\UserAvatarAsset;
|
|
|
|
#[HandlerRoles('main')]
|
|
final class UsersApiRoutes implements RouteHandler {
|
|
use RouteHandlerCommon;
|
|
|
|
public function __construct(
|
|
private SiteInfo $siteInfo,
|
|
private UrlRegistry $urls,
|
|
private UsersContext $usersCtx,
|
|
private AuthInfo $authInfo,
|
|
) {}
|
|
|
|
/** @return FieldTransformer<UserInfo> */
|
|
public function createUserTransformer(): FieldTransformer {
|
|
$fields = [
|
|
'id' => [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->id,
|
|
],
|
|
];
|
|
|
|
$openid = $this->authInfo->hasScope('openid');
|
|
|
|
if(!$openid || $this->authInfo->hasScope('profile')) {
|
|
$fields['name'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->name,
|
|
];
|
|
$fields['colour_raw'] = [
|
|
'default' => true,
|
|
'transform' => function($user) {
|
|
$colour = $this->usersCtx->getUserColour($user);
|
|
return $colour->inherits ? null : Colour::toRawRgb($colour);
|
|
},
|
|
'include' => fn() => true,
|
|
];
|
|
$fields['colour_css'] = [
|
|
'default' => true,
|
|
'transform' => function($user) {
|
|
$colour = $this->usersCtx->getUserColour($user);
|
|
return $colour->inherits ? (string)$colour : (string)ColourRgb::convert($colour);
|
|
},
|
|
];
|
|
$fields['country_code'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->countryCode,
|
|
];
|
|
$fields['rank'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => (
|
|
$this->usersCtx->hasActiveBan($user)
|
|
? 0
|
|
: $this->usersCtx->getUserRank($user)
|
|
),
|
|
];
|
|
$fields['roles'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => (
|
|
$this->usersCtx->hasActiveBan($user)
|
|
? ['x-banned']
|
|
: XArray::select(
|
|
$this->usersCtx->roles->getRoles(
|
|
userInfo: $user,
|
|
hasString: true,
|
|
orderByRank: true
|
|
),
|
|
fn($roleInfo) => $roleInfo->string,
|
|
)
|
|
),
|
|
];
|
|
$fields['is_super'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->super,
|
|
'include' => fn($value) => $value === true,
|
|
];
|
|
$fields['title'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => empty($user->title) ? null : $user->title,
|
|
];
|
|
$fields['created_at'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->createdAt->toIso8601ZuluString(),
|
|
];
|
|
$fields['last_active_at'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->lastActiveAt?->toIso8601ZuluString(),
|
|
];
|
|
$fields['profile_url'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => ($this->siteInfo->url . $this->urls->format('user-profile', ['user' => $user->id])),
|
|
];
|
|
$fields['avatar_url'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => ($this->siteInfo->url . $this->urls->format('user-avatar', ['user' => $user->id])),
|
|
];
|
|
$fields['is_deleted'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->deleted,
|
|
'include' => fn($value) => $value === true,
|
|
];
|
|
}
|
|
|
|
if($this->authInfo->hasScope($openid ? 'email' : 'identify:email'))
|
|
$fields['email'] = [
|
|
'default' => true,
|
|
'transform' => fn($user) => $user->emailAddress,
|
|
];
|
|
|
|
return new FieldTransformer($fields);
|
|
}
|
|
|
|
/** @return int|mixed[] */
|
|
#[AccessControl]
|
|
#[ExactRoute('GET', '/api/v1/me')]
|
|
#[Before('authz:cookie', required: false)]
|
|
#[Before('authz:bearer', required: false)]
|
|
#[Before('authz:misuzu', required: false)]
|
|
public function getMe(HttpResponseBuilder $response, HttpRequest $request): int|array {
|
|
$response->setHeader('Cache-Control', 'no-store');
|
|
|
|
$openid = $this->authInfo->hasScope('openid');
|
|
if(!$openid
|
|
&& !$this->authInfo->hasScope('identify')
|
|
&& !$this->authInfo->hasScope('beans'))
|
|
return 403;
|
|
|
|
$transformer = $this->createUserTransformer();
|
|
if(!$transformer->filter($request))
|
|
return 400;
|
|
|
|
try {
|
|
$userInfo = $this->usersCtx->getUserInfo($this->authInfo->userId, UsersData::GET_USER_ID);
|
|
} catch(RuntimeException) {
|
|
return 404;
|
|
}
|
|
|
|
return $transformer->convert($userInfo);
|
|
}
|
|
}
|