lib/config.local.php
lib/tos.local.txt
media/custom/
+media/dark-custom/
var-*
*._*
composer.phar
-# Select docker image from https://hub.docker.com/_/php/
-image: php:8.1
-
# Select what we should cache
cache:
paths:
- vendor/
-before_script:
- # Install git, the docker php image doesn't have it installed by default
- - apt-get update -yqq
- - apt-get install git -yqq
- - apt-get install zip -yqq
- # Enable necessary php extensions
- - docker-php-ext-enable curl && docker-php-ext-enable json && docker-php-ext-enable zip && docker-php-ext-enable mbstring && docker-php-ext-enable gd && docker-php-ext-enable pdo_mysql
- # Install composer
- - curl -sS https://getcomposer.org/installer | php
- # Create composer.json file manually, since this is a project without any non-dev dependencies yet
- - php composer.phar require --dev php-parallel-lint/php-parallel-lint
- - php composer.phar require --dev friendsofphp/php-cs-fixer:3.10.0
- # Install all project dependencies
- - php composer.phar install
-
-# Run tests
+# Run tests for php:8.1
job_lint_app_81:
image: php:8.1
- script:
+ before_script: &before_linter_script
+ # Install git, the docker php image doesn't have it installed by default
+ - apt-get update -yqq
+ - apt-get install git -yqq
+ - apt-get install zip -yqq
+ # Enable necessary php extensions
+ - docker-php-ext-enable curl && docker-php-ext-enable json && docker-php-ext-enable zip && docker-php-ext-enable mbstring && docker-php-ext-enable gd && docker-php-ext-enable pdo_mysql
+ # Install composer
+ - curl -sS https://getcomposer.org/installer | php
+ # Create composer.json file manually, since this is a project without any non-dev dependencies yet
+ - php composer.phar require --dev php-parallel-lint/php-parallel-lint
+ - php composer.phar require --dev friendsofphp/php-cs-fixer:3.10.0
+ # Install all project dependencies
+ - php composer.phar install
+ script: &linter_script
- ./vendor/bin/parallel-lint --exclude vendor .
- ./vendor/bin/php-cs-fixer -vvv fix . --dry-run --using-cache=no --rules=@PSR2
+# Run tests for php:7.4
job_lint_app_74:
image: php:7.4
+ before_script: *before_linter_script
+ script: *linter_script
+
+publish:
+ image: docker:latest
+ stage: deploy
+ services:
+ - docker:dind
script:
- - ./vendor/bin/parallel-lint --exclude vendor .
- - ./vendor/bin/php-cs-fixer -vvv fix . --dry-run --using-cache=no --rules=@PSR2
+ - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
+ - docker build -t $CI_REGISTRY/$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
+ # If we're on the default branch, also tag the image as latest
+ - docker build -t $CI_REGISTRY/$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG -t $CI_REGISTRY/$CI_REGISTRY_IMAGE:latest .
+ - docker push $CI_REGISTRY/$CI_REGISTRY_IMAGE --all-tags
+ only:
+ - tags
ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "UTC" > /etc/timezone
-COPY docker/cleanup.sh /cleanup.sh
-COPY docker/run.sh /run.sh
-RUN chmod o=,ug=rx /cleanup.sh /run.sh
-COPY docker/docker_config.php /docker_config.php
+COPY --chmod=550 docker/cleanup.sh docker/run.sh /
+COPY --chmod=640 docker/docker_config.php /docker_config.php
-RUN mkdir -p /usr/local/etc/php
COPY docker/php.ini /usr/local/etc/php/php.ini
COPY docker/lighttpd.conf /etc/lighttpd/lighttpd.conf
-# install jirafeau
-RUN mkdir /www
+# Install Jirafeau
WORKDIR /www
-# Will ignore some files through .dockerignore
-COPY . .
-RUN rm -rf docker && \
+
+RUN --mount=type=bind,source=.,target=/mnt \
+ cp -r /mnt/* /www/ && \
+ rm -rf /www/docker && \
touch /www/lib/config.local.php && \
chown -R $(id -u lighttpd).$(id -g www-data) /www && \
- chmod o=,ug=rwX -R /www
+ chmod 770 /www
-CMD /run.sh
+CMD ["/run.sh"]
EXPOSE 80
\ No newline at end of file
- Move var folder to a place on your server which can't be directly accessed
- Disable automatic listing on your web server config or place a index.html in var's sub-directory (this is a limited solution)
-If you are using Apache, you can add the following line to your configuration to prevent people to access to your `var` folder:
+If you are using Apache, you can add the following lines to your configuration to prevent people to access to your `var` folder:
-`RedirectMatch 301 ^/var-.* http://my.service.jirafeau`
+```apache
+<LocationMatch "^/var-*">
+ Require all denied
+</LocationMatch>
+```
+
+Or you can put a `.htaccess` file containing this into your `var` folder:
+
+```apache
+Require all denied
+```
If you are using nginx, you can add the following to your $vhost.conf:
You may change the default theme to any of the existing ones or a custom.
-Open your `lib/config.local.php` and change setting in the `style` key to the name of any folder in the `/media` directory.
+Open your `lib/config.local.php` and change setting in the `style` key to the name of any folder in the `/media` directory. If you want to change the theme for dark mode, you have to set the `dark_style` key in the config file.
-Hint: To create a custom theme just copy the `courgette` folder and name your theme `custom` (this way it will be ignored by git and not overwritten during updates). You are invited to enhance the existing themes and send pull requests however.
+Hint: To create a custom theme just copy the `courgette` folder and name your theme `custom` (this way it will be ignored by git and not overwritten during updates). If you want to create a custom theme for dark mode, you have to put it in a folder named `dark-custom`. You are invited to enhance the existing themes and send pull requests however.
### I found a bug, what should I do?
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
+docker run -d -p 80:80 --sysctl net.ipv4.ip_unprivileged_port_start=80 registry.gitlab.com/jirafeau/jirafeau
```
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/).
Example:
```
-docker run -it -p 8080:80 --rm -e ADMIN_PASSWORD='p4ssw0rd' -e WEB_ROOT='jirafeau.mydomain.com/' -e UPLOAD_PASSWORD='foo,bar' -e PREVIEW=0 mojo42/jirafeau:latest
+docker run -it -p 8080:80 --rm -e ADMIN_PASSWORD='p4ssw0rd' -e WEB_ROOT='jirafeau.mydomain.com/' -e UPLOAD_PASSWORD='foo,bar' -e PREVIEW=0 registry.gitlab.com/jirafeau/jirafeau:latest
```
## Data storage
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
+docker run -it --rm -p 8080:80 --mount source=jirafeau_data,target=/data registry.gitlab.com/jirafeau/jirafeau:latest
```
## Few notes
}
}
-run_setup($cfg);
\ No newline at end of file
+run_setup($cfg);
require(JIRAFEAU_ROOT . 'lib/functions.php');
require(JIRAFEAU_ROOT . 'lib/lang.php');
-if ($cfg['download_password_requirement'] === "generated"){
+if ($cfg['download_password_requirement'] === "generated") {
$download_pass = jirafeau_gen_download_pass($cfg['download_password_gen_len'], $cfg['download_password_gen_chars']);
}
</p>
</div>
- <?php if ($cfg['download_password_requirement'] === "generated"){
- ?>
+ <?php if ($cfg['download_password_requirement'] === "generated") {
+ ?>
<div id="show_password">
<p><?php echo t('PSW') ?></p>
<?php
if ($cfg['one_time_download']) {
echo '<tr><td>' . t('ONE_TIME_DL') . ':</td>';
- echo '<td><input type="checkbox" id="one_time_download" /></td></tr>';
+ echo '<td><input type="checkbox" id="one_time_download"';
+
+ if ($cfg['one_time_download_preselected']) {
+ echo ' checked';
+ }
+
+ echo ' /></td></tr>';
}
- if ($cfg['download_password_requirement'] === 'generated'){
+ if ($cfg['download_password_requirement'] === 'generated') {
echo '<input type="hidden" name="key" id="input_key" value="' . $download_pass .'"/>';
- }else{
+ } else {
echo '<tr><td><label for="input_key">' . t('PSW') . ':' . '</label></td>';
echo '<td><input type="password" name="key" id="input_key" autocomplete = "new-password"';
- if ($cfg['download_password_policy'] === 'regex'){
+ if ($cfg['download_password_policy'] === 'regex') {
echo ' pattern="' . substr($cfg['download_password_policy_regex'], 1, strlen($cfg['download_password_policy_regex']) - 2) . '"'; //remove php delimiters
}
- if ($cfg['download_password_requirement'] === 'required'){
+ if ($cfg['download_password_requirement'] === 'required') {
echo ' required';
}
echo '/></td></tr>';
*/
$cfg['one_time_download'] = true;
+/* When set to "true", the checkbox for deleting the file after the first download
+ * is preselected.
+ */
+$cfg['one_time_download_preselected'] = false;
+
/* Set maximal upload size expressed in MB.
* »0« means unlimited upload size.
*/
// Convert UTC timestamp to a datetime field
function jirafeau_get_datetimefield($timestamp)
{
-
$ts = date_create("@" . $timestamp);
$content = '<span class="datetime" data-datetime="' . date_format($ts, 'Y-m-d H:i') . '">'
. date_format($ts, 'Y-m-d H:i') . ' (GMT)</span>';
function jirafeau_admin_bug_report($cfg)
{
$out = "<fieldset><legend>" . t('REPORTING_AN_ISSUE') . "</legend>";
- $out .= "If you have a problem related to Jirafeau, please <a href='https://gitlab.com/jirafeau/Jirafeau/-/issues'>open an issue</a>, explain your problem in english and copy-paste the following content:<br/><br/><code>";
+ $out .= "If you have a problem related to Jirafeau, please <a href='" . JIRAFEAU_WEBSITE . "/-/issues'>open an issue</a>, explain your problem in english and copy-paste the following content:<br/><br/><code>";
$out .= "# Jirafeau<br/>";
$out .= "- version: " . JIRAFEAU_VERSION . "<br/>";
$enc = sodium_crypto_secretstream_xchacha20poly1305_push($crypt_state, $to_enc);
if (fwrite($w, $enc) === false) {
- return '';
+ return '';
}
}
/* Jirafeau package */
define('JIRAFEAU_PACKAGE', 'Jirafeau');
-define('JIRAFEAU_VERSION', '4.6.0');
+define('JIRAFEAU_VERSION', '4.6.x-dev');
+
+define('JIRAFEAU_WEBSITE', 'https://gitlab.com/jirafeau/Jirafeau');
/* Directories. */
define('VAR_FILES', $cfg['var_root'] . 'files/');
<!-- Project links -->
<?php
echo t('MADE_WITH') .
- ' <a href="https://gitlab.com/jirafeau/Jirafeau" target="_blank" rel="noopener noreferrer">' . t('JI_PROJECT') . '</a>' .
+ ' <a href="' . JIRAFEAU_WEBSITE . '" 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 dependent links -->
<div class="info">
<h2>Scripting interface</h2>
<p>This interface permits to script your uploads and downloads.</p>
- <p>See <a href="https://gitlab.com/jirafeau/Jirafeau/blob/master/script.php">source code</a> of this interface to get available calls :)</p>
+ <p>See <a href="<?php echo JIRAFEAU_WEBSITE ?>/blob/master/script.php">source code</a> of this interface to get available calls :)</p>
<p>You may download a preconfigured <a href="script.php?lang=bash">Bash Script</a> to easily send to and get files from the API via command line.</p>
</div>
<br />
$key = '';
if (isset($_POST['key'])) {
$key = $_POST['key'];
- if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex'){
- if (!preg_match($cfg['download_password_policy_regex'], $key)){
+ if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex') {
+ if (!preg_match($cfg['download_password_policy_regex'], $key)) {
echo 'Error 14: The download password is not complying to the security standards.';
exit;
}
}
- }elseif ($cfg['download_password_requirement'] !== 'optional'){
+ } elseif ($cfg['download_password_requirement'] !== 'optional') {
echo 'Error 13: The parameter password is required.';
exit;
}
$key = '';
if (isset($_POST['key'])) {
$key = $_POST['key'];
- if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex'){
- if (!preg_match($cfg['download_password_policy_regex'], $key)){
+ if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex') {
+ if (!preg_match($cfg['download_password_policy_regex'], $key)) {
echo 'Error 14: The download password is not complying to the security standards.';
exit;
}
}
- }elseif ($cfg['download_password_requirement'] !== 'optional'){
+ } elseif ($cfg['download_password_requirement'] !== 'optional') {
echo 'Error 13: The parameter password is required.';
exit;
}
$key = '';
if (isset($_POST['key'])) {
$key = $_POST['key'];
- if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex'){
- if (!preg_match($cfg['download_password_policy_regex'], $key)){
+ if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex') {
+ if (!preg_match($cfg['download_password_policy_regex'], $key)) {
echo 'Error 14: The download password is not complying to the security standards.';
exit;
}
}
- }elseif ($cfg['download_password_requirement'] !== 'optional'){
+ } elseif ($cfg['download_password_requirement'] !== 'optional') {
echo 'Error 13: The parameter password is required.';
exit;
}