diff options
-rw-r--r-- | build/docker/docker-compose-ncpdev.yml | 6 | ||||
-rw-r--r-- | changelog.md | 20 | ||||
-rw-r--r-- | ncp-web/css/ncp.css | 15 | ||||
-rw-r--r-- | ncp-web/download_logs.php | 75 | ||||
-rw-r--r-- | ncp-web/img/logs.svg | 38 | ||||
-rw-r--r-- | ncp-web/index.php | 16 | ||||
-rw-r--r-- | ncp-web/js/ncp.js | 46 | ||||
-rw-r--r-- | ncp-web/ncp-launcher.php | 10 | ||||
-rw-r--r-- | updates/1.42.0.sh (renamed from updates/1.41.0.sh) | 0 |
9 files changed, 214 insertions, 12 deletions
diff --git a/build/docker/docker-compose-ncpdev.yml b/build/docker/docker-compose-ncpdev.yml index e4e5d7db..80b06544 100644 --- a/build/docker/docker-compose-ncpdev.yml +++ b/build/docker/docker-compose-ncpdev.yml @@ -8,9 +8,9 @@ services: - "443:443" - "4443:4443" volumes: - - ./ncp-web:/var/www/ncp-web - - ./etc:/usr/local/etc - - ./changelog.md:/changelog.md + - ../../ncp-web:/var/www/ncp-web + - ../../etc:/usr/local/etc + - ../../changelog.md:/changelog.md - ncdata:/data container_name: nextcloudpi diff --git a/changelog.md b/changelog.md index b6cd0ff5..596534e8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,13 +1,19 @@ -<<<<<<< HEAD -[v1.40.5](https://github.com/nextcloud/nextcloudpi/commit/6c3cb37) (2021-10-11) letsencrypt: keep original cert name +[v1.41.0](https://github.com/nextcloud/nextcloudpi/commit/33d8167) (2021-10-13) ncp-web: add NCP logs section -[v1.40.4 ](https://github.com/nextcloud/nextcloudpi/commit/de104a5) (2021-10-06) Make templating safer and more verbose (#1343) -======= -[v1.40.5](https://github.com/nextcloud/nextcloudpi/commit/f7c393f) (2021-10-11) add architecture and kernel info to ncp-info (#1360) +[v1.40.10](https://github.com/nextcloud/nextcloudpi/commit/8bb5795) (2021-10-12) nc-import-ncp: run activated apps upon import + +[v1.40.9 ](https://github.com/nextcloud/nextcloudpi/commit/a4998cd) (2021-10-12) letsencrypt: favor most recent cert if there are many + +[v1.40.8 ](https://github.com/nextcloud/nextcloudpi/commit/9bddfad) (2021-10-12) fix HPB with dynamic IP + +[v1.40.7 ](https://github.com/nextcloud/nextcloudpi/commit/4e790e4) (2021-10-12) letsencrypt: fix template generation -[v1.40.4](https://github.com/nextcloud/nextcloudpi/commit/de104a5) (2021-10-06) Make templating safer and more verbose (#1343) ->>>>>>> b532589 (add architecture and kernel info to ncp-info (#1360)) +[v1.40.6 ](https://github.com/nextcloud/nextcloudpi/commit/b64859e) (2021-10-11) add architecture and kernel info to ncp-info (#1360) + +[v1.40.5](https://github.com/nextcloud/nextcloudpi/commit/cc3f336) (2021-10-11) letsencrypt: keep original cert name + +[v1.40.4 ](https://github.com/nextcloud/nextcloudpi/commit/de104a5) (2021-10-06) Make templating safer and more verbose (#1343) [v1.40.3 ](https://github.com/nextcloud/nextcloudpi/commit/8a6c1c0) (2021-10-06) ncp-check-nc-version: dont notify the same version more than once diff --git a/ncp-web/css/ncp.css b/ncp-web/css/ncp.css index 56599b8d..fec345df 100644 --- a/ncp-web/css/ncp.css +++ b/ncp-web/css/ncp.css @@ -1153,6 +1153,9 @@ select { .icon-backups { background-image: url('../img/defaults-white.svg'); } +.icon-logs { + background-image: url('../img/logs.svg'); +} .icon-config { background-image: url('../img/settings-white.svg'); } @@ -1238,6 +1241,10 @@ a#versionlink:hover { cursor:pointer; } +#log-download-btn-wrapper { + text-align: center +} + .dialog { display:block; background: white; @@ -1375,6 +1382,14 @@ a#versionlink:hover { overflow: auto; } +#logs-details-box { + background-color: #fbfbfb; + border: solid 1px lightgray; + color: #565656; + overflow: auto; + height: 80vh; +} + #language-selection { border: none; } diff --git a/ncp-web/download_logs.php b/ncp-web/download_logs.php new file mode 100644 index 00000000..5e02469f --- /dev/null +++ b/ncp-web/download_logs.php @@ -0,0 +1,75 @@ +<?php +/// +// NextCloudPi Web Panel backend +// +// Copyleft 2019 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com> +// GPL licensed (see end of file) * Use at your own risk! +// +// More at https://nextcloudpi.com +/// + +include ('csrf.php'); +session_start(); + +// CSRF check +$token = isset($_REQUEST['token']) ? $_REQUEST['token'] : ''; +if ( empty($token) || !validateCSRFToken($token) ) + exit('Unauthorized download'); + +$file = '/var/log/ncp.log'; + +if (!file_exists($file) + die('File not found'); + +if (!is_readable($file)) + die('NCP does not have read permissions on this file'); + +function filesize_compat($file) +{ + if(PHP_INT_SIZE === 4) # workaround for 32-bit architectures + return trim(shell_exec("stat -c%s " . escapeshellarg($file))); + else + return filesize($file); +} + +$size = filesize_compat($file); + +$mime_type = 'text/plain'; + +ob_start(); +ob_clean(); +header('Content-Description: File Transfer'); +header('Content-Type: ' . $mime_type); +header("Content-Transfer-Encoding: Binary"); +header("Content-disposition: attachment; filename=\"" . basename($file) . "\""); +header('Content-Length: ' . $size); +header('Expires: 0'); +header('Cache-Control: must-revalidate'); +header('Pragma: public'); + +$chunksize = 8 * (1024 * 1024); + +if($size > $chunksize || PHP_INT_SIZE === 4) # always chunk for 32-bit architectures +{ + $handle = fopen($file, 'rb') or die("Error opening file"); + + while (!feof($handle)) + { + $buffer = fread($handle, $chunksize); + echo $buffer; + + ob_flush(); + flush(); + } + + fclose($handle); +} +else + readfile($file); + +ob_flush(); +flush(); + +exit(); + +?> diff --git a/ncp-web/img/logs.svg b/ncp-web/img/logs.svg new file mode 100644 index 00000000..3d44ae87 --- /dev/null +++ b/ncp-web/img/logs.svg @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + viewBox="0 0 16 16" + width="16" + version="1.1" + height="16" + id="svg887" + sodipodi:docname="logs.svg" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs891" /> + <sodipodi:namedview + id="namedview889" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="54.0625" + inkscape:cx="8" + inkscape:cy="8" + inkscape:window-width="2560" + inkscape:window-height="1080" + inkscape:window-x="1440" + inkscape:window-y="1087" + inkscape:window-maximized="1" + inkscape:current-layer="svg887" /> + <path + d="m2.5 1c-0.28 0-0.5 0.22-0.5 0.5v13c0 0.28 0.22 0.5 0.5 0.5h11c0.28 0 0.5-0.22 0.5-0.5v-10.5l-3-3h-8.5zm1.5 2h6v1h-6v-1zm0 3h5v1h-5v-1zm0 3h8v1h-8v-1zm0 3h4v1h-4v-1z" + id="path885" + style="fill:#ffffff" /> +</svg> diff --git a/ncp-web/index.php b/ncp-web/index.php index b5d99f3c..361f4210 100644 --- a/ncp-web/index.php +++ b/ncp-web/index.php @@ -190,6 +190,11 @@ HTML; <div class="icon-config"></div> </div> </div> + <div id="logs-btn" title="<?php echo $l->__("Logs"); ?>"> + <div class="expand"> + <div class="icon-logs"></div> + </div> + </div> <a href="wizard" title="<?php echo $l->__("NextCloudPi Wizard"); ?>"> <div class="wizard-btn"> <div class="expand"> @@ -266,8 +271,16 @@ HTML; } echo '</table>'; ?> + </div> </div> - </div> + <div id="logs-wrapper" class="content-box <?php if(!array_key_exists('app',$_GET) || (array_key_exists('app',$_GET) && $_GET['app'] != 'logs')) echo 'hidden';?>"> + <h2 class="text-title"><?php echo $l->__("NextCloudPi logs"); ?></h2> + <div id="logs-content" class="table-wrapper"> + <div id="logs-details-box" class="outputbox"><?php echo str_replace(array("\r\n", "\n", "\r"), '<br/>', file_get_contents('/var/log/ncp.log')) ?></div> + <div id="log-download-btn-wrapper"><input id="log-download-btn" type="button" value="Download"/></div> + </div> + </div> + </div> <div id="poweroff-dialog" class='dialog primary hidden'> @@ -283,6 +296,7 @@ HTML; include('csrf.php'); echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>'; echo '<input type="hidden" id="csrf-token-ui" name="csrf-token-ui" value="' . getCSRFToken() . '"/>'; + echo '<input type="hidden" id="csrf-token-dl" name="csrf-token-dl" value="' . getCSRFToken() . '"/>'; echo '<input type="hidden" id="csrf-token-cfg" name="csrf-token-cfg" value="' . getCSRFToken() . '"/>'; ?> <script src="js/minified.js"></script> diff --git a/ncp-web/js/ncp.js b/ncp-web/js/ncp.js index bd0dc108..f2f8e43a 100644 --- a/ncp-web/js/ncp.js +++ b/ncp-web/js/ncp.js @@ -24,6 +24,8 @@ window.onpopstate = function(event) { switch_to_section('nc-config'); else if (selectedID == 'dashboard') switch_to_section('dashboard'); + else if (selectedID == 'logs') + switch_to_section('logs'); else click_app($('#' + selectedID)); }; @@ -38,6 +40,7 @@ function switch_to_section(section) // TODO unify repeating code $( '#config-wrapper > div' ).hide(); $( '#dashboard-wrapper' ).hide(); + $( '#logs-wrapper' ).hide(); $( '#nc-config-wrapper' ).hide(); $( '#backups-wrapper' ).hide(); $( '#' + section + '-wrapper' ).show(); @@ -228,6 +231,21 @@ function dialog_action(button) clicked_dialog_action(clicked_dialog_button); } +function refresh_dl_token() +{ + $.request('post', 'ncp-launcher.php', { action:'next-dl', + csrf_token: $( '#csrf-token' ).get( '.value' ) }).then( + function success( result ) + { + var ret = $.parseJSON( result ); + if ( ret.token ) + $('#csrf-token').set( { value: ret.token } ); + if ( ret.token_dl ) + $('#csrf-token-dl').set( { value: ret.token_dl } ); + } + ).error( errorMsg ) +} + // backups function set_backup_handlers() { @@ -235,7 +253,9 @@ function set_backup_handlers() { var tr = this.up().up(); var path = tr.get('.id'); - window.location.replace('download.php?bkp=' + encodeURIComponent(path) + '&token=' + encodeURIComponent(tr.next().get('.value'))); + var token_dl = $('#csrf-token-dl').get('.value'); + window.location.replace('download.php?bkp=' + encodeURIComponent(path) + '&token=' + encodeURIComponent(token_dl)); + refresh_dl_token(); }); $( '.delete-bkp' ).on('click', function(e) { @@ -365,6 +385,12 @@ $(function() if (location.search) selectedID = location.search.split('=')[1]; + // scroll down logs box by default + var logs_box_l = $('#logs-details-box'); + var logs_box = logs_box_l[0]; + logs_box.scrollTop = logs_box.scrollHeight; + //$('#logs-details-box').scrollTop = $('#logs-details-box').scrollHeight; + // Event source to receive process output in real time if (!!window.EventSource) var source = new EventSource('ncp-output.php'); @@ -687,6 +713,24 @@ $(function() history.pushState(null, selectedID, "?app=backups"); } ); + // logs button + $( '#logs-btn' ).on('click', function(e) + { + if ( lock ) return; + close_menu(); + switch_to_section( 'logs' ); + history.pushState(null, selectedID, "?app=logs"); + } ); + + // log download button + $( '#log-download-btn' ).on('click', function(e) + { + var token_dl = $('#csrf-token-dl').get('.value'); + var token = $('#csrf-token').get('.value'); + window.location.replace('download_logs.php?token=' + encodeURIComponent(token_dl)); + refresh_dl_token(); + } ); + // language selection var langold = $( '#language-selection' ).get( '.value' ); $( '#language-selection' ).on( 'change', function(e) diff --git a/ncp-web/ncp-launcher.php b/ncp-web/ncp-launcher.php index d6c52b37..eb2281ae 100644 --- a/ncp-web/ncp-launcher.php +++ b/ncp-web/ncp-launcher.php @@ -177,6 +177,16 @@ else if ( $_POST['action'] == "cfg-ui" ) } // +// dl-token +// +else if ( $_POST['action'] == "next-dl" ) +{ + echo '{ "token": "' . getCSRFToken() . '",'; // Get new token + echo '"token_dl": "' . getCSRFToken() . '",'; // Get new download token + echo ' "ret": "' . $ret . '" }'; +} + +// // path field // else if ( $_POST['action'] == "path-exists" ) diff --git a/updates/1.41.0.sh b/updates/1.42.0.sh index 8fd474de..8fd474de 100644 --- a/updates/1.41.0.sh +++ b/updates/1.42.0.sh |