]> git.p6c8.net - jirafeau_project.git/blobdiff - lib/functions.js.php
fix input validation on required/regex setting
[jirafeau_project.git] / lib / functions.js.php
index 7d248b5c7b5c4e616eb7a8369616ad9644f06643..58623e6b2c053d91c41bc028269632a87331601e 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  *  Jirafeau, your web file repository
 <?php
 /*
  *  Jirafeau, your web file repository
- *  Copyright (C) 2015  Jerome Jutteau <j.jutteau@gmail.com>
+ *  Copyright (C) 2015  Jerome Jutteau <jerome@jutteau.fr>
  *  Copyright (C) 2015  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
  *
  *  This program is free software: you can redistribute it and/or modify
  *  Copyright (C) 2015  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
  *
  *  This program is free software: you can redistribute it and/or modify
  */
 
 header('Content-Type: text/javascript');
  */
 
 header('Content-Type: text/javascript');
-
 define('JIRAFEAU_ROOT', dirname(__FILE__) . '/../');
 
 require(JIRAFEAU_ROOT . 'lib/settings.php');
 require(JIRAFEAU_ROOT . 'lib/functions.php');
 require(JIRAFEAU_ROOT . 'lib/lang.php');
 define('JIRAFEAU_ROOT', dirname(__FILE__) . '/../');
 
 require(JIRAFEAU_ROOT . 'lib/settings.php');
 require(JIRAFEAU_ROOT . 'lib/functions.php');
 require(JIRAFEAU_ROOT . 'lib/lang.php');
+
 ?>
 ?>
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
+var web_root = "<?php echo $cfg['web_root']; ?>";
 
 
-function translate (expr)
-{
-    var lang_array = <?php echo json_lang_generator() ?>;
-    if (lang_array.hasOwnProperty(expr))
-        return lang_array[expr];
-    return expr;
+var lang_array = <?php echo json_lang_generator(null); ?>;
+var lang_array_fallback = <?php echo json_lang_generator("en"); ?>;
+
+function translate (expr) {
+    if (lang_array.hasOwnProperty(expr)) {
+        var e = lang_array[expr];
+        if (!isEmpty(e))
+            return e;
+    }
+    if (lang_array_fallback.hasOwnProperty(expr)) {
+        var e = lang_array_fallback[expr];
+        if (!isEmpty(e))
+            return e;
+    }
+    return "FIXME: " + expr;
 }
 
 function isEmpty(str) {
 }
 
 function isEmpty(str) {
@@ -130,21 +141,23 @@ function show_link (reference, delete_code, crypt_key, date)
     if (!!document.getElementById('upload_finished_download_page'))
     {
         document.getElementById('upload_link').href = download_link_href;
     if (!!document.getElementById('upload_finished_download_page'))
     {
         document.getElementById('upload_link').href = download_link_href;
+        document.getElementById('upload_link_text').innerHTML = web_root + download_link_href;
     }
 
     // Email link
     var filename = document.getElementById('file_select').files[0].name;
     }
 
     // Email link
     var filename = document.getElementById('file_select').files[0].name;
-    var b = encodeURIComponent("Download file \"" + filename + "\":") + "%0D";
-    b += encodeURIComponent("<?php echo $cfg['web_root']; ?>" + download_link_href) + "%0D";
+    var b = encodeURIComponent("<?php echo t("DL"); ?> \"" + filename + "\":") + "%0D" + "%0A";
+    b += encodeURIComponent(web_root + download_link_href) + "%0D" + "%0A";
     if (false == isEmpty(date))
     {
     if (false == isEmpty(date))
     {
-        b += "%0D" + encodeURIComponent("This file will be available until " + date.format('YYYY-MM-DD hh:mm (GMT O)')) + "%0D";
+        b += "%0D" + "%0A" + encodeURIComponent("<?php echo t("VALID_UNTIL"); ?>: " + date.format('YYYY-MM-DD hh:mm (GMT O)')) + "%0D" + "%0A";
         document.getElementById('upload_link_email').href = "mailto:?body=" + b + "&subject=" + encodeURIComponent(filename);
     }
 
     // Delete link
     var delete_link_href = 'f.php?h=' + reference + '&d=' + delete_code;
     document.getElementById('delete_link').href = delete_link_href;
         document.getElementById('upload_link_email').href = "mailto:?body=" + b + "&subject=" + encodeURIComponent(filename);
     }
 
     // Delete link
     var delete_link_href = 'f.php?h=' + reference + '&d=' + delete_code;
     document.getElementById('delete_link').href = delete_link_href;
+    document.getElementById('delete_link_text').innerHTML = web_root + delete_link_href;
 
     // Validity date
     if (isEmpty(date))
 
     // Validity date
     if (isEmpty(date))
@@ -170,15 +183,17 @@ function show_link (reference, delete_code, crypt_key, date)
         }
 
         // Test if content can be previewed
         }
 
         // Test if content can be previewed
