diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbee2b..51f8c27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v2.1 ++ Improved theme style. ++ Improved page redirecting. ++ Allow e-mail login. ++ Support for ShareX deletion URL. ++ Fixed HTTP/2 push preload. ++ Added video.js support. + ## v2.0 + Migrated from Flight to Slim 3 framework. + Added install wizard (using the CLI is no longer required). diff --git a/app/Controllers/UploadController.php b/app/Controllers/UploadController.php index a81199d..f00228c 100644 --- a/app/Controllers/UploadController.php +++ b/app/Controllers/UploadController.php @@ -83,7 +83,7 @@ class UploadController extends Controller { $media = $this->getMedia($args['userCode'], $args['mediaCode']); - if (!$media || !$media->published && Session::get('user_id') !== $media->user_id && !Session::get('admin', false)) { + if (!$media || (!$media->published && Session::get('user_id') !== $media->user_id && !Session::get('admin', false))) { throw new NotFoundException($request, $response); } @@ -108,10 +108,11 @@ class UploadController extends Controller } } catch (FileNotFoundException $e) { - throw $e; + throw new NotFoundException($request, $response); } return $this->view->render($response, 'upload/public.twig', [ + 'delete_token' => isset($args['token']) ? $args['token'] : null, 'media' => $media, 'type' => $mime, 'extension' => pathinfo($media->filename, PATHINFO_EXTENSION), @@ -119,6 +120,52 @@ class UploadController extends Controller } } + /** + * @param Request $request + * @param Response $response + * @param $args + * @return Response + * @throws NotFoundException + * @throws UnauthorizedException + */ + public function deleteByToken(Request $request, Response $response, $args): Response + { + $media = $this->getMedia($args['userCode'], $args['mediaCode']); + + if (!$media) { + throw new NotFoundException($request, $response); + } + + $user = $this->database->query('SELECT `id`, `active` FROM `users` WHERE `token` = ? LIMIT 1', $args['token'])->fetch(); + + if (!$user) { + Session::alert('Token specified not found.', 'danger'); + return $response->withRedirect($request->getHeaderLine('HTTP_REFERER')); + } + + if (!$user->active) { + Session::alert('Account disabled.', 'danger'); + return $response->withRedirect($request->getHeaderLine('HTTP_REFERER')); + } + + if (Session::get('admin', false) || $user->id === $media->user_id) { + + $filesystem = $this->getStorage(); + try { + $filesystem->delete($media->storage_path); + } catch (FileNotFoundException $e) { + throw new NotFoundException($request, $response); + } finally { + $this->database->query('DELETE FROM `uploads` WHERE `id` = ?', $media->mediaId); + $this->logger->info('User ' . $user->username . ' deleted a media via token.', [$media->mediaId]); + } + } else { + throw new UnauthorizedException(); + } + + return redirect($response, '/home'); + } + /** * @param Request $request * @param Response $response @@ -212,6 +259,10 @@ class UploadController extends Controller { $media = $this->database->query('SELECT * FROM `uploads` WHERE `id` = ? LIMIT 1', $args['id'])->fetch(); + if (!$media) { + throw new NotFoundException($request, $response); + } + if (Session::get('admin', false) || $media->user_id === Session::get('user_id')) { $filesystem = $this->getStorage(); @@ -240,7 +291,7 @@ class UploadController extends Controller { $mediaCode = pathinfo($mediaCode)['filename']; - $media = $this->database->query('SELECT * FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_code` = ? AND `uploads`.`code` = ? LIMIT 1', [ + $media = $this->database->query('SELECT `uploads`.*, `users`.*, `users`.`id` AS `userId`, `uploads`.`id` AS `mediaId` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_code` = ? AND `uploads`.`code` = ? LIMIT 1', [ $userCode, $mediaCode, ])->fetch(); @@ -282,7 +333,7 @@ class UploadController extends Controller ob_end_clean(); return $response ->withHeader('Content-Type', $mime) - ->withHeader('Content-Disposition', $disposition . ';filename="' . $media->filename . '"') + ->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"') ->withHeader('Content-Length', $storage->getSize($media->storage_path)) ->withBody(new Stream($storage->readStream($media->storage_path))); } diff --git a/app/Controllers/UserController.php b/app/Controllers/UserController.php index c4aff23..1cdf501 100644 --- a/app/Controllers/UserController.php +++ b/app/Controllers/UserController.php @@ -348,7 +348,7 @@ class UserController extends Controller ], 'URL' => '$json:url$', 'ThumbnailURL' => '$json:url$/raw', - 'DeletionURL' => '$json:url$/delete', + 'DeletionURL' => '$json:url$/delete/' . $user->token, ]; return $response diff --git a/app/routes.php b/app/routes.php index 7b84b5d..48fd2e0 100644 --- a/app/routes.php +++ b/app/routes.php @@ -35,5 +35,7 @@ $app->map(['GET', 'POST'], '/logout', \App\Controllers\LoginController::class . $app->post('/upload', \App\Controllers\UploadController::class . ':upload'); $app->get('/{userCode}/{mediaCode}', \App\Controllers\UploadController::class . ':show'); +$app->get('/{userCode}/{mediaCode}/delete/{token}', \App\Controllers\UploadController::class . ':show'); +$app->post('/{userCode}/{mediaCode}/delete/{token}', \App\Controllers\UploadController::class . ':deleteByToken'); $app->get('/{userCode}/{mediaCode}/raw', \App\Controllers\UploadController::class . ':showRaw'); $app->get('/{userCode}/{mediaCode}/download', \App\Controllers\UploadController::class . ':download'); \ No newline at end of file diff --git a/bootstrap/app.php b/bootstrap/app.php index d318644..4e3b328 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -27,9 +27,12 @@ $config = array_replace_recursive([ 'username' => null, 'password' => null, ], - 'routerCacheFile' => __DIR__ . '/../resources/cache/routes.cache.php', ], require __DIR__ . '/../config.php'); +if (!$config['displayErrorDetails']) { + $config['routerCacheFile'] = __DIR__ . '/../resources/cache/routes.cache.php'; +} + $container = new Container(['settings' => $config]); $container['logger'] = function ($container) { diff --git a/composer.json b/composer.json index b1997d5..63bc32e 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "sergix44/xbackbone", - "version": "2.0", + "version": "2.1", "description": "A lightweight ShareX PHP backend", "type": "project", "require": { diff --git a/package.json b/package.json index a4779e6..330b071 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "dependencies": { + "@fortawesome/fontawesome-free": "^5.4.1", "bootstrap": "^4.1.3", "clipboard": "^2.0.1", "highlightjs": "^9.10.0", "jquery": "^3.3.1", "popper.js": "^1.14.4", "tooltip.js": "^1.3.0", - "@fortawesome/fontawesome-free": "^5.4.1" + "video.js": "^7.3.0" }, "devDependencies": { "grunt": "^1.0", diff --git a/resources/templates/upload/public.twig b/resources/templates/upload/public.twig index 6f461db..c9faa0f 100644 --- a/resources/templates/upload/public.twig +++ b/resources/templates/upload/public.twig @@ -23,8 +23,20 @@
+ {% include 'comp/alert.twig' %}
+ {% if delete_token is not null %} +
+
+

Are you sure you want to delete this item? It will be gone forever!

+
+ + No +
+
+
+ {% endif %} {% if type starts with 'image' %}
@@ -48,11 +60,13 @@
{% elseif type starts with 'video' %} - +
+ +
{% else %}
diff --git a/src/css/app.css b/src/css/app.css index 50304c7..71567fb 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -60,4 +60,10 @@ body { height: 40px; line-height: 40px; text-align: right; +} + +.video-content { + width: 80%; + margin-right: auto; + margin-left: auto; } \ No newline at end of file