Moved some settings from admin to user side
Updated docs
This commit is contained in:
parent
50051b3691
commit
5a7ff39ce9
22 changed files with 335 additions and 109 deletions
|
@ -51,7 +51,7 @@ class LoginController extends Controller
|
|||
}
|
||||
|
||||
$username = param($request, 'username');
|
||||
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota`, `ldap` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
|
||||
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota`, `ldap`, `copy_raw` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
|
||||
|
||||
if ($this->config['ldap']['enabled'] && ($user->ldap ?? true)) {
|
||||
$user = $this->ldapLogin($request, $username, param($request, 'password'), $user);
|
||||
|
@ -80,6 +80,7 @@ class LoginController extends Controller
|
|||
$this->session->set('user_id', $user->id);
|
||||
$this->session->set('username', $user->username);
|
||||
$this->session->set('admin', $user->is_admin);
|
||||
$this->session->set('copy_raw', $user->copy_raw);
|
||||
$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);
|
||||
|
||||
$this->session->alert(lang('welcome', [$user->username]), 'info');
|
||||
|
|
|
@ -73,7 +73,7 @@ class DashboardController extends Controller
|
|||
'next' => $page < floor($query->getPages()),
|
||||
'previous' => $page >= 1,
|
||||
'current_page' => ++$page,
|
||||
'copy_url_behavior' => $this->getSetting('copy_url_behavior', 'off'),
|
||||
'copy_raw' => $this->session->get('copy_raw', false),
|
||||
'tags' => $tags,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -25,6 +25,8 @@ class ExportController extends Controller
|
|||
|
||||
$medias = $this->database->query('SELECT `uploads`.`filename`, `uploads`.`storage_path` FROM `uploads` WHERE `user_id` = ?', $user->id);
|
||||
|
||||
$this->logger->info("User $user->id, $user->name, exporting data...");
|
||||
|
||||
set_time_limit(0);
|
||||
ob_end_clean();
|
||||
|
||||
|
|
|
@ -59,14 +59,18 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
if (param($request, 'password') !== null && !empty(param($request, 'password'))) {
|
||||
$this->database->query('UPDATE `users` SET `email`=?, `password`=? WHERE `id` = ?', [
|
||||
$this->database->query('UPDATE `users` SET `email`=?, `password`=?, `hide_uploads`=?, `copy_raw`=? WHERE `id` = ?', [
|
||||
param($request, 'email'),
|
||||
password_hash(param($request, 'password'), PASSWORD_DEFAULT),
|
||||
param($request, 'hide_uploads') !== null ? 1 : 0,
|
||||
param($request, 'copy_raw') !== null ? 1 : 0,
|
||||
$user->id,
|
||||
]);
|
||||
} else {
|
||||
$this->database->query('UPDATE `users` SET `email`=? WHERE `id` = ?', [
|
||||
$this->database->query('UPDATE `users` SET `email`=?, `hide_uploads`=?, `copy_raw`=? WHERE `id` = ?', [
|
||||
param($request, 'email'),
|
||||
param($request, 'hide_uploads') !== null ? 1 : 0,
|
||||
param($request, 'copy_raw') !== null ? 1 : 0,
|
||||
$user->id,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -27,25 +27,24 @@ class SettingController extends Controller
|
|||
return redirect($response, route('system'));
|
||||
}
|
||||
|
||||
// registrations
|
||||
$this->updateSetting('register_enabled', param($request, 'register_enabled', 'off'));
|
||||
$this->updateSetting('hide_by_default', param($request, 'hide_by_default', 'off'));
|
||||
$this->updateSetting('quota_enabled', param($request, 'quota_enabled', 'off'));
|
||||
|
||||
// quota
|
||||
$this->updateSetting('quota_enabled', param($request, 'quota_enabled', 'off'));
|
||||
$this->updateSetting('default_user_quota', stringToBytes(param($request, 'default_user_quota', '1G')));
|
||||
$user = make(UserQuery::class)->get($request, $this->session->get('user_id'));
|
||||
$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);
|
||||
|
||||
$this->updateSetting('default_user_quota', stringToBytes(param($request, 'default_user_quota', '1G')));
|
||||
$this->updateSetting('copy_url_behavior', param($request, 'copy_url_behavior') === null ? 'default' : 'raw');
|
||||
|
||||
$this->applyTheme($request);
|
||||
$this->applyLang($request);
|
||||
$this->updateSetting('custom_head', param($request, 'custom_head'));
|
||||
|
||||
|
||||
$this->updateSetting('recaptcha_enabled', param($request, 'recaptcha_enabled', 'off'));
|
||||
$this->updateSetting('recaptcha_site_key', param($request, 'recaptcha_site_key'));
|
||||
$this->updateSetting('recaptcha_secret_key', param($request, 'recaptcha_secret_key'));
|
||||
|
||||
$this->applyTheme($request);
|
||||
$this->applyLang($request);
|
||||
|
||||
$this->logger->info("User $user->username updated the system settings.");
|
||||
$this->session->alert(lang('settings_saved'));
|
||||
|
||||
return redirect($response, route('system'));
|
||||
|
|
|
@ -30,6 +30,8 @@ class TagController extends Controller
|
|||
|
||||
[$id, $limit] = make(TagQuery::class)->addTag(param($request, 'tag'), param($request, 'mediaId'));
|
||||
|
||||
$this->logger->info("Tag added $id.");
|
||||
|
||||
return json($response, [
|
||||
'limitReached' => $limit,
|
||||
'tagId' => $id,
|
||||
|
@ -58,6 +60,8 @@ class TagController extends Controller
|
|||
throw new HttpNotFoundException($request);
|
||||
}
|
||||
|
||||
$this->logger->info("Tag removed ".param($request, 'tagId').', from media '.param($request, 'mediaId'));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ class UpgradeController extends Controller
|
|||
|
||||
return redirect($response, route('system'));
|
||||
}
|
||||
$this->logger->info('System update started.');
|
||||
|
||||
$config = require BASE_DIR.'config.php';
|
||||
$config['maintenance'] = true;
|
||||
|
@ -89,6 +90,8 @@ class UpgradeController extends Controller
|
|||
$updateZip->close();
|
||||
unlink($tmpFile);
|
||||
|
||||
$this->logger->info('System update completed.');
|
||||
|
||||
return redirect($response, urlFor('/install'));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class UploadController extends Controller
|
|||
$maxFileSize = min(stringToBytes(ini_get('post_max_size')), stringToBytes(ini_get('upload_max_filesize')));
|
||||
|
||||
return view()->render($response, 'upload/web.twig', [
|
||||
'max_file_size' => humanFileSize($maxFileSize)
|
||||
'max_file_size' => humanFileSize($maxFileSize),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,6 @@ class UploadController extends Controller
|
|||
*/
|
||||
public function uploadWeb(Request $request, Response $response): Response
|
||||
{
|
||||
if ($this->config['maintenance']) {
|
||||
$this->json['message'] = 'Endpoint under maintenance.';
|
||||
|
||||
return json($response, $this->json, 503);
|
||||
}
|
||||
|
||||
try {
|
||||
$file = $this->validateFile($request, $response);
|
||||
|
||||
|
@ -92,25 +86,15 @@ class UploadController extends Controller
|
|||
|
||||
try {
|
||||
$file = $this->validateFile($request, $response);
|
||||
} catch (ValidationException $e) {
|
||||
return $e->response();
|
||||
}
|
||||
|
||||
if (param($request, 'token') === null) {
|
||||
$this->json['message'] = 'Token not specified.';
|
||||
if (param($request, 'token') === null) {
|
||||
$this->json['message'] = 'Token not specified.';
|
||||
|
||||
return json($response, $this->json, 400);
|
||||
}
|
||||
return json($response, $this->json, 400);
|
||||
}
|
||||
|
||||
$user = $this->database->query('SELECT * FROM `users` WHERE `token` = ? LIMIT 1', param($request, 'token'))->fetch();
|
||||
$user = $this->database->query('SELECT * FROM `users` WHERE `token` = ? LIMIT 1', param($request, 'token'))->fetch();
|
||||
|
||||
if (!$user) {
|
||||
$this->json['message'] = 'Token specified not found.';
|
||||
|
||||
return json($response, $this->json, 404);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->validateUser($request, $response, $file, $user);
|
||||
} catch (ValidationException $e) {
|
||||
return $e->response();
|
||||
|
@ -174,6 +158,12 @@ class UploadController extends Controller
|
|||
*/
|
||||
protected function validateUser(Request $request, Response $response, UploadedFileInterface $file, $user)
|
||||
{
|
||||
if (!$user) {
|
||||
$this->json['message'] = 'Token specified not found.';
|
||||
|
||||
throw new ValidationException(json($response, $this->json, 404));
|
||||
}
|
||||
|
||||
if (!$user->active) {
|
||||
$this->json['message'] = 'Account disabled.';
|
||||
|
||||
|
@ -196,11 +186,6 @@ class UploadController extends Controller
|
|||
$code = humanRandomString();
|
||||
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
|
||||
|
||||
$published = 1;
|
||||
if ($this->getSetting('hide_by_default') === 'on') {
|
||||
$published = 0;
|
||||
}
|
||||
|
||||
$fileInfo = pathinfo($file->getClientFilename());
|
||||
$storagePath = "$user->user_code/$code.$fileInfo[extension]";
|
||||
|
||||
|
@ -211,7 +196,7 @@ class UploadController extends Controller
|
|||
$code,
|
||||
$file->getClientFilename(),
|
||||
$storagePath,
|
||||
$published,
|
||||
$user->hide_uploads == '1' ? 0 : 1,
|
||||
]);
|
||||
$mediaId = $this->database->getPdo()->lastInsertId();
|
||||
|
||||
|
|
|
@ -95,7 +95,10 @@ class UserController extends Controller
|
|||
param($request, 'password'),
|
||||
param($request, 'is_admin') !== null ? 1 : 0,
|
||||
param($request, 'is_active') !== null ? 1 : 0,
|
||||
$maxUserQuota
|
||||
$maxUserQuota,
|
||||
false,
|
||||
param($request, 'hide_uploads') !== null ? 1 : 0,
|
||||
param($request, 'copy_raw') !== null ? 1 : 0
|
||||
);
|
||||
|
||||
if (param($request, 'send_notification') !== null) {
|
||||
|
@ -186,7 +189,9 @@ class UserController extends Controller
|
|||
param($request, 'is_admin') !== null ? 1 : 0,
|
||||
param($request, 'is_active') !== null ? 1 : 0,
|
||||
$user->max_disk_quota,
|
||||
param($request, 'ldap') !== null ? 1 : 0
|
||||
param($request, 'ldap') !== null ? 1 : 0,
|
||||
param($request, 'hide_uploads') !== null ? 1 : 0,
|
||||
param($request, 'copy_raw') !== null ? 1 : 0
|
||||
);
|
||||
|
||||
if ($user->id === $this->session->get('user_id')) {
|
||||
|
|
|
@ -70,7 +70,6 @@ class UserQuery
|
|||
return $user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $email
|
||||
* @param string $username
|
||||
|
@ -80,9 +79,11 @@ class UserQuery
|
|||
* @param int $maxUserQuota
|
||||
* @param string|null $activateToken
|
||||
* @param int $ldap
|
||||
* @param int $hideUploads
|
||||
* @param int $copyRaw
|
||||
* @return bool|\PDOStatement|string
|
||||
*/
|
||||
public function create(string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null, int $ldap =0)
|
||||
public function create(string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null, int $ldap = 0, int $hideUploads = 0, int $copyRaw = 0)
|
||||
{
|
||||
do {
|
||||
$userCode = humanRandomString(5);
|
||||
|
@ -90,7 +91,7 @@ class UserQuery
|
|||
|
||||
$token = $this->generateUserUploadToken();
|
||||
|
||||
return $this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`, `activate_token`, `ldap`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
||||
return $this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`, `activate_token`, `ldap`, `hide_uploads`, `copy_raw`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
||||
$email,
|
||||
$username,
|
||||
$password !== null ? password_hash($password, PASSWORD_DEFAULT) : null,
|
||||
|
@ -100,7 +101,9 @@ class UserQuery
|
|||
$token,
|
||||
$maxUserQuota,
|
||||
$activateToken,
|
||||
$ldap
|
||||
$ldap,
|
||||
$hideUploads,
|
||||
$copyRaw,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -113,12 +116,14 @@ class UserQuery
|
|||
* @param int $isActive
|
||||
* @param int $maxUserQuota
|
||||
* @param int $ldap
|
||||
* @param int $hideUploads
|
||||
* @param int $copyRaw
|
||||
* @return bool|\PDOStatement|string
|
||||
*/
|
||||
public function update($id, string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, int $ldap = 0)
|
||||
public function update($id, string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, int $ldap = 0, int $hideUploads = 0, int $copyRaw = 0)
|
||||
{
|
||||
if (!empty($password)) {
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=? WHERE `id` = ?', [
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=?, `hide_uploads`=?, `copy_raw`=? WHERE `id` = ?', [
|
||||
$email,
|
||||
$username,
|
||||
password_hash($password, PASSWORD_DEFAULT),
|
||||
|
@ -126,16 +131,20 @@ class UserQuery
|
|||
$isActive,
|
||||
$maxUserQuota,
|
||||
$ldap,
|
||||
$hideUploads,
|
||||
$copyRaw,
|
||||
$id,
|
||||
]);
|
||||
} else {
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=? WHERE `id` = ?', [
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=?, `hide_uploads`=?, `copy_raw`=? WHERE `id` = ?', [
|
||||
$email,
|
||||
$username,
|
||||
$isAdmin,
|
||||
$isActive,
|
||||
$maxUserQuota,
|
||||
$ldap,
|
||||
$hideUploads,
|
||||
$copyRaw,
|
||||
$id,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ Some functions that every user that use XBackBone should know:
|
|||
+ (`v3.1`+) With the right click on the uploaded media, you can select them, and then remove them in bulk.
|
||||
+ (`v3.1`+) You can add additional tag to your uploads, clicking on the **+** button on the media.
|
||||
+ (`v3.1`+) You can add you can delete tags, by right-click on them.
|
||||
+ (`v3.1`+) You can choose in your profile options if hide the uploads by default.
|
||||
+ (`v3.1`+) You can choose in your profile options if always copy the raw url (from the web interface).
|
||||
|
||||
## Administrator
|
||||
In addition, from the system page, and administrator can:
|
||||
|
|
195
docs/changelog.md
Normal file
195
docs/changelog.md
Normal file
|
@ -0,0 +1,195 @@
|
|||
---
|
||||
layout: default
|
||||
title: Changelog
|
||||
nav_order: 8
|
||||
---
|
||||
|
||||
## v.3.1 (WIP)
|
||||
+ Added tagging system (add, delete, search of tagged files).
|
||||
+ Added basic media auto-tagging on upload.
|
||||
+ Added registration system.
|
||||
+ Added password recovery system.
|
||||
+ Added ability to export all media of an account.
|
||||
+ Added ability to choose between default and raw url on copy.
|
||||
+ Added hide by default option.
|
||||
+ Added user disk quota.
|
||||
+ Added reCAPTCHA login protection.
|
||||
+ Added bulk delete.
|
||||
+ Added account clean function.
|
||||
+ Added user disk quota system.
|
||||
+ Added notification option on account create.
|
||||
+ Added LDAP authentication.
|
||||
+ Fixed bug html files raws are rendered in a browser.
|
||||
+ The theme is now re-applied after every system update.
|
||||
+ Updated system settings page.
|
||||
+ Updated translations.
|
||||
+ Improved grid layout.
|
||||
+ Fixes and improvements.
|
||||
|
||||
## v.3.0.2
|
||||
+ Fixed error with migrate command.
|
||||
+ Updated translations.
|
||||
|
||||
## v.3.0.1
|
||||
+ Fixed error with older mysql versions.
|
||||
+ Fixed config is compiled with the di container.
|
||||
+ Small installer update.
|
||||
|
||||
## v.3.0
|
||||
+ Upgraded from Slim3 to Slim 4.
|
||||
+ Added web upload.
|
||||
+ Added ability to add custom HTML in \<head\> tag.
|
||||
+ Added ability to show a preview of PDF files.
|
||||
+ Added remember me functionality.
|
||||
+ Added delete button on the preview page if the user is logged in.
|
||||
+ New project icon (by [@SerenaItalia](https://www.deviantart.com/serenaitalia)).
|
||||
+ Raw URL now accept file extensions.
|
||||
+ The linux script can be used on headless systems.
|
||||
+ Improved installer.
|
||||
+ Improved thumbnail generation.
|
||||
+ Replaced videojs player with Plyr.
|
||||
+ Implemented SameSite XSS protection.
|
||||
+ Small fixes and improvements.
|
||||
|
||||
## v.2.6.6
|
||||
+ Ability to choose between releases and prereleases with the web updater.
|
||||
+ Updated translations.
|
||||
|
||||
## v2.6.5
|
||||
+ Fixed error after orphaned files removal #74.
|
||||
+ Fixed update password not correctly removed from log files #74.
|
||||
+ Changed color to some buttons to address visibility with some themes.
|
||||
|
||||
## v2.6.4
|
||||
+ Filter on displayable images.
|
||||
+ Fixed during upload error on php compiled for 32 bit.
|
||||
+ Fixed icons on the installer page.
|
||||
+ The generated random strings are now more human readable.
|
||||
|
||||
## v2.6.3
|
||||
+ Fixed #67.
|
||||
+ Fixed bad preload statement.
|
||||
+ Fixed wrong redirect after install in subdirs.
|
||||
|
||||
## v2.6.2
|
||||
+ Use the font awesome web font for better performances.
|
||||
+ Changed background default color.
|
||||
+ Added method for cache busting when updating/change theme.
|
||||
+ Added russian translation from [Weblate](https://hosted.weblate.org/projects/xbackbone/xbackbone/).
|
||||
|
||||
## v2.6.1
|
||||
+ Fixed bad redirects on the web installer (#62).
|
||||
+ Fixed login page with dark themes.
|
||||
+ Improved shell commands.
|
||||
+ Added alert if required extensions are not loaded.
|
||||
+ Updated translations.
|
||||
|
||||
## v2.6
|
||||
+ Added support to use AWS S3, Google Cloud Storage, Dropbox and FTP(s) accounts as storage location.
|
||||
+ Fixed missing icon.
|
||||
+ Added german and norwegian translations from [Weblate](https://hosted.weblate.org/projects/xbackbone/xbackbone/).
|
||||
+ Improved lang detection.
|
||||
+ Added ability to force system language.
|
||||
|
||||
## v2.5.3
|
||||
+ Fixed bad css loading on Firefox (#35).
|
||||
+ Fixed wrong style for publish/unpublish button.
|
||||
+ Improved exception stacktrace logging.
|
||||
|
||||
## v2.5.2
|
||||
+ Improved session handling.
|
||||
+ Fixed telegram share not working.
|
||||
+ Fix for big text file now are not rendered in the browser.
|
||||
+ Added preloading for some resources to improve performances.
|
||||
+ Added check for block execution on EOL and unsupported PHP versions.
|
||||
+ Other minor improvements.
|
||||
|
||||
## v2.5.1
|
||||
+ Fixed bad redirect if the theme folder is not writable. (#27)
|
||||
+ Improved HTTP partial content implementation for large files.
|
||||
|
||||
## v2.5
|
||||
+ Updated project license to <a href="https://choosealicense.com/licenses/agpl-3.0/">AGPL v3.0</a> (now releases ships with the new license).
|
||||
+ **[BETA]** Added self update feature.
|
||||
+ Added partial content implementation (stream seeking on chromium based browsers).
|
||||
+ Improved video.js alignment with large videos.
|
||||
+ Optimized output zip release size.
|
||||
+ Templates cleanup and optimizations.
|
||||
+ Improved error handling.
|
||||
+ Added project favicon.
|
||||
|
||||
## v2.4.1
|
||||
+ Fixed error message when the file is too large. (#15)
|
||||
+ Fixed button alignment.
|
||||
|
||||
## v2.4
|
||||
+ Added function to remove orphaned files.
|
||||
+ Switch between tab and gallery mode using an admin account.
|
||||
+ Multiple uploads sorting methods.
|
||||
+ Search in uploads.
|
||||
+ Internal refactoring and improvements
|
||||
+ Updated js dependencies.
|
||||
|
||||
## v2.3.1
|
||||
+ Fixed en lang.
|
||||
+ Fixed forced background with dark themes.
|
||||
+ Added checks during the installation wizard.
|
||||
+ cURL and Wget can now directly download the file.
|
||||
|
||||
## v2.3
|
||||
+ Improved image scaling in user gallery.
|
||||
+ Added overlay on user gallery images.
|
||||
+ Fixed IT translation.
|
||||
+ Fontawesome icon match the single file mime-type.
|
||||
+ Enable audio player with video.js.
|
||||
+ Video and audio now starts with volume at 50%.
|
||||
+ Added linux script to allow uploads from linux screenshot tools.
|
||||
+ Minor layout fixes.
|
||||
|
||||
## v2.2
|
||||
+ Added multi-language support.
|
||||
+ Improved routing.
|
||||
+ Fixed HTTP/2 push is resetting the current session.
|
||||
+ Minor improvements and bug fixes.
|
||||
|
||||
## 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).
|
||||
+ Allow discord bot to display the preview.
|
||||
+ Theme switcher on the web UI.
|
||||
+ Added used space indicator per user.
|
||||
+ MySQL support.
|
||||
+ Improvements under the hood.
|
||||
|
||||
## v1.3
|
||||
+ Added command to switch between bootswatch.com themes.
|
||||
+ Added popever to write the telegram message when sharing.
|
||||
+ Packaging improvements.
|
||||
+ Updated some dependencies.
|
||||
+ Allow Facebook bots to display the preview.
|
||||
|
||||
## v1.2
|
||||
+ Previews are now scaled for better page load.
|
||||
+ Added auto config generator for ShareX.
|
||||
+ Show upload file size on the dashboard.
|
||||
+ Fixed insert for admin user (running `php bin\migrate --install`).
|
||||
+ Removed HTTP2 push from the dashboard to improve loading time.
|
||||
|
||||
## 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.
|
|
@ -6,11 +6,11 @@ nav_order: 7
|
|||
|
||||
# Common Issues
|
||||
|
||||
#### Error 404 after installation
|
||||
### Error 404 after installation
|
||||
If you have apache, check if it's reading the file `.htaccess` and the `mod_rewrite` is enabled.
|
||||
|
||||
#### [Discord, Telegram, ...] is not showing the image/video preview of the link.
|
||||
### [Discord, Telegram, ...] is not showing the image/video preview of the link.
|
||||
If you have Cloudflare enabled, check if it's blocking bots. If this function is enabled the Discord bot, Telebot, etc that fetch the preview will be blocked.
|
||||
|
||||
#### How to increase the max file size?
|
||||
### How to increase the max file size?
|
||||
Increase the post_max_size and upload_max_filesize in your php.ini
|
|
@ -11,11 +11,12 @@ nav_order: 1
|
|||
XBackBone is a simple and lightweight PHP file manager that support the instant sharing tool ShareX and *NIX systems. It supports uploading and displaying images, GIF, video, code, formatted text, pdf, and file downloading and uploading. Also have a web UI with multi user management, media gallery and search support.
|
||||
{: .fs-5 .fw-300 }
|
||||
|
||||
<p align="center">
|
||||
[Download](https://github.com/SergiX44/XBackBone/releases/latest){: .btn .btn-green }
|
||||
[GitHub](https://github.com/SergiX44/XBackBone){: .btn .btn-blue }
|
||||
</p>
|
||||
|
||||
## Main Features
|
||||
|
||||
+ Supports every upload type from ShareX.
|
||||
+ Config generator for ShareX.
|
||||
+ Low memory footprint.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
layout: default
|
||||
title: License & Credits
|
||||
nav_order: 8
|
||||
nav_order: 9
|
||||
---
|
||||
|
||||
# License
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `hide_uploads` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `copy_raw` BOOLEAN NOT NULL DEFAULT 0;
|
|
@ -1 +1,3 @@
|
|||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `hide_uploads` BOOLEAN NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `users` ADD COLUMN `copy_raw` BOOLEAN NOT NULL DEFAULT 0;
|
|
@ -19,7 +19,7 @@
|
|||
<div class="pl-3 pt-2d5"><span class="badge badge-dark shadow-lg">{{ media.size }}</span></div>
|
||||
<div class="text-right pr-3 pt-2d5">
|
||||
<div class="btn-group shadow-lg">
|
||||
<button type="button" class="btn btn-sm btn-success btn-clipboard" data-toggle="tooltip" title="{{ lang('copy_link') }}" data-clipboard-text="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension) }}{{ copy_url_behavior == 'raw' ? '/raw' }}">
|
||||
<button type="button" class="btn btn-sm btn-success btn-clipboard" data-toggle="tooltip" title="{{ lang('copy_link') }}" data-clipboard-text="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension) }}{{ copy_raw ? '/raw' }}">
|
||||
<i class="fas fa-link"></i>
|
||||
</button>
|
||||
<a href="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension ~ '/download') }}" class="btn btn-sm btn-secondary" data-toggle="tooltip" title="{{ lang('download') }}"><i class="fas fa-cloud-download-alt"></i></a>
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
{% if media.username is not null %}
|
||||
<a href="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension) }}" class="btn btn-sm btn-outline-secondary" data-toggle="tooltip" title="{{ lang('open') }}" target="_blank"><i class="fas fa-external-link-alt"></i></a>
|
||||
<a href="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension ~ '/download') }}" class="btn btn-sm btn-outline-primary" data-toggle="tooltip" title="{{ lang('download') }}"><i class="fas fa-cloud-download-alt"></i></a>
|
||||
<a href="javascript:void(0)" class="btn btn-sm btn-outline-success btn-clipboard" data-toggle="tooltip" title="{{ lang('copy_link') }}" data-clipboard-text="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension) }}{{ copy_url_behavior == 'raw' ? '/raw' }}"><i class="fas fa-link"></i></a>
|
||||
<a href="javascript:void(0)" class="btn btn-sm btn-outline-success btn-clipboard" data-toggle="tooltip" title="{{ lang('copy_link') }}" data-clipboard-text="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension) }}{{ copy_raw ? '/raw' }}"><i class="fas fa-link"></i></a>
|
||||
{% else %}
|
||||
<a href="{{ route('upload.raw', {'id': media.id}) }}" class="btn btn-sm btn-outline-dark" data-toggle="tooltip" title="{{ lang('raw') }}" target="_blank"><i class="fas fa-external-link-alt"></i></a>
|
||||
{% endif %}
|
||||
|
|
|
@ -65,18 +65,6 @@
|
|||
<input type="checkbox" name="register_enabled" data-toggle="toggle" {{ register_enabled == 'on' ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="hide_by_default" class="col-sm-4 col-form-label">{{ lang('hide_by_default') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="hide_by_default" data-toggle="toggle" {{ hide_by_default == 'on' ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="copy_url_behavior" class="col-sm-4 col-form-label">{{ lang('copy_url_behavior') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="copy_url_behavior" data-toggle="toggle" data-off="Default URL" data-on="Raw URL" data-onstyle="primary" data-offstyle="secondary" {{ copy_url_behavior == 'raw' ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="themes" class="col-sm-4 col-form-label">{{ lang('theme') }}</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -13,54 +13,66 @@
|
|||
<div class="card-body">
|
||||
<form method="post" action="{{ route('user.store') }}">
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-sm-2 col-form-label">E-Mail</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="email" class="col-sm-3 col-form-label">E-Mail</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="email" class="form-control" id="email" placeholder="email@example.com" name="email" autocomplete="off" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-sm-2 col-form-label">{{ lang('username') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="email" class="col-sm-3 col-form-label">{{ lang('username') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="username" placeholder="{{ lang('username') }}" name="username" autocomplete="off" required >
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-sm-2 col-form-label">{{ lang('password') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="password" class="col-sm-3 col-form-label">{{ lang('password') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="password" class="form-control" id="password" placeholder="{{ lang('password') }}" name="password" autocomplete="off">
|
||||
<small>{{ lang('user_create_password') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="hide_uploads" class="col-sm-3 col-form-label">{{ lang('hide_by_default') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="hide_uploads" data-toggle="toggle">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="copy_raw" class="col-sm-3 col-form-label">{{ lang('copy_url_behavior') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="copy_raw" data-toggle="toggle" data-off="Default URL" data-on="Raw URL" data-onstyle="primary" data-offstyle="secondary">
|
||||
</div>
|
||||
</div>
|
||||
{% if quota_enabled == 'on' %}
|
||||
<div class="form-group row">
|
||||
<label for="max_user_quota" class="col-sm-2 col-form-label">{{ lang('max_user_quota') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="max_user_quota" class="col-sm-3 col-form-label">{{ lang('max_user_quota') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="max_user_quota" name="max_user_quota" pattern="([0-9]+[K|M|G|T])|(\-1)" title="512M, 2G, 1T, ..." placeholder="1G" value="{{ default_user_quota }}" required>
|
||||
<small>512M, 2G, 1T, ... (-1=∞)</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="form-group row">
|
||||
<label for="is_admin" class="col-sm-2 col-form-label">{{ lang('is_admin') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="is_admin" class="col-sm-3 col-form-label">{{ lang('is_admin') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="is_admin" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="is_active" class="col-sm-2 col-form-label">{{ lang('is_active') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="is_active" class="col-sm-3 col-form-label">{{ lang('is_active') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="is_active" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}" checked>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group row">
|
||||
<label for="send_notification" class="col-sm-2 col-form-label">{{ lang('send_notification') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="send_notification" class="col-sm-3 col-form-label">{{ lang('send_notification') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="send_notification" data-toggle="toggle" data-onstyle="info" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row justify-content-md-end">
|
||||
<div class="col-sm-10">
|
||||
<div class="col-sm-9">
|
||||
<button type="submit" class="btn btn-outline-success">
|
||||
<i class="fas fa-save fa-fw"></i> {{ lang('save') }}
|
||||
</button>
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
<div class="card-body">
|
||||
<form method="post" action="{{ route( (profile ? 'profile.update' : 'user.update'), {'id': user.id}) }}">
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="email" class="col-sm-3 col-form-label">Email</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="email" class="form-control" id="email" placeholder="email@example.com" name="email" value="{{ user.email }}" autocomplete="off" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-2 col-form-label">{{ lang('username') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="username" class="col-sm-3 col-form-label">{{ lang('username') }}</label>
|
||||
<div class="col-sm-9">
|
||||
{% if profile %}
|
||||
<input type="text" class="form-control disabled" id="username" value="{{ user.username }}" readonly>
|
||||
{% else %}
|
||||
|
@ -31,14 +31,14 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-sm-2 col-form-label">{{ lang('password') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="password" class="col-sm-3 col-form-label">{{ lang('password') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="password" class="form-control" id="password" placeholder="{{ lang('password') }}" name="password" autocomplete="off"{{ user.ldap ? ' disabled' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="token" class="col-sm-2 col-form-label">{{ lang('token') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="token" class="col-sm-3 col-form-label">{{ lang('token') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input type="text" id="token" class="form-control" value="{{ user.token }}" readonly>
|
||||
<div class="input-group-append">
|
||||
|
@ -49,8 +49,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">{{ lang('client_config') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="hide_uploads" class="col-sm-3 col-form-label">{{ lang('hide_by_default') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="hide_uploads" data-toggle="toggle" {{ user.hide_uploads ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="copy_raw" class="col-sm-3 col-form-label">{{ lang('copy_url_behavior') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="copy_raw" data-toggle="toggle" data-off="Default URL" data-on="Raw URL" data-onstyle="primary" data-offstyle="secondary" {{ user.copy_raw ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">{{ lang('client_config') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="btn-group">
|
||||
<a href="{{ route('config.sharex', {'id': user.id}) }}" class="btn btn-lg btn-outline-dark"><i class="fas fa-fw fa-download"></i> ShareX Config</a>
|
||||
<a href="{{ route('config.script', {'id': user.id}) }}" class="btn btn-lg btn-outline-danger"><i class="fas fa-fw fa-download"></i> Linux Script</a>
|
||||
|
@ -58,8 +70,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">{{ lang('export_data') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="col-sm-3 col-form-label">{{ lang('export_data') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="btn-group">
|
||||
<a href="{{ route('export.data', {'id': user.id}) }}" class="btn btn-lg btn-outline-warning"><i class="fas fa-fw fa-file-archive"></i> {{ lang('download') }}</a>
|
||||
</div>
|
||||
|
@ -70,36 +82,36 @@
|
|||
<hr>
|
||||
{% if quota_enabled == 'on' %}
|
||||
<div class="form-group row">
|
||||
<label for="max_user_quota" class="col-sm-2 col-form-label">{{ lang('max_user_quota') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="max_user_quota" class="col-sm-3 col-form-label">{{ lang('max_user_quota') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="max_user_quota" name="max_user_quota" pattern="([0-9]+[K|M|G|T])|(\-1)" title="512M, 2G, 1T, ..." placeholder="1G" value="{{ max_disk_quota }}" required>
|
||||
<small>512M, 2G, 1T, ... (-1=∞)</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="form-group row">
|
||||
<label for="is_admin" class="col-sm-2 col-form-label">{{ lang('is_admin') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="is_admin" class="col-sm-3 col-form-label">{{ lang('is_admin') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="is_admin" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}" {{ user.is_admin ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="is_active" class="col-sm-2 col-form-label">{{ lang('is_active') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="is_active" class="col-sm-3 col-form-label">{{ lang('is_active') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="is_active" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}" {{ user.active ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
{% if config.ldap.enabled %}
|
||||
<div class="form-group row">
|
||||
<label for="ldap" class="col-sm-2 col-form-label">LDAP Auth</label>
|
||||
<div class="col-sm-10">
|
||||
<label for="ldap" class="col-sm-3 col-form-label">LDAP Auth</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="checkbox" name="ldap" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}" {{ user.ldap ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">{{ lang('delete_all') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="col-sm-3 col-form-label">{{ lang('delete_all') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="btn-group">
|
||||
<a href="{{ route('user.clear', {'id': user.id}) }}" class="btn btn-lg btn-outline-danger"><i class="fas fa-fw fa-recycle"></i> {{ lang('clear_account') }}</a>
|
||||
</div>
|
||||
|
@ -107,7 +119,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
<div class="form-group row justify-content-md-end">
|
||||
<div class="col-sm-10">
|
||||
<div class="col-sm-9">
|
||||
<button type="submit" class="btn btn-outline-info">
|
||||
<i class="fas fa-save fa-fw"></i> {{ lang('save') }}
|
||||
</button>
|
||||
|
|
Loading…
Reference in a new issue