-         type = document.getElementById('file_select').files[0].type;
-         if (type.indexOf("image") > -1 ||
-             type.indexOf("audio") > -1 ||
-             type.indexOf("text") > -1 ||
-             type.indexOf("video") > -1)
-         {
+        type = document.getElementById('file_select').files[0].type;
+        if ((type.startsWith('image/')
+                || type.startsWith('audio')
+                || type.startsWith('text/plain')
+                || type.startsWith('video/'))
+            && !type.includes('image/svg+xml'))
+        {
             document.getElementById('preview_link').href = preview_link_href;
             document.getElementById('preview_link').href = preview_link_href;
+            document.getElementById('preview_link_text').innerHTML = web_root + preview_link_href;
             document.getElementById('upload_finished_preview').style.display = '';
             document.getElementById('upload_finished_preview').style.display = '';
-         }
+        }
     }
 
     // Direct download link
     }
 
     // Direct download link
@@ -188,6 +203,7 @@ function show_link (reference, delete_code, crypt_key, date)
         direct_download_link_href += '&k=' + crypt_key;
     }
     document.getElementById('direct_link').href = direct_download_link_href;
         direct_download_link_href += '&k=' + crypt_key;
     }
     document.getElementById('direct_link').href = direct_download_link_href;
+    document.getElementById('direct_link_text').innerHTML = web_root + direct_download_link_href;
 
     // Hide preview and direct download link if password is set
     if (document.getElementById('input_key').value.length > 0)
 
     // Hide preview and direct download link if password is set
     if (document.getElementById('input_key').value.length > 0)
@@ -259,12 +275,18 @@ function control_selected_file_size(max_size, error_str)
     }
 }
 
     }
 }
 
+function XHRErrorHandler(e)
+{
+    var text = "${e.type}: ${e.loaded} bytes transferred"
+    console.log(text)
+}
+
 function pop_failure (e)
 {
 function pop_failure (e)
 {
-    var text = "An error occured";
+    var text = "<p>An error occured";
     if (typeof e !== 'undefined')
     if (typeof e !== 'undefined')
-        text = e;
-    text = "<p>" + text + "</p>";
+        text += ": " + e;
+    text += "</p>";
     document.getElementById('error_pop').innerHTML = e;
 
     document.getElementById('uploading').style.display = 'none';
     document.getElementById('error_pop').innerHTML = e;
 
     document.getElementById('uploading').style.display = 'none';
@@ -300,33 +322,38 @@ function add_time_string_to_date(d, time)
         d.setSeconds (d.getSeconds() + 604800);
         return true;
     }
         d.setSeconds (d.getSeconds() + 604800);
         return true;
     }
