Merge branch 'release/1.0.0' into bugfix/dropdown-correct-display
This commit is contained in:
commit
b0fe6bd9e2
Binary file not shown.
BIN
.nuget/packages/AppLimit.CloudComputing.SharpBox.1.1.0.457.nupkg
Normal file
BIN
.nuget/packages/AppLimit.CloudComputing.SharpBox.1.1.0.457.nupkg
Normal file
Binary file not shown.
@ -56,9 +56,10 @@ done
|
||||
echo "== FRONT-END-BUILD =="
|
||||
|
||||
cd ${SRC_PATH}
|
||||
yarn install
|
||||
# debug config
|
||||
if [ "$DEBUG_INFO" = true ]; then
|
||||
yarn debug-info
|
||||
fi
|
||||
yarn install
|
||||
yarn ${BUILD_ARGS}
|
||||
yarn ${DEPLOY_ARGS}
|
||||
|
@ -2,12 +2,12 @@
|
||||
PRODUCT=onlyoffice
|
||||
REPO=${PRODUCT}
|
||||
STATUS=""
|
||||
SRV_VERSION=latest
|
||||
MYSQL_VERSION=8.0.18
|
||||
ELK_VERSION=7.13.1
|
||||
SERVICE_PORT=5050
|
||||
CONTAINER_PREFIX=${PRODUCT}-
|
||||
DOCKERFILE=Dockerfile-app
|
||||
DOCKER_TAG=latest
|
||||
DOCKERFILE=Dockerfile.app
|
||||
|
||||
# zookeeper #
|
||||
ZOO_PORT=2181
|
||||
|
@ -1,355 +0,0 @@
|
||||
### STAGE 1: Base image ######
|
||||
ARG SRC_PATH=/app/onlyoffice/src
|
||||
ARG BUILD_PATH=/var/www
|
||||
ARG REPO_TAG=5.0.202-focal-amd64
|
||||
ARG REPO=mcr.microsoft.com/dotnet/sdk
|
||||
|
||||
FROM $REPO:$REPO_TAG AS base
|
||||
ARG RELEASE_DATE=2021-04-11
|
||||
ARG VERSION=8.9.0.190
|
||||
ARG GIT_BRANCH=master
|
||||
ARG SRC_PATH
|
||||
ARG BUILD_PATH
|
||||
|
||||
LABEL onlyoffice.appserver.release-date="${RELEASE_DATE}" \
|
||||
onlyoffice.appserver.version="${VERSION}" \
|
||||
maintainer="Ascensio System SIA <support@onlyoffice.com>"
|
||||
|
||||
ENV LANG=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en \
|
||||
LC_ALL=en_US.UTF-8
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade && \
|
||||
apt-get -y dist-upgrade && \
|
||||
apt-get install -yq sudo locales && \
|
||||
addgroup --system --gid 107 onlyoffice && \
|
||||
adduser -uid 104 --quiet --home /var/www/onlyoffice --system --gid 107 onlyoffice && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
apt-get -y update && \
|
||||
apt-get install -yq git apt-utils npm nodejs && \
|
||||
npm install --global yarn
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
echo ${GIT_BRANCH} && \
|
||||
git clone --depth 1 -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git ${SRC_PATH}
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
cd ${SRC_PATH} && \
|
||||
mkdir -p /var/www/public/ && cp -rf public/* /var/www/public/ && \
|
||||
mkdir -p /app/onlyoffice/config/ && cp -rf config/* /app/onlyoffice/config/ && \
|
||||
mkdir -p /etc/nginx/conf.d && cp -f config/nginx/onlyoffice*.conf /etc/nginx/conf.d/ && \
|
||||
mkdir -p /etc/nginx/includes/ && cp -f config/nginx/includes/onlyoffice*.conf /etc/nginx/includes/ && \
|
||||
sed -e 's/#//' -i /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
cd ${SRC_PATH}/build/install/common/ && \
|
||||
bash build-frontend.sh -sp ${SRC_PATH} && \
|
||||
bash build-backend.sh -sp ${SRC_PATH} -ar "--disable-parallel" && \
|
||||
bash publish-backend.sh -sp ${SRC_PATH} -bp ${BUILD_PATH} -ar "--disable-parallel"
|
||||
|
||||
COPY config/mysql/conf.d/mysql.cnf /etc/mysql/conf.d/mysql.cnf
|
||||
COPY config/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
RUN sed -i 's/Server=.*;Port=/Server=127.0.0.1;Port=/' /app/onlyoffice/config/appsettings.test.json
|
||||
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
||||
|
||||
### STAGE 2: Build ###
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:5.0.4-focal-amd64 as builder
|
||||
|
||||
COPY --from=base /app/onlyoffice/config/ /app/onlyoffice/config/
|
||||
|
||||
# add defualt user and group for no-root run
|
||||
RUN mkdir -p /var/log/onlyoffice && \
|
||||
mkdir -p /app/onlyoffice/data && \
|
||||
addgroup --system --gid 107 onlyoffice && \
|
||||
adduser -uid 104 --quiet --home /var/www/onlyoffice --system --gid 107 onlyoffice && \
|
||||
chown onlyoffice:onlyoffice /app/onlyoffice -R && \
|
||||
chown onlyoffice:onlyoffice /var/log -R && \
|
||||
chown onlyoffice:onlyoffice /var/www -R
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade && \
|
||||
apt-get install -yq nano &&\
|
||||
apt-get install -yq jq &&\
|
||||
apt-get install -yq nodejs &&\
|
||||
apt-get install -yq libgdiplus
|
||||
|
||||
#USER onlyoffice
|
||||
EXPOSE 5050
|
||||
|
||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||
|
||||
### STAGE 3: Run ###
|
||||
|
||||
## NGINX ##
|
||||
#FROM nginx:stable-alpine AS web
|
||||
FROM nginx AS web
|
||||
ARG SRC_PATH="/app/onlyoffice/src"
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade && \
|
||||
apt-get install -yq vim && \
|
||||
# Remove default nginx website
|
||||
rm -rf /usr/share/nginx/html/*
|
||||
|
||||
# copy static services files and config values
|
||||
COPY --from=base /etc/nginx/conf.d /etc/nginx/conf.d
|
||||
COPY --from=base /etc/nginx/includes /etc/nginx/includes
|
||||
COPY --from=base /var/www/public /var/www/public
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.CRM/Client/dist /var/www/products/ASC.CRM/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Editor/dist /var/www/products/ASC.Files/editor
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Files/Client/dist /var/www/products/ASC.Files/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Login/dist /var/www/studio/login
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.People/Client/dist /var/www/products/ASC.People/client
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Projects/Client/dist /var/www/products/ASC.Projects/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Client/dist /var/www/studio/client
|
||||
|
||||
COPY /config/nginx/templates/upstream.conf.template /etc/nginx/templates/upstream.conf.template
|
||||
|
||||
# add defualt user and group for no-root run
|
||||
RUN chown nginx:nginx /etc/nginx/* -R &&\
|
||||
chown nginx:nginx /docker-entrypoint.d/* &&\
|
||||
# changes for upstream configure
|
||||
sed -i 's/localhost:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5012/$service_backup/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5021/$service_crm/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5007/$service_files/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5004/$service_people_server/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5020/$service_projects_server/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5000/$service_api/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:5003/$service_studio/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/localhost:9999/$service_urlshortener/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/172.*/$document_server;/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
# configute the image nginx whith less privileged https://hub.docker.com/_/nginx
|
||||
sed -i 's/pid.*nginx.pid;/pid \/tmp\/nginx.pid;/' /etc/nginx/nginx.conf && \
|
||||
sed -i 's/http.*{/http {\n client_body_temp_path \/tmp\/client_temp;\n proxy_temp_path \/tmp\/proxy_temp_path;\n fastcgi_temp_path \/tmp\/fastcgi_temp;\n uwsgi_temp_path \/tmp\/uwsgi_temp;\n scgi_temp_path \/tmp\/scgi_temp;/' /etc/nginx/nginx.conf
|
||||
|
||||
## ASC.ApiSystem ##
|
||||
FROM builder AS api_system
|
||||
|
||||
WORKDIR /var/www/services/apisystem/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/apisystem/ .
|
||||
|
||||
CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
|
||||
|
||||
## ASC.Data.Backup ##
|
||||
FROM builder AS backup
|
||||
|
||||
WORKDIR /var/www/services/backup/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/backup/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Data.Backup.dll", "ASC.Data.Backup", "core:products:folder=/var/www/products/", "core:products:subfolder=server"]
|
||||
|
||||
## ASC.CRM ##
|
||||
FROM builder AS crm
|
||||
|
||||
WORKDIR /var/www/products/ASC.CRM/server/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.CRM.dll", "ASC.CRM"]
|
||||
|
||||
## ASC.Data.Storage.Encryption ##
|
||||
FROM builder AS data_storage_encryption
|
||||
|
||||
WORKDIR /var/www/services/storage.encryption/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/storage.encryption/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Data.Storage.Encryption.dll", "ASC.Data.Storage.Encryption"]
|
||||
|
||||
## ASC.Files ##
|
||||
FROM builder AS files
|
||||
|
||||
WORKDIR /var/www/products/ASC.Files/server/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${SRC_PATH}/ASC.Files/Server/DocStore .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Files.dll", "ASC.Files"]
|
||||
|
||||
## ASC.Files.Service ##
|
||||
FROM builder AS files_services
|
||||
|
||||
WORKDIR /var/www/products/ASC.Files/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People*.dll /var/www/products/ASC.People/Server/
|
||||
|
||||
CMD ["ASC.Files.Service.dll", "ASC.Files.Service", "core:products:folder=/var/www/products/", "core:products:subfolder=server"]
|
||||
|
||||
## ASC.Data.Storage.Migration ##
|
||||
FROM builder AS data_storage_migration
|
||||
|
||||
WORKDIR /var/www/services/storage.migration/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/storage.migration/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ /var/www/products/ASC.Files/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ /var/www/products/ASC.People/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ /var/www/products/ASC.CRM/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ /var/www/products/ASC.Projects/Server/
|
||||
|
||||
|
||||
CMD ["ASC.Data.Storage.Migration.dll", "ASC.Data.Storage.Migration"]
|
||||
|
||||
## ASC.Notify ##
|
||||
FROM builder AS notify
|
||||
|
||||
WORKDIR /var/www/services/notify/service
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base /var/www/services/notify/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/Server/
|
||||
|
||||
CMD ["ASC.Notify.dll", "ASC.Notify", "core:products:folder=/var/www/products/", "core:products:subfolder=server"]
|
||||
|
||||
## ASC.People ##
|
||||
FROM builder AS people_server
|
||||
|
||||
WORKDIR /var/www/products/ASC.People/server/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.People.dll", "ASC.People"]
|
||||
|
||||
## ASC.Projects ##
|
||||
FROM builder AS projects_server
|
||||
|
||||
WORKDIR /var/www/products/ASC.Projects/server/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Projects.dll", "ASC.Projects"]
|
||||
|
||||
## ASC.Socket.IO.Svc ##
|
||||
FROM builder AS socket
|
||||
|
||||
WORKDIR /var/www/services/socket/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/socket/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/socket/client /var/www/ASC.Socket.IO
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Socket.IO.Svc.dll", "ASC.Socket.IO.Svc"]
|
||||
|
||||
## ASC.Studio.Notify ##
|
||||
FROM builder AS studio_notify
|
||||
|
||||
WORKDIR /var/www/services/studio.notify/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base /var/www/services/studio.notify/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/Server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/Server/
|
||||
|
||||
CMD ["ASC.Studio.Notify.dll", "ASC.Studio.Notify", "core:products:folder=/var/www/products/", "core:products:subfolder=server"]
|
||||
|
||||
## ASC.TelegramService ##
|
||||
FROM builder AS telegram_service
|
||||
|
||||
WORKDIR /var/www/services/telegram/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/telegram/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.TelegramService.dll", "ASC.TelegramService"]
|
||||
|
||||
## ASC.Thumbnails.Svc ##
|
||||
FROM builder AS thumbnails
|
||||
|
||||
WORKDIR /var/www/services/thumb/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/thumb/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/thumb/client /var/www/services/thumb/client
|
||||
|
||||
CMD ["ASC.Thumbnails.Svc.dll", "ASC.Thumbnails.Svc"]
|
||||
|
||||
## ASC.UrlShortener.Svc ##
|
||||
FROM builder AS urlshortener
|
||||
|
||||
WORKDIR /var/www/services/urlshortener/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/urlshortener/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/services/urlshortener/client /var/www/services/urlshortener/client
|
||||
|
||||
CMD ["ASC.UrlShortener.Svc.dll", "ASC.UrlShortener.Svc"]
|
||||
|
||||
## ASC.Web.Api ##
|
||||
FROM builder AS api
|
||||
|
||||
WORKDIR /var/www/studio/api/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/studio/api .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Web.Api.dll", "ASC.Web.Api"]
|
||||
|
||||
## ASC.Web.Studio ##
|
||||
FROM builder AS studio
|
||||
|
||||
WORKDIR /var/www/studio/server/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.sh .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/studio/server/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Files/server/ASC.Files*.dll /var/www/products/ASC.Files/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.People/server/ASC.People.dll /var/www/products/ASC.People/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.CRM/server/ASC.CRM*.dll /var/www/products/ASC.CRM/server/
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice /var/www/products/ASC.Projects/server/ASC.Projects*.dll /var/www/products/ASC.Projects/server/
|
||||
|
||||
CMD ["ASC.Web.Studio.dll", "ASC.Web.Studio"]
|
@ -37,19 +37,17 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash - && \
|
||||
apt-get install -y nodejs
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
echo ${GIT_BRANCH} && \
|
||||
git clone --depth 1 --recurse-submodules -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git ${SRC_PATH}
|
||||
RUN echo ${GIT_BRANCH} && \
|
||||
git clone --recurse-submodules -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git ${SRC_PATH}
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
cd ${SRC_PATH} && \
|
||||
RUN cd ${SRC_PATH} && \
|
||||
mkdir -p /app/onlyoffice/config/ && cp -rf config/* /app/onlyoffice/config/ && \
|
||||
mkdir -p /etc/nginx/conf.d && cp -f config/nginx/onlyoffice*.conf /etc/nginx/conf.d/ && \
|
||||
mkdir -p /etc/nginx/includes/ && cp -f config/nginx/includes/onlyoffice*.conf /etc/nginx/includes/ && \
|
||||
sed -i "s/\"number\".*,/\"number\": \"${PRODUCT_VERSION}.${BUILD_NUMBER}\",/g" /app/onlyoffice/config/appsettings.json && \
|
||||
sed -e 's/#//' -i /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
cd ${SRC_PATH}/build/install/common/ && \
|
||||
bash build-frontend.sh -sp "${SRC_PATH}" -ba "${BUILD_ARGS}" -da "${DEPLOY_ARGS}" && -di "${DEBUG_INFO}" && \
|
||||
bash build-frontend.sh -sp "${SRC_PATH}" -ba "${BUILD_ARGS}" -da "${DEPLOY_ARGS}" -di "${DEBUG_INFO}" && \
|
||||
bash build-backend.sh -sp "${SRC_PATH}" && \
|
||||
bash publish-backend.sh -sp "${SRC_PATH}" -bp "${BUILD_PATH}" && \
|
||||
cp -rf ${SRC_PATH}/products/ASC.Files/Server/DocStore ${BUILD_PATH}/products/ASC.Files/server/ && \
|
||||
@ -64,7 +62,6 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
rm -rf ${SRC_PATH}/products/ASC.People/Server/* && \
|
||||
rm -rf ${SRC_PATH}/products/ASC.Projects/Server/*
|
||||
|
||||
|
||||
COPY config/mysql/conf.d/mysql.cnf /etc/mysql/conf.d/mysql.cnf
|
||||
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
@ -18,7 +18,6 @@ x-service:
|
||||
DOCUMENT_SERVER_JWT_HEADER: ${DOCUMENT_SERVER_JWT_HEADER}
|
||||
DOCUMENT_SERVER_URL_PUBLIC: ${DOCUMENT_SERVER_URL_PUBLIC}
|
||||
DOCUMENT_SERVER_URL_INTERNAL: ${DOCUMENT_SERVER_URL_INTERNAL}
|
||||
DOCUMENT_SERVER_URL_CONVERTER: ${DOCUMENT_SERVER_URL_CONVERTER}
|
||||
KAFKA_HOST: ${KAFKA_HOST}
|
||||
ELK_HOST: ${ELK_HOST}
|
||||
PROXY_HOST: ${PROXY_HOST}
|
||||
@ -32,7 +31,6 @@ x-service:
|
||||
- calendar_data:/var/www/products/ASC.Calendar/server/
|
||||
- mail_data:/var/www/products/ASC.Mail/server/
|
||||
|
||||
|
||||
services:
|
||||
onlyoffice-elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
|
||||
@ -55,97 +53,64 @@ services:
|
||||
- "9200"
|
||||
- "9300"
|
||||
|
||||
onlyoffice-zookeeper:
|
||||
image: zookeeper:latest
|
||||
container_name: ${ZOO_HOST}
|
||||
restart: always
|
||||
expose:
|
||||
- "2181"
|
||||
environment:
|
||||
ZOO_MY_ID: 1
|
||||
ZOO_PORT: ${ZOO_PORT:-2181}
|
||||
ZOO_SERVER: ${ZOO_SERVER}
|
||||
volumes:
|
||||
- zoo_data:/data
|
||||
- zoo_log:/datalog
|
||||
|
||||
onlyoffice-kafka:
|
||||
image: confluentinc/cp-kafka:latest
|
||||
container_name: ${KAFKA_HOST}
|
||||
restart: always
|
||||
expose:
|
||||
- "9092"
|
||||
depends_on:
|
||||
- onlyoffice-zookeeper
|
||||
environment:
|
||||
KAFKA_ADVERTISED_LISTENERS: ${KAFKA_ADVERTISED_LISTENERS}
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: ${KAFKA_LISTENER_SECURITY_PROTOCOL_MAP}
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: ${KAFKA_INTER_BROKER_LISTENER_NAME}
|
||||
KAFKA_ZOOKEEPER_CONNECT: ${KAFKA_ZOOKEEPER_CONNECT}
|
||||
KAFKA_BROKER_ID: ${KAFKA_BROKER_ID}
|
||||
KAFKA_LOG4J_LOGGERS: ${KAFKA_LOG4J_LOGGERS}
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: ${KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR}
|
||||
volumes:
|
||||
- kafka_data:/var/lib/kafka/data
|
||||
|
||||
onlyoffice-api-system:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-api-system:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-api-system:${DOCKER_TAG}"
|
||||
container_name: ${API_SYSTEM_HOST}
|
||||
|
||||
onlyoffice-backup:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-backup:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-backup:${DOCKER_TAG}"
|
||||
container_name: ${BACKUP_HOST}
|
||||
|
||||
onlyoffice-calendar:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-calendar:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-calendar:${DOCKER_TAG}"
|
||||
container_name: ${CALENDAR_HOST}
|
||||
|
||||
onlyoffice-crm:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-crm:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-crm:${DOCKER_TAG}"
|
||||
container_name: ${CRM_HOST}
|
||||
|
||||
onlyoffice-storage-encryption:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-storage-encryption:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-storage-encryption:${DOCKER_TAG}"
|
||||
container_name: ${STORAGE_ENCRYPTION_HOST}
|
||||
|
||||
onlyoffice-files:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-files:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-files:${DOCKER_TAG}"
|
||||
container_name: ${FILES_HOST}
|
||||
|
||||
onlyoffice-files-services:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-files-services:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-files-services:${DOCKER_TAG}"
|
||||
container_name: ${FILES_SERVICES_HOST}
|
||||
|
||||
onlyoffice-mail:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-mail:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-mail:${DOCKER_TAG}"
|
||||
container_name: ${MAIL_HOST}
|
||||
|
||||
onlyoffice-storage-migration:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-storage-migration:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-storage-migration:${DOCKER_TAG}"
|
||||
container_name: ${STORAGE_MIGRATION_HOST}
|
||||
|
||||
onlyoffice-people-server:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-people-server:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-people-server:${DOCKER_TAG}"
|
||||
container_name: ${PEOPLE_SERVER_HOST}
|
||||
|
||||
onlyoffice-projects-server:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-projects-server:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-projects-server:${DOCKER_TAG}"
|
||||
container_name: ${PROJECTS_SERVER_HOST}
|
||||
|
||||
onlyoffice-socket:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-socket:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-socket:${DOCKER_TAG}"
|
||||
container_name: ${SOCKET_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
@ -153,17 +118,17 @@ services:
|
||||
|
||||
onlyoffice-studio-notify:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-studio-notify:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-studio-notify:${DOCKER_TAG}"
|
||||
container_name: ${STUDIO_NOTIFY_HOST}
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-telegram-service:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-telegram-service:${DOCKER_TAG}"
|
||||
container_name: ${TELEGRAM_SERVICE_HOST}
|
||||
|
||||
onlyoffice-thumbnails:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-thumbnails:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-thumbnails:${DOCKER_TAG}"
|
||||
container_name: ${THUMBNAILS_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
@ -171,7 +136,7 @@ services:
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-urlshortener:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-urlshortener:${DOCKER_TAG}"
|
||||
container_name: ${URLSHORTENER_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
@ -179,24 +144,24 @@ services:
|
||||
|
||||
onlyoffice-api:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-api:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-api:${DOCKER_TAG}"
|
||||
container_name: ${API_HOST}
|
||||
|
||||
onlyoffice-studio:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-studio:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-studio:${DOCKER_TAG}"
|
||||
container_name: ${STUDIO_HOST}
|
||||
|
||||
onlyoffice-ssoauth:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-ssoauth:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-ssoauth:${DOCKER_TAG}"
|
||||
container_name: ${SSOAUTH_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
- "9834"
|
||||
|
||||
onlyoffice-proxy:
|
||||
image: "${REPO}/${STATUS}appserver-proxy:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-proxy:${DOCKER_TAG}"
|
||||
container_name: ${PROXY_HOST}
|
||||
restart: always
|
||||
expose:
|
||||
@ -257,10 +222,7 @@ networks:
|
||||
name: ${NETWORK_NAME}
|
||||
|
||||
volumes:
|
||||
kafka_data:
|
||||
es_data:
|
||||
zoo_data:
|
||||
zoo_log:
|
||||
proxy_log:
|
||||
app_data:
|
||||
files_data:
|
||||
|
@ -6,158 +6,158 @@ services:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: api_system
|
||||
image: "${REPO}/${STATUS}appserver-api-system:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-api-system:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-backup:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: backup
|
||||
image: "${REPO}/${STATUS}appserver-backup:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-backup:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-calendar:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: calendar
|
||||
image: "${REPO}/${STATUS}appserver-calendar:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-calendar:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-crm:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: crm
|
||||
image: "${REPO}/${STATUS}appserver-crm:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-crm:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-storage-encryption:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: data_storage_encryption
|
||||
image: "${REPO}/${STATUS}appserver-storage-encryption:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-storage-encryption:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-files:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: files
|
||||
image: "${REPO}/${STATUS}appserver-files:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-files:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-files-services:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: files_services
|
||||
image: "${REPO}/${STATUS}appserver-files-services:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-files-services:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-mail:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: mail
|
||||
image: "${REPO}/${STATUS}appserver-mail:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-mail:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-storage-migration:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: data_storage_migration
|
||||
image: "${REPO}/${STATUS}appserver-storage-migration:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-storage-migration:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-notify:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: notify
|
||||
image: "${REPO}/${STATUS}appserver-notify:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-notify:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-people-server:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: people_server
|
||||
image: "${REPO}/${STATUS}appserver-people-server:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-people-server:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-projects-server:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: projects_server
|
||||
image: "${REPO}/${STATUS}appserver-projects-server:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-projects-server:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-socket:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: socket
|
||||
image: "${REPO}/${STATUS}appserver-socket:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-socket:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-studio-notify:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: studio_notify
|
||||
image: "${REPO}/${STATUS}appserver-studio-notify:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-studio-notify:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: telegram_service
|
||||
image: "${REPO}/${STATUS}appserver-telegram-service:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-telegram-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-thumbnails:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: thumbnails
|
||||
image: "${REPO}/${STATUS}appserver-thumbnails:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-thumbnails:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: urlshortener
|
||||
image: "${REPO}/${STATUS}appserver-urlshortener:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-urlshortener:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-api:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: api
|
||||
image: "${REPO}/${STATUS}appserver-api:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-api:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-studio:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: studio
|
||||
image: "${REPO}/${STATUS}appserver-studio:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-studio:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-ssoauth:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: ssoauth
|
||||
image: "${REPO}/${STATUS}appserver-ssoauth:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-ssoauth:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-bin-share:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: bin_share
|
||||
image: "${REPO}/${STATUS}appserver-bin-share:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-bin-share:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-wait-bin-share:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: wait_bin_share
|
||||
image: "${REPO}/${STATUS}appserver-wait-bin-share:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-wait-bin-share:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-proxy:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: web
|
||||
image: "${REPO}/${STATUS}appserver-proxy:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-proxy:${DOCKER_TAG}"
|
||||
|
@ -1,8 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "##########################################################"
|
||||
echo "############## Run App Service ####################"
|
||||
echo "##########################################################"
|
||||
# read parameters
|
||||
if [ -n "$1" ]; then
|
||||
DOTNET_RUN="${1}";
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
DOTNET_LOG_NAME="${1}";
|
||||
shift
|
||||
fi
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
PARAMETERS="$PARAMETERS --${1}";
|
||||
shift
|
||||
done
|
||||
|
||||
echo "#-------------------------------------#"
|
||||
echo "Run ${DOTNET_RUN}"
|
||||
echo "#-------------------------------------#"
|
||||
|
||||
PRODUCT=${PRODUCT:-"onlyoffice"}
|
||||
BASE_DIR="/app/${PRODUCT}"
|
||||
@ -29,9 +45,6 @@ DOCUMENT_SERVER_JWT_SECRET=${DOCUMENT_SERVER_JWT_SECRET:-"your_jwt_secret"}
|
||||
DOCUMENT_SERVER_JWT_HEADER=${DOCUMENT_SERVER_JWT_HEADER:-"AuthorizationJwt"}
|
||||
DOCUMENT_SERVER_URL_PUBLIC=${DOCUMENT_SERVER_URL_PUBLIC:-"/ds-vpath/"}
|
||||
DOCUMENT_SERVER_URL_INTERNAL=${DOCUMENT_SERVER_URL_INTERNAL:-"${SHEME}://${PRODUCT}-document-server/"}
|
||||
DOCUMENT_SERVER_URL_CONVERTER=${DOCUMENT_SERVER_URL_CONVERTER:-"/ds-vpath/ConvertService.ashx"}
|
||||
VIEWED_MEDIA=${VIEWED_MEDIA:-'".aac",".flac",".m4a",".mp3",".oga",".ogg",".wav",".f4v",".m4v",".mov",".mp4",".ogv",".webm",".avi"'}
|
||||
FFMPEG_EXTS=${FFMPEG_EXTS:-'"avi", "mpeg", "mpg", "wmv"'}
|
||||
|
||||
ELK_SHEME=${ELK_SHEME:-"http"}
|
||||
ELK_HOST=${ELK_HOST:-"${PRODUCT}-elasticsearch"}
|
||||
@ -42,29 +55,12 @@ KAFKA_HOST=${KAFKA_HOST:-"kafka"}":9092"
|
||||
|
||||
APP_STORAGE_ROOT=${APP_STORAGE_ROOT:-"${BASE_DIR}/data/"}
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
DOTNET_RUN="${1}";
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
DOTNET_LOG_NAME="${1}";
|
||||
shift
|
||||
fi
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
PARAMETERS="$PARAMETERS --${1}";
|
||||
shift
|
||||
done
|
||||
|
||||
sed -i "s!Server=.*;Pooling=!Server=${MYSQL_HOST};Port=3306;Database=${MYSQL_DATABASE};User ID=${MYSQL_USER};Password=${MYSQL_PASSWORD};Pooling=!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"base-domain\".*,!\"base-domain\": \"${APP_CORE_BASE_DOMAIN}\",!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"machinekey\".*,!\"machinekey\": \"${APP_CORE_MACHINEKEY}\",!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"public\".*,!\"public\": \"${DOCUMENT_SERVER_URL_PUBLIC}\",!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"internal\".*,!\"internal\": \"${DOCUMENT_SERVER_URL_INTERNAL}\",!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"portal\".*!\"portal\": \"${APP_URL_PORTAL}\",!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"viewed-media\".*!\"viewed-media\": \[${VIEWED_MEDIA}\]!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"exts\".*!\"exts\": \[ ${FFMPEG_EXTS} \]!g" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "0,/\"value\"/s!\"value\".*,!\"value\": \"${DOCUMENT_SERVER_JWT_SECRET}\",!" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
sed -i "s!\"header\".*!\"header\": \"${DOCUMENT_SERVER_JWT_HEADER}\"!" ${PATH_TO_CONF}/appsettings.${APP_DOTNET_ENV}.json
|
||||
|
||||
@ -73,7 +69,6 @@ sed -i "s!\"Host\".*!\"Host\": \"${ELK_HOST}\",!g" ${PATH_TO_CONF}/elastic.json
|
||||
sed -i "s!\"Port\".*!\"Port\": \"${ELK_PORT}\",!g" ${PATH_TO_CONF}/elastic.json
|
||||
sed -i "s!\"Threads\".*!\"Threads\": \"${ELK_THREADS}\"!g" ${PATH_TO_CONF}/elastic.json
|
||||
|
||||
|
||||
sed -i "s!\"subfolder\".*!\"subfolder\": \"server\",!g" ${PATH_TO_CONF}/appsettings.services.json
|
||||
sed -i "s!\"BootstrapServers\".*!\"BootstrapServers\": \"${KAFKA_HOST}\"!g" ${PATH_TO_CONF}/kafka.${APP_DOTNET_ENV}.json
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
export SRV_VERSION=$DOCKER_TAG
|
||||
export DOCKER_TAG=$DOCKER_TAG
|
||||
BUILD_NUMBER="$(date "+%Y%m%d%H")"
|
||||
docker-compose -f build.yml build \
|
||||
--build-arg GIT_BRANCH=$SOURCE_BRANCH \
|
||||
|
@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
export SRV_VERSION=$DOCKER_TAG
|
||||
export DOCKER_TAG=$DOCKER_TAG
|
||||
docker-compose -f build.yml push
|
||||
|
43
build/install/docker/kafka.yml
Normal file
43
build/install/docker/kafka.yml
Normal file
@ -0,0 +1,43 @@
|
||||
version: "3.6"
|
||||
services:
|
||||
onlyoffice-zookeeper:
|
||||
image: zookeeper:latest
|
||||
container_name: ${ZOO_HOST}
|
||||
restart: always
|
||||
expose:
|
||||
- "2181"
|
||||
environment:
|
||||
ZOO_MY_ID: 1
|
||||
ZOO_PORT: ${ZOO_PORT:-2181}
|
||||
ZOO_SERVER: ${ZOO_SERVER}
|
||||
volumes:
|
||||
- /app/onlyoffice/data/zookeeper/zoo_data:/data
|
||||
- /app/onlyoffice/data/zookeeper/zoo_log:/datalog
|
||||
|
||||
onlyoffice-kafka:
|
||||
image: confluentinc/cp-kafka:latest
|
||||
container_name: ${KAFKA_HOST}
|
||||
restart: always
|
||||
expose:
|
||||
- "9092"
|
||||
depends_on:
|
||||
- onlyoffice-zookeeper
|
||||
environment:
|
||||
KAFKA_ADVERTISED_LISTENERS: ${KAFKA_ADVERTISED_LISTENERS}
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: ${KAFKA_LISTENER_SECURITY_PROTOCOL_MAP}
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: ${KAFKA_INTER_BROKER_LISTENER_NAME}
|
||||
KAFKA_ZOOKEEPER_CONNECT: ${KAFKA_ZOOKEEPER_CONNECT}
|
||||
KAFKA_BROKER_ID: ${KAFKA_BROKER_ID}
|
||||
KAFKA_LOG4J_LOGGERS: ${KAFKA_LOG4J_LOGGERS}
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: ${KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR}
|
||||
volumes:
|
||||
#- /app/onlyoffice/data/kafka_data:/var/lib/kafka/data
|
||||
- kafka_data:/var/lib/kafka/data
|
||||
|
||||
volumes:
|
||||
kafka_data:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: "onlyoffice"
|
@ -18,7 +18,6 @@ x-service:
|
||||
DOCUMENT_SERVER_JWT_HEADER: ${DOCUMENT_SERVER_JWT_HEADER}
|
||||
DOCUMENT_SERVER_URL_PUBLIC: ${DOCUMENT_SERVER_URL_PUBLIC}
|
||||
DOCUMENT_SERVER_URL_INTERNAL: ${DOCUMENT_SERVER_URL_INTERNAL}
|
||||
DOCUMENT_SERVER_URL_CONVERTER: ${DOCUMENT_SERVER_URL_CONVERTER}
|
||||
KAFKA_HOST: ${KAFKA_HOST}
|
||||
ELK_HOST: ${ELK_HOST}
|
||||
PROXY_HOST: ${PROXY_HOST}
|
||||
@ -35,7 +34,7 @@ x-service:
|
||||
services:
|
||||
onlyoffice-notify:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${STATUS}appserver-notify:${SRV_VERSION}"
|
||||
image: "${REPO}/${STATUS}appserver-notify:${DOCKER_TAG}"
|
||||
container_name: ${NOTIFY_HOST}
|
||||
|
||||
networks:
|
||||
|
@ -68,10 +68,12 @@ namespace ASC.Common.Caching
|
||||
public class AscCache : ICache
|
||||
{
|
||||
private IMemoryCache MemoryCache { get; }
|
||||
private ConcurrentDictionary<string, object> MemoryCacheKeys { get; }
|
||||
|
||||
public AscCache(IMemoryCache memoryCache)
|
||||
{
|
||||
MemoryCache = memoryCache;
|
||||
MemoryCache = memoryCache;
|
||||
MemoryCacheKeys = new ConcurrentDictionary<string, object>();
|
||||
}
|
||||
|
||||
public T Get<T>(string key) where T : class
|
||||
@ -80,14 +82,29 @@ namespace ASC.Common.Caching
|
||||
}
|
||||
|
||||
public void Insert(string key, object value, TimeSpan sligingExpiration)
|
||||
{
|
||||
MemoryCache.Set(key, value, new MemoryCacheEntryOptions(){ SlidingExpiration = sligingExpiration });
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions()
|
||||
.SetSlidingExpiration(sligingExpiration)
|
||||
.RegisterPostEvictionCallback(EvictionCallback);
|
||||
|
||||
MemoryCache.Set(key, value, options);
|
||||
MemoryCacheKeys.TryAdd(key, null);
|
||||
}
|
||||
|
||||
public void Insert(string key, object value, DateTime absolutExpiration)
|
||||
{
|
||||
MemoryCache.Set(key, value, absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration));
|
||||
}
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions()
|
||||
.SetAbsoluteExpiration(absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration))
|
||||
.RegisterPostEvictionCallback(EvictionCallback);
|
||||
|
||||
MemoryCache.Set(key, value, options);
|
||||
MemoryCacheKeys.TryAdd(key, null);
|
||||
}
|
||||
|
||||
private void EvictionCallback(object key, object value, EvictionReason reason, object state)
|
||||
{
|
||||
MemoryCacheKeys.TryRemove(key.ToString(), out _);
|
||||
}
|
||||
|
||||
public void Remove(string key)
|
||||
{
|
||||
@ -96,21 +113,19 @@ namespace ASC.Common.Caching
|
||||
|
||||
public void Remove(Regex pattern)
|
||||
{
|
||||
//var cache = GetCache();
|
||||
var copy = MemoryCacheKeys.ToDictionary(p => p.Key, p => p.Value);
|
||||
var keys = copy.Select(p => p.Key).Where(k => pattern.IsMatch(k)).ToArray();
|
||||
|
||||
//var copy = cache.ToDictionary(p => p.Key, p => p.Value);
|
||||
|
||||
//var keys = copy.Select(p => p.Key).Where(k => pattern.IsMatch(k)).ToArray();
|
||||
//foreach (var key in keys)
|
||||
//{
|
||||
// cache.Remove(key);
|
||||
//}
|
||||
foreach (var key in keys)
|
||||
{
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ConcurrentDictionary<string, T> HashGetAll<T>(string key)
|
||||
{
|
||||
return MemoryCache.GetOrCreate(key, r=> new ConcurrentDictionary<string, T>());
|
||||
return MemoryCache.GetOrCreate(key, r => new ConcurrentDictionary<string, T>());
|
||||
}
|
||||
|
||||
public T HashGet<T>(string key, string field)
|
||||
|
@ -41,7 +41,7 @@
|
||||
"value": "ffmpeg",
|
||||
"exts": [ "avi", "mpeg", "mpg", "wmv" ]
|
||||
},
|
||||
"viewed-media": [".aac",".flac",".m4a",".mp3",".oga",".ogg",".wav",".f4v",".m4v",".mov",".mp4",".ogv",".webm",".avi"],
|
||||
"viewed-media": [ ".aac",".flac",".m4a",".mp3",".oga",".ogg",".wav",".f4v",".m4v",".mov",".mp4",".ogv",".webm",".avi" ],
|
||||
"thirdparty": {
|
||||
"enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ]
|
||||
}
|
||||
|
@ -256,6 +256,7 @@ class VideoViewer extends Component {
|
||||
loop: false,
|
||||
isNew: false,
|
||||
error: false,
|
||||
isLoaded: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@ -377,7 +378,7 @@ class VideoViewer extends Component {
|
||||
};
|
||||
|
||||
onPlay = () => {
|
||||
this.setState({ playing: !this.state.isNew, isNew: false });
|
||||
this.setState({ playing: !this.state.isNew, isNew: false, isLoaded: true });
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -395,6 +396,7 @@ class VideoViewer extends Component {
|
||||
playbackRate,
|
||||
pip,
|
||||
error,
|
||||
isLoaded,
|
||||
} = this.state;
|
||||
const { errorLabel } = this.props;
|
||||
|
||||
@ -461,11 +463,13 @@ class VideoViewer extends Component {
|
||||
<ReactPlayer
|
||||
ref={this.ref}
|
||||
className="react-player"
|
||||
style={{ opacity: isLoaded ? 1 : 0 }}
|
||||
width="100%"
|
||||
height="100%"
|
||||
url={url}
|
||||
pip={pip}
|
||||
playing={playing}
|
||||
playsinline={true}
|
||||
controls={controls}
|
||||
light={light}
|
||||
loop={loop}
|
||||
|
@ -4,8 +4,8 @@ import omit from "lodash/omit";
|
||||
|
||||
export const desktopConstants = Object.freeze({
|
||||
domain: window.location.origin,
|
||||
provider: "AppServer",
|
||||
guid: "{FFF0E1EB-13DB-4678-B67D-FF0A41DBBCEF}",
|
||||
provider: "onlyoffice",
|
||||
cryptoEngineId: "{FFF0E1EB-13DB-4678-B67D-FF0A41DBBCEF}",
|
||||
});
|
||||
|
||||
export function regDesktop(
|
||||
@ -33,7 +33,7 @@ export function regDesktop(
|
||||
extendedData = {
|
||||
...data,
|
||||
encryptionKeys: {
|
||||
cryptoEngineId: desktopConstants.guid,
|
||||
cryptoEngineId: desktopConstants.cryptoEngineId,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -256,7 +256,7 @@ class AuthStore {
|
||||
window.AscDesktopEditor.cloudCryptoCommand(
|
||||
"share",
|
||||
{
|
||||
cryptoEngineId: desktopConstants.guid,
|
||||
cryptoEngineId: desktopConstants.cryptoEngineId,
|
||||
file: [file.viewUrl],
|
||||
keys: keys,
|
||||
},
|
||||
|
@ -92,6 +92,9 @@ class SettingsStore {
|
||||
};
|
||||
debugInfo = false;
|
||||
|
||||
userFormValidation = /^[\p{L}\p{M}'\-]+$/gu;
|
||||
folderFormValidation = new RegExp('[*+:"<>?|\\\\/]', "gim");
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
@ -113,9 +113,13 @@ class SnackBar extends React.Component {
|
||||
</Text>
|
||||
|
||||
{btnText && (
|
||||
<button className="button" onClick={this.onActionClick}>
|
||||
<Text color={textColor}>{btnText}</Text>
|
||||
</button>
|
||||
<Text
|
||||
color={textColor}
|
||||
className="button"
|
||||
onClick={this.onActionClick}
|
||||
>
|
||||
{btnText}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{countDownTime > -1 && (
|
||||
|
@ -65,7 +65,7 @@ const StyledSnackBar = styled(Box)`
|
||||
font-size: 13px;
|
||||
color: "#000";
|
||||
cursor: pointer;
|
||||
line-height: 12px;
|
||||
line-height: 14px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
`;
|
||||
|
@ -280,8 +280,17 @@ class TableHeader extends React.Component {
|
||||
|
||||
if (!enable) {
|
||||
gridTemplateColumns.push("0px");
|
||||
gridTemplateColumns[1] =
|
||||
this.getSubstring(gridTemplateColumns[1]) +
|
||||
|
||||
let colIndex = 1;
|
||||
let leftEnableColumn = gridTemplateColumns[index - colIndex];
|
||||
while (leftEnableColumn === "0px") {
|
||||
colIndex++;
|
||||
leftEnableColumn = gridTemplateColumns[index - colIndex];
|
||||
}
|
||||
|
||||
//added the size of the disabled column to the left column
|
||||
gridTemplateColumns[index - colIndex] =
|
||||
this.getSubstring(gridTemplateColumns[index - colIndex]) +
|
||||
this.getSubstring(item) +
|
||||
"px";
|
||||
} else if (item !== `${settingsSize}px` && item !== checkboxSize) {
|
||||
|
@ -182,15 +182,15 @@ export default function withContent(WrappedContent) {
|
||||
};
|
||||
|
||||
renameTitle = (e) => {
|
||||
const { t } = this.props;
|
||||
const { t, folderFormValidation } = this.props;
|
||||
|
||||
let title = e.target.value;
|
||||
//const chars = '*+:"<>?|/'; TODO: think how to solve problem with interpolation escape values in i18n translate
|
||||
const regexp = new RegExp('[*+:"<>?|\\\\/]', "gim");
|
||||
if (title.match(regexp)) {
|
||||
|
||||
if (title.match(folderFormValidation)) {
|
||||
toastr.warning(t("ContainsSpecCharacter"));
|
||||
}
|
||||
title = title.replace(regexp, "_");
|
||||
title = title.replace(folderFormValidation, "_");
|
||||
return this.setState({ itemTitle: title });
|
||||
};
|
||||
|
||||
@ -324,7 +324,11 @@ export default function withContent(WrappedContent) {
|
||||
id: fileActionId,
|
||||
} = filesStore.fileActionStore;
|
||||
const { replaceFileStream, setEncryptionAccess } = auth;
|
||||
const { culture, isDesktopClient } = auth.settingsStore;
|
||||
const {
|
||||
culture,
|
||||
isDesktopClient,
|
||||
folderFormValidation,
|
||||
} = auth.settingsStore;
|
||||
|
||||
return {
|
||||
setIsLoading,
|
||||
@ -346,6 +350,7 @@ export default function withContent(WrappedContent) {
|
||||
homepage: config.homepage,
|
||||
viewer: auth.userStore.user,
|
||||
viewAs,
|
||||
folderFormValidation,
|
||||
};
|
||||
}
|
||||
)(observer(WithContent));
|
||||
|
@ -114,15 +114,15 @@ export default function withContextOptions(WrappedComponent) {
|
||||
setConvertItem(item);
|
||||
setConvertDialogVisible(true);
|
||||
} else {
|
||||
this.openDocEditor(false);
|
||||
this.gotoDocEditor(false);
|
||||
}
|
||||
};
|
||||
|
||||
onPreviewClick = () => {
|
||||
this.openDocEditor(true);
|
||||
this.gotoDocEditor(true);
|
||||
};
|
||||
|
||||
openDocEditor = (preview = false) => {
|
||||
gotoDocEditor = (preview = false) => {
|
||||
const { item, openDocEditor, isDesktop } = this.props;
|
||||
const { id, providerKey, fileExst } = item;
|
||||
|
||||
|
@ -21,10 +21,7 @@ const StyledDownloadAppList = styled.div`
|
||||
`;
|
||||
|
||||
const DownloadAppListContainer = ({ t }) => {
|
||||
const windowsLink =
|
||||
"https://www.onlyoffice.com/download-desktop.aspx#windows";
|
||||
const macLink = "https://www.onlyoffice.com/download-desktop.aspx#mac";
|
||||
const linuxLink = "https://www.onlyoffice.com/download-desktop.aspx#linux";
|
||||
const desktopLink = "https://www.onlyoffice.com/desktop.aspx";
|
||||
const androidLink = "https://www.onlyoffice.com/office-for-android.aspx";
|
||||
const iosLink = "https://www.onlyoffice.com/office-for-ios.aspx";
|
||||
|
||||
@ -35,7 +32,7 @@ const DownloadAppListContainer = ({ t }) => {
|
||||
</Text>
|
||||
<div className="download-app-list">
|
||||
<IconButton
|
||||
onClick={() => window.open(windowsLink)}
|
||||
onClick={() => window.open(desktopLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/windows.react.svg"
|
||||
size="25"
|
||||
@ -44,7 +41,7 @@ const DownloadAppListContainer = ({ t }) => {
|
||||
hoverColor="#3785D3"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(macLink)}
|
||||
onClick={() => window.open(desktopLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/macOS.react.svg"
|
||||
size="25"
|
||||
@ -53,7 +50,7 @@ const DownloadAppListContainer = ({ t }) => {
|
||||
hoverColor="#000000"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(linuxLink)}
|
||||
onClick={() => window.open(desktopLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/linux.react.svg"
|
||||
size="25"
|
||||
|
@ -29,6 +29,7 @@ const PureConnectDialogContainer = (props) => {
|
||||
setConnectDialogVisible,
|
||||
personal,
|
||||
getSubfolders,
|
||||
folderFormValidation,
|
||||
} = props;
|
||||
const {
|
||||
corporate,
|
||||
@ -78,7 +79,15 @@ const PureConnectDialogContainer = (props) => {
|
||||
};
|
||||
const onChangeFolderName = (e) => {
|
||||
setIsTitleValid(true);
|
||||
setCustomerTitleValue(e.target.value);
|
||||
let title = e.target.value;
|
||||
//const chars = '*+:"<>?|/'; TODO: think how to solve problem with interpolation escape values in i18n translate
|
||||
|
||||
if (title.match(folderFormValidation)) {
|
||||
toastr.warning(t("Home:ContainsSpecCharacter"));
|
||||
}
|
||||
title = title.replace(folderFormValidation, "_");
|
||||
|
||||
setCustomerTitleValue(title);
|
||||
};
|
||||
const onChangeMakeShared = () => setMakeShared(!isCorporate);
|
||||
|
||||
@ -313,6 +322,7 @@ const ConnectDialog = withTranslation([
|
||||
"ConnectDialog",
|
||||
"Common",
|
||||
"Translations",
|
||||
"Home",
|
||||
])(PureConnectDialogContainer);
|
||||
|
||||
export default inject(
|
||||
@ -330,7 +340,11 @@ export default inject(
|
||||
openConnectWindow,
|
||||
fetchThirdPartyProviders,
|
||||
} = settingsStore.thirdPartyStore;
|
||||
const { getOAuthToken, personal } = auth.settingsStore;
|
||||
const {
|
||||
getOAuthToken,
|
||||
personal,
|
||||
folderFormValidation,
|
||||
} = auth.settingsStore;
|
||||
|
||||
const {
|
||||
treeFolders,
|
||||
@ -354,6 +368,7 @@ export default inject(
|
||||
providers,
|
||||
visible,
|
||||
item,
|
||||
folderFormValidation,
|
||||
|
||||
getOAuthToken,
|
||||
getSubfolders,
|
||||
|
@ -86,6 +86,7 @@ class DownloadDialogComponent extends React.Component {
|
||||
window.open(viewUrl, "_self");
|
||||
this.onClose();
|
||||
} else if (fileConvertIds.length || folderIds.length) {
|
||||
this.onClose();
|
||||
downloadFiles(fileConvertIds, folderIds, t("Translations:ArchivingData"));
|
||||
}
|
||||
};
|
||||
|
@ -136,7 +136,6 @@ const SelectFileDialogAsideView = ({
|
||||
isDisabled={selectedFile.length === 0}
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
size="big"
|
||||
label={t("Common:CloseButton")}
|
||||
onClick={onClose}
|
||||
|
@ -242,7 +242,6 @@ class SelectFileDialogModalView extends React.Component {
|
||||
/>
|
||||
<Button
|
||||
className="modal-dialog-button"
|
||||
primary
|
||||
size="medium"
|
||||
label={t("Common:CloseButton")}
|
||||
onClick={onClose}
|
||||
|
@ -92,7 +92,6 @@ const SelectFolderDialogAsideView = ({
|
||||
isDisabled={isLoadingData || !isAvailable || !canCreate}
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
size="big"
|
||||
label={t("Common:CloseButton")}
|
||||
onClick={onClose}
|
||||
|
@ -69,7 +69,6 @@ const SelectFolderDialogModalView = ({
|
||||
isDisabled={isLoadingData || !isAvailable || !canCreate}
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
size="medium"
|
||||
label={t("Common:CloseButton")}
|
||||
onClick={onClose}
|
||||
|
@ -8,7 +8,7 @@ export function encryptionUploadDialog(callback) {
|
||||
const filter = docserviceStore.encryptedDocs.map((f) => "*" + f).join(" ");
|
||||
|
||||
const data = {
|
||||
cryptoEngineId: desktopConstants.guid,
|
||||
cryptoEngineId: desktopConstants.cryptoEngineId,
|
||||
filter: filter,
|
||||
};
|
||||
|
||||
@ -30,7 +30,7 @@ export function setEncryptionAccess(file) {
|
||||
window.AscDesktopEditor.cloudCryptoCommand(
|
||||
"share",
|
||||
{
|
||||
cryptoEngineId: desktopConstants.guid,
|
||||
cryptoEngineId: desktopConstants.cryptoEngineId,
|
||||
file: [file.viewUrl],
|
||||
keys: keys,
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { runInAction } from "mobx";
|
||||
import { EDITOR_PROTOCOL } from "./constants";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import { homepage } from "../../package.json";
|
||||
|
||||
export const presentInArray = (array, search, caseInsensitive = false) => {
|
||||
let pattern = caseInsensitive ? search.toLowerCase() : search;
|
||||
@ -156,13 +158,20 @@ export const checkProtocol = (fileId, withRedirect) =>
|
||||
reject();
|
||||
window.removeEventListener("blur", onBlur);
|
||||
withRedirect &&
|
||||
window.open(`/products/files/private?fileId=${fileId}`, "_blank");
|
||||
window.open(
|
||||
combineUrl("", homepage, `private?fileId=${fileId}`),
|
||||
"_blank"
|
||||
);
|
||||
}, 1000);
|
||||
|
||||
window.addEventListener("blur", onBlur);
|
||||
|
||||
window.open(
|
||||
`${EDITOR_PROTOCOL}:${window.location.origin}/products/files/doceditor?fileId=${fileId}`,
|
||||
combineUrl(
|
||||
`${EDITOR_PROTOCOL}:${window.location.origin}`,
|
||||
homepage,
|
||||
`doceditor?fileId=${fileId}`
|
||||
),
|
||||
"_self"
|
||||
);
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ class PureHome extends React.Component {
|
||||
getFileInfo,
|
||||
} = this.props;
|
||||
|
||||
const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gm"); //TODO: Always find?
|
||||
const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gmi"); //TODO: Always find?
|
||||
const match = window.location.pathname.match(reg);
|
||||
let filterObj = null;
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { combineUrl } from "@appserver/common/utils";
|
||||
import { updateTempContent } from "@appserver/common/utils";
|
||||
import { thumbnailStatuses } from "../helpers/constants";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import { openDocEditor } from "../helpers/utils";
|
||||
import { openDocEditor as openEditor } from "../helpers/utils";
|
||||
import toastr from "studio/toastr";
|
||||
|
||||
const { FilesFilter } = api;
|
||||
@ -1572,7 +1572,7 @@ class FilesStore {
|
||||
};
|
||||
|
||||
openDocEditor = (id, providerKey = null, tab = null, url = null) => {
|
||||
return openDocEditor(id, providerKey, tab, url);
|
||||
return openEditor(id, providerKey, tab, url);
|
||||
};
|
||||
|
||||
createThumbnails = () => {
|
||||
|
@ -18,7 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.456" />
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.457" />
|
||||
<PackageReference Include="Box.V2.Core" Version="3.24.0" />
|
||||
<PackageReference Include="DocuSign.eSign.dll" Version="4.4.1" />
|
||||
<PackageReference Include="Dropbox.Api" Version="4.10.0" />
|
||||
|
@ -408,7 +408,7 @@ namespace ASC.Web.Files
|
||||
{
|
||||
if (!readLink && fileDao.IsSupportedPreSignedUri(file))
|
||||
{
|
||||
context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true);
|
||||
context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -231,4 +232,68 @@ namespace ASC.Files.Model
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public class UploadModelBinder : IModelBinder
|
||||
{
|
||||
public Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
if (bindingContext == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
var defaultBindingContext = bindingContext as DefaultModelBindingContext;
|
||||
var composite = bindingContext.ValueProvider as CompositeValueProvider;
|
||||
|
||||
if (defaultBindingContext != null && composite != null && !composite.Any())
|
||||
{
|
||||
bindingContext.ValueProvider = defaultBindingContext.OriginalValueProvider;
|
||||
}
|
||||
|
||||
var result = new UploadModel();
|
||||
|
||||
if (bindingContext.GetBoolValue(nameof(result.CreateNewIfExist), out var createNewIfExist))
|
||||
{
|
||||
result.CreateNewIfExist = createNewIfExist;
|
||||
}
|
||||
|
||||
if (bindingContext.GetBoolValue(nameof(result.KeepConvertStatus), out var keepConvertStatus))
|
||||
{
|
||||
result.KeepConvertStatus = keepConvertStatus;
|
||||
}
|
||||
|
||||
if (bindingContext.GetBoolValue(nameof(result.StoreOriginalFileFlag), out var storeOriginalFileFlag))
|
||||
{
|
||||
result.StoreOriginalFileFlag = storeOriginalFileFlag;
|
||||
}
|
||||
|
||||
if (bindingContext.GetFirstValue(nameof(result.ContentType), out var contentType))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
result.ContentType = new ContentType(contentType);
|
||||
}
|
||||
}
|
||||
|
||||
if (bindingContext.GetFirstValue(nameof(result.ContentDisposition), out var contentDisposition))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(contentDisposition))
|
||||
{
|
||||
result.ContentDisposition = new ContentDisposition(contentDisposition);
|
||||
}
|
||||
}
|
||||
|
||||
bindingContext.HttpContext.Request.EnableBuffering();
|
||||
|
||||
bindingContext.HttpContext.Request.Body.Position = 0;
|
||||
|
||||
result.Stream = new MemoryStream();
|
||||
bindingContext.HttpContext.Request.Body.CopyToAsync(result.Stream).Wait();
|
||||
result.Stream.Position = 0;
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(result);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
|
||||
using ASC.Files.Core.Model;
|
||||
@ -7,7 +9,7 @@ using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace ASC.Files.Model
|
||||
{
|
||||
public class UploadModel : IModelWithFile
|
||||
public class UploadModel : IModelWithFile, IDisposable
|
||||
{
|
||||
public IFormFile File { get; set; }
|
||||
public ContentType ContentType { get; set; }
|
||||
@ -15,6 +17,41 @@ namespace ASC.Files.Model
|
||||
public IEnumerable<IFormFile> Files { get; set; }
|
||||
public bool? CreateNewIfExist { get; set; }
|
||||
public bool? StoreOriginalFileFlag { get; set; }
|
||||
public bool KeepConvertStatus { get; set; }
|
||||
public bool KeepConvertStatus { get; set; }
|
||||
|
||||
private Stream stream;
|
||||
private bool disposedValue;
|
||||
|
||||
public Stream Stream
|
||||
{
|
||||
get => File?.OpenReadStream() ?? stream;
|
||||
set => stream = value;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing && stream != null)
|
||||
{
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
stream = null;
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
~UploadModel()
|
||||
{
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ namespace ASC.Api.Documents
|
||||
/// <param name="files" visible="false">List of files when posted as multipart/form-data</param>
|
||||
/// <returns>Uploaded file</returns>
|
||||
[Create("@my/upload")]
|
||||
public object UploadFileToMyFromForm([FromForm] UploadModel uploadModel)
|
||||
public object UploadFileToMy([ModelBinder(BinderType = typeof(UploadModelBinder))] UploadModel uploadModel)
|
||||
{
|
||||
uploadModel.CreateNewIfExist = false;
|
||||
return FilesControllerHelperInt.UploadFile(GlobalFolderHelper.FolderMy, uploadModel);
|
||||
@ -445,7 +445,7 @@ namespace ASC.Api.Documents
|
||||
/// <param name="files" visible="false">List of files when posted as multipart/form-data</param>
|
||||
/// <returns>Uploaded file</returns>
|
||||
[Create("@common/upload")]
|
||||
public object UploadFileToCommonFromForm([FromForm] UploadModel uploadModel)
|
||||
public object UploadFileToCommon([ModelBinder(BinderType = typeof(UploadModelBinder))] UploadModel uploadModel)
|
||||
{
|
||||
uploadModel.CreateNewIfExist = false;
|
||||
return FilesControllerHelperInt.UploadFile(GlobalFolderHelper.FolderCommon, uploadModel);
|
||||
@ -474,13 +474,13 @@ namespace ASC.Api.Documents
|
||||
/// <param name="keepConvertStatus" visible="false">Keep status conversation after finishing</param>
|
||||
/// <returns>Uploaded file</returns>
|
||||
[Create("{folderId}/upload", order: int.MaxValue)]
|
||||
public object UploadFileFromForm(string folderId, [FromForm] UploadModel uploadModel)
|
||||
public object UploadFile(string folderId, [ModelBinder(BinderType = typeof(UploadModelBinder))] UploadModel uploadModel)
|
||||
{
|
||||
return FilesControllerHelperString.UploadFile(folderId, uploadModel);
|
||||
}
|
||||
|
||||
[Create("{folderId:int}/upload", order: int.MaxValue - 1)]
|
||||
public object UploadFileFromForm(int folderId, [FromForm] UploadModel uploadModel)
|
||||
public object UploadFile(int folderId, [ModelBinder(BinderType = typeof(UploadModelBinder))] UploadModel uploadModel)
|
||||
{
|
||||
return FilesControllerHelperInt.UploadFile(folderId, uploadModel);
|
||||
}
|
||||
@ -598,6 +598,7 @@ namespace ASC.Api.Documents
|
||||
/// <category>Files</category>
|
||||
/// <returns></returns>
|
||||
[Create("file/{fileId}/startedit")]
|
||||
[Consumes("application/json")]
|
||||
public object StartEditFromBody(string fileId, [FromBody] StartEditModel model)
|
||||
{
|
||||
return FilesControllerHelperString.StartEdit(fileId, model.EditingAlone, model.Doc);
|
||||
@ -611,11 +612,18 @@ namespace ASC.Api.Documents
|
||||
}
|
||||
|
||||
[Create("file/{fileId:int}/startedit")]
|
||||
[Consumes("application/json")]
|
||||
public object StartEditFromBody(int fileId, [FromBody] StartEditModel model)
|
||||
{
|
||||
return FilesControllerHelperInt.StartEdit(fileId, model.EditingAlone, model.Doc);
|
||||
}
|
||||
|
||||
[Create("file/{fileId:int}/startedit")]
|
||||
public object StartEdit(int fileId)
|
||||
{
|
||||
return FilesControllerHelperInt.StartEdit(fileId, false, null);
|
||||
}
|
||||
|
||||
[Create("file/{fileId:int}/startedit")]
|
||||
[Consumes("application/x-www-form-urlencoded")]
|
||||
public object StartEditFromForm(int fileId, [FromForm] StartEditModel model)
|
||||
|
@ -19,5 +19,7 @@
|
||||
"TemporaryPassword": "Vorübergehendes Kennwort",
|
||||
"TermsOfUsePopupHelperLink": "Erfahren Sie mehr über die Nutzungsbedingungen",
|
||||
"UpdatingProcess": "Wird aktualisiert...",
|
||||
"WriteComment": "Kommentar hinzufügen"
|
||||
"WriteComment": "Kommentar hinzufügen",
|
||||
"ErrorInvalidUserLastName": "Ungültiger Nachname",
|
||||
"ErrorInvalidUserFirstName": "Ungültiger Vorname"
|
||||
}
|
||||
|
@ -20,5 +20,7 @@
|
||||
"TemporaryPassword": "Temporary password",
|
||||
"TermsOfUsePopupHelperLink": "Read more about terms of use",
|
||||
"UpdatingProcess": "Updating...",
|
||||
"WriteComment": "Add comment"
|
||||
"WriteComment": "Add comment",
|
||||
"ErrorInvalidUserLastName": "Invalid last name",
|
||||
"ErrorInvalidUserFirstName": "Invalid first name"
|
||||
}
|
||||
|
@ -19,5 +19,7 @@
|
||||
"TemporaryPassword": "Mot de passe temporaire",
|
||||
"TermsOfUsePopupHelperLink": "Savoir plus à propos de termes d'utilisation ",
|
||||
"UpdatingProcess": "Mis à jour...",
|
||||
"WriteComment": "Ajouter un commentaire"
|
||||
"WriteComment": "Ajouter un commentaire",
|
||||
"ErrorInvalidUserLastName": "Prénom invalide",
|
||||
"ErrorInvalidUserFirstName": "Nom invalide"
|
||||
}
|
||||
|
@ -19,5 +19,7 @@
|
||||
"TemporaryPassword": "Password temporanea",
|
||||
"TermsOfUsePopupHelperLink": "Maggiori dettagli sui termini di utilizzo",
|
||||
"UpdatingProcess": "Caricamento in corso...",
|
||||
"WriteComment": "Aggiungi commento"
|
||||
"WriteComment": "Aggiungi commento",
|
||||
"ErrorInvalidUserLastName": "Cognome non valido",
|
||||
"ErrorInvalidUserFirstName": "Nome non valido"
|
||||
}
|
||||
|
@ -19,5 +19,7 @@
|
||||
"TemporaryPassword": "Senha temporária",
|
||||
"TermsOfUsePopupHelperLink": "Leia mais sobre os termos de uso",
|
||||
"UpdatingProcess": "Atualizando...",
|
||||
"WriteComment": "Adicionar comentário"
|
||||
"WriteComment": "Adicionar comentário",
|
||||
"ErrorInvalidUserLastName": "Sobrenome inválido",
|
||||
"ErrorInvalidUserFirstName": "Primeiro nome inválido"
|
||||
}
|
||||
|
@ -20,5 +20,7 @@
|
||||
"TemporaryPassword": "Временный пароль",
|
||||
"TermsOfUsePopupHelperLink": "Подробнее об условиях использования",
|
||||
"UpdatingProcess": "Обновление...",
|
||||
"WriteComment": "Добавить комментарий"
|
||||
"WriteComment": "Добавить комментарий",
|
||||
"ErrorInvalidUserLastName": "Недопустимая фамилия",
|
||||
"ErrorInvalidUserFirstName": "Недопустимое имя"
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class TextField extends React.Component {
|
||||
isRequired,
|
||||
hasError,
|
||||
labelText,
|
||||
errorMessage,
|
||||
|
||||
inputName,
|
||||
inputValue,
|
||||
@ -32,6 +33,7 @@ class TextField extends React.Component {
|
||||
<FieldContainer
|
||||
isRequired={isRequired}
|
||||
hasError={hasError}
|
||||
errorMessage={errorMessage}
|
||||
labelText={labelText}
|
||||
tooltipContent={tooltipContent}
|
||||
helpButtonHeaderContent={helpButtonHeaderContent}
|
||||
|
@ -242,8 +242,19 @@ class CreateUserForm extends React.Component {
|
||||
}
|
||||
|
||||
onInputChange = (event) => {
|
||||
const { userFormValidation } = this.props;
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile[event.target.name] = event.target.value;
|
||||
const value = event.target.value;
|
||||
const title = event.target.name;
|
||||
|
||||
if (!value.match(userFormValidation)) {
|
||||
stateCopy.errors[title] = true;
|
||||
} else {
|
||||
if (this.state.errors[title]) stateCopy.errors[title] = false;
|
||||
}
|
||||
|
||||
stateCopy.profile[title] = value;
|
||||
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
};
|
||||
@ -262,8 +273,20 @@ class CreateUserForm extends React.Component {
|
||||
this.setIsEdit();
|
||||
};
|
||||
|
||||
scrollToErrorForm = () => {
|
||||
const element = this.mainFieldsContainerRef.current;
|
||||
const parent = element.closest(".scroll-body");
|
||||
(parent || window).scrollTo(0, element.offsetTop);
|
||||
};
|
||||
|
||||
validate = () => {
|
||||
const { profile, errors: stateErrors } = this.state;
|
||||
|
||||
if (stateErrors.firstName || stateErrors.lastName) {
|
||||
this.scrollToErrorForm();
|
||||
return;
|
||||
}
|
||||
|
||||
const errors = {
|
||||
firstName: !profile.firstName.trim(),
|
||||
lastName: !profile.lastName.trim(),
|
||||
@ -274,9 +297,7 @@ class CreateUserForm extends React.Component {
|
||||
errors.firstName || errors.lastName || errors.email || errors.password;
|
||||
|
||||
if (hasError) {
|
||||
const element = this.mainFieldsContainerRef.current;
|
||||
const parent = element.closest(".scroll-body");
|
||||
(parent || window).scrollTo(0, element.offsetTop);
|
||||
this.scrollToErrorForm();
|
||||
}
|
||||
|
||||
this.setState({ errors: errors });
|
||||
@ -436,6 +457,9 @@ class CreateUserForm extends React.Component {
|
||||
const pattern = getUserContactsPattern();
|
||||
const contacts = getUserContacts(profile.contacts);
|
||||
|
||||
const notEmptyFirstName = Boolean(profile.firstName.trim());
|
||||
const notEmptyLastName = Boolean(profile.lastName.trim());
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainContainer>
|
||||
@ -470,6 +494,9 @@ class CreateUserForm extends React.Component {
|
||||
<TextField
|
||||
isRequired={true}
|
||||
hasError={errors.firstName}
|
||||
{...(notEmptyFirstName && {
|
||||
errorMessage: t("ErrorInvalidUserFirstName"),
|
||||
})}
|
||||
labelText={`${t("FirstName")}:`}
|
||||
inputName="firstName"
|
||||
inputValue={profile.firstName}
|
||||
@ -481,6 +508,9 @@ class CreateUserForm extends React.Component {
|
||||
<TextField
|
||||
isRequired={true}
|
||||
hasError={errors.lastName}
|
||||
{...(notEmptyLastName && {
|
||||
errorMessage: t("ErrorInvalidUserLastName"),
|
||||
})}
|
||||
labelText={`${t("Common:LastName")}:`}
|
||||
inputName="lastName"
|
||||
inputValue={profile.lastName}
|
||||
@ -687,6 +717,7 @@ export default withRouter(
|
||||
setCroppedAvatar: peopleStore.avatarEditorStore.setCroppedAvatar,
|
||||
updateProfileInUsers: peopleStore.usersStore.updateProfileInUsers,
|
||||
updateCreatedAvatar: peopleStore.targetUserStore.updateCreatedAvatar,
|
||||
userFormValidation: auth.settingsStore.userFormValidation,
|
||||
}))(
|
||||
observer(
|
||||
withTranslation(["ProfileAction", "Common", "Translations"])(
|
||||
|
@ -238,8 +238,19 @@ class UpdateUserForm extends React.Component {
|
||||
}
|
||||
|
||||
onInputChange(event) {
|
||||
const { userFormValidation } = this.props;
|
||||
var stateCopy = Object.assign({}, this.state);
|
||||
stateCopy.profile[event.target.name] = event.target.value;
|
||||
const value = event.target.value;
|
||||
const title = event.target.name;
|
||||
|
||||
if (!value.match(userFormValidation)) {
|
||||
stateCopy.errors[title] = true;
|
||||
} else {
|
||||
if (this.state.errors[title]) stateCopy.errors[title] = false;
|
||||
}
|
||||
|
||||
stateCopy.profile[title] = value;
|
||||
|
||||
this.setState(stateCopy);
|
||||
this.setIsEdit();
|
||||
}
|
||||
@ -278,21 +289,30 @@ class UpdateUserForm extends React.Component {
|
||||
this.setIsEdit();
|
||||
}
|
||||
|
||||
scrollToErrorForm = () => {
|
||||
const element = this.mainFieldsContainerRef.current;
|
||||
const parent = element.closest(".scroll-body");
|
||||
(parent || window).scrollTo(0, element.offsetTop);
|
||||
};
|
||||
validate() {
|
||||
const { profile } = this.state;
|
||||
const errors = {
|
||||
const { profile, errors } = this.state;
|
||||
|
||||
if (errors.firstName || errors.lastName) {
|
||||
this.scrollToErrorForm();
|
||||
return;
|
||||
}
|
||||
|
||||
const errorsObj = {
|
||||
firstName: !profile.firstName.trim(),
|
||||
lastName: !profile.lastName.trim(),
|
||||
};
|
||||
const hasError = errors.firstName || errors.lastName;
|
||||
const hasError = errorsObj.firstName || errorsObj.lastName;
|
||||
|
||||
if (hasError) {
|
||||
const element = this.mainFieldsContainerRef.current;
|
||||
const parent = element.closest(".scroll-body");
|
||||
(parent || window).scrollTo(0, element.offsetTop);
|
||||
this.scrollToErrorForm();
|
||||
}
|
||||
|
||||
this.setState({ errors: errors });
|
||||
this.setState({ errors: errorsObj });
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
@ -615,6 +635,8 @@ class UpdateUserForm extends React.Component {
|
||||
|
||||
const pattern = getUserContactsPattern();
|
||||
const contacts = getUserContacts(profile.contacts);
|
||||
const notEmptyFirstName = Boolean(profile.firstName.trim());
|
||||
const notEmptyLastName = Boolean(profile.lastName.trim());
|
||||
//TODO: inject guestsCaption in 'ProfileTypePopupHelper' key instead of hardcoded 'Guests'
|
||||
const tooltipTypeContent = (
|
||||
<>
|
||||
@ -790,6 +812,9 @@ class UpdateUserForm extends React.Component {
|
||||
isRequired={true}
|
||||
hasError={errors.firstName}
|
||||
labelText={`${t("FirstName")}:`}
|
||||
{...(notEmptyFirstName && {
|
||||
errorMessage: t("ErrorInvalidUserFirstName"),
|
||||
})}
|
||||
inputName="firstName"
|
||||
inputValue={profile.firstName}
|
||||
inputIsDisabled={isLoading}
|
||||
@ -802,6 +827,9 @@ class UpdateUserForm extends React.Component {
|
||||
<TextField
|
||||
isRequired={true}
|
||||
hasError={errors.lastName}
|
||||
{...(notEmptyLastName && {
|
||||
errorMessage: t("ErrorInvalidUserLastName"),
|
||||
})}
|
||||
labelText={`${t("Common:LastName")}:`}
|
||||
inputName="lastName"
|
||||
inputValue={profile.lastName}
|
||||
@ -1020,6 +1048,7 @@ export default withRouter(
|
||||
isEditTargetUser: peopleStore.targetUserStore.isEditTargetUser,
|
||||
personal: auth.settingsStore.personal,
|
||||
setUserIsUpdate: auth.userStore.setUserIsUpdate,
|
||||
userFormValidation: auth.settingsStore.userFormValidation,
|
||||
}))(
|
||||
observer(
|
||||
withTranslation(["ProfileAction", "Common", "Translations"])(
|
||||
|
@ -11,10 +11,10 @@
|
||||
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
|
||||
<WarningsAsErrors></WarningsAsErrors>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Version>1.1.0.456</Version>
|
||||
<Version>1.1.0.457</Version>
|
||||
<PackageLicenseExpression></PackageLicenseExpression>
|
||||
<AssemblyVersion>1.1.0.456</AssemblyVersion>
|
||||
<FileVersion>1.1.0.456</FileVersion>
|
||||
<AssemblyVersion>1.1.0.457</AssemblyVersion>
|
||||
<FileVersion>1.1.0.457</FileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
|
@ -50,7 +50,9 @@ namespace AppLimit.CloudComputing.SharpBox.Common.Net.Web.Dav
|
||||
|
||||
// set the content type
|
||||
request.ContentType = "application/octet-stream";
|
||||
|
||||
#if NET5_0
|
||||
request.Headers.Add("Expect", "100-continue");
|
||||
#endif
|
||||
// go ahead
|
||||
return request;
|
||||
}
|
||||
@ -87,9 +89,9 @@ namespace AppLimit.CloudComputing.SharpBox.Common.Net.Web.Dav
|
||||
return (HttpStatusCode)code;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
#region Overrides
|
||||
|
||||
public override WebRequest CreateWebRequest(string url, string method, ICredentials credentials, bool bAllowStreamBuffering, object context)
|
||||
{
|
||||
@ -154,6 +156,6 @@ namespace AppLimit.CloudComputing.SharpBox.Common.Net.Web.Dav
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -368,7 +368,16 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
|
||||
return (
|
||||
<PrivateRoute
|
||||
key={m.id}
|
||||
path={appURL}
|
||||
path={
|
||||
m.appName === "files"
|
||||
? [
|
||||
"/Products/Files",
|
||||
"/Products/Files/",
|
||||
"/Products/Files/?desktop=true",
|
||||
appURL,
|
||||
]
|
||||
: appURL
|
||||
}
|
||||
component={System}
|
||||
system={system}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user