diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8631082 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.php text eol=lf +*.json text eol=lf diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 79dfec7..34a060c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,5 +1,5 @@ # These are supported funding model platforms - +github: prasathmani patreon: ccpprogrammers open_collective: tinyfilemanager ko_fi: tinyfilemanager diff --git a/.github/workflows/PublishDocker.yml b/.github/workflows/PublishDocker.yml index 73dee66..517bae8 100644 --- a/.github/workflows/PublishDocker.yml +++ b/.github/workflows/PublishDocker.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: | ${{ secrets.DOCKERHUB_USERNAME }}/tinyfilemanager @@ -21,6 +21,8 @@ jobs: type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx @@ -35,4 +37,5 @@ jobs: uses: docker/build-push-action@v2 with: push: true - tags: ${{ steps.meta.outputs.tags }} \ No newline at end of file + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index 5d0ba45..b306bf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,8 +22,5 @@ RUN docker-php-ext-install \ WORKDIR /var/www/html COPY tinyfilemanager.php index.php -COPY config-sample.php config.php -RUN sed -i "s/\$root_path =.*;/\$root_path = \$_SERVER['DOCUMENT_ROOT'].'\/data';/g" config.php && \ - sed -i "s/\$root_url = '';/\$root_url = 'data\/';/g" config.php CMD ["sh", "-c", "php -S 0.0.0.0:80"] diff --git a/README.md b/README.md index a066123..a4f80da 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ [![GitHub Release](https://img.shields.io/github/release/prasathmani/tinyfilemanager.svg?style=flat-square)](https://github.com/prasathmani/tinyfilemanager/releases) [![GitHub License](https://img.shields.io/github/license/prasathmani/tinyfilemanager.svg?style=flat-square)](https://github.com/prasathmani/tinyfilemanager/blob/master/LICENSE) [![Paypal](https://img.shields.io/badge/Donate-Paypal-lightgrey.svg?style=flat-square)](https://www.paypal.me/prasathmani) +![GitHub Sponsors](https://img.shields.io/github/sponsors/prasathmani) -> TinyFileManager is web based file manager and it is a simple, fast and small file manager with a single file, multi-language ready web application for storing, uploading, editing and managing files and folders online via web browser. The Application runs on PHP 5.5+, It allows the creation of multiple users and each user can have its own directory and a build-in support for managing text files with cloud9 IDE and it supports syntax highlighting for over 150+ languages and over 35+ themes. +> TinyFileManager is web based PHP file manager and it is a simple, fast and small size in single-file PHP file that can be dropped into any folder on your server, multi-language ready web application for storing, uploading, editing and managing files and folders online via web browser. The Application runs on PHP 5.5+, It allows the creation of multiple users and each user can have its own directory and a build-in support for managing text files with cloud9 IDE and it supports syntax highlighting for over 150+ languages and over 35+ themes. ## Demo @@ -37,13 +38,15 @@ Default username/password: **admin/admin@123** and **user/12345**. To enable/disable authentication set `$use_auth` to true or false. -:information_source: Rename the `config-sample.php` file into `config.php` to use configuration, it is an additional configuration file, Feel free to remove completely this file and configure "tinyfilemanager.php" as a single file application. +:information_source: Add your own configuration file [config.php](https://tinyfilemanager.github.io/config-sample.txt) in the same folder to use as additional configuration file. + +:information_source: To work offline without CDN resources, use [offline](https://github.com/prasathmani/tinyfilemanager/tree/offline) branch ### :loudspeaker: Features - :cd: Open Source, light and extremely simple - :iphone: Mobile friendly view for touch devices -- :information_source: Basic features likes Create, Delete, Modify, View, Quick Preview, Download, Copy and Move files +- :information_source: Basic features likes Create, Delete, Modify, View, Download, Copy and Move files - :arrow_double_up: Ajax Upload, Ability to drag & drop, upload from URL, multiple files upload with file extensions filter - :file_folder: Ability to create folders and files - :gift: Ability to compress, extract files (`zip`, `tar`) @@ -54,7 +57,7 @@ To enable/disable authentication set `$use_auth` to true or false. - :zap: Backup files and IP blacklist and whitelist - :mag_right: Search - Search and filter files using `datatable js` - :file_folder: Exclude folders and files from listing -- :globe_with_meridians: Multi-language(20+) support and for translations `translation.json` is file required +- :globe_with_meridians: Multi-language(32+) support and for translations `translation.json` is file required - :bangbang: lots more... ## Deploy by Docker @@ -79,8 +82,6 @@ DockerHub: [https://hub.docker.com/r/tinyfilemanager/tinyfilemanager](https://hu #### How to change config within docker -**Important!!!** First, you can copy `config-sample.php` to `config.php`, and must modify this following config - Origin: ```php @@ -105,10 +106,10 @@ $root_path = $_SERVER['DOCUMENT_ROOT'].'/data'; $root_url = 'data/'; ``` -Then, change another config what you want, and add a new volume `-v /absolute/path/config.php:/var/www/html/config.php` in `docker run` command, like this: +Then, change another config what you want, and add a new volume `-v /absolute/path/index.php:/var/www/html/index.php` in `docker run` command, like this: ```shell -$ docker run -d -v /absolute/path:/var/www/html/data -v /absolute/path/config.php:/var/www/html/config.php -p 80:80 --restart=always --name tinyfilemanager tinyfilemanager/tinyfilemanager:master +$ docker run -d -v /absolute/path:/var/www/html/data -v /absolute/path/index.php:/var/www/html/index.php -p 80:80 --restart=always --name tinyfilemanager tinyfilemanager/tinyfilemanager:master ``` #### Stop running @@ -123,6 +124,6 @@ $ docker rm -f tinyfilemanager - Available under the [GNU license](https://github.com/prasathmani/tinyfilemanager/blob/master/LICENSE) - Original concept and development by github.com/alexantr/filemanager -- CDN Used - _jQuery, Bootstrap, Font Awesome, Highlight js, ace js, DropZone js, ekko-lightbox js, and DataTable js_ +- CDN Used - _jQuery, Bootstrap, Font Awesome, Highlight js, ace js, DropZone js, and DataTable js_ - To report a bug or request a feature, please file an [issue](https://github.com/prasathmani/tinyfilemanager/issues) - [Contributors](https://github.com/prasathmani/tinyfilemanager/wiki/Authors-and-Contributors) diff --git a/config-sample.php b/config-sample.php deleted file mode 100644 index c75b9a9..0000000 --- a/config-sample.php +++ /dev/null @@ -1,123 +0,0 @@ - 'Password', 'Username2' => 'Password2', ...) -// Generate secure password hash - https://tinyfilemanager.github.io/docs/pwd.html -$auth_users = array( - 'admin' => '$2y$10$/K.hjNr84lLNDt8fTXjoI.DBp6PpeyoJ.mGwrrLuCZfAwfSAGqhOW', //admin@123 - 'user' => '$2y$10$Fg6Dz8oH9fPoZ2jJan5tZuv6Z4Kp7avtQ9bDfrdRntXtPeiMAZyGO' //12345 -); - -// Readonly users -// e.g. array('users', 'guest', ...) -$readonly_users = array( - 'user' -); - -// Enable highlight.js (https://highlightjs.org/) on view's page -$use_highlightjs = true; - -// highlight.js style -// for dark theme use 'ir-black' -$highlightjs_style = 'vs'; - -// Enable ace.js (https://ace.c9.io/) on view's page -$edit_files = true; - -// Default timezone for date() and time() -// Doc - http://php.net/manual/en/timezones.php -$default_timezone = 'Etc/UTC'; // UTC - -// Root path for file manager -// use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder' -$root_path = $_SERVER['DOCUMENT_ROOT']; - -// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder' -// Will not working if $root_path will be outside of server document root -$root_url = ''; - -// Server hostname. Can set manually if wrong -$http_host = $_SERVER['HTTP_HOST']; - -// user specific directories -// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...) -$directories_users = array(); - -// input encoding for iconv -$iconv_input_encoding = 'UTF-8'; - -// date() format for file modification date -// Doc - https://www.php.net/manual/en/datetime.format.php -$datetime_format = 'd.m.y H:i:s'; - -// Allowed file extensions for create and rename files -// e.g. 'txt,html,css,js' -$allowed_file_extensions = ''; - -// Allowed file extensions for upload files -// e.g. 'gif,png,jpg,html,txt' -$allowed_upload_extensions = ''; - -// Favicon path. This can be either a full url to an .PNG image, or a path based on the document root. -// full path, e.g http://example.com/favicon.png -// local path, e.g images/icons/favicon.png -$favicon_path = ''; - -// Files and folders to excluded from listing -// e.g. array('myfile.html', 'personal-folder', '*.php', ...) -$exclude_items = array(''); - -// Online office Docs Viewer -// Availabe rules are 'google', 'microsoft' or false -// google => View documents using Google Docs Viewer -// microsoft => View documents using Microsoft Web Apps Viewer -// false => disable online doc viewer -$online_viewer = 'google'; - -// Sticky Nav bar -// true => enable sticky header -// false => disable sticky header -$sticky_navbar = true; - - -// max upload file size -$max_upload_size_bytes = 5000; - -// Possible rules are 'OFF', 'AND' or 'OR' -// OFF => Don't check connection IP, defaults to OFF -// AND => Connection must be on the whitelist, and not on the blacklist -// OR => Connection must be on the whitelist, or not on the blacklist -$ip_ruleset = 'OFF'; - -// Should users be notified of their block? -$ip_silent = true; - -// IP-addresses, both ipv4 and ipv6 -$ip_whitelist = array( - '127.0.0.1', // local ipv4 - '::1' // local ipv6 -); - -// IP-addresses, both ipv4 and ipv6 -$ip_blacklist = array( - '0.0.0.0', // non-routable meta ipv4 - '::' // non-routable meta ipv6 -); - -?> diff --git a/screenshot.gif b/screenshot.gif index d44818f..e98d505 100644 Binary files a/screenshot.gif and b/screenshot.gif differ diff --git a/tinyfilemanager.php b/tinyfilemanager.php index 6c0ce63..bb546ba 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -1,16 +1,17 @@ 'Directory path', 'Username2' => 'Directory path', ...) -$directories_users = array(); - // input encoding for iconv $iconv_input_encoding = 'UTF-8'; // date() format for file modification date // Doc - https://www.php.net/manual/en/function.date.php -$datetime_format = 'd.m.y H:i'; +$datetime_format = 'm/d/Y g:i A'; + +// Path display mode when viewing file information +// 'full' => show full path +// 'relative' => show path relative to root_path +// 'host' => show path on the host +$path_display_mode = 'full'; // Allowed file extensions for create and rename files // e.g. 'txt,html,css,js' @@ -98,8 +102,8 @@ $exclude_items = array(); // Online office Docs Viewer // Availabe rules are 'google', 'microsoft' or false -// google => View documents using Google Docs Viewer -// microsoft => View documents using Microsoft Web Apps Viewer +// Google => View documents using Google Docs Viewer +// Microsoft => View documents using Microsoft Web Apps Viewer // false => disable online doc viewer $online_viewer = 'google'; @@ -111,7 +115,11 @@ $sticky_navbar = true; // Maximum file upload size // Increase the following values in php.ini to work properly // memory_limit, upload_max_filesize, post_max_size -$max_upload_size_bytes = 5000; +$max_upload_size_bytes = 5000000000; // size 5,000,000,000 bytes (~5GB) + +// chunk size used for upload +// eg. decrease to 1MB if nginx reports problem 413 entity too large +$upload_chunk_size_bytes = 2000000; // chunk size 2,000,000 bytes (~2MB) // Possible rules are 'OFF', 'AND' or 'OR' // OFF => Don't check connection IP, defaults to OFF @@ -134,17 +142,37 @@ $ip_blacklist = array( '::' // non-routable meta ipv6 ); -// if User has the customized config file, try to use it to override the default config above +// if User has the external config file, try to use it to override the default config above [config.php] +// sample config - https://tinyfilemanager.github.io/config-sample.txt $config_file = __DIR__.'/config.php'; if (is_readable($config_file)) { @include($config_file); } +// External CDN resources that can be used in the HTML (replace for GDPR compliance) +$external = array( + 'css-bootstrap' => '', + 'css-dropzone' => '', + 'css-font-awesome' => '', + 'css-highlightjs' => '', + 'js-ace' => '', + 'js-bootstrap' => '', + 'js-dropzone' => '', + 'js-jquery' => '', + 'js-jquery-datatables' => '', + 'js-highlightjs' => '', + 'pre-jsdelivr' => '', + 'pre-cloudflare' => '' +); + // --- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL --- // max upload file size define('MAX_UPLOAD_SIZE', $max_upload_size_bytes); +// upload chunk size +define('UPLOAD_CHUNK_SIZE', $upload_chunk_size_bytes); + // private key and session name to store to the session if ( !defined( 'FM_SESSION_ID')) { define('FM_SESSION_ID', 'filemanager'); @@ -165,9 +193,6 @@ $report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_report // Hide Permissions and Owner cols in file-listing $hide_Cols = isset($cfg->data['hide_Cols']) ? $cfg->data['hide_Cols'] : true; -// Show directory size: true or speedup output: false -$calc_folder = isset($cfg->data['calc_folder']) ? $cfg->data['calc_folder'] : true; - // Theme $theme = isset($cfg->data['theme']) ? $cfg->data['theme'] : 'light'; @@ -203,7 +228,7 @@ if (defined('FM_EMBED')) { mb_regex_encoding('UTF-8'); } - session_cache_limiter(''); + session_cache_limiter('nocache'); // Prevent logout issue after page was cached session_name(FM_SESSION_ID ); function session_error_handling_function($code, $msg, $file, $line) { // Permission denied for default session, try to create a new one @@ -218,6 +243,15 @@ if (defined('FM_EMBED')) { restore_error_handler(); } +//Generating CSRF Token +if (empty($_SESSION['token'])) { + if (function_exists('random_bytes')) { + $_SESSION['token'] = bin2hex(random_bytes(32)); + } else { + $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); + } +} + if (empty($auth_users)) { $use_auth = false; } @@ -240,6 +274,7 @@ defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . // logout if (isset($_GET['logout'])) { unset($_SESSION[FM_SESSION_ID]['logged']); + unset( $_SESSION['token']); fm_redirect(FM_SELF_URL); } @@ -259,9 +294,7 @@ if ($ip_ruleset != 'OFF') { } $clientIp = getClientIP(); - $proceed = false; - $whitelisted = in_array($clientIp, $ip_whitelist); $blacklisted = in_array($clientIp, $ip_blacklist); @@ -284,23 +317,22 @@ if ($ip_ruleset != 'OFF') { fm_show_header_login(); fm_show_message(); } - exit(); } } -// Auth +// Checking if the user is logged in or not. If not, it will show the login form. if ($use_auth) { if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) { // Logged - } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'])) { + } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'], $_POST['token'])) { // Logging In sleep(1); if(function_exists('password_verify')) { - if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']])) { + if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']]) && verifyToken($_POST['token'])) { $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr']; fm_set_msg(lng('You are logged in')); - fm_redirect(FM_SELF_URL . '?p='); + fm_redirect(FM_SELF_URL); } else { unset($_SESSION[FM_SESSION_ID]['logged']); fm_set_msg(lng('Login failed. Invalid username or password'), 'error'); @@ -321,7 +353,7 @@ if ($use_auth) {