Updated leftovers from rebase.

This commit is contained in:
flash 2025-03-25 13:51:39 +00:00
parent 5ba8b30047
commit 238bb3f48e
Signed by: flash
GPG key ID: 2C9C2C574D47FE3E
8 changed files with 42 additions and 52 deletions

View file

@ -1 +1 @@
20250325 20250325.1

10
composer.lock generated
View file

@ -3679,16 +3679,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.10", "version": "2.1.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "051a3b6b9b80df4ba3a7f801a8b53ad7d8f1c15f" "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/051a3b6b9b80df4ba3a7f801a8b53ad7d8f1c15f", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8ca5f79a8f63c49b2359065832a654e1ec70ac30",
"reference": "051a3b6b9b80df4ba3a7f801a8b53ad7d8f1c15f", "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3733,7 +3733,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-03-23T14:57:55+00:00" "time": "2025-03-24T13:45:00+00:00"
} }
], ],
"aliases": [], "aliases": [],

View file

@ -6,7 +6,8 @@ use Misuzu\OAuth2\{OAuth2AccessInfoGetField,OAuth2Context};
use Misuzu\Users\{UsersContext,UserInfo}; use Misuzu\Users\{UsersContext,UserInfo};
use Index\Config\Config; use Index\Config\Config;
use Index\Http\{HttpRequest,HttpResponseBuilder}; use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpMiddleware,RouteHandler,RouteHandlerCommon}; use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
use Index\Http\Routing\Filters\PrefixFilter;
final class AuthApiRoutes implements RouteHandler { final class AuthApiRoutes implements RouteHandler {
use RouteHandlerCommon; use RouteHandlerCommon;
@ -27,9 +28,9 @@ final class AuthApiRoutes implements RouteHandler {
return in_array($targetId, $whitelist, true); return in_array($targetId, $whitelist, true);
} }
/** @return void|int */ /** @return void|array{error: string, error_description?: string} */
#[HttpMiddleware('/api/v1')] #[PrefixFilter('/api/v1')]
#[HttpMiddleware('/oauth2')] #[PrefixFilter('/oauth2')]
public function handleAuthorization(HttpResponseBuilder $response, HttpRequest $request) { public function handleAuthorization(HttpResponseBuilder $response, HttpRequest $request) {
if($this->authInfo->loggedIn) if($this->authInfo->loggedIn)
return; return;

View file

@ -86,6 +86,7 @@ class AuthInfo {
get => $this->appInfo?->id; get => $this->appInfo?->id;
} }
/** @var string[]|null */
public ?array $scopes { public ?array $scopes {
get { get {
if($this->appInfo !== null) if($this->appInfo !== null)

View file

@ -3,7 +3,9 @@ namespace Misuzu\Emoticons;
use Index\XArray; use Index\XArray;
use Index\Http\{HttpRequest,HttpResponseBuilder}; use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpGet,HttpOptions,RouteHandler,RouteHandlerCommon}; use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
use Index\Http\Routing\AccessControl\AccessControl;
use Index\Http\Routing\Routes\ExactRoute;
final class EmotesApiRoutes implements RouteHandler { final class EmotesApiRoutes implements RouteHandler {
use RouteHandlerCommon; use RouteHandlerCommon;
@ -12,18 +14,10 @@ final class EmotesApiRoutes implements RouteHandler {
private EmotesData $emotes private EmotesData $emotes
) {} ) {}
/** @return int|mixed[] */ /** @return mixed[] */
#[HttpOptions('/api/v1/emotes')] #[AccessControl]
#[HttpGet('/api/v1/emotes')] #[ExactRoute('GET', '/api/v1/emotes')]
public function getEmotes(HttpResponseBuilder $response, HttpRequest $request): int|array { public function getEmotes(HttpResponseBuilder $response, HttpRequest $request): array {
$response->setHeader('Access-Control-Allow-Origin', '*');
$response->setHeader('Access-Control-Allow-Methods', 'GET');
$response->addHeader('Access-Control-Allow-Headers', 'Cache-Control');
$response->setHeader('Cache-Control', 'public, max-age=3600');
if($request->method === 'OPTIONS')
return 204;
$includeId = !empty($request->getParam('include_id')); $includeId = !empty($request->getParam('include_id'));
$includeOrder = !empty($request->getParam('include_order')); $includeOrder = !empty($request->getParam('include_order'));

View file

@ -173,9 +173,9 @@ final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
]; ];
} }
/** @return int|array{keys?: array<string, string>} */ /** @return array{keys?: array<string, string>} */
#[HttpOptions('/oauth2/jwks.json')] #[AccessControl]
#[HttpGet('/oauth2/jwks.json')] #[ExactRoute('GET', '/oauth2/jwks.json')]
#[UrlFormat('oauth2-jwks', '/oauth2/jwks.json')] #[UrlFormat('oauth2-jwks', '/oauth2/jwks.json')]
public function getJwks(HttpResponseBuilder $response, HttpRequest $request): array { public function getJwks(HttpResponseBuilder $response, HttpRequest $request): array {
return $this->oauth2Ctx->keys->getPublicKeysForJson(); return $this->oauth2Ctx->keys->getPublicKeysForJson();
@ -360,15 +360,10 @@ final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
* email_verified?: bool, * email_verified?: bool,
* }|array{ error: string, error_description: string } * }|array{ error: string, error_description: string }
*/ */
#[HttpOptions('/oauth2/userinfo')] #[AccessControl(allowHeaders: ['Authorization'], exposeHeaders: ['WWW-Authenticate'])]
#[HttpGet('/oauth2/userinfo')] #[ExactRoute('GET', '/oauth2/userinfo')]
#[UrlFormat('oauth2-openid-userinfo', '/oauth2/userinfo')] #[UrlFormat('oauth2-openid-userinfo', '/oauth2/userinfo')]
public function getUserInfo(HttpResponseBuilder $response, HttpRequest $request): int|array { public function getUserInfo(HttpResponseBuilder $response, HttpRequest $request): array {
$response->setHeader('Access-Control-Allow-Origin', '*');
$response->setHeader('Access-Control-Allow-Headers', 'Authorization');
if($request->method === 'OPTIONS')
return 204;
if(!$this->authInfo->loggedInBearer) { if(!$this->authInfo->loggedInBearer) {
$response->statusCode = 401; $response->statusCode = 401;
$response->setHeader('WWW-Authenticate', 'Bearer error="invalid_token", error_description="Bearer authentication must be used."'); $response->setHeader('WWW-Authenticate', 'Bearer error="invalid_token", error_description="Bearer authentication must be used."');

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Misuzu\Routing; namespace Misuzu\Routing;
use Index\Http\HttpResponse;
use Index\Http\Routing\HandlerContext; use Index\Http\Routing\HandlerContext;
use Index\Http\Routing\ErrorHandling\HtmlErrorHandler; use Index\Http\Routing\ErrorHandling\HtmlErrorHandler;
use Index\Http\Streams\Stream; use Index\Http\Streams\Stream;
@ -17,16 +18,18 @@ class RoutingErrorHandler extends HtmlErrorHandler {
return; return;
} }
if(str_starts_with($request->path, '/api')) { if(str_starts_with($context->request->requestTarget, '/api')) {
$response->setTypeJson(); $context->response->setTypeJson();
$response->content = json_encode([ $context->response->body = Stream::createStream(json_encode([
'error' => sprintf('http:%s', $code), 'error' => sprintf('http:%s', $context->response->statusCode),
'message' => $message, 'message' => $context->response->reasonPhrase === ''
], JSON_UNESCAPED_SLASHES); ? HttpResponse::defaultReasonPhase($context->response->statusCode)
: $context->response->reasonPhrase,
], JSON_UNESCAPED_SLASHES));
return; return;
} }
$path = sprintf('%s/error-%03d.html', Misuzu::PATH_PUBLIC, $code); $path = sprintf('%s/error-%03d.html', Misuzu::PATH_PUBLIC, $context->response->statusCode);
if(is_file($path)) { if(is_file($path)) {
$context->response->setTypeHTML(); $context->response->setTypeHTML();
$context->response->body = Stream::createStreamFromFile($path, 'rb'); $context->response->body = Stream::createStreamFromFile($path, 'rb');

View file

@ -8,7 +8,9 @@ use Misuzu\Users\Assets\UserAvatarAsset;
use Index\XArray; use Index\XArray;
use Index\Colour\{Colour,ColourRgb}; use Index\Colour\{Colour,ColourRgb};
use Index\Http\{HttpRequest,HttpResponseBuilder}; use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpGet,HttpOptions,RouteHandler,RouteHandlerCommon}; use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
use Index\Http\Routing\AccessControl\AccessControl;
use Index\Http\Routing\Routes\ExactRoute;
use Index\Urls\UrlRegistry; use Index\Urls\UrlRegistry;
final class UsersApiRoutes implements RouteHandler { final class UsersApiRoutes implements RouteHandler {
@ -22,16 +24,10 @@ final class UsersApiRoutes implements RouteHandler {
) {} ) {}
/** @return int|mixed[] */ /** @return int|mixed[] */
#[HttpOptions('/api/v1/me')] #[AccessControl]
#[HttpGet('/api/v1/me')] #[ExactRoute('GET', '/api/v1/me')]
public function getEmotes(HttpResponseBuilder $response, HttpRequest $request): int|array { public function getMe(HttpResponseBuilder $response, HttpRequest $request): int|array {
$response->setHeader('Access-Control-Allow-Origin', '*'); $response->setHeader('Cache-Control', 'no-store');
$response->setHeader('Access-Control-Allow-Methods', 'GET');
$response->addHeader('Access-Control-Allow-Headers', 'Cache-Control');
$response->setHeader('Cache-Control', 'public, max-age=3600');
if($request->method === 'OPTIONS')
return 204;
$openid = $this->authInfo->hasScope('openid'); $openid = $this->authInfo->hasScope('openid');
if(!$openid if(!$openid