Merge branch 'develop' into refactoring/generic-classes

This commit is contained in:
Anton Suhorukov 2023-04-04 12:33:26 +03:00
commit a733c29c2b
1059 changed files with 11815 additions and 7487 deletions

View File

@ -1,6 +1,6 @@
@echo off
pwsh %~dp0/build.backend.docker.ps1 %1
pwsh %~dp0/build.backend.docker.ps1 %*
echo.

View File

@ -63,7 +63,7 @@ if [ "${arch_name}" = "x86_64" ]; then
docker compose -f db.yml up -d
elif [ "${arch_name}" = "arm64" ]; then
echo "CPU Type: arm64 -> run db.yml with arm64v8 image"
MYSQL_IMAGE=arm64v8/mysql:8.0.31-oracle \
MYSQL_IMAGE=arm64v8/mysql:8.0.32-oracle \
docker compose -f db.yml up -d
else
echo "Error: Unknown CPU Type: ${arch_name}."

View File

@ -84,11 +84,11 @@ else
fi
# add onlyoffice repo
echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] http://download.onlyoffice.com/repo/debian squeeze main" | tee /etc/apt/sources.list.d/onlyoffice.list
mkdir -p -m 700 $HOME/.gnupg
gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/onlyoffice.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys CB2DE8E5
chmod 644 /usr/share/keyrings/onlyoffice.gpg
echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] http://download.onlyoffice.com/repo/debian squeeze main" | tee /etc/apt/sources.list.d/onlyoffice.list
echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] http://static.teamlab.info.s3.amazonaws.com/repo/4testing/debian stable main" | sudo tee /etc/apt/sources.list.d/onlyoffice4testing.list
curl -fsSL https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/onlyoffice.gpg --import
chmod 644 /usr/share/keyrings/onlyoffice.gpg
declare -x LANG="en_US.UTF-8"
declare -x LANGUAGE="en_US:en"

View File

@ -20,13 +20,12 @@ if [ "$DOCUMENT_SERVER_INSTALLED" = "false" ]; then
DS_DB_PWD=$DS_COMMON_NAME;
DS_JWT_ENABLED=${DS_JWT_ENABLED:-true};
DS_JWT_SECRET="$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 12)";
DS_JWT_SECRET="$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)";
DS_JWT_HEADER="AuthorizationJwt";
if ! su - postgres -s /bin/bash -c "psql -lqt" | cut -d \| -f 1 | grep -q ${DS_DB_NAME}; then
su - postgres -s /bin/bash -c "psql -c \"CREATE DATABASE ${DS_DB_NAME};\""
su - postgres -s /bin/bash -c "psql -c \"CREATE USER ${DS_DB_USER} WITH password '${DS_DB_PWD}';\""
su - postgres -s /bin/bash -c "psql -c \"GRANT ALL privileges ON DATABASE ${DS_DB_NAME} TO ${DS_DB_USER};\""
su - postgres -s /bin/bash -c "psql -c \"CREATE DATABASE ${DS_DB_NAME} OWNER ${DS_DB_USER};\""
fi
echo ${package_sysname}-documentserver $DS_COMMON_NAME/ds-port select $DS_PORT | sudo debconf-set-selections

View File

@ -37,7 +37,7 @@ fi
locale-gen en_US.UTF-8
# add elasticsearch repo
ELASTIC_VERSION="7.16.3"
ELASTIC_VERSION="7.10.0"
ELASTIC_DIST=$(echo $ELASTIC_VERSION | awk '{ print int($1) }')
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/elastic-${ELASTIC_DIST}.x.gpg --import
echo "deb [signed-by=/usr/share/keyrings/elastic-${ELASTIC_DIST}.x.gpg] https://artifacts.elastic.co/packages/${ELASTIC_DIST}.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-${ELASTIC_DIST}.x.list
@ -48,14 +48,11 @@ curl -sL https://deb.nodesource.com/setup_16.x | bash -
#add dotnet repo
if [ "$DIST" = "debian" ] && [ "$DISTRIB_CODENAME" = "stretch" ]; then
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
wget -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/debian/9/prod.list
elif [ "$DISTRIB_CODENAME" != "jammy" ]; then
curl https://packages.microsoft.com/config/$DIST/10/packages-microsoft-prod.deb -O
else
curl https://packages.microsoft.com/config/$DIST/$REV/packages-microsoft-prod.deb -O
dpkg -i packages-microsoft-prod.deb && rm packages-microsoft-prod.deb
elif dpkg -l | grep -q "packages-microsoft-prod"; then
apt-get purge -y packages-microsoft-prod dotnet*
fi
dpkg -i packages-microsoft-prod.deb && rm packages-microsoft-prod.deb
MYSQL_REPO_VERSION="$(curl https://repo.mysql.com | grep -oP 'mysql-apt-config_\K.*' | grep -o '^[^_]*' | sort --version-sort --field-separator=. | tail -n1)"
MYSQL_PACKAGE_NAME="mysql-apt-config_${MYSQL_REPO_VERSION}_all.deb"

View File

@ -747,7 +747,7 @@ set_jwt_secret () {
fi
if [[ -z ${JWT_SECRET} ]] && [[ "$UPDATE" != "true" ]]; then
DOCUMENT_SERVER_JWT_SECRET=$(get_random_str 12);
DOCUMENT_SERVER_JWT_SECRET=$(get_random_str 32);
fi
}
@ -870,6 +870,7 @@ install_product () {
docker-compose -f $BASE_DIR/migration-runner.yml up -d
docker-compose -f $BASE_DIR/${PRODUCT}.yml up -d
docker-compose -f $BASE_DIR/notify.yml up -d
docker-compose -f $BASE_DIR/healthchecks.yml up -d
}
get_local_image_RepoDigests() {

View File

@ -86,7 +86,7 @@ name=onlyoffice repo
baseurl=http://download.onlyoffice.com/repo/centos/main/noarch/
gpgcheck=1
enabled=1
gpgkey=http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x8320CA65CB2DE8E5
gpgkey=https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE
END
cat > /etc/yum.repos.d/onlyoffice4testing.repo <<END
@ -95,7 +95,7 @@ name=onlyoffice4testing repo
baseurl=http://static.teamlab.info.s3.amazonaws.com/repo/4testing/centos/main/noarch/
gpgcheck=1
enabled=1
gpgkey=http://static.teamlab.info.s3.amazonaws.com/k8s
gpgkey=https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE
END
#DOWNLOAD_URL_PREFIX="https://download.onlyoffice.com/install-appserver/install-RedHat"

View File

@ -73,13 +73,12 @@ if [ "$DOCUMENT_SERVER_INSTALLED" = "false" ]; then
DS_DB_PWD=$DS_COMMON_NAME;
declare -x JWT_ENABLED=true;
declare -x JWT_SECRET="$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 12)";
declare -x JWT_SECRET="$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)";
declare -x JWT_HEADER="AuthorizationJwt";
if ! su - postgres -s /bin/bash -c "psql -lqt" | cut -d \| -f 1 | grep -q ${DS_DB_NAME}; then
su - postgres -s /bin/bash -c "psql -c \"CREATE DATABASE ${DS_DB_NAME};\""
su - postgres -s /bin/bash -c "psql -c \"CREATE USER ${DS_DB_USER} WITH password '${DS_DB_PWD}';\""
su - postgres -s /bin/bash -c "psql -c \"GRANT ALL privileges ON DATABASE ${DS_DB_NAME} TO ${DS_DB_USER};\""
su - postgres -s /bin/bash -c "psql -c \"CREATE DATABASE ${DS_DB_NAME} OWNER ${DS_DB_USER};\""
fi
${package_manager} -y install ${package_sysname}-documentserver

View File

@ -79,7 +79,7 @@ if ! rpm -q mysql-community-server; then
fi
#add elasticsearch repo
ELASTIC_VERSION="7.16.3"
ELASTIC_VERSION="7.10.0"
ELASTIC_DIST=$(echo $ELASTIC_VERSION | awk '{ print int($1) }')
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
cat > /etc/yum.repos.d/elasticsearch.repo <<END

View File

@ -1,4 +1,5 @@
#!/bin/bash
set -xe
SRC_PATH="/AppServer"
ARGS=""

View File

@ -1,4 +1,5 @@
#!/bin/bash
set -xe
SRC_PATH="/AppServer"
BUILD_ARGS="build"

View File

@ -212,6 +212,10 @@ set_core_machinekey () {
CORE_MACHINEKEY=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 12);
echo $CORE_MACHINEKEY >> $APP_DIR/.private/machinekey
fi
$JSON_USERCONF "this.core={'base-domain': \"$APP_HOST\", 'machinekey': \"$CORE_MACHINEKEY\" }" >/dev/null 2>&1
$JSON $APP_DIR/apisystem.$ENVIRONMENT.json -e "this.core={'base-domain': \"$APP_HOST\", 'machinekey': \"$CORE_MACHINEKEY\" }" >/dev/null 2>&1
sed "s^\(machine_key\)\s*=.*^\1 = ${CORE_MACHINEKEY}^g" -i $APP_DIR/radicale.config
}
install_json() {
@ -226,9 +230,6 @@ install_json() {
if [ ! -e $USER_CONF ]; then
echo "{}" >> $USER_CONF
chown ${PACKAGE_SYSNAME}:${PACKAGE_SYSNAME} $USER_CONF
set_core_machinekey
$JSON_USERCONF "this.core={'base-domain': \"$APP_HOST\", 'machinekey': \"$CORE_MACHINEKEY\" }" >/dev/null 2>&1
fi
}
@ -303,8 +304,9 @@ establish_mysql_conn(){
SSL Mode=none;AllowPublicKeyRetrieval=true;Connection Timeout=30;Maximum Pool Size=300"
$JSON_USERCONF "this.ConnectionStrings={'default': {'connectionString': \"$CONNECTION_STRING\"}}" >/dev/null 2>&1
sed "s/Server=.*/$CONNECTION_STRING\"/g" -i $PRODUCT_DIR/services/ASC.Migration.Runner/appsettings.runner.json
$JSON $APP_DIR/apisystem.$ENVIRONMENT.json -e "this.ConnectionStrings={'default': {'connectionString': \"$CONNECTION_STRING\"}}" >/dev/null 2>&1
sed "s_\(\"ConnectionString\":\).*_\1 \"${CONNECTION_STRING//&/\\&}\"_" -i $PRODUCT_DIR/services/ASC.Migration.Runner/appsettings.runner.json
change_mysql_config
#Enable database migration
@ -435,7 +437,7 @@ setup_nginx(){
shopt -s nocasematch
PORTS=()
if $(getenforce) >/dev/null 2>&1; then
if command -v getenforce &> /dev/null; then
case $(getenforce) in
enforcing|permissive)
PORTS+=('5000') #ASC.Web.Api
@ -446,14 +448,17 @@ setup_nginx(){
PORTS+=('5006') #ASC.Studio.Notify
PORTS+=('5007') #ASC.Files/server
PORTS+=('5009') #ASC.Files/service
PORTS+=('5010') #ASC.ApiSystem
PORTS+=('5011') #ASC.Login
PORTS+=('5012') #ASC.Data.Backup
PORTS+=('5013') #ASC.Files/editor
PORTS+=('5027') #ASC.ClearEvents
PORTS+=('5028') #ASC.Socket.IO
PORTS+=('5032') #ASC.Data.Backup.BackgroundTasks
PORTS+=('5033') #ASC.Web.HealthChecks
PORTS+=('5100') #ASC.ApiCache
PORTS+=('8081') #Storybook
PORTS+=('9834') #ASC.SsoAuth
PORTS+=('9899') #ASC.Socket.IO
setsebool -P httpd_can_network_connect on
;;
disabled)
@ -480,8 +485,7 @@ setup_docs() {
local JSON_DSCONF="$JSON $DS_CONF -e"
#Changing the Docs port in nginx conf
sed -i "s/0.0.0.0:.*;/0.0.0.0:$DOCUMENT_SERVER_PORT;/" $NGINX_CONF/ds.conf
sed -i "s/]:.*;/]:$DOCUMENT_SERVER_PORT default_server;/g" $NGINX_CONF/ds.conf
sed 's/\(listen .*:\)\([0-9]\{2,5\}\b\)\( default_server\)\?\(;\)/\1'${DS_PORT}'\3\4/' -i $NGINX_CONF/ds.conf
sed "0,/proxy_pass .*;/{s/proxy_pass .*;/proxy_pass http:\/\/${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT};/}" -i $NGINX_CONF/${PACKAGE_SYSNAME}.conf
#Enable JWT validation for Docs
@ -495,7 +499,7 @@ setup_docs() {
#Save Docs address and JWT in .json
$JSON_USERCONF "this.files={'docservice': {\
'secret': {'value': \"$DOCUMENT_SERVER_JWT_SECRET\",'header': \"$DOCUMENT_SERVER_JWT_HEADER\"}, \
'url': {'public': \"http://${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT}\", 'internal': \"http://${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT}\",'portal': \"http://$APP_HOST:$APP_PORT\"}}}" >/dev/null 2>&1
'url': {'public': \"http://${DOCUMENT_SERVER_HOST}:${DOCUMENT_SERVER_PORT}\", 'internal': \"\",'portal': \"http://$APP_HOST:$APP_PORT\"}}}" >/dev/null 2>&1
echo "OK"
}
@ -562,7 +566,7 @@ setup_elasticsearch() {
echo -n "Configuring elasticsearch... "
#Save elasticsearch parameters in .json
$JSON $APP_DIR/elastic.json -e "this.elastic={'Scheme': \"${ELK_SHEME}\",'Host': \"${ELK_HOST}\",'Port': \"${ELK_PORT}\",'Threads': \"1\" }" >/dev/null 2>&1
$JSON $APP_DIR/elastic.$ENVIRONMENT.json -e "this.elastic={'Scheme': \"${ELK_SHEME}\",'Host': \"${ELK_HOST}\",'Port': \"${ELK_PORT}\",'Threads': \"1\" }" >/dev/null 2>&1
change_elasticsearch_config
@ -586,7 +590,7 @@ setup_redis() {
setup_rabbitmq() {
echo -n "Configuring rabbitmq... "
$JSON $APP_DIR/rabbitmq.json -e "this.RabbitMQ={'Hostname': \"${RABBITMQ_HOST}\",'UserName': \"${RABBITMQ_USER}\",'Password': \"${RABBITMQ_PASSWORD}\",'Port': \"${RABBITMQ_PORT}\",'VirtualHost': \"/\" }" >/dev/null 2>&1
$JSON $APP_DIR/rabbitmq.$ENVIRONMENT.json -e "this.RabbitMQ={'Hostname': \"${RABBITMQ_HOST}\",'UserName': \"${RABBITMQ_USER}\",'Password': \"${RABBITMQ_PASSWORD}\",'Port': \"${RABBITMQ_PORT}\",'VirtualHost': \"/\" }" >/dev/null 2>&1
systemctl enable rabbitmq-server >/dev/null 2>&1
systemctl restart rabbitmq-server
@ -594,6 +598,15 @@ setup_rabbitmq() {
echo "OK"
}
product_configuration(){
echo -n "Configuring ${PRODUCT}... "
$JSON $APP_DIR/plugins.json -e "this.pluginsConf={'path': \"$PRODUCT_DIR/Tools/radicale/plugins/\" }" >/dev/null 2>&1
set_core_machinekey
echo "OK"
}
if command -v yum >/dev/null 2>&1; then
DIST="RedHat"
PACKAGE_MANAGER="rpm -q"
@ -607,6 +620,7 @@ elif command -v apt >/dev/null 2>&1; then
fi
install_json
product_configuration
if $PACKAGE_MANAGER mysql-client >/dev/null 2>&1 || $PACKAGE_MANAGER mysql-community-client >/dev/null 2>&1; then
input_db_params

View File

@ -1,4 +1,5 @@
#!/bin/bash
set -xe
SRC_PATH="/AppServer"
BUILD_PATH="/publish"

View File

@ -1,4 +1,5 @@
#!/bin/bash
set -xe
BASEDIR="$(cd $(dirname $0) && pwd)"
BUILD_PATH="$BASEDIR/modules"
@ -75,7 +76,7 @@ reassign_values (){
EXEC_FILE="ASC.ApiSystem.dll"
;;
socket )
SERVICE_PORT="5028"
SERVICE_PORT="9899"
WORK_DIR="${BASE_DIR}/services/ASC.Socket.IO/"
EXEC_FILE="server.js"
;;
@ -88,6 +89,7 @@ reassign_values (){
SERVICE_PORT="5005"
WORK_DIR="${BASE_DIR}/services/ASC.Notify/"
EXEC_FILE="ASC.Notify.dll"
CORE_EVENT_BUS=" --core:eventBus:subscriptionClientName=asc_event_bus_notify_queue"
;;
people-server )
SERVICE_PORT="5004"
@ -103,6 +105,7 @@ reassign_values (){
SERVICE_PORT="5009"
WORK_DIR="${BASE_DIR}/products/ASC.Files/service/"
EXEC_FILE="ASC.Files.Service.dll"
CORE_EVENT_BUS=" --core:eventBus:subscriptionClientName=asc_event_bus_files_service_queue"
;;
studio )
SERVICE_PORT="5003"
@ -128,6 +131,7 @@ reassign_values (){
SERVICE_PORT="5032"
WORK_DIR="${BASE_DIR}/services/ASC.Data.Backup.BackgroundTasks/"
EXEC_FILE="ASC.Data.Backup.BackgroundTasks.dll"
CORE_EVENT_BUS=" --core:eventBus:subscriptionClientName=asc_event_bus_backup_queue"
;;
doceditor )
SERVICE_PORT="5013"
@ -162,7 +166,8 @@ reassign_values (){
SERVICE_TYPE="notify"
RESTART="always"
EXEC_START="${DOTNET_RUN} ${WORK_DIR}${EXEC_FILE} --urls=${APP_URLS}:${SERVICE_PORT} --pathToConf=${PATH_TO_CONF} \
--'\$STORAGE_ROOT'=${STORAGE_ROOT} --log:dir=${LOG_DIR} --log:name=${SERVICE_NAME}${CORE}${ENVIRONMENT}"
--'\$STORAGE_ROOT'=${STORAGE_ROOT} --log:dir=${LOG_DIR} --log:name=${SERVICE_NAME}${CORE}${CORE_EVENT_BUS}${ENVIRONMENT}"
unset CORE_EVENT_BUS
fi
}

View File

@ -12,6 +12,7 @@ Architecture: any
Depends: debconf,
${misc:Depends}, ${shlibs:Depends},
{{product}}-api (= {{package_header_tag_version}}),
{{product}}-api-system (= {{package_header_tag_version}}),
{{product}}-backup (= {{package_header_tag_version}}),
{{product}}-backup-background (= {{package_header_tag_version}}),
{{product}}-clear-events (= {{package_header_tag_version}}),

View File

@ -7,7 +7,7 @@
CONTAINER_PREFIX=${PRODUCT}-
MYSQL_VERSION=8.0.32
MYSQL_IMAGE=mysql:${MYSQL_VERSION}
ELK_VERSION=7.13.1
ELK_VERSION=7.10.0
SERVICE_PORT=5050
DOCUMENT_SERVER_IMAGE_NAME=onlyoffice/4testing-documentserver-ee:latest
DOCKERFILE=Dockerfile.app

View File

@ -227,6 +227,10 @@ CMD ["ASC.Files.dll", "ASC.Files"]
## ASC.Files.Service ##
FROM dotnetrun AS files_services
RUN apt-get -y update && \
apt-get install -yq ffmpeg &&\
rm -rf /var/lib/apt/lists/*
WORKDIR ${BUILD_PATH}/products/ASC.Files/service/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py

View File

@ -129,8 +129,8 @@ ENV DNS_NAMESERVER=127.0.0.11 \
MAP_HASH_BUCKET_SIZE=""
RUN apt-get -y update && \
apt-get install -yq vim && \
apt-get install -y dos2unix && \
apt-get install -yq vim \
dos2unix && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /usr/share/nginx/html/*
@ -150,7 +150,7 @@ RUN dos2unix /docker-entrypoint.d/prepare-nginx-proxy.sh && \
RUN chown nginx:nginx /etc/nginx/* -R && \
chown nginx:nginx /docker-entrypoint.d/* && \
# changes for upstream configure
sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
# sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5012/$service_backup/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5007/$service_files/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5004/$service_people_server/' /etc/nginx/conf.d/onlyoffice.conf && \
@ -164,6 +164,7 @@ RUN chown nginx:nginx /etc/nginx/* -R && \
sed -i 's/127.0.0.1:5011/$service_login/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5001/$service_client/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5033/$service_healthchecks/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/$public_root/\/var\/www\/public\//' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/172.*/$document_server;/' /etc/nginx/conf.d/onlyoffice.conf
## ASC.Data.Backup.BackgroundTasks ##
@ -176,22 +177,22 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.B
CMD ["ASC.Data.Backup.BackgroundTasks.dll", "ASC.Data.Backup.BackgroundTasks"]
# ASC.ApiSystem ##
FROM dotnetrun AS api_system
WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
# FROM dotnetrun AS api_system
# WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
# CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
## ASC.ClearEvents ##
FROM dotnetrun AS clear-events
WORKDIR ${BUILD_PATH}/services/ASC.ClearEvents/
# FROM dotnetrun AS clear-events
# WORKDIR ${BUILD_PATH}/services/ASC.ClearEvents/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ClearEvents/service/ .
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ClearEvents/service/ .
CMD ["ASC.ClearEvents.dll", "ASC.ClearEvents"]
# CMD ["ASC.ClearEvents.dll", "ASC.ClearEvents"]
## ASC.Migration ##
# FROM dotnetrun AS migration
@ -222,6 +223,9 @@ CMD ["ASC.Files.dll", "ASC.Files"]
## ASC.Files.Service ##
FROM dotnetrun AS files_services
RUN apt-get -y update && \
apt-get install -yq ffmpeg
WORKDIR ${BUILD_PATH}/products/ASC.Files/service/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
@ -257,13 +261,13 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Socket
CMD ["server.js", "ASC.Socket.IO"]
## ASC.SsoAuth ##
FROM noderun AS ssoauth
WORKDIR ${BUILD_PATH}/services/ASC.SsoAuth/
# FROM noderun AS ssoauth
# WORKDIR ${BUILD_PATH}/services/ASC.SsoAuth/
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.SsoAuth/service/ .
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.SsoAuth/service/ .
CMD ["app.js", "ASC.SsoAuth"]
# CMD ["app.js", "ASC.SsoAuth"]
## ASC.Studio.Notify ##
FROM dotnetrun AS studio_notify
@ -328,7 +332,7 @@ ENV SRC_PATH=${SRC_PATH}
WORKDIR ${BUILD_PATH}/services/ASC.Migration.Runner/
RUN apt-get update && \
apt-get install -y dos2unix
apt-get install -yq dos2unix
COPY docker-migration-entrypoint.sh docker-migration-entrypoint.sh

View File

@ -8,12 +8,12 @@ services:
target: backup_background
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-backup-background:${DOCKER_TAG}"
onlyoffice-clear-events:
build:
context: ./
dockerfile: "${DOCKERFILE}"
target: clear-events
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
# onlyoffice-clear-events:
# build:
# context: ./
# dockerfile: "${DOCKERFILE}"
# target: clear-events
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
# onlyoffice-migration:
# build:
@ -92,12 +92,12 @@ services:
target: api
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
onlyoffice-api-system:
build:
context: ./
dockerfile: "${DOCKERFILE}"
target: api_system
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
# onlyoffice-api-system:
# build:
# context: ./
# dockerfile: "${DOCKERFILE}"
# target: api_system
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
onlyoffice-studio:
build:
@ -106,12 +106,12 @@ services:
target: studio
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio:${DOCKER_TAG}"
onlyoffice-ssoauth:
build:
context: ./
dockerfile: "${DOCKERFILE}"
target: ssoauth
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
# onlyoffice-ssoauth:
# build:
# context: ./
# dockerfile: "${DOCKERFILE}"
# target: ssoauth
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
# onlyoffice-webhooks-service:
# build:

View File

@ -3,5 +3,3 @@ sql_mode = 'NO_ENGINE_SUBSTITUTION'
max_connections = 1000
max_allowed_packet = 1048576000
group_concat_max_len = 2048
log-error = /var/log/mysql/error.log

View File

@ -24,7 +24,6 @@ services:
- ./config/mysql/conf.d/:/etc/mysql/conf.d
networks:
- ${NETWORK_NAME}
tmpfs: /var/log/mysql/
networks:
onlyoffice:

View File

@ -146,12 +146,19 @@ updateJsonData(jsonData,"$.files.docservice.secret.value", DOCUMENT_SERVER_JWT_S
updateJsonData(jsonData,"$.files.docservice.secret.header", DOCUMENT_SERVER_JWT_HEADER)
writeJsonFile(filePath, jsonData)
filePath = "/app/onlyoffice/config/apisystem.json"
jsonData = openJsonFile(filePath)
updateJsonData(jsonData, "$.ConnectionStrings.default.connectionString", "Server="+ MYSQL_HOST +";Port=3306;Database="+ MYSQL_DATABASE +";User ID="+ MYSQL_USER +";Password="+ MYSQL_PASSWORD +";Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;ConnectionReset=false",)
updateJsonData(jsonData,"$.core.base-domain", APP_CORE_BASE_DOMAIN)
updateJsonData(jsonData,"$.core.machinekey", APP_CORE_MACHINEKEY)
writeJsonFile(filePath, jsonData)
filePath = "/app/onlyoffice/config/elastic.json"
jsonData = openJsonFile(filePath)
updateJsonData(jsonData,"$.elastic.Scheme", ELK_SHEME)
updateJsonData(jsonData,"$.elastic.Host", ELK_HOST)
updateJsonData(jsonData,"$.elastic.Port", ELK_PORT)
updateJsonData(jsonData,"$.elastic.Threads", ELK_THREADS)
jsonData["elastic"]["Scheme"] = ELK_SHEME
jsonData["elastic"]["Host"] = ELK_HOST
jsonData["elastic"]["Port"] = ELK_PORT
jsonData["elastic"]["Threads"] = ELK_THREADS
writeJsonFile(filePath, jsonData)
filePath = "/app/onlyoffice/config/kafka.json"

View File

@ -32,26 +32,28 @@ x-service: &x-service-base
- ${ROOT_DIR}/config/apisystem.${ENV_EXTENSION}.json:/app/onlyoffice/config/apisystem.${ENV_EXTENSION}.json
services:
onlyoffice-elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
container_name: ${ELK_HOST}
restart: always
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65535
hard: 65535
volumes:
- es_data:/usr/share/elasticsearch/data
expose:
- "9200"
- "9300"
# onlyoffice-elasticsearch:
# image: onlyoffice/elasticsearch:${ELK_VERSION}
# container_name: ${ELK_HOST}
# restart: always
# environment:
# - discovery.type=single-node
# - bootstrap.memory_lock=true
# - "ES_JAVA_OPTS=-Xms4g -Xmx4g -Dlog4j2.formatMsgNoLookups=true"
# - "indices.fielddata.cache.size=30%"
# - "indices.memory.index_buffer_size=30%"
# ulimits:
# memlock:
# soft: -1
# hard: -1
# nofile:
# soft: 65535
# hard: 65535
# volumes:
# - es_data:/usr/share/elasticsearch/data
# expose:
# - "9200"
# - "9300"
onlyoffice-backup-background-tasks:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-backup-background:${DOCKER_TAG}"
@ -62,10 +64,10 @@ services:
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-backup:${DOCKER_TAG}"
container_name: ${BACKUP_HOST}
onlyoffice-clear-events:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
container_name: ${CLEAR_EVENTS_HOST}
# onlyoffice-clear-events:
# <<: *x-service-base
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
# container_name: ${CLEAR_EVENTS_HOST}
# onlyoffice-migration:
# <<: *x-service-base
@ -117,23 +119,23 @@ services:
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
container_name: ${API_HOST}
onlyoffice-api-system:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
container_name: ${API_SYSTEM_HOST}
# onlyoffice-api-system:
# <<: *x-service-base
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
# container_name: ${API_SYSTEM_HOST}
onlyoffice-studio:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio:${DOCKER_TAG}"
container_name: ${STUDIO_HOST}
onlyoffice-ssoauth:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
container_name: ${SSOAUTH_HOST}
expose:
- ${SERVICE_PORT}
- "9834"
# onlyoffice-ssoauth:
# <<: *x-service-base
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
# container_name: ${SSOAUTH_HOST}
# expose:
# - ${SERVICE_PORT}
# - "9834"
# onlyoffice-webhooks-service:
# <<: *x-service-base
@ -153,7 +155,7 @@ services:
depends_on:
- onlyoffice-backup-background-tasks
- onlyoffice-backup
- onlyoffice-clear-events
# - onlyoffice-clear-events
# - onlyoffice-migration
# - webhooks-service
- onlyoffice-files
@ -164,14 +166,14 @@ services:
# - onlyoffice-telegram-service
# - onlyoffice-urlshortener
- onlyoffice-api
- onlyoffice-api-system
# - onlyoffice-api-system
- onlyoffice-studio
- onlyoffice-ssoauth
# - onlyoffice-ssoauth
environment:
- SERVICE_BACKUP=${SERVICE_BACKUP}
- SERVICE_FILES=${SERVICE_FILES}
- SERVICE_FILES_SERVICES=${SERVICE_FILES_SERVICES}
- SERVICE_CLEAR_EVENTS=${SERVICE_CLEAR_EVENTS}
# - SERVICE_CLEAR_EVENTS=${SERVICE_CLEAR_EVENTS}
# - SERVICE_MIGRATION=${SERVICE_MIGRATION}
# - SERVICE_WEBHOOKS_SERVICE=${SERVICE_WEBHOOKS_SERVICE}
- SERVICE_NOTIFY=${SERVICE_NOTIFY}

View File

@ -29,13 +29,15 @@ x-service: &x-service-base
services:
onlyoffice-elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
image: onlyoffice/elasticsearch:${ELK_VERSION}
container_name: ${ELK_HOST}
restart: always
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "ES_JAVA_OPTS=-Xms4g -Xmx4g -Dlog4j2.formatMsgNoLookups=true"
- "indices.fielddata.cache.size=30%"
- "indices.memory.index_buffer_size=30%"
ulimits:
memlock:
soft: -1

View File

@ -1,4 +1,4 @@
version: "3.6"
version: "3.8"
services:
onlyoffice-document-server:
image: "${DOCUMENT_SERVER_IMAGE_NAME}"
@ -19,5 +19,5 @@ services:
networks:
default:
external:
name: ${NETWORK_NAME}
name: ${NETWORK_NAME}
external: true

View File

@ -28,6 +28,7 @@ BuildRequires: dotnet-sdk-7.0
BuildRoot: %_tmppath/%name-%version-%release.%arch
Requires: %name-api = %version-%release
Requires: %name-api-system = %version-%release
Requires: %name-backup = %version-%release
Requires: %name-backup-background = %version-%release
Requires: %name-clear-events = %version-%release

View File

@ -1,6 +1,6 @@
@echo off
pwsh %~dp0/restart.backend.docker.ps1
pwsh %~dp0/restart.backend.docker.ps1 %*
echo.

View File

@ -1,6 +1,6 @@
@echo off
pwsh %~dp0/start.backend.docker.ps1
pwsh %~dp0/start.backend.docker.ps1 %*
echo.

View File

@ -24,6 +24,8 @@
// 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
using System.Runtime.InteropServices;
namespace ASC.ActiveDirectory.Base.Settings;
[Scope]
@ -86,7 +88,7 @@ public class LdapSettings : ISettings<LdapSettings>, ICloneable
public LdapSettings GetDefault()
{
var isMono = WorkContext.IsMono;
var isNotWindows = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var settings = new LdapSettings()
{
@ -94,10 +96,10 @@ public class LdapSettings : ISettings<LdapSettings>, ICloneable
UserDN = "",
PortNumber = LdapConstants.STANDART_LDAP_PORT,
UserFilter = string.Format("({0}=*)",
isMono
isNotWindows
? LdapConstants.RfcLDAPAttributes.UID
: LdapConstants.ADSchemaAttributes.USER_PRINCIPAL_NAME),
LoginAttribute = isMono
LoginAttribute = isNotWindows
? LdapConstants.RfcLDAPAttributes.UID
: LdapConstants.ADSchemaAttributes.ACCOUNT_NAME,
FirstNameAttribute = LdapConstants.ADSchemaAttributes.FIRST_NAME,
@ -108,14 +110,14 @@ public class LdapSettings : ISettings<LdapSettings>, ICloneable
LocationAttribute = LdapConstants.ADSchemaAttributes.STREET,
GroupDN = "",
GroupFilter = string.Format("({0}={1})", LdapConstants.ADSchemaAttributes.OBJECT_CLASS,
isMono
isNotWindows
? LdapConstants.ObjectClassKnowedValues.POSIX_GROUP
: LdapConstants.ObjectClassKnowedValues.GROUP),
UserAttribute =
isMono
isNotWindows
? LdapConstants.RfcLDAPAttributes.UID
: LdapConstants.ADSchemaAttributes.DISTINGUISHED_NAME,
GroupAttribute = isMono ? LdapConstants.RfcLDAPAttributes.MEMBER_UID : LdapConstants.ADSchemaAttributes.MEMBER,
GroupAttribute = isNotWindows ? LdapConstants.RfcLDAPAttributes.MEMBER_UID : LdapConstants.ADSchemaAttributes.MEMBER,
GroupNameAttribute = LdapConstants.ADSchemaAttributes.COMMON_NAME,
Authentication = true,
AcceptCertificate = false,

View File

@ -1,157 +0,0 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
using ValidationResult = ASC.Security.Cryptography.EmailValidationKeyProvider.ValidationResult;
namespace ASC.Api.Core.Security;
[Scope]
public class DocSpaceLinkHelper
{
private readonly IDbContextFactory<MessagesContext> _dbContextFactory;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly MessageService _messageService;
private readonly MessageTarget _messageTarget;
private readonly Signature _signature;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
private readonly UserManager _userManager;
private readonly AuthManager _authManager;
public TimeSpan ExpirationInterval => _emailValidationKeyProvider.ValidEmailKeyInterval;
public TimeSpan ExpirationVisitInterval => _emailValidationKeyProvider.ValidVisitLinkInterval;
public DocSpaceLinkHelper(
IHttpContextAccessor httpContextAccessor,
MessageTarget messageTarget,
MessageService messageService,
Signature signature,
IDbContextFactory<MessagesContext> dbContextFactory,
EmailValidationKeyProvider emailValidationKeyProvider,
UserManager userManager,
AuthManager authManager)
{
_httpContextAccessor = httpContextAccessor;
_messageTarget = messageTarget;
_messageService = messageService;
_dbContextFactory = dbContextFactory;
_signature = signature;
_emailValidationKeyProvider = emailValidationKeyProvider;
_userManager = userManager;
_authManager = authManager;
}
public string MakeKey(Guid linkId)
{
return _signature.Create(linkId);
}
public string MakeKey(string email, EmployeeType employeeType)
{
return email + ConfirmType.LinkInvite.ToStringFast() + employeeType.ToStringFast();
}
public Guid Parse(string key)
{
return _signature.Read<Guid>(key);
}
public ValidationResult Validate(string key, string email, EmployeeType employeeType)
{
return string.IsNullOrEmpty(email) ? ValidateRoomExternalLink(key) : ValidateEmailLink(email, key, employeeType);
}
public ValidationResult ValidateEmailLink(string email, string key, EmployeeType employeeType)
{
var result = _emailValidationKeyProvider.ValidateEmailKey(MakeKey(email, employeeType), key, ExpirationInterval);
if (result == ValidationResult.Ok)
{
var user = _userManager.GetUserByEmail(email);
if (user == ASC.Core.Users.Constants.LostUser || _authManager.GetUserPasswordStamp(user.Id) != DateTime.MinValue)
{
return ValidationResult.Invalid;
}
if (!CanUsed(email, key, ExpirationVisitInterval))
{
return ValidationResult.Expired;
}
}
return result;
}
public ValidationResult ValidateRoomExternalLink(string key)
{
var payload = Parse(key);
return payload == default ? ValidationResult.Invalid : ValidationResult.Ok;
}
public ValidationResult ValidateExtarnalLink(string key, EmployeeType employeeType)
{
return _emailValidationKeyProvider.ValidateEmailKey(ConfirmType.LinkInvite.ToStringFast() + (int)employeeType, key);
}
private bool CanUsed(string email, string key, TimeSpan interval)
{
var message = GetLinkInfo(email, key);
if (message == null)
{
SaveVisitLinkInfo(email, key);
return true;
}
return message.Date + interval > DateTime.UtcNow;
}
private AuditEvent GetLinkInfo(string email, string key)
{
using var context = _dbContextFactory.CreateDbContext();
var target = _messageTarget.Create(email);
var description = JsonConvert.SerializeObject(new[] { key },
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
var message = context.AuditEvents.Where(a => a.Target == target.ToString() &&
a.DescriptionRaw == description).FirstOrDefault();
return message;
}
private void SaveVisitLinkInfo(string email, string key)
{
var headers = _httpContextAccessor?.HttpContext?.Request?.Headers;
var target = _messageTarget.Create(email);
_messageService.Send(headers, MessageAction.RoomInviteLinkUsed, target, key);
}
}

View File

@ -38,7 +38,7 @@ public class EmailValidationKeyModelHelper
private readonly AuthContext _authContext;
private readonly UserManager _userManager;
private readonly AuthManager _authentication;
private readonly DocSpaceLinkHelper _docSpaceLinkHelper;
private readonly InvitationLinkHelper _invitationLinkHelper;
private readonly AuditEventsRepository _auditEventsRepository;
private readonly TenantUtil _tenantUtil;
private readonly MessageTarget _messageTarget;
@ -49,7 +49,7 @@ public class EmailValidationKeyModelHelper
AuthContext authContext,
UserManager userManager,
AuthManager authentication,
DocSpaceLinkHelper docSpaceLinkHelper,
InvitationLinkHelper invitationLinkHelper,
AuditEventsRepository auditEventsRepository,
TenantUtil tenantUtil,
MessageTarget messageTarget)
@ -59,7 +59,7 @@ public class EmailValidationKeyModelHelper
_authContext = authContext;
_userManager = userManager;
_authentication = authentication;
_docSpaceLinkHelper = docSpaceLinkHelper;
_invitationLinkHelper = invitationLinkHelper;
_auditEventsRepository = auditEventsRepository;
_tenantUtil = tenantUtil;
_messageTarget = messageTarget;
@ -110,13 +110,7 @@ public class EmailValidationKeyModelHelper
break;
case ConfirmType.LinkInvite:
checkKeyResult = string.IsNullOrEmpty(email) ? _docSpaceLinkHelper.ValidateRoomExternalLink(key)
: _docSpaceLinkHelper.ValidateEmailLink(email, key, emplType ?? default);
if (checkKeyResult == ValidationResult.Invalid)
{
checkKeyResult = _provider.ValidateEmailKey(type.ToString() + (int)(emplType ?? default), key, _provider.ValidEmailKeyInterval);
}
checkKeyResult = _invitationLinkHelper.Validate(key, email, emplType ?? default).Result;
break;
case ConfirmType.PortalOwnerChange:

View File

@ -0,0 +1,186 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
using Constants = ASC.Core.Users.Constants;
using ValidationResult = ASC.Security.Cryptography.EmailValidationKeyProvider.ValidationResult;
namespace ASC.Api.Core.Security;
[Scope]
public class InvitationLinkHelper
{
private readonly IDbContextFactory<MessagesContext> _dbContextFactory;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly MessageService _messageService;
private readonly MessageTarget _messageTarget;
private readonly Signature _signature;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
private readonly UserManager _userManager;
private readonly AuthManager _authManager;
public TimeSpan IndividualLinkExpirationInterval => _emailValidationKeyProvider.ValidEmailKeyInterval;
public InvitationLinkHelper(
IHttpContextAccessor httpContextAccessor,
MessageTarget messageTarget,
MessageService messageService,
Signature signature,
IDbContextFactory<MessagesContext> dbContextFactory,
EmailValidationKeyProvider emailValidationKeyProvider,
UserManager userManager,
AuthManager authManager)
{
_httpContextAccessor = httpContextAccessor;
_messageTarget = messageTarget;
_messageService = messageService;
_dbContextFactory = dbContextFactory;
_signature = signature;
_emailValidationKeyProvider = emailValidationKeyProvider;
_userManager = userManager;
_authManager = authManager;
}
public string MakeIndividualLinkKey(Guid linkId)
{
return _signature.Create(linkId);
}
public async Task<LinkValidationResult> ValidateAsync(string key, string email, EmployeeType employeeType)
{
var validationResult = new LinkValidationResult { Result = ValidationResult.Invalid };
var (commonWithRoomLinkResult, linkId) = ValidateCommonWithRoomLink(key);
if (commonWithRoomLinkResult != ValidationResult.Invalid)
{
validationResult.Result = commonWithRoomLinkResult;
validationResult.LinkType = InvitationLinkType.CommonWithRoom;
validationResult.LinkId = linkId;
return validationResult;
}
var commonLinkResult = _emailValidationKeyProvider.ValidateEmailKey(ConfirmType.LinkInvite.ToStringFast() + (int)employeeType,
key, _emailValidationKeyProvider.ValidEmailKeyInterval);
if (commonLinkResult != ValidationResult.Invalid)
{
validationResult.Result = commonLinkResult;
validationResult.LinkType = InvitationLinkType.Common;
return validationResult;
}
if (string.IsNullOrEmpty(email))
{
return validationResult;
}
var individualLinkResult = await ValidateIndividualLink(email, key, employeeType);
validationResult.Result = individualLinkResult;
validationResult.LinkType = InvitationLinkType.Individual;
return validationResult;
}
public LinkValidationResult Validate(string key, string email, EmployeeType employeeType)
{
return ValidateAsync(key, email, employeeType).Result;
}
private async Task<ValidationResult> ValidateIndividualLink(string email, string key, EmployeeType employeeType)
{
var result = _emailValidationKeyProvider.ValidateEmailKey(email + ConfirmType.LinkInvite.ToStringFast() + employeeType.ToStringFast(),
key, IndividualLinkExpirationInterval);
if (result != ValidationResult.Ok)
{
return result;
}
var user = _userManager.GetUserByEmail(email);
if (user.Equals(Constants.LostUser) || _authManager.GetUserPasswordStamp(user.Id) != DateTime.MinValue)
{
return ValidationResult.Invalid;
}
var visitMessage = await GetLinkVisitMessageAsync(email, key);
if (visitMessage == null)
{
SaveLinkVisitMessage(email, key);
}
else if (visitMessage.Date + _emailValidationKeyProvider.ValidVisitLinkInterval < DateTime.UtcNow)
{
return ValidationResult.Expired;
}
return result;
}
private (ValidationResult, Guid) ValidateCommonWithRoomLink(string key)
{
var linkId = _signature.Read<Guid>(key);
return linkId == default ? (ValidationResult.Invalid, default) : (ValidationResult.Ok, linkId);
}
private async Task<AuditEvent> GetLinkVisitMessageAsync(string email, string key)
{
using var context = _dbContextFactory.CreateDbContext();
var target = _messageTarget.Create(email);
var description = JsonConvert.SerializeObject(new[] { key });
var message = await context.AuditEvents.FirstOrDefaultAsync(a => a.Target == target.ToString() && a.DescriptionRaw == description);
return message;
}
private void SaveLinkVisitMessage(string email, string key)
{
var headers = _httpContextAccessor?.HttpContext?.Request.Headers;
var target = _messageTarget.Create(email);
_messageService.Send(headers, MessageAction.RoomInviteLinkUsed, target, key);
}
}
public enum InvitationLinkType
{
Common,
CommonWithRoom,
Individual
}
public class LinkValidationResult
{
public ValidationResult Result { get; set; }
public InvitationLinkType LinkType { get; set; }
public Guid LinkId { get; set; }
}

View File

@ -160,6 +160,8 @@ public static class MimeMapping
AddMimeMapping(".dotm", "application/vnd.ms-word.template.macroEnabled.12");
AddMimeMapping(".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template");
AddMimeMapping(".dp", "application/commonground");
AddMimeMapping(".dps", "application/presentation");
AddMimeMapping(".dpt", "application/presentation");
AddMimeMapping(".drw", "application/drafting");
AddMimeMapping(".dump", "application/octet-stream");
AddMimeMapping(".dv", "video/x-dv");
@ -181,6 +183,8 @@ public static class MimeMapping
AddMimeMapping(".eps", "application/postscript");
AddMimeMapping(".epub", "application/epub+zip");
AddMimeMapping(".es", "application/x-esrehber");
AddMimeMapping(".et", "application/spreadsheet");
AddMimeMapping(".ett", "application/spreadsheet");
AddMimeMapping(".etx", "text/x-setext");
AddMimeMapping(".evy", "application/envoy");
AddMimeMapping(".evy", "application/x-envoy");
@ -616,6 +620,7 @@ public static class MimeMapping
AddMimeMapping(".stl", "application/vndms-pkistl");
AddMimeMapping(".stm", "text/html");
AddMimeMapping(".stp", "application/step");
AddMimeMapping(".stw", "application/vnd.sun.xml.writer.template");
AddMimeMapping(".sv4cpio", "application/x-sv4cpio");
AddMimeMapping(".sv4crc", "application/x-sv4crc");
AddMimeMapping(".svf", "image/vnd.dwg");
@ -625,6 +630,9 @@ public static class MimeMapping
AddMimeMapping(".svg", "image/svg+xml");
AddMimeMapping(".svgt", "image/svg+xml");
AddMimeMapping(".swf", "application/x-shockwave-flash");
AddMimeMapping(".sxi", "application/presentation");
AddMimeMapping(".sxc", "application/vnd.sun.xml.calc");
AddMimeMapping(".sxw", "application/vnd.sun.xml.writer");
AddMimeMapping(".t", "application/x-troff");
AddMimeMapping(".talk", "text/x-speech");
AddMimeMapping(".tar", "application/x-tar");
@ -719,7 +727,8 @@ public static class MimeMapping
AddMimeMapping(".wp6", "application/wordperfect");
AddMimeMapping(".wpd", "application/wordperfect");
AddMimeMapping(".wpd", "application/x-wpwin");
AddMimeMapping(".wps", "application/vnd.ms-works");
AddMimeMapping(".wps", "application/document");
AddMimeMapping(".wpt", "application/document");
AddMimeMapping(".wq1", "application/x-lotus");
AddMimeMapping(".wri", "application/mswrite");
AddMimeMapping(".wri", "application/x-wri");

View File

@ -40,4 +40,5 @@ public interface ITariffService
void SetTariff(int tenantId, Tariff tariff);
Uri GetAccountLink(int tenant, string backUrl);
Task<bool> PaymentChange(int tenant, Dictionary<string, int> quantity);
int GetPaymentDelay();
}

View File

@ -940,4 +940,9 @@ public class TariffService : ITariffService
}
}
}
public int GetPaymentDelay()
{
return _paymentDelay;
}
}

View File

@ -329,6 +329,11 @@ public class PermissionContext
return CheckPermissions(securityObject, null, actions);
}
public bool CheckPermissions(IAccount account, ISecurityObject securityObject, params IAction[] actions)
{
return PermissionResolver.Check(account, securityObject, null, actions);
}
public bool CheckPermissions(ISecurityObjectId objectId, ISecurityObjectProvider securityObjProvider, params IAction[] actions)
{
return PermissionResolver.Check(AuthContext.CurrentAccount, objectId, securityObjProvider, actions);

View File

@ -95,16 +95,26 @@ class DbQuotaService : IQuotaService
var dbTenantQuotaRow = _mapper.Map<TenantQuotaRow, DbQuotaRow>(row);
dbTenantQuotaRow.UserId = row.UserId;
if (exchange)
var exist = coreDbContext.QuotaRows.Find(new object[] { dbTenantQuotaRow.Tenant, dbTenantQuotaRow.UserId, dbTenantQuotaRow.Path });
if (exist == null)
{
coreDbContext.QuotaRows
.Where(r => r.Path == row.Path && r.Tenant == row.Tenant && r.UserId == row.UserId)
.ExecuteUpdate(x => x.SetProperty(p => p.Counter, p => (p.Counter + row.Counter)));
coreDbContext.QuotaRows.Add(dbTenantQuotaRow);
coreDbContext.SaveChanges();
}
else
{
coreDbContext.AddOrUpdate(coreDbContext.QuotaRows, dbTenantQuotaRow);
coreDbContext.SaveChanges();
if (exchange)
{
coreDbContext.QuotaRows
.Where(r => r.Path == row.Path && r.Tenant == row.Tenant && r.UserId == row.UserId)
.ExecuteUpdate(x => x.SetProperty(p => p.Counter, p => (p.Counter + row.Counter)));
}
else
{
coreDbContext.AddOrUpdate(coreDbContext.QuotaRows, dbTenantQuotaRow);
coreDbContext.SaveChanges();
}
}
}

View File

@ -79,7 +79,7 @@ public static class DbQuotaExtension
Tenant = -3,
Name = "startup",
Description = null,
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
Features = "free,total_size:2147483648,manager:5,room:5",
Price = 0,
ProductId = null,
Visible = false

View File

@ -312,7 +312,7 @@ public class SmtpSender : INotifySender
{
ContentId = attachment.ContentId,
Content = new MimeContent(new MemoryStream(attachment.Content)),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentDisposition = new ContentDisposition(ContentDisposition.Inline),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = attachment.FileName
};

View File

@ -172,10 +172,15 @@ public class TelegramHelper
public TelegramBotClient InitClient(string token, string proxy)
{
if (string.IsNullOrEmpty(proxy))
{
return new TelegramBotClient(token);
}
var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(proxy);
return string.IsNullOrEmpty(proxy) ? new TelegramBotClient(token) : new TelegramBotClient(token, httpClient);
return new TelegramBotClient(token, httpClient);
}
}

View File

@ -193,8 +193,15 @@ public class NotifyHelper
if (!string.IsNullOrEmpty(url))
{
args.Add(new TagValue(CommonTags.VirtualRootPath, url));
args.Add(new TagValue(CommonTags.ProfileUrl, url + _commonLinkUtility.GetMyStaff()));
args.Add(new TagValue(CommonTags.LetterLogo, _tenantLogoManager.GetLogoDark(false)));
args.Add(new TagValue(CommonTags.ProfileUrl, url + _commonLinkUtility.GetMyStaff()));
var attachment = _tenantLogoManager.GetMailLogoAsAttacment().Result;
if (attachment != null)
{
args.Add(new TagValue(CommonTags.LetterLogo, "cid:" + attachment.ContentId));
args.Add(new TagValue(CommonTags.EmbeddedAttachments, new[] { attachment }));
}
}
return args;

View File

@ -230,18 +230,15 @@ public class S3Storage : BaseStorage
request.ServerSideEncryptionKeyManagementServiceKeyId = kmsKeyId;
}
if (!WorkContext.IsMono) // System.Net.Sockets.SocketException: Connection reset by peer
switch (acl)
{
switch (acl)
{
case ACL.Auto:
request.CannedACL = GetDomainACL(domain);
break;
case ACL.Read:
case ACL.Private:
request.CannedACL = GetS3Acl(acl);
break;
}
case ACL.Auto:
request.CannedACL = GetDomainACL(domain);
break;
case ACL.Read:
case ACL.Private:
request.CannedACL = GetS3Acl(acl);
break;
}
if (!string.IsNullOrEmpty(contentDisposition))

View File

@ -1,146 +1,146 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
namespace ASC.MessagingSystem.Core;
[Scope]
public class MessageService
{
private readonly ILogger<MessageService> _logger;
private readonly IMessageSender _sender;
private readonly HttpRequest _request;
private readonly MessageFactory _messageFactory;
private readonly MessagePolicy _messagePolicy;
public MessageService(
IConfiguration configuration,
MessageFactory messageFactory,
DbMessageSender sender,
MessagePolicy messagePolicy,
ILogger<MessageService> logger)
{
if (configuration["messaging:enabled"] != "true")
{
return;
}
_sender = sender;
_messagePolicy = messagePolicy;
_messageFactory = messageFactory;
_logger = logger;
}
public MessageService(
IConfiguration configuration,
IHttpContextAccessor httpContextAccessor,
MessageFactory messageFactory,
DbMessageSender sender,
MessagePolicy messagePolicy,
ILogger<MessageService> logger)
: this(configuration, messageFactory, sender, messagePolicy, logger)
{
_request = httpContextAccessor?.HttpContext?.Request;
}
#region HttpRequest
public void Send(MessageAction action)
{
SendRequestMessage(null, null, action, null);
}
public void Send(MessageAction action, string d1)
{
SendRequestMessage(null, null, action, null, d1);
}
public void Send(MessageAction action, string d1, string d2)
{
SendRequestMessage(null, null, action, null, d1, d2);
}
public void Send(MessageAction action, string d1, string d2, string d3)
{
SendRequestMessage(null, null, action, null, d1, d2, d3);
}
public void Send(MessageAction action, string d1, string d2, string d3, string d4)
{
SendRequestMessage(null, null, action, null, d1, d2, d3, d4);
}
public void Send(MessageAction action, IEnumerable<string> d1, string d2)
{
SendRequestMessage(null, null, action, null, string.Join(", ", d1), d2);
}
public void Send(MessageAction action, string d1, IEnumerable<string> d2)
{
SendRequestMessage(null, null, action, null, d1, string.Join(", ", d2));
}
public void Send(MessageAction action, string d1, string d2, IEnumerable<string> d3)
{
SendRequestMessage(null, null, action, null, d1, d2, string.Join(", ", d3));
}
public void Send(MessageAction action, IEnumerable<string> d1)
{
SendRequestMessage(null, null, action, null, string.Join(", ", d1));
}
public void Send(string loginName, MessageAction action)
{
SendRequestMessage(loginName, null, action, null);
}
public void Send(string loginName, MessageAction action, string d1)
{
SendRequestMessage(loginName, null, action, null, d1);
}
#endregion
#region HttpRequest & Target
public void Send(MessageAction action, MessageTarget target)
{
SendRequestMessage(null, null, action, target);
namespace ASC.MessagingSystem.Core;
[Scope]
public class MessageService
{
private readonly ILogger<MessageService> _logger;
private readonly IMessageSender _sender;
private readonly HttpRequest _request;
private readonly MessageFactory _messageFactory;
private readonly MessagePolicy _messagePolicy;
public MessageService(
IConfiguration configuration,
MessageFactory messageFactory,
DbMessageSender sender,
MessagePolicy messagePolicy,
ILogger<MessageService> logger)
{
if (configuration["messaging:enabled"] != "true")
{
return;
}
_sender = sender;
_messagePolicy = messagePolicy;
_messageFactory = messageFactory;
_logger = logger;
}
public MessageService(
IConfiguration configuration,
IHttpContextAccessor httpContextAccessor,
MessageFactory messageFactory,
DbMessageSender sender,
MessagePolicy messagePolicy,
ILogger<MessageService> logger)
: this(configuration, messageFactory, sender, messagePolicy, logger)
{
_request = httpContextAccessor?.HttpContext?.Request;
}
#region HttpRequest
public void Send(MessageAction action)
{
SendRequestMessage(null, null, action, null);
}
public void Send(MessageAction action, string d1)
{
SendRequestMessage(null, null, action, null, d1);
}
public void Send(MessageAction action, string d1, string d2)
{
SendRequestMessage(null, null, action, null, d1, d2);
}
public void Send(MessageAction action, string d1, string d2, string d3)
{
SendRequestMessage(null, null, action, null, d1, d2, d3);
}
public void Send(MessageAction action, string d1, string d2, string d3, string d4)
{
SendRequestMessage(null, null, action, null, d1, d2, d3, d4);
}
public void Send(MessageAction action, IEnumerable<string> d1, string d2)
{
SendRequestMessage(null, null, action, null, string.Join(", ", d1), d2);
}
public void Send(MessageAction action, string d1, IEnumerable<string> d2)
{
SendRequestMessage(null, null, action, null, d1, string.Join(", ", d2));
}
public void Send(MessageAction action, string d1, string d2, IEnumerable<string> d3)
{
SendRequestMessage(null, null, action, null, d1, d2, string.Join(", ", d3));
}
public void Send(MessageAction action, IEnumerable<string> d1)
{
SendRequestMessage(null, null, action, null, string.Join(", ", d1));
}
public void Send(string loginName, MessageAction action)
{
SendRequestMessage(loginName, null, action, null);
}
public void Send(string loginName, MessageAction action, string d1)
{
SendRequestMessage(loginName, null, action, null, d1);
}
#endregion
#region HttpRequest & Target
public void Send(MessageAction action, MessageTarget target)
{
SendRequestMessage(null, null, action, target);
}
public void Send(DateTime? dateTime, MessageAction action, MessageTarget target, string d1)
{
SendRequestMessage(null, dateTime, action, target, d1);
}
public void Send(MessageAction action, MessageTarget target, string d1)
{
SendRequestMessage(null, null, action, target, d1);
public void Send(MessageAction action, MessageTarget target, string d1)
{
SendRequestMessage(null, null, action, target, d1);
}
public void Send(MessageAction action, MessageTarget target, string d1, Guid userId)
public void Send(MessageAction action, MessageTarget target, string d1, Guid userId)
{
if (TryAddNotificationParam(action, userId, out var parametr))
{
@ -149,45 +149,45 @@ public class MessageService
else
{
SendRequestMessage(null, null, action, target, d1);
}
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2)
{
SendRequestMessage(null, null, action, target, d1, d2);
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, string d3)
{
SendRequestMessage(null, null, action, target, d1, d2, d3);
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, string d3, string d4)
{
SendRequestMessage(null, null, action, target, d1, d2, d3, d4);
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1, string d2)
{
SendRequestMessage(null, null, action, target, string.Join(", ", d1), d2);
}
public void Send(MessageAction action, MessageTarget target, string d1, IEnumerable<string> d2)
{
SendRequestMessage(null, null, action, target, d1, string.Join(", ", d2));
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, IEnumerable<string> d3)
{
SendRequestMessage(null, null, action, target, d1, d2, string.Join(", ", d3));
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1)
{
SendRequestMessage(null, null, action, target, string.Join(", ", d1));
}
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1, List<Guid> userIds, EmployeeType userType)
public void Send(MessageAction action, MessageTarget target, string d1, string d2)
{
SendRequestMessage(null, null, action, target, d1, d2);
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, string d3)
{
SendRequestMessage(null, null, action, target, d1, d2, d3);
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, string d3, string d4)
{
SendRequestMessage(null, null, action, target, d1, d2, d3, d4);
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1, string d2)
{
SendRequestMessage(null, null, action, target, string.Join(", ", d1), d2);
}
public void Send(MessageAction action, MessageTarget target, string d1, IEnumerable<string> d2)
{
SendRequestMessage(null, null, action, target, d1, string.Join(", ", d2));
}
public void Send(MessageAction action, MessageTarget target, string d1, string d2, IEnumerable<string> d3)
{
SendRequestMessage(null, null, action, target, d1, d2, string.Join(", ", d3));
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1)
{
SendRequestMessage(null, null, action, target, string.Join(", ", d1));
}
public void Send(MessageAction action, MessageTarget target, IEnumerable<string> d1, List<Guid> userIds, EmployeeType userType)
{
if (TryAddNotificationParam(action, userIds, out var parametr, userType))
{
@ -196,140 +196,140 @@ public class MessageService
else
{
SendRequestMessage(null, null, action, target, string.Join(", ", d1));
}
}
public void Send(string loginName, MessageAction action, MessageTarget target)
{
SendRequestMessage(loginName, null, action, target);
}
public void Send(string loginName, MessageAction action, MessageTarget target, string d1)
{
SendRequestMessage(loginName, null, action, target, d1);
}
#endregion
private void SendRequestMessage(string loginName, DateTime? dateTime, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
if (_request == null)
{
_logger.DebugEmptyHttpRequest(action);
return;
}
var message = _messageFactory.Create(_request, loginName, dateTime, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
#region HttpHeaders
public void Send(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action)
{
SendHeadersMessage(userData, httpHeaders, action, null);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action)
{
SendHeadersMessage(null, httpHeaders, action, null);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, string d1)
{
SendHeadersMessage(null, httpHeaders, action, null, d1);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, IEnumerable<string> d1)
{
SendHeadersMessage(null, httpHeaders, action, null, d1?.ToArray());
}
public void Send(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target)
{
SendHeadersMessage(userData, httpHeaders, action, target);
}
#endregion
#region HttpHeaders & Target
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target)
{
SendHeadersMessage(null, httpHeaders, action, target);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, string d1)
{
SendHeadersMessage(null, httpHeaders, action, target, d1);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, IEnumerable<string> d1)
{
SendHeadersMessage(null, httpHeaders, action, target, d1?.ToArray());
}
#endregion
private void SendHeadersMessage(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
var message = _messageFactory.Create(userData, httpHeaders, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
#region Initiator
public void Send(MessageInitiator initiator, MessageAction action, params string[] description)
{
SendInitiatorMessage(initiator.ToString(), action, null, description);
}
#endregion
#region Initiator & Target
public void Send(MessageInitiator initiator, MessageAction action, MessageTarget target, params string[] description)
{
SendInitiatorMessage(initiator.ToString(), action, target, description);
}
#endregion
private void SendInitiatorMessage(string initiator, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
var message = _messageFactory.Create(_request, initiator, null, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
public void Send(string loginName, MessageAction action, MessageTarget target)
{
SendRequestMessage(loginName, null, action, target);
}
public void Send(string loginName, MessageAction action, MessageTarget target, string d1)
{
SendRequestMessage(loginName, null, action, target, d1);
}
#endregion
private void SendRequestMessage(string loginName, DateTime? dateTime, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
if (_request == null)
{
_logger.DebugEmptyHttpRequest(action);
return;
}
var message = _messageFactory.Create(_request, loginName, dateTime, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
#region HttpHeaders
public void Send(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action)
{
SendHeadersMessage(userData, httpHeaders, action, null);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action)
{
SendHeadersMessage(null, httpHeaders, action, null);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, string d1)
{
SendHeadersMessage(null, httpHeaders, action, null, d1);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, IEnumerable<string> d1)
{
SendHeadersMessage(null, httpHeaders, action, null, d1?.ToArray());
}
public void Send(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target)
{
SendHeadersMessage(userData, httpHeaders, action, target);
}
#endregion
#region HttpHeaders & Target
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target)
{
SendHeadersMessage(null, httpHeaders, action, target);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, string d1)
{
SendHeadersMessage(null, httpHeaders, action, target, d1);
}
public void Send(IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, IEnumerable<string> d1)
{
SendHeadersMessage(null, httpHeaders, action, target, d1?.ToArray());
}
#endregion
private void SendHeadersMessage(MessageUserData userData, IDictionary<string, StringValues> httpHeaders, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
var message = _messageFactory.Create(userData, httpHeaders, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
#region Initiator
public void Send(MessageInitiator initiator, MessageAction action, params string[] description)
{
SendInitiatorMessage(initiator.ToString(), action, null, description);
}
#endregion
#region Initiator & Target
public void Send(MessageInitiator initiator, MessageAction action, MessageTarget target, params string[] description)
{
SendInitiatorMessage(initiator.ToString(), action, target, description);
}
#endregion
private void SendInitiatorMessage(string initiator, MessageAction action, MessageTarget target, params string[] description)
{
if (_sender == null)
{
return;
}
var message = _messageFactory.Create(_request, initiator, null, action, target, description);
if (!_messagePolicy.Check(message))
{
return;
}
_sender.Send(message);
}
public int SendLoginMessage(MessageUserData userData, MessageAction action)
{
@ -364,8 +364,7 @@ public class MessageService
UserRole = (int)userType
});
}
else if (action == MessageAction.UserCreated
&& action == MessageAction.UserUpdated)
else if (action == MessageAction.UserCreated || action == MessageAction.UserUpdated)
{
parametr = JsonSerializer.Serialize(new AdditionalNotificationInfo
{
@ -378,7 +377,7 @@ public class MessageService
}
return true;
}
}
}
public class AdditionalNotificationInfo
@ -386,6 +385,7 @@ public class AdditionalNotificationInfo
public int RoomId { get; set; }
public string RoomTitle { get; set; }
public string RoomOldTitle { get; set; }
public string RootFolderTitle { get; set; }
public int UserRole { get; set; }
public List<Guid> UserIds { get; set; }
}

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%"/&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%"/&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -126,8 +126,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -96,8 +96,8 @@
&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;
&lt;td colspan="3" style="margin: 0; padding: 0; background-color: #fff; height: 65px; padding: 20px 0 0 30px;"&gt;
&lt;div style="text-align: left; height: 65px; width: 570px; margin: 0; padding: 0;"&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 216px; height: 35px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 216px; height: 35px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;a href="%SITEURL%" style="text-decoration: none; display: inline-block; width: 386px; height: 44px; margin: 0; padding: 0;" target="_blank"&gt;
&lt;img src="%LOGO%" style="border: 0px none; width: 386px; height: 44px; margin: 0; padding: 0;" alt="%LOGOTEXT%" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/td&gt;

View File

@ -90,7 +90,7 @@ class Program
//culture = "ru";
//exportPath = @"C:\Git\portals\";
//key = "*,HtmlMaster*";
key = "*";
//key = "*";
if (format == "json")
{
@ -118,7 +118,7 @@ class Program
}
enabledSettings = scopeClass.Configuration.GetSetting<EnabledSettings>("enabled");
cultures = scopeClass.ResourceData.GetCultures().Where(r => r.Available).Select(r => r.Title).Intersect(enabledSettings.Langs).ToList();
cultures = scopeClass.ResourceData.GetCultures().Where(r => r.Available).Select(r => r.Title).ToList();//.Intersect(enabledSettings.Langs).ToList();
projects = scopeClass.ResourceData.GetAllFiles();
ExportWithProject(project, module, filePath, culture, exportPath, key);

View File

@ -177,7 +177,11 @@ const findImagesIntoFiles = (fileList, imageList) => {
const usedImages = [];
imageList.forEach((i) => {
if (i.path.indexOf("flags") > -1 || i.path.indexOf("thirdparties") > -1)
if (
i.path.indexOf("flags") > -1 ||
i.path.indexOf("thirdparties") > -1 ||
i.path.indexOf("notifications") > -1
)
return usedImages.push(i.fileName);
imgCollection.push(i.fileName);

View File

@ -3857,6 +3857,15 @@ namespace ASC.AuditTrail {
}
}
/// <summary>
/// Looks up a localized string similar to Trash emptied.
/// </summary>
public static string TrashEmptied {
get {
return ResourceManager.GetString("TrashEmptied", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trusted mail domain settings updated.
/// </summary>

View File

@ -1450,4 +1450,7 @@
<data name="RoomsModule" xml:space="preserve">
<value>Rooms</value>
</data>
<data name="TrashEmptied" xml:space="preserve">
<value>Trash emptied</value>
</data>
</root>

View File

@ -44,6 +44,7 @@ public class AuditEventDto : BaseEvent, IMapFrom<AuditEventQuery>
[Event("TargetIdCol", 34)]
public MessageTarget Target { get; set; }
public string Context { get; set; }
public override void Mapping(Profile profile)
{

View File

@ -1,65 +1,65 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
// (c) Copyright Ascensio System SIA 2010-2022
//
// 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 Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// 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
using ASC.Core.Tenants;
namespace ASC.AuditTrail.Models.Mappings;
[Scope]
namespace ASC.AuditTrail.Models.Mappings;
[Scope]
internal class EventTypeConverter : ITypeConverter<LoginEventQuery, LoginEventDto>,
ITypeConverter<AuditEventQuery, AuditEventDto>
{
private readonly UserFormatter _userFormatter;
private readonly AuditActionMapper _auditActionMapper;
private readonly MessageTarget _messageTarget;
ITypeConverter<AuditEventQuery, AuditEventDto>
{
private readonly UserFormatter _userFormatter;
private readonly AuditActionMapper _auditActionMapper;
private readonly MessageTarget _messageTarget;
private readonly TenantUtil _tenantUtil;
public EventTypeConverter(
UserFormatter userFormatter,
AuditActionMapper actionMapper,
public EventTypeConverter(
UserFormatter userFormatter,
AuditActionMapper actionMapper,
MessageTarget messageTarget,
TenantUtil tenantUtil)
{
_userFormatter = userFormatter;
_auditActionMapper = actionMapper;
TenantUtil tenantUtil)
{
_userFormatter = userFormatter;
_auditActionMapper = actionMapper;
_messageTarget = messageTarget;
_tenantUtil = tenantUtil;
}
public LoginEventDto Convert(LoginEventQuery source, LoginEventDto destination, ResolutionContext context)
{
var result = context.Mapper.Map<LoginEventDto>(source.Event);
if (source.Event.DescriptionRaw != null)
{
result.Description = JsonConvert.DeserializeObject<IList<string>>(source.Event.DescriptionRaw,
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
_tenantUtil = tenantUtil;
}
public LoginEventDto Convert(LoginEventQuery source, LoginEventDto destination, ResolutionContext context)
{
var result = context.Mapper.Map<LoginEventDto>(source.Event);
if (source.Event.DescriptionRaw != null)
{
result.Description = JsonConvert.DeserializeObject<IList<string>>(source.Event.DescriptionRaw,
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
}
if (!(string.IsNullOrEmpty(source.FirstName) || string.IsNullOrEmpty(source.LastName)))
@ -91,26 +91,26 @@ internal class EventTypeConverter : ITypeConverter<LoginEventQuery, LoginEventDt
result.Date = _tenantUtil.DateTimeFromUtc(result.Date);
result.IP = result.IP.Split(':').Length > 1 ? result.IP.Split(':')[0] : result.IP;
return result;
}
public AuditEventDto Convert(AuditEventQuery source, AuditEventDto destination, ResolutionContext context)
return result;
}
public AuditEventDto Convert(AuditEventQuery source, AuditEventDto destination, ResolutionContext context)
{
var target = source.Event.Target;
source.Event.Target = null;
source.Event.Target = null;
var result = context.Mapper.Map<AuditEventDto>(source.Event);
result.Target = _messageTarget.Parse(target);
if (source.Event.DescriptionRaw != null)
{
result.Description = JsonConvert.DeserializeObject<IList<string>>(
source.Event.DescriptionRaw,
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
result.Target = _messageTarget.Parse(target);
if (source.Event.DescriptionRaw != null)
{
result.Description = JsonConvert.DeserializeObject<IList<string>>(
source.Event.DescriptionRaw,
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
}
if (result.UserId == Core.Configuration.Constants.CoreSystem.ID)
@ -150,7 +150,25 @@ internal class EventTypeConverter : ITypeConverter<LoginEventQuery, LoginEventDt
result.Date = _tenantUtil.DateTimeFromUtc(result.Date);
result.IP = result.IP.Split(':').Length > 1 ? result.IP.Split(':')[0] : result.IP;
return result;
}
}
if (map?.ProductType == ProductType.Documents)
{
var rawNotificationInfo = result.Description?.LastOrDefault();
if (!string.IsNullOrEmpty(rawNotificationInfo) && rawNotificationInfo.StartsWith('{') && rawNotificationInfo.EndsWith('}'))
{
var notificationInfo = System.Text.Json.JsonSerializer.Deserialize<AdditionalNotificationInfo>(rawNotificationInfo);
result.Context = result.Action == (int)MessageAction.RoomRenamed ? notificationInfo.RoomOldTitle :
!string.IsNullOrEmpty(notificationInfo.RoomTitle) ? notificationInfo.RoomTitle : notificationInfo.RootFolderTitle;
}
}
if (string.IsNullOrEmpty(result.Context))
{
result.Context = result.Module;
}
return result;
}
}

View File

@ -56,6 +56,7 @@ public class DbWorker
using var tx = await dbContext.Database.BeginTransactionAsync(IsolationLevel.ReadCommitted);
var notifyQueue = _mapper.Map<NotifyMessage, NotifyQueue>(m);
notifyQueue.Attachments = JsonConvert.SerializeObject(m.Attachments);
notifyQueue = dbContext.NotifyQueue.Add(notifyQueue).Entity;
await dbContext.SaveChangesAsync();

View File

@ -66,18 +66,18 @@
},
"files": {
"thirdparty": {
"enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ]
"enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive" ]
},
"docservice": {
"coauthor-docs": [ ".pptx", ".ppsx", ".xlsx", ".csv", ".docx", ".docxf", ".oform", ".txt" ],
"commented-docs": [ ".docx", ".docxf", ".xlsx", ".pptx" ],
"convert-docs": [ ".pptm", ".ppt", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".rtf" ],
"edited-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".txt", ".rtf", ".mht", ".html", ".htm" ],
"encrypted-docs": [ ".docx", ".docxf", ".xlsx", ".pptx", ".oform" ],
"coauthor-docs": [ ".csv", ".docm", ".docx", ".docxf", ".dotm", ".dotx", ".oform", ".potm", ".potx", ".ppsm", ".pptm", ".ppsx", ".pptx", ".txt", ".xlsm", ".xlsx", ".xltm", ".xltx" ],
"commented-docs": [ ".docm", ".docx", ".docxf", ".dotm", ".dotx", ".potm", ".potx", ".ppsm", ".pptm", ".ppsx", ".pptx", ".xlsm", ".xlsx", ".xltm", ".xltx" ],
"convert-docs": [ ".doc", ".dot", ".dps", ".dpt", ".epub", ".et", ".ett", ".fb2", ".fodp", ".fods", ".fodt", ".htm", ".html", ".mht", ".mhtml", ".odp", ".ods", ".odt", ".otp", ".ots", ".ott", ".pot", ".pps", ".ppt", ".rtf", ".stw", ".sxc", "sxi", ".sxw", ".wps", ".wpt", ".xls", ".xlsb", ".xlt", ".xml" ],
"edited-docs": [ "csv", ".doc", ".docm", ".docx", ".docxf", ".dot", ".dotm", ".dotx", ".dps", ".dpt", ".epub", ".et", ".ett", ".fb2", ".fodp", ".fods", ".fodt", ".htm", ".html", ".mht", ".mhtml", ".odp", ".ods", ".odt", ".oform", ".otp", ".ots", ".ott", ".pot", ".potm", ".potx", ".pps", ".ppsm", ".ppsx", ".ppt", ".pptm", ".pptx", ".rtf", ".stw", ".sxc", "sxi", ".sxw", ".txt", ".wps", ".wpt", ".xls", ".xlsb", ".xlsm", ".xlsx", ".xlt", ".xltm", ".xltx", ".xml" ],
"encrypted-docs": [ ".docm", ".docx", ".docxf", ".dotm", ".dotx", ".oform", ".potm", ".potx", ".ppsm", ".pptm", ".ppsx", ".pptx", ".xlsm", ".xlsx", ".xltm", ".xltx" ],
"formfilling-docs": [ ".oform" ],
"customfilter-docs": [ ".xlsx" ],
"reviewed-docs": [ ".docx", ".docxf" ],
"viewed-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ],
"customfilter-docs": [ ".xlsm", ".xlsx", ".xltm", ".xltx" ],
"reviewed-docs": [ ".docm", ".docx", ".docxf", ".dotm", ".dotx" ],
"viewed-docs": [ ".csv", ".djvu", ".doc", ".docm", ".docx", ".docxf", ".dot", ".dotm", ".dotx", ".dps", ".dpt", ".epub", ".et", ".ett", ".fb2", ".fodp", ".fods", ".fodt", ".gdoc", ".gsheet", ".gslides", ".htm", ".html", ".mht", ".mhtml", ".odp", ".ods", ".odt", ".oform", ".otp", ".ots", ".ott", ".oxps", ".pdf", ".pot", ".potm", ".potx", ".pps", ".ppsm", ".ppsx", ".ppt", ".pptm", ".pptx", ".rtf", ".stw", ".sxc", "sxi", ".sxw", ".txt", ".wps", ".wpt", ".xls", ".xlsb", ".xlsm", ".xlsx", ".xlt", ".xltm", ".xltx", ".xml", ".xps" ],
"secret": {
"value": "secret",
"header": "AuthorizationJwt"
@ -110,7 +110,7 @@
"min": 3,
"max": 50
},
"images": "images",
"images": "static/images",
"hide-settings": "Monitoring,LdapSettings,DocService,MailService,PublicPortal,ProxyHttpContent,SpamSubscription,FullTextSearch",
"hub": {
"url": "/socket.io",
@ -225,7 +225,8 @@
},
{
"height": 720,
"width": 1280
"width": 1280,
"resizeMode": "Max"
}
]
},

View File

@ -489,37 +489,6 @@
"twiliosender": ""
}
}
},
{
"type": "ASC.FederatedLogin.LoginProviders.VKLoginProvider, ASC.FederatedLogin",
"services": [
{
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"type": "ASC.FederatedLogin.LoginProviders.VKLoginProvider, ASC.FederatedLogin"
},
{
"key": "vk",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "vk",
"type": "ASC.FederatedLogin.LoginProviders.VKLoginProvider, ASC.FederatedLogin"
}
],
"instanceScope": "perlifetimescope",
"parameters": {
"name": "vk",
"order": "14",
"props": {
"vkClientId": "",
"vkClientSecret": ""
},
"additional": {
"vkRedirectUrl" : "https://service.teamlab.info/oauth2.aspx"
}
}
},
{
"type": "ASC.FederatedLogin.LoginProviders.WordpressLoginProvider, ASC.FederatedLogin",
@ -551,37 +520,6 @@
"wpRedirectUrl" : "https://service.teamlab.info/oauth2.aspx"
}
}
},
{
"type": "ASC.FederatedLogin.LoginProviders.YandexLoginProvider, ASC.FederatedLogin",
"services": [
{
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"type": "ASC.FederatedLogin.LoginProviders.YandexLoginProvider, ASC.FederatedLogin"
},
{
"key": "yandex",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "yandex",
"type": "ASC.FederatedLogin.LoginProviders.YandexLoginProvider, ASC.FederatedLogin"
}
],
"instanceScope": "perlifetimescope",
"parameters": {
"name": "yandex",
"order": "15",
"props": {
"yandexClientId": "",
"yandexClientSecret": ""
},
"additional": {
"yandexRedirectUrl" : "https://service.teamlab.info/oauth2.aspx"
}
}
},
{
"type": "ASC.Core.Common.Configuration.DataStoreConsumer, ASC.Core.Common",

File diff suppressed because it is too large Load Diff

View File

@ -3502,122 +3502,6 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>Collaborator</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Cyrl-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>Color</name>
<description/>
@ -4546,6 +4430,122 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>Context</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Cyrl-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>ContinueButton</name>
<description/>
@ -20090,6 +20090,122 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>PowerUser</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Cyrl-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>PreparationPortalTitle</name>
<description/>

View File

@ -90,7 +90,7 @@ namespace ASC.Migrations.MySql.Migrations.CoreDb
new
{
Tenant = -3,
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
Features = "free,total_size:2147483648,manager:5,room:5",
Name = "startup",
Price = 0m,
Visible = false

View File

@ -120,7 +120,7 @@ public partial class CoreDbContextMigrate : Migration
migrationBuilder.InsertData(
table: "tenants_quota",
columns: new[] { "tenant", "description", "features", "name", "product_id" },
values: new object[] { -3, null, "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", null });
values: new object[] { -3, null, "free,total_size:2147483648,manager:5,room:5", "startup", null });
migrationBuilder.InsertData(
table: "tenants_quota",

View File

@ -87,7 +87,7 @@ namespace ASC.Migrations.MySql.Migrations.CoreDb
new
{
Tenant = -3,
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
Features = "free,total_size:2147483648,manager:5,room:5",
Name = "startup",
Price = 0m,
Visible = false

View File

@ -85,7 +85,7 @@ namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
new
{
Tenant = -3,
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
Features = "free,total_size:2147483648,manager:5,room:5",
Name = "startup",
Price = 0m,
Visible = false

View File

@ -113,7 +113,7 @@ public partial class CoreDbContextMigrate : Migration
schema: "onlyoffice",
table: "tenants_quota",
columns: new[] { "tenant", "description", "features", "name", "visible" },
values: new object[] { -3, null, "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", false });
values: new object[] { -3, null, "free,total_size:2147483648,manager:5,room:5", "startup", false });
migrationBuilder.InsertData(
schema: "onlyoffice",

View File

@ -82,7 +82,7 @@ namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
new
{
Tenant = -3,
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
Features = "free,total_size:2147483648,manager:5,room:5",
Name = "startup",
Price = 0m,
Visible = false

View File

@ -36,8 +36,8 @@
"devDependencies": {
"auto-changelog": "file:./packages/auto-changelog-2.3.1.tgz",
"he": "^1.2.0",
"shx": "^0.3.3",
"terser": "^5.8.0"
"shx": "^0.3.4",
"terser": "^5.16.6"
},
"packageManager": "yarn@3.2.4"
}

View File

@ -41,49 +41,49 @@
"test:ui:mobile": "cross-env DEVICE_TYPE=mobile npx codecept-ui"
},
"dependencies": {
"copy-to-clipboard": "^3.3.1",
"copy-to-clipboard": "^3.3.3",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"firebase": "^8.10.0",
"firebase": "^8.10.1",
"hex-to-rgba": "^2.0.1",
"react-avatar-editor": "^13.0.0",
"react-colorful": "^5.5.1",
"react-hotkeys-hook": "^3.4.4",
"react-markdown": "^7.0.1",
"react-colorful": "^5.6.1",
"react-hotkeys-hook": "^3.4.7",
"react-markdown": "^7.1.2",
"react-smartbanner": "^5.1.4",
"react-string-format": "^0.1.4",
"windows-iana": "^5.1.0"
},
"devDependencies": {
"@babel/core": "^7.15.5",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-export-default-from": "^7.14.5",
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "^7.15.6",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.18.6",
"@babel/core": "^7.21.3",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-export-default-from": "^7.18.10",
"@babel/plugin-transform-runtime": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@svgr/webpack": "^5.5.0",
"babel-loader": "^8.2.2",
"babel-loader": "^8.3.0",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^9.0.1",
"css-loader": "^6.2.0",
"copy-webpack-plugin": "^9.1.0",
"css-loader": "^6.7.3",
"external-remotes-plugin": "^1.0.0",
"file-loader": "^6.2.0",
"html-loader": "^4.2.0",
"html-webpack-plugin": "5.3.2",
"html-webpack-plugin": "5.5.0",
"json-loader": "^0.5.7",
"playwright": "^1.18.1",
"sass": "^1.39.2",
"sass-loader": "^12.1.0",
"serve": "14.1.1",
"shx": "^0.3.3",
"source-map-loader": "^3.0.0",
"style-loader": "3.2.1",
"terser-webpack-plugin": "^5.2.4",
"typescript": "^4.7.4",
"webpack": "5.76.0",
"playwright": "^1.32.0",
"sass": "^1.59.3",
"sass-loader": "^12.6.0",
"serve": "14.2.0",
"shx": "^0.3.4",
"source-map-loader": "^3.0.2",
"style-loader": "3.3.2",
"terser-webpack-plugin": "^5.3.7",
"typescript": "^4.9.5",
"webpack": "5.76.3",
"webpack-cli": "4.10.0",
"webpack-dev-server": "4.3.1"
"webpack-dev-server": "4.13.1"
},
"title": "ONLYOFFICE"
}

View File

@ -1,5 +1,5 @@
{
"ChangePhoneInstructionSent": "Mobil telefonun dəyişdirilməsi haqqında təlimat müvəffəqiyyətlə göndərilmişdir",
"ChangePhoneInstructionSent": "Mobil telefonun dəyişdirilməsi haqqında təlimat müvəffəqiyyətlə göndərilmişdir.",
"MobilePhoneChangeTitle": "Mobil telefon nömrəsini dəyiş",
"MobilePhoneEraseDescription": "İstifadəçinin telefonu silinəcək və telefon nömrəsinin dəyişdirilməsi instruksiyası elektron poçt ünvanına göndəriləcək"
"MobilePhoneEraseDescription": "İstifadəçinin telefonu silinəcək və telefon nömrəsinin dəyişdirilməsi instruksiyası elektron poçt ünvanına göndəriləcək."
}

View File

@ -1,7 +1,5 @@
{
"BackupPortal": "Portal məlumatlarını yedəkləyin",
"ChangeOwner": "Modul administratorlarını təyin edin",
"DeactivateOrDeletePortal": " Modullara giriş hüquqlarını təyin edin",
"ManagePortal": " Portal konfiqurasiyasını idarə edin",
"BackupPortal": "DocSpace məlumatlarını yedəkləyin",
"ManagePortal": " DocSpace konfiqurasiyasını idarə edin",
"ManageUser": "İstifadəçi hesablarını idarə edin"
}

View File

@ -1,8 +1,7 @@
{
"ChangeUserStatusDialog": "{{ userStatus }} olan istifadəçilər {{ status }} olacaqlar.",
"ChangeUserStatusDialogHeader": "İstifadəçi statusunun dəyişdirilməsi",
"ChangeUserStatusDialogMessage": "Potalın sahibinin və öz statusunuzu dəyişdirə bilməzsiniz.",
"ChangeUsersActiveStatus": "iz ver",
"ChangeUsersDisableStatus": "Söndürülüb",
"ChangeUsersDisableStatus": "söndürülüb",
"ChangeUsersStatusButton": "İstifadəçi statusunun dəyişdirilməsi"
}

View File

@ -2,6 +2,6 @@
"ChangeUserTypeButton": "Növün dəyişdirilməsi",
"ChangeUserTypeHeader": "İstifadəçi növünün dəyişdirilməsi",
"ChangeUserTypeMessage": "'{{ firstType }}' tipinə malik olan istifadəçilər '{{ secondType }}' istifadəçi tipinə dəyişdirildi.",
"ChangeUserTypeMessageWarning": "Portal inzibatçının və özüvüzün istifadəçi tipini dəyişdirə bilməzsiniz.",
"ChangeUserTypeMessageWarning": "DocSpace inzibatçının və özüvüzün istifadəçi tipini dəyişdirə bilməzsiniz.",
"SuccessChangeUserType": "İstifadəçi tipi müvəffəqiyyətlə dəyişdirildi"
}

View File

@ -1,26 +1,26 @@
{
"ChangePasswordSuccess": "Şifrə uğurla dəyişdirildi",
"ConfirmOwnerPortalSuccessMessage": "Portal sahibi uğurla dəyişdirildi. 10 saniyə ərzində yönləndiriləcəksiniz",
"ConfirmOwnerPortalTitle": "Lütfən portal sahibini {{newOwner}} olaraq dəyişdirmək istədiyinizi təsdiqləyin",
"ConfirmOwnerPortalSuccessMessage": "DocSpace sahibi uğurla dəyişdirildi. 10 saniyə ərzində yönləndiriləcəksiniz.",
"ConfirmOwnerPortalTitle": "Lütfən DocSpace sahibini {{newOwner}} olaraq dəyişdirmək istədiyinizi təsdiqləyin.",
"CurrentNumber": "Cari mobil telefon nömrəniz",
"DeleteProfileBtn": "Hesabımı silin",
"DeleteProfileConfirmation": "Diqqət! Hesabınızı silmək üzrəsiniz.",
"DeleteProfileConfirmationInfo": "\"Hesabımı silin\" seçiminə klikləməklə bizim Məxfilik siyasətimizlə razılaşırsınız..",
"DeleteProfileConfirmationInfo": "\"Hesabımı silin\" seçiminə klikləməklə bizim Məxfilik siyasətimizlə razılaşırsınız.",
"DeleteProfileSuccessMessage": "Hesabınız uğurla silinmişdir.",
"DeleteProfileSuccessMessageInfo": "Hesabınızın və onunla bağlı məlumatların silinməsi haqqında daha ətraflı öyrənmək üçün bizim Məxfilik Siyasətimizə nəzər yetirin.",
"EmailAndPasswordCopiedToClipboard": "E-poçt ünvanı və şifrə mübadilə buferinə kopyalandı.",
"EnterAppCodeDescription": "Öz tətbiqinizdən əldə etdiyiniz 6 rəqəmli kodu daxil edin. Əgər telefonunuz əlçatan deyilsə, o zaman ehtiyat kodlarından istifadə edin.",
"EnterAppCodeTitle": "Doğrulama tətbiqindən kodu daxil edin.",
"EnterCodePlaceholder": "Kodu daxil edin.",
"EnterAppCodeTitle": "Doğrulama tətbiqindən kodu daxil edin",
"EnterCodePlaceholder": "Kodu daxil edin",
"EnterPhone": "Mobil telefon nömrəsi daxil edin",
"GetCode": "Kodu əldə edin",
"InviteTitle": "Siz portala qoşulmaq üçün dəvət olunmusunuz!",
"LoginRegistryButton": "Qoşulun",
"PassworResetTitle": "İndi yeni şifrə yarada bilərsiniz.",
"PhoneSubtitle": "Əlavə portal təhlükəsizliyini təmin etmək üçün iki faktorlu autentifikasiya işə salınıb. Portalda işə davam etmək üçün mobil telefon nömrənizi daxil edin. Mobil telefon nömrəsi ölkə kodu ilə beynəlxalq formatda daxil edilməlidir.",
"PhoneSubtitle": "Əlavə təhlükəsizliyini təmin etmək üçün iki faktorlu autentifikasiya işə salınıb. DocSpace işə davam etmək üçün mobil telefon nömrənizi daxil edin. Mobil telefon nömrəsi ölkə kodu ilə beynəlxalq formatda daxil edilməlidir.",
"SetAppButton": "Tətbiqə qoşulun",
"SetAppDescription": "İki faktorlu avtorizasiya kodu aktivləşdirildi. Portalda işləməyə davam etmək üçün doğrulama tətbiqini quraşdırın. Doğrulama tətbiqini <1>Android</1> və <4>iOS</4> və ya <8>Windows Phone</8> üçün istifadə edə bilərsiniz.",
"SetAppDescription": "İki faktorlu avtorizasiya kodu aktivləşdirildi. DocSpace-də işləməyə davam etmək üçün doğrulama tətbiqini quraşdırın. Doğrulama tətbiqini <1>Android</1> və <4>iOS</4> və ya <8>Windows Phone</8> üçün istifadə edə bilərsiniz.",
"SetAppInstallDescription": "Tətbiqə qoşulmaq üçün QR kodu skan edin və ya manual olaraq öz gizli açarınızı <1>{{ secretKey }}</1>, daha sonra isə aşağıdakı xanada tətbiqdən əldə etdiyiz 6 rəqəmli kodu daxil edin.",
"SetAppTitle": "Doğrulama tətbiqini quraşdırın",
"WelcomeUser": "Portalımıza xoş gəlmisiniz!\nBaşlamaq üçün qeydiyyatdan keçin və ya sosial şəbəkə vasitəsilə giriş edin."
"WelcomeUser": "DocSpace-ə xoş gəlmisiniz!\nBaşlamaq üçün qeydiyyatdan keçin və ya sosial şəbəkə vasitəsilə giriş edin."
}

View File

@ -1,6 +1,6 @@
{
"ConversionMessage": "Bütün yüklənilmiş sənədlər sürətli redaktə etmək üçün Office Open XML formatına (docx, xlsx və ya pptx) konvertasiya olunur.",
"ConvertedFileDestination": "Faylın nüsxəsi <strong>{{folderTitle}}</strong> qovluğunda yaradılacaq",
"ConvertedFileDestination": "Faylın nüsxəsi <strong>{{folderTitle}}</strong> qovluğunda yaradılacaq.",
"HideMessage": "Bu bildirişi bir daha göstərmə",
"InfoCreateFileIn": "Yeni fayl '{{fileTitle}}' '{{folderTitle}}' qovluğunda yaradıldı",
"SaveOriginalFormatMessage": "Faylın nüsxəsini orijinal formatda yadda saxla"

View File

@ -1,6 +1,6 @@
{
"ConversionPasswordFormCaption": "Şablonu yadda saxlamaq üçün şifrəni daxil edin",
"ConversionPasswordMasterFormCaption": "oform kimi yadda saxlamaq üçün şifrəni daxil edin",
"CreationError": "Faylın yaradılmasında xəta. Yanlış şifrə daxil edilib",
"CreationError": "Faylın yaradılmasında xəta. Yanlış şifrə daxil edilib.",
"SuccessfullyCreated": "Fayl '{{fileTitle}}' yaradıldı"
}

View File

@ -3,5 +3,5 @@
"Error403Text": "Təəssüf ki, giriş rədd edilmişdir.",
"Error404Text": "Təəssüf ki, resurs tapıla bilmir.",
"ErrorEmptyResponse": "Boş cavab",
"ErrorOfflineText": "İnternet bağlantısı tapılmadı."
"ErrorOfflineText": "İnternet bağlantısı tapılmadı"
}

View File

@ -14,7 +14,7 @@
"EmptyFile": "Boş fayl",
"EmptyFilterDescriptionText": "Heç bir fayl və ya qovluq bu süzgəcə uyğun deyil. Xahiş edirik digər süzgəc parametrindən istifadə edin və ya bütün faylların göstərilməsi üçün süzgəci sıfırlayın.",
"EmptyFilterSubheadingText": "Bu süzgəc üçün heç bir fayl tapılmadı",
"EmptyFolderDecription": "Faylları buraya çəkin və ya yenilərini yaradın.",
"EmptyFolderDecription": "Faylları buraya çəkin və ya yenilərini yaradın",
"EmptyFolderHeader": "Bu qovluqda heç bir fayl yoxdur",
"EmptyRecycleBin": "Boş zibil qutusu",
"EmptyScreenFolder": "Burada hələ ki, heç bir sənəd yoxdur",

View File

@ -1,5 +1,5 @@
{
"EmptyScreenDescription": "Lütfən, internet bağlantınızı yoxlayın və səhifəni yeniləyin, yaxud da bir qədər sonra yenidən yoxlayın",
"EmptyScreenDescription": "Lütfən, internet bağlantınızı yoxlayın və səhifəni yeniləyin, yaxud da bir qədər sonra yenidən yoxlayın.",
"GalleryEmptyScreenDescription": "Detalları görmək üçün istənilən forma şablonunu seçin",
"GalleryEmptyScreenHeader": "Forma şablonlarının yüklənməsi uğursuz oldu",
"TemplateInfo": "Şablon məlumatı"

View File

@ -4,6 +4,5 @@
"ItemsSelected": "Seçilmiş elementlər",
"LastModifiedBy": "tərəfindən Son Dəyişiklik",
"SystemProperties": "Sistem xüsusiyyətləri",
"Versions": "Versiyalar",
"ViewDetails": "Detallara baxın"
"Versions": "Versiyalar"
}

View File

@ -1,5 +1,5 @@
{
"LblInviteAgain": "Bir daha dəvət et",
"MessageEmailActivationInstuctionsSentOnEmail": "<1>{{email}}</1> elektron poçtuna aktivləşdirmə haqqında məlumat göndərilmişdir",
"MessageEmailActivationInstuctionsSentOnEmail": "<1>{{email}}</1> elektron poçtuna aktivləşdirmə haqqında məlumat göndərilmişdir.",
"UserStatus": "Status"
}

View File

@ -1,4 +1,4 @@
{
"PortalRestoring": "Portalın bərpası",
"PreparationPortalDescription": "Bərpa prosesi başa çatdıqdan sonra siz avtomatik olaraq portalınıza yönləndiriləcəksiniz."
"PreparationPortalDescription": "Bərpa prosesi başa çatdıqdan sonra siz avtomatik olaraq DocSpace-ə yönləndiriləcəksiniz."
}

View File

@ -1,8 +1,8 @@
{
"PrivacyButton": "ONLYOFFICE Desktop Editors tətbiqini açmaq",
"PrivacyClick": "Şifrələnmiş sənədlərlə işləmək üçün brauzer dialoqunda <1> ONLYOFFICE Desktop </1> düyməsini klikləyin ",
"PrivacyClick": "Şifrələnmiş sənədlərlə işləmək üçün brauzer dialoqunda <1> ONLYOFFICE Desktop </1> düyməsini klikləyin .",
"PrivacyDescriptionConnect": "Buludunuz bağlandıqdan sonra bu faylı masaüstü tətbiqinin interfeysindən aça bilərsiniz",
"PrivacyDescriptionEditors": "Əgər sizdə ONLYOFFICE Desktop Editors proqramı mövcuddursa və açılmırsa, çox güman brauzer tərəfindən bloklanılır",
"PrivacyDescriptionEditors": "Əgər sizdə ONLYOFFICE Desktop Editors proqramı mövcuddursa və açılmırsa, çox güman brauzer tərəfindən bloklanılır.",
"PrivacyDialog": "Dialoq pəncərəsi görsənmirsə, aşağıdakı düyməyə klikəyin",
"PrivacyEditors": "ONLYOFFICE Desktop Editors yoxdurmu?",
"PrivacyHeader": "Bu sənəd şifrələnmişdir ",

View File

@ -4,7 +4,7 @@
"EditPhoto": "Şəklin redaktə olunması",
"InterfaceTheme": "İnterfeys mövzusu",
"LightTheme": "İşıqlı tema",
"MessageEmailActivationInstuctionsSentOnEmail": " <strong>{{ email }}</strong> elektron poçta emailin aktivlşdirilməsi haqqında təlimat göndərilmişdir",
"MessageEmailActivationInstuctionsSentOnEmail": " <strong>{{ email }}</strong> elektron poçta emailin aktivlşdirilməsi haqqında təlimat göndərilmişdir.",
"ProviderSuccessfullyConnected": "Provayder müvəffəqiyyətlə qoşuldu",
"ProviderSuccessfullyDisconnected": "Provayderin əlaqəsi müvəffəqiyyətlə kəsildi",
"ShowBackupCodes": "Rezerv kodlarını göstər",

View File

@ -1,4 +1,4 @@
{
"SendInviteAgainDialog": "'Gözləmə' statusunda olan istifadəçilərə dəvətnamə yenidən göndərildi.",
"SendInviteAgainDialogMessage": "İstifadəçilər təsdiqdən sonra 'Aktiv' statusuna keçiriləcəklər"
"SendInviteAgainDialogMessage": "İstifadəçilər təsdiqdən sonra 'Aktiv' statusuna keçiriləcəklər."
}

View File

@ -10,10 +10,10 @@
"AuditTrailNav": "Audit izi",
"AutoBackup": "Avtomatik ehtiyat nüsxəsi",
"AutoBackupDescription": "Portal məlumatlarının avtomatik yedəklənməsi üçün bu seçimdən istifadə edin.",
"AutoBackupHelp": "<strong>Avtomatik ehtiyat nüsxə</strong> seçimi daha sonra yerli serverə bərpa edə bilmək üçün portal məlumatlarının ehtiyat nüsxəsini çıxarmaq prosesini avtomatlaşdırmaq məqsədilə istifadə olunur.",
"AutoBackupHelp": "<strong>Avtomatik ehtiyat nüsxə</strong> seçimi daha sonra yerli serverə bərpa edə bilmək üçün DocSpace məlumatlarının ehtiyat nüsxəsini çıxarmaq prosesini avtomatlaşdırmaq məqsədilə istifadə olunur.",
"AutoBackupHelpNote": "Məlumat yaddaşını, avtomatik yedəkləmə müddətini və saxlanılan nüsxələrin maksimum sayını seçin. <br/><strong>Qeyd:</strong> ehtiyat nüsxəsini üçüncü tərəf hesabında (DropBox, Box.com, OneDrive və ya Google Drive) saxlamazdan əvvəl bu hesabı {{organizationName}} Ümumi qovluğuna qoşmalısınız.",
"AutoSavePeriod": "Avtomatik yadda saxlama müddəti",
"AutoSavePeriodHelp": "Aşağıda göstərilən vaxt portalda təyin olunmuş saat qurşağına uyğun gəlir.",
"AutoSavePeriodHelp": "Aşağıda göstərilən vaxt DocSpace təyin olunmuş saat qurşağına uyğun gəlir.",
"Backup": "Yedəkləmə",
"BackupCreatedError": "Xəta ilə üzləşdiniz. Administratorunuzla əlaqə saxlayın.",
"BackupCreatedSuccess": "Ehtiyat nüsxə uğurla yaradıldı.",
@ -79,7 +79,7 @@
"PortalRenamingMobile": "onlyoffice.com/onlyoffice.eu portal ünvanının yanında görünəcək hissəni daxil edin. Qeyd edin: Yadda saxla düyməsini kliklədikdən sonra köhnə portal ünvanınız yeni istifadəçiləri üçün əlçatan olacaq.",
"PortalRenamingSettingsTooltip": "onlyoffice.com/onlyoffice.eu portal ünvanının yanında görünəcək hissəni daxil edin.",
"ProductUserOpportunities": "Profillərə və qruplara baxın",
"RecoveryFileNotSelected": "Bərpa xətası. Bərpa olunacaq fayl seçilməyib",
"RecoveryFileNotSelected": "Bərpa xətası. Bərpa olunacaq fayl seçilməyib.",
"RestoreBackup": "Məlumatların bərpası",
"RestoreBackupDescription": "Portalınızı əvvəllər saxlanmış ehtiyat faylından bərpa etmək üçün bu seçimdən istifadə edin.",
"RestoreBackupResetInfoWarningText": "Bütün cari parollar sıfırlanacaq. Portal istifadəçiləri girişin bərpası linki ilə e-poçt məktubu alacaqlar.",

View File

@ -11,7 +11,7 @@
"InternalLink": "Daxili link",
"Notify users": "İstifadəçilərə məlumat ver",
"ReadOnly": "Yalnız oxumaq üçün",
"ShareEmailBody": "Sizə {{itemName}} sənədinə giriş icazəsi verildi. Sənədi hazırda açmaq üçün aşağıdakı linki klikləyin: {{shareLink}} ",
"ShareEmailBody": "Sizə {{itemName}} sənədinə giriş icazəsi verildi. Sənədi hazırda açmaq üçün aşağıdakı linki klikləyin: {{shareLink}}.",
"ShareEmailSubject": "Sizə {{itemName}} sənədinə giriş icazəsi verildi ",
"ShareVia": "Paylaş",
"SharingSettingsTitle": "Paylaşma sazlamaları"

View File

@ -4,7 +4,7 @@
"ErrorEmail": "Etibarsız e-poçt ünvanı",
"ErrorInitWizard": "Xidmət hal-hazırda əlçatan deyil, lütfən bir qədər sonra yenidən cəhd edin.",
"ErrorInitWizardButton": "Yenidən cəhd edin",
"ErrorLicenseBody": "Lisenziya etibarlı deyil. Düzgün faylı seçdiyinizə əmin olun",
"ErrorLicenseBody": "Lisenziya etibarlı deyil. Düzgün faylı seçdiyinizə əmin olun.",
"ErrorPassword": "Şifrə tələblərə uyğun deyil",
"ErrorUploadLicenseFile": "Lisenziya faylını seçin",
"GeneratePassword": "Şifrə yaradın",

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