diff options
author | nachoparker <nacho@ownyourbits.com> | 2018-03-29 13:57:39 +0300 |
---|---|---|
committer | nachoparker <nacho@ownyourbits.com> | 2018-04-01 19:08:10 +0300 |
commit | 925c6fe7e5ef094f61fb701a9aeb3d9618ac55b8 (patch) | |
tree | 239de40dba9a97aecf05fc24a14785afba75d622 /ncp-web | |
parent | f31caf4d0411423230c58cbfed04072bea0a2d2e (diff) |
ncp-web: use random passwords for NC and ncp-webv0.53.7
Diffstat (limited to 'ncp-web')
-rw-r--r-- | ncp-web/activate/CSS.css | 233 | ||||
-rw-r--r-- | ncp-web/activate/JS.js | 113 | ||||
-rw-r--r-- | ncp-web/activate/index.php | 64 | ||||
-rw-r--r-- | ncp-web/img/background.png | bin | 0 -> 125193 bytes | |||
-rw-r--r-- | ncp-web/img/clippy.svg | 55 | ||||
-rw-r--r-- | ncp-web/img/loading-small.gif (renamed from ncp-web/loading-small.gif) | bin | 1772 -> 1772 bytes | |||
-rw-r--r-- | ncp-web/index.php | 9 | ||||
-rw-r--r-- | ncp-web/ncp-launcher.php | 2 | ||||
-rw-r--r-- | ncp-web/ncp.js | 3 |
9 files changed, 475 insertions, 4 deletions
diff --git a/ncp-web/activate/CSS.css b/ncp-web/activate/CSS.css new file mode 100644 index 00000000..572eb603 --- /dev/null +++ b/ncp-web/activate/CSS.css @@ -0,0 +1,233 @@ +/* + * NextcloudPlus Web Panel style sheets. Based on official Nextcloud 12 datasheets + * + * Copyleft 2018 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://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/ +*/ + + +html,body { + height:100% +} +article,aside,dialog,figure,footer,header,hgroup,nav,section { + display:block +} +body { + text-align: center; + line-height:1.5 +} +a { + border:0; + color:#fff; + text-decoration:none; + cursor:pointer +} +a * { + cursor:pointer +} +select,.button span,label { + cursor:pointer +} +body { + background-image: url(../img/background.png); + background-color:#0082c9; + font-weight:400; + line-height:1.6em; + font-family:'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif; + color:#fff; + height:auto +} +#nojavascript { + position:fixed; + top:0; + bottom:0; + height:100%; + width:100%; + z-index:9000; + text-align:center; + background-color:rgba(0, 0, 0, 0.5); + color:#fff; + line-height:125%; + font-size:24px +} +#nojavascript div { + display:block; + position:relative; + width:50%; + top:35%; + margin:0px auto +} +#nojavascript a { + color:#fff; + border-bottom:2px dotted #fff +} +#nojavascript a:hover,#nojavascript a:focus { + color:#dbdbdb +} +::-webkit-scrollbar { + width:5px +} +::-webkit-scrollbar-track-piece { + background-color:transparent +} +::-webkit-scrollbar-thumb { + background:#dbdbdb; + border-radius:3px +} +select,button,input,textarea { + width: 3em; + min-height:32px; + box-sizing:border-box; + text-align: center; +} +select,button,.button,input:not([type='range']),textarea,#quota,.pager li a { + margin:3px 3px 3px 0; + padding:7px 6px; + font-size:13px; + background-color:#fff; + color:#545454; + border:1px solid #dbdbdb; + outline:none; + border-radius:3px; +} +select:not(:disabled):not(.primary),button:not(:disabled):not(.primary),.button:not(:disabled):not(.primary),input:not([type='range']):not(:disabled):not(.primary),textarea:not(:disabled):not(.primary),#quota:not(:disabled):not(.primary),.pager li a:not(:disabled):not(.primary) { +} +select:not(:disabled):not(.primary):not(#quota):hover,button:not(:disabled):not(.primary):not(#quota):hover,.button:not(:disabled):not(.primary):not(#quota):hover,input:not([type='range']):not(:disabled):not(.primary):not(#quota):hover,textarea:not(:disabled):not(.primary):not(#quota):hover,#quota:not(:disabled):not(.primary):not(#quota):hover,.pager li a:not(:disabled):not(.primary):not(#quota):hover,select:not(:disabled):not(.primary):focus,button:not(:disabled):not(.primary):focus,.button:not(:disabled):not(.primary):focus,input:not([type='range']):not(:disabled):not(.primary):focus,textarea:not(:disabled):not(.primary):focus,#quota:not(:disabled):not(.primary):focus,.pager li a:not(:disabled):not(.primary):focus,select:not(:disabled):not(.primary).active,button:not(:disabled):not(.primary).active,.button:not(:disabled):not(.primary).active,input:not([type='range']):not(:disabled):not(.primary).active,textarea:not(:disabled):not(.primary).active,#quota:not(:disabled):not(.primary).active,.pager li a:not(:disabled):not(.primary).active { + border-color:#0082c9; + outline:none +} +select:not(:disabled):not(.primary):active,button:not(:disabled):not(.primary):active,.button:not(:disabled):not(.primary):active,input:not([type='range']):not(:disabled):not(.primary):active,textarea:not(:disabled):not(.primary):active,#quota:not(:disabled):not(.primary):active,.pager li a:not(:disabled):not(.primary):active { + outline:none; + background-color:#fff +} +select:disabled,button:disabled,.button:disabled,input:not([type='range']):disabled,textarea:disabled,#quota:disabled,.pager li a:disabled { + background-color:#ebebeb; + color:rgba(0, 0, 0, 0.4); + cursor:default; + opacity:0.5 +} +select.primary,button.primary,.button.primary,input:not([type='range']).primary,textarea.primary,#quota.primary,.pager li a.primary { + border:1px solid #0082c9; + background-color:rgba(0, 130, 201, .7); + color:#fff; + cursor:pointer +} +select.primary:not(:disabled):hover,button.primary:not(:disabled):hover,.button.primary:not(:disabled):hover,input:not([type='range']).primary:not(:disabled):hover,textarea.primary:not(:disabled):hover,#quota.primary:not(:disabled):hover,.pager li a.primary:not(:disabled):hover,select.primary:not(:disabled):focus,button.primary:not(:disabled):focus,.button.primary:not(:disabled):focus,input:not([type='range']).primary:not(:disabled):focus,textarea.primary:not(:disabled):focus,#quota.primary:not(:disabled):focus,.pager li a.primary:not(:disabled):focus { + background-color:rgba(0, 130, 201, .85) +} +select.primary:not(:disabled):active,button.primary:not(:disabled):active,.button.primary:not(:disabled):active,input:not([type='range']).primary:not(:disabled):active,textarea.primary:not(:disabled):active,#quota.primary:not(:disabled):active,.pager li a.primary:not(:disabled):active { + background-color:rgba(0, 130, 201, .7) +} +select.primary:disabled,button.primary:disabled,.button.primary:disabled,input:not([type='range']).primary:disabled,textarea.primary:disabled,#quota.primary:disabled,.pager li a.primary:disabled { + background-color:rgba(0, 130, 201, .7); + color:#bababa +} +input { +} +input:not([type='radio']):not([type='checkbox']):not([type='range']):not([type='submit']):not([type='button']):not([type='reset']):not([type='color']):not([type='file']):not([type='image']) { + -webkit-appearance:textfield; + -moz-appearance:textfield +} +select,button,.button,input[type='button'],input[type='submit'],input[type='reset'] { + padding:6px 12px; + width:auto; + min-height:34px; + cursor:pointer; + box-sizing:border-box; + background-color:#f7f7f7 +} +button,.button,input[type='button'],input[type='submit'],input[type='reset'] { + font-weight:bold; +} +button::-moz-focus-inner,.button::-moz-focus-inner,input[type='button']::-moz-focus-inner,input[type='submit']::-moz-focus-inner,input[type='reset']::-moz-focus-inner { + border:0 +} +button,.button { +} +button > span[class^='icon-'],.button > span[class^='icon-'],button > span[class*=' icon-'],.button > span[class*=' icon-'] { + display:inline-block; + vertical-align:text-bottom; + opacity:0.5 +} +textarea { + color:#545454; + cursor:text; + font-family:inherit; + height:auto +} +textarea:not(:disabled):active,textarea:not(:disabled):hover,textarea:not(:disabled):focus { + border-color:#dbdbdb !important; + background-color:#fff !important +} +select { + -webkit-appearance:none; + -moz-appearance:none; + appearance:none; + background:url('../../../core/css/../img/actions/triangle-s.svg') no-repeat right 4px center; + background-color:inherit; + outline:0; + padding-right:24px !important +} +button img,.button img { + cursor:pointer +} +input[type='checkbox'].radio,input[type='radio'].radio,input[type='checkbox'].checkbox,input[type='radio'].checkbox { + position:absolute; + left:-10000px; + top:auto; + width:1px; + height:1px; + overflow:hidden +} +#header { + color: white; +} +h2 { + font-size:20px; + font-weight:300; + margin-bottom:12px; + line-height:140% +} +h3 { + font-size:15px; + font-weight:300; + margin:12px 0 +} +em { + font-style:normal; + -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=50)'; + opacity:0.5 +} +dl { + padding:12px 0 +} +dt,dd { + display:inline-block; + padding:12px; + padding-left:0 +} +dt { + width:130px; + white-space:nowrap; + text-align:right +} +kbd { + padding:4px 10px; + border:1px solid #ccc; + box-shadow:0 1px 0 rgba(0, 0, 0, .2); + border-radius:3px; + display:inline-block; + white-space:nowrap +} + +hr { border: solid 1px white; } + +#ncp-logo { margin-top: 24px; } + +#loading-gif { display: none; } + +#ncp-pwd,#nc-pwd{ width:30em; } + +img { vertical-align: middle; } diff --git a/ncp-web/activate/JS.js b/ncp-web/activate/JS.js new file mode 100644 index 00000000..e9152707 --- /dev/null +++ b/ncp-web/activate/JS.js @@ -0,0 +1,113 @@ +/// +// NextcloudPi Web Panel javascript library +// +// Copyleft 2017 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://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/ +/// + +var MINI = require('minified'); +var $ = MINI.$, $$ = MINI.$$, EE = MINI.EE; +var selectedID = null; +var confLock = false; + +function errorMsg() +{ + $('#error-box').fill( "Something went wrong. Try refreshing the page" ); +} + +$(function() +{ + // print info page + $( '#print-pwd' ).on( 'click', function(e) { window.print(); } ); + + // copy to clipboard + $( '#cp-ncp' ).on( 'click', function(e) + { + var input = document.getElementById('ncp-pwd'); + input.focus(); + input.select(); + var res =document.execCommand( 'copy' ); + $('#cp-ncp-ok').fill( res ? "✓" : "✘" ); + input.selectionStart = input.selectionEnd; + } ); + + // copy to clipboard + $( '#cp-nc' ).on( 'click', function(e) + { + var input = document.getElementById('nc-pwd'); + input.focus(); + input.select(); + var res =document.execCommand( 'copy' ); + $('#cp-nc-ok').fill( res ? "✓" : "✘" ); + input.selectionStart = input.selectionEnd; + } ); + + // activate NextCloudPi + $( '#activate-ncp' ).on( 'click', function(e) + { + $( '#activate-ncp' ).hide(); + $( '#print-pwd' ).hide(); + $('#loading-gif').set( { $display: 'inline' } ); + + // request + $.request('post', '../ncp-launcher.php', { action: 'launch', + ref : 'nc-admin', + config: '{ "PASSWORD":"' + $('#nc-pwd').get('.value') + '",' + + '"CONFIRM" :"' + $('#nc-pwd').get('.value') + '",' + + '"USER" : "ncp" }', + csrf_token: $( '#csrf-token' ).get( '.value' ) }).then( + function success( result ) + { + var ret = $.parseJSON( result ); + if ( ret.ret == '0' ) { + if ( ret.token ) + $('#csrf-token').set( { value: ret.token } ); + + // request + $.request('post', '../ncp-launcher.php', { action: 'launch', + ref : 'nc-passwd', + config: '{ "PASSWORD":"' + $('#ncp-pwd').get('.value') + '",' + + '"CONFIRM" :"' + $('#ncp-pwd').get('.value') + '"}', + csrf_token: $( '#csrf-token' ).get( '.value' ) }).then( + + function success( result ) + { + var ret = $.parseJSON( result ); + if ( ret.ret == '0' ) + { + setTimeout( function(){ + $('#loading-gif').hide(); + $('#error-box').fill( "ACTIVATION SUCCESSFUL" ); + var url = window.location.protocol + '//' + window.location.hostname + ':4443'; + if ( !window.open( url, '_blank' ) ) // try to open in a new tab first + window.location.replace( url ); + }, 2000 ); + } else { + $('#error-box').fill( "nc-passwd error" ); + } + } ).error( errorMsg ); + } else { + $('#error-box').fill( "nc-admin error" ); + } + } ).error( errorMsg ); + } ); +} ); + +// License +// +// This script is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This script is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this script; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place, Suite 330, +// Boston, MA 02111-1307 USA diff --git a/ncp-web/activate/index.php b/ncp-web/activate/index.php new file mode 100644 index 00000000..0b08f61e --- /dev/null +++ b/ncp-web/activate/index.php @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<html class="ng-csp" data-placeholder-focus="false" lang="en"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <meta charset="utf-8"> + <title> NextCloudPlus Activation </title> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="referrer" content="never"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"> + <link rel="icon" type="image/png" href="img/favicon.png"/> + <link rel="stylesheet" href="CSS.css"> +<?php session_start(); ?> +</head> +<body id="body-login"> + <noscript> + <div id="nojavascript"> + <div> + This application requires JavaScript for correct operation. Please <a href="https://www.enable-javascript.com/" target="_blank" rel="noreferrer noopener">enable JavaScript</a> and reload the page. </div> + </div> + </noscript> + <div class="wrapper"> + <div class="v-align"> + <header role="banner"> + <div id="header"> + <img id="ncp-logo" src="../img/ncp-logo.svg"> +<?php + $nc_pwd = rtrim( base64_encode( random_bytes(32) ) , '=' ); // remove last '='. Remove rtrim in the future + $ncp_pwd = rtrim( base64_encode( random_bytes(32) ) , '=' ); // remove last '='. Remove rtrim in the future + echo <<<HTML + <h1>NextCloudPlus Activation</h1> + <p>Your NextCloudPlus user is </p><input readonly type="text" size=32 value="ncp"> + <p>Your NextCloudPlus password is </p><input readonly id="ncp-pwd" type="text" size=32 value="{$ncp_pwd}"> <img id="cp-ncp" src="../img/clippy.svg"><span id="cp-ncp-ok"></span> + <p>Save this password in order to access to the NextCloudPlus web interface at https://nextcloudplus.local:4443</p> + <p>This password can be changed using 'nc-passwd'</p> +<hr> + <p>Your NextCloud user is </p><input readonly type="text" size=32 value="ncp"> + <p>Your Nextcloud password is </p><input readonly id="nc-pwd" type="text" size=32 value="{$nc_pwd}"> <img id="cp-nc" src="../img/clippy.svg"><span id="cp-nc-ok"></span> + <p>Save this password in order to access NextCloud https://nextcloudplus.local</p> + <p>This password can be changed from the Nextcloud user configuration</p> +<br> + <p> + <button type="button" id="print-pwd" > Print </button> + <button type="button" id="activate-ncp"> Activate </button> + </p> + <img id="loading-gif" src="../img/loading-small.gif"> + <div id="error-box"></div> +HTML; +?> + </div> + </header> + </div> + </div> + <footer role="contentinfo"> + <p class="info"> + <a href="https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/" target="_blank" rel="noreferrer noopener">NextCloudPlus</a> – Keep your data close</p> + </footer> + <?php + include('../csrf.php'); + echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>'; + ?> + <script src="../minified.js"></script> + <script src="JS.js"></script> +</body> +</html> diff --git a/ncp-web/img/background.png b/ncp-web/img/background.png Binary files differnew file mode 100644 index 00000000..9e7be378 --- /dev/null +++ b/ncp-web/img/background.png diff --git a/ncp-web/img/clippy.svg b/ncp-web/img/clippy.svg new file mode 100644 index 00000000..f3917155 --- /dev/null +++ b/ncp-web/img/clippy.svg @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="25.000994" + width="23.436043" + version="1.1" + viewBox="0 0 23.436043 25.000994" + id="svg4" + sodipodi:docname="clippy.svg" + inkscape:version="0.92.2 2405546, 2018-03-11"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1079" + id="namedview6" + showgrid="false" + inkscape:zoom="5.2149125" + inkscape:cx="-56.850391" + inkscape:cy="25.220872" + inkscape:window-x="1920" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg4" /> + <path + d="M 18.748757,23.438029 H 1.5608961 L 1.5616403,7.8127013 H 18.749538 v 4.6879107 l 1.562533,-6.25e-4 8.19e-4,-7.8128197 c 9e-5,-0.911582 -0.650795,-1.562845 -1.563314,-1.562689 l -5.417302,7.44e-4 C 13.333574,1.2767457 11.849119,0 10.000173,0 8.1512276,0 6.6668216,1.2767457 6.6668216,3.1256903 H 1.6667167 c -0.911581,0 -1.66597249857,0.650952 -1.66597249857,1.562377 L 0,23.43846 c -3.7898574e-5,0.912519 0.7551721,1.562533 1.6667531,1.562533 l 17.0831719,-7.44e-4 c 0.912519,-0.0016 1.562532,-0.650013 1.562532,-1.562533 V 18.750118 H 18.749851 Z M 4.9976876,4.6876363 h 1.667534 c 0.911426,0 1.666598,-0.650327 1.666598,-1.561909 0,-0.911424 0.755328,-1.458936 1.666754,-1.458936 0.9114254,0 1.6667544,0.547512 1.6667544,1.458936 0,0.911582 0.833298,1.561909 1.666597,1.561909 h 1.97926 c 0.807829,0 1.875039,0.65095 1.875039,1.562532 H 3.1234296 c -6.25e-4,-1.015646 0.935644,-1.562532 1.873164,-1.562532 z M 3.1234296,17.187897 h 3.125065 V 15.625365 H 3.1234296 Z M 15.623379,14.062832 v -3.125065 l -6.2501314,4.687598 6.2498184,4.687598 v -3.125066 l 7.812977,-7.8e-5 v -3.125065 l -7.812351,-7.8e-5 z M 3.1231166,20.312963 h 6.250131 V 18.75043 H 3.1231166 Z M 12.498314,9.3752343 H 3.1231166 V 10.937767 H 12.498314 Z M 7.8107146,12.5003 h -4.687598 v 1.562532 h 4.687598 z" + id="path2" + style="opacity:1;fill:#ffffff;stroke-width:1.56253278" + inkscape:connector-curvature="0" /> +</svg> diff --git a/ncp-web/loading-small.gif b/ncp-web/img/loading-small.gif Binary files differindex 2d04fd0d..2d04fd0d 100644 --- a/ncp-web/loading-small.gif +++ b/ncp-web/img/loading-small.gif diff --git a/ncp-web/index.php b/ncp-web/index.php index 70a6e26d..ff66862f 100644 --- a/ncp-web/index.php +++ b/ncp-web/index.php @@ -17,6 +17,11 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"> <meta name="mobile-web-app-capable" content="yes"> <?php + exec("a2query -s ncp-activation", $output, $ret); + if ($ret == 0) { + header("Location: activate"); + exit(); + } session_start(); $modules_path = '/usr/local/etc/nextcloudpi-config.d/'; $l10nDir = "l10n"; @@ -34,7 +39,7 @@ ini_set('session.cookie_secure', 1); // HTTP2 push headers - header("Link: </minified.js>; rel=preload; as=script;,</ncp.js>; rel=preload; as=script;,</ncp.css>; rel=preload; as=style;,</img/ncp-logo.svg>; rel=preload; as=image;, </loading-small.gif>; rel=preload; as=image;, rel=preconnect href=ncp-launcher.php;"); + header("Link: </minified.js>; rel=preload; as=script;,</ncp.js>; rel=preload; as=script;,</ncp.css>; rel=preload; as=style;,</img/ncp-logo.svg>; rel=preload; as=image;, </img/loading-small.gif>; rel=preload; as=image;, rel=preconnect href=ncp-launcher.php;"); ?> <link rel="icon" type="image/png" href="img/favicon.png"/> @@ -175,7 +180,7 @@ HTML; <div id="config-box"></div> <div id="config-button-wrapper"> <button id="config-button"><?php echo $l->__("Run"); ?></button> - <img id="loading-gif" src="loading-small.gif"> + <img id="loading-gif" src="img/loading-small.gif"> <div id="circle-retstatus" class="icon-red-circle"></div> </div> </form> diff --git a/ncp-web/ncp-launcher.php b/ncp-web/ncp-launcher.php index aba9b985..004432d0 100644 --- a/ncp-web/ncp-launcher.php +++ b/ncp-web/ncp-launcher.php @@ -118,7 +118,7 @@ else if ( $_POST['action'] == "launch" && $_POST['config'] ) { $value = "[". join(",", $value) ."]"; } - preg_match( '/^[\[\]\w-.,@_\/:]+$/' , $value , $matches ) + preg_match( '/^[\[\]\w+-.,@_\/:]+$/' , $value , $matches ) or exit( '{ "output": "Invalid input" , "token": "' . getCSRFToken() . '" }' ); $code = preg_replace( '/\n' . $name . '_=.*' . PHP_EOL . '/' , PHP_EOL . $name . '_=' . $value . PHP_EOL , diff --git a/ncp-web/ncp.js b/ncp-web/ncp.js index 5d60537c..cd28779d 100644 --- a/ncp-web/ncp.js +++ b/ncp-web/ncp.js @@ -127,7 +127,7 @@ $(function() // request $.request('post', 'ncp-launcher.php', { action:'launch', ref:selectedID , - config: $.toJSON(cfg) , + config: $.toJSON(cfg), csrf_token: $( '#csrf-token' ).get( '.value' ) }).then( function success( result ) { @@ -254,6 +254,7 @@ $(function() { $('#poweroff-dialog').hide(); $('#overlay').hide(); + // request $.request('post', 'ncp-launcher.php', { action:'poweroff', csrf_token: $( '#csrf-token' ).get( '.value' ) }).then( |