+    if (time == 'fortnight')
+    {
+        d.setSeconds (d.getSeconds() + 1209600);
+        return true;
+    }
     if (time == 'month')
     {
     if (time == 'month')
     {
-        d.setSeconds (d.getSeconds() + 2419200);
+               d.setSeconds (d.getSeconds() + 2592000);
         return true;
     }
     if (time == 'quarter')
     {
         return true;
     }
     if (time == 'quarter')
     {
-        d.setSeconds (d.getSeconds() + 7257600);
+               d.setSeconds (d.getSeconds() + 7776000);
         return true;
     }
     if (time == 'year')
     {
         return true;
     }
     if (time == 'year')
     {
-        d.setSeconds (d.getSeconds() + 29030400);
+               d.setSeconds (d.getSeconds() + 31536000);
         return true;
     }
     return false;
 }
 
         return true;
     }
     return false;
 }
 
-function classic_upload (file, time, password, one_time, upload_password)
+function classic_upload (file, time, password, one_time)
 {
     // Delay time estimation init as we can't have file size
     upload_time_estimation_init(0);
 
     var req = new XMLHttpRequest ();
     req.upload.addEventListener ("progress", upload_progress, false);
 {
     // Delay time estimation init as we can't have file size
     upload_time_estimation_init(0);
 
     var req = new XMLHttpRequest ();
     req.upload.addEventListener ("progress", upload_progress, false);
-    req.addEventListener ("error", pop_failure, false);
-    req.addEventListener ("abort", pop_failure, false);
+    req.addEventListener ("error", XHRErrorHandler, false);
+    req.addEventListener ("abort", XHRErrorHandler, false);
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
@@ -356,6 +383,10 @@ function classic_upload (file, time, password, one_time, upload_password)
 
             show_link (res[0], res[1], res[2], expiryDate);
         }
 
             show_link (res[0], res[1], res[2], expiryDate);
         }
+        else
+        {
+            pop_failure ("<?php echo t("ERR_OCC"); ?>");
+        }
     }
     req.open ("POST", 'script.php' , true);
 
     }
     req.open ("POST", 'script.php' , true);
 
@@ -367,9 +398,6 @@ function classic_upload (file, time, password, one_time, upload_password)
         form.append ("key", password);
     if (one_time)
         form.append ("one_time_download", '1');
         form.append ("key", password);
     if (one_time)
         form.append ("one_time_download", '1');
-    if (upload_password.length > 0)
-        form.append ("upload_password", upload_password);
-
     req.send (form);
 }
 
     req.send (form);
 }
 
@@ -384,8 +412,9 @@ var async_global_ref = '';
 var async_global_max_size = 0;
 var async_global_time;
 var async_global_transfering = 0;
 var async_global_max_size = 0;
 var async_global_time;
 var async_global_transfering = 0;
