From ab6b21723bff74c62b1a7cf4b3034be0d7f1cb76 Mon Sep 17 00:00:00 2001 From: Michael Reid Date: Thu, 3 Oct 2024 05:29:43 -0400 Subject: [PATCH] Feng Office: Update to v3.11.2.8 (#5992) * Update makefiles and digests * Update service scripts * Add resource workers * Add PHP profiles for DSM 6 * Miscellaneous fixes * Simplify DSM6 privilage file * Implement backup function * Implement restore function * Bump to v3.11.2.8 --- cross/fengoffice/Makefile | 12 +- cross/fengoffice/digests | 6 +- spk/fengoffice/Makefile | 55 +-- spk/fengoffice/src/conf/PKG_DEPS | 2 - spk/fengoffice/src/conf/resource | 69 ++++ spk/fengoffice/src/conf_6/privilege | 7 + spk/fengoffice/src/conf_6/resource | 20 + spk/fengoffice/src/dsm-control.sh | 78 ---- spk/fengoffice/src/fengoffice.sh | 18 - spk/fengoffice/src/installer.sh | 144 ------- spk/fengoffice/src/service-setup.sh | 371 ++++++++++++++++++ spk/fengoffice/src/web/fengoffice.conf | 16 + spk/fengoffice/src/web/fengoffice.json | 32 ++ spk/fengoffice/src/wizard/install_uifile | 28 -- spk/fengoffice/src/wizard/install_uifile.sh | 246 ++++++++++++ spk/fengoffice/src/wizard/uninstall_uifile | 27 -- spk/fengoffice/src/wizard/uninstall_uifile.sh | 96 +++++ spk/fengoffice/src/wizard/upgrade_uifile | 19 + 18 files changed, 916 insertions(+), 330 deletions(-) delete mode 100644 spk/fengoffice/src/conf/PKG_DEPS create mode 100644 spk/fengoffice/src/conf/resource create mode 100644 spk/fengoffice/src/conf_6/privilege create mode 100644 spk/fengoffice/src/conf_6/resource delete mode 100644 spk/fengoffice/src/dsm-control.sh delete mode 100644 spk/fengoffice/src/fengoffice.sh delete mode 100755 spk/fengoffice/src/installer.sh create mode 100755 spk/fengoffice/src/service-setup.sh create mode 100644 spk/fengoffice/src/web/fengoffice.conf create mode 100644 spk/fengoffice/src/web/fengoffice.json delete mode 100644 spk/fengoffice/src/wizard/install_uifile create mode 100644 spk/fengoffice/src/wizard/install_uifile.sh delete mode 100644 spk/fengoffice/src/wizard/uninstall_uifile create mode 100644 spk/fengoffice/src/wizard/uninstall_uifile.sh create mode 100644 spk/fengoffice/src/wizard/upgrade_uifile diff --git a/cross/fengoffice/Makefile b/cross/fengoffice/Makefile index e16e151775c..46e3821636f 100644 --- a/cross/fengoffice/Makefile +++ b/cross/fengoffice/Makefile @@ -1,9 +1,8 @@ PKG_NAME = fengoffice -PKG_VERS = 2.5.1.2 -PKG_EXT = zip -PKG_DIST_NAME = $(PKG_NAME)_$(PKG_VERS).$(PKG_EXT) -PKG_DIST_SITE = https://sourceforge.net/projects/opengoo/files/$(PKG_NAME)/$(PKG_NAME)_$(PKG_VERS) -PKG_DIR = $(PKG_NAME)-$(PKG_VERS) +PKG_VERS = 3.11.2.8 +PKG_EXT = tar.gz +PKG_DIST_NAME = $(PKG_NAME)-$(PKG_VERS).$(PKG_EXT) +PKG_DIST_SITE = https://github.com/fengoffice/$(PKG_NAME)/archive/$(PKG_VERS) DEPENDS = @@ -11,7 +10,6 @@ HOMEPAGE = https://www.fengoffice.com COMMENT = Feng Office is a Collaboration Platform and Project Management System. LICENSE = AGPL -EXTRACT_PATH = $(WORK_DIR)/$(PKG_DIR) CONFIGURE_TARGET = nop COMPILE_TARGET = nop INSTALL_TARGET = fengoffice_install @@ -21,5 +19,5 @@ include ../../mk/spksrc.cross-cc.mk .PHONY: fengoffice_install fengoffice_install: mkdir -p $(STAGING_INSTALL_PREFIX)/share/fengoffice - tar -cf - -C $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) . | tar -xf - -C $(STAGING_INSTALL_PREFIX)/share/fengoffice + tar -cf - -C $(WORK_DIR)/$(PKG_NAME)-$(PKG_VERS) . | tar -xf - -C $(STAGING_INSTALL_PREFIX)/share/fengoffice install -m 644 src/install_helper.php $(STAGING_INSTALL_PREFIX)/share/fengoffice/public/install/install_helper.php diff --git a/cross/fengoffice/digests b/cross/fengoffice/digests index dcb6686b4ed..4e81cd978d0 100644 --- a/cross/fengoffice/digests +++ b/cross/fengoffice/digests @@ -1,3 +1,3 @@ -fengoffice_2.5.1.2.zip SHA1 86972fee42a48879d6da80e858407945a028d260 -fengoffice_2.5.1.2.zip SHA256 1c3dfc9ae529cd7a39105d6029fb49d5f1936d77e17aa9af8a97df8888508969 -fengoffice_2.5.1.2.zip MD5 5746ab690c818f36be9b4b7fb4206c2e +fengoffice-3.11.2.8.tar.gz SHA1 b700ff65ec7bac41f27fc50866cd81dffca79f36 +fengoffice-3.11.2.8.tar.gz SHA256 b146bba574349d0480407a101b4f4924f876425ff5955470c515efbc953b8b6c +fengoffice-3.11.2.8.tar.gz MD5 766ac490d2aeb1ca9a2868a35fcf1300 diff --git a/spk/fengoffice/Makefile b/spk/fengoffice/Makefile index 0cd7ce6a5ff..68a666575d0 100644 --- a/spk/fengoffice/Makefile +++ b/spk/fengoffice/Makefile @@ -1,41 +1,50 @@ SPK_NAME = fengoffice -SPK_VERS = 2.5.1.2 -SPK_REV = 3 +SPK_VERS = 3.11.2.8 +SPK_REV = 4 SPK_ICON = src/fengoffice.png -DSM_UI_DIR = app -DEPENDS = cross/busybox cross/$(SPK_NAME) +DEPENDS = cross/$(SPK_NAME) +# Pure PHP package, make sure ARCH is not defined +override ARCH= + +# Due to not obvious WebStation handling requirements +REQUIRED_MIN_DSM = 6.0 +SPK_DEPENDS = "WebStation:PHP7.4:MariaDB10:Apache2.4" -MAINTAINER = moneytoo +MAINTAINER = SynoCommunity DESCRIPTION = Feng Office is a Collaboration Platform and Project Management System. -ADMIN_URL = /fengoffice/ DISPLAY_NAME = Feng Office -CHANGELOG = "1. DSM 5.0 compatibility" +CHANGELOG = "1. Update to v3.11.2.8.
2. Add PHP profiles for DSM 6.
3. Add backup and restore functions." + +HOMEPAGE = https://www.fengoffice.com/ +LICENSE = AGPL + +STARTABLE = yes +SERVICE_USER = auto +SERVICE_SETUP = src/service-setup.sh -HOMEPAGE = https://www.fengoffice.com/ -LICENSE = AGPL +ADMIN_URL = /fengoffice/ WIZARDS_DIR = src/wizard/ -CONF_DIR = src/conf/ +SYSTEM_GROUP = http -INSTALLER_SCRIPT = src/installer.sh -SSS_SCRIPT = src/dsm-control.sh +DSM_UI_DIR = app +DSM_UI_CONFIG = src/app/config +CONF_DIR = src/conf/ -INSTALL_DEP_SERVICES = apache-web mysql -START_DEP_SERVICES = apache-web mysql +include ../../mk/spksrc.common.mk -INSTALL_PREFIX = /usr/local/$(SPK_NAME) +# Alternate conf dir for DSM 6 +ifeq ($(call version_lt, ${TCVERSION}, 7.0),1) +CONF_DIR = src/conf_6/ +endif POST_STRIP_TARGET = fengoffice_extra_install -BUSYBOX_CONFIG = daemon nice -ENV += BUSYBOX_CONFIG="$(BUSYBOX_CONFIG)" - include ../../mk/spksrc.spk.mk .PHONY: fengoffice_extra_install -fengoffice_extra_install: - install -m 755 -d $(STAGING_DIR)/var - install -m 755 src/fengoffice.sh $(STAGING_DIR)/bin/ - install -m 755 -d $(STAGING_DIR)/app - install -m 644 src/app/config $(STAGING_DIR)/app/config +fengoffice_extra_install: + install -m 755 -d $(STAGING_DIR)/web + install -m 644 src/web/fengoffice.conf $(STAGING_DIR)/web/fengoffice.conf + install -m 644 src/web/fengoffice.json $(STAGING_DIR)/web/fengoffice.json diff --git a/spk/fengoffice/src/conf/PKG_DEPS b/spk/fengoffice/src/conf/PKG_DEPS deleted file mode 100644 index 9f832e23f1a..00000000000 --- a/spk/fengoffice/src/conf/PKG_DEPS +++ /dev/null @@ -1,2 +0,0 @@ -[MariaDB] -dsm_min_ver=5.0-4300 diff --git a/spk/fengoffice/src/conf/resource b/spk/fengoffice/src/conf/resource new file mode 100644 index 00000000000..24c4770f090 --- /dev/null +++ b/spk/fengoffice/src/conf/resource @@ -0,0 +1,69 @@ +{ + "mariadb10-db": { + "admin-account-m10": "root", + "admin-pw-m10": "{{wizard_mysql_password_root}}", + "create-db": { + "db-collision": "skip", + "db-name": "fengoffice", + "flag": "{{wizard_create_db}}" + }, + "drop-db-uninst": true, + "drop-user-uninst": true, + "grant-user": { + "db-name": "fengoffice", + "flag": "{{mysql_grant_user}}", + "host": "localhost", + "user-name": "fengoffice", + "user-pw": "{{wizard_mysql_password_fengoffice}}" + } + }, + "webservice": { + "pkg_dir_prepare": [ + { + "group": "http", + "mode": "0755", + "source": "/var/packages/fengoffice/target/share/fengoffice", + "target": "fengoffice", + "user": "sc-fengoffice" + } + ], + "portals": [ + { + "alias": "fengoffice", + "app": "com.synocommunity.packages.fengoffice", + "name": "Feng Office", + "service": "fengoffice", + "type": "alias" + } + ], + "services": [ + { + "backend": 2, + "display_name": "Feng Office", + "icon": "app/images/fengoffice-{0}.png", + "php": { + "backend": 8, + "extensions": [ + "curl", + "gd", + "imagick", + "imap", + "intl", + "mysqli", + "pdo_mysql", + "xmlrpc", + "zip", + "zlib" + ], + "group": "http", + "profile_desc": "PHP Profile for fengoffice", + "profile_name": "fengoffice Profile", + "user": "sc-fengoffice" + }, + "root": "fengoffice", + "service": "fengoffice", + "type": "apache_php" + } + ] + } +} diff --git a/spk/fengoffice/src/conf_6/privilege b/spk/fengoffice/src/conf_6/privilege new file mode 100644 index 00000000000..1491ce3109b --- /dev/null +++ b/spk/fengoffice/src/conf_6/privilege @@ -0,0 +1,7 @@ +{ + "defaults": { + "run-as": "root" + }, + "username": "sc-fengoffice", + "join-groupname": "http" +} diff --git a/spk/fengoffice/src/conf_6/resource b/spk/fengoffice/src/conf_6/resource new file mode 100644 index 00000000000..495e04d9bf6 --- /dev/null +++ b/spk/fengoffice/src/conf_6/resource @@ -0,0 +1,20 @@ +{ + "mariadb10-db": { + "admin-account-m10": "root", + "admin-pw-m10": "{{wizard_mysql_password_root}}", + "create-db": { + "db-collision": "skip", + "db-name": "fengoffice", + "flag": "{{wizard_create_db}}" + }, + "drop-db-uninst": true, + "drop-user-uninst": true, + "grant-user": { + "db-name": "fengoffice", + "flag": "{{mysql_grant_user}}", + "host": "localhost", + "user-name": "fengoffice", + "user-pw": "{{wizard_mysql_password_fengoffice}}" + } + } +} diff --git a/spk/fengoffice/src/dsm-control.sh b/spk/fengoffice/src/dsm-control.sh deleted file mode 100644 index 0e96fbbc46d..00000000000 --- a/spk/fengoffice/src/dsm-control.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/sh - -# Package -PACKAGE="fengoffice" -DNAME="Feng Office" - -# Others -INSTALL_DIR="/usr/local/${PACKAGE}" -WEB_DIR="/var/services/web" -PATH="${INSTALL_DIR}/bin:${PATH}" -BUILDNUMBER="$(/bin/get_key_value /etc.defaults/VERSION buildnumber)" -USER="$([ "${BUILDNUMBER}" -ge "4418" ] && echo -n http || echo -n nobody)" -FENGOFFICE="${INSTALL_DIR}/bin/fengoffice.sh" -PID_FILE="${INSTALL_DIR}/var/fengoffice.pid" - - -start_daemon () -{ - start-stop-daemon -S -q -m -b -N 10 -x ${FENGOFFICE} -c ${USER} -u ${USER} -p ${PID_FILE} > /dev/null -} - -stop_daemon () -{ - start-stop-daemon -K -q -u ${USER} -p ${PID_FILE} - wait_for_status 1 20 || start-stop-daemon -K -s 9 -q -p ${PID_FILE} -} - -daemon_status () -{ - start-stop-daemon -K -q -t -u ${USER} -p ${PID_FILE} -} - -wait_for_status () -{ - counter=$2 - while [ ${counter} -gt 0 ]; do - daemon_status - [ $? -eq $1 ] && return - let counter=counter-1 - sleep 1 - done -return 1 -} - - -case $1 in - start) - if daemon_status; then - echo ${DNAME} is already running - else - echo Starting ${DNAME} ... - start_daemon - fi - ;; - stop) - if daemon_status; then - echo Stopping ${DNAME} ... - stop_daemon - else - echo ${DNAME} is not running - fi - ;; - status) - if daemon_status; then - echo ${DNAME} is running - exit 0 - else - echo ${DNAME} is not running - exit 1 - fi - ;; - log) - exit 1 - ;; - *) - exit 1 - ;; -esac diff --git a/spk/fengoffice/src/fengoffice.sh b/spk/fengoffice/src/fengoffice.sh deleted file mode 100644 index 79298346a95..00000000000 --- a/spk/fengoffice/src/fengoffice.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -set -e - -PHP="php" -FENGOFFICE="/var/services/web/fengoffice/cron.php" -SLEEP_TIME="600" - -# Main loop -while true; do - # Update - echo "Updating..." - ${PHP} ${FENGOFFICE} - - # Wait - echo "Waiting ${SLEEP_TIME} seconds..." - sleep ${SLEEP_TIME} -done diff --git a/spk/fengoffice/src/installer.sh b/spk/fengoffice/src/installer.sh deleted file mode 100755 index 34feceb6075..00000000000 --- a/spk/fengoffice/src/installer.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/sh - -# Package -PACKAGE="fengoffice" -DNAME="Feng Office" -VERSION="2.5.1.2" - -# Others -INSTALL_DIR="/usr/local/${PACKAGE}" -SSS="/var/packages/${PACKAGE}/scripts/start-stop-status" -WEB_DIR="/var/services/web" -TMP_DIR="${SYNOPKG_PKGDEST}/../../@tmp" -BUILDNUMBER="$(/bin/get_key_value /etc.defaults/VERSION buildnumber)" - -USER="$([ "${BUILDNUMBER}" -ge "4418" ] && echo -n http || echo -n nobody)" -MYSQL="$([ "${BUILDNUMBER}" -ge "7321" ] && echo -n /bin/mysql || echo -n /usr/syno/mysql/bin/mysql)" -MYSQLDUMP="$([ "${BUILDNUMBER}" -ge "7321" ] && echo -n /bin/mysqldump || echo -n /usr/syno/mysql/bin/mysqldump)" -MYSQL_USER="fengoffice" -MYSQL_DATABASE="fengoffice" - - -preinst () -{ - if [ "${SYNOPKG_PKG_STATUS}" == "INSTALL" ]; then - if ! ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e quit > /dev/null 2>&1; then - echo "Incorrect MySQL root password" - exit 1 - fi - if ${MYSQL} -u root -p"${wizard_mysql_password_root}" mysql -e "SELECT User FROM user" | grep ^${MYSQL_USER}$ > /dev/null 2>&1; then - echo "MySQL user ${MYSQL_USER} already exists" - exit 1 - fi - if ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e "SHOW DATABASES" | grep ^${MYSQL_DATABASE}$ > /dev/null 2>&1; then - echo "MySQL database ${MYSQL_DATABASE} already exists" - exit 1 - fi - fi - - exit 0 -} - -postinst () -{ - # Link - ln -s ${SYNOPKG_PKGDEST} ${INSTALL_DIR} - - # Install busybox stuff - ${INSTALL_DIR}/bin/busybox --install ${INSTALL_DIR}/bin - - # Install the web interface - cp -pR ${INSTALL_DIR}/share/${PACKAGE} ${WEB_DIR} - - # Setup database and run installer - if [ "${SYNOPKG_PKG_STATUS}" == "INSTALL" ]; then - ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e "CREATE DATABASE ${MYSQL_DATABASE}; GRANT ALL PRIVILEGES ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'localhost' IDENTIFIED BY '${wizard_mysql_password_fengoffice:=fengoffice}';" - cd ${WEB_DIR}/${PACKAGE}/public/install/ && QUERY_STRING="script_installer_storage[database_type]=mysql&script_installer_storage[database_host]=localhost&script_installer_storage[database_user]=${MYSQL_USER}&script_installer_storage[database_pass]=${wizard_mysql_password_fengoffice:=fengoffice}&script_installer_storage[database_name]=${MYSQL_DATABASE}&script_installer_storage[database_prefix]=fo_&script_installer_storage[database_engine]=InnoDB&script_installer_storage[absolute_url]=http://${wizard_domain_name:=`hostname`}/${PACKAGE}&script_installer_storage[plugins][]=core_dimensions&script_installer_storage[plugins][]=workspaces&script_installer_storage[plugins][]=mail&submited=submited" php install_helper.php > /dev/null - fi - - # Fix permissions - chown -R ${USER} ${WEB_DIR}/${PACKAGE}/config - chown -R ${USER} ${WEB_DIR}/${PACKAGE}/cache - chown -R ${USER} ${WEB_DIR}/${PACKAGE}/upload - chown -R ${USER} ${WEB_DIR}/${PACKAGE}/tmp - - exit 0 -} - -preuninst () -{ - # Check database - if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ] && ! ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e quit > /dev/null 2>&1; then - echo "Incorrect MySQL root password" - exit 1 - fi - - # Check database export location - if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" -a -n "${wizard_dbexport_path}" ]; then - if [ -f "${wizard_dbexport_path}" -o -e "${wizard_dbexport_path}/${MYSQL_DATABASE}.sql" ]; then - echo "File ${wizard_dbexport_path}/${MYSQL_DATABASE}.sql already exists. Please remove or choose a different location" - exit 1 - fi - fi - - # Stop the package - ${SSS} stop > /dev/null - - exit 0 -} - -postuninst () -{ - # Remove link - rm -f ${INSTALL_DIR} - - # Export and remove database - if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then - if [ -n "${wizard_dbexport_path}" ]; then - mkdir -p ${wizard_dbexport_path} - ${MYSQLDUMP} -u root -p"${wizard_mysql_password_root}" ${MYSQL_DATABASE} > ${wizard_dbexport_path}/${MYSQL_DATABASE}.sql - fi - ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e "DROP DATABASE ${MYSQL_DATABASE}; DROP USER '${MYSQL_USER}'@'localhost';" - fi - - # Remove the web interface - rm -fr ${WEB_DIR}/${PACKAGE} - - exit 0 -} - -preupgrade () -{ - # Stop the package - ${SSS} stop > /dev/null - - # Save configuration and files - rm -fr ${TMP_DIR}/${PACKAGE} - mkdir -p ${TMP_DIR}/${PACKAGE} - mv ${WEB_DIR}/${PACKAGE}/config/config.php ${TMP_DIR}/${PACKAGE}/ - mv ${WEB_DIR}/${PACKAGE}/config/installed_version.php ${TMP_DIR}/${PACKAGE}/ - mkdir ${TMP_DIR}/${PACKAGE}/upload/ - cp -r ${WEB_DIR}/${PACKAGE}/upload/*/ ${TMP_DIR}/${PACKAGE}/upload/ - - exit 0 -} - -postupgrade () -{ - # Detect old version - INSTALLED_VERSION=`sed -n "s|return '\(.*\)';|\1|p" ${TMP_DIR}/${PACKAGE}/installed_version.php | xargs` - - # Restore configuration - mv ${TMP_DIR}/${PACKAGE}/config.php ${WEB_DIR}/${PACKAGE}/config/ - cp -r ${TMP_DIR}/${PACKAGE}/upload/*/ ${WEB_DIR}/${PACKAGE}/upload/ - rm -fr ${TMP_DIR}/${PACKAGE} - - # Fix permissions - chown -R ${USER} ${WEB_DIR}/${PACKAGE}/upload - - # Run update scripts - php ${WEB_DIR}/${PACKAGE}/public/upgrade/console.php ${INSTALLED_VERSION} ${VERSION} > /dev/null - php ${WEB_DIR}/${PACKAGE}/public/install/plugin-console.php update_all > /dev/null - - exit 0 -} diff --git a/spk/fengoffice/src/service-setup.sh b/spk/fengoffice/src/service-setup.sh new file mode 100755 index 00000000000..8edab5b015c --- /dev/null +++ b/spk/fengoffice/src/service-setup.sh @@ -0,0 +1,371 @@ + +# Package +SC_DNAME="Feng Office" +SC_PKG_PREFIX="com-synocommunity-packages-" +SC_PKG_NAME="${SC_PKG_PREFIX}${SYNOPKG_PKGNAME}" +SVC_KEEP_LOG=y +SVC_BACKGROUND=y +SVC_WRITE_PID=y + +# Others +MYSQL="/usr/local/mariadb10/bin/mysql" +MYSQLDUMP="/usr/local/mariadb10/bin/mysqldump" +MYSQL_USER="${SYNOPKG_PKGNAME}" +MYSQL_DATABASE="${SYNOPKG_PKGNAME}" +if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -ge 7 ]; then + WEB_DIR="/var/services/web_packages" +else + WEB_DIR="/var/services/web" + # DSM 6 file and process ownership + WEB_USER="http" + WEB_GROUP="http" +fi +WEB_ROOT="${WEB_DIR}/${SYNOPKG_PKGNAME}" +SYNOSVC="/usr/syno/sbin/synoservice" + +exec_php () +{ + PHP="/usr/local/bin/php74" + # Define the resource file + RESOURCE_FILE="${SYNOPKG_PKGDEST}/web/fengoffice.json" + # Extract extensions and assign to variable + if [ -f "$RESOURCE_FILE" ]; then + PHP_SETTINGS=$(jq -r '.extensions | map("-d extension=" + . + ".so") | join(" ")' "$RESOURCE_FILE") + else + PHP_SETTINGS="" + fi + # Fix for mysqli default socket on DSM 6 + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + PHP_SETTINGS="${PHP_SETTINGS} -d mysqli.default_socket=/run/mysqld/mysqld10.sock" + fi + COMMAND="${PHP} ${PHP_SETTINGS} $*" + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + /bin/su "$WEB_USER" -s /bin/sh -c "${COMMAND}" >> ${LOG_FILE} 2>&1 + else + $COMMAND >> ${LOG_FILE} 2>&1 + fi + return $? +} + +service_prestart () +{ + FENGOFFICE="${WEB_ROOT}/cron.php" + SLEEP_TIME="600" + # Main loop + while true; do + # Update + echo "Updating..." + exec_php "${FENGOFFICE}" + # Wait + echo "Waiting ${SLEEP_TIME} seconds..." + sleep ${SLEEP_TIME} + done & + echo "$!" > "${PID_FILE}" +} + +validate_preinst () +{ + # Check for modification to PHP template defaults on DSM 6 + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + WS_TMPL_DIR="/var/packages/WebStation/target/misc" + WS_TMPL_FILE="php74_fpm.mustache" + WS_TMPL_PATH="${WS_TMPL_DIR}/${WS_TMPL_FILE}" + # Check for PHP template defaults + if ! grep -q -E '^user = http$' "${WS_TMPL_PATH}" || ! grep -q -E '^listen\.owner = http$' "${WS_TMPL_PATH}"; then + echo "PHP template defaults have been modified. Installation is not supported." + exit 1 + fi + fi + + if [ "${SYNOPKG_PKG_STATUS}" = "INSTALL" ]; then + if ! ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e quit > /dev/null 2>&1; then + echo "Incorrect MySQL 'root' password" + exit 1 + fi + if ${MYSQL} -u root -p"${wizard_mysql_password_root}" mysql -e "SELECT User FROM user" | grep ^${MYSQL_USER}$ > /dev/null 2>&1; then + echo "MySQL user '${MYSQL_USER}' already exists" + exit 1 + fi + if ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e "SHOW DATABASES" | grep ^${MYSQL_DATABASE}$ > /dev/null 2>&1; then + echo "MySQL database '${MYSQL_DATABASE}' already exists" + exit 1 + fi + + # Check for valid backup to restore + if [ "${wizard_fengoffice_restore}" = "true" ] && [ -n "${wizard_backup_file}" ]; then + if [ ! -f "${wizard_backup_file}" ]; then + echo "The backup file path specified is incorrect or not accessible" + exit 1 + fi + # Check backup file prefix + filename=$(basename "${wizard_backup_file}") + expected_prefix="${SYNOPKG_PKGNAME}_backup_v" + + if [ "${filename#"$expected_prefix"}" = "$filename" ]; then + echo "The backup filename does not start with the expected prefix" + exit 1 + fi + fi + fi +} + +service_postinst () +{ + # Web interface setup for DSM 6 -- used by INSTALL and UPGRADE + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + # Install the web interface + echo "Installing web interface" + ${MKDIR} ${WEB_ROOT} + rsync -aX ${SYNOPKG_PKGDEST}/share/${SYNOPKG_PKGNAME}/ ${WEB_ROOT} 2>&1 + + # Install web configurations + TEMPDIR="${SYNOPKG_PKGTMP}/web" + ${MKDIR} ${TEMPDIR} + WS_CFG_DIR="/usr/syno/etc/packages/WebStation" + WS_CFG_FILE="WebStation.json" + WS_CFG_PATH="${WS_CFG_DIR}/${WS_CFG_FILE}" + TMP_WS_CFG_PATH="${TEMPDIR}/${WS_CFG_FILE}" + PHP_CFG_FILE="PHPSettings.json" + PHP_CFG_PATH="${WS_CFG_DIR}/${PHP_CFG_FILE}" + TMP_PHP_CFG_PATH="${TEMPDIR}/${PHP_CFG_FILE}" + PHP_PROF_NAME="Default PHP 7.4 Profile" + WS_BACKEND="$(jq -r '.default.backend' ${WS_CFG_PATH})" + WS_PHP="$(jq -r '.default.php' ${WS_CFG_PATH})" + RESTART_APACHE="no" + RSYNC_ARCH_ARGS="--backup --suffix=.bak --remove-source-files" + # Check if Apache is the selected back-end + if [ ! "$WS_BACKEND" = "2" ]; then + echo "Set Apache as the back-end server" + jq '.default.backend = 2' ${WS_CFG_PATH} > ${TMP_WS_CFG_PATH} + rsync -aX ${RSYNC_ARCH_ARGS} ${TMP_WS_CFG_PATH} ${WS_CFG_DIR}/ 2>&1 + RESTART_APACHE="yes" + fi + # Check if default PHP profile is selected + if [ -z "$WS_PHP" ] || [ "$WS_PHP" = "null" ]; then + echo "Enable default PHP profile" + # Locate default PHP profile + PHP_PROF_ID="$(jq -r '. | to_entries[] | select(.value | type == "object" and .profile_desc == "'"$PHP_PROF_NAME"'") | .key' "${PHP_CFG_PATH}")" + jq ".default.php = \"$PHP_PROF_ID\"" "${WS_CFG_PATH}" > ${TMP_WS_CFG_PATH} + rsync -aX ${RSYNC_ARCH_ARGS} ${TMP_WS_CFG_PATH} ${WS_CFG_DIR}/ 2>&1 + RESTART_APACHE="yes" + fi + # Check for PHP profile + if ! jq -e ".[\"${SC_PKG_NAME}\"]" "${PHP_CFG_PATH}" >/dev/null; then + echo "Add PHP profile for ${SC_DNAME}" + jq --slurpfile newProfile ${SYNOPKG_PKGDEST}/web/${SYNOPKG_PKGNAME}.json '.["'"${SC_PKG_NAME}"'"] = $newProfile[0]' ${PHP_CFG_PATH} > ${TMP_PHP_CFG_PATH} + rsync -aX ${RSYNC_ARCH_ARGS} ${TMP_PHP_CFG_PATH} ${WS_CFG_DIR}/ 2>&1 + RESTART_APACHE="yes" + fi + # Check for Apache config + if [ ! -f "/usr/local/etc/apache24/sites-enabled/${SYNOPKG_PKGNAME}.conf" ]; then + echo "Add Apache config for ${SC_DNAME}" + rsync -aX ${SYNOPKG_PKGDEST}/web/${SYNOPKG_PKGNAME}.conf /usr/local/etc/apache24/sites-enabled/ 2>&1 + RESTART_APACHE="yes" + fi + # Restart Apache if configs have changed + if [ "$RESTART_APACHE" = "yes" ]; then + if jq -e 'to_entries | map(select((.key | startswith("'"${SC_PKG_PREFIX}"'")) and .key != "'"${SC_PKG_NAME}"'")) | length > 0' "${PHP_CFG_PATH}" >/dev/null; then + echo " [WARNING] Multiple PHP profiles detected, will require restart of DSM to load new configs" + else + echo "Restart Apache to load new configs" + ${SYNOSVC} --restart pkgctl-Apache2.4 + fi + fi + # Clean-up temporary files + ${RM} ${TEMPDIR} + fi + + # Fix permissions + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + chown -R ${WEB_USER}:${WEB_GROUP} ${WEB_ROOT} 2>/dev/null + fi + + if [ "${SYNOPKG_PKG_STATUS}" = "INSTALL" ]; then + # Check restore action + if [ "${wizard_fengoffice_restore}" = "true" ]; then + echo "The backup file is valid, performing restore" + # Extract archive to temp folder + TEMPDIR="${SYNOPKG_PKGTMP}/${SYNOPKG_PKGNAME}" + ${MKDIR} "${TEMPDIR}" + tar -xzf "${wizard_backup_file}" -C "${TEMPDIR}" 2>&1 + # Fix file ownership + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + chown -R ${WEB_USER}:${WEB_GROUP} ${TEMPDIR} 2>/dev/null + fi + + # Restore configuration and data + echo "Restoring configuration and data to ${WEB_DIR}" + rsync -aX --update -I "${TEMPDIR}/${SYNOPKG_PKGNAME}" "${WEB_DIR}/" 2>&1 + + # Update database password + sed -i "s/^\(\s*define('DB_PASS',\s*'\).*\(');\s*\)$/\1${wizard_mysql_password_fengoffice}\2/" ${WEB_ROOT}/config/config.php + + # Restore the Database + echo "Restoring database to ${MYSQL_DATABASE}" + ${MYSQL} -u root -p"${wizard_mysql_password_root}" ${MYSQL_DATABASE} < ${TEMPDIR}/database/${MYSQL_DATABASE}-dbbackup.sql 2>&1 + + # Run update scripts + exec_php "${WEB_ROOT}/public/upgrade/console.php" + exec_php "${WEB_ROOT}/public/install/plugin-console.php" "update_all" + + # Clean-up temporary files + ${RM} "${TEMPDIR}" + else + # Setup parameters for installation script + QUERY_STRING="\ +script_installer_storage[database_type]=mysqli\ +&script_installer_storage[database_host]=localhost\ +&script_installer_storage[database_user]=${MYSQL_USER}\ +&script_installer_storage[database_pass]=${wizard_mysql_password_fengoffice:=${SYNOPKG_PKGNAME}}\ +&script_installer_storage[database_name]=${MYSQL_DATABASE}\ +&script_installer_storage[database_prefix]=fo_\ +&script_installer_storage[database_engine]=InnoDB\ +&script_installer_storage[absolute_url]=http://${wizard_domain_name:=$(hostname)}/${SYNOPKG_PKGNAME}\ +&script_installer_storage[plugins][]=core_dimensions\ +&script_installer_storage[plugins][]=mail\ +&script_installer_storage[plugins][]=workspaces\ +&submited=submited" + # Prepare environment + cd ${WEB_ROOT}/public/install/ || return + # Execute based on DSM version + echo "Run ${SC_DNAME} installer" + exec_php "install_helper.php" + fi + fi +} + +validate_preuninst () +{ + # Check database + if [ "${SYNOPKG_PKG_STATUS}" = "UNINSTALL" ] && ! ${MYSQL} -u root -p"${wizard_mysql_password_root}" -e quit > /dev/null 2>&1; then + echo "Incorrect MySQL 'root' password" + exit 1 + fi + # Check export directory + if [ "${SYNOPKG_PKG_STATUS}" = "UNINSTALL" ] && [ -n "${wizard_export_path}" ]; then + if [ ! -d "${wizard_export_path}" ]; then + # If the export path directory does not exist, create it + ${MKDIR} "${wizard_export_path}" || { + # If mkdir fails, print an error message and exit + echo "Error: Unable to create directory ${wizard_export_path}. Check permissions." + exit 1 + } + elif [ ! -w "${wizard_export_path}" ]; then + # If the export path directory is not writable, print an error message and exit + echo "Error: Unable to write to directory ${wizard_export_path}. Check permissions." + exit 1 + fi + fi +} + +service_preuninst () +{ + if [ "${SYNOPKG_PKG_STATUS}" = "UNINSTALL" ] && [ -n "${wizard_export_path}" ]; then + # Prepare archive structure + if [ -f "${WEB_ROOT}/config/installed_version.php" ]; then + FENG_VER=$(sed -n "s|return '\(.*\)';|\1|p" ${WEB_ROOT}/config/installed_version.php | xargs) + else + FENG_VER=$(sed -n "s|return '\(.*\)';|\1|p" ${WEB_ROOT}/version.php | xargs) + fi + TEMPDIR="${SYNOPKG_PKGTMP}/${SYNOPKG_PKGNAME}_backup_v${FENG_VER}_$(date +"%Y%m%d")" + ${MKDIR} "${TEMPDIR}" + + # Backup Directories + echo "Copying previous configuration and data from ${WEB_ROOT}" + rsync -aX "${WEB_ROOT}" "${TEMPDIR}/" 2>&1 + + # Backup the Database + echo "Copying previous database from ${MYSQL_DATABASE}" + ${MKDIR} "${TEMPDIR}/database" + ${MYSQLDUMP} -u root -p"${wizard_mysql_password_root}" ${MYSQL_DATABASE} > ${TEMPDIR}/database/${MYSQL_DATABASE}-dbbackup.sql 2>&1 + + # Create backup archive + archive_name="$(basename "$TEMPDIR").tar.gz" + echo "Creating compressed archive of ${SC_DNAME} data in file $archive_name" + tar -C "$TEMPDIR" -czf "${SYNOPKG_PKGTMP}/$archive_name" . 2>&1 + + # Move archive to export directory + RSYNC_BAK_ARGS="--backup --suffix=.bak" + rsync -aX ${RSYNC_BAK_ARGS} "${SYNOPKG_PKGTMP}/$archive_name" "${wizard_export_path}/" 2>&1 + echo "Backup file copied successfully to ${wizard_export_path}" + + # Clean-up temporary files + ${RM} "${TEMPDIR}" + ${RM} "${SYNOPKG_PKGTMP}/$archive_name" + fi +} + +service_postuninst () +{ + # Web interface removal for DSM 6 -- used by UNINSTALL and UPGRADE + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + # Remove the web interface + echo "Removing web interface" + ${RM} ${WEB_ROOT} + + # Remove web configurations + TEMPDIR="${SYNOPKG_PKGTMP}/web" + ${MKDIR} ${TEMPDIR} + WS_CFG_DIR="/usr/syno/etc/packages/WebStation" + PHP_CFG_FILE="PHPSettings.json" + PHP_CFG_PATH="${WS_CFG_DIR}/${PHP_CFG_FILE}" + TMP_PHP_CFG_PATH="${TEMPDIR}/${PHP_CFG_FILE}" + RESTART_APACHE="no" + RSYNC_ARCH_ARGS="--backup --suffix=.bak --remove-source-files" + # Check for PHP profile + if jq -e ".[\"${SC_PKG_NAME}\"]" "${PHP_CFG_PATH}" >/dev/null; then + echo "Removing PHP profile for ${SC_DNAME}" + jq 'del(.["'"${SC_PKG_NAME}"'"])' ${PHP_CFG_PATH} > ${TMP_PHP_CFG_PATH} + rsync -aX ${RSYNC_ARCH_ARGS} ${TMP_PHP_CFG_PATH} ${WS_CFG_DIR}/ 2>&1 + ${RM} "${WS_CFG_DIR}/php_profile/${SC_PKG_NAME}" + RESTART_APACHE="yes" + fi + # Check for Apache config + if [ -f "/usr/local/etc/apache24/sites-enabled/${SYNOPKG_PKGNAME}.conf" ]; then + echo "Removing Apache config for ${SC_DNAME}" + ${RM} /usr/local/etc/apache24/sites-enabled/${SYNOPKG_PKGNAME}.conf + RESTART_APACHE="yes" + fi + # Restart Apache if configs have changed + if [ "$RESTART_APACHE" = "yes" ]; then + if jq -e 'to_entries | map(select((.key | startswith("'"${SC_PKG_PREFIX}"'")) and .key != "'"${SC_PKG_NAME}"'")) | length > 0' "${PHP_CFG_PATH}" >/dev/null; then + echo " [WARNING] Multiple PHP profiles detected, will require restart of DSM to load new configs" + else + echo "Restart Apache to load new configs" + ${SYNOSVC} --restart pkgctl-Apache2.4 + fi + fi + # Clean-up temporary files + ${RM} ${TEMPDIR} + fi +} + +service_save () +{ + # Save configuration and files + [ -d ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME} ] && ${RM} ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME} + mkdir -p ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME} + mv ${WEB_ROOT}/config/config.php ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/ + if [ -f "${WEB_ROOT}/config/installed_version.php" ]; then + mv ${WEB_ROOT}/config/installed_version.php ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/ + fi + mkdir ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/upload/ + cp -r ${WEB_ROOT}/upload/*/ ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/upload/ +} + +service_restore () +{ + # Restore configuration + mv ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/config.php ${WEB_ROOT}/config/ + cp -r ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME}/upload/*/ ${WEB_ROOT}/upload/ + ${RM} ${SYNOPKG_TEMP_UPGRADE_FOLDER}/${SYNOPKG_PKGNAME} + + # Fix permissions + if [ ${SYNOPKG_DSM_VERSION_MAJOR} -lt 7 ]; then + chown -R ${WEB_USER}:${WEB_GROUP} ${WEB_ROOT}/upload + fi + + # Run update scripts + exec_php "${WEB_ROOT}/public/upgrade/console.php" + exec_php "${WEB_ROOT}/public/install/plugin-console.php" "update_all" +} diff --git a/spk/fengoffice/src/web/fengoffice.conf b/spk/fengoffice/src/web/fengoffice.conf new file mode 100644 index 00000000000..57ca65aafdf --- /dev/null +++ b/spk/fengoffice/src/web/fengoffice.conf @@ -0,0 +1,16 @@ +Alias "/fengoffice" "/var/services/web/fengoffice" + + + ProxySet timeout=3600 + + + + + + SetHandler "proxy:fcgi://fengoffice" + + + + DirectoryIndex index.php index.htm index.html + + diff --git a/spk/fengoffice/src/web/fengoffice.json b/spk/fengoffice/src/web/fengoffice.json new file mode 100644 index 00000000000..7d288462557 --- /dev/null +++ b/spk/fengoffice/src/web/fengoffice.json @@ -0,0 +1,32 @@ +{ + "backend": 8, + "custom_open_basedir": false, + "display_errors": false, + "enable_cache": true, + "enable_xdebug": false, + "extensions": [ + "curl", + "gd", + "imagick", + "imap", + "intl", + "mysqli", + "pdo_mysql", + "xmlrpc", + "zip", + "zlib" + ], + "fpm_settings": { + "max_children": 20, + "max_spare_servers": 3, + "min_spare_servers": 1, + "mode": "dynamic", + "start_servers": 2 + }, + "open_basedir": "", + "php_settings": { + "mysqli.default_socket": "/run/mysqld/mysqld10.sock" + }, + "profile_desc": "PHP Profile for fengoffice", + "profile_name": "fengoffice Profile" +} diff --git a/spk/fengoffice/src/wizard/install_uifile b/spk/fengoffice/src/wizard/install_uifile deleted file mode 100644 index 1a18c3ee0d1..00000000000 --- a/spk/fengoffice/src/wizard/install_uifile +++ /dev/null @@ -1,28 +0,0 @@ -[{ - "step_title": "Feng Office database configuration", - "items": [{ - "type": "password", - "desc": "Enter your MySQL password.", - "subitems": [{ - "key": "wizard_mysql_password_root", - "desc": "Root password" - }] - }, { - "type": "password", - "desc": "A 'fengoffice' MySQL user and database will be created. Please enter a password for the 'fengoffice' user.", - "subitems": [{ - "key": "wizard_mysql_password_fengoffice", - "desc": "fengoffice password" - }] - }] -}, { - "step_title": "Feng Office configuration", - "items": [{ - "type": "textfield", - "desc": "Domain name of your DiskStation. For example: you.synology.me.", - "subitems": [{ - "key": "wizard_domain_name", - "desc": "Domain name" - }] - }] -}] diff --git a/spk/fengoffice/src/wizard/install_uifile.sh b/spk/fengoffice/src/wizard/install_uifile.sh new file mode 100644 index 00000000000..6de92198ef6 --- /dev/null +++ b/spk/fengoffice/src/wizard/install_uifile.sh @@ -0,0 +1,246 @@ +#!/bin/bash + +# for backwards compatability +if [ -z "${SYNOPKG_PKGDEST_VOL}" ]; then + SYNOPKG_PKGDEST_VOL="/volume1" +fi +INTERNAL_IP=$(ip -4 route get 8.8.8.8 | awk '/8.8.8.8/ && /src/ {print $NF}') + +quote_json () +{ + sed -e 's|\\|\\\\|g' -e 's|\"|\\\"|g' +} + +page_append () +{ + if [ -z "$1" ]; then + echo "$2" + elif [ -z "$2" ]; then + echo "$1" + else + echo "$1,$2" + fi +} + +RESTORE_BACKUP_FILE="wizard_fengoffice_restore" +BACKUP_FILE_PATH="wizard_backup_file" +RESTORE_ERROR_TEXT="An empty file path is not allowed when restore is enabled." +INSTALL_NEW_INSTANCE="wizard_fengoffice_install" +DOMAIN_NAME="wizard_domain_name" +INSTALL_ERROR_TEXT="An empty domain name is not allowed when install is enabled." + +checkNewInstall() +{ + CHECK_NEW_INSTALL=$(/bin/cat< 0' "${PHP_CFG_PATH}" >/dev/null; then + return 0 # true + else + return 1 # false + fi +} + +PAGE_INSTALL_CONFIG=$(/bin/cat< "${SYNOPKG_TEMP_LOGFILE}" +} + +main "$@" diff --git a/spk/fengoffice/src/wizard/uninstall_uifile b/spk/fengoffice/src/wizard/uninstall_uifile deleted file mode 100644 index 717cbe2e203..00000000000 --- a/spk/fengoffice/src/wizard/uninstall_uifile +++ /dev/null @@ -1,27 +0,0 @@ -[{ - "step_title": "Remove fengoffice database", - "items": [{ - "desc": "Attention: The fengoffice database will be removed during package uninstallation. All users and projects will be deleted." - }, { - "type": "password", - "desc": "Enter your MySQL password", - "subitems": [{ - "key": "wizard_mysql_password_root", - "desc": "Root password" - }] - }, { - "type": "textfield", - "desc": "Optional: Provide directory for database export. Leave blank to skip export. The directory will be created if it does not exist", - "subitems": [{ - "key": "wizard_dbexport_path", - "desc": "Database export location", - "validator": { - "allowBlank": true, - "regex": { - "expr": "/^\\\/volume[0-9]+\\\//", - "errorText": "Path should begin with /volume?/ with ? the number of the volume" - } - } - }] - }] -}] diff --git a/spk/fengoffice/src/wizard/uninstall_uifile.sh b/spk/fengoffice/src/wizard/uninstall_uifile.sh new file mode 100644 index 00000000000..d0f15ac942c --- /dev/null +++ b/spk/fengoffice/src/wizard/uninstall_uifile.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +# for backwards compatability +if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then + if [ -z "${SYNOPKG_PKGDEST_VOL}" ]; then + SYNOPKG_PKGDEST_VOL="/volume1" + fi + if [ -z "${SYNOPKG_PKGNAME}" ]; then + SYNOPKG_PKGNAME="fengoffice" + fi +fi + +quote_json () +{ + sed -e 's|\\|\\\\|g' -e 's|\"|\\\"|g' +} + +page_append () +{ + if [ -z "$1" ]; then + echo "$2" + elif [ -z "$2" ]; then + echo "$1" + else + echo "$1,$2" + fi +} + +ERROR_TEXT="Path should begin with /volume?/ with ? the number of the volume" + +getValidPath() +{ + VALID_PATH=$(/bin/cat< "${SYNOPKG_TEMP_LOGFILE}" +} + +main "$@" diff --git a/spk/fengoffice/src/wizard/upgrade_uifile b/spk/fengoffice/src/wizard/upgrade_uifile new file mode 100644 index 00000000000..f1dadd4a59f --- /dev/null +++ b/spk/fengoffice/src/wizard/upgrade_uifile @@ -0,0 +1,19 @@ +[{ + "step_title": "Feng Office upgrade", + "items": [{ + "desc": "The upgrading process ensures that your configurations and files are saved prior to updating your setup." + }, { + "type": "multiselect", + "subitems": [{ + "key": "wizard_create_db", + "desc": "Creates initial DB", + "defaultValue": false, + "hidden": true + }, { + "key": "mysql_grant_user", + "desc": "Initializes user rights", + "defaultValue": false, + "hidden": true + }] + }] +}]