-
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
168 changed files
with
42,650 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.idea/ | ||
vendor/ | ||
storage/ | ||
!resources/cache/.gitkeep | ||
resources/database/*.db | ||
resources/sessions/sess_* | ||
logs/log-*.txt | ||
config.php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Options -Indexes | ||
RewriteEngine On | ||
RewriteRule ^(app|bin|bootstrap|resources|storage|vendor|logs)(/.*|)$ - [NC,F] | ||
RewriteCond %{REQUEST_FILENAME} !-f | ||
RewriteCond %{REQUEST_FILENAME} !-d | ||
RewriteRule ^(.*)$ index.php [QSA,L] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
## v1.1 | ||
+ Added logging. | ||
+ Fixed back to top when click delete or publish/unpublish. | ||
+ Improved migrate system. | ||
+ Login redirect back to the requested page. | ||
+ Updated Bootstrap theme. | ||
+ Added share to Telegram. | ||
|
||
## v1.0 | ||
+ Initial version. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# XBackBone 📤 | ||
XBackBone is a simple, self-hosted, lightweight PHP backend for the instant sharing tool ShareX. It supports uploading and displaying images, GIF, video, code, formatted text, and file downloading and uploading. Also have a web UI with multi user managemant and past uploads history. | ||
|
||
## Features | ||
|
||
+ Supports every upload type from ShareX. | ||
+ User management, multi user features. | ||
+ Public and private uploads. | ||
+ Web UI for each user. | ||
+ Logging system. | ||
|
||
## How to Install | ||
XBackBone require PHP >= `7.1`, the composer package manager and writable storage path: | ||
|
||
+ Clone this repository in your web root folder: | ||
|
||
```sh | ||
git clone http://github.com/SergiX44/XBackBone . | ||
``` | ||
+ Run a composer from your shell: | ||
|
||
```sh | ||
composer install --no-dev | ||
``` | ||
+ Setup the config file: | ||
|
||
```sh | ||
cp config.example.php config.php | ||
``` | ||
By default, XBackBone will use Sqlite as DB engine, and a `storage` dir in the current directory. You can leave these settings unchanged for a simple personal installation. | ||
You must set the `base_url`, or remove it for get dynamically the url from request (not raccomanded). | ||
|
||
```php | ||
return [ | ||
'base_url' => 'https://myaswesomedomain.com', // no trailing slash | ||
'storage_dir' => 'storage', | ||
'db' => [ | ||
'connection' => 'sqlite', | ||
'dsn' => 'resources/database/xbackbone.db', | ||
'username' => null, // username and password not needed for sqlite | ||
'password' => null, | ||
] | ||
]; | ||
``` | ||
+ Finally, run the migrate script to setup the database | ||
|
||
```sh | ||
php bin/migrate --install | ||
``` | ||
+ Now just login with `admin/admin`, **be sure to change these credentials after your first login**. | ||
|
||
## Notes | ||
If you do not use Apache, or the Apache `.htaccess` is not enabled, set your web server so that the `static/` folder is the only one accessible from the outside, otherwise even private uploads and logs will be accessible! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
namespace App\Controllers; | ||
|
||
|
||
use App\Exceptions\AuthenticationException; | ||
use App\Exceptions\UnauthorizedException; | ||
use App\Web\Session; | ||
use Flight; | ||
use League\Flysystem\Adapter\Local; | ||
use League\Flysystem\Filesystem; | ||
|
||
abstract class Controller | ||
{ | ||
|
||
/** | ||
* @throws AuthenticationException | ||
*/ | ||
protected function checkLogin(): void | ||
{ | ||
if (!Session::get('logged', false)) { | ||
Session::set('redirectTo', (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); | ||
throw new AuthenticationException(); | ||
} | ||
} | ||
|
||
/** | ||
* @throws AuthenticationException | ||
* @throws UnauthorizedException | ||
*/ | ||
protected function checkAdmin(): void | ||
{ | ||
$this->checkLogin(); | ||
if (!Session::get('admin', false)) { | ||
throw new UnauthorizedException(); | ||
} | ||
} | ||
|
||
|
||
protected function humanFilesize($size, $precision = 2): string | ||
{ | ||
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) { | ||
} | ||
return round($size, $precision) . ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i]; | ||
} | ||
|
||
protected function getStorage(): Filesystem | ||
{ | ||
return new Filesystem(new Local(Flight::get('config')['storage_dir'])); | ||
} | ||
|
||
protected function http2push(string $url, string $as = 'image'): void | ||
{ | ||
if (Flight::request()->scheme === 'HTTP/2.0') { | ||
$headers = isset(Flight::response()->headers()['Link']) ? Flight::response()->headers()['Link'] : []; | ||
$headers[] = "<${url}>; rel=preload; as=${as}"; | ||
Flight::response()->header('Link', $headers); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace App\Controllers; | ||
|
||
|
||
use App\Database\DB; | ||
use App\Traits\SingletonController; | ||
use App\Web\Session; | ||
use Flight; | ||
use League\Flysystem\FileNotFoundException; | ||
|
||
class DashboardController extends Controller | ||
{ | ||
use SingletonController; | ||
|
||
const PER_PAGE = 21; | ||
const PER_PAGE_ADMIN = 50; | ||
|
||
public function redirects(): void | ||
{ | ||
$this->checkLogin(); | ||
Flight::redirect('/home'); | ||
} | ||
|
||
public function home($page = 1): void | ||
{ | ||
$this->checkLogin(); | ||
|
||
$page = max(0, --$page); | ||
|
||
if (Session::get('admin', false)) { | ||
$medias = DB::query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` ORDER BY `timestamp` DESC LIMIT ? OFFSET ?', [self::PER_PAGE_ADMIN, $page * self::PER_PAGE_ADMIN])->fetchAll(); | ||
$pages = DB::query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count / self::PER_PAGE_ADMIN; | ||
} else { | ||
$medias = DB::query('SELECT `uploads`.*,`users`.`user_code`, `users`.`username` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? ORDER BY `timestamp` DESC LIMIT ? OFFSET ?', [Session::get('user_id'), self::PER_PAGE, $page * self::PER_PAGE])->fetchAll(); | ||
$pages = DB::query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` = ?', Session::get('user_id'))->fetch()->count / self::PER_PAGE; | ||
} | ||
|
||
$filesystem = $this->getStorage(); | ||
$base_url = Flight::get('config')['base_url']; | ||
|
||
foreach ($medias as $media) { | ||
$extension = pathinfo($media->filename, PATHINFO_EXTENSION); | ||
try { | ||
$mime = $filesystem->getMimetype($media->storage_path); | ||
} catch (FileNotFoundException $e) { | ||
$mime = null; | ||
} | ||
$media->mimetype = $mime; | ||
$media->extension = $extension; | ||
|
||
if ($type = explode('/', $mime)[0] === 'image') { | ||
$this->http2push("$base_url/$media->user_code/$media->code.$extension/raw"); | ||
} | ||
} | ||
|
||
Flight::render( | ||
Session::get('admin', false) ? 'dashboard/admin.twig' : 'dashboard/home.twig', | ||
[ | ||
'medias' => $medias, | ||
'next' => $page < floor($pages), | ||
'previous' => $page >= 1, | ||
'current_page' => ++$page, | ||
] | ||
); | ||
} | ||
|
||
public function system() | ||
{ | ||
$this->checkAdmin(); | ||
|
||
$usersCount = DB::query('SELECT COUNT(*) AS `count` FROM `users`')->fetch()->count; | ||
$mediasCount = DB::query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count; | ||
$orphanFilesCount = DB::query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` IS NULL')->fetch()->count; | ||
|
||
$medias = DB::query('SELECT `users`.`user_code`, `uploads`.`code`, `uploads`.`storage_path` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id`')->fetchAll(); | ||
|
||
$totalSize = 0; | ||
|
||
$filesystem = $this->getStorage(); | ||
foreach ($medias as $media) { | ||
$totalSize += $filesystem->getSize($media->storage_path); | ||
} | ||
|
||
Flight::render('dashboard/system.twig', [ | ||
'usersCount' => $usersCount, | ||
'mediasCount' => $mediasCount, | ||
'orphanFilesCount' => $orphanFilesCount, | ||
'totalSize' => $this->humanFilesize($totalSize), | ||
'max_filesize' => ini_get('post_max_size') . '/' . ini_get('upload_max_filesize'), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace App\Controllers; | ||
|
||
|
||
use App\Database\DB; | ||
use App\Traits\SingletonController; | ||
use App\Web\Log; | ||
use App\Web\Session; | ||
use Flight; | ||
|
||
class LoginController extends Controller | ||
{ | ||
use SingletonController; | ||
|
||
public function show(): void | ||
{ | ||
if (Session::get('logged', false)) { | ||
Flight::redirect('/home'); | ||
return; | ||
} | ||
Flight::render('auth/login.twig'); | ||
} | ||
|
||
public function login(): void | ||
{ | ||
$form = Flight::request()->data; | ||
|
||
$result = DB::query('SELECT `id`,`username`, `password`,`is_admin`, `active` FROM `users` WHERE `username` = ? LIMIT 1', $form->username)->fetch(); | ||
|
||
if (!$result || !password_verify($form->password, $result->password)) { | ||
Flight::redirect('login'); | ||
Session::alert('Wrong credentials', 'danger'); | ||
return; | ||
} | ||
|
||
if (!$result->active) { | ||
Flight::redirect('login'); | ||
Session::alert('Your account is disabled.', 'danger'); | ||
return; | ||
} | ||
|
||
Session::set('logged', true); | ||
Session::set('user_id', $result->id); | ||
Session::set('username', $result->username); | ||
Session::set('admin', $result->is_admin); | ||
|
||
Session::alert("Welcome, $result->username!", 'info'); | ||
Log::info("User $result->username logged in."); | ||
|
||
if (Session::has('redirectTo')) { | ||
Flight::redirect(Session::get('redirectTo')); | ||
return; | ||
} | ||
|
||
Flight::redirect('/home'); | ||
} | ||
|
||
public function logout(): void | ||
{ | ||
$this->checkLogin(); | ||
Session::clear(); | ||
Session::set('logged', false); | ||
Session::alert('Goodbye!', 'warning'); | ||
Flight::redirect('/login'); | ||
} | ||
|
||
} |
Oops, something went wrong.