+var async_global_last_code;
 
 
-function async_upload_start (max_size, file, time, password, one_time, upload_password)
+function async_upload_start (max_size, file, time, password, one_time)
 {
     async_global_transfered = 0;
     async_global_file = file;
 {
     async_global_transfered = 0;
     async_global_file = file;
@@ -393,8 +422,8 @@ function async_upload_start (max_size, file, time, password, one_time, upload_pa
     async_global_time = time;
 
     var req = new XMLHttpRequest ();
     async_global_time = time;
 
     var req = new XMLHttpRequest ();
-    req.addEventListener ("error", pop_failure, false);
-    req.addEventListener ("abort", pop_failure, false);
+    req.addEventListener ("error", XHRErrorHandler, false);
+    req.addEventListener ("abort", XHRErrorHandler, false);
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
@@ -424,8 +453,6 @@ function async_upload_start (max_size, file, time, password, one_time, upload_pa
         form.append ("key", password);
     if (one_time)
         form.append ("one_time_download", '1');
         form.append ("key", password);
     if (one_time)
         form.append ("one_time_download", '1');
-    if (upload_password.length > 0)
-        form.append ("upload_password", upload_password);
 
     // Start time estimation
     upload_time_estimation_init(async_global_file.size);
 
     // Start time estimation
     upload_time_estimation_init(async_global_file.size);
@@ -456,6 +483,7 @@ function async_upload_progress (e)
 
 function async_upload_push (code)
 {
 
 function async_upload_push (code)
 {
+    async_global_last_code = code;
     if (async_global_transfered == async_global_file.size)
     {
         hide_upload_progression ();
     if (async_global_transfered == async_global_file.size)
     {
         hide_upload_progression ();
@@ -464,31 +492,53 @@ function async_upload_push (code)
     }
     var req = new XMLHttpRequest ();
     req.upload.addEventListener ("progress", async_upload_progress, false);
     }
     var req = new XMLHttpRequest ();
     req.upload.addEventListener ("progress", async_upload_progress, false);
-    req.addEventListener ("error", pop_failure, false);
-    req.addEventListener ("abort", pop_failure, false);
+    req.addEventListener ("error", XHRErrorHandler, false);
+    req.addEventListener ("abort", XHRErrorHandler, false);
     req.onreadystatechange = function ()
     {
     req.onreadystatechange = function ()
     {
-        if (req.readyState == 4 && req.status == 200)
+        if (req.readyState == 4)
         {
         {
-            var res = req.responseText;
+            if (req.status == 200)
+            {
+                var res = req.responseText;
 
 
-            if (/^Error/.test(res))
+                // This error may be triggered when Jirafeau does not receive any file in POST.
+                // This may be due to bad php configuration where post_max_size is too low
+                // comparing to upload_max_filesize. Let's retry with lower file size.
+                if (res === "Error 23")
+                {
+                    async_global_max_size = Math.max(1, async_global_max_size - 500);
+                    async_upload_push (async_global_last_code);
+                    return;
+                }
+                else if (/^Error/.test(res))
+                {
+                    pop_failure (res);
+                    return;
+                }
+
+                res = res.split ("\n");
+                var code = res[0]
+                async_global_transfered = async_global_transfering;
+                async_upload_push (code);
+                return;
+            }
+            else
             {
             {
-                pop_failure (res);
+                // lower async_global_max_size and retry
+                // This can occurs in several cases:
+                // - Request Entity Too Large (413) due to server bad configuration relative to PHP configuration
+                // - Server Error (500) which can happen when PHP's `max_execution_time` is too low comparared to sent size
+                async_global_max_size = Math.max(1, parseInt (async_global_max_size * 0.5));
+                async_upload_push (async_global_last_code);
                 return;
             }
                 return;
             }
-
-            res = res.split ("\n");
-            var code = res[0]
-            async_global_transfered = async_global_transfering;
-            async_upload_push (code);
         }
     }
     req.open ("POST", 'script.php?push_async' , true);
 
         }
     }
     req.open ("POST", 'script.php?push_async' , true);
 
-    var chunk_size = parseInt (async_global_max_size * 0.50);
     var start = async_global_transfered;
     var start = async_global_transfered;
-    var end = start + chunk_size;
+    var end = start + async_global_max_size;
     if (end >= async_global_file.size)
         end = async_global_file.size;
     var blob = async_global_file.slice (start, end);
     if (end >= async_global_file.size)
         end = async_global_file.size;
     var blob = async_global_file.slice (start, end);
@@ -504,8 +554,8 @@ function async_upload_push (code)
 function async_upload_end (code)
 {
     var req = new XMLHttpRequest ();
 function async_upload_end (code)
 {
     var req = new XMLHttpRequest ();
-    req.addEventListener ("error", pop_failure, false);
-    req.addEventListener ("abort", pop_failure, false);
+    req.addEventListener ("error", XHRErrorHandler, false);
+    req.addEventListener ("abort", XHRErrorHandler, false);
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
     req.onreadystatechange = function ()
     {
         if (req.readyState == 4 && req.status == 200)
@@ -542,18 +592,18 @@ function async_upload_end (code)
     req.send (form);
 }
 
     req.send (form);
 }
 
-function upload (max_size)
+function upload (max_chunk_size)
 {
 {
-    if (check_html5_file_api ()
-        && document.getElementById('file_select').files[0].size >= max_size)
+    var one_time_checkbox = document.getElementById('one_time_download');
+    var one_time = one_time_checkbox !== null ? one_time_checkbox.checked : false;
+    if (check_html5_file_api ())
     {
         async_upload_start (
     {
         async_upload_start (
-            max_size,
+            max_chunk_size,
             document.getElementById('file_select').files[0],
             document.getElementById('select_time').value,
             document.getElementById('input_key').value,
             document.getElementById('file_select').files[0],
             document.getElementById('select_time').value,
             document.getElementById('input_key').value,
-            document.getElementById('one_time_download').checked,
-            document.getElementById('upload_password').value
+            one_time
             );
     }
     else
             );
     }
     else
@@ -562,8 +612,7 @@ function upload (max_size)
             document.getElementById('file_select').files[0],
             document.getElementById('select_time').value,
             document.getElementById('input_key').value,
             document.getElementById('file_select').files[0],
             document.getElementById('select_time').value,
             document.getElementById('input_key').value,
-            document.getElementById('one_time_download').checked,
-            document.getElementById('upload_password').value
+            one_time
             );
     }
 }
             );
     }
 }
@@ -587,9 +636,11 @@ function upload_time_estimation_add(total_transfered_size)
     // Let's compute the current speed
     var d = new Date();
     var speed = upload_time_estimation_moving_average_speed;
     // Let's compute the current speed
     var d = new Date();
     var speed = upload_time_estimation_moving_average_speed;
-    if (d.getTime() - upload_time_estimation_transfered_date != 0)
+    if (d.getTime() - upload_time_estimation_transfered_date != 0) {
         speed = (total_transfered_size - upload_time_estimation_transfered_size)
                 / (d.getTime() - upload_time_estimation_transfered_date);
         speed = (total_transfered_size - upload_time_estimation_transfered_size)
                 / (d.getTime() - upload_time_estimation_transfered_date);
+        speed = Math.max(0, speed);
+    }
     // Let's compute moving average speed on 30 values
     var m = (upload_time_estimation_moving_average_speed * 29 + speed) / 30;
     // Update global values
     // Let's compute moving average speed on 30 values
     var m = (upload_time_estimation_moving_average_speed * 29 + speed) / 30;
     // Update global values
@@ -607,17 +658,17 @@ function upload_time_estimation_speed_string()
     if (s <= 1000)
     {
         res = s.toString();
     if (s <= 1000)
     {
         res = s.toString();
-        scale = "Bit/s";
+        scale = "B/s";
     }
     else if (s < 1000000)
     {
         res = Math.floor(s/100) / 10;
     }
     else if (s < 1000000)
     {
         res = Math.floor(s/100) / 10;
-        scale = "KBit/s";
+        scale = "KB/s";
     }
     else
     {
         res = Math.floor(s/100000) / 10;
     }
     else
     {
         res = Math.floor(s/100000) / 10;
-        scale = "Mbit/s";
+        scale = "MB/s";
     }
     if (res == 0)
         return '';
     }
     if (res == 0)
         return '';
@@ -627,44 +678,37 @@ function upload_time_estimation_speed_string()
 function milliseconds_to_time_string (milliseconds)
 {
     function numberEnding (number) {
 function milliseconds_to_time_string (milliseconds)
 {
     function numberEnding (number) {
-      var currentLanguage = '<?php echo $cfg['lang']; ?>';
-
-      if(currentLanguage == 'de') {
-        return (number > 1) ? 'n' : '';
-      }
-      else {
-        return (number > 1) ? 's' : '';
-      }
+        return (number > 1) ? translate ('PLURAL_ENDING') : '';
     }
 
     var temp = Math.floor(milliseconds / 1000);
     var years = Math.floor(temp / 31536000);
     if (years) {
     }
 
     var temp = Math.floor(milliseconds / 1000);
     var years = Math.floor(temp / 31536000);
     if (years) {
-        return years + ' ' + translate ('year') + numberEnding(years);
+        return years + ' ' + translate ('YEAR') + numberEnding(years);
     }
     var days = Math.floor((temp %= 31536000) / 86400);
     if (days) {
     }
     var days = Math.floor((temp %= 31536000) / 86400);
     if (days) {
-        return days + ' ' + translate ('day') + numberEnding(days);
+        return days + ' ' + translate ('DAY') + numberEnding(days);
     }
     var hours = Math.floor((temp %= 86400) / 3600);
     if (hours) {
     }
     var hours = Math.floor((temp %= 86400) / 3600);
     if (hours) {
-        return hours + ' ' + translate ('hour') + numberEnding(hours);
+        return hours + ' ' + translate ('HOUR') + numberEnding(hours);
     }
     var minutes = Math.floor((temp %= 3600) / 60);
     if (minutes) {
     }
     var minutes = Math.floor((temp %= 3600) / 60);
     if (minutes) {
-        return minutes + ' ' + translate ('minute') + numberEnding(minutes);
+        return minutes + ' ' + translate ('MINUTE') + numberEnding(minutes);
     }
     var seconds = temp % 60;
     if (seconds) {
     }
     var seconds = temp % 60;
     if (seconds) {
-        return seconds + ' ' + translate ('second') + numberEnding(seconds);
+        return seconds + ' ' + translate ('SECOND') + numberEnding(seconds);
     }
     }
-    return translate ('less than a second');
+    return translate ('LESS_1_SEC');
 }
 
 function upload_time_estimation_time()
 {
     // Estimate remaining time
 }
 
 function upload_time_estimation_time()
 {
     // Estimate remaining time
-    if (upload_time_estimation_moving_average_speed == 0)
+    if (upload_time_estimation_moving_average_speed <= 0)
         return 0;
     return (upload_time_estimation_total_size - upload_time_estimation_transfered_size)
             / upload_time_estimation_moving_average_speed;
         return 0;
     return (upload_time_estimation_total_size - upload_time_estimation_transfered_size)
             / upload_time_estimation_moving_average_speed;
@@ -735,7 +779,55 @@ function copyLinkToClipboard(link_id) {
 }
 
 function addCopyListener(button_id, link_id) {
 }
 
 function addCopyListener(button_id, link_id) {
-    document.getElementById(button_id)
+    if(document.getElementById(button_id)){
+        document.getElementById(button_id)
             .addEventListener("click", function() {
                 copyLinkToClipboard(link_id);});
             .addEventListener("click", function() {
                 copyLinkToClipboard(link_id);});
+    }
 }
 }
+
+function copyTextToClipboard(text_id){
+    var copyText = document.getElementById(text_id);
+    copyText.select();
+    copyText.setSelectionRange(0, 99999); 
+    navigator.clipboard.writeText(copyText.value);
+}
+
+function addTextCopyListener(button_id, text_id) {
+    if(document.getElementById(button_id)){
+        document.getElementById(button_id)
+            .addEventListener("click", function() {
+                copyTextToClipboard(text_id);});
+    }
+}
+
+function set_dark_mode() {
+    let steel_sheet = "<?php echo 'media/' . $cfg['dark_style'] . '/style.css.php'; ?>";
+    let shortcut_icon = "<?php echo 'media/' . $cfg['dark_style'] . '/favicon.ico'; ?>";
+    document.getElementById('stylesheet').href = steel_sheet;
+    document.getElementById('shortcut_icon').href = steel_sheet;
+}
+
+function set_light_mode() {
+    let steel_sheet = "<?php echo 'media/' . $cfg['style'] . '/style.css.php'; ?>";
+    let shortcut_icon = "<?php echo 'media/' . $cfg['style'] . '/favicon.ico'; ?>";
+    document.getElementById('stylesheet').href = steel_sheet;
+    document.getElementById('shortcut_icon').href = steel_sheet;
+}
+
+function color_scheme_preferences() {
+
+    let dark_mode_steel_sheet = "<?php echo 'media/' . $cfg['dark_style'] . '/style.css.php'; ?>"
+    if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+        set_dark_mode();
+    } else {
+        set_light_mode();
+    }
+
+    // When user change its preference
+    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', lightMode => {
+        lightMode.matches ? set_dark_mode() : set_light_mode();
+    });
+}
+
+// @license-end

patrick-canterino.de