ncp-web: add localization (#372)

* Implement localization loader L10N.

Localize a few strings in index.php for testing.

* Determine language from HTTP_ACCEPT_LANGUAGE header.

* Fix parsing of available languages for localization.

* Fix parsing of language translations (for localization).

* Fix function L10N->find_language

* Change variable naming to comply with conventions.

* Add remaining localize calls in index.php.

Add more localization strings.

* Fix styles to prevent check mark from being hidden.

* Handle exception in case localization couldn't be loaded.

* Add module localization support.

* Fix detection of core module in L10N->load

* Remove module specific localization from core l10n file.

* Fix determination of module name in L10N->load.

* Add localization files for more modules.

* Ignore l10n directory in modules path.

* Add support for dropdown lists in module settings.

* Add support for saving dropdown menus.

* Fix regex for recognizing dropdown option lists.

* Fix dropdown list regex not recognizing active option.

* Fix typo in ncp-launcher.php

* Workaround for jquery's 'find' method not working. //TODO: Find proper fix.

* Fix parsing of dropdown lists when updating config.

* Load language setting from config if available.

* add ncp-provisioning to SD card images

* Add intellij config to gitignore

* Fix bug when loading language from nc-webui config.

* Remove redundant language definition.
Replace umlauts by html special char expressions.

* Change selected option markup from `*<option>*` to `_<option>_`.

* Remove ide metadata.

* Add translations for ncp-app nc-backup.

* Add translation hooks to ncp-launcher.php

* Fix type in translations for nc-backup

* Remove translation hooks for field contents in ncp-launcher.php
This commit is contained in:
theCalcaholic 2018-02-26 20:21:59 +01:00 committed by nachoparker
parent c4a111c289
commit 1a7c8b9b5e
44 changed files with 384 additions and 88 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.*.swp
*.img
*.bz2
.idea/
qemu-raspbian-network/
torrent/
armbian/

View File

@ -1,5 +1,7 @@
[v0.46.34](https://github.com/nextcloud/nextcloudpi/commit/2694914) (2018-02-26) ncp-web: fix responsive in iPad
[v0.46.35](https://github.com/nextcloud/nextcloudpi/commit/e417926) (2018-02-26) ncp-web: add localization (#372)
[v0.46.34](https://github.com/nextcloud/nextcloudpi/commit/3fc902b) (2018-02-26) ncp-web: fix responsive in iPad
[v0.46.33](https://github.com/nextcloud/nextcloudpi/commit/dea4836) (2018-02-23) Added some useful comments for first time users

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-audit": "Sicherheitsüberprüfung"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-automount": "Automatische Datenträgereinbindung"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-autoupdate-ncp": "Automatische NextCloudPi Updates"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-backup-auto": "Automatische Backups"
}}

View File

@ -0,0 +1,7 @@
{"translations": {
"nc-backup": "Backup erstellen",
"DESTDIR": "Zielverzeichnis",
"INCLUDEDATA": "Inkl. Dateien",
"COMPRESS": "Komprimieren",
"BACKUPLIMIT": "Maximale Anzahl"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-database": "Datenbank"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-datadir": "Datenverzeichnis"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-export-ncp": "NCP Export"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-fix-permissions": "Berechtigungen wiederherstellen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-format-USB": "USB Laufwerke formatieren"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-forward-ports": "Portweiterleitungen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-httpsonly": "HTTPS Zwang"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-import-ncp": "NCP Import"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-info": "System Informationen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-init": "Initialisierung"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-limits": "Systembegrenzungen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-nextcloud": "Nextcloud Einstellungen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-notify-updates": "Update-Benachrichtigungen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-passwd": "NCP Passwort"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-ramlogs": "Ram Logs"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-restore": "Wiederherstellung"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-scan-auto": "Automatischer Datei-Scan"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-scan": "Datei-Scan"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-snapshot-auto": "Automatische Snapshots"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-snapshot": "Snapshot erstellen"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-static-IP": "Statische IP Adresse"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-swapfile": "Swap Datei"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-update": "Update"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-webui": "NCP Weboberfläche"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"nc-wifi": "WLAN"
}}

View File

@ -0,0 +1,3 @@
{"translations": {
"unattended-upgrades": "Unüberwachte System-Upgrades"
}}

View File

@ -14,6 +14,7 @@
#
ACTIVE_=yes
LANGUAGE_=[_auto_,en,de]
DESCRIPTION="Enable or disable the NCP web interface"
configure()

127
ncp-web/L10N.php Normal file
View File

@ -0,0 +1,127 @@
<?php
class L10N {
private $translations = [];
const default_language = "en_US";
private $language;
public function __construct($desired_languages, $l10n_dir, $modules_path=null)
{
if (!isset($desired_languages)) {
$desired_languages = "";
}
$l10n_dir = rtrim($l10n_dir, '/');
$available_languages = array_filter(scandir($l10n_dir),
function ($s) {
return pathinfo($s, PATHINFO_EXTENSION) == "json";
});
$available_languages = array_map(
function ($s) {
return basename($s, ".json");
},
$available_languages);
$desired_lang = $this->load_language_setting($modules_path);
if($desired_lang != "auto")
{
$desired_languages = $desired_lang;
}
$lang = $this->find_language($available_languages, $desired_languages);
$this->language = $lang;
if ($lang === L10N::default_language || !file_exists(join('/', [$l10n_dir, $lang . ".json"])) || !$this->load($lang, $l10n_dir, $modules_path)) {
$this->language = L10N::default_language;
}
}
function load($lang, $l10n_dir, $modules_path)
{
$modules_path = join('/', [rtrim($modules_path, '/'), $l10n_dir]);
$files = [join('/', [$l10n_dir, $lang . ".json"])];
if (is_dir($modules_path)) {
foreach (scandir($modules_path) as $dir) {
$file_path = join('/', [$modules_path, trim($dir, '/'), $lang . ".json"]);
if (is_file($file_path)) {
array_push($files, $file_path);
}
}
}
$jsonError = null;
foreach ($files as $file) {
$module_name = pathinfo(pathinfo($file, PATHINFO_DIRNAME), PATHINFO_BASENAME);
if( $module_name == pathinfo($l10n_dir, PATHINFO_BASENAME)) {
$module_name = "__core__";
}
$json = json_decode(file_get_contents($file), true);
if (!is_array($json)) {
$jsonError = json_last_error();
continue;
}
$this->translations[$module_name] = $json['translations'];
}
return ($jsonError == null);
}
public function __($text, $module="__core__") {
if( isset($this->translations[$module]) && isset($this->translations[$module][$text])) {
return $this->translations[$module][$text];
}
return $text;
}
function find_language(array $available_languages, $desired_language) {
$available_languages = array_flip($available_languages);
$langs = [];
preg_match_all('~([\w-]+)(?:[^,\d]+([\d.]+))?~', strtolower($desired_language), $matches, PREG_SET_ORDER);
foreach($matches as $match) {
list($a, $b) = explode('-', $match[1]) + array('', '');
$value = isset($match[2]) ? (float) $match[2] : 1.0;
if(isset($available_languages[$match[1]])) {
$langs[$match[1]] = $value;
continue;
}
if(isset($available_languages[$a])) {
$langs[$a] = $value - 0.1;
}
}
arsort($langs);
if(count($langs) == 0) {
return L10N::default_language;
}
return array_keys($langs)[0];
}
function load_language_setting($modules_path) {
$webui_config_file = join('/', [rtrim($modules_path, '/'), 'nc-webui.sh']);
$fh = fopen( $webui_config_file ,'r')
or exit( '{ "output": "' . $webui_config_file . ' read error" }' );
$lang = "auto";
while ( $line = fgets($fh) )
{
// drop down menu
if(preg_match('/^LANGUAGE_=\[(([_\w]+,)*[_\w]+)\]$/', $line, $matches))
{
$options = explode(',', $matches[1]);
foreach($options as $option)
{
if($option[0] == "_" && $option[count($option) - 1] == "_")
{
fclose($fh);
$lang = trim($option,'_');
}
}
fclose($fh);
return $lang;
}
}
}
}

View File

@ -8,57 +8,71 @@
-->
<!DOCTYPE html>
<html class="ng-csp" data-placeholder-focus="false" lang="en" >
<html class="ng-csp" data-placeholder-focus="false" lang="en">
<head>
<meta charset="utf-8">
<title>NextCloudPi Panel</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="referrer" content="never">
<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
<meta charset="utf-8">
<title>NextCloudPi Panel</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="referrer" content="never">
<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
session_start();
$modules_path = '/usr/local/etc/nextcloudpi-config.d/';
$l10nDir = "l10n";
// security headers
header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("X-Robots-Tag: none");
header("X-Permitted-Cross-Domain-Policies: none");
header("X-Frame-Options: DENY");
header("Cache-Control: max-age=15778463");
ini_set('session.cookie_httponly', 1);
if ( isset($_SERVER['HTTPS']) )
ini_set('session.cookie_secure', 1);
// security headers
header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("X-Robots-Tag: none");
header("X-Permitted-Cross-Domain-Policies: none");
header("X-Frame-Options: DENY");
header("Cache-Control: max-age=15778463");
ini_set('session.cookie_httponly', 1);
if (isset($_SERVER['HTTPS']))
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;");
?>
<link rel="icon" type="image/png" href="img/favicon.png" />
<link rel="stylesheet" href="ncp.css">
// 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;");
?>
<link rel="icon" type="image/png" href="img/favicon.png"/>
<link rel="stylesheet" href="ncp.css">
</head>
<body id="body-user">
<noscript>
<div id="nojavascript"> <div>This application requires JavaScript for correct operation. Please <a href="http://enable-javascript.com/" target="_blank" rel="noreferrer">enable JavaScript</a> and reload the page. </div> </div>
</noscript>
<div id="notification-container">
<?php
exec( "ncp-test-updates" , $output, $ret );
if ( $ret == 0 )
{
echo '<div id="notification">';
echo '<div id="update-notification" class="row type-error closeable">';
echo "version " . file_get_contents( "/var/run/.ncp-latest-version" ) . " is available";
echo '<a class="action close icon-close" href="#" alt="Dismiss"></a>';
echo '</div>';
echo '</div>';
}
?>
</div>
<?php
require("L10N.php");
try {
$l = new L10N($_SERVER["HTTP_ACCEPT_LANGUAGE"], $l10nDir, $modules_path);
} catch (Exception $e) {
die("<p class='error'>Error while loading localizations!</p>");
}
?>
<noscript>
<div id="nojavascript">
<div>
<?php sprintf($l->__("This application requires JavaScript for correct operation. Please %s enable JavaScript %s and reload the page."),
"<a href=\"http://enable-javascript.com/\" target=\"_blank\" rel=\"noreferrer\">", "</a>"); ?>
</div>
</div>
</noscript>
<div id="notification-container">
<?php
exec("ncp-test-updates", $output, $ret);
if ($ret == 0) {
echo '<div id="notification">';
echo '<div id="update-notification" class="row type-error closeable">';
sprintf($l->__("version %s is available"), file_get_contents("/var/run/.ncp-latest-version"));
echo '<a class="action close icon-close" href="#" alt="Dismiss"></a>';
echo '</div>';
echo '</div>';
}
?>
</div>
<?php
if ( file_exists( 'wizard') && !file_exists( 'wizard.cfg' ) )
{
if (file_exists('wizard') && !file_exists('wizard.cfg')) {
echo <<<HTML
<div id="first-run-wizard">
<div class='dialog'>
@ -68,14 +82,14 @@
<br>
<a href="wizard"><img class="wizard-btn" src="wizard/img/ncp-logo.svg" class="wizard"></a>
<br>
<button type="button" class="wizard-btn" id="go-wizard" >run </button>
<button type="button" class="first-run-close" id="skip-wizard" >skip </button>
<button type="button" class="first-run-close" id="close-wizard">close</button>
<button type="button" class="wizard-btn" id="go-wizard" >{$l->__("run")} </button>
<button type="button" class="first-run-close" id="skip-wizard" >{$l->__("skip")} </button>
<button type="button" class="first-run-close" id="close-wizard">{$l->__("close")}</button>
<br><br>
</div>
</div>
HTML;
touch( 'wizard.cfg' );
touch('wizard.cfg');
}
?>
@ -103,14 +117,14 @@ HTML;
</div>
</a>
HTML;
?>
<div id="poweroff">
<div id="expand">
<div class="icon-power-white"></div>
?>
<div id="poweroff">
<div id="expand">
<div class="icon-power-white"></div>
</div>
</div>
</div>
</div>
</div>
</header>
</header>
<div id="content-wrapper">
<div id="content" class="app-files" role="main">
@ -119,40 +133,38 @@ HTML;
<ul id="ncp-options">
<?php
// fill options with contents from directory
$path = '/usr/local/etc/nextcloudpi-config.d/';
$files = array_diff(scandir($path), array('.', '..','nc-wifi.sh'));
// fill options with contents from directory
$files = array_diff(scandir($modules_path), array('.', '..', 'nc-wifi.sh', 'l10n'));
foreach($files as $file)
{
$script = pathinfo( $file , PATHINFO_FILENAME );
$txt = file_get_contents( $path . $file );
foreach ($files as $file) {
$script = pathinfo($file, PATHINFO_FILENAME);
$txt = file_get_contents($modules_path . $file);
$active = "";
if ( preg_match('/^ACTIVE_=yes$/m', $txt, $matches) )
$active = "";
$active = "";
if (preg_match('/^ACTIVE_=yes$/m', $txt, $matches))
$active = "";
echo "<li id=\"$script\" class=\"nav-recent\">";
echo "<a href=\"#\"> $script$active </a>";
echo "<li id=\"$script\" class=\"nav-recent\">";
echo "<a href=\"#\"> {$l->__($script, $script)}$active </a>";
if ( preg_match('/^DESCRIPTION="(.*)"$/m', $txt, $matches) )
echo "<input id=\"$script-desc\" type=\"hidden\" value=\"$matches[1]\" />";
if (preg_match('/^DESCRIPTION="(.*)"$/m', $txt, $matches))
echo "<input id=\"$script-desc\" type=\"hidden\" value=\"{$l->__($matches[1], $script)}\" />";
if ( preg_match('/^INFO="(.*)"/msU', $txt, $matches) )
echo "<input id=\"$script-info\" type=\"hidden\" value=\"$matches[1]\" />";
if (preg_match('/^INFO="(.*)"/msU', $txt, $matches))
echo "<input id=\"$script-info\" type=\"hidden\" value=\"{$l->__($matches[1], $script)}\" />";
if ( preg_match('/^INFOTITLE="(.*)"/msU', $txt, $matches) )
echo "<input id=\"$script-infotitle\" type=\"hidden\" value=\"$matches[1]\" />";
if (preg_match('/^INFOTITLE="(.*)"/msU', $txt, $matches))
echo "<input id=\"$script-infotitle\" type=\"hidden\" value=\"{$l->__($matches[1], $script)}\" />";
echo "</li>";
}
echo "</li>";
}
?>
</ul>
</div>
<div id="app-content">
<div id="app-navigation-toggle" class="icon-menu hidden"></div>
<h2 id="config-box-title">Configure NextCloudPi features</h2>
<h2 id="config-box-title"><?php echo $l->__("Configure NextCloudPi features"); ?></h2>
<a href="#" target="_blank">
<div id="config-extra-info" class="icon-info"></div>
</a>
@ -162,16 +174,15 @@ HTML;
<form>
<div id="config-box"></div>
<div id="config-button-wrapper">
<button id="config-button">Run</button>
<button id="config-button"><?php echo $l->__("Run"); ?></button>
<img id="loading-gif" src="loading-small.gif">
<div id="circle-retstatus" class="icon-red-circle"></div>
</div>
</form>
<textarea readonly id="details-box" rows="12"></textarea>
</div>
</div>
</div>
</div>
<div id="poweroff-dialog" class='dialog primary hidden'>
<div id='poweroff-option_shutdown' class='button big-button'>
@ -183,11 +194,11 @@ HTML;
</div>
<?php
include ('csrf.php');
include('csrf.php');
echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>';
?>
<script src="minified.js"></script>
<script src="ncp.js"></script>
<script src="minified.js"></script>
<script src="ncp.js"></script>
</body>
</html>

9
ncp-web/l10n/de.json Normal file
View File

@ -0,0 +1,9 @@
{"translations": {
"This application requires JavaScript for correct operation. Please %s enable JavaScript %s and reload the page.":
"Diese Anwendung ben&ouml;tigt Javascript um richtig zu funktionieren. Bitte %s aktivieren Sie JavaScript %s und laden die Seite dann neu.",
"version %s is available": "Eine neue Version ist verf&uuml;gbar: %s.",
"run": "Ausführen",
"skip": "&Uuml;berspringen",
"close": "Schlie&szlig;en",
"Configure NextCloudPi features": "NextCloudPi Funktionen konfigurieren"
}}

0
ncp-web/l10n/index.html Normal file
View File

1
ncp-web/l10n/index.php Normal file
View File

@ -0,0 +1 @@
<?php

View File

@ -11,8 +11,18 @@
include ('csrf.php');
session_start();
$modules_path = '/usr/local/etc/nextcloudpi-config.d/';
$l10nDir = "l10n";
ignore_user_abort( true );
require("L10N.php");
try {
$l = new L10N($_SERVER["HTTP_ACCEPT_LANGUAGE"], $l10nDir, $modules_path);
} catch (Exception $e) {
die(json_encode("<p class='error'>Error while loading localizations!</p>"));
}
if ( $_POST['action'] == "cfgreq" )
{
if ( !$_POST['ref'] ) exit( '{ "output": "Invalid request" }' );
@ -43,16 +53,33 @@ if ( $_POST['action'] == "cfgreq" )
if ( $matches[2] == "yes" )
$checked = "checked";
$output = $output . "<tr>";
$output = $output . "<td><label for=\"$matches[1]\">$matches[1]</label></td>";
$output = $output . "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output = $output . "<td><input type=\"checkbox\" id=\"$matches[1]\" name=\"$matches[1]\" value=\"$matches[2]\" $checked></td>";
$output = $output . "</tr>";
}
// drop down menu
else if(preg_match('/^(\w+)_=\[(([_\w]+,)*[_\w]+)\]$/', $line, $matches))
{
$options = explode(",", $matches[2]);
$output .= "<tr>";
$output .= "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output .= "<td><select id=\"$matches[1]\" name=\"$matches[1]\">";
foreach($options as $option)
{
$output .= "<option value='". trim($option, "_") ."' ";
if( $option[0] == "_" && $option[count($option) - 1] == "_" )
{
$output .="selected='selected'";
}
$output .= ">". $l->__(trim($option, "_"), $_POST['ref']) ."</option>";
}
$output .= "</select></td></tr>";
}
// text field
else if ( preg_match('/^(\w+)_=(.*)$/', $line, $matches) )
{
$output = $output . "<tr>";
$output = $output . "<td><label for=\"$matches[1]\">$matches[1]</label></td>";
$output = $output . "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output = $output . "<td><input type=\"text\" name=\"$matches[1]\" id=\"$matches[1]\" value=\"$matches[2]\" size=\"40\"></td>";
$output = $output . "</tr>";
}
@ -87,7 +114,11 @@ else if ( $_POST['action'] == "launch" && $_POST['config'] )
if ( !empty( $params ) )
foreach( $params as $name => $value )
{
preg_match( '/^[\w.,@_\/-]+$/' , $value , $matches )
if( is_array($value))
{
$value = "[". join(",", $value) ."]";
}
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 ,

View File

@ -628,7 +628,7 @@ kbd {
}
#app-navigation li > a {
display:block;
width:100%;
width:90%;
line-height:44px;
min-height:44px;
padding:0 12px;

View File

@ -96,12 +96,25 @@ $(function()
// create configuration object
var cfg = {};
$( 'input' , '#config-box' ).each( function(item){
$( 'input' , '#config-box' ).each( function(item){
if( item.getAttribute('type') == 'checkbox' )
item.value = item.checked ? 'yes' : 'no';
cfg[item.name] = item.value;
} );
$( 'select', '#config-box' ).each( function(item) {
var select = {
'id': item.name,
'value': []
};
$("#" + item.id + '>option').each(function(option) {
select.value.push(option.selected ? "_" + option.value + "_" : "" + option.value);
});
cfg[select.id] = select.value;
});
// reset box
$('#details-box').fill();
$('#details-box').show();

View File

@ -88,6 +88,7 @@ Listen 4443
</Directory>
EOF
$APTINSTALL libapache2-mod-authnz-external pwauth
a2enmod authnz_external authn_core auth_basic
a2ensite ncp

View File

@ -99,6 +99,8 @@ for file in etc/nextcloudpi-config.d/*; do
cp "$file" /usr/local/"$file"
done
cp -rT etc/nextcloudpi-config.d/l10n /usr/local/etc/nextcloudpi-config.d/l10n
# these files can contain sensitive information, such as passwords
chown -R root:www-data /usr/local/etc/nextcloudpi-config.d
chmod 660 /usr/local/etc/nextcloudpi-config.d/*