Merge branch 'develop' into feature/thumbnails

# Conflicts:
#	products/ASC.Files/Client/src/HOCs/withFileActions.js
This commit is contained in:
Artem Tarasov 2021-06-11 18:30:44 +03:00
commit ee4760e899
263 changed files with 5869 additions and 1766 deletions

View File

@ -61,6 +61,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Api", "web\ASC.Web.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Studio", "web\ASC.Web.Studio\ASC.Web.Studio.csproj", "{9BF17F6E-04A9-4597-9273-21AD09600329}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Common.Tests", "common\Tests\ASC.Common.Tests\ASC.Common.Tests.csproj", "{E6DEAA28-9A73-470A-8F17-3E72B1E8D208}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Core.Common.Tests", "common\Tests\ASC.Core.Common.Tests\ASC.Core.Common.Tests.csproj", "{EF613F37-CFA9-4631-AA6E-512262FABC8E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Notify.Textile.Tests", "common\Tests\ASC.Notify.Textile.Tests\ASC.Notify.Textile.Tests.csproj", "{8FAD3D1B-3ADC-470C-9933-CAE1B95A8599}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -183,6 +189,18 @@ Global
{9BF17F6E-04A9-4597-9273-21AD09600329}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Release|Any CPU.Build.0 = Release|Any CPU
{E6DEAA28-9A73-470A-8F17-3E72B1E8D208}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6DEAA28-9A73-470A-8F17-3E72B1E8D208}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6DEAA28-9A73-470A-8F17-3E72B1E8D208}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E6DEAA28-9A73-470A-8F17-3E72B1E8D208}.Release|Any CPU.Build.0 = Release|Any CPU
{EF613F37-CFA9-4631-AA6E-512262FABC8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF613F37-CFA9-4631-AA6E-512262FABC8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF613F37-CFA9-4631-AA6E-512262FABC8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF613F37-CFA9-4631-AA6E-512262FABC8E}.Release|Any CPU.Build.0 = Release|Any CPU
{8FAD3D1B-3ADC-470C-9933-CAE1B95A8599}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FAD3D1B-3ADC-470C-9933-CAE1B95A8599}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FAD3D1B-3ADC-470C-9933-CAE1B95A8599}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FAD3D1B-3ADC-470C-9933-CAE1B95A8599}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,163 @@
#!/bin/bash
#
# (c) Copyright Ascensio System SIA 2021
#
# This program is a free software product. You can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License (AGPL)
# version 3 as published by the Free Software Foundation. In accordance with
# Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
# that Ascensio System SIA expressly excludes the warranty of non-infringement
# of any third-party rights.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
# details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
#
# You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
# street, Riga, Latvia, EU, LV-1050.
#
# The interactive user interfaces in modified source and object code versions
# of the Program must display Appropriate Legal Notices, as required under
# Section 5 of the GNU AGPL version 3.
#
# Pursuant to Section 7(b) of the License you must retain the original Product
# logo when distributing the program. Pursuant to Section 7(e) we decline to
# grant you any rights under trademark law for use of our trademarks.
#
# All the Product's GUI elements, including illustrations and icon sets, as
# well as technical writing content are licensed under the terms of the
# Creative Commons Attribution-ShareAlike 4.0 International. See the License
# terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
#
PARAMETERS="";
DOCKER="";
LOCAL_SCRIPTS="false"
HELP="false";
product="appserver"
while [ "$1" != "" ]; do
case $1 in
-ls | --local_scripts )
if [ "$2" == "true" ] || [ "$2" == "false" ]; then
PARAMETERS="$PARAMETERS ${1}";
LOCAL_SCRIPTS=$2
shift
fi
;;
"-?" | -h | --help )
HELP="true";
DOCKER="true";
PARAMETERS="$PARAMETERS -ht install-Docker.sh";
;;
esac
PARAMETERS="$PARAMETERS ${1}";
shift
done
root_checking () {
if [ ! $( id -u ) -eq 0 ]; then
echo "To perform this action you must be logged in with root rights"
exit 1;
fi
}
command_exists () {
type "$1" &> /dev/null;
}
install_curl () {
if command_exists apt-get; then
apt-get -y update
apt-get -y -q install curl
elif command_exists yum; then
yum -y install curl
fi
if ! command_exists curl; then
echo "command curl not found"
exit 1;
fi
}
read_installation_method () {
echo "Select 'Y' to install ONLYOFFICE $product using Docker (recommended). Select 'N' to install it using RPM/DEB packages.";
read -p "Install with Docker [Y/N/C]? " choice
case "$choice" in
y|Y )
DOCKER="true";
;;
n|N )
DOCKER="false";
;;
c|C )
exit 0;
;;
* )
echo "Please, enter Y, N or C to cancel";
;;
esac
if [ "$DOCKER" == "" ]; then
read_installation_method;
fi
}
root_checking
if ! command_exists curl ; then
install_curl;
fi
if [ "$HELP" == "false" ]; then
read_installation_method;
fi
#DOWNLOAD_URL_PREFIX="http://download.onlyoffice.com/install-appserver/"
DOWNLOAD_URL_PREFIX="https://raw.githubusercontent.com/ONLYOFFICE/${product}/develop/build/install/OneClickInstall"
if [ "$DOCKER" == "true" ]; then
if [ "$LOCAL_SCRIPTS" == "true" ]; then
bash install-Docker.sh ${PARAMETERS}
else
curl -s -O ${DOWNLOAD_URL_PREFIX}/install-Docker.sh
bash install-Docker.sh ${PARAMETERS}
rm install-Docker.sh
fi
else
if [ -f /etc/redhat-release ] ; then
DIST=$(cat /etc/redhat-release |sed s/\ release.*//);
REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//);
REV_PARTS=(${REV//\./ });
REV=${REV_PARTS[0]};
if [[ "${DIST}" == CentOS* ]] && [ ${REV} -lt 7 ]; then
echo "CentOS 7 or later is required";
exit 1;
fi
if [ "$LOCAL_SCRIPTS" == "true" ]; then
bash install-RedHat.sh ${PARAMETERS}
else
curl -s -O ${DOWNLOAD_URL_PREFIX}/install-RedHat.sh
bash install-RedHat.sh ${PARAMETERS}
rm install-RedHat.sh
fi
elif [ -f /etc/debian_version ] ; then
if [ "$LOCAL_SCRIPTS" == "true" ]; then
bash install-Debian.sh ${PARAMETERS}
else
curl -s -O ${DOWNLOAD_URL_PREFIX}/install-Debian.sh
bash install-Debian.sh ${PARAMETERS}
rm install-Debian.sh
fi
else
echo "Not supported OS";
exit 1;
fi
fi

View File

@ -0,0 +1,891 @@
#!/bin/bash
#
# (c) Copyright Ascensio System SIA 2021
#
# This program is a free software product. You can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License (AGPL)
# version 3 as published by the Free Software Foundation. In accordance with
# Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
# that Ascensio System SIA expressly excludes the warranty of non-infringement
# of any third-party rights.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
# details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
#
# You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
# street, Riga, Latvia, EU, LV-1050.
#
# The interactive user interfaces in modified source and object code versions
# of the Program must display Appropriate Legal Notices, as required under
# Section 5 of the GNU AGPL version 3.
#
# Pursuant to Section 7(b) of the License you must retain the original Product
# logo when distributing the program. Pursuant to Section 7(e) we decline to
# grant you any rights under trademark law for use of our trademarks.
#
# All the Product's GUI elements, including illustrations and icon sets, as
# well as technical writing content are licensed under the terms of the
# Creative Commons Attribution-ShareAlike 4.0 International. See the License
# terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
#
PRODUCT="onlyoffice"
BASE_DIR="/app/$PRODUCT";
STATUS=""
NETWORK=${PRODUCT}
DISK_REQUIREMENTS=40960;
MEMORY_REQUIREMENTS=5500;
CORE_REQUIREMENTS=2;
DIST="";
REV="";
KERNEL="";
INSTALL_MYSQL_SERVER="true";
INSTALL_DOCUMENT_SERVER="true";
INSTALL_APPSERVER="true";
UPDATE="false";
HUB="";
USERNAME="";
PASSWORD="";
MYSQL_DATABASE=""
MYSQL_USER=""
MYSQL_PASSWORD=""
MYSQL_ROOT_PASSWORD=""
MYSQL_HOST=""
ZOO_PORT=""
ZOO_HOST=""
KAFKA_HOST=""
ELK_HOST=""
DOCUMENT_SERVER_JWT_SECRET=""
DOCUMENT_SERVER_HOST=""
APP_CORE_BASE_DOMAIN=""
APP_CORE_MACHINEKEY=""
APP_DOTNET_ENV=""
HELP_TARGET="install-Docker.sh";
SKIP_HARDWARE_CHECK="false";
EXTERNAL_PORT="8092"
SERVICE_PORT="5050"
while [ "$1" != "" ]; do
case $1 in
-u | --update )
if [ "$2" != "" ]; then
UPDATE=$2
shift
fi
;;
-hub | --hub )
if [ "$2" != "" ]; then
HUB=$2
shift
fi
;;
-un | --username )
if [ "$2" != "" ]; then
USERNAME=$2
shift
fi
;;
-p | --password )
if [ "$2" != "" ]; then
PASSWORD=$2
shift
fi
;;
-ias | --installappserver )
if [ "$2" != "" ]; then
INSTALL_APPSERVER=$2
shift
fi
;;
-ids | --installdocumentserver )
if [ "$2" != "" ]; then
INSTALL_DOCUMENT_SERVER=$2
shift
fi
;;
-imysql | --installmysql )
if [ "$2" != "" ]; then
INSTALL_MYSQL_SERVER=$2
shift
fi
;;
-ht | --helptarget )
if [ "$2" != "" ]; then
HELP_TARGET=$2
shift
fi
;;
-mysqld | --mysqldatabase )
if [ "$2" != "" ]; then
MYSQL_DATABASE=$2
shift
fi
;;
-mysqlrp | --mysqlrootpassword )
if [ "$2" != "" ]; then
MYSQL_ROOT_PASSWORD=$2
shift
fi
;;
-mysqlu | --mysqluser )
if [ "$2" != "" ]; then
MYSQL_USER=$2
shift
fi
;;
-mysqlh | --mysqlhost )
if [ "$2" != "" ]; then
MYSQL_HOST=$2
shift
fi
;;
-mysqlp | --mysqlpassword )
if [ "$2" != "" ]; then
MYSQL_PASSWORD=$2
shift
fi
;;
-zp | --zookeeperport )
if [ "$2" != "" ]; then
ZOO_PORT=$2
shift
fi
;;
-zh | --zookeeperhost )
if [ "$2" != "" ]; then
ZOO_HOST=$2
shift
fi
;;
-kh | --kafkahost )
if [ "$2" != "" ]; then
KAFKA_HOST=$2
shift
fi
;;
-esh | --elasticsearchhost )
if [ "$2" != "" ]; then
ELK_HOST=$2
shift
fi
;;
-skiphc | --skiphardwarecheck )
if [ "$2" != "" ]; then
SKIP_HARDWARE_CHECK=$2
shift
fi
;;
-ip | --internalport )
if [ "$2" != "" ]; then
SERVICE_PORT=$2
shift
fi
;;
-ep | --externalport )
if [ "$2" != "" ]; then
EXTERNAL_PORT=$2
shift
fi
;;
-ash | --appserverhost )
if [ "$2" != "" ]; then
APP_CORE_BASE_DOMAIN=$2
shift
fi
;;
-mk | --machinekey )
if [ "$2" != "" ]; then
APP_CORE_MACHINEKEY=$2
shift
fi
;;
-env | --environment )
if [ "$2" != "" ]; then
APP_DOTNET_ENV=$2
shift
fi
;;
-s | --status )
if [ "$2" != "" ]; then
STATUS=$2
shift
fi
;;
-ls | --local_scripts )
if [ "$2" != "" ]; then
shift
fi
;;
-? | -h | --help )
echo " Usage: bash $HELP_TARGET [PARAMETER] [[PARAMETER], ...]"
echo
echo " Parameters:"
echo " -hub, --hub dockerhub name"
echo " -un, --username dockerhub username"
echo " -p, --password dockerhub password"
echo " -ias, --installappserver install or update appserver (true|false)"
echo " -ids, --installdocumentserver install or update document server (true|false)"
echo " -imysql, --installmysql install or update mysql (true|false)"
echo " -mysqlrp, --mysqlrootpassword mysql server root password"
echo " -mysqld, --mysqldatabase appserver database name"
echo " -mysqlu, --mysqluser appserver database user"
echo " -mysqlp, --mysqlpassword appserver database password"
echo " -mysqlh, --mysqlhost mysql server host"
echo " -ash, --appserverhost appserver host"
echo " -zp, --zookeeperport zookeeper port (default value 2181)"
echo " -zh, --zookeeperhost zookeeper host"
echo " -kh, --kafkahost kafka host"
echo " -esh, --elasticsearchhost elasticsearch host"
echo " -env, --environment appserver environment"
echo " -skiphc, --skiphardwarecheck skip hardware check (true|false)"
echo " -ip, --internalport internal appserver port (default value 5050)"
echo " -ep, --externalport external appserver port (default value 8092)"
echo " -mk, --machinekey setting for core.machinekey"
echo " -ls, --local_scripts run the installation from local scripts"
echo " -?, -h, --help this help"
echo
echo " Install all the components without document server:"
echo " bash $HELP_TARGET -ids false"
echo
echo " Install Document Server only. Skip the installation of MYSQL and Appserver:"
echo " bash $HELP_TARGET -ias false -ids true -imysql false -ims false"
echo " Update all installed components. Stop the containers that need to be updated, remove them and run the latest versions of the corresponding components. The portal data should be picked up automatically:"
echo " bash $HELP_TARGET -u true"
echo
echo " Update Document Server only to version 4.4.2.20 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -dv 4.4.2.20 -ias false"
echo
echo " Update Appserver only to version 0.1.10 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -av 9.1.0.393 -ids false"
echo
exit 0
;;
* )
echo "Unknown parameter $1" 1>&2
exit 1
;;
esac
shift
done
root_checking () {
if [ ! $( id -u ) -eq 0 ]; then
echo "To perform this action you must be logged in with root rights"
exit 1;
fi
}
command_exists () {
type "$1" &> /dev/null;
}
file_exists () {
if [ -z "$1" ]; then
echo "file path is empty"
exit 1;
fi
if [ -f "$1" ]; then
return 0; #true
else
return 1; #false
fi
}
to_lowercase () {
echo "$1" | awk '{print tolower($0)}'
}
trim () {
echo -e "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
get_random_str () {
LENGTH=$1;
if [[ -z ${LENGTH} ]]; then
LENGTH=12;
fi
VALUE=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c ${LENGTH});
echo "$VALUE"
}
get_os_info () {
OS=`to_lowercase \`uname\``
if [ "${OS}" == "windowsnt" ]; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "darwin" ]; then
echo "Not supported OS";
exit 1;
else
OS=`uname`
if [ "${OS}" == "SunOS" ] ; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "AIX" ] ; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "Linux" ] ; then
MACH=`uname -m`
if [ "${MACH}" != "x86_64" ]; then
echo "Currently only supports 64bit OS's";
exit 1;
fi
KERNEL=`uname -r`
if [ -f /etc/redhat-release ] ; then
CONTAINS=$(cat /etc/redhat-release | { grep -sw release || true; });
if [[ -n ${CONTAINS} ]]; then
DIST=`cat /etc/redhat-release |sed s/\ release.*//`
REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
else
DIST=`cat /etc/os-release | grep -sw 'ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
REV=`cat /etc/os-release | grep -sw 'VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
fi
elif [ -f /etc/SuSE-release ] ; then
REV=`cat /etc/os-release | grep '^VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
DIST='SuSe'
elif [ -f /etc/debian_version ] ; then
REV=`cat /etc/debian_version`
DIST='Debian'
if [ -f /etc/lsb-release ] ; then
DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print $2 }'`
REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print $2 }'`
elif [ -f /etc/lsb_release ] || [ -f /usr/bin/lsb_release ] ; then
DIST=`lsb_release -a 2>&1 | grep 'Distributor ID:' | awk -F ":" '{print $2 }'`
REV=`lsb_release -a 2>&1 | grep 'Release:' | awk -F ":" '{print $2 }'`
fi
elif [ -f /etc/os-release ] ; then
DIST=`cat /etc/os-release | grep -sw 'ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
REV=`cat /etc/os-release | grep -sw 'VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
fi
fi
DIST=$(trim $DIST);
REV=$(trim $REV);
fi
}
check_os_info () {
if [[ -z ${KERNEL} || -z ${DIST} || -z ${REV} ]]; then
echo "$KERNEL, $DIST, $REV";
echo "Not supported OS";
exit 1;
fi
}
check_kernel () {
MIN_NUM_ARR=(3 10 0);
CUR_NUM_ARR=();
CUR_STR_ARR=$(echo $KERNEL | grep -Po "[0-9]+\.[0-9]+\.[0-9]+" | tr "." " ");
for CUR_STR_ITEM in $CUR_STR_ARR
do
CUR_NUM_ARR=(${CUR_NUM_ARR[@]} $CUR_STR_ITEM)
done
INDEX=0;
while [[ $INDEX -lt 3 ]]; do
if [ ${CUR_NUM_ARR[INDEX]} -lt ${MIN_NUM_ARR[INDEX]} ]; then
echo "Not supported OS Kernel"
exit 1;
elif [ ${CUR_NUM_ARR[INDEX]} -gt ${MIN_NUM_ARR[INDEX]} ]; then
INDEX=3
fi
(( INDEX++ ))
done
}
check_hardware () {
AVAILABLE_DISK_SPACE=$(df -m / | tail -1 | awk '{ print $4 }');
if [ ${AVAILABLE_DISK_SPACE} -lt ${DISK_REQUIREMENTS} ]; then
echo "Minimal requirements are not met: need at least $DISK_REQUIREMENTS MB of free HDD space"
exit 1;
fi
TOTAL_MEMORY=$(free -m | grep -oP '\d+' | head -n 1);
if [ ${TOTAL_MEMORY} -lt ${MEMORY_REQUIREMENTS} ]; then
echo "Minimal requirements are not met: need at least $MEMORY_REQUIREMENTS MB of RAM"
exit 1;
fi
CPU_CORES_NUMBER=$(cat /proc/cpuinfo | grep processor | wc -l);
if [ ${CPU_CORES_NUMBER} -lt ${CORE_REQUIREMENTS} ]; then
echo "The system does not meet the minimal hardware requirements. CPU with at least $CORE_REQUIREMENTS cores is required"
exit 1;
fi
}
install_service () {
COMMAND_NAME=$1
PACKAGE_NAME=$2
PACKAGE_NAME=${PACKAGE_NAME:-"$COMMAND_NAME"}
if command_exists apt-get; then
apt-get -y update -qq
apt-get -y -q install $PACKAGE_NAME
elif command_exists yum; then
yum -y install $PACKAGE_NAME
fi
if ! command_exists $COMMAND_NAME; then
echo "command $COMMAND_NAME not found"
exit 1;
fi
}
install_docker_compose () {
if ! command_exists python3; then
install_service python3
fi
if command_exists apt-get; then
apt-get -y update -qq
apt-get -y -q install python3-pip
elif command_exists yum; then
curl -O https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py || true
rm get-pip.py
fi
python3 -m pip install docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
if ! command_exists docker-compose; then
echo "command docker-compose not found"
exit 1;
fi
}
check_ports () {
RESERVED_PORTS=(443 2181 2888 3306 3888 8081 8099 9092 9200 9300 9800 9899 9999 33060);
ARRAY_PORTS=();
USED_PORTS="";
if ! command_exists netstat; then
install_service netstat net-tools
fi
if [ "${EXTERNAL_PORT//[0-9]}" = "" ]; then
for RESERVED_PORT in "${RESERVED_PORTS[@]}"
do
if [ "$RESERVED_PORT" -eq "$EXTERNAL_PORT" ] ; then
echo "External port $EXTERNAL_PORT is reserved. Select another port"
exit 1;
fi
if [ "$RESERVED_PORT" -eq "$SERVICE_PORT" ] ; then
echo "Internal port $SERVICE_PORT is reserved. Select another port"
exit 1;
fi
done
else
echo "Invalid external port $EXTERNAL_PORT"
exit 1;
fi
if [ "$INSTALL_APPSERVER" == "true" ]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "$EXTERNAL_PORT");
fi
for PORT in "${ARRAY_PORTS[@]}"
do
REGEXP=":$PORT$"
CHECK_RESULT=$(netstat -lnt | awk '{print $4}' | { grep $REGEXP || true; })
if [[ $CHECK_RESULT != "" ]]; then
if [[ $USED_PORTS != "" ]]; then
USED_PORTS="$USED_PORTS, $PORT"
else
USED_PORTS="$PORT"
fi
fi
done
if [[ $USED_PORTS != "" ]]; then
echo "The following TCP Ports must be available: $USED_PORTS"
exit 1;
fi
}
check_docker_version () {
CUR_FULL_VERSION=$(docker -v | cut -d ' ' -f3 | cut -d ',' -f1);
CUR_VERSION=$(echo $CUR_FULL_VERSION | cut -d '-' -f1);
CUR_EDITION=$(echo $CUR_FULL_VERSION | cut -d '-' -f2);
if [ "${CUR_EDITION}" == "ce" ] || [ "${CUR_EDITION}" == "ee" ]; then
return 0;
fi
if [ "${CUR_VERSION}" != "${CUR_EDITION}" ]; then
echo "Unspecific docker version"
exit 1;
fi
MIN_NUM_ARR=(1 10 0);
CUR_NUM_ARR=();
CUR_STR_ARR=$(echo $CUR_VERSION | grep -Po "[0-9]+\.[0-9]+\.[0-9]+" | tr "." " ");
for CUR_STR_ITEM in $CUR_STR_ARR
do
CUR_NUM_ARR=(${CUR_NUM_ARR[@]} $CUR_STR_ITEM)
done
INDEX=0;
while [[ $INDEX -lt 3 ]]; do
if [ ${CUR_NUM_ARR[INDEX]} -lt ${MIN_NUM_ARR[INDEX]} ]; then
echo "The outdated Docker version has been found. Please update to the latest version."
exit 1;
elif [ ${CUR_NUM_ARR[INDEX]} -gt ${MIN_NUM_ARR[INDEX]} ]; then
return 0;
fi
(( INDEX++ ))
done
}
install_docker_using_script () {
if ! command_exists curl ; then
install_service curl
fi
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
rm get-docker.sh
}
install_docker () {
if [ "${DIST}" == "Ubuntu" ] || [ "${DIST}" == "Debian" ] || [[ "${DIST}" == CentOS* ]] || [ "${DIST}" == "Fedora" ]; then
install_docker_using_script
systemctl start docker
systemctl enable docker
elif [ "${DIST}" == "Red Hat Enterprise Linux Server" ]; then
echo ""
echo "Your operating system does not allow Docker CE installation."
echo "You can install Docker EE using the manual here - https://docs.docker.com/engine/installation/linux/rhel/"
echo ""
exit 1;
elif [ "${DIST}" == "SuSe" ]; then
echo ""
echo "Your operating system does not allow Docker CE installation."
echo "You can install Docker EE using the manual here - https://docs.docker.com/engine/installation/linux/suse/"
echo ""
exit 1;
elif [ "${DIST}" == "altlinux" ]; then
apt-get -y install docker-io
chkconfig docker on
service docker start
systemctl enable docker
else
echo ""
echo "Docker could not be installed automatically."
echo "Please use this official instruction https://docs.docker.com/engine/installation/linux/other/ for its manual installation."
echo ""
exit 1;
fi
if ! command_exists docker ; then
echo "error while installing docker"
exit 1;
fi
}
docker_login () {
if [[ -n ${USERNAME} && -n ${PASSWORD} ]]; then
docker login ${HUB} --username ${USERNAME} --password ${PASSWORD}
fi
}
create_network () {
EXIST=$(docker network ls | awk '{print $2;}' | { grep -x ${NETWORK} || true; });
if [[ -z ${EXIST} ]]; then
docker network create --driver bridge ${NETWORK}
fi
}
get_container_env_parameter () {
CONTAINER_NAME=$1;
PARAMETER_NAME=$2;
VALUE="";
if [[ -z ${CONTAINER_NAME} ]]; then
echo "Empty container name"
exit 1;
fi
if [[ -z ${PARAMETER_NAME} ]]; then
echo "Empty parameter name"
exit 1;
fi
if command_exists docker ; then
CONTAINER_EXIST=$(docker ps -aqf "name=$CONTAINER_NAME");
if [[ -n ${CONTAINER_EXIST} ]]; then
VALUE=$(docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' ${CONTAINER_NAME} | grep "${PARAMETER_NAME}=" | sed 's/^.*=//');
fi
fi
echo "$VALUE"
}
set_jwt_secret () {
CURRENT_JWT_SECRET="";
if [[ -z ${JWT_SECRET} ]]; then
CURRENT_JWT_SECRET=$(get_container_env_parameter "${PRODUCT}-document-server" "JWT_SECRET");
if [[ -n ${CURRENT_JWT_SECRET} ]]; then
DOCUMENT_SERVER_JWT_SECRET="$CURRENT_JWT_SECRET";
fi
fi
if [[ -z ${JWT_SECRET} ]]; then
CURRENT_JWT_SECRET=$(get_container_env_parameter "${PRODUCT}-api" "DOCUMENT_SERVER_JWT_SECRET");
if [[ -n ${CURRENT_JWT_SECRET} ]]; then
DOCUMENT_SERVER_JWT_SECRET="$CURRENT_JWT_SECRET";
fi
fi
if [[ -z ${JWT_SECRET} ]] && [[ "$UPDATE" != "true" ]]; then
DOCUMENT_SERVER_JWT_SECRET=$(get_random_str 12);
fi
}
set_core_machinekey () {
CURRENT_CORE_MACHINEKEY="";
if [[ -z ${CORE_MACHINEKEY} ]]; then
if file_exists ${BASE_DIR}/.private/machinekey; then
CURRENT_CORE_MACHINEKEY=$(cat ${BASE_DIR}/.private/machinekey);
if [[ -n ${CURRENT_CORE_MACHINEKEY} ]]; then
APP_CORE_MACHINEKEY="$CURRENT_CORE_MACHINEKEY";
fi
fi
fi
if [[ -z ${CORE_MACHINEKEY} ]]; then
CURRENT_CORE_MACHINEKEY=$(get_container_env_parameter "${PRODUCT}-api" "$APP_CORE_MACHINEKEY");
if [[ -n ${CURRENT_CORE_MACHINEKEY} ]]; then
APP_CORE_MACHINEKEY="$CURRENT_CORE_MACHINEKEY";
fi
fi
if [[ -z ${CORE_MACHINEKEY} ]] && [[ "$UPDATE" != "true" ]]; then
APP_CORE_MACHINEKEY=$(get_random_str 12);
echo $APP_CORE_MACHINEKEY > ${BASE_DIR}/.private/machinekey
fi
}
download_files () {
mkdir -p ${BASE_DIR}
mkdir -p ${BASE_DIR}/.private/
mkdir -p ${BASE_DIR}/config/mysql/conf.d/
if ! command_exists wget; then
install_service wget
fi
DOWNLOAD_URL_PREFIX="https://raw.githubusercontent.com/ONLYOFFICE/AppServer/develop/build/install/docker"
wget -q -O $BASE_DIR/.env "${DOWNLOAD_URL_PREFIX}/.env"
wget -q -O $BASE_DIR/appserver.yml "${DOWNLOAD_URL_PREFIX}/appserver.yml"
wget -q -O $BASE_DIR/db.yml "${DOWNLOAD_URL_PREFIX}/db.yml"
wget -q -O $BASE_DIR/ds.yml "${DOWNLOAD_URL_PREFIX}/ds.yml"
wget -q -O $BASE_DIR/config/createdb.sql "${DOWNLOAD_URL_PREFIX}/config/createdb.sql"
wget -q -O $BASE_DIR/config/onlyoffice.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.sql"
wget -q -O $BASE_DIR/config/onlyoffice.data.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.data.sql"
wget -q -O $BASE_DIR/config/mysql/conf.d/mysql.cnf "${DOWNLOAD_URL_PREFIX}/config/mysql/conf.d/mysql.cnf"
wget -q -O $BASE_DIR/config/onlyoffice.resources.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.resources.sql"
wget -q -O $BASE_DIR/config/onlyoffice.upgradev110.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.upgradev110.sql"
wget -q -O $BASE_DIR/config/onlyoffice.upgradev111.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.upgradev111.sql"
wget -q -O $BASE_DIR/config/onlyoffice.upgradev115.sql "${DOWNLOAD_URL_PREFIX}/config/onlyoffice.upgradev115.sql"
if [[ -n ${STATUS} ]]; then
sed -i "s/STATUS=.*/STATUS=\"${STATUS}\"/g" $BASE_DIR/.env
fi
}
reconfigure () {
VARIABLE_NAME=$1
VARIABLE_VALUE=$(echo $2 | sed -e 's/;/%/g' -e 's/=/%/g' -e 's/!/%/g')
if [[ -n ${VARIABLE_VALUE} ]]; then
sed -i "s/${VARIABLE_NAME}=.*/${VARIABLE_NAME}=${VARIABLE_VALUE}/g" $BASE_DIR/.env
fi
}
install_mysql_server () {
if ! command_exists docker-compose; then
install_docker_compose
fi
if [[ -z ${MYSQL_PASSWORD} ]] && [[ -z ${MYSQL_ROOT_PASSWORD} ]]; then
MYSQL_PASSWORD=$(get_random_str 20);
MYSQL_ROOT_PASSWORD=$(get_random_str 20);
elif [[ -z ${MYSQL_PASSWORD} ]] || [[ -z ${MYSQL_ROOT_PASSWORD} ]]; then
MYSQL_PASSWORD=${MYSQL_PASSWORD:-"$MYSQL_ROOT_PASSWORD"}
MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-"$MYSQL_PASSWORD"}
fi
reconfigure MYSQL_DATABASE ${MYSQL_DATABASE}
reconfigure MYSQL_USER ${MYSQL_USER}
reconfigure MYSQL_PASSWORD ${MYSQL_PASSWORD}
reconfigure MYSQL_ROOT_PASSWORD ${MYSQL_ROOT_PASSWORD}
reconfigure MYSQL_HOST ${MYSQL_HOST}
docker-compose -f $BASE_DIR/db.yml up -d
}
install_document_server () {
if ! command_exists docker-compose; then
install_docker_compose
fi
reconfigure DOCUMENT_SERVER_JWT_SECRET ${DOCUMENT_SERVER_JWT_SECRET}
reconfigure DOCUMENT_SERVER_HOST ${DOCUMENT_SERVER_HOST}
docker-compose -f $BASE_DIR/ds.yml up -d
}
install_appserver () {
if ! command_exists docker-compose; then
install_docker_compose
fi
reconfigure ZOO_PORT ${ZOO_PORT}
reconfigure ZOO_HOST ${ZOO_HOST}
reconfigure KAFKA_HOST ${KAFKA_HOST}
reconfigure ELK_HOST ${ELK_HOST}
reconfigure SERVICE_PORT ${SERVICE_PORT}
reconfigure APP_CORE_MACHINEKEY ${APP_CORE_MACHINEKEY}
reconfigure APP_CORE_BASE_DOMAIN ${APP_CORE_BASE_DOMAIN}
if [[ -n $EXTERNAL_PORT ]]; then
sed -i "s/8092:8092/${EXTERNAL_PORT}:8092/g" $BASE_DIR/appserver.yml
fi
docker-compose -f $BASE_DIR/appserver.yml up -d
}
start_installation () {
root_checking
get_os_info
check_os_info
if [ "$UPDATE" != "true" ]; then
check_ports
fi
if [ "$SKIP_HARDWARE_CHECK" != "true" ]; then
check_hardware
fi
if command_exists docker ; then
check_docker_version
service docker start
else
install_docker
fi
docker_login
download_files
set_jwt_secret
set_core_machinekey
create_network
if [ "$INSTALL_MYSQL_SERVER" == "true" ]; then
install_mysql_server
fi
if [ "$INSTALL_DOCUMENT_SERVER" == "true" ]; then
install_document_server
fi
if [ "$INSTALL_APPSERVER" == "true" ]; then
install_appserver
fi
echo ""
echo "Thank you for installing ONLYOFFICE Appserver."
echo "In case you have any questions contact us via http://support.onlyoffice.com or visit our forum at http://dev.onlyoffice.org"
echo ""
exit 0;
}
start_installation

View File

@ -49,7 +49,7 @@ if [ -z "${UPDATE}" ]; then
fi
if [ -z "${LOCAL_SCRIPTS}" ]; then
LOCAL_SCRIPTS="true";
LOCAL_SCRIPTS="false";
fi
cat > /etc/yum.repos.d/onlyoffice.repo <<END
@ -70,7 +70,8 @@ enabled=1
gpgkey=http://static.teamlab.info.s3.amazonaws.com/k8s
END
DOWNLOAD_URL_PREFIX="https://download.onlyoffice.com/install-appserver/install-RedHat"
#DOWNLOAD_URL_PREFIX="https://download.onlyoffice.com/install-appserver/install-RedHat"
DOWNLOAD_URL_PREFIX="https://raw.githubusercontent.com/ONLYOFFICE/${product}/develop/build/install/OneClickInstall/install-RedHat"
if [ "$LOCAL_SCRIPTS" = "true" ]; then
source install-RedHat/bootstrap.sh

View File

@ -32,7 +32,7 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
echo ${GIT_BRANCH} && \
git clone --depth 1 -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git ${SRC_PATH}
git clone --depth 1 --recurse-submodules -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git ${SRC_PATH}
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
cd ${SRC_PATH} && \
@ -45,6 +45,7 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
bash build-frontend.sh -sp ${SRC_PATH} && \
bash build-backend.sh -sp ${SRC_PATH} -ar "--disable-parallel" && \
bash publish-backend.sh -sp ${SRC_PATH} -bp ${BUILD_PATH} -ar "--disable-parallel" && \
cp -rf ${SRC_PATH}/products/ASC.Files/Server/DocStore ${BUILD_PATH}/products/ASC.Files/server/ && \
rm -rf ${SRC_PATH}/common/* && \
rm -rf ${SRC_PATH}/web/ASC.Web.Core/* && \
rm -rf ${SRC_PATH}/web/ASC.Web.Studio/* && \
@ -253,11 +254,11 @@ CMD ["ASC.Projects.dll", "ASC.Projects"]
## ASC.Socket.IO.Svc ##
FROM builder AS socket
WORKDIR ${BUILD_PATH}/services/socket/
WORKDIR ${BUILD_PATH}/services/socket.io.svc/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Socket.IO.Svc/service/ .
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Socket.IO/service/ ${BUILD_PATH}/www/ASC.Socket.IO/
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Socket.IO/service/ ${BUILD_PATH}/ASC.Socket.IO/
CMD ["ASC.Socket.IO.Svc.dll", "ASC.Socket.IO.Svc"]

View File

@ -149,7 +149,7 @@ services:
container_name: ${SOCKET_HOST}
expose:
- ${SERVICE_PORT}
- "9999"
- "9899"
onlyoffice-studio-notify:
<<: *x-service-base

View File

@ -47,7 +47,7 @@ App Server is a platform for building your own online office by connecting ONLYO
%prep
rm -rf %{_rpmdir}/%{_arch}/%{product}-*
rm -rf %{_rpmdir}/%{_arch}/%{name}-*
%setup -n %{sourcename}
%include build.spec

View File

@ -29,15 +29,18 @@ namespace ASC.Api.Core.Auth
UrlEncoder encoder,
ISystemClock clock,
SecurityContext securityContext,
UserManager userManager,
IServiceProvider serviceProvider) :
base(options, logger, encoder, clock)
{
SecurityContext = securityContext;
UserManager = userManager;
ServiceProvider = serviceProvider;
}
private SecurityContext SecurityContext { get; }
public IServiceProvider ServiceProvider { get; }
private UserManager UserManager { get; }
private IServiceProvider ServiceProvider { get; }
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
@ -70,21 +73,31 @@ namespace ASC.Api.Core.Auth
if (checkKeyResult == EmailValidationKeyProvider.ValidationResult.Ok)
{
Guid userId;
if (!SecurityContext.IsAuthenticated)
{
if (emailValidationKeyModel.UiD.HasValue && !emailValidationKeyModel.UiD.Equals(Guid.Empty))
{
SecurityContext.AuthenticateMe(emailValidationKeyModel.UiD.Value, claims);
userId = emailValidationKeyModel.UiD.Value;
}
else
{
SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem, claims);
if(emailValidationKeyModel.Type == Web.Studio.Utility.ConfirmType.EmailActivation)
{
userId = ASC.Core.Configuration.Constants.CoreSystem.ID;
}
else
{
userId = UserManager.GetUserByEmail(emailValidationKeyModel.Email).ID;
}
}
}
else
{
SecurityContext.AuthenticateMe(SecurityContext.CurrentAccount, claims);
userId = SecurityContext.CurrentAccount.ID;
}
SecurityContext.AuthenticateMe(userId, claims);
}
var result = checkKeyResult switch

View File

@ -25,16 +25,12 @@
</ItemGroup>
<ItemGroup>
<Compile Remove="Notify\AWSEmail.cs" />
<Compile Remove="Tests\Logging\SpecialFolderPathConverterTest.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ARSoft.Tools.NetStandard.DXSdata" Version="1.0.0" />
<PackageReference Include="Autofac" Version="6.0.0" />
<PackageReference Include="Autofac.Configuration" Version="6.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Confluent.Kafka" Version="1.4.3" />
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
<PackageReference Include="Grpc" Version="2.32.0" />
<PackageReference Include="Grpc.Tools" Version="2.32.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@ -42,17 +38,9 @@
<PackageReference Include="JWT" Version="6.1.4" />
<PackageReference Include="log4net" Version="2.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.2" />
<!-- <PackageReference Include="Microsoft.CodeQuality.Analyzers" Version="2.9.4">
<PrivateAssets>all</PrivateAssets>
@ -62,10 +50,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> -->
<PackageReference Include="MySql.Data" Version="8.0.23" />
<PackageReference Include="NLog" Version="4.7.5" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NVelocity" Version="1.2.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
</ItemGroup>
@ -77,7 +62,5 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Notify\" />
<Folder Include="Tests\Geolocation\" />
<Folder Include="Tests\Security\Authorizing\" />
</ItemGroup>
</Project>

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<system.data>
<DbProviderFactories>
<clear/>
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data"/>
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="db" connectionString="Server=teamlab;Database=teamlab_site;UserID=dev;Pwd=dev;pooling=True;Character Set=utf8" providerName="MySql.Data.MySqlClient" />
<add name="core" connectionString="Server=teamlab;Database=test;UserID=dev;Pwd=dev;pooling=True;Character Set=utf8" providerName="MySql.Data.MySqlClient" />
<add name="core.eu" connectionString="Server=teamlab;Database=test2;UserID=dev;Pwd=dev;pooling=True;Character Set=utf8" providerName="MySql.Data.MySqlClient" />
<add name="webstudio" connectionString="Server=teamlab;Database=test2;UserID=dev;Pwd=dev;pooling=True;Character Set=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
<log4net>
<addProperty>
<key>UNIX:LogDirectory</key>
<value>/var/log/onlyoffice/</value>
</addProperty>
<addProperty>
<key>WINDOWS:LogDirectory</key>
<value>..\..\Logs\</value>
</addProperty>
<logger name="ASC">
<appender-ref ref="File" />
<level value="ALL" />
</logger>
<appender name="File" type="ASC.Common.Logging.SelfCleaningAppender, ASC.Common">
<file type="log4net.Util.PatternString" >
<converter>
<name value="folder" />
<type value="ASC.Common.Logging.SpecialFolderPathConverter, ASC.Common" />
</converter>
<conversionPattern value="%folder{LogDirectory}Test" />
</file>
<encoding value="utf-8"/>
<staticLogFileName value="false" />
<preserveLogFileNameExtension value="true"/>
<rollingStyle value="Composite"/>
<datePattern value=".MM-dd.lo\g"/>
<maximumFileSize value="50MB"/>
<maxSizeRollBackups value="-1"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level [%thread] %logger - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>

View File

@ -1,165 +0,0 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
/*#if DEBUG
using ASC.Common.Data;
using NUnit.Framework;
using System;
using System.Data.SQLite;
namespace ASC.Common.Tests.Data
{
[TestFixture]
public class DataTest
{
private string dbId = Guid.NewGuid().ToString();
private string cs = "Data Source=dbtest.sqlite;Version=3";
public DataTest()
{
DbRegistry.RegisterDatabase(dbId, new SQLiteFactory(), cs);
}
[Test]
public void RegistryTest()
{
Assert.AreEqual(cs, DbRegistry.GetConnectionString(dbId));
Assert.IsTrue(DbRegistry.IsDatabaseRegistered(dbId));
Assert.IsNotNull(DbRegistry.CreateDbConnection(dbId));
}
[Test]
public void DbTransactionTest()
{
var dbManager = new DbManager(dbId);
dbManager.ExecuteNonQuery("create table if not exists a(c1 TEXT)", null);
var tx = dbManager.BeginTransaction();
dbManager.ExecuteNonQuery("insert into a(c1) values (?)", "s");
dbManager.ExecuteNonQuery("insert into a(c1) values (?)", "s2");
tx.Dispose();
dbManager.ExecuteNonQuery("insert into a(c1) values (?)", "s3");
}
[Test]
public void GroupConcatTest()
{
using (var connect = new SQLiteConnection("Data Source=:memory:"))
{
connect.Open();
var command = new SQLiteCommand("create table a(c1 TEXT)", connect);
command.ExecuteNonQuery();
command.CommandText = "insert into a values (NULL);insert into a values ('x');insert into a values ('y');";
command.ExecuteNonQuery();
command.CommandText = "select group_concat(c1, 4) from a";
var result1 = command.ExecuteScalar<string>();
Assert.AreEqual("x4y", result1);
command.CommandText = "select group_concat(c1) from a";
var result2 = command.ExecuteScalar<string>();
Assert.AreEqual("x,y", result2);
command.CommandText = "select group_concat(c1) from a where 1 = 0";
var result3 = command.ExecuteScalar<string>();
Assert.AreEqual(null, result3);
command.CommandText = "select group_concat(c1, NULL) from a";
var result4 = command.ExecuteScalar<string>();
Assert.AreEqual("x,y", result4);
command.CommandText = "select concat(1, NULL, '4566')";
var result5 = command.ExecuteScalar<string>();
Assert.AreEqual("14566", result5);
command.CommandText = "select concat()";
var result6 = command.ExecuteScalar<string>();
Assert.AreEqual(null, result6);
command.CommandText = "select concat_ws(',', 45, 77)";
var result7 = command.ExecuteScalar<string>();
Assert.AreEqual("45,77", result7);
}
}
[Test]
public void ExecuteScalarTest()
{
using (var connect = new SQLiteConnection("Data Source=:memory:"))
{
connect.Open();
var command = new SQLiteCommand("create table a(c1 TEXT, c2 DATETIME)", connect);
command.ExecuteNonQuery();
command.CommandText = "insert into a values (NULL, '2012-01-01 00:00:00');insert into a values ('x', NULL);insert into a values ('y', '2012-01-02 00:00:00');";
command.ExecuteNonQuery();
var value1 = command.ExecuteScalar<object>("select c1 from a where c1 = 'x'");
Assert.AreEqual("x", value1);
var value2 = command.ExecuteScalar<string>("select c1 from a where c1 = 'x'");
Assert.AreEqual("x", value2);
var value3 = command.ExecuteScalar<object>("select c1 from a where c1 = 'xxx'");
Assert.IsNull(value3);
var value4 = command.ExecuteScalar<DateTime>("select c2 from a where c1 = 'y'");
Assert.AreEqual(new DateTime(2012, 1, 2), value4);
var value5 = command.ExecuteScalar<DateTime>("select c2 from a where c1 = 'x'");
Assert.AreEqual(DateTime.MinValue, value5);
var value6 = command.ExecuteScalar<DateTime?>("select c2 from a where c1 = 'y'");
Assert.AreEqual(new DateTime(2012, 1, 2), value6);
var value7 = command.ExecuteScalar<DateTime?>("select c2 from a where c1 = 'x'");
Assert.IsNull(value7);
}
}
[Test]
public void ExecuteListWithParamsTest()
{
using (var connect = new SQLiteConnection("Data Source=:memory:"))
{
connect.Open();
connect.ExecuteList("select @p", new { p = "ok" });
}
}
[Test]
public void MySqlUnnamedParametersTest()
{
using (var db = new DbManager("core"))
{
db.ExecuteNonQuery("insert into _test(c2,c3,c4) values (?,?,?),(?,?,?)", "sdfaf", "eryrtyre", 4, "a", "aa", 5);
}
}
}
}
#endif*/

View File

@ -1,44 +0,0 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
#if DEBUG
using NUnit.Framework;
namespace ASC.Common.Tests.Data
{
[TestFixture]
public class MultiRegionalDbTest
{
//[Test]
//public void ExecuteListTest()
//{
// using var db = new MultiRegionalDbManager(null, null, "core");
// var r1 = db.ExecuteList("select 1");
// Assert.IsTrue(r1.Count > 1);
//}
}
}
#endif

View File

@ -48,20 +48,15 @@
<None Remove="protos\UserPhotoCacheItem.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.CloudFront" Version="3.5.3.16" />
<PackageReference Include="AWSSDK.Core" Version="3.5.1.25" />
<PackageReference Include="AWSSDK.S3" Version="3.5.3.3" />
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.5.0.27" />
<PackageReference Include="Grpc.Tools" Version="2.32.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MailKit" Version="2.5.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,3 +1,5 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("3ff04204-4b22-4899-bcde-07edfcbb5355")]
[assembly: InternalsVisibleTo("ASC.Core.Common.Tests")]

View File

@ -70,7 +70,7 @@ namespace ASC.Security.Cryptography
}
if (!TimeSpan.TryParse(configuration["auth:validinterval"], out var authValidInterval))
{
validInterval = TimeSpan.FromDays(7);
authValidInterval = TimeSpan.FromHours(1);
}
ValidEmailKeyInterval = validInterval;

View File

@ -5,8 +5,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>

View File

@ -16,8 +16,6 @@
<ItemGroup>
<ProjectReference Include="..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>

View File

@ -10,6 +10,10 @@
<NoWarn>1701;1702;NU1701</NoWarn>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Selectel\**" />
<EmbeddedResource Remove="Selectel\**" />
@ -25,9 +29,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.CloudFront" Version="3.5.3.16" />
<PackageReference Include="AWSSDK.S3" Version="3.5.3.3" />
<PackageReference Include="Google.Api.Gax" Version="3.2.0" />
<PackageReference Include="Google.Api.Gax.Rest" Version="3.2.0" />
<PackageReference Include="Google.Apis" Version="1.49.0" />
<PackageReference Include="Google.Apis.Auth" Version="1.49.0" />
<PackageReference Include="Google.Apis.Core" Version="1.49.0" />
<PackageReference Include="Google.Apis.Storage.v1" Version="1.49.0.2102" />
@ -36,12 +41,12 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.5" />
<PackageReference Include="openstack.net" Version="1.7.9" />
<PackageReference Include="Rackspace" Version="0.2.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>

View File

@ -14,6 +14,10 @@
<None Remove="callback.htm" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="callback.htm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@ -26,11 +30,9 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>

View File

@ -21,7 +21,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -18,7 +18,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>

View File

@ -1,6 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProductVersion>9.0.30729</ProductVersion>
<TargetFramework>net5.0</TargetFramework>
<AssemblyTitle>ASC.Notify.Textile</AssemblyTitle>
<Company>Ascensio System SIA</Company>
@ -22,7 +21,6 @@
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\ASC.Textile\ASC.Textile.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\NotifyTemplateResource.Designer.cs">
<DesignTime>True</DesignTime>
@ -30,7 +28,6 @@
<DependentUpon>NotifyTemplateResource.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\NotifyTemplateResource.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
@ -52,5 +49,4 @@
<DependentUpon>NotifyTemplateResource.resx</DependentUpon>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -30,7 +30,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.11" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\..\..\..\Program Files (x86)\Microsoft\Xamarin\NuGet\nunit\3.12.0\lib\netstandard2.0\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\..\..\..\Program Files (x86)\Microsoft\Xamarin\NuGet\nunit\3.12.0\lib\netstandard2.0\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Notify.Textile\ASC.Notify.Textile.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\..\..\..\Program Files (x86)\Microsoft\Xamarin\NuGet\nunit\3.12.0\lib\netstandard2.0\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -13,6 +13,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />

View File

@ -29,6 +29,7 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
<PackageReference Include="Grpc" Version="2.32.0" />
<PackageReference Include="Grpc.Tools" Version="2.32.0">
@ -37,14 +38,11 @@
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="MySql.Data" Version="8.0.23" />
<PackageReference Include="SharpZipLib" Version="1.3.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\products\ASC.Files\Core\ASC.Files.Core.csproj" />
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
<PackageReference Include="Grpc" Version="2.32.0" />
<PackageReference Include="Grpc.Tools" Version="2.32.0">
@ -29,11 +30,6 @@
<ItemGroup>
<ProjectReference Include="..\..\..\products\ASC.Files\Server\ASC.Files.csproj" />
<ProjectReference Include="..\..\..\products\ASC.People\Server\ASC.People.csproj" />
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>

View File

@ -5,14 +5,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>

View File

@ -13,6 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>

View File

@ -16,9 +16,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="WebSocketSharpNetStandart" Version="1.0.3-rc11" />
<PackageReference Include="WebSocketSharpNetStandart" Version="1.0.3-rc11" />
</ItemGroup>
<ItemGroup>

View File

@ -34,28 +34,31 @@ using ASC.Common;
using ASC.Common.Logging;
using ASC.Common.Utils;
using ASC.Core;
using ASC.Core.Notify.Signalr;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using WebSocketSharp;
namespace ASC.Socket.IO.Svc
{
[Singletone]
public class SocketServiceLauncher : IHostedService
{
//private const int PingInterval = 10000;
private const int PingInterval = 10000;
private Process Proc { get; set; }
private ProcessStartInfo StartInfo { get; set; }
//private WebSocket WebSocket { get; set; }
// private CancellationTokenSource CancellationTokenSource { get; set; }
private WebSocket WebSocket { get; set; }
private CancellationTokenSource CancellationTokenSource { get; set; }
private ILog Logger { get; set; }
private string LogDir { get; set; }
private IConfiguration Configuration { get; set; }
private ConfigurationExtension ConfigurationExtension { get; }
private CoreBaseSettings CoreBaseSettings { get; set; }
//private SignalrServiceClient SignalrServiceClient { get; set; }
private SignalrServiceClient SignalrServiceClient { get; set; }
private IHostEnvironment HostEnvironment { get; set; }
public SocketServiceLauncher(
@ -63,15 +66,15 @@ namespace ASC.Socket.IO.Svc
IConfiguration configuration,
ConfigurationExtension configurationExtension,
CoreBaseSettings coreBaseSettings,
//IOptionsSnapshot<SignalrServiceClient> signalrServiceClient,
IOptionsSnapshot<SignalrServiceClient> signalrServiceClient,
IHostEnvironment hostEnvironment)
{
Logger = options.CurrentValue;
//CancellationTokenSource = new CancellationTokenSource();
CancellationTokenSource = new CancellationTokenSource();
Configuration = configuration;
ConfigurationExtension = configurationExtension;
CoreBaseSettings = coreBaseSettings;
//SignalrServiceClient = signalrServiceClient.Value;
SignalrServiceClient = signalrServiceClient.Value;
HostEnvironment = hostEnvironment;
}
@ -117,7 +120,7 @@ namespace ASC.Socket.IO.Svc
public Task StopAsync(CancellationToken cancellationToken)
{
//StopPing();
StopPing();
StopNode();
return Task.CompletedTask;
}
@ -127,8 +130,8 @@ namespace ASC.Socket.IO.Svc
StopNode();
Proc = Process.Start(StartInfo);
//var task = new Task(StartPing, CancellationTokenSource.Token, TaskCreationOptions.LongRunning);
//task.Start(TaskScheduler.Default); TODO: not available in .net core
var task = new Task(StartPing, CancellationTokenSource.Token, TaskCreationOptions.LongRunning);
task.Start(TaskScheduler.Default);
}
private void StopNode()
@ -153,94 +156,94 @@ namespace ASC.Socket.IO.Svc
}
}
//private void StartPing()
//{
// Thread.Sleep(PingInterval);
private void StartPing()
{
Thread.Sleep(PingInterval);
// var error = false;
// WebSocket = new WebSocket(string.Format("ws://127.0.0.1:{0}/socket.io/?EIO=3&transport=websocket", StartInfo.EnvironmentVariables["port"]));
// WebSocket.SetCookie(new WebSocketSharp.Net.Cookie("authorization", SignalrServiceClient.CreateAuthToken()));
// WebSocket.EmitOnPing = true;
var error = false;
WebSocket = new WebSocket(string.Format("ws://127.0.0.1:{0}/socket.io/?EIO=3&transport=websocket", StartInfo.EnvironmentVariables["port"]));
WebSocket.SetCookie(new WebSocketSharp.Net.Cookie("authorization", SignalrServiceClient.CreateAuthToken()));
WebSocket.EmitOnPing = true;
// WebSocket.Log.Level = WebSocketSharp.LogLevel.Trace;
WebSocket.Log.Level = WebSocketSharp.LogLevel.Trace;
// WebSocket.Log.Output = (logData, filePath) =>
// {
// if (logData.Message.Contains("SocketException"))
// {
// error = true;
// }
WebSocket.Log.Output = (logData, filePath) =>
{
if (logData.Message.Contains("SocketException"))
{
error = true;
}
// Logger.Debug(logData.Message);
// };
Logger.Debug(logData.Message);
};
// WebSocket.OnOpen += (sender, e) =>
// {
// Logger.Info("Open");
// error = false;
WebSocket.OnOpen += (sender, e) =>
{
Logger.Info("Open");
error = false;
// Thread.Sleep(PingInterval);
Thread.Sleep(PingInterval);
// Task.Run(() =>
// {
// while (WebSocket.Ping())
// {
// Logger.Debug("Ping " + WebSocket.ReadyState);
// Thread.Sleep(PingInterval);
// }
// Logger.Debug("Reconnect" + WebSocket.ReadyState);
Task.Run(() =>
{
while (WebSocket.Ping())
{
Logger.Debug("Ping " + WebSocket.ReadyState);
Thread.Sleep(PingInterval);
}
Logger.Debug("Reconnect" + WebSocket.ReadyState);
// }, CancellationTokenSource.Token);
// };
}, CancellationTokenSource.Token);
};
// WebSocket.OnClose += (sender, e) =>
// {
// Logger.Info("Close");
// if (CancellationTokenSource.IsCancellationRequested) return;
WebSocket.OnClose += (sender, e) =>
{
Logger.Info("Close");
if (CancellationTokenSource.IsCancellationRequested) return;
// if (error)
// {
// Process.GetCurrentProcess().Kill();
// }
// else
// {
// WebSocket.Connect();
// }
if (error)
{
Process.GetCurrentProcess().Kill();
}
else
{
WebSocket.Connect();
}
// };
};
// WebSocket.OnMessage += (sender, e) =>
// {
// if (e.Data.Contains("error"))
// {
// Logger.Error("Auth error");
// CancellationTokenSource.Cancel();
// }
// };
WebSocket.OnMessage += (sender, e) =>
{
if (e.Data.Contains("error"))
{
Logger.Error("Auth error");
CancellationTokenSource.Cancel();
}
};
// WebSocket.OnError += (sender, e) =>
// {
// Logger.Error("Error", e.Exception);
// };
WebSocket.OnError += (sender, e) =>
{
Logger.Error("Error", e.Exception);
};
// WebSocket.Connect();
//}
WebSocket.Connect();
}
//private void StopPing()
//{
// try
// {
// CancellationTokenSource.Cancel();
// if (WebSocket.IsAlive)
// {
// WebSocket.Close();
// WebSocket = null;
// }
// }
// catch (Exception)
// {
// Logger.Error("Ping failed stop");
// }
//}
private void StopPing()
{
try
{
CancellationTokenSource.Cancel();
if (WebSocket.IsAlive)
{
WebSocket.Close();
WebSocket = null;
}
}
catch (Exception)
{
Logger.Error("Ping failed stop");
}
}
}
}

View File

@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="NLog" Version="4.7.5" />
@ -23,7 +24,6 @@
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
</ItemGroup>

View File

@ -11,13 +11,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>

View File

@ -13,6 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" />
@ -20,8 +21,6 @@
<ItemGroup>
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.FederatedLogin\ASC.FederatedLogin.csproj" />
</ItemGroup>

View File

@ -12,8 +12,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>
@ -23,6 +21,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>

View File

@ -26,7 +26,6 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using ASC.Common;

View File

@ -39,7 +39,7 @@ using Microsoft.Extensions.Options;
namespace ASC.Thumbnails.Svc
{
[Scope]
[Singletone]
public class ThumbnailsServiceLauncher : IHostedService
{
private ProcessStartInfo StartInfo { get; set; }

View File

@ -13,6 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>

View File

@ -146,7 +146,7 @@ namespace ASC.UrlShortener.Svc
}
}
startInfo.EnvironmentVariables.Add("logPath", Path.GetFullPath(CrossPlatform.PathCombine(hostEnvironment.ContentRootPath, log.LogDirectory, "web.urlshortener.log")));
startInfo.EnvironmentVariables.Add("logPath", CrossPlatform.PathCombine(log.LogDirectory, "web.urlshortener.log"));
return startInfo;
}

View File

@ -38,8 +38,13 @@ client.interceptors.response.use(
switch (true) {
case error.response.status === 401:
setWithCredentialsStatus(false);
window.location.href = loginURL;
request({
method: "post",
url: "/authentication/logout",
}).then((res) => {
setWithCredentialsStatus(false);
window.location.href = loginURL;
});
break;
case error.response.status === 402:
if (!window.location.pathname.includes("payments")) {

View File

@ -107,7 +107,7 @@ export function getListAdmins(filter = Filter.getDefault()) {
return request({
method: "get",
url: `/people/filter.json?${filterParams}`,
url: `/people/filter.json?isadministrator=true&${filterParams}`,
});
}

View File

@ -249,3 +249,69 @@ export function updateConsumerProps(newProps) {
return request(options);
}
export function getTfaSettings() {
return request({
method: "get",
url: `/settings/tfaapp`,
});
}
export function setTfaSettings(type) {
return request({
method: "put",
url: "/settings/tfaapp",
data: { type: type },
});
}
export function getTfaBackupCodes() {
return request({
method: "get",
url: "/settings/tfaappcodes",
});
}
export function getTfaNewBackupCodes() {
return request({
method: "put",
url: "/settings/tfaappnewcodes",
});
}
export function getTfaConfirmLink() {
return request({
method: "get",
url: "/settings/tfaapp/confirm",
});
}
export function unlinkTfaApp() {
return request({
method: "put",
url: "/settings/tfaappnewapp",
});
}
export function getTfaSecretKeyAndQR(confirmKey = null) {
const options = {
method: "get",
url: "/settings/tfaapp/setup",
};
if (confirmKey) options.headers = { confirm: confirmKey };
return request(options);
}
export function validateTfaCode(code) {
const data = {
code,
};
return request({
method: "post",
url: "/settings/tfaapp/validate",
data,
});
}

View File

@ -46,3 +46,17 @@ export function checkIsAuthenticated() {
return state;
});
}
export function loginWithTfaCode(userName, passwordHash, code) {
const data = {
userName,
passwordHash,
code,
};
return request({
method: "post",
url: `/authentication/${code}`,
data,
});
}

View File

@ -179,9 +179,11 @@ const ProfileViewLoader = ({ id, className, style, isEdit, ...rest }) => {
/>
</StyledBox1>
<RectangleLoader
className="rectangle-loader"
title={title}
width="100%"
height="80"
style={{ maxWidth: "420px" }}
borderRadius={borderRadius}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}

View File

@ -1,7 +1,7 @@
import styled from "styled-components";
const StyledTreeFolder = styled.div`
width: 100%;
width: 90%;
display: grid;
grid-template-columns: 8px 1fr;
grid-template-rows: 1fr;

View File

@ -11,6 +11,10 @@ const StyledArticleBody = styled.div`
flex-grow: 1;
height: 100%;
.custom-scrollbar {
width: calc(100% + 24px) !important;
}
@media ${tablet} {
height: calc(100% - 104px);
display: table;

View File

@ -1,6 +1,82 @@
// Override default variables before the import
$font-family-base: "Open Sans", sans-serif;
@font-face {
font-family: "Open Sans";
font-weight: 300;
font-style: normal;
src: url("../../public/fonts/light/open-sans-light.woff2") format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: 300;
font-style: italic;
src: url("../../public/fonts/light-italic/open-sans-light-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: normal;
font-style: normal;
src: url("../../public/fonts/regular/open-sans-regular.woff2") format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: normal;
font-style: italic;
src: url("../../public/fonts/italic/open-sans-italic.woff2") format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: 600;
font-style: normal;
src: url("../../public/fonts/semibold/open-sans-semibold.woff2")
format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: 600;
font-style: italic;
src: url("../../public/fonts/semibold-italic/open-sans-semibold-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: bold;
font-style: normal;
src: url("../../public/fonts/bold/open-sans-bold.woff2") format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: bold;
font-style: italic;
src: url("../../public/fonts/bold-italic/open-sans-bold-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: 800;
font-style: normal;
src: url("../../public/fonts/extra-bold/open-sans-extra-bold.woff2")
format("woff2");
}
@font-face {
font-family: "Open Sans";
font-weight: 800;
font-style: italic;
src: url("../../public/fonts/extra-bold-italic/open-sans-extra-bold-italic.woff2")
format("woff2");
}
html,
body {
height: 100%;
@ -19,7 +95,6 @@ body {
body {
margin: 0;
overflow: hidden;
}
body.loading * {

View File

@ -5,6 +5,7 @@ import history from "../history";
import ModuleStore from "./ModuleStore";
import SettingsStore from "./SettingsStore";
import UserStore from "./UserStore";
import TfaStore from "./TfaStore";
import { logout as logoutDesktop, desktopConstants } from "../desktop";
import { combineUrl, isAdmin } from "../utils";
import isEmpty from "lodash/isEmpty";
@ -15,6 +16,7 @@ class AuthStore {
userStore = null;
moduleStore = null;
settingsStore = null;
tfaStore = null;
isLoading = false;
isAuthenticated = false;
@ -26,6 +28,7 @@ class AuthStore {
this.userStore = new UserStore();
this.moduleStore = new ModuleStore();
this.settingsStore = new SettingsStore();
this.tfaStore = new TfaStore();
makeAutoObservable(this);
}
@ -153,18 +156,33 @@ class AuthStore {
try {
const response = await api.user.login(user, hash);
if (!response || !response.token) throw "Empty API response";
if (!response || (!response.token && !response.tfa))
throw response.error.message;
if (response.tfa && response.confirmUrl) {
const url = response.confirmUrl.replace(window.location.origin, "");
return Promise.resolve({ url, user, hash });
}
setWithCredentialsStatus(true);
await this.init();
return Promise.resolve(true);
return Promise.resolve({ url: this.settingsStore.defaultPage });
} catch (e) {
return Promise.reject(e);
}
};
loginWithCode = async (userName, passwordHash, code) => {
await this.tfaStore.loginWithCode(userName, passwordHash, code);
setWithCredentialsStatus(true);
await this.init();
return Promise.resolve(this.settingsStore.defaultPage);
};
thirdPartyLogin = async (SerializedProfile) => {
try {
const response = await api.user.thirdPartyLogin(SerializedProfile);

View File

@ -0,0 +1,72 @@
import { makeAutoObservable } from "mobx";
import api from "../api";
import history from "../history";
class TfaStore {
tfaSettings = null;
backupCodes = [];
tfaAndroidAppUrl =
"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2";
tfaIosAppUrl = "https://apps.apple.com/app/google-authenticator/id388497605";
tfaWinAppUrl =
"https://www.microsoft.com/ru-ru/p/authenticator/9wzdncrfj3rj?rtc=1&activetab=pivot:overviewtab";
constructor() {
makeAutoObservable(this);
}
getTfaType = async () => {
const res = await api.settings.getTfaSettings();
const sms = res[0].enabled;
const app = res[1].enabled;
const type = sms ? "sms" : app ? "app" : "none";
this.tfaSettings = type;
return type;
};
getTfaSettings = async () => {
return await api.settings.getTfaSettings();
};
setTfaSettings = async (type) => {
return await api.settings.setTfaSettings(type);
};
setBackupCodes = (codes) => {
this.backupCodes = codes;
};
getTfaConfirmLink = async (res) => {
if (res) {
return await api.settings.getTfaConfirmLink();
}
};
getSecretKeyAndQR = async (confirmKey) => {
return api.settings.getTfaSecretKeyAndQR(confirmKey);
};
loginWithCode = async (userName, passwordHash, code) => {
return api.user.loginWithTfaCode(userName, passwordHash, code);
};
loginWithCodeAndCookie = async (code) => {
return api.settings.validateTfaCode(code);
};
getBackupCodes = async () => {
return api.settings.getTfaBackupCodes();
};
getNewBackupCodes = async () => {
return api.settings.getTfaNewBackupCodes();
};
unlinkApp = async () => {
return api.settings.unlinkTfaApp();
};
}
export default TfaStore;

View File

@ -93,14 +93,23 @@ export function updateTempContent(isAuth = false) {
}
}
let timer = null;
export function hideLoader() {
if (isMobile) return;
if (timer) {
clearTimeout(timer);
timer = null;
}
TopLoaderService.end();
}
export function showLoader() {
if (isMobile) return;
TopLoaderService.start();
hideLoader();
timer = setTimeout(() => TopLoaderService.start(), 500);
}
export { withLayoutSize } from "./withLayoutSize";

View File

@ -135,7 +135,7 @@ class ComboBox extends React.Component {
/>
{displayType !== "toggle" && (
<DropDown
className="dropdown-container"
className="dropdown-container not-selectable"
directionX={directionX}
directionY={directionY}
manualY="102%"

View File

@ -105,7 +105,7 @@ class ContextMenuSub extends Component {
return (
<li
key={"separator_" + index}
className="p-menu-separator"
className="p-menu-separator not-selectable"
role="separator"
></li>
);
@ -133,7 +133,7 @@ class ContextMenuSub extends Component {
{ "p-menuitem-active": active },
item.className
);
const linkClassName = classNames("p-menuitem-link", {
const linkClassName = classNames("p-menuitem-link", "not-selectable", {
"p-disabled": item.disabled,
});
const iconClassName = classNames("p-menuitem-icon", {
@ -148,7 +148,7 @@ class ContextMenuSub extends Component {
></ReactSVG>
);
const label = item.label && (
<span className="p-menuitem-text">{item.label}</span>
<span className="p-menuitem-text not-selectable">{item.label}</span>
);
const submenuIcon = item.items && (
<ArrowIcon className={submenuIconClassName} />
@ -235,7 +235,7 @@ class ContextMenuSub extends Component {
unmountOnExit={true}
onEnter={this.onEnter}
>
<ul ref={this.submenuRef} className={className}>
<ul ref={this.submenuRef} className={`${className} not-selectable`}>
{submenu}
</ul>
</CSSTransition>

View File

@ -123,6 +123,7 @@ class HelpButton extends React.Component {
className,
dataTip,
style,
tooltipColor,
} = this.props;
return (
@ -151,6 +152,7 @@ class HelpButton extends React.Component {
afterShow={this.afterShow}
afterHide={this.afterHide}
getContent={getContent}
color={tooltipColor}
/>
) : (
<Tooltip
@ -162,6 +164,7 @@ class HelpButton extends React.Component {
offsetLeft={offsetLeft}
afterShow={this.afterShow}
afterHide={this.afterHide}
color={tooltipColor}
>
{tooltipContent}
</Tooltip>
@ -220,10 +223,11 @@ HelpButton.propTypes = {
/** Accepts id */
id: PropTypes.string,
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
tooltipColor: PropTypes.string,
};
HelpButton.defaultProps = {
iconName: "./static/images/question.react.svg",
iconName: "/static/images/question.react.svg",
place: "top",
offsetRight: 120,
offsetLeft: 0,
@ -233,6 +237,7 @@ HelpButton.defaultProps = {
displayType: "auto",
className: "icon-button",
color: "#A3A9AE",
tooltipColor: "#fff",
};
export default HelpButton;

View File

@ -122,6 +122,7 @@ class InputBlock extends React.Component {
//iconNames.includes(iconName) && (
<div className="append">
<StyledIconBlock
className="input-block-icon"
isDisabled={isDisabled}
onClick={this.onIconClick}
isClickable={typeof onIconClick === "function"}

View File

@ -69,6 +69,7 @@
"dependencies": {
"email-addresses": "^3.1.0",
"fast-deep-equal": "^3.1.3",
"framer-motion": "^4.1.17",
"html-to-react": "^1.4.5",
"lodash": "4.17.21",
"moment": "^2.29.1",

View File

@ -426,7 +426,7 @@ class PasswordInput extends React.Component {
showCopyLink,
} = this.props;
const { copyLabel, disableCopyAction } = this.state;
const { copyLabel, disableCopyAction, type } = this.state;
return (
<StyledInput

View File

@ -20,6 +20,7 @@ const StyledInput = styled(SimpleInput)`
line-height: ${(props) => props.theme.passwordInput.lineHeight};
flex-direction: row;
flex-wrap: wrap;
position: relative;
.input-relative {
svg {
@ -36,8 +37,16 @@ const StyledInput = styled(SimpleInput)`
flex-wrap: wrap;
}
.input-block-icon {
height: 42px;
}
.append {
padding-right: 8px;
position: absolute;
right: -16px;
top: 50%;
transform: translate(-50%, -50%);
}
.prepend-children {

View File

@ -71,11 +71,14 @@ class Row extends React.Component {
this.cm.current.show(e);
};
const { onRowClick, ...rest } = this.props;
return (
<StyledRow ref={this.row} {...this.props} onContextMenu={onContextMenu}>
<StyledRow ref={this.row} {...rest} onContextMenu={onContextMenu}>
{renderCheckbox && (
<StyledCheckbox>
<StyledCheckbox className="not-selectable">
<Checkbox
className="checkbox"
isChecked={checked}
isIndeterminate={indeterminate}
onChange={changeCheckbox}
@ -83,9 +86,13 @@ class Row extends React.Component {
</StyledCheckbox>
)}
{renderElement && (
<StyledElement className="styled-element">{element}</StyledElement>
<StyledElement onClick={onRowClick} className="styled-element">
{element}
</StyledElement>
)}
<StyledContent className="row_content">{children}</StyledContent>
<StyledContent onClick={onRowClick} className="row_content">
{children}
</StyledContent>
<StyledOptionButton
className="row_context-menu-wrapper"
spacerWidth={contextButtonSpacerWidth}
@ -137,6 +144,8 @@ Row.propTypes = {
indeterminate: PropTypes.bool,
/** when selecting row element. Returns data value. */
onSelect: PropTypes.func,
/** On click anywhere in the row, except the checkbox and context menu */
onRowClick: PropTypes.func,
rowContextClick: PropTypes.func,
/** Accepts css style */
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),

View File

@ -37,6 +37,14 @@ StyledContent.defaultProps = { theme: Base };
const StyledCheckbox = styled.div`
flex: 0 0 16px;
.checkbox {
padding: 7px 0;
@media ${tablet} {
padding: 10px 0;
}
}
`;
const StyledElement = styled.div`

View File

@ -51,7 +51,7 @@ const Base = {
color: black,
backgroundColor: white,
fontFamily: "Open Sans, sans-serif, Arial",
fontSize: "30px",
fontSize: "13px",
text: {
color: black,

View File

@ -52,6 +52,7 @@ const Dark = {
color: whiteSolitude,
backgroundColor: blueCharcoal,
fontFamily: "Open Sans, sans-serif, Arial",
fontSize: "13px",
text: {
color: white,

View File

@ -1,19 +1,54 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { ToggleButtonContainer, HiddenInput } from "./styled-toggle-button";
import { ToggleButtonIcon, ToggleButtonCheckedIcon } from "./svg";
import Text from "../text";
import globalColors from "../utils/globalColors";
import { motion } from "framer-motion";
import Base from "../themes/base";
const ToggleIcon = ({ isChecked }) => {
const ToggleIcon = ({ isChecked, isLoading }) => {
return (
<>
{isChecked ? (
<ToggleButtonCheckedIcon className="toggle-button" />
) : (
<ToggleButtonIcon className="toggle-button" />
)}
</>
<motion.svg
animate={[
isChecked ? "checked" : "notChecked",
isLoading ? "isLoading" : "",
]}
width="28"
height="16"
viewBox="0 0 28 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<motion.rect
width="28"
height="16"
rx="8"
variants={{
checked: { fill: Base.toggleButton.fillColor },
notChecked: { fill: Base.toggleButton.fillColorOff },
}}
/>
<motion.circle
fill-rule="evenodd"
clip-rule="evenodd"
cy="8"
fill="white"
variants={{
isLoading: {
r: [5, 6, 6],
transition: {
r: {
yoyo: Infinity,
duration: 0.6,
ease: "easeOut",
},
},
},
checked: { cx: 20, r: 6 },
notChecked: { cx: 8, r: 6 },
}}
/>
</motion.svg>
);
};
@ -32,7 +67,15 @@ class ToggleButton extends Component {
}
render() {
const { isDisabled, label, onChange, id, className, style } = this.props;
const {
isDisabled,
label,
onChange,
id,
className,
style,
isLoading,
} = this.props;
const { gray } = globalColors;
const colorProps = isDisabled ? { color: gray } : {};
@ -51,7 +94,7 @@ class ToggleButton extends Component {
disabled={isDisabled}
onChange={onChange}
/>
<ToggleIcon isChecked={this.state.checked} />
<ToggleIcon isChecked={this.state.checked} isLoading={isLoading} />
{label && (
<Text className="toggle-button-text" as="span" {...colorProps}>
{label}

View File

@ -1,2 +0,0 @@
export { default as ToggleButtonIcon } from "./toggle.button.react.svg";
export { default as ToggleButtonCheckedIcon } from "./toggle.button.checked.react.svg";

View File

@ -1,4 +0,0 @@
<svg width="28" height="16" viewBox="0 0 28 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="28" height="16" rx="8" fill="#2DA7DB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 14C23.3137 14 26 11.3137 26 8C26 4.68629 23.3137 2 20 2C16.6863 2 14 4.68629 14 8C14 11.3137 16.6863 14 20 14Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 336 B

View File

@ -1,4 +0,0 @@
<svg width="28" height="16" viewBox="0 0 28 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="28" height="16" rx="8" fill="#A3A9AE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 330 B

View File

@ -39,10 +39,11 @@ class Tooltip extends Component {
reference,
className,
style,
color,
} = this.props;
return (
<StyledTooltip className={className} style={style}>
<StyledTooltip className={className} style={style} color={color}>
<ReactTooltip
id={id}
ref={reference}
@ -98,6 +99,7 @@ Tooltip.propTypes = {
className: PropTypes.string,
/** Accepts css style */
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
color: PropTypes.string,
};
Tooltip.defaultProps = {
@ -107,6 +109,7 @@ Tooltip.defaultProps = {
offsetRight: 0,
offsetBottom: 0,
offsetLeft: 0,
color: "#fff",
};
export default Tooltip;

View File

@ -3,6 +3,7 @@ import Base from "../themes/base";
const StyledTooltip = styled.div`
.__react_component_tooltip {
background-color: ${(props) => props.color} !important;
border-radius: ${(props) => props.theme.tooltip.borderRadius};
-moz-border-radius: ${(props) => props.theme.tooltip.borderRadius};
-webkit-border-radius: ${(props) => props.theme.tooltip.borderRadius};
@ -21,6 +22,22 @@ const StyledTooltip = styled.div`
border: ${(props) => props.theme.tooltip.after.border};
}
}
.__react_component_tooltip.place-left::after {
border-left: 6px solid ${(props) => props.color} !important;
}
.__react_component_tooltip.place-right::after {
border-right: 6px solid ${(props) => props.color} !important;
}
.__react_component_tooltip.place-top::after {
border-top: 6px solid ${(props) => props.color} !important;
}
.__react_component_tooltip.place-bottom::after {
border-bottom: 6px solid ${(props) => props.color} !important;
}
`;
StyledTooltip.defaultProps = {

Some files were not shown because too many files have changed in this diff Show More