diff --git a/app/Http/Controllers/MicropubController.php b/app/Http/Controllers/MicropubController.php index 7c26a615..69e45e35 100644 --- a/app/Http/Controllers/MicropubController.php +++ b/app/Http/Controllers/MicropubController.php @@ -211,6 +211,16 @@ class MicropubController extends Controller ], 201)->header('Location', $media->url); } + /** + * Return the relavent CORS headers to a pre-flight OPTIONS request. + * + * @return \Illuminate\Http\Response + */ + public function mediaOptionsResponse(): Response + { + return response('OK', 200); + } + /** * Get the file type from the mimetype of the uploaded file. * diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 005c0d69..3ef8070a 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -62,5 +62,6 @@ class Kernel extends HttpKernel 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'micropub.token' => \App\Http\Middleware\VerifyMicropubToken::class, 'myauth' => \App\Http\Middleware\MyAuthMiddleware::class, + 'cors' => \App\Http\Middleware\CorsHeaders::class, ]; } diff --git a/app/Http/Middleware/CorsHeaders.php b/app/Http/Middleware/CorsHeaders.php new file mode 100644 index 00000000..61b3e1e3 --- /dev/null +++ b/app/Http/Middleware/CorsHeaders.php @@ -0,0 +1,28 @@ +path() === 'api/media') { + $response->header('Access-Control-Allow-Origin', '*'); + $response->header('Access-Control-Allow-Methods', 'OPTIONS, POST'); + $response->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, DNT, X-CSRF-TOKEN, X-REQUESTED-WITH'); + $response->header('Access-Control-Allow-Credentials', 'true'); + } + + return $response; + } +} diff --git a/routes/web.php b/routes/web.php index b1e077d2..96734fcf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -136,7 +136,8 @@ Route::group(['domain' => config('url.longurl')], function () { // Micropub Endpoints Route::get('api/post', 'MicropubController@get')->middleware('micropub.token'); Route::post('api/post', 'MicropubController@post')->middleware('micropub.token'); - Route::post('api/media', 'MicropubController@media')->middleware('micropub.token')->name('media-endpoint'); + Route::post('api/media', 'MicropubController@media')->middleware('micropub.token', 'cors')->name('media-endpoint'); + Route::options('/api/media', 'MicropubController@mediaOptionsResponse')->middleware('cors'); //webmention Route::get('webmention', 'WebMentionsController@get'); diff --git a/tests/Feature/CorsHeadersTest.php b/tests/Feature/CorsHeadersTest.php new file mode 100644 index 00000000..3d3ef924 --- /dev/null +++ b/tests/Feature/CorsHeadersTest.php @@ -0,0 +1,34 @@ +call( + 'OPTIONS', + '/api/media', + [], + [], + [], + ['HTTP_Authorization' => 'Bearer ' . $this->getToken()] + ); + $response->assertHeader('Access-Control-Allow-Origin', '*'); + } + + /** @test */ + public function check_missing_on_other_route() + { + $response = $this->get('/'); + $response->assertHeaderMissing('Access-Control-Allow-Origin'); + } +}