Completed user quota implementation

This commit is contained in:
Sergio Brighenti 2020-03-01 17:03:07 +01:00
parent a5b8db5330
commit 17c24860b2
19 changed files with 191 additions and 133 deletions

View file

@ -25,32 +25,22 @@ class AdminController extends Controller
*/
public function system(Request $request, Response $response): Response
{
$usersCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `users`')->fetch()->count;
$mediasCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count;
$orphanFilesCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` IS NULL')->fetch()->count;
$totalSize = $this->database->query('SELECT SUM(`current_disk_quota`) AS `sum` FROM `users`')->fetch()->sum ?? 0;
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
$hideByDefault = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'hide_by_default\'')->fetch()->value ?? 'off';
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value ?? 'off';
$quotaEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'quota_enabled\'')->fetch()->value ?? 'off';
$defaultUserQuota = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'default_user_quota\'')->fetch()->value ?? stringToBytes('1G');
return view()->render($response, 'dashboard/system.twig', [
'usersCount' => $usersCount,
'mediasCount' => $mediasCount,
'orphanFilesCount' => $orphanFilesCount,
'totalSize' => humanFileSize($totalSize),
'usersCount' => $usersCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `users`')->fetch()->count,
'mediasCount' => $mediasCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count,
'orphanFilesCount' => $orphanFilesCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` IS NULL')->fetch()->count,
'totalSize' => humanFileSize($totalSize = $this->database->query('SELECT SUM(`current_disk_quota`) AS `sum` FROM `users`')->fetch()->sum ?? 0),
'post_max_size' => ini_get('post_max_size'),
'upload_max_filesize' => ini_get('upload_max_filesize'),
'installed_lang' => $this->lang->getList(),
'forced_lang' => $request->getAttribute('forced_lang'),
'php_version' => phpversion(),
'max_memory' => ini_get('memory_limit'),
'register_enabled' => $registerEnabled,
'hide_by_default' => $hideByDefault,
'copy_url_behavior' => $copyUrl,
'quota_enabled' => $quotaEnabled,
'default_user_quota' => humanFileSize($defaultUserQuota, 0, true),
'register_enabled' => $this->getSetting('register_enabled', 'off'),
'hide_by_default' => $this->getSetting('hide_by_default', 'off'),
'copy_url_behavior' => $this->getSetting('copy_url_behavior', 'off'),
'quota_enabled' => $this->getSetting('quota_enabled', 'off'),
'default_user_quota' => humanFileSize($this->getSetting('default_user_quota', stringToBytes('1G')), 0, true),
]);
}

View file

@ -23,10 +23,8 @@ class LoginController extends Controller
return redirect($response, route('home'));
}
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
return view()->render($response, 'auth/login.twig', [
'register_enabled' => $registerEnabled,
'register_enabled' => $this->getSetting('register_enabled', 'off'),
]);
}
@ -41,35 +39,34 @@ class LoginController extends Controller
public function login(Request $request, Response $response): Response
{
$username = param($request, 'username');
$result = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active` 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` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
if (!$result || !password_verify(param($request, 'password'), $result->password)) {
if (!$user || !password_verify(param($request, 'password'), $user->password)) {
$this->session->alert(lang('bad_login'), 'danger');
return redirect($response, route('login'));
}
if (isset($this->config['maintenance']) && $this->config['maintenance'] && !$result->is_admin) {
if (isset($this->config['maintenance']) && $this->config['maintenance'] && !$user->is_admin) {
$this->session->alert(lang('maintenance_in_progress'), 'info');
return redirect($response, route('login'));
}
if (!$result->active) {
if (!$user->active) {
$this->session->alert(lang('account_disabled'), 'danger');
return redirect($response, route('login'));
}
$this->session->set('logged', true);
$this->session->set('user_id', $result->id);
$this->session->set('username', $result->username);
$this->session->set('admin', $result->is_admin);
// TODO: update
$this->session->set('used_space', humanFileSize($this->getUsedSpaceByUser($result->id)));
$this->session->set('user_id', $user->id);
$this->session->set('username', $user->username);
$this->session->set('admin', $user->is_admin);
$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);
$this->session->alert(lang('welcome', [$result->username]), 'info');
$this->logger->info("User $result->username logged in.");
$this->session->alert(lang('welcome', [$user->username]), 'info');
$this->logger->info("User $user->username logged in.");
if (param($request, 'remember') === 'on') {
$this->refreshRememberCookie($result->id);
$this->refreshRememberCookie($user->id);
}
if ($this->session->has('redirectTo')) {

View file

@ -27,8 +27,7 @@ class RegisterController extends Controller
return redirect($response, route('home'));
}
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
if ($registerEnabled === 'off') {
if ($this->getSetting('register_enabled', 'off') === 'off') {
throw new HttpNotFoundException($request);
}
@ -48,8 +47,7 @@ class RegisterController extends Controller
return redirect($response, route('home'));
}
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
if ($registerEnabled === 'off') {
if ($this->getSetting('register_enabled', 'off') === 'off') {
throw new HttpNotFoundException($request);
}

View file

@ -53,13 +53,33 @@ abstract class Controller
}
/**
* @param $id
*
* @param $key
* @param null $default
* @return object
*/
protected function getUsedSpaceByUser($id)
protected function getSetting($key, $default = null)
{
return $this->database->query('SELECT `current_disk_quota`, `max_disk_quota` FROM `users` WHERE `id` = ?', $id)->fetch();
return $this->database->query('SELECT `value` FROM `settings` WHERE `key` = '.$this->database->getPdo()->quote($key))->fetch()->value ?? $default;
}
/**
* @param $current
* @param $max
*/
protected function setSessionQuotaInfo($current, $max)
{
$this->session->set('current_disk_quota', humanFileSize($current));
if ($this->getSetting('quota_enabled', 'off') === 'on') {
if ($max < 0) {
$this->session->set('max_disk_quota', '∞');
} else {
$this->session->set('max_disk_quota', humanFileSize($max));
$this->session->set('percent_disk_quota', round(($current * 100) / $max));
}
} else {
$this->session->set('max_disk_quota', null);
$this->session->set('percent_disk_quota', null);
}
}
/**
@ -80,8 +100,7 @@ abstract class Controller
} else {
$tot = $user->current_disk_quota + $fileSize;
$quotaEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'quota_enabled\'')->fetch()->value ?? 'off';
if ($quotaEnabled === 'on' && $user->max_disk_quota > 0 && $user->max_disk_quota < $tot) {
if ($this->getSetting('quota_enabled') === 'on' && $user->max_disk_quota > 0 && $user->max_disk_quota < $tot) {
return false;
}
}

View file

@ -9,8 +9,8 @@ use Psr\Http\Message\ServerRequestInterface as Request;
class DashboardController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
@ -24,15 +24,15 @@ class DashboardController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int|null $page
* @param Request $request
* @param Response $response
* @param int|null $page
*
* @throws \Twig\Error\LoaderError
* @return Response
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
* @throws \Twig\Error\LoaderError
*/
public function home(Request $request, Response $response, int $page = 0): Response
{
@ -58,23 +58,21 @@ class DashboardController extends Controller
->search(param($request, 'search', null))
->run($page);
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value ?? 'off';
return view()->render(
$response,
($this->session->get('admin', false) && $this->session->get('gallery_view', true)) ? 'dashboard/list.twig' : 'dashboard/grid.twig',
[
'medias' => $query->getMedia(),
'next' => $page < floor($query->getPages()),
'previous' => $page >= 1,
'medias' => $query->getMedia(),
'next' => $page < floor($query->getPages()),
'previous' => $page >= 1,
'current_page' => ++$page,
'copy_url_behavior' => $copyUrl,
'copy_url_behavior' => $this->getSetting('copy_url_behavior', 'off'),
]
);
}
/**
* @param Response $response
* @param Response $response
*
* @return Response
*/

View file

@ -66,14 +66,12 @@ class MediaController extends Controller
throw new HttpNotFoundException($request);
}
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value ?? 'off';
return view()->render($response, 'upload/public.twig', [
'delete_token' => $token,
'media' => $media,
'type' => $type,
'url' => urlFor("/{$userCode}/{$mediaCode}"),
'copy_url_behavior' => $copyUrl,
'copy_url_behavior' => $this->getSetting('copy_url_behavior', 'off'),
]);
}
@ -203,8 +201,10 @@ class MediaController extends Controller
$size = $this->deleteMedia($request, $media->storage_path, $id);
$this->updateUserQuota($request, $media->user_id, $size, true);
$this->logger->info('User '.$this->session->get('username').' deleted a media.', [$id]);
//TODO update
$this->session->set('used_space', humanFileSize($this->getUsedSpaceByUser($this->session->get('user_id'))));
if ($media->user_id === $this->session->get('user_id')) {
$user = $this->getUser($request, $media->user_id, true);
$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);
}
} else {
throw new HttpUnauthorizedException($request);
}

View file

@ -13,6 +13,8 @@ class SettingController extends Controller
* @param Response $response
*
* @return Response
* @throws \Slim\Exception\HttpNotFoundException
* @throws \Slim\Exception\HttpUnauthorizedException
*/
public function saveSettings(Request $request, Response $response): Response
{
@ -24,6 +26,10 @@ class SettingController extends Controller
$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'));
$user = $this->getUser($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');

View file

@ -38,9 +38,8 @@ class UploadController extends Controller
* @param Response $response
*
* @return Response
* @throws FileExistsException
* @throws \Exception
*
* @throws \Slim\Exception\HttpNotFoundException
* @throws \Slim\Exception\HttpUnauthorizedException
*/
public function upload(Request $request, Response $response): Response
{
@ -109,7 +108,7 @@ class UploadController extends Controller
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
$published = 1;
if (($this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'hide_by_default\'')->fetch()->value ?? 'off') === 'on') {
if ($this->getSetting('hide_by_default') === 'on') {
$published = 0;
}

View file

@ -12,14 +12,14 @@ class UserController extends Controller
const PER_PAGE = 15;
/**
* @param Response $response
* @param int|null $page
* @param Response $response
* @param int|null $page
*
* @throws \Twig\Error\LoaderError
* @return Response
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
* @throws \Twig\Error\LoaderError
*/
public function index(Response $response, int $page = 0): Response
{
@ -32,31 +32,35 @@ class UserController extends Controller
return view()->render($response,
'user/index.twig',
[
'users' => $users,
'next' => $page < floor($pages),
'previous' => $page >= 1,
'users' => $users,
'next' => $page < floor($pages),
'previous' => $page >= 1,
'current_page' => ++$page,
'quota_enabled' => $this->getSetting('quota_enabled'),
]
);
}
/**
* @param Response $response
* @param Response $response
*
* @throws \Twig\Error\LoaderError
* @return Response
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
* @throws \Twig\Error\LoaderError
*/
public function create(Response $response): Response
{
return view()->render($response, 'user/create.twig');
return view()->render($response, 'user/create.twig', [
'default_user_quota' => humanFileSize($this->getSetting('default_user_quota'), 0, true),
'quota_enabled' => $this->getSetting('quota_enabled', 'off'),
]);
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
@ -92,13 +96,26 @@ class UserController extends Controller
return redirect($response, route('user.create'));
}
$maxUserQuota = -1;
if ($this->getSetting('quota_enabled') === 'on') {
$maxUserQuota = param($request, 'max_user_quota', humanFileSize($this->getSetting('default_user_quota'), 0, true));
if (!preg_match('/([0-9]+[K|M|G|T])|(\-1)/i', $maxUserQuota)) {
$this->session->alert(lang('invalid_quota', 'danger'));
return redirect($response, route('user.create'));
}
if ($maxUserQuota !== '-1') {
$maxUserQuota = stringToBytes($maxUserQuota);
}
}
do {
$userCode = humanRandomString(5);
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `user_code` = ?', $userCode)->fetch()->count > 0);
$token = $this->generateUserUploadToken();
$this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`) VALUES (?, ?, ?, ?, ?, ?, ?)', [
$this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', [
param($request, 'email'),
param($request, 'username'),
password_hash(param($request, 'password'), PASSWORD_DEFAULT),
@ -106,6 +123,7 @@ class UserController extends Controller
param($request, 'is_active') !== null ? 1 : 0,
$userCode,
$token,
$maxUserQuota,
]);
$this->session->alert(lang('user_created', [param($request, 'username')]), 'success');
@ -115,17 +133,17 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
* @param $id
*
* @throws HttpNotFoundException
* @return Response
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws HttpUnauthorizedException
*
* @return Response
* @throws HttpNotFoundException
*/
public function edit(Request $request, Response $response, int $id): Response
{
@ -133,19 +151,21 @@ class UserController extends Controller
return view()->render($response, 'user/edit.twig', [
'profile' => false,
'user' => $user,
'user' => $user,
'quota_enabled' => $this->getSetting('quota_enabled', 'off'),
'max_disk_quota' => $user->max_disk_quota > 0 ? humanFileSize($user->max_disk_quota, 0, true) : -1,
]);
}
/**
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
* @param Request $request
* @param Response $response
* @param int $id
*
* @return Response
* @throws HttpUnauthorizedException
*
* @throws HttpNotFoundException
*/
public function update(Request $request, Response $response, int $id): Response
{
@ -181,21 +201,35 @@ class UserController extends Controller
return redirect($response, route('user.edit', ['id' => $id]));
}
if ($this->getSetting('quota_enabled') === 'on') {
$maxUserQuota = param($request, 'max_user_quota', humanFileSize($this->getSetting('default_user_quota'), 0, true));
if (!preg_match('/([0-9]+[K|M|G|T])|(\-1)/i', $maxUserQuota)) {
$this->session->alert(lang('invalid_quota', 'danger'));
return redirect($response, route('user.create'));
}
if ($maxUserQuota !== '-1') {
$user->max_disk_quota = stringToBytes($maxUserQuota);
}
}
if (param($request, 'password') !== null && !empty(param($request, 'password'))) {
$this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=? WHERE `id` = ?', [
$this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
param($request, 'email'),
param($request, 'username'),
password_hash(param($request, 'password'), PASSWORD_DEFAULT),
param($request, 'is_admin') !== null ? 1 : 0,
param($request, 'is_active') !== null ? 1 : 0,
$user->max_disk_quota,
$user->id,
]);
} else {
$this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=? WHERE `id` = ?', [
$this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
param($request, 'email'),
param($request, 'username'),
param($request, 'is_admin') !== null ? 1 : 0,
param($request, 'is_active') !== null ? 1 : 0,
$user->max_disk_quota,
$user->id,
]);
}
@ -210,14 +244,14 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
* @param Request $request
* @param Response $response
* @param int $id
*
* @return Response
* @throws HttpUnauthorizedException
*
* @throws HttpNotFoundException
*/
public function delete(Request $request, Response $response, int $id): Response
{
@ -238,14 +272,14 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
* @param Request $request
* @param Response $response
* @param int $id
*
* @return Response
* @throws HttpUnauthorizedException
*
* @throws HttpNotFoundException
*/
public function refreshToken(Request $request, Response $response, int $id): Response
{

View file

@ -16,8 +16,7 @@ class InjectMiddleware extends Middleware
*/
public function __invoke(Request $request, RequestHandler $handler)
{
$head = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'custom_head\'')->fetch();
$this->view->getTwig()->addGlobal('customHead', $head->value ?? null);
$this->view->getTwig()->addGlobal('customHead', $this->getSetting('custom_head'));
return $handler->handle($request);
}

View file

@ -16,10 +16,10 @@ class LangMiddleware extends Middleware
*/
public function __invoke(Request $request, RequestHandler $handler)
{
$forcedLang = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'lang\'')->fetch();
if ($forcedLang) {
$this->lang::setLang($forcedLang->value);
$request = $request->withAttribute('forced_lang', $forcedLang->value);
$forcedLang = $this->getSetting('lang');
if ($forcedLang !== null) {
$this->lang::setLang($forcedLang);
$request = $request->withAttribute('forced_lang', $forcedLang);
}
return $handler->handle($request);

View file

@ -18,22 +18,21 @@ class RememberMiddleware extends Middleware
public function __invoke(Request $request, RequestHandler $handler)
{
if (!$this->session->get('logged', false) && !empty($request->getCookieParams()['remember'])) {
list($selector, $token) = explode(':', $request->getCookieParams()['remember']);
[$selector, $token] = explode(':', $request->getCookieParams()['remember']);
$result = $this->database->query('SELECT `id`, `email`, `username`,`is_admin`, `active`, `remember_token` FROM `users` WHERE `remember_selector` = ? AND `remember_expire` > ? LIMIT 1',
$user = $this->database->query('SELECT `id`, `email`, `username`,`is_admin`, `active`, `remember_token`, `current_disk_quota`, `max_disk_quota` FROM `users` WHERE `remember_selector` = ? AND `remember_expire` > ? LIMIT 1',
[$selector, date('Y-m-d\TH:i:s', time())]
)->fetch();
if ($result && password_verify($token, $result->remember_token) && $result->active) {
if ($user && password_verify($token, $user->remember_token) && $user->active) {
$this->session->set('logged', true);
$this->session->set('user_id', $result->id);
$this->session->set('username', $result->username);
$this->session->set('admin', $result->is_admin);
// TODO: update
$this->session->set('used_space', humanFileSize($this->getUsedSpaceByUser($result->id)));
$this->session->set('user_id', $user->id);
$this->session->set('username', $user->username);
$this->session->set('admin', $user->is_admin);
$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);
}
$this->refreshRememberCookie($result->id);
$this->refreshRememberCookie($user->id);
}
return $handler->handle($request);

View file

@ -120,6 +120,7 @@ return [
'register' => 'Register',
'register_success' => 'The account has been created, a confirmation email has been sent.',
'default_user_quota' => 'Default User Quota',
'max_user_quota' => 'Max User Quota',
'invalid_quota' => 'Invalid values as default user quota.',
'mail.activate_text' => "Hi %s!\nthank you for creating your account on %s (%s), click on the following link to activate it:\n\n%s",
'mail.activate_account' => '%s - Account Activation',

View file

@ -35,8 +35,16 @@
<i class="fas fa-fw fa-user"></i> {{ session.get('username') }}
</a>
<div class="dropdown-menu shadow-sm" aria-labelledby="userDropdown">
<a class="dropdown-item disabled" href="javascript:void(0)">{{ lang('used') }}: {{ session.get('used_space') }}</a>
<a class="dropdown-item disabled" href="javascript:void(0)">{{ lang('used') }}: {{ session.get('current_disk_quota') }}{% if session.get('max_disk_quota') %}/{{ session.get('max_disk_quota') }}{% endif %}</a>
{% if session.get('percent_disk_quota') is not null %}
<a class="dropdown-item disabled" href="javascript:void(0)">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: {{ session.get('percent_disk_quota') }}%" aria-valuenow="{{ session.get('percent_disk_quota') }}" aria-valuemin="0" aria-valuemax="100">{{ session.get('percent_disk_quota') }}%</div>
</div>
</a>
{% endif %}
{% if session.get('admin') %}
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ route('switchView') }}"><i class="fas fa-fw fa-sync"></i> {{ lang('switch_to') }}: {{ session.get('gallery_view') is null or session.get('gallery_view') ? lang('gallery') : lang('table') }}</a>
{% endif %}
<div class="dropdown-divider"></div>

View file

@ -59,28 +59,24 @@
<div class="card-header"><i class="fas fa-cog fa-fw"></i> {{ lang('system_settings') }}</div>
<div class="card-body">
<form method="post" action="{{ route('settings.save') }}">
<div class="form-group row">
<label for="register_enabled" class="col-sm-4 col-form-label">{{ lang('register_enabled') }}</label>
<div class="col-sm-8">
<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">
@ -89,21 +85,19 @@
</select>
</div>
</div>
<div class="form-group row">
<label for="quota_enabled" class="col-sm-4 col-form-label">{{ lang('quota_enabled') }}</label>
<div class="col-sm-8">
<input type="checkbox" name="quota_enabled" data-toggle="toggle" {{ quota_enabled == 'on' ? 'checked' }}>
</div>
</div>
<div class="form-group row">
<label for="default_user_quota" class="col-sm-4 col-form-label">{{ lang('default_user_quota') }}</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="default_user_quota" name="default_user_quota" pattern="[0-9]+[K|M|G|T]" title="512M, 2G, 1T, ..." placeholder="1G" value="{{ default_user_quota }}">
<small>512M, 2G, 1T, ...</small>
</div>
</div>
<div class="form-group row">
<label for="lang" class="col-sm-4 col-form-label">{{ lang('enforce_language') }}</label>
<div class="col-sm-8">
@ -116,7 +110,6 @@
<small>{{ lang('default_lang_behavior') }}</small>
</div>
</div>
<div class="form-group row">
<label for="custom_head" class="col-sm-4 col-form-label">{{ lang('custom_head_html') }}</label>
<div class="col-sm-8">
@ -124,7 +117,6 @@
<small>{{ lang('custom_head_html_hint') }}</small>
</div>
</div>
<button type="submit" class="btn btn-outline-success float-right mt-3">
<i class="fas fa-save fa-fw"></i> {{ lang('apply') }}
</button>

View file

@ -20,7 +20,7 @@
</div>
<div class="row">
<div class="col">
<form action="{{ route('upload') }}" method="post" id="upload-dropzone" class="dropzone">
<form action="{{ route('upload') }}?web=1" method="post" id="upload-dropzone" class="dropzone">
<div class="fallback">
<input name="file" type="file" multiple>
</div>

View file

@ -30,6 +30,15 @@
<input type="password" class="form-control" id="password" placeholder="{{ lang('password') }}" name="password" autocomplete="off" required>
</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">
<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">

View file

@ -66,6 +66,15 @@
</div>
</div>
{% if not profile %}
{% 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">
<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">

View file

@ -35,7 +35,7 @@
<td>
<pre>{{ user.user_code|default(lang('none')) }}</pre>
</td>
<td>{{ humanFileSize(user.current_disk_quota) }}</td>
<td>{{ humanFileSize(user.current_disk_quota) }}{% if quota_enabled == 'on' %}/{{ user.max_disk_quota > 0 ? humanFileSize(user.max_disk_quota) : '∞' }}{% endif %}</td>
<td>
{% if user.active %}
<span class="badge badge-success"><i class="fas fa-check"></i></span>