- Litespeed workaround for large files
- Admin interface can compute data folder size
- REUSE compliance test
-- multiple docker features: mcrypt support, daily cleanup, unprivilidged user
+- multiple docker features: mcrypt support, daily cleanup, unprivileged user
- Add upload password capability in script options
- Various bugfixes around retries and error management
- Automatically lower chunk size sent to server refusing large chunks
- Security fixes, thanks [Bishopfox Team](https://www.bishopfox.com/)
- Translation fixes
- Docker fix
-- Advertise javascript license for LibreJS compatibility
+- Advertise JavaScript license for LibreJS compatibility
- other minor fixes
- Upgrade from 3.4.0: in-place upgrade
- Link on API page to generate bash script
- More informative error codes for API
- Security Fix: Prevent authentication bypass for admin interface
-- CLI script to remove expired files automatically with a cronjob
+- CLI script to remove expired files automatically with a cron job
- SHA-256 hash the admin password
- New theme "elegantish"
- Fix for JavaScript MIME-Type, prevents blocking the resource on some servers
- Show download link for a file in admin interface
- Default time for expiration (set to 'month' by default)
- New expiration time: 'quarter'
-- A lof of translation contributions
+- A lot of translation contributions
- Code cleanups
- Upgrade from 1.1: in-place upgrade
- Unlimited file size upload using HTML5 file API
- Show speed and estimated time during upload
- A lot of fixes
-- A lot of new langages
+- A lot of new languages
- Small API to upload files
- Limit access to Jirafeau using IP, mask, passwords
- Manage (some) proxy headers
- Keep uploader's ip
- Delete link for each upload
- No more clear text password storage
-- Simple langage support
+- Simple language support
- Add an admin interface
- New Design
- Add term of use
This project won't evolve to a file manager and will focus to keep a very few dependencies.
-So things like a markdown parser for the ToS or E-Mail tasks would be usefull for sure, but may be [rejected](https://gitlab.com/mojo42/Jirafeau/issues/37#note_1191566) since they would a lot of dependencies and makes the project more complex.
+So things like a markdown parser for the ToS or E-Mail tasks would be useful for sure, but may be [rejected](https://gitlab.com/mojo42/Jirafeau/issues/37#note_1191566) since they would a lot of dependencies and makes the project more complex.
## Structure
-Here is a little explaination of Jirafeau's arboresence in a simplified
-view only to show the most importants files and their role.
+Here is a little explanation of Jirafeau's structure in a simplified
+view only to show the most important files and their role.
```
.
├── tos.php : "Terms of Service" page
├── lib
│ ├── config.original.php : default parameters
-│ ├── config.local.php : the users parameters (auto generated, not versionized)
+│ ├── config.local.php : the users parameters (auto generated, not versioned)
│ ├── functions_*.js : JavaScript functions for index.php (AJAX etc)
│ ├── functions.php : core functions and tools of Jirafeau
│ ├── tos.original.txt : default text show on the ToS page
-│ ├── tos.local.txt : a users alternative text show on the ToS page (not versionized)
+│ ├── tos.local.txt : a users alternative text show on the ToS page (not versioned)
│ ├── settings.php : core settings of Jirafeau, includes the configuration params automatically
│ ├── locales : language folder, contains all language files
│ └── template
│ ├── footer.php : footer with links to source and ToS for all HTML views
│ └── header.php : header with logo and title for all HTML views
├── media : folder containing all skins
-└── var-xxxxxxx : the users folder containing all data (auto generated, not versionized)
- ├── async : chunks of uploaded files (not succressfull yet)
+└── var-xxxxxxx : the users folder containing all data (auto generated, not versioned)
+ ├── async : chunks of uploaded files (not successful yet)
├── files : all files that have been uploaded successfully
│ ├── [hashed file name] : the original file
│ └── [hashed file name]_count : count many links to this file exist
- └── links : all links, including meta-informations, pointing to files
+ └── links : all links, including metadata, pointing to files
└── [link] : the link file, includes which original file should be used and some meta data like creation date, expiration time
```
## Translations
-Translation may be add via [Jirafeau's Weblate](https://hosted.weblate.org/projects/jirafeau/master/).
+Translation may be added via [Jirafeau's Weblate](https://hosted.weblate.org/projects/jirafeau/master/).
## Coding style
Please create one branch for each feature and send one merge request for each branch.
-Dont squash several changes or commits into one merge request as this is hard to review.
+Don't squash several changes or commits into one merge request as this is hard to review.
Please use ```next-release``` as base branch and send your merge request to this branch (not ```master```).
-Quick walktrough:
+Quick walkthrough:
* Create ticket for new feature
* Fork the original repository, clone the own repository, add the original repository as upstream
exit;
}
- /* Unlog if asked. */
+ /* Logout if requested. */
if (jirafeau_admin_session_logged() && isset($_POST['action']) && (strcmp($_POST['action'], 'logout') == 0)) {
jirafeau_admin_session_end();
}
if (!jirafeau_admin_session_logged()) {
- /* Test HTTP authentification. */
+ /* Test HTTP authentication. */
if (!empty($cfg['admin_http_auth_user']) &&
$cfg['admin_http_auth_user'] == $_SERVER['PHP_AUTH_USER']) {
jirafeau_admin_session_start();
}
- /* Test web password authentification. */
+ /* Test web password authentication. */
elseif (!empty($cfg['admin_password']) && isset($_POST['admin_password'])) {
if ($cfg['admin_password'] === hash('sha256', $_POST['admin_password'])) {
jirafeau_admin_session_start();
# Run Jirafeau through a pre-made Docker image
-Jirafeau is a small PHP application so running it inside a docker is pretty straightforward.
+Jirafeau is a small PHP application so running it inside a docker container is pretty straightforward.
```
docker pull mojo42/jirafeau:latest
docker run -it --rm -p 8080:80 mojo42/jirafeau:latest
```
-Then connect on [locahost:8080](http://localhost:8080/).
+Then connect on [localhost:8080](http://localhost:8080/).
The admin console is located on `/admin.php`, check console output to get auto-generated admin password.
# Build your own Jirafeau docker image
# Security
-You may be interested to run Jirafeau on port 80:
+You may be interested in running Jirafeau on port 80:
```
docker run -d -p 80:80 --sysctl net.ipv4.ip_unprivileged_port_start=80 mojo42/jirafeau
```
-Note that Jirafeau image does not provide any SSL/TLS. You may be interrested in using [docker compose](https://docs.docker.com/compose/) combined with [Let's Encrypt](https://letsencrypt.org/).
+Note that Jirafeau image does not provide any SSL/TLS. You may be interested in using [docker compose](https://docs.docker.com/compose/) combined with [Let's Encrypt](https://letsencrypt.org/).
# Options
-Jirafeau docker image accept some options through environment variables to ease its configuration.
+Jirafeau's docker image accepts some options through environment variables to ease its configuration.
More details about options in `lib/config.original.php`.
Available options:
Files and links are stored in `/data` by default. Sub folders are automatically created with needed permissions at creation if needed.
Note that configuration is not stored in /data.
-Example of using a dedicated volume to store Jirafeau data separatly from containter:
+Example of using a dedicated volume to store Jirafeau data separately from the container:
```
docker volume create jirafeau_data
docker run -it --rm -p 8080:80 --mount source=jirafeau_data,target=/data mojo42/jirafeau:latest
* rename it to »config.local.php« and adapt the parameters.
**/
-/* URL of installation, with traling slash (eg. »https://exmaple.com/jirafeau/«)
+/* URL of installation, with trailing slash (eg. »https://example.com/jirafeau/«)
*/
$cfg['web_root'] = '';
*/
$cfg['var_root'] = '';
-/* Language - choice between 'auto' or any language located in the /lib/locales/ folder.
+/* Language - choose between 'auto' or any language located in the /lib/locales/ folder.
* The mode »auto« will cause the script to detect the user's browser information
- * and offer a matching language, and use »en« if it is not available.
- * Forcing to a specific lang lightly reduce lang computation.
+ * and offer a matching language, or use »en« if it is not available.
+ * Forcing a specific lang will slightly reduce computation time.
*/
$cfg['lang'] = 'auto';
$cfg['link_name_length'] = 8;
/* Upload password(s).
- * An empty array will disable the password authentification.
+ * An empty array will disable password authentication.
* $cfg['upload_password'] = array(); // No password
* $cfg['upload_password'] = array('psw1'); // One password
* $cfg['upload_password'] = array('psw1', 'psw2'); // Two passwords
$cfg['upload_ip_nopassword'] = array();
/* Password for the admin interface.
- * An empty password will disable the password authentification.
+ * An empty password will disable password authentication.
* The password is a sha256 hash of the original version.
*/
$cfg['admin_password'] = '';
*/
/**
- * Transform a string in a path by seperating each letters by a '/'.
+ * Transform a string in a path by separating each letters by a '/'.
* @return path finishing with a '/'
*/
function s2p($s)
}
}
- /* file informations */
+ /* file information */
$hash = jirafeau_hash_file($file_hash_method, $file['tmp_name']);
$name = str_replace(NL, '', trim($file['name']));
$mime_type = $file['type'];
}
/**
- * Read link informations
- * @return array containing informations.
+ * Read link information
+ * @return array containing information.
*/
function jirafeau_get_link($hash)
{
/* Push new found directory. */
$stack[] = $d . $node . '/';
} elseif (is_file($d . $node)) {
- /* Read link informations. */
+ /* Read link information. */
$l = jirafeau_get_link($node);
if (!count($l)) {
continue;
if (!empty($link_hash) && $link_hash != $node) {
continue;
}
- /* Print link informations. */
+ /* Print link information. */
echo '<tr>';
echo '<td>' .
'<strong><a id="upload_link" href="f.php?h='. jirafeau_escape($node) .'" title="' .
/* Push new found directory. */
$stack[] = $d . $node . '/';
} elseif (is_file($d . $node)) {
- /* Read link informations. */
+ /* Read link information. */
$l = jirafeau_get_link(basename($node));
if (!count($l)) {
continue;
/**
- * Clean old async transferts.
+ * Clean old async transfers.
* @return number of cleaned files.
*/
function jirafeau_admin_clean_async()
/* Push new found directory. */
$stack[] = $d . $node . '/';
} elseif (is_file($d . $node)) {
- /* Read async informations. */
+ /* Read async information. */
$a = jirafeau_get_async_ref(basename($node));
if (!count($a)) {
continue;
}
- /* Delete transferts older than 1 hour. */
+ /* Delete transfers older than 1 hour. */
if (time() - $a['last_edited'] > 3600) {
jirafeau_async_delete(basename($node));
$count++;
}
/**
- * Read async transfert informations
- * @return array containing informations.
+ * Read async transfer information
+ * @return array containing information.
*/
function jirafeau_get_async_ref($ref)
{
}
/**
- * Delete async transfert informations
+ * Delete async transfer information
*/
function jirafeau_async_delete($ref)
{
/**
* Init a new asynchronous upload.
- * @param $finename Name of the file to send
+ * @param $filename Name of the file to send
* @param $one_time One time upload parameter
* @param $key eventual password (or blank)
* @param $time time limit
$password = md5($key);
}
- /* Store informations. */
+ /* Store information. */
$p .= $ref;
$handle = fopen($p, 'w');
fwrite(
}
/**
- * Finalyze an asynchronous upload.
+ * Finalize an asynchronous upload.
* @param $ref asynchronous upload reference
* @param $code client code for this operation
* @param $crypt boolean asking to crypt or not
// root of the domain without handling the URL scheme
$absPrefix = parse_url($cfg['web_root'], PHP_URL_PATH);
if (true === empty($absPrefix)) {
- // fallback if installation isnt done yet: relative links to same level on the current page
+ // fallback if installation isn't done yet: relative links to same level on the current page
$absPrefix = './';
}
define('JIRAFEAU_ABSPREFIX', $absPrefix);
' <a href="https://gitlab.com/mojo42/Jirafeau" target="_blank" rel="noopener noreferrer">' . t('JI_PROJECT') . '</a>' .
' (<a href="https://www.gnu.org/licenses/agpl.html" target="_blank" rel="noopener noreferrer"><abbr title="GNU Affero General Public License v3">AGPL-3.0</abbr></a>)';
?>
- <!-- Installation dependend links -->
+ <!-- Installation dependent links -->
<?php
if (false === empty($cfg['installation_done'])) {
echo ' <span>|</span> ';
echo " $0 delete URL"
echo
echo "Global variables to export:"
- echo " JIRAFEAU_PROXY: Domain and port of proxy server, eg. »proxysever.example.com:3128«"
+ echo " JIRAFEAU_PROXY: Domain and port of proxy server, eg. »proxyserver.example.com:3128«"
echo " JIRAFEAU_URL : URI to Jirafeau installation with trailing slash, eg. »https://example.com/jirafeau/«"
echo " JIRAFEAU_TIME : expiration time, eg. »minute«, »hour«, »day«, »week«, fortnight, »month«, »quarter«, »year« or »none«"
echo " JIRAFEAU_ONE_TIME : self-destroy after first download, eg. »1« to enable or »« (empty) to disable"