Working on user registration, user disk quota, password recovery
This commit is contained in:
parent
e2478f5880
commit
49c9e48e5e
|
@ -34,9 +34,10 @@ class AdminController extends Controller
|
|||
$totalSize += $filesystem->getSize($media->storage_path);
|
||||
}
|
||||
|
||||
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value;
|
||||
$hideByDefault = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'hide_by_default\'')->fetch()->value;
|
||||
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value;
|
||||
$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';
|
||||
$defaultUserQuota = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'default_user_quota\'')->fetch()->value ?? '1G';
|
||||
|
||||
return view()->render($response, 'dashboard/system.twig', [
|
||||
'usersCount' => $usersCount,
|
||||
|
@ -52,6 +53,7 @@ class AdminController extends Controller
|
|||
'register_enabled' => $registerEnabled,
|
||||
'hide_by_default' => $hideByDefault,
|
||||
'copy_url_behavior' => $copyUrl,
|
||||
'default_user_quota' => $defaultUserQuota,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
namespace App\Controllers\Auth;
|
||||
|
||||
use App\Controllers\Controller;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
|
@ -10,11 +11,11 @@ class LoginController extends Controller
|
|||
/**
|
||||
* @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 show(Response $response): Response
|
||||
{
|
||||
|
@ -22,16 +23,20 @@ class LoginController extends Controller
|
|||
return redirect($response, route('home'));
|
||||
}
|
||||
|
||||
return view()->render($response, 'auth/login.twig');
|
||||
$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,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
*
|
||||
* @return Response
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function login(Request $request, Response $response): Response
|
||||
{
|
12
app/Controllers/Auth/PasswordRecoveryController.php
Normal file
12
app/Controllers/Auth/PasswordRecoveryController.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Controllers\Auth;
|
||||
|
||||
|
||||
use App\Controllers\Controller;
|
||||
|
||||
class PasswordRecoveryController extends Controller
|
||||
{
|
||||
|
||||
}
|
120
app/Controllers/Auth/RegisterController.php
Normal file
120
app/Controllers/Auth/RegisterController.php
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Controllers\Auth;
|
||||
|
||||
|
||||
use App\Controllers\Controller;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Exception\HttpNotFoundException;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @return Response
|
||||
* @throws HttpNotFoundException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function registerForm(Request $request, Response $response): Response
|
||||
{
|
||||
if ($this->session->get('logged', false)) {
|
||||
return redirect($response, route('home'));
|
||||
}
|
||||
|
||||
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
|
||||
if ($registerEnabled === 'off') {
|
||||
throw new HttpNotFoundException($request);
|
||||
}
|
||||
|
||||
return view()->render($response, 'auth/register.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @return Response
|
||||
* @throws HttpNotFoundException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function register(Request $request, Response $response): Response
|
||||
{
|
||||
if ($this->session->get('logged', false)) {
|
||||
return redirect($response, route('home'));
|
||||
}
|
||||
|
||||
$registerEnabled = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'register_enabled\'')->fetch()->value ?? 'off';
|
||||
if ($registerEnabled === 'off') {
|
||||
throw new HttpNotFoundException($request);
|
||||
}
|
||||
|
||||
if (param($request, 'email') === null && !filter_var(param($request, 'email'), FILTER_VALIDATE_EMAIL)) {
|
||||
$this->session->alert(lang('email_required'), 'danger');
|
||||
|
||||
return redirect($response, route('register.show'));
|
||||
}
|
||||
|
||||
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `email` = ?', param($request, 'email'))->fetch()->count > 0) {
|
||||
$this->session->alert(lang('email_taken'), 'danger');
|
||||
|
||||
return redirect($response, route('register.show'));
|
||||
}
|
||||
|
||||
if (param($request, 'username') === null) {
|
||||
$this->session->alert(lang('username_required'), 'danger');
|
||||
|
||||
return redirect($response, route('register.show'));
|
||||
}
|
||||
|
||||
if (param($request, 'password') === null) {
|
||||
$this->session->alert(lang('password_required'), 'danger');
|
||||
|
||||
return redirect($response, route('register.show'));
|
||||
}
|
||||
|
||||
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `username` = ?', param($request, 'username'))->fetch()->count > 0) {
|
||||
$this->session->alert(lang('username_taken'), 'danger');
|
||||
|
||||
return redirect($response, route('register.show'));
|
||||
}
|
||||
|
||||
do {
|
||||
$userCode = humanRandomString(5);
|
||||
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `user_code` = ?', $userCode)->fetch()->count > 0);
|
||||
|
||||
$token = $this->generateUserUploadToken();
|
||||
$activateToken = bin2hex(random_bytes(16));
|
||||
|
||||
$this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `activate_token`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', [
|
||||
param($request, 'email'),
|
||||
param($request, 'username'),
|
||||
password_hash(param($request, 'password'), PASSWORD_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
$userCode,
|
||||
$token,
|
||||
$activateToken,
|
||||
]);
|
||||
|
||||
$this->session->alert(lang('register_success', [param($request, 'username')]), 'success');
|
||||
$this->logger->info('New user registered.', [array_diff_key($request->getParsedBody(), array_flip(['password']))]);
|
||||
|
||||
return redirect($response, route('login.show'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @param string $activateToken
|
||||
* @return Response
|
||||
*/
|
||||
public function activateUser(Request $request, Response $response, string $activateToken): Response
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -126,4 +126,17 @@ abstract class Controller
|
|||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function generateUserUploadToken(): string
|
||||
{
|
||||
do {
|
||||
$token = 'token_'.md5(uniqid('', true));
|
||||
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `token` = ?', $token)->fetch()->count > 0);
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ 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;
|
||||
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value ?? 'off';
|
||||
|
||||
return view()->render(
|
||||
$response,
|
||||
|
|
|
@ -66,7 +66,7 @@ class MediaController extends Controller
|
|||
throw new HttpNotFoundException($request);
|
||||
}
|
||||
|
||||
$copyUrl = $this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'copy_url_behavior\'')->fetch()->value;
|
||||
$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,
|
||||
|
|
|
@ -16,8 +16,14 @@ class SettingController extends Controller
|
|||
*/
|
||||
public function saveSettings(Request $request, Response $response): Response
|
||||
{
|
||||
if (!preg_match('/[0-9]+[K|M|G|T]/i', param($request, 'default_user_quota', '1G'))) {
|
||||
$this->session->alert(lang('invalid_quota', 'danger'));
|
||||
return redirect($response, route('system'));
|
||||
}
|
||||
|
||||
$this->updateSetting('register_enabled', param($request, 'register_enabled', 'off'));
|
||||
$this->updateSetting('hide_by_default', param($request, 'hide_by_default', 'off'));
|
||||
$this->updateSetting('default_user_quota', param($request, 'default_user_quota', '1G'));
|
||||
$this->updateSetting('copy_url_behavior', param($request, 'copy_url_behavior') === null ? 'default' : 'raw');
|
||||
|
||||
$this->applyTheme($request);
|
||||
|
|
|
@ -101,7 +101,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 === 'on') {
|
||||
if (($this->database->query('SELECT `value` FROM `settings` WHERE `key` = \'hide_by_default\'')->fetch()->value ?? 'off') === 'on') {
|
||||
$published = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class UserController extends Controller
|
|||
*/
|
||||
public function store(Request $request, Response $response): Response
|
||||
{
|
||||
if (param($request, 'email') === null) {
|
||||
if (param($request, 'email') === null && !filter_var(param($request, 'email'), FILTER_VALIDATE_EMAIL)) {
|
||||
$this->session->alert(lang('email_required'), 'danger');
|
||||
|
||||
return redirect($response, route('user.create'));
|
||||
|
@ -96,7 +96,7 @@ class UserController extends Controller
|
|||
$userCode = humanRandomString(5);
|
||||
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `user_code` = ?', $userCode)->fetch()->count > 0);
|
||||
|
||||
$token = $this->generateNewToken();
|
||||
$token = $this->generateUserUploadToken();
|
||||
|
||||
$this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`) VALUES (?, ?, ?, ?, ?, ?, ?)', [
|
||||
param($request, 'email'),
|
||||
|
@ -151,7 +151,7 @@ class UserController extends Controller
|
|||
{
|
||||
$user = $this->getUser($request, $id, false);
|
||||
|
||||
if (param($request, 'email') === null) {
|
||||
if (param($request, 'email') === null && !filter_var(param($request, 'email'), FILTER_VALIDATE_EMAIL)) {
|
||||
$this->session->alert(lang('email_required'), 'danger');
|
||||
|
||||
return redirect($response, route('user.edit', ['id' => $id]));
|
||||
|
@ -251,7 +251,7 @@ class UserController extends Controller
|
|||
{
|
||||
$user = $this->getUser($request, $id, true);
|
||||
|
||||
$token = $this->generateNewToken();
|
||||
$token = $this->generateUserUploadToken();
|
||||
|
||||
$this->database->query('UPDATE `users` SET `token`=? WHERE `id` = ?', [
|
||||
$token,
|
||||
|
@ -264,16 +264,4 @@ class UserController extends Controller
|
|||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function generateNewToken(): string
|
||||
{
|
||||
do {
|
||||
$token = 'token_'.md5(uniqid('', true));
|
||||
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `token` = ?', $token)->fetch()->count > 0);
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ if (!function_exists('humanFileSize')) {
|
|||
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
|
||||
}
|
||||
|
||||
return round($size, $precision).' '.['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i];
|
||||
return round($size, $precision).' '.['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,8 @@ if (!function_exists('stringToBytes')) {
|
|||
|
||||
$val = (float) $val;
|
||||
switch ($last) {
|
||||
case 't':
|
||||
$val *= 1024;
|
||||
case 'g':
|
||||
$val *= 1024;
|
||||
case 'm':
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
// Auth routes
|
||||
use App\Controllers\AdminController;
|
||||
use App\Controllers\Auth\RegisterController;
|
||||
use App\Controllers\ClientController;
|
||||
use App\Controllers\DashboardController;
|
||||
use App\Controllers\ExportController;
|
||||
use App\Controllers\LoginController;
|
||||
use App\Controllers\Auth\LoginController;
|
||||
use App\Controllers\MediaController;
|
||||
use App\Controllers\ProfileController;
|
||||
use App\Controllers\SettingController;
|
||||
use App\Controllers\ThemeController;
|
||||
use App\Controllers\UpgradeController;
|
||||
use App\Controllers\UploadController;
|
||||
use App\Controllers\UserController;
|
||||
|
@ -63,6 +63,8 @@ $app->group('', function (RouteCollectorProxy $group) {
|
|||
})->add(App\Middleware\CheckForMaintenanceMiddleware::class)->add(AuthMiddleware::class);
|
||||
|
||||
$app->get('/', [DashboardController::class, 'redirects'])->setName('root');
|
||||
$app->get('/register', [RegisterController::class, 'registerForm'])->setName('register.show');
|
||||
$app->post('/register', [RegisterController::class, 'register'])->setName('register');
|
||||
$app->get('/login', [LoginController::class, 'show'])->setName('login.show');
|
||||
$app->post('/login', [LoginController::class, 'login'])->setName('login');
|
||||
$app->map(['GET', 'POST'], '/logout', [LoginController::class, 'logout'])->setName('logout');
|
||||
|
|
|
@ -111,9 +111,14 @@ return [
|
|||
'remember_me' => 'Remember me',
|
||||
'please_wait' => 'Please wait…',
|
||||
'dont_close' => 'Do not close this tab until completion.',
|
||||
'register_enabled' => 'Registration Enabled',
|
||||
'hide_by_default' => 'Hide uploads by default',
|
||||
'register_enabled' => 'Registrations enabled',
|
||||
'hide_by_default' => 'Hide media by default',
|
||||
'copy_url_behavior' => 'Copy URL mode',
|
||||
'settings_saved' => 'System settings saved!',
|
||||
'export_data' => 'Export Data'
|
||||
'export_data' => 'Export Data',
|
||||
'password_recovery' => 'Recover password',
|
||||
'no_account' => 'Don\'t have an account?',
|
||||
'register' => 'Register',
|
||||
'default_user_quota' => 'Default User Quota',
|
||||
'invalid_quota' => 'Invalid values as default user quota.',
|
||||
];
|
||||
|
|
7
resources/schemas/mysql/mysql.5.sql
Normal file
7
resources/schemas/mysql/mysql.5.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
ALTER TABLE `users`
|
||||
ADD COLUMN `activate_token` VARCHAR(32) DEFAULT NULL,
|
||||
ADD COLUMN `reset_token` VARCHAR(32) DEFAULT NULL,
|
||||
ADD COLUMN `disk_quota` BIGINT(20) NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE `users` ADD INDEX (`activate_token`);
|
||||
ALTER TABLE `users` ADD INDEX (`reset_token`);
|
10
resources/schemas/sqlite/sqlite.5.sql
Normal file
10
resources/schemas/sqlite/sqlite.5.sql
Normal file
|
@ -0,0 +1,10 @@
|
|||
ALTER TABLE `users` ADD COLUMN `activate_token` VARCHAR(32);
|
||||
ALTER TABLE `users` ADD COLUMN `reset_token` VARCHAR(32);
|
||||
ALTER TABLE `users` ADD COLUMN `disk_quota` BIGINT NOT NULL DEFAULT -1;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS `activate_token_index`
|
||||
ON `users` (`activate_token`);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS `reset_token_index`
|
||||
ON `users` (`reset_token`);
|
||||
|
|
@ -35,19 +35,28 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label for="inputEmail" class="sr-only">{{ lang('login.username') }}</label>
|
||||
<label for="username" class="sr-only">{{ lang('login.username') }}</label>
|
||||
<input type="text" id="username" class="form-control" placeholder="{{ lang('login.username') }}" name="username" required autofocus>
|
||||
<label for="password" class="sr-only">{{ lang('password') }}</label>
|
||||
<input type="password" id="password" class="form-control" placeholder="{{ lang('password') }}" name="password" required>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" name="remember" class="form-check-input float-left" id="remember">
|
||||
<label class="form-check-label" for="remember">{{ lang('remember_me') }}</label>
|
||||
</div>
|
||||
<a href="#" class="">{{ lang('password_recovery') }}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12">
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">{{ lang('login') }}</button>
|
||||
{% if register_enabled == 'on' %}
|
||||
<div class="text-center mt-2">
|
||||
{{ lang('no_account') }} <a href="{{ route('register.show') }}">{{ lang('register') }}</a>.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
56
resources/templates/auth/register.twig
Normal file
56
resources/templates/auth/register.twig
Normal file
|
@ -0,0 +1,56 @@
|
|||
{% extends 'base.twig' %}
|
||||
|
||||
{% block title %}{{ lang('login') }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 40px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<form class="form-signin" method="post" action="{{ route('register') }}">
|
||||
<div class="row text-center">
|
||||
<div class="col-md-12">
|
||||
<h1 class="h3 mb-3 font-weight-normal">{{ config.app_name }}</h1>
|
||||
{% include 'comp/alert.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label for="username" class="sr-only">{{ lang('username') }}</label>
|
||||
<input type="text" id="username" class="form-control" placeholder="{{ lang('username') }}" name="username" required autofocus>
|
||||
<label for="email" class="sr-only">E-Mail</label>
|
||||
<input type="email" id="email" class="form-control" placeholder="mail@example.com" name="password" required>
|
||||
<label for="password" class="sr-only">{{ lang('password') }}</label>
|
||||
<input type="password" id="password" class="form-control" placeholder="{{ lang('password') }}" name="password" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12">
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">{{ lang('register') }}</button>
|
||||
<div class="text-center mt-2">
|
||||
<a href="{{ route('login.show') }}">{{ lang('cancel') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -37,7 +37,7 @@
|
|||
<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>
|
||||
{% if session.get('admin') %}
|
||||
<a class="dropdown-item" href="{{ route('switchView') }}"><i class="fas fa-fw fa-sync"></i> {{ lang('switch_to') }}: {{ session.gallery_view is null or session.gallery_view ? lang('gallery') : lang('table') }}</a>
|
||||
<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>
|
||||
<a class="dropdown-item" href="{{ route('profile') }}"><i class="fas fa-fw fa-user"></i> {{ lang('profile') }}</a>
|
||||
|
|
|
@ -90,6 +90,13 @@
|
|||
</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 }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="custom_head" class="col-sm-4 col-form-label">{{ lang('enforce_language') }}</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -34,6 +34,11 @@ body {
|
|||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: .50rem;
|
||||
border-top-left-radius: 0;
|
||||
|
|
|
@ -106,7 +106,7 @@ var app = {
|
|||
window.open($('#telegram-share-button').data('url') + $('#telegram-share-text').val(), '_blank');
|
||||
},
|
||||
checkForUpdates: function () {
|
||||
$('#checkForUpdatesMessage').empty().html('<i class="fas fa-sync fa-spin"></i>');
|
||||
$('#checkForUpdatesMessage').empty().html('<i class="fas fa-spinner fa-pulse fa-3x"></i>');
|
||||
$('#doUpgradeButton').prop('disabled', true);
|
||||
$.get(window.AppConfig.base_url + '/system/checkForUpdates?prerelease=' + $(this).data('prerelease'), function (data) {
|
||||
$('#checkForUpdatesMessage').empty().text(data.message);
|
||||
|
|
Loading…
Reference in a new issue