Merge branch 'develop' into feature/new-settings-description

This commit is contained in:
Nikita Gopienko 2023-09-01 16:47:52 +03:00
commit b0cbe39aa6
128 changed files with 8189 additions and 261 deletions

View File

@ -31,6 +31,7 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build 4testing
run: |
cd .${DOCKER_PATH}

View File

@ -63,7 +63,10 @@ jobs:
wget https://packages.microsoft.com/config/$(lsb_release -is | \
tr [:upper:] [:lower:])/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
wget -O - https://deb.nodesource.com/setup_18.x | sudo -E bash -
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/nodesource.gpg --import
chmod 644 /usr/share/keyrings/nodesource.gpg
apt-get -y update
sudo apt install -y dotnet-sdk-7.0 yarn nodejs dh-make rename dpkg-sig lintian
sudo npm install -g json
echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_OUTPUT
@ -133,7 +136,10 @@ jobs:
wget https://packages.microsoft.com/config/$(lsb_release -is | \
tr [:upper:] [:lower:])/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
wget -O - https://deb.nodesource.com/setup_18.x | sudo -E bash -
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/nodesource.gpg --import
chmod 644 /usr/share/keyrings/nodesource.gpg
apt-get -y update
sudo apt install -y dotnet-sdk-7.0 yarn nodejs dh-make rename python3-pip python3-rpm
sudo npm install -g json
sudo pip install rpmlint

View File

@ -31,6 +31,7 @@ if [ "$UPDATE" = "true" ] && [ "$DOCUMENT_SERVER_INSTALLED" = "true" ]; then
RECONFIGURE_PRODUCT="true"
else
systemctl is-active openresty | grep -q "^active" && systemctl stop openresty
apt-get install -y --only-upgrade ${ds_pkg_name};
fi
fi
@ -61,6 +62,8 @@ if [ "$DOCUMENT_SERVER_INSTALLED" = "false" ]; then
echo ${package_sysname}-documentserver $DS_COMMON_NAME/jwt-secret select ${DS_JWT_SECRET} | sudo debconf-set-selections
echo ${package_sysname}-documentserver $DS_COMMON_NAME/jwt-header select ${DS_JWT_HEADER} | sudo debconf-set-selections
systemctl is-active openresty | grep -q "^active" && systemctl stop openresty
if [ "$INSTALLATION_TYPE" = "COMMUNITY" ]; then
apt-get install -yq ${package_sysname}-documentserver
else

View File

@ -40,7 +40,9 @@ chmod 644 /usr/share/keyrings/elastic-${ELASTIC_DIST}.x.gpg
# add nodejs repo
[[ "$DISTRIB_CODENAME" =~ ^(bionic|stretch)$ ]] && NODE_VERSION="16" || NODE_VERSION="18"
curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash -
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/nodesource.gpg --import
chmod 644 /usr/share/keyrings/nodesource.gpg
#add dotnet repo
if [ "$DIST" = "debian" ] && [ "$DISTRIB_CODENAME" = "stretch" ]; then
@ -103,10 +105,7 @@ echo "deb [signed-by=/usr/share/keyrings/openresty.gpg] http://openresty.org/pac
chmod 644 /usr/share/keyrings/openresty.gpg
#Temporary fix for missing openresty repository for debian bookworm
[ "$DISTRIB_CODENAME" = "bookworm" ] && sed -i "s/$DISTRIB_CODENAME/bullseye/g" /etc/apt/sources.list.d/openresty.list
if systemctl is-active nginx | grep -q "active"; then
systemctl disable nginx && systemctl stop nginx
fi
systemctl is-active nginx | grep -q "^active" && systemctl stop nginx
# setup msttcorefonts
echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections

View File

@ -867,6 +867,26 @@ read_continue_installation () {
}
domain_check () {
if ! command_exists dig; then
install_service dig dnsutils
fi
if ! command_exists ping; then
if command_exists apt-get; then
install_service ping iputils-ping
elif command_exists yum; then
install_service ping iputils
fi
fi
if ! command_exists ip; then
if command_exists apt-get; then
install_service ip iproute2
elif command_exists yum; then
install_service ip iproute
fi
fi
DOMAINS=$(dig +short -x $(curl -s ifconfig.me) | sed 's/\.$//')
if [[ -n "$DOMAINS" ]]; then
@ -875,7 +895,7 @@ domain_check () {
if [[ -n "$IP_ADDRESS" && "$IP_ADDRESS" =~ ^(10\.|127\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.) ]]; then
LOCAL_RESOLVED_DOMAINS+="$DOMAIN"
elif [[ -n "$IP_ADDRESS" ]]; then
APP_URL_PORTAL=${APP_URL_PORTAL-:"http://${DOMAIN}:${EXTERNAL_PORT}"}
APP_URL_PORTAL=${APP_URL_PORTAL:-"http://${DOMAIN}:${EXTERNAL_PORT}"}
fi
done <<< "$DOMAINS"
fi
@ -1262,6 +1282,8 @@ install_elasticsearch () {
install_product () {
DOCKER_TAG="${DOCKER_TAG:-$(get_available_version ${IMAGE_NAME})}"
reconfigure DOCKER_TAG ${DOCKER_TAG}
[ "${UPDATE}" = "true" ] && LOCAL_CONTAINER_TAG="$(docker inspect --format='{{index .Config.Image}}' ${CONTAINER_NAME} | awk -F':' '{print $2}')"
if [ "${UPDATE}" = "true" ] && [ "${LOCAL_CONTAINER_TAG}" != "${DOCKER_TAG}" ]; then
@ -1274,7 +1296,6 @@ install_product () {
reconfigure APP_CORE_MACHINEKEY ${APP_CORE_MACHINEKEY}
reconfigure APP_CORE_BASE_DOMAIN ${APP_CORE_BASE_DOMAIN}
reconfigure APP_URL_PORTAL "${APP_URL_PORTAL:-"http://${PACKAGE_SYSNAME}-proxy:8092"}"
reconfigure DOCKER_TAG ${DOCKER_TAG}
[[ -n $EXTERNAL_PORT ]] && sed -i "s/8092:8092/${EXTERNAL_PORT}:8092/g" $BASE_DIR/${PRODUCT}.yml

View File

@ -62,7 +62,7 @@ if [ "${MYSQL_FIRST_TIME_INSTALL}" = "true" ]; then
MYSQL="mysql --connect-expired-password -u$MYSQL_SERVER_USER -D mysql";
else
MYSQL="mysql --connect-expired-password -u$MYSQL_SERVER_USER -p${MYSQL_TEMPORARY_ROOT_PASS} -D mysql";
MYSQL_ROOT_PASS=$(echo $MYSQL_TEMPORARY_ROOT_PASS | sed -e 's/;/%/g' -e 's/=/%/g');
MYSQL_ROOT_PASS=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 12);
fi
MYSQL_AUTHENTICATION_PLUGIN=$($MYSQL -e "SHOW VARIABLES LIKE 'default_authentication_plugin';" -s | awk '{print $2}')

View File

@ -60,8 +60,7 @@ curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.
#add nodejs repo
[ "$REV" = "7" ] && NODE_VERSION="16" || NODE_VERSION="18"
curl -sL https://rpm.nodesource.com/setup_${NODE_VERSION}.x | sed 's/centos|/'$DIST'|/g' | sudo bash - || true
rpm --import http://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL
yum install -y https://rpm.nodesource.com/pub_${NODE_VERSION}.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm
#add dotnet repo
if [ $REV = "7" ] || [[ $DIST != "redhat" && $REV = "8" ]]; then
@ -95,10 +94,7 @@ END
rpm --import https://openresty.org/package/pubkey.gpg
OPENRESTY_REPO_FILE=$( [[ "$REV" -ge 9 ]] && echo "openresty2.repo" || echo "openresty.repo" )
curl -o /etc/yum.repos.d/openresty.repo "https://openresty.org/package/centos/${OPENRESTY_REPO_FILE}"
if systemctl is-active nginx | grep -q "active"; then
systemctl disable nginx && systemctl stop nginx
fi
systemctl is-active nginx | grep -q "^active" && systemctl stop nginx
${package_manager} -y install epel-release \
python3 \

View File

@ -56,20 +56,6 @@ while [ "$1" != "" ]; do
fi
;;
-dsh | --docshost )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_HOST=$2
shift
fi
;;
-dsp | --docsport )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_PORT=$2
shift
fi
;;
-ess | --elasticsheme )
if [ "$2" != "" ]; then
ELK_SHEME=$2
@ -175,14 +161,34 @@ while [ "$1" != "" ]; do
fi
;;
-js | --jwtsecret )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_JWT_SECRET=$2
shift
fi
;;
-jh | --jwtheader )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_JWT_HEADER=$2
shift
fi
;;
-docsurl | --docsurl )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_URL_EXTERNAL=$2
shift
fi
;;
-? | -h | --help )
echo " Usage: bash ${PRODUCT}-configuration [PARAMETER] [[PARAMETER], ...]"
echo
echo " Parameters:"
echo " -ash, --appshost ${PRODUCT} ip"
echo " -asp, --appsport ${PRODUCT} port (default 80)"
echo " -dsh, --docshost document server ip"
echo " -dsp, --docsport document server port (default 8083)"
echo " -docsurl, --docsurl $PACKAGE_SYSNAME docs server address (example http://$PACKAGE_SYSNAME-docs-address:8083)"
echo " -esh, --elastichost elasticsearch ip"
echo " -esp, --elasticport elasticsearch port (default 9200)"
echo " -rdh, --redishost redis ip"
@ -195,6 +201,8 @@ while [ "$1" != "" ]; do
echo " -mysqld, --mysqldatabase ${PRODUCT} database name"
echo " -mysqlu, --mysqluser ${PRODUCT} database user"
echo " -mysqlp, --mysqlpassword ${PRODUCT} database password"
echo " -js, --jwtsecret defines the secret key to validate the JWT in the request"
echo " -jh. --jwtheader defines the http header that will be used to send the JWT"
echo " -mk, --machinekey setting for core.machinekey"
echo " -e, --environment environment (default 'production')"
echo " -?, -h, --help this help"
@ -309,7 +317,7 @@ establish_mysql_conn(){
command -v mysql >/dev/null 2>&1 || { echo "MySQL client not found"; exit 1; }
MYSQL="mysql -h$DB_HOST -u$DB_USER"
MYSQL="mysql -P$DB_PORT -h$DB_HOST -u$DB_USER"
if [ -n "$DB_PWD" ]; then
MYSQL="$MYSQL -p$DB_PWD"
fi
@ -321,6 +329,10 @@ establish_mysql_conn(){
$MYSQL -e ";" >/dev/null 2>&1 || { echo "FAILURE"; exit 1; }
fi
if $PACKAGE_MANAGER mysql-server >/dev/null 2>&1 || $PACKAGE_MANAGER mysql-community-server >/dev/null 2>&1; then
change_mysql_config
fi
#Save db settings in .json
CONNECTION_STRING="Server=$DB_HOST;Port=$DB_PORT;Database=$DB_NAME;User ID=$DB_USER;Password=$DB_PWD;Pooling=true; \
Character Set=utf8; AutoEnlist=false; SSL Mode=none;AllowPublicKeyRetrieval=true;Connection Timeout=30;Maximum Pool Size=300"
@ -328,8 +340,7 @@ Character Set=utf8; AutoEnlist=false; SSL Mode=none;AllowPublicKeyRetrieval=true
save_undefined_param "${USER_CONF}" "ConnectionStrings.default.connectionString" "${CONNECTION_STRING}"
save_undefined_param "${APP_DIR}/apisystem.${ENVIRONMENT}.json" "ConnectionStrings.default.connectionString" "${CONNECTION_STRING}"
sed "s_\(\"ConnectionString\":\).*_\1 \"${CONNECTION_STRING//_/\\_}\"_" -i $PRODUCT_DIR/services/ASC.Migration.Runner/appsettings.runner.json
change_mysql_config
sed "s&\(\"ConnectionString\":\).*&\1 \"$(printf "%q" "${CONNECTION_STRING}")\"&" -i $PRODUCT_DIR/services/ASC.Migration.Runner/appsettings.runner.json
#Enable database migration
save_undefined_param "${USER_CONF}" "migration.enabled" "true"
@ -519,25 +530,42 @@ setup_openresty(){
echo "OK"
}
# Function gets Document server host and port using regular expression, we need it to check connection
parse_external_docs_url () {
if [[ $DOCUMENT_SERVER_URL_EXTERNAL =~ ^(https?://)?([^:/]+)(:([0-9]+))?(/.*)?$ ]]; then
DOCUMENT_SERVER_PORT="${BASH_REMATCH[4]:-80}"
DOCUMENT_SERVER_HOST="${BASH_REMATCH[2]}"
[[ -n ${BASH_REMATCH[1]} ]] || DOCUMENT_SERVER_URL_EXTERNAL="http://$DOCUMENT_SERVER_HOST:$DOCUMENT_SERVER_PORT"
fi
}
setup_docs() {
echo -n "Configuring docs... "
local DS_CONF_DIR="/etc/${PACKAGE_SYSNAME}/documentserver"
local DOCUMENT_SERVER_HOST=${DOCUMENT_SERVER_HOST:-localhost}
local DOCUMENT_SERVER_PORT=${DOCUMENT_SERVER_PORT:-$(grep -oP '(?<=:)\d+(?=\s)' ${DS_CONF_DIR}/nginx/ds.conf)}
if [ $1 == "LOCAL_DOCS_SERVER" ]; then
local DS_CONF_DIR="/etc/${PACKAGE_SYSNAME}/documentserver"
local DOCUMENT_SERVER_PORT=$(grep -oP '(?<=:)\d+(?=\s)' ${DS_CONF_DIR}/nginx/ds.conf)
local DOCUMENT_SERVER_JWT_SECRET=${DOCUMENT_SERVER_JWT_SECRET:-$(json -f ${DS_CONF_DIR}/local.json services.CoAuthoring.secret.inbox.string)}
local DOCUMENT_SERVER_JWT_HEADER=${DOCUMENT_SERVER_JWT_HEADER:-$(json -f ${DS_CONF_DIR}/local.json services.CoAuthoring.token.inbox.header)}
$JSON ${DS_CONF_DIR}/local.json -e "this.rabbitmq = { 'url': 'amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@${RABBITMQ_HOST}:${RABBITMQ_PORT}' }" >/dev/null 2>&1
$JSON ${DS_CONF_DIR}/local.json -e "this.services.CoAuthoring.redis = { 'host': '$REDIS_HOST' }" >/dev/null 2>&1
sed 's/\(listen .*:\)\([0-9]\{2,5\}\b\)\( default_server\)\?\(;\)/\1'${DOCUMENT_SERVER_PORT}'\3\4/' -i ${DS_CONF_DIR}/nginx/ds.conf
elif [ $1 == "EXTERNAL_DOCS_SERVER" ]; then
local APP_HOST=$(curl -s ifconfig.me)
local EXTERNAL_DOCS_FLAG="rewrite"
fi
#Changing the Docs port in nginx conf
sed 's/\(listen .*:\)\([0-9]\{2,5\}\b\)\( default_server\)\?\(;\)/\1'${DOCUMENT_SERVER_PORT}'\3\4/' -i ${DS_CONF_DIR}/nginx/ds.conf
sed "0,/proxy_pass .*;/{s/proxy_pass .*;/proxy_pass http:\/\/${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT};/}" -i ${NGINX_DIR}/conf.d/${PACKAGE_SYSNAME}.conf
local DOCUMENT_SERVER_JWT_SECRET=$(json -f ${DS_CONF_DIR}/local.json services.CoAuthoring.secret.inbox.string)
local DOCUMENT_SERVER_JWT_HEADER=$(json -f ${DS_CONF_DIR}/local.json services.CoAuthoring.token.inbox.header)
sed "0,/proxy_pass .*;/{s#proxy_pass .*;#proxy_pass ${DOCUMENT_SERVER_URL_EXTERNAL:-http://$APP_HOST:$DOCUMENT_SERVER_PORT};#}" -i ${NGINX_DIR}/conf.d/${PACKAGE_SYSNAME}.conf
#Save Docs address and JWT in .json
save_undefined_param "${USER_CONF}" "files.docservice.secret.value" "${DOCUMENT_SERVER_JWT_SECRET}"
save_undefined_param "${USER_CONF}" "files.docservice.secret.header" "${DOCUMENT_SERVER_JWT_HEADER} "
save_undefined_param "${USER_CONF}" "files.docservice.url.public" "/ds-vpath/"
save_undefined_param "${USER_CONF}" "files.docservice.url.internal" "http://${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT}"
save_undefined_param "${USER_CONF}" "files.docservice.url.portal" "http://${APP_HOST}:${APP_PORT}"
save_undefined_param "${USER_CONF}" "files.docservice.secret.value" "${DOCUMENT_SERVER_JWT_SECRET}" "$EXTERNAL_DOCS_FLAG"
save_undefined_param "${USER_CONF}" "files.docservice.secret.header" "${DOCUMENT_SERVER_JWT_HEADER:-"AuthorizationJwt"}" "$EXTERNAL_DOCS_FLAG"
save_undefined_param "${USER_CONF}" "files.docservice.url.public" "${DOCUMENT_SERVER_URL_EXTERNAL:-"/ds-vpath/"}" "$EXTERNAL_DOCS_FLAG"
save_undefined_param "${USER_CONF}" "files.docservice.url.internal" "${DOCUMENT_SERVER_URL_EXTERNAL:-"http://$APP_HOST:$DOCUMENT_SERVER_PORT"}" "$EXTERNAL_DOCS_FLAG"
save_undefined_param "${USER_CONF}" "files.docservice.url.portal" "http://${APP_HOST}:${APP_PORT}" "$EXTERNAL_DOCS_FLAG"
echo "OK"
}
@ -617,10 +645,12 @@ setup_elasticsearch() {
save_undefined_param "${APP_DIR}/elastic.${ENVIRONMENT}.json" "elastic.Port" "${ELK_PORT}"
save_undefined_param "${APP_DIR}/elastic.${ENVIRONMENT}.json" "elastic.Threads" "1"
change_elasticsearch_config
if [ $1 == "LOCAL_ELASTIC_SERVER" ]; then
change_elasticsearch_config
systemctl enable elasticsearch >/dev/null 2>&1
systemctl restart elasticsearch
systemctl enable elasticsearch >/dev/null 2>&1
systemctl restart elasticsearch
fi
echo "OK"
}
@ -629,13 +659,16 @@ setup_redis() {
$JSON $APP_DIR/redis.$ENVIRONMENT.json -e "this.Redis={'Hosts': [ { Host: \"${REDIS_HOST}\", Port: \"${REDIS_PORT}\" } ] }" >/dev/null 2>&1
if [ -e /etc/redis/redis.conf ]; then
sed -i "s~\(redis_host =\).*~\1 \"$REDIS_HOST\"~" "${NGINX_DIR}/conf.d/${PACKAGE_SYSNAME}.conf"
sed -i "s~\(redis_port =\).*~\1 $REDIS_PORT~" "${NGINX_DIR}/conf.d/${PACKAGE_SYSNAME}.conf"
if [ $1 == "LOCAL_REDIS_SERVER" ]; then
sed "s_\(^bind\).*_\1 ${REDIS_HOST}_" -i /etc/redis/redis.conf
sed -r "/^save\s[0-9]+/d" -i /etc/redis/redis.conf
fi
systemctl enable $REDIS_PACKAGE >/dev/null 2>&1
systemctl restart $REDIS_PACKAGE
systemctl enable $REDIS_PACKAGE >/dev/null 2>&1
systemctl restart $REDIS_PACKAGE
fi
echo "OK"
}
@ -649,8 +682,10 @@ setup_rabbitmq() {
save_undefined_param "${APP_DIR}/rabbitmq.${ENVIRONMENT}.json" "RabbitMQ.Port" "${RABBITMQ_PORT}"
save_undefined_param "${APP_DIR}/rabbitmq.${ENVIRONMENT}.json" "RabbitMQ.VirtualHost" "/"
systemctl enable rabbitmq-server >/dev/null 2>&1
systemctl restart rabbitmq-server
if [ $1 == "LOCAL_RABBITMQ_SERVER" ]; then
systemctl enable rabbitmq-server >/dev/null 2>&1
systemctl restart rabbitmq-server
fi
echo "OK"
}
@ -673,6 +708,19 @@ product_configuration(){
echo "OK"
}
# Function below checks if there is a connection to the external service. 0 - OK, connection established
check_connection_external_services() {
exec {FD}<> /dev/tcp/$1/$2 && exec {FD}>&-
HOST_RESPONCE=$?
if [[ $HOST_RESPONCE -ne 0 ]]; then
echo -e "Host is not responding: $1:$2"
return $HOST_RESPONCE
fi
return $HOST_RESPONCE
}
if command -v yum >/dev/null 2>&1; then
DIST="RedHat"
PACKAGE_MANAGER="rpm -q"
@ -694,8 +742,12 @@ if $PACKAGE_MANAGER mysql-client >/dev/null 2>&1 || $PACKAGE_MANAGER mysql-commu
fi
if $PACKAGE_MANAGER ${PACKAGE_SYSNAME}-documentserver >/dev/null 2>&1 || $PACKAGE_MANAGER ${PACKAGE_SYSNAME}-documentserver-de >/dev/null 2>&1 || $PACKAGE_MANAGER ${PACKAGE_SYSNAME}-documentserver-ee >/dev/null 2>&1; then
setup_docs
setup_enterprise
setup_docs "LOCAL_DOCS_SERVER"
setup_enterprise
elif [[ ! -z $DOCUMENT_SERVER_URL_EXTERNAL ]]; then
parse_external_docs_url "$DOCUMENT_SERVER_URL_EXTERNAL"
check_connection_external_services "$DOCUMENT_SERVER_HOST" "$DOCUMENT_SERVER_PORT" || { echo "ONLYOFFICE Docs host is not responding"; }
setup_docs "EXTERNAL_DOCS_SERVER"
fi
if $PACKAGE_MANAGER openresty >/dev/null 2>&1; then
@ -703,15 +755,27 @@ if $PACKAGE_MANAGER openresty >/dev/null 2>&1; then
fi
if $PACKAGE_MANAGER elasticsearch >/dev/null 2>&1; then
setup_elasticsearch
setup_elasticsearch "LOCAL_ELASTIC_SERVER"
elif check_connection_external_services "$ELK_HOST" "$ELK_PORT"; then
setup_elasticsearch "EXTERNAL_ELASTIC_SERVER"
else
echo "Elasticsearch host is not responding"
fi
if $PACKAGE_MANAGER $REDIS_PACKAGE >/dev/null 2>&1 >/dev/null 2>&1; then
setup_redis
setup_redis "LOCAL_REDIS_SERVER"
elif check_connection_external_services "$REDIS_HOST" "$REDIS_PORT"; then
setup_redis "EXTERNAL_REDIS_SERVER"
else
echo "Redis host is not responding"
fi
if $PACKAGE_MANAGER rabbitmq-server >/dev/null 2>&1; then
setup_rabbitmq
setup_rabbitmq "LOCAL_RABBITMQ_SERVER"
elif check_connection_external_services "$RABBITMQ_HOST" "$RABBITMQ_PORT"; then
setup_rabbitmq "EXTERNAL_RABBITMQ_SERVER"
else
echo "Rabbitmq host is not responding"
fi
restart_services

View File

@ -99,7 +99,6 @@
DOCEDITOR_HOST=${CONTAINER_PREFIX}doceditor
LOGIN_HOST=${CONTAINER_PREFIX}login
HELTHCHECKS_HOST=${CONTAINER_PREFIX}healthchecks
REDIS_HOST=${CONTAINER_PREFIX}redis
# proxy upstream environment #
SERVICE_API_SYSTEM=${API_SYSTEM_HOST}:${SERVICE_PORT}

View File

@ -46,7 +46,10 @@ RUN apt-get -y update && \
npm && \
locale-gen en_US.UTF-8 && \
npm install --global yarn && \
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && \
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/nodesource.gpg --import && \
chmod 644 /usr/share/keyrings/nodesource.gpg && \
apt-get -y update && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/*
RUN git clone -b main/community-server https://github.com/ONLYOFFICE/document-templates ${SRC_PATH}/ASC.Files/Server/DocStore

View File

@ -31,7 +31,10 @@ RUN apt-get -y update && \
npm && \
locale-gen en_US.UTF-8 && \
npm install --global yarn && \
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && \
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/nodesource.gpg --import && \
chmod 644 /usr/share/keyrings/nodesource.gpg && \
apt-get -y update && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/*

View File

@ -2,82 +2,68 @@ resolver $DNS_NAMESERVER valid=30s;
map $SERVICE_LOGIN $service_login {
volatile;
$SERVICE_LOGIN $SERVICE_LOGIN;
"" 127.0.0.1:5011;
default $SERVICE_LOGIN;
}
map $SERVICE_DOCEDITOR $service_doceditor {
volatile;
$SERVICE_DOCEDITOR $SERVICE_DOCEDITOR;
}
map $SERVICE_CLIENT $service_client {
volatile;
$SERVICE_CLIENT $SERVICE_CLIENT;
"" 127.0.0.1:5013;
default $SERVICE_DOCEDITOR;
}
map $SERVICE_API_SYSTEM $service_api_system {
volatile;
$SERVICE_API_SYSTEM $SERVICE_API_SYSTEM;
"" 127.0.0.1:5010;
default $SERVICE_API_SYSTEM;
}
map $SERVICE_BACKUP $service_backup {
volatile;
$SERVICE_BACKUP $SERVICE_BACKUP;
"" 127.0.0.1:5012;
default $SERVICE_BACKUP;
}
map $SERVICE_FILES $service_files {
volatile;
$SERVICE_FILES $SERVICE_FILES;
}
map $SERVICE_FILES_SERVICES $service_files_services {
volatile;
$SERVICE_FILES_SERVICES $SERVICE_FILES_SERVICES;
}
map $SERVICE_NOTIFY $service_notify {
volatile;
$SERVICE_NOTIFY $SERVICE_NOTIFY;
"" 127.0.0.1:5007;
default $SERVICE_FILES;
}
map $SERVICE_PEOPLE_SERVER $service_people_server {
volatile;
$SERVICE_PEOPLE_SERVER $SERVICE_PEOPLE_SERVER;
"" 127.0.0.1:5004;
default $SERVICE_PEOPLE_SERVER;
}
map $SERVICE_SOCKET $service_socket {
volatile;
$SERVICE_SOCKET $SERVICE_SOCKET;
}
map $SERVICE_STUDIO_NOTIFY $service_studio_notify {
volatile;
$SERVICE_STUDIO_NOTIFY $SERVICE_STUDIO_NOTIFY;
}
map $SERVICE_THUMBNAILS $service_thumbnails {
volatile;
$SERVICE_THUMBNAILS $SERVICE_THUMBNAILS;
"" 127.0.0.1:9899;
default $SERVICE_SOCKET;
}
map $SERVICE_API $service_api {
volatile;
$SERVICE_API $SERVICE_API;
"" 127.0.0.1:5000;
default $SERVICE_API;
}
map $SERVICE_STUDIO $service_studio {
volatile;
$SERVICE_STUDIO $SERVICE_STUDIO;
"" 127.0.0.1:5003;
default $SERVICE_STUDIO;
}
map $SERVICE_SSOAUTH $service_sso {
volatile;
$SERVICE_SSOAUTH $SERVICE_SSOAUTH;
"" 127.0.0.1:9834;
default $SERVICE_SSOAUTH;
}
map $SERVICE_HELTHCHECKS $service_healthchecks {
volatile;
$SERVICE_HELTHCHECKS $SERVICE_HELTHCHECKS;
"" 127.0.0.1:5033;
default $SERVICE_HELTHCHECKS;
}
map "$DOCUMENT_SERVER_URL_EXTERNAL" "$document_server" {
@ -85,3 +71,9 @@ map "$DOCUMENT_SERVER_URL_EXTERNAL" "$document_server" {
default "$DOCUMENT_SERVER_URL_EXTERNAL";
"" "http://$DOCUMENT_CONTAINER_NAME";
}
map $SERVICE_CLIENT $service_client {
volatile;
"" 127.0.0.1:5001;
default $SERVICE_CLIENT;
}

View File

@ -271,6 +271,9 @@ services:
- SERVICE_HELTHCHECKS=${SERVICE_HELTHCHECKS}
- DOCUMENT_CONTAINER_NAME=${DOCUMENT_CONTAINER_NAME}
- DOCUMENT_SERVER_URL_EXTERNAL=${DOCUMENT_SERVER_URL_EXTERNAL}
- REDIS_CONTAINER_NAME=${REDIS_CONTAINER_NAME}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- SERVICE_PORT=${SERVICE_PORT}
volumes:
- proxy_log:/var/log/nginx

View File

@ -220,7 +220,9 @@ services:
- SERVICE_HELTHCHECKS=${SERVICE_HELTHCHECKS}
- DOCUMENT_CONTAINER_NAME=${DOCUMENT_CONTAINER_NAME}
- DOCUMENT_SERVER_URL_EXTERNAL=${DOCUMENT_SERVER_URL_EXTERNAL}
- REDIS_CONTAINER_NAME=${REDIS_CONTAINER_NAME}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- SERVICE_PORT=${SERVICE_PORT}
volumes:
- proxy_log:/var/log/nginx

View File

@ -1,5 +1,7 @@
#!/bin/sh
REDIS_HOST=${REDIS_HOST:-"onlyoffice-redis"}
REDIS_HOST=${REDIS_HOST:-"${REDIS_CONTAINER_NAME}"}
REDIS_PORT=${REDIS_PORT:-"6379"}
envsubst '$MAP_HASH_BUCKET_SIZE,$COUNT_WORKER_CONNECTIONS' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
sed -i "s!redis_host = \"127.0.0.1\"!redis_host = \"${REDIS_HOST}\"!g" /etc/nginx/conf.d/onlyoffice.conf
sed -i "s~\(redis_host =\).*~\1 \"$REDIS_HOST\"~" /etc/nginx/conf.d/onlyoffice.conf
sed -i "s~\(redis_port =\).*~\1 $REDIS_PORT~" /etc/nginx/conf.d/onlyoffice.conf

View File

@ -95,6 +95,9 @@ public static class NotifyQueueExtension
.HasColumnName("creation_date")
.HasColumnType("datetime");
entity.HasIndex(e => e.CreationDate)
.HasDatabaseName("creation_date");
entity.Property(e => e.Reciever)
.HasColumnName("reciever")
.HasColumnType("varchar(255)")
@ -155,6 +158,9 @@ public static class NotifyQueueExtension
entity.Property(e => e.CreationDate).HasColumnName("creation_date");
entity.HasIndex(e => e.CreationDate)
.HasDatabaseName("creation_date_notify_queue");
entity.Property(e => e.Reciever)
.HasColumnName("reciever")
.HasMaxLength(255)

View File

@ -34,6 +34,7 @@ public interface ITenantQuotaFeatureChecker
public abstract class TenantQuotaFeatureChecker<T, T1> : ITenantQuotaFeatureChecker where T : TenantQuotaFeature<T1> where T1 : IComparable<T1>
{
private static readonly object _lock = new object();
protected readonly ITenantQuotaFeatureStat<T, T1> _tenantQuotaFeatureStatistic;
protected readonly TenantManager _tenantManager;
@ -64,11 +65,14 @@ public abstract class TenantQuotaFeatureChecker<T, T1> : ITenantQuotaFeatureChec
protected void Check(TenantQuota quota, T1 newValue)
{
var val = quota.GetFeature<T>().Value;
if (newValue.CompareTo(val) > 0)
lock (_lock)
{
throw new TenantQuotaException(string.Format(Exception, val));
var val = quota.GetFeature<T>().Value;
if (newValue.CompareTo(val) > 0)
{
throw new TenantQuotaException(string.Format(Exception, val));
}
}
}
}

View File

@ -35,56 +35,101 @@ public class BackupFileUploadHandler
public async Task Invoke(HttpContext context,
PermissionContext permissionContext,
BackupAjaxHandler backupAjaxHandler)
BackupAjaxHandler backupAjaxHandler,
ICache cache,
TenantManager tenantManager,
IConfiguration configuration)
{
FileUploadResult result;
BackupFileUploadResult result = null;
try
{
if (context.Request.Form.Files.Count == 0)
{
result = Error("No files.");
}
if (!await permissionContext.CheckPermissionsAsync(SecutiryConstants.EditPortalSettings))
{
result = Error("Access denied.");
throw new ArgumentException("Access denied.");
}
var file = context.Request.Form.Files[0];
var filePath = await backupAjaxHandler.GetTmpFilePathAsync();
if (File.Exists(filePath))
var tenantId = tenantManager.GetCurrentTenant().Id;
var path = await backupAjaxHandler.GetTmpFilePathAsync();
if (context.Request.Query["Init"].ToString() == "true")
{
File.Delete(filePath);
}
long.TryParse(context.Request.Query["totalSize"], out var size);
if (size <= 0)
{
throw new ArgumentException("Total size must be greater than 0.");
}
await using (var fileStream = File.Create(filePath))
var maxSize = (await tenantManager.GetCurrentTenantQuotaAsync()).MaxTotalSize;
if (size > maxSize)
{
throw new ArgumentException(BackupResource.LargeBackup);
}
try
{
if (File.Exists(path))
{
File.Delete(path);
}
cache.Insert($"{tenantId} backupTotalSize", size.ToString(), TimeSpan.FromMinutes(10));
int.TryParse(configuration["files:uploader:chunk-size"], out var chunkSize);
chunkSize = chunkSize == 0 ? 10 * 1024 * 1024 : chunkSize;
result = Success(chunkSize);
}
catch
{
throw new ArgumentException("Can't start upload.");
}
}
else
{
await file.CopyToAsync(fileStream);
}
long.TryParse(cache.Get<string>($"{tenantId} backupTotalSize"), out var totalSize);
if (totalSize <= 0)
{
throw new ArgumentException("Need init upload.");
}
result = Success();
var file = context.Request.Form.Files[0];
using var stream = file.OpenReadStream();
using var fs = File.Open(path, FileMode.Append);
await stream.CopyToAsync(fs);
if (fs.Length >= totalSize)
{
cache.Remove($"{tenantId} backupTotalSize");
result = Success(endUpload: true);
}
else
{
result = Success();
}
}
}
catch (Exception error)
{
result = Error(error.Message);
}
await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(result));
await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(result, new System.Text.Json.JsonSerializerOptions()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
}));
}
private FileUploadResult Success()
private BackupFileUploadResult Success(int chunk = 0, bool endUpload = false)
{
return new FileUploadResult
return new BackupFileUploadResult
{
Success = true
Success = true,
ChunkSize = chunk,
EndUpload = endUpload
};
}
private FileUploadResult Error(string messageFormat, params object[] args)
private BackupFileUploadResult Error(string messageFormat, params object[] args)
{
return new FileUploadResult
return new BackupFileUploadResult
{
Success = false,
Message = string.Format(messageFormat, args)
@ -92,6 +137,14 @@ public class BackupFileUploadHandler
}
}
internal class BackupFileUploadResult
{
public bool Success { get; set; }
public string Message { get; set; }
public int ChunkSize { get; set; }
public bool EndUpload { get; set; }
}
public static class BackupFileUploadHandlerExtensions
{
public static IApplicationBuilder UseBackupFileUploadHandler(this IApplicationBuilder builder)

View File

@ -77,5 +77,14 @@ namespace ASC.Data.Backup.Core {
return ResourceManager.GetString("ButtonSetPassword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Backup is larger than the total size of the portal.
/// </summary>
internal static string LargeBackup {
get {
return ResourceManager.GetString("LargeBackup", resourceCulture);
}
}
}
}

View File

@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@ -53,10 +112,10 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BackupNotFound" xml:space="preserve">
<value>The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later.</value>
@ -64,4 +123,7 @@
<data name="ButtonSetPassword" xml:space="preserve">
<value>Set Password</value>
</data>
<data name="LargeBackup" xml:space="preserve">
<value>Backup is larger than the total size of the portal</value>
</data>
</root>

View File

@ -33,6 +33,8 @@ global using System.Reflection;
global using System.Security.Cryptography;
global using System.ServiceModel;
global using System.Text;
global using System.Text.Json.Serialization;
global using System.Text.RegularExpressions;
global using System.Xml;
global using System.Xml.Linq;
@ -82,7 +84,6 @@ global using ASC.Notify.Recipients;
global using ASC.Security.Cryptography;
global using ASC.Web.Core.PublicResources;
global using ASC.Web.Core.Users;
global using ASC.Web.Core.Utility;
global using ASC.Web.Core.WhiteLabel;
global using ASC.Web.Files.Utils;
global using ASC.Web.Studio.Core;

View File

@ -110,6 +110,7 @@ public class ChunkZipWriteOperator : IDataWriteOperator
theMemStream.Position = 0;
StoragePath = await _sessionHolder.UploadChunkAsync(_chunkedUploadSession, theMemStream, theMemStream.Length);
_sha.TransformBlock(buffer, 0, bytesRead, buffer, 0);
}
else
{
@ -120,7 +121,6 @@ public class ChunkZipWriteOperator : IDataWriteOperator
await theMemStream.CopyToAsync(_fileStream);
_fileStream.Flush();
}
_sha.TransformBlock(buffer, 0, bytesRead, buffer, 0);
}
}
if (last)

View File

@ -3,7 +3,7 @@
"name": "Onlyoffice Single Sign-On handler",
"port": 9834,
"appsettings": "../../../config",
"machinekey": "1123askdasjklasbnd",
"machinekey": "1123askdasjklasbnd",
"environment": "Development",
"logName": "web.sso.%DATE%.log",
"contact": {
@ -22,7 +22,7 @@
"baseUrl": "http://localhost",
"port": 80,
"ssoUrl": "/ssologin.ashx",
"authUrl": "/Auth.aspx"
"authUrl": "/login"
}
},
"routes": {
@ -62,6 +62,6 @@
"data": "../../Data",
"image-path": "images",
"rebranding": "rebranding",
"https":"certs"
"https": "certs"
}
}

View File

@ -8,7 +8,7 @@
"logSamlData": false,
"portal": {
"ssoUrl": "/ssologin.ashx",
"authUrl": "/Auth.aspx"
"authUrl": "/login"
}
},
"routes": {

View File

@ -42,10 +42,10 @@ global using ASC.Files.Core.EF;
global using ASC.Web.Api.Routing;
global using ASC.Web.Studio.Core.Backup;
global using ASC.Web.Studio.Core.Notify;
global using ASC.Web.Studio.Utility;
global using Microsoft.AspNetCore.Authorization;
global using Autofac;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Http.Features;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore.Server.Kestrel.Core;

View File

@ -285,7 +285,17 @@
"documentation-email": "documentation@onlyoffice.com",
"max-upload-size": 5242880,
"zendesk-key": "",
"samesite": ""
"samesite": "",
"sso": {
"saml": {
"login":{
"url" :"/sso/login"
},
"logout":{
"url" :"/sso/slo"
}
}
}
},
"ConnectionStrings": {
"default": {

View File

@ -16,6 +16,7 @@
{
"Period":"00:15:00"
},
"ChunkSize": 20971520
"ChunkSize": 20971520,
"MaxLocalSize": 1048576000
}
}

View File

@ -91,30 +91,6 @@ server {
proxy_set_header Proxy "";
set $csp "";
access_by_lua '
local key = string.format("csp:%s",ngx.var.host)
local redis = require "resty.redis"
local red = redis:new()
local redis_host = "127.0.0.1"
local redis_port = 6379
red:set_timeout(1000) -- 1 second
local ok, err = red:connect(redis_host, redis_port)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
end
local csp, err = red:hget(key, "data")
if csp == ngx.null then
ngx.log(ngx.ERR, "failed to get redis key: ", err)
else
ngx.header.Content_Security_Policy = csp
end
';
location ~* ^/ds-vpath/ {
rewrite /ds-vpath/(.*) /$1 break;
@ -136,6 +112,31 @@ server {
}
location / {
set $csp "";
access_by_lua '
if ngx.req.get_method() == "GET" then
local key = string.format("csp:%s",ngx.var.host)
local redis = require "resty.redis"
local red = redis:new()
local redis_host = "127.0.0.1"
local redis_port = 6379
red:set_timeout(1000) -- 1 second
local ok, err = red:connect(redis_host, redis_port)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
end
local csp, err = red:hget(key, "data")
if csp == ngx.null then
ngx.log(ngx.ERR, "failed to get redis key: ", err)
else
ngx.header.Content_Security_Policy = csp
end
end
';
proxy_pass http://127.0.0.1:5001;
location ~* /(manifest.json|sw.js|appIcon(.)*\.png|icon.svg|bg-error.png|favicon.ico|debuginfo.md) {
try_files /$basename /index.html =404;

View File

@ -22545,6 +22545,122 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>ErrorDeactivatedText</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Latn-AZ</language>
<approved>false</approved>
</translation>
<translation>
<language>bg-BG</language>
<approved>false</approved>
</translation>
<translation>
<language>cs-CZ</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>el-GR</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-ES</language>
<approved>false</approved>
</translation>
<translation>
<language>fi-FI</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>hy-AM</language>
<approved>false</approved>
</translation>
<translation>
<language>it-IT</language>
<approved>false</approved>
</translation>
<translation>
<language>ja-JP</language>
<approved>false</approved>
</translation>
<translation>
<language>ko-KR</language>
<approved>false</approved>
</translation>
<translation>
<language>lo-LA</language>
<approved>false</approved>
</translation>
<translation>
<language>lv-LV</language>
<approved>false</approved>
</translation>
<translation>
<language>nl-NL</language>
<approved>false</approved>
</translation>
<translation>
<language>pl-PL</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-BR</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-PT</language>
<approved>false</approved>
</translation>
<translation>
<language>ro-RO</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>sk-SK</language>
<approved>false</approved>
</translation>
<translation>
<language>sl-SI</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
<translation>
<language>uk-UA</language>
<approved>false</approved>
</translation>
<translation>
<language>vi-VN</language>
<approved>false</approved>
</translation>
<translation>
<language>zh-CN</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>ErrorEmptyResponse</name>
<description/>

View File

@ -27862,6 +27862,122 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>SignInWithMicrosoft</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Latn-AZ</language>
<approved>false</approved>
</translation>
<translation>
<language>bg-BG</language>
<approved>false</approved>
</translation>
<translation>
<language>cs-CZ</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>el-GR</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-ES</language>
<approved>false</approved>
</translation>
<translation>
<language>fi-FI</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>hy-AM</language>
<approved>false</approved>
</translation>
<translation>
<language>it-IT</language>
<approved>false</approved>
</translation>
<translation>
<language>ja-JP</language>
<approved>false</approved>
</translation>
<translation>
<language>ko-KR</language>
<approved>false</approved>
</translation>
<translation>
<language>lo-LA</language>
<approved>false</approved>
</translation>
<translation>
<language>lv-LV</language>
<approved>false</approved>
</translation>
<translation>
<language>nl-NL</language>
<approved>false</approved>
</translation>
<translation>
<language>pl-PL</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-BR</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-PT</language>
<approved>false</approved>
</translation>
<translation>
<language>ro-RO</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>sk-SK</language>
<approved>false</approved>
</translation>
<translation>
<language>sl-SI</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
<translation>
<language>uk-UA</language>
<approved>false</approved>
</translation>
<translation>
<language>vi-VN</language>
<approved>false</approved>
</translation>
<translation>
<language>zh-CN</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>SignInWithSso</name>
<description/>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.MySql.SaaS.Migrations
{
/// <inheritdoc />
public partial class MigrationContext_Upgrade2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "creation_date",
table: "notify_queue",
column: "creation_date");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "creation_date",
table: "notify_queue");
}
}
}

View File

@ -4618,6 +4618,9 @@ namespace ASC.Migrations.MySql.SaaS.Migrations
b.HasKey("NotifyId")
.HasName("PRIMARY");
b.HasIndex("CreationDate")
.HasDatabaseName("creation_date");
b.HasIndex("TenantId");
b.ToTable("notify_queue", (string)null);

View File

@ -5,6 +5,10 @@
"Code": "Daxil etmək üçün kod",
"CopyWindowCode": "Pəncərənin kodunu kopyalayın",
"CreateSampleHeader": "DocSpace yerləşdirmə nümunəsi yaradın",
"CSPDescription": "DocSpace-i vebsaytda iframe kimi təhlükəsiz şəkildə yerləşdirmək üçün onun URL-ni icazələr siyahısına əlavə edin.",
"CSPHeader": "DocSpace-i iframe kimi yerləşdirin",
"CSPHelp": "Bu parametr məzmun hücumlarından qorunmaq üçün istifadə edilə bilən təhlükəsizlik mexanizmidir. CSP təhlükəsiz mənbə yükləmə mənbələrini təsvir edir. \"Ağ siyahıya salınmayan\" mənbələrdən endrilmə bloklanıb. İstifadə olunacaq domenləri (protokollu) göstərin.",
"CSPInputPlaceholder": "URL'yi bu cür daxil edin: https://example.com",
"CustomizingDisplay": "Ekranı fərdiləşdirin",
"DataDisplay": "Məlumatların göstərilməsi parametrləri",
"Descending": "Azalan",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Ehtiyat nüsxə uğurla yaradıldı.",
"BackupList": "Ehtiyyat siyahısı",
"BackupListWarningText": "Siyahıdan müəyyən elementləri silsəniz, onların müvafiq faylları da silinəcək. Bu əməliyyat geri qaytarıla bilməz. Bütün faylları silmək üçün linkdən istifadə edin:",
"BetaLabel": "BETA",
"Branding": "Brendləşmə",
"BrandingSectionDescription": "Şirkət məlumatlarınızı göstərin, DocSpace interfeysində göstərilən xarici resurslara və e-poçt ünvanlarına keçidlər əlavə edin.",
"BrandingSubtitle": "İstifadəçilərə brendlə bağlı təcrübə təmin etmək üçün bu seçimdən istifadə edin.",

View File

@ -5,6 +5,10 @@
"Code": "Код за вмъкване",
"CopyWindowCode": "Копирайте кода за вграждане на прозореца",
"CreateSampleHeader": "Създайте примерно DocSpace вграждане",
"CSPDescription": "За безопасно вграждане на DocSpace като iframe в уебсайт, добавете URL адреса му към вашия списък с разрешени.",
"CSPHeader": "Вградете DocSpace като iframe",
"CSPHelp": "Тази настройка е защитен механизъм, който може да се използва за защита срещу атаки на инжектирано съдържание. CSP описва сигурни източници за изтегляне на ресурси. Изтеглянето от ресурси, които не са включени в „белия списък“, е блокирано. Посочете домейните (заедно с протокола), с които ще работи.",
"CSPInputPlaceholder": "Въведете URL адреса така: https://example.com",
"CustomizingDisplay": "Персонализиране на дисплея",
"DataDisplay": "Настройки за дисплей на данните",
"Descending": "Низходящ",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Резервното копие е създадено успешно.",
"BackupList": "Списък с резервни копия",
"BackupListWarningText": "Ако изтриете всички елементи от списъка, съответните им файлове също ще бъдат изтрити. Това действие не може да бъде отменено. За да изтриете всички файлове, използвайте връзката:",
"BetaLabel": "BETA",
"Branding": "Брандинг",
"BrandingSectionDescription": "Посочете информацията за вашата компания, добавете линкове към външни ресурси и имейл адреси, показвани в DocSpace интерфейса.",
"BrandingSubtitle": "Използвайте тази опция, за да предоставите брандинг преживяване на потребителите си.",

View File

@ -5,6 +5,10 @@
"Code": "Kód pro vložení",
"CopyWindowCode": "Kopírování kódu pro vložení okna",
"CreateSampleHeader": "Vytvoření vzorového vložení DocSpace",
"CSPDescription": "Chcete-li bezpečně vložit DocSpace jako iframe do webové stránky, přidejte její adresu URL do seznamu povolených adres.",
"CSPHeader": "Vložit DocSpace jako iframe",
"CSPHelp": "Toto nastavení je bezpečnostní mechanismus, který lze použít k ochraně před útoky typu \"content injection\". CSP popisuje bezpečné zdroje pro stahování zdrojů. Stahování ze zdrojů, které nejsou uvedeny na `bílém seznamu`, je blokováno. Zadejte domény (spolu s protokolem), se kterými bude pracovat.",
"CSPInputPlaceholder": "Zadejte adresu URL takto: https://example.com",
"CustomizingDisplay": "Přizpůsobení zobrazení",
"DataDisplay": "Nastavení zobrazení dat",
"Descending": "Sestupně",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Kopie zálohy byla úspěšně vytvořena.",
"BackupList": "Seznam záloh",
"BackupListWarningText": "Pokud odstraníte nějaké položky ze seznamu, budou také odstraněny odpovídající soubory. Tuto akci nelze vrátit zpět. Chcete-li odstranit všechny soubory, použijte odkaz:",
"BetaLabel": "BETA",
"Branding": "Branding",
"BrandingSectionDescription": "Zadejte informace o své společnosti, přidejte odkazy na externí zdroje a e-mailové adresy zobrazené v rozhraní DocSpace.",
"BrandingSubtitle": "Tuto možnost použijte, abyste uživatelům poskytli zážitek na úrovni značky.",

View File

@ -2,6 +2,7 @@
"Error401Text": "Die Ressource kann zurzeit nicht zugegriffen werden.",
"Error403Text": "Zugriff verweigert.",
"Error404Text": "Die Ressource kann nicht gefunden werden.",
"ErrorDeactivatedText": "Dieser DocSpace ist deaktiviert",
"ErrorEmptyResponse": "Leere Antwort",
"ErrorOfflineText": "Keine Internetverbindung gefunden",
"ErrorUnavailableText": "DocSpace nicht verfügbar"

View File

@ -5,6 +5,10 @@
"Code": "Code zum Einfügen",
"CopyWindowCode": "Fenster-Einbettungscode kopieren",
"CreateSampleHeader": "Beispiel DocSpace-Einbettung erstellen",
"CSPDescription": "Um DocSpace sicher als iFrame in eine Website einzubetten, fügen Sie die URL zu Ihrer Zulassungsliste hinzu.",
"CSPHeader": "DocSpace als iFrame einbetten",
"CSPHelp": "Diese Einstellung ist ein Sicherheitsmechanismus, der zum Schutz vor Content-Injection-Angriffen verwendet werden kann. CSP beschreibt sichere Quellen für das Herunterladen von Ressourcen. Das Herunterladen von Ressourcen, die nicht in der `Weißliste` enthalten sind, wird blockiert. Geben Sie die Domänen (zusammen mit dem Protokoll) an, mit denen es arbeiten soll.",
"CSPInputPlaceholder": "Geben Sie eine URL wie folgt ein: https://example.com",
"CustomizingDisplay": "Anpassen der Anzeige",
"DataDisplay": "Einstellungen der Datenanzeige",
"Descending": "Absteigend",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Die Sicherungskopie wurde erfolgreich erstellt.",
"BackupList": "Backup-Liste",
"BackupListWarningText": "Falls Sie einige Elemente aus der Liste löschen, werden die entsprechende Dateien auch gelöscht. Dieser Vorgang nicht rückgängig gemacht werden kann. Um alle Dateien zu löschen, verwenden Sie den Link:",
"BetaLabel": "BETA",
"Branding": "Branding",
"BrandingSectionDescription": "Geben Sie Ihre Unternehmensinformationen an, fügen Sie Links zu externen Ressourcen und E-Mail-Adressen hinzu, die auf der DocSpace-Oberfläche angezeigt werden.",
"BrandingSubtitle": "Verwenden Sie diese Option, um den Nutzern ein markengerechtes Erlebnis zu bieten.",

View File

@ -5,6 +5,10 @@
"Code": "Κώδικας για εισαγωγή",
"CopyWindowCode": "Αντιγραφή του κώδικα ενσωμάτωσης του παραθύρου",
"CreateSampleHeader": "Δημιουργία δείγματος ενσωμάτωσης DocSpace",
"CSPDescription": "Για να ενσωματώσετε με ασφάλεια το DocSpace ως iframe σε έναν ιστότοπο, προσθέστε τη διεύθυνση URL του στη λίστα αδειών σας.",
"CSPHeader": "Ενσωμάτωση του DocSpace ως iframe",
"CSPHelp": "Αυτή η ρύθμιση είναι ένας μηχανισμός ασφαλείας που μπορεί να χρησιμοποιηθεί για την προστασία από επιθέσεις έγχυσης περιεχομένου. Το CSP περιγράφει ασφαλείς πηγές λήψης πόρων. Η λήψη από πόρους που δεν περιλαμβάνονται στη «λευκή λίστα» αποκλείεται. Καθορίστε τους τομείς (μαζί με το πρωτόκολλο) με τους οποίους θα λειτουργεί.",
"CSPInputPlaceholder": "Εισάγετε τη διεύθυνση URL ως εξής: https://example.com",
"CustomizingDisplay": "Προσαρμογή της εμφάνισης",
"DataDisplay": "Ρυθμίσεις εμφάνισης δεδομένων",
"Descending": "Φθίνουσα",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Το εφεδρικό αντίγραφο έχει δημιουργηθεί επιτυχώς.",
"BackupList": "Εφεδρική λίστα",
"BackupListWarningText": "Εάν διαγράψετε στοιχεία από τη λίστα, θα διαγραφούν και τα αντίστοιχα αρχεία τους. Αυτή η ενέργεια δεν μπορεί να αναιρεθεί. Για να διαγράψετε όλα τα αρχεία, χρησιμοποιήστε τον σύνδεσμο:",
"BetaLabel": "BETA",
"Branding": "Επωνυμία",
"BrandingSectionDescription": "Καθορίστε τα στοιχεία της εταιρείας σας, προσθέστε συνδέσμους προς εξωτερικούς πόρους και διευθύνσεις ηλεκτρονικού ταχυδρομείου που εμφανίζονται μέσα στο περιβάλλον εργασίας του DocSpace.",
"BrandingSubtitle": "Χρησιμοποιήστε αυτήν την επιλογή για να παρέχετε στους χρήστες εμπειρία που ταιριάζει στην επωνυμία.",

View File

@ -2,6 +2,7 @@
"Error401Text": "Sorry, the resource is not currently accessible.",
"Error403Text": "Sorry, access denied.",
"Error404Text": "Sorry, the resource cannot be found.",
"ErrorDeactivatedText": "This DocSpace is deactivated",
"ErrorEmptyResponse": "Empty response",
"ErrorOfflineText": "No internet connection",
"ErrorUnavailableText": "DocSpace unavailable",

View File

@ -33,7 +33,7 @@
"EmptyFilterDescriptionText": "No files or folders match this filter. Try a different one or clear filter to view all files. ",
"EmptyFilterSubheadingText": "No files to be displayed for this filter here",
"EmptyFolderDecription": "Drop files here or create new ones",
"EmptyFolderDescriptionUser": "Files and folders uploaded by admins will appeared here.",
"EmptyFolderDescriptionUser": "Files and folders uploaded by admins will appear here.",
"EmptyFolderHeader": "No files in this folder",
"EmptyRecycleBin": "Empty Trash",
"EmptyRootRoomHeader": "Welcome to DocSpace",

View File

@ -2,6 +2,7 @@
"Error401Text": "Perdón, el recurso no es accesible actualmente.",
"Error403Text": "Perdón, acceso denegado.",
"Error404Text": "Perdón, no se puede encontrar el recurso.",
"ErrorDeactivatedText": "Este DocSpace está desactivado",
"ErrorEmptyResponse": "Respuesta vacía",
"ErrorOfflineText": "No se ha encontrado ninguna conexión a Internet",
"ErrorUnavailableText": "DocSpace no está disponible"

View File

@ -5,6 +5,10 @@
"Code": "Lisättävä koodi",
"CopyWindowCode": "Kopioi ikkunan upotuskoodi",
"CreateSampleHeader": "Luo esimerkki DocSpace-upotuksesta",
"CSPDescription": "Upottaaksesi DocSpacen iframeksi verkkosivulle, lisää sen URL sallittujen luetteloon.",
"CSPHeader": "Upota DocSpace iframeksi",
"CSPHelp": "Tämä asetus on suojausmekanismi, jota voidaan käyttää suojelemaan sisällön lisäyshyökkäyksiltä. CSP kuvaa suojatut resurssien latauslähteet. Lataaminen resursseista, jotka eivät sisälly \"valkoiseen listaan\", on estetty. Määritä toimialueet (yhdessä protokollan kanssa) joiden kanssa se toimii.",
"CSPInputPlaceholder": "Syötä URL näin: https://example.com",
"CustomizingDisplay": "Näytön mukauttaminen",
"DataDisplay": "Tietojen näyttöasetukset",
"Descending": "Laskeva",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Turvatallenteen kopio on luotu onnistuneesti.",
"BackupList": "Varmuuskopiolista",
"BackupListWarningText": "Jos poistat luettelosta kohteita, myös vastaavat tiedostot poistetaan. Tätä toimintoa ei voi kumota. Jos haluat poistaa kaikki tiedostot, käytä linkkiä:",
"BetaLabel": "BETA",
"Branding": "Brändäys",
"BrandingSectionDescription": "Tarkenna yrityksesi tiedot, lisää linkit Docspace-käyttöliittymässä näkyvät ulkoiset resurssit ja sähköpostiosoitteet.",
"BrandingSubtitle": "Käytä tätä vaihtoehtoa tarjotaksesi käyttäjille brändikokemusta.",

View File

@ -2,6 +2,7 @@
"Error401Text": "Désolé, la ressource n'est pas disponible actuellement.",
"Error403Text": "Désolé, accès refusé.",
"Error404Text": "Désolé, la ressource n'a pu être trouvée.",
"ErrorDeactivatedText": "Ce DocSpace est désactivé",
"ErrorEmptyResponse": "Réponse vide",
"ErrorOfflineText": "Aucune connexion Internet trouvée",
"ErrorUnavailableText": "DocSpace non disponible"

View File

@ -2,6 +2,7 @@
"Error401Text": "Ներողություն, ռեսուրսը ներկայումս հասանելի չէ.",
"Error403Text": "Ներողություն, մատչումն արգելված է.",
"Error404Text": "Ներողություն, ռեսուրսը հնարավոր չէ գտնել:",
"ErrorDeactivatedText": "Այս DocSpace-ն ապաակտիվացված է",
"ErrorEmptyResponse": "Դատարկ պատասխան",
"ErrorOfflineText": "Ինտերնետ կապ չի գտնվել",
"ErrorUnavailableText": "DocSpace-ը առկա չէ"

View File

@ -2,6 +2,7 @@
"Error401Text": "Spiacente, la risorsa non è attualmente accessibile.",
"Error403Text": "Spiacente, accesso negato.",
"Error404Text": "Spiacente, impossibile trovare la risorsa.",
"ErrorDeactivatedText": "Questo DocSpace è disattivato",
"ErrorEmptyResponse": "Risposta vuota",
"ErrorOfflineText": "Nessuna connessione a internet trovata",
"ErrorUnavailableText": "DocSpace non disponibile"

View File

@ -5,6 +5,10 @@
"Code": "挿入するコード",
"CopyWindowCode": " ウィンドウの埋め込みコードをコピーする",
"CreateSampleHeader": "サンプルDocSpaceエンベッドの作成",
"CSPDescription": "DocSpaceをiframeとして安全にウェブサイトに埋め込むには、そのURLを許可リストに追加してください。",
"CSPHeader": "DocSpaceをiframeとして埋め込む",
"CSPHelp": "この設定は、コンテンツ・インジェクション攻撃から保護するために使用できるセキュリティ・メカニズムです。CSP には安全なリソースのダウンロード・ソースが記述されています。ホワイトリストに含まれていないリソースからのダウンロードはブロックされます。動作するドメインを(プロトコルと共に)指定します。",
"CSPInputPlaceholder": "URLを次のように入力 https://example.com",
"CustomizingDisplay": "表示のカスタマイズ",
"DataDisplay": "データ表示設定",
"Descending": "下降",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "バックアップ・コピーは正常に作成されました。",
"BackupList": "バックアップリスト",
"BackupListWarningText": "リストからアイテムを削除すると、対応するファイルも削除されます。この操作を元に戻すことができません。すべてのファイルを削除するために次のリンクをクリックしてください:",
"BetaLabel": "BETA",
"Branding": "ブランディング",
"BrandingSectionDescription": "DocSpaceのインターフェイス内に表示される企業情報、外部リソースへのリンク、メールアドレスの追加を指定してください。",
"BrandingSubtitle": "このオプションを使用すると、ユーザーにオンブランドのエクスペリエンスを提供することができます。",

View File

@ -5,6 +5,10 @@
"Code": "Code om in te voegen",
"CopyWindowCode": "Kopieer venster insluitcode",
"CreateSampleHeader": "Voorbeeld DocSpace insluiten maken",
"CSPDescription": "Om DocSpace veilig in te sluiten als een iframe in een website, voegt u de URL toe aan uw toestaan-lijst.",
"CSPHeader": "DocSpace insluiten als iframe",
"CSPHelp": "Deze instelling is een beveiligingsmechanisme dat kan worden gebruikt om bescherming te bieden tegen aanvallen waarbij materiaal wordt geïnjecteerd. Het CSP beschrijft veilige bronnen voor het downloaden. Downloaden van bronnen die niet op de `witte lijst` staan, wordt vervolgens geblokkeerd. Geef de domeinen aan (samen met het protocol) waar het mee gaat werken.",
"CSPInputPlaceholder": "Voer de URL als volgt in: https://example.com",
"CustomizingDisplay": "De weergave aanpassen",
"DataDisplay": "Instellingen weergave gegevens",
"Descending": "Aflopend",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "De back-up kopie is succesvol aangemaakt.",
"BackupList": "Back-up lijst",
"BackupListWarningText": "Als u items uit de lijst verwijdert, worden hun bijbehorende bestanden ook verwijderd. Deze actie kan niet ongedaan gemaakt worden. Om alle bestanden te verwijderen, gebruik de link:",
"BetaLabel": "BETA",
"Branding": "Branding",
"BrandingSectionDescription": "Specificeer uw bedrijfsinformatie, voeg links toe naar externe bronnen en e-mailadressen die in de DocSpace interface worden weergegeven.",
"BrandingSubtitle": "Gebruik deze optie om gebruikers een on-brand ervaring te bieden.",

View File

@ -5,6 +5,10 @@
"Code": "Kod do wstawienia",
"CopyWindowCode": "Skopiuj kod osadzania dla okna",
"CreateSampleHeader": "Utwórz szablon osadzania DocSpace",
"CSPDescription": "Aby bezpiecznie osadzić DocSpace jako element iframe na swojej stronie internetowej, dodaj jego adres URL do swojej listy dozwolonych.",
"CSPHeader": "Osadź DocSpace jako iframe",
"CSPHelp": "Dane ustawienie to mechanizm zabezpieczający przed atakami polegającymi na wstrzykiwaniu zawartości. Zasady zabezpieczeń zawartości (CSP) opisują bezpieczne źródła pobierania zasobów. Pobieranie z zasobów, które nie znajdują się na Białej Liście, jest zablokowane. Określ domeny (wraz z protokołem), z którymi będzie to działać.",
"CSPInputPlaceholder": "Wpisz URL w następujący sposób: https://example.com",
"CustomizingDisplay": "Personalizacja wyświetlania",
"DataDisplay": "Ustawienia wyświetlania danych",
"Descending": "Malejąco",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Kopia zapasowa została pomyślnie utworzona.",
"BackupList": "Lista kopii zapasowych",
"BackupListWarningText": "Jeśli usuniesz wszystkie elementy z listy, odpowiadające im pliki zostaną również usunięte. Ta czynność nie może zostać cofnięta. Aby usunąć wszystkie pliki, użyj linku:",
"BetaLabel": "BETA",
"Branding": "Branding",
"BrandingSectionDescription": "Dodaj informacje o firmie, linki do zasobów zewnętrznych i adresy e-mail widoczne w interfejsie DocSpace.",
"BrandingSubtitle": "Użyj tej opcji, aby zapewnić użytkownikom doświadczenie marki.",

View File

@ -2,6 +2,7 @@
"Error401Text": "Desculpe, o recurso não está atualmente acessível.",
"Error403Text": "Desculpe, acesso negado.",
"Error404Text": "Desculpe, o recurso não pode ser encontrado.",
"ErrorDeactivatedText": "Este DocSpace está desativado",
"ErrorEmptyResponse": "Resposta vazia",
"ErrorOfflineText": "Nenhuma conexão com a Internet foi encontrada",
"ErrorUnavailableText": "DocSpace indisponível"

View File

@ -5,6 +5,10 @@
"Code": "Código a inserir",
"CopyWindowCode": "Copiar código de incorporação da janela",
"CreateSampleHeader": "Criar um exemplo de incorporação do DocSpace",
"CSPDescription": "Para incorporar com segurança o DocSpace como um iframe num Website, adicione o seu URL à sua lista de permissões.",
"CSPHeader": "Incorporar o DocSpace como iframe",
"CSPHelp": "Esta definição é um mecanismo de segurança que pode ser utilizado para proteger contra ataques de injeção de conteúdos. O CSP descreve fontes seguras de download de recursos. O download de recursos não incluídos na \"lista branca\" está bloqueado. Especifique os domínios (juntamente com o protocolo) com os quais irá trabalhar.",
"CSPInputPlaceholder": "Introduzir um URL como este: https://example.com",
"CustomizingDisplay": "A personalizar a visualização",
"DataDisplay": "Definições de visualização de dados",
"Descending": "Descendente",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "A cópia de segurança foi criada com sucesso.",
"BackupList": "Lista de Cópias de Segurança",
"BackupListWarningText": "Se eliminar qualquer item desta lista, os ficheiros que lhes correspondem serão também eliminados. Esta ação não pode ser anulada. Para eliminar todos os ficheiros utilize o link:",
"BetaLabel": "BETA",
"Branding": "Imagem de Marca",
"BrandingSectionDescription": "Especifique a informação da sua empresa, adicione ligações a recursos externos e endereços de correio eletrónico exibidos dentro da interface do DocSpace.",
"BrandingSubtitle": "Utilize esta opção para fornecer uma experiência de marca aos utilizadores.",

View File

@ -2,6 +2,7 @@
"Error401Text": "Извините, страница недоступна.",
"Error403Text": "Извините, доступ закрыт.",
"Error404Text": "Извините, страница не найдена.",
"ErrorDeactivatedText": "Этот DocSpace деактивирован",
"ErrorEmptyResponse": "Пустой ответ",
"ErrorOfflineText": "Нет подключения к интернету",
"ErrorUnavailableText": "DocSpace недоступен"

View File

@ -7,7 +7,7 @@
"CreateSampleHeader": "Создать образец встраивания DocSpace",
"CSPDescription": "Чтобы безопасно встроить DocSpace в качестве iframe в веб-сайт, добавьте его URL-адрес в список разрешенных.",
"CSPHeader": "Встроить DocSpace в качестве iframe",
"CSPHelp": "Данный параметр является механизмом безопасности, который можно использовать для защиты от атак путем внедрения контента. CSP описывает безопасные источники для загрузки. Скачивание с ресурсов, не включенных в «белый список», блокируется. Укажите домены (вместе с протоколом), с которыми он будет работать.",
"CSPHelp": "Данный параметр является механизмом безопасности, который можно использовать для защиты от атак путем внедрения контента. CSP описывает безопасные источники для загрузки. Скачивание с ресурсов, не включенных в «белый список», блокируется. Укажите домены (вместе с протоколом), с которыми он будет работать.",
"CSPInputPlaceholder": "Введите URL-адрес в формате: https://example.com",
"CustomizingDisplay": "Настройка отображения",
"DataDisplay": "Настройки отображения данных",

View File

@ -5,6 +5,10 @@
"Code": "Kód na vloženie",
"CopyWindowCode": "Kopírovať kód na vloženie okna",
"CreateSampleHeader": "Vytvoriť vzor vloženia DocSpace",
"CSPDescription": "Pokiaľ chcete bezpečne umiestniť DocSpace na webovú stránku ako iframe, pridajte jeho URL do zoznamu povolených adries.",
"CSPHeader": "Vložiť DocSpace ako iframe",
"CSPHelp": "Toto nastavenie je bezpečnostný mechanizmus, ktorý sa môže použiť na ochranu pred útokmi formou vstrekovania obsahu. CSP popisuje bezpečné zdroje na sťahovanie obsahu. Sťahovanie zo zdrojov, ktoré nie sú na zozname povolených, je zablokované. Zadajte domény (spolu s protokolom), s ktorými bude pracovať.",
"CSPInputPlaceholder": "URL zadávajte nasledovne: https://example.com",
"CustomizingDisplay": "Prispôsobenie zobrazovania",
"DataDisplay": "Nastavenia zobrazovania údajov",
"Descending": "Zostupne",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Kópia zálohy bola úspešne vytvorená.",
"BackupList": "Zoznam záloh",
"BackupListWarningText": "Ak odstránite niektoré položky zo zoznamu, odstránia sa aj ich príslušné súbory. Táto akcia sa nedá vrátiť späť. Ak chcete odstrániť všetky súbory, použite odkaz:",
"BetaLabel": "BETA",
"Branding": "Branding",
"BrandingSectionDescription": "Zadajte informácie o vašej spoločnosti, pridajte odkazy na externé zdroje a e-mailové adresy zobrazené v rozhraní DocSpace.",
"BrandingSubtitle": "Toto nastavenie použite, ak chcete používateľom poskytnúť zážitok zo značky.",

View File

@ -5,6 +5,10 @@
"Code": "Koda za vstavitev",
"CopyWindowCode": "Kopiraj kodo za vdelavo okna",
"CreateSampleHeader": "Ustvarite vzorec vdelave DocSpace",
"CSPDescription": "Če želite varno vdelati DocSpace kot iframe na spletno mesto, dodajte njegov URL na seznam dovoljenih.",
"CSPHeader": "Vdelajte DocSpace kot iframe",
"CSPHelp": "Ta nastavitev je varnostni mehanizem, ki se lahko uporablja za zaščito pred napadi z vnašanjem vsebine. CSP opisuje varne vire za prenos prenos. Prenos iz virov, ki niso na `belem seznamu`, je blokiran. Določite domene (skupaj s protokolom), s katerimi bo delovalo.",
"CSPInputPlaceholder": "Vnesite URL kot v primeru: https://example.com",
"CustomizingDisplay": "Prilagajanje zaslona",
"DataDisplay": "Nastavitve prikaza podatkov",
"Descending": "Padajoče",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Varnostna kopija je bila uspešno ustvarjena.",
"BackupList": "Seznam varnostnih kopij",
"BackupListWarningText": "Če izbrišete kateri koli predmet iz seznama, bodo izbrisane tudi ustrezne datoteke. Tega dejanja ni mogoče razveljaviti. Če želite izbrisati vse datoteke, uporabite povezavo:",
"BetaLabel": "BETA",
"Branding": "Blagovna znamka",
"BrandingSectionDescription": "Specificiraj podatke o svojem podjetju, dodaj povezave do zunanjih virov in e-mail naslove, prikazane v vmesniku DocSpace.",
"BrandingSubtitle": "Uporabite to možnost, da uporabnikom zagotovite izkušnjo blagovne znamke.",

View File

@ -5,6 +5,10 @@
"Code": "Girilecek kod",
"CopyWindowCode": "Pencere gömülü kodunu kopyala",
"CreateSampleHeader": "Örnek DocSpace yerleştirmesi oluştur",
"CSPDescription": "DocSpace'i bir web sitesine iframe olarak güvenli bir şekilde gömmek için URL bağlantısını izin verilenler listenize ekleyin.",
"CSPHeader": "DocSpace'i iframe olarak gömün",
"CSPHelp": "Bu ayar, içerik yerleştirme saldırılarına karşı koruma sağlamak adına kullanılabilecek bir güvenlik mekanizmasıdır. CSP, güvenli kaynak indirme kaynaklarını niteler. 'Beyaz listede' yer almayan kaynaklardan indirme engellenmiştir. Çalışacağı etki alanlarını (protokol ile) belirtin.",
"CSPInputPlaceholder": "URL'yi bu şekilde girin: https://example.com",
"CustomizingDisplay": "Ekranı özelleştirme",
"DataDisplay": "Veri görüntüleme ayarları",
"Descending": "Azalan",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Yedekleme kopyası başarıyla oluşturuldu.",
"BackupList": "Yedekleme listesi",
"BackupListWarningText": "Listeden herhangi bir öğe silerseniz bu öğe ile ilgili dosyalar da silinir. Bu işlem geri alınamaz. Tüm dosyaları silmek için linke tıklayın:",
"BetaLabel": "BETA",
"Branding": "Markalaşma",
"BrandingSectionDescription": "Şirket bilgilerinizi belirtin, DocSpace arayüzünde görüntülenen harici kaynaklara ve e-posta adreslerine bağlantılar ekleyin.",
"BrandingSubtitle": "Kullanıcılara markayla ilgili deneyim sağlamak için bu seçeneği kullanın.",

View File

@ -5,6 +5,10 @@
"Code": "Код для вставлення",
"CopyWindowCode": "Скопіювати код вбудовування вікна",
"CreateSampleHeader": "Створити зразок вбудовування DocSpace",
"CSPDescription": "Щоб безпечно впровадити DocSpace на вебсайті як вбудований фрейм, додайте його URL-адресу до списку дозволених.",
"CSPHeader": "Впровадити DocSpace як вбудований фрейм",
"CSPHelp": "Цей параметр є механізмом безпеки, який можна використовувати для захисту від ін’єкційних атак. CSP описує безпечні джерела завантаження ресурсів. Завантаження з ресурсів, які не входять до «білого списку», заблоковано. Вкажіть домени (разом із протоколом), з якими він працюватиме.",
"CSPInputPlaceholder": "Введіть URL-адресу в такому форматі: https://example.com",
"CustomizingDisplay": "Настроювання показу",
"DataDisplay": "Параметри відображення даних",
"Descending": "За спаданням",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Резервна копія успішно створена.",
"BackupList": "Список резервних копій",
"BackupListWarningText": "Якщо ви видалите будь-які елементи зі списку, їх відповідні файли також будуть видалені. Цю дію не можна скасувати. Для видалення всіх файлів використовуйте посилання:",
"BetaLabel": "BETA",
"Branding": "Брендинг",
"BrandingSectionDescription": "Укажіть інформацію про свою компанію, додайте адреси електронної пошти та посилання на зовнішні ресурси, що будуть показані в інтерфейсі DocSpace.",
"BrandingSubtitle": "Використовуйте цей параметр, щоб продемонструвати користувачам ваш бренд.",

View File

@ -5,6 +5,10 @@
"Code": "Mã để chèn",
"CopyWindowCode": "Sao chép mã nhúng cửa sổ",
"CreateSampleHeader": "Tạo mẫu nhúng DocSpace",
"CSPDescription": "Để nhúng DocSpace một cách an toàn dưới dạng iframe trong một trang web, hãy thêm URL của nó vào danh sách cho phép của bạn.",
"CSPHeader": "Nhúng DocSpace dưới dạng iframe",
"CSPHelp": "Cài đặt này là một cơ chế bảo mật có thể được sử dụng để bảo vệ chống lại các cuộc tấn công injection. CSP mô tả các nguồn tài nguyên tải xuống an toàn. Việc tải xuống từ các nguồn tài nguyên không có trong “danh sách trắng” sẽ bị chặn. Chỉ định các miền (cùng với giao thức) mà nó sẽ hoạt động.",
"CSPInputPlaceholder": "Nhập URL như thế này: https://example.com",
"CustomizingDisplay": "Tùy chỉnh hiển thị",
"DataDisplay": "Cài đặt hiển thị dữ liệu",
"Descending": "Giảm dần",

View File

@ -39,6 +39,7 @@
"BackupCreatedSuccess": "Bản sao lưu đã được tạo thành công.",
"BackupList": "Danh sách sao lưu",
"BackupListWarningText": "Nếu bạn xóa bất kỳ mục nào trong danh sách, các file tương ứng của chúng cũng sẽ bị xóa. Tác vụ này không thể được hoàn tác. Để xóa tất cả các file này sử dụng liên kết:",
"BetaLabel": "BETA",
"Branding": "Thương hiệu",
"BrandingSectionDescription": "Nêu rõ thông tin công ty của bạn, thêm liên kết đến tài nguyên bên ngoài và địa chỉ email được hiển thị trong giao diện DocSpace.",
"BrandingSubtitle": "Sử dụng tùy chọn này để cung cấp trải nghiệm thương hiệu cho người dùng.",

View File

@ -2,6 +2,7 @@
"Error401Text": "抱歉,资源目前无法访问。",
"Error403Text": "对不起,拒绝访问。",
"Error404Text": "对不起,找不到资源。",
"ErrorDeactivatedText": "该协作空间已停用",
"ErrorEmptyResponse": "空响应",
"ErrorOfflineText": "未找到网络连接。",
"ErrorUnavailableText": "协作空间不可用"

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { inject, observer } from "mobx-react";
import { I18nextProvider, useTranslation } from "react-i18next";
@ -9,6 +9,11 @@ import { ZendeskAPI } from "@docspace/common/components/Zendesk";
import { ReportDialog } from "SRC_DIR/components/dialogs";
import DocspaceLogo from "SRC_DIR/DocspaceLogo";
import {
getCrashReport,
downloadJson,
getCurrentDate,
} from "SRC_DIR/helpers/crashReport";
import i18n from "./i18n";
@ -34,12 +39,30 @@ const StyledWrapper = styled.div`
}
`;
const Error520 = ({ errorLog, currentColorScheme, FirebaseHelper }) => {
const Error520 = ({
errorLog,
currentColorScheme,
FirebaseHelper,
user,
version,
}) => {
const { t } = useTranslation(["Common"]);
const { error } = useParams();
const [reportDialogVisible, setReportDialogVisible] = useState(false);
const autoSendReport = async () => {
const report = getCrashReport(user.id, version, user.cultureName, errorLog);
const reportWithDescription = Object.assign(report, {
description: "AUTO SEND",
});
await FirebaseHelper.sendCrashReport(reportWithDescription);
};
useEffect(() => {
FirebaseHelper.isEnabledDB && autoSendReport();
}, []);
const showDialog = () => {
setReportDialogVisible(true);
};
@ -63,9 +86,9 @@ const Error520 = ({ errorLog, currentColorScheme, FirebaseHelper }) => {
<ErrorContainer
isPrimaryButton={false}
headerText={t("SomethingWentWrong")}
customizedBodyText={t("SomethingWentWrongDescription")}
buttonText={t("SendReport")}
onClickButton={showDialog}
//customizedBodyText={t("SomethingWentWrongDescription")}
//buttonText={t("SendReport")}
//onClickButton={showDialog}
/>
<Link
className="link"
@ -88,10 +111,13 @@ const Error520 = ({ errorLog, currentColorScheme, FirebaseHelper }) => {
const Error520Wrapper = inject(({ auth }) => {
const { currentColorScheme, firebaseHelper } = auth.settingsStore;
const { user } = auth.userStore;
return {
currentColorScheme,
FirebaseHelper: firebaseHelper,
user,
version: auth.version,
};
})(observer(Error520));

View File

@ -20,7 +20,7 @@ const ErrorUnavailable = ({ logoUrl }) => {
return ready ? (
<StyledWrapper>
<DocspaceLogo />
<ErrorContainer headerText={t("ErrorUnavailableText")} />
<ErrorContainer headerText={t("ErrorDeactivatedText")} />
</StyledWrapper>
) : (
<></>

View File

@ -79,10 +79,6 @@ const HeaderContainer = styled.div`
font-size: 18px;
line-height: 59px !important;
}
.settings-section_header {
padding-top: 6px;
}
}
`;

View File

@ -8,7 +8,6 @@ import { TenantStatus } from "@docspace/common/constants";
import { startRestore } from "@docspace/common/api/portal";
import { combineUrl } from "@docspace/common/utils";
import toastr from "@docspace/components/toast/toastr";
import { request } from "@docspace/common/api/client";
const ButtonContainer = (props) => {
const {
@ -28,31 +27,13 @@ const ButtonContainer = (props) => {
setTenantStatus,
isFormReady,
getStorageParams,
uploadLocalFile,
} = props;
const navigate = useNavigate();
const [isUploadingLocalFile, setIsUploadingLocalFile] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const localFileUploading = async () => {
try {
const checkedFile = await request({
baseURL: combineUrl(window.DocSpaceConfig?.proxy?.url, config.homepage),
method: "post",
url: `/backupFileUpload.ashx`,
responseType: "text",
data: restoreResource,
});
return checkedFile;
} catch (e) {
toastr.error(e);
setIsUploadingLocalFile(false);
return null;
}
};
const onRestoreClick = async () => {
if (isCheckedThirdPartyStorage) {
const requiredFieldsFilled = isFormReady();
@ -76,16 +57,16 @@ const ButtonContainer = (props) => {
}
if (isCheckedLocalFile) {
const isUploadedFile = await localFileUploading();
const uploadedFile = await uploadLocalFile();
if (!isUploadedFile) {
if (!uploadedFile) {
toastr.error(t("BackupCreatedError"));
setIsLoading(false);
return;
}
if (isUploadedFile?.Message) {
toastr.error(isUploadedFile.Message);
setIsUploadingLocalFile(false);
if (!uploadedFile.data.EndUpload) {
toastr.error(uploadedFile.data.Message ?? t("BackupCreatedError"));
setIsLoading(false);
return;
}
@ -109,19 +90,17 @@ const ButtonContainer = (props) => {
} catch (e) {
toastr.error(e);
setIsUploadingLocalFile(false);
setIsLoading(false);
}
};
const isButtonDisabled =
isLoading ||
isUploadingLocalFile ||
!isMaxProgress ||
!isConfirmed ||
!isEnableRestore ||
!restoreResource;
const isLoadingButton = isUploadingLocalFile || isLoading;
const isLoadingButton = isLoading;
return (
<>
@ -156,11 +135,13 @@ export default inject(({ auth, backup }) => {
isFormReady,
getStorageParams,
restoreResource,
uploadLocalFile,
} = backup;
const { isRestoreAndAutoBackupAvailable } = currentQuotaStore;
const isMaxProgress = downloadingProgress === 100;
return {
uploadLocalFile,
isMaxProgress,
setTenantStatus,
isEnableRestore: isRestoreAndAutoBackupAvailable,

View File

@ -5,10 +5,7 @@ import FileInput from "@docspace/components/file-input";
const LocalFile = ({ setRestoreResource, isEnableRestore, t }) => {
const onClickInput = (file) => {
let data = new FormData();
data.append("file", file);
setRestoreResource(data);
setRestoreResource(file);
};
return (

View File

@ -164,7 +164,9 @@ class ThirdPartyServices extends React.Component {
(consumer) =>
consumer.title !== "Bitly" &&
consumer.title !== "WordPress" &&
consumer.title !== "DocuSign"
consumer.title !== "DocuSign" &&
consumer.name !== "clickatell" && //TODO: hide while 2fa by sms is not working
consumer.name !== "twilio"
);
const imgSrc = theme.isBase ? IntegrationSvgUrl : IntegrationDarkSvgUrl;

View File

@ -163,12 +163,13 @@ const TwoFactorAuth = (props) => {
label: t("Disabled"),
value: "none",
},
{
//TODO: hide while 2fa by sms is not working
/*{
id: "by-sms",
label: t("BySms"),
value: "sms",
disabled: !smsDisabled,
},
},*/
{
id: "by-app",
label: t("ByApp"),

View File

@ -92,7 +92,7 @@ const MainProfile = (props) => {
: DefaultUserAvatarMax;
const tooltipLanguage = (
<Text as="div" fontSize="12px">
<Text as="div" fontSize="12px" color="#333333">
<Trans t={t} i18nKey="NotFoundLanguage" ns="Common">
"In case you cannot find your language in the list of the available
ones, feel free to write to us at
@ -447,13 +447,8 @@ const MainProfile = (props) => {
export default inject(({ auth, peopleStore }) => {
const { withActivationBar, sendActivationLink } = auth.userStore;
const {
theme,
helpLink,
culture,
currentColorScheme,
documentationEmail,
} = auth.settingsStore;
const { theme, helpLink, culture, currentColorScheme, documentationEmail } =
auth.settingsStore;
const {
targetUser: profile,

View File

@ -159,6 +159,7 @@ const Sdk = ({
component = (
<FilesSelector
isPanelVisible={true}
isPanelOpen={true}
onSelectFile={onSelectFile}
filteredType={selectorType}
withSubfolders={false}

View File

@ -7,7 +7,9 @@ import {
} from "../pages/PortalSettings/utils";
import toastr from "@docspace/components/toast/toastr";
import { AutoBackupPeriod } from "@docspace/common/constants";
//import api from "@docspace/common/api";
import { combineUrl } from "@docspace/common/utils";
import config from "PACKAGE_FILE";
import { uploadBackup } from "@docspace/common/api/files";
const { EveryDayType, EveryWeekType } = AutoBackupPeriod;
@ -79,8 +81,8 @@ class BackupStore {
get isTheSameThirdPartyAccount() {
if (this.connectedThirdPartyAccount && this.selectedThirdPartyAccount)
return (
this.connectedThirdPartyAccount.providerKey ===
this.selectedThirdPartyAccount.provider_key
this.connectedThirdPartyAccount.title ===
this.selectedThirdPartyAccount.title
);
return true;
}
@ -617,6 +619,73 @@ class BackupStore {
setRestoreResource = (value) => {
this.restoreResource = value;
};
setChunkUploadSize = (chunkUploadSize) => {
this.chunkUploadSize = chunkUploadSize;
};
uploadFileChunks = async (requestsDataArray, url) => {
const length = requestsDataArray.length;
let res;
for (let index = 0; index < length; index++) {
res = await uploadBackup(
combineUrl(window.DocSpaceConfig?.proxy?.url, config.homepage, url),
requestsDataArray[index]
);
if (!res) return false;
if (res.data.Message || !res.data.Success) return res;
}
return res;
};
uploadLocalFile = async () => {
try {
const url = "/backupFileUpload.ashx";
const res = await uploadBackup(
combineUrl(
window.DocSpaceConfig?.proxy?.url,
config.homepage,
`${url}?init=true&totalSize=${this.restoreResource.size}`
)
);
if (!res) return false;
if (res.data.Message || !res.data.Success) return res;
const chunkUploadSize = res.data.ChunkSize;
const chunks = Math.ceil(
this.restoreResource.size / chunkUploadSize,
chunkUploadSize
);
const requestsDataArray = [];
let chunk = 0;
while (chunk < chunks) {
const offset = chunk * chunkUploadSize;
const formData = new FormData();
formData.append(
"file",
this.restoreResource.slice(offset, offset + chunkUploadSize)
);
requestsDataArray.push(formData);
chunk++;
}
return await this.uploadFileChunks(requestsDataArray, url);
} catch (e) {
toastr.error(e);
return null;
}
};
}
export default BackupStore;

View File

@ -824,7 +824,7 @@ class FilesActionStore {
return removeFiles(items, [], false, true)
.then(async (res) => {
if (res[0]?.error) return Promise.reject(res[0].error);
const data = res ? res : null;
const data = res[0] ? res[0] : null;
await this.uploadDataStore.loopFilesOperations(data, pbData);
this.updateCurrentFolder(null, [itemId], null, operationId);
})

View File

@ -170,9 +170,17 @@ class ProfileActionsStore {
};
onLogoutClick = () => {
this.authStore.logout().then(() => {
this.authStore.logout().then((ssoLogoutUrl) => {
this.filesStore.reset();
this.peopleStore.reset();
setTimeout(() => {
window.location.replace(
combineUrl(
window.DocSpaceConfig?.proxy?.url,
ssoLogoutUrl || "/login"
)
);
}, 300);
});
};

View File

@ -279,8 +279,8 @@ class SsoFormStore {
try {
return await validateCerts(data);
} catch (err) {
toastr.error(err);
console.error(err);
toastr.error(err?.response?.data || err);
console.error("validateCertificate failed", { err });
}
};

View File

@ -567,6 +567,10 @@ export function uploadFile(url, data) {
return axios.post(url, data);
}
export function uploadBackup(url, data) {
return axios.post(url, data);
}
export function downloadFiles(fileIds, folderIds, shareKey) {
const data = { fileIds, folderIds };
const share = shareKey ? `?share=${shareKey}` : "";

View File

@ -2,6 +2,7 @@ import ShareGoogleReactSvgUrl from "PUBLIC_DIR/images/share.google.react.svg?url
import ShareFacebookReactSvgUrl from "PUBLIC_DIR/images/share.facebook.react.svg?url";
import ShareTwitterReactSvgUrl from "PUBLIC_DIR/images/share.twitter.react.svg?url";
import ShareLinkedinReactSvgUrl from "PUBLIC_DIR/images/share.linkedin.react.svg?url";
import ShareMicrosoftReactSvgUrl from "PUBLIC_DIR/images/share.microsoft.react.svg?url";
export const LANGUAGE = "asc_language";
export const COOKIE_EXPIRATION_YEAR = 31536000000;
@ -266,6 +267,10 @@ export const providersData = Object.freeze({
label: "linkedin",
icon: ShareLinkedinReactSvgUrl,
},
microsoft: {
label: "microsoft",
icon: ShareMicrosoftReactSvgUrl,
},
});
export const LoaderStyle = {
title: "",

View File

@ -93,31 +93,35 @@ class AuthStore {
const requests = [];
const isPortalDeactivated = this.settingsStore.isPortalDeactivate;
const isPortalRestore =
this.settingsStore.tenantStatus === TenantStatus.PortalRestore;
if (
this.settingsStore.isLoaded &&
this.settingsStore.socketUrl &&
!this.settingsStore.isPublicRoom
) {
requests.push(
this.userStore.init().then(() => {
if (
this.isQuotaAvailable &&
this.settingsStore.tenantStatus !== TenantStatus.PortalRestore
) {
this.getTenantExtra();
}
})
);
!isPortalDeactivated &&
requests.push(
this.userStore.init().then(() => {
if (this.isQuotaAvailable && !isPortalRestore) {
this.getTenantExtra();
}
})
);
} else {
this.userStore.setIsLoaded(true);
}
if (this.isAuthenticated && !skipRequest) {
this.settingsStore.tenantStatus !== TenantStatus.PortalRestore &&
!isPortalRestore &&
!isPortalDeactivated &&
requests.push(this.settingsStore.getAdditionalResources());
if (!this.settingsStore.passwordSettings) {
if (this.settingsStore.tenantStatus !== TenantStatus.PortalRestore) {
if (!isPortalRestore && !isPortalDeactivated) {
requests.push(
this.settingsStore.getPortalPasswordSettings(),
this.settingsStore.getCompanyInfoSettings()
@ -320,10 +324,9 @@ class AuthStore {
};
logout = async () => {
await api.user.logout();
const ssoLogoutUrl = await api.user.logout();
this.isLogout = true;
//console.log("Logout response ", response);
setWithCredentialsStatus(false);
@ -331,6 +334,8 @@ class AuthStore {
isDesktop && logoutDesktop();
if (ssoLogoutUrl) return ssoLogoutUrl;
this.reset(true);
this.userStore.setUser(null);
this.init();

View File

@ -441,6 +441,10 @@ class SettingsStore {
}
};
get isPortalDeactivate() {
return this.tenantStatus === TenantStatus.PortalDeactivate;
}
init = async () => {
this.setIsLoading(true);
const requests = [];
@ -448,12 +452,15 @@ class SettingsStore {
requests.push(
this.getPortalSettings(),
this.getAppearanceTheme(),
this.getWhiteLabelLogoUrls(),
this.getBuildVersionInfo()
this.getWhiteLabelLogoUrls()
);
await Promise.all(requests);
if (!this.isPortalDeactivate) {
await this.getBuildVersionInfo();
}
this.setIsLoading(false);
this.setIsLoaded(true);
};

View File

@ -283,6 +283,8 @@ export function getProviderTranslation(provider, t, linked = false) {
return t("Common:SignInWithTwitter");
case "linkedin":
return t("Common:SignInWithLinkedIn");
case "microsoft":
return t("Common:SignInWithMicrosoft");
case "sso":
return t("Common:SignInWithSso");
}

View File

@ -283,9 +283,11 @@ internal class DropboxStorage : IThirdPartyStorage<FileMetadata, FolderMetadata,
public async Task<Metadata> FinishResumableSessionAsync(string dropboxSession, string dropboxFilePath, long offset)
{
using var tempBody = new MemoryStream();
return await _dropboxClient.Files.UploadSessionFinishAsync(
new UploadSessionCursor(dropboxSession, (ulong)offset),
new CommitInfo(dropboxFilePath, WriteMode.Overwrite.Instance));
new CommitInfo(dropboxFilePath, WriteMode.Overwrite.Instance),
body: tempBody);
}
public string MakeId(Metadata dropboxItem)

View File

@ -479,7 +479,7 @@ public class EntryManager
.ToListAsync();
var filesCount = count - folders.Count;
var filesOffset = folders.Count > 0 ? 0 : from - await allFoldersCountTask;
var filesOffset = Math.Max(folders.Count > 0 ? 0 : from - await allFoldersCountTask, 0);
var files = await fileDao.GetFilesAsync(parent.Id, orderBy, filesFilterType, subjectGroup, subjectId, filesSearchText, searchInContent, withSubfolders, excludeSubject, filesOffset, filesCount)
.ToListAsync();

View File

@ -0,0 +1,6 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0H9.50383V9.50383H0V0Z" fill="#F25022"/>
<path d="M10.4961 0H20V9.50383H10.4961V0Z" fill="#7FBA00"/>
<path d="M0 10.4961H9.50383V19.9999H0V10.4961Z" fill="#00A4EF"/>
<path d="M10.4961 10.4961H20V19.9999H10.4961V10.4961Z" fill="#FFB900"/>
</svg>

After

Width:  |  Height:  |  Size: 353 B

View File

@ -104,6 +104,7 @@
"EncryptionKeysReload": "Şifrələmə düymələri yenidən daxil edilməlidir",
"EnterName": "Adı daxil edin",
"Error": "Səhv",
"ErrorEmptyList": "Aktivlərin siyahısı dəyişdirilib. Zəhmət olmasa, məzmunu yoxlayın və yenidən cəhd edin.",
"ErrorInternalServer": "Daxili server xətası. Daha sonra yenidən cəhd edin.",
"ErrorReport": "Xəta hesabatı",
"ErrorReportDescription": "Hansı məlumatın daxil olduğunu görmək üçün aşağıdakı hesabatıın. Xəta hesabatlarında istifadəçilərin şəxsi məlumatları əks olunmur. Komandamızın problemi daha yaxşı başa düşməsi üçün şərh sahəsindən istifadə edərək məsələni aydın şəkildə təsvir edin.",
@ -239,6 +240,7 @@
"SignInWithFacebook": "Facebook ilə giriş edin",
"SignInWithGoogle": "Google ilə giriş edin",
"SignInWithLinkedIn": "LinkedIn ilə giriş edin",
"SignInWithMicrosoft": "Microsoft ilə giriş edin",
"SignInWithSso": "SSO ilə daxil olun",
"SignInWithTwitter": "Twitter ilə giriş edin",
"Size": "Ölçü",

View File

@ -104,6 +104,7 @@
"EncryptionKeysReload": "Криптиращите ключове трябва да се въведат отново",
"EnterName": "Въведи име",
"Error": "Грешка",
"ErrorEmptyList": "Списъкът с обекти бе променен. Моля, проверете съдържанието и опитайте отново.",
"ErrorInternalServer": "Вътрешна грешка на сървъра. Опитайте отново по-късно.",
"ErrorReport": "Доклад за грешки",
"ErrorReportDescription": "Отворете доклада по-долу, за да видите какви данни са включени. Докладите за грешки не съдържат лични данни на потребителите. За да помогнете на нашия екип да разбере по-добре проблема, опишете го в свободна форма, като използвате полето за коментар.",
@ -239,6 +240,7 @@
"SignInWithFacebook": "Влез с Facebook",
"SignInWithGoogle": "Влез с Google",
"SignInWithLinkedIn": "Влез с LinkedIn",
"SignInWithMicrosoft": "Влез с Microsoft",
"SignInWithSso": "Вход със SSO",
"SignInWithTwitter": "Влез с Twitter",
"Size": "Размер",

View File

@ -104,6 +104,7 @@
"EncryptionKeysReload": "Šifrovací klíče musí být zadány znovu",
"EnterName": "Zadejte název",
"Error": "Chyba",
"ErrorEmptyList": "Seznam entit byl změněn. Zkontrolujte prosím jeho obsah a zkuste to znovu.",
"ErrorInternalServer": "Interní chyba serveru. Zkuste to později.",
"ErrorReport": "Chybové hlášení",
"ErrorReportDescription": "Otevřete níže uvedenou zprávu a podívejte se, jaké údaje obsahuje. Chybová hlášení neobsahují žádné osobní údaje uživatelů. Abyste našemu týmu pomohli lépe porozumět problému, popište jej ve volném formuláři pomocí pole pro komentář.",
@ -239,6 +240,7 @@
"SignInWithFacebook": "Přihlásit se pomocí Facebooku",
"SignInWithGoogle": "Přihlásit se pomocí Google",
"SignInWithLinkedIn": "Přihlásit se pomocí LinkedIn",
"SignInWithMicrosoft": "Přihlásit se pomocí Microsoft",
"SignInWithSso": "Přihlásit se pomocí SSO",
"SignInWithTwitter": "Přihlásit se pomocí Twitteru",
"Size": "Velikost",

View File

@ -104,6 +104,7 @@
"EncryptionKeysReload": "Verschlüsselungsschlüssel müssen erneut eingegeben werden",
"EnterName": "Namen eingeben",
"Error": "Fehler",
"ErrorEmptyList": "Die Liste der Entitäten wurde geändert. Bitte überprüfen Sie den Inhalt und versuchen Sie es erneut.",
"ErrorInternalServer": "Interner Serverfehler. Versuchen Sie nochmals später.",
"ErrorReport": "Fehlerbericht ",
"ErrorReportDescription": "Öffnen Sie den unten stehenden Bericht, um zu sehen, welche Daten enthalten sind. Die Fehlerberichte enthalten keine persönlichen Benutzerdaten. Um unserem Team zu helfen, das Problem besser zu verstehen, beschreiben Sie es im freien Formular im Kommentarfeld.",
@ -239,6 +240,7 @@
"SignInWithFacebook": "Login über Facebook",
"SignInWithGoogle": "Login über Google",
"SignInWithLinkedIn": "Login über LinkedIn",
"SignInWithMicrosoft": "Login über Microsoft",
"SignInWithSso": "Mit SSO anmelden",
"SignInWithTwitter": "Login über Twitter",
"Size": "Größe",

View File

@ -104,6 +104,7 @@
"EncryptionKeysReload": "Τα κλειδιά κρυπτογράφησης πρέπει να εισαχθούν εκ νέου",
"EnterName": "Εισαγωγή ονόματος",
"Error": "Σφάλμα",
"ErrorEmptyList": "Ο κατάλογος των οντοτήτων έχει αλλάξει. Ελέγξτε τα περιεχόμενα και προσπαθήστε ξανά.",
"ErrorInternalServer": "Σφάλμα εσωτερικού διακομιστή. Δοκιμάστε ξανά αργότερα.",
"ErrorReport": "Αναφορά σφάλματος",
"ErrorReportDescription": "Ανοίξτε την παρακάτω αναφορά για να δείτε ποια δεδομένα περιλαμβάνονται. Οι αναφορές σφαλμάτων δεν περιέχουν προσωπικά δεδομένα των χρηστών. Για να βοηθήσετε την ομάδα μας να κατανοήσει καλύτερα το πρόβλημα, περιγράψτε το στη φόρμα χρησιμοποιώντας το πεδίο σχολίων.",
@ -239,6 +240,7 @@
"SignInWithFacebook": "Συνδεθείτε με το Facebook",
"SignInWithGoogle": "Συνδεθείτε με την Google",
"SignInWithLinkedIn": "Συνδεθείτε με το LinkedIn",
"SignInWithMicrosoft": "Συνδεθείτε με το Microsoft",
"SignInWithSso": "Σύνδεση με SSO",
"SignInWithTwitter": "Συνδεθείτε με το Twitter",
"Size": "Μέγεθος",

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