Merge branch 'feature/file-folder-selectors' of https://github.com/ONLYOFFICE/AppServer into feature/file-folder-selectors
This commit is contained in:
commit
76a82faf23
18
ASC.Web.sln
18
ASC.Web.sln
@ -43,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Notify.Textile", "commo
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ElasticSearch", "common\services\ASC.ElasticSearch\ASC.ElasticSearch.csproj", "{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Calendar", "products\ASC.Calendar\Server\ASC.Calendar.csproj", "{867BF98F-9638-4E99-BB68-651E1B812547}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files", "products\ASC.Files\Server\ASC.Files.csproj", "{77BA2F61-6155-4283-BB39-F8E42F46A0B0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Service", "products\ASC.Files\Service\ASC.Files.Service.csproj", "{5D41FFFF-816C-40B2-95CD-E2DDDCB83784}"
|
||||
@ -82,7 +84,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM", "products\ASC.CRM
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Mail", "products\ASC.Mail\Server\ASC.Mail.csproj", "{137CA67B-D0F5-4746-B8BC-1888D2859B90}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Calendar", "products\ASC.Calendar\Server\ASC.Calendar.csproj", "{F39933F8-7598-492F-9DD3-E25780D68288}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Radicale", "common\services\ASC.Radicale\ASC.Radicale.csproj", "{74998718-3C9A-4A89-B834-14453762C60F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.SsoAuth.Svc", "common\services\ASC.SsoAuth.Svc\ASC.SsoAuth.Svc.csproj", "{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}"
|
||||
EndProject
|
||||
@ -174,6 +176,10 @@ Global
|
||||
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{867BF98F-9638-4E99-BB68-651E1B812547}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{867BF98F-9638-4E99-BB68-651E1B812547}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{867BF98F-9638-4E99-BB68-651E1B812547}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{867BF98F-9638-4E99-BB68-651E1B812547}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -238,14 +244,14 @@ Global
|
||||
{277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{74998718-3C9A-4A89-B834-14453762C60F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{74998718-3C9A-4A89-B834-14453762C60F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74998718-3C9A-4A89-B834-14453762C60F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74998718-3C9A-4A89-B834-14453762C60F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F39933F8-7598-492F-9DD3-E25780D68288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F39933F8-7598-492F-9DD3-E25780D68288}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F39933F8-7598-492F-9DD3-E25780D68288}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F39933F8-7598-492F-9DD3-E25780D68288}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -10,9 +10,17 @@ package_services="";
|
||||
RES_APP_INSTALLED="is already installed";
|
||||
RES_APP_CHECK_PORTS="uses ports"
|
||||
RES_CHECK_PORTS="please, make sure that the ports are free.";
|
||||
RES_INSTALL_SUCCESS="Thank you for installing ONLYOFFICE ${product}.";
|
||||
RES_INSTALL_SUCCESS="Thank you for installing ONLYOFFICE ${product^^}.";
|
||||
RES_QUESTIONS="In case you have any questions contact us via http://support.onlyoffice.com or visit our forum at http://dev.onlyoffice.org"
|
||||
|
||||
res_unsupported_version () {
|
||||
RES_CHOICE="Please, enter Y or N"
|
||||
RES_CHOICE_INSTALLATION="Continue installation [Y/N]? "
|
||||
RES_UNSPPORTED_VERSION="You have an unsupported version of $DIST installed"
|
||||
RES_SELECT_INSTALLATION="Select 'N' to cancel the ONLYOFFICE installation (recommended). Select 'Y' to continue installing ONLYOFFICE"
|
||||
RES_ERROR_REMINDER="Please note, that if you continue with the installation, there may be errors"
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
case $1 in
|
||||
|
||||
|
@ -15,6 +15,8 @@ ${package_manager} clean all
|
||||
|
||||
${package_manager} -y install yum-utils
|
||||
|
||||
DIST=$(rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release);
|
||||
DIST=$(echo $DIST | sed -n '/-.*/s///p');
|
||||
REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//);
|
||||
REV_PARTS=(${REV//\./ });
|
||||
REV=${REV_PARTS[0]};
|
||||
@ -23,6 +25,33 @@ if ! [[ "$REV" =~ ^[0-9]+$ ]]; then
|
||||
REV=7;
|
||||
fi
|
||||
|
||||
read_unsupported_installation () {
|
||||
read -p "$RES_CHOICE_INSTALLATION " CHOICE_INSTALLATION
|
||||
case "$CHOICE_INSTALLATION" in
|
||||
y|Y ) yum -y install $DIST*-release
|
||||
;;
|
||||
|
||||
n|N ) exit 0;
|
||||
;;
|
||||
|
||||
* ) echo $RES_CHOICE;
|
||||
read_unsupported_installation
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
{ yum check-update $DIST*-release; exitCode=$?; } || true #Checking for distribution update
|
||||
|
||||
UPDATE_AVAILABLE_CODE=100
|
||||
if [[ $exitCode -eq $UPDATE_AVAILABLE_CODE ]]; then
|
||||
res_unsupported_version
|
||||
echo $RES_UNSPPORTED_VERSION
|
||||
echo $RES_SELECT_INSTALLATION
|
||||
echo $RES_ERROR_REMINDER
|
||||
echo $RES_QUESTIONS
|
||||
read_unsupported_installation
|
||||
fi
|
||||
|
||||
# add epel repo
|
||||
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-$REV.noarch.rpm || true
|
||||
rpm -ivh https://rpms.remirepo.net/enterprise/remi-release-$REV.rpm || true
|
||||
@ -140,7 +169,7 @@ ${package_manager} -y install epel-release \
|
||||
make \
|
||||
yarn \
|
||||
dotnet-sdk-5.0 \
|
||||
elasticsearch-7.8.1 --enablerepo=elasticsearch \
|
||||
elasticsearch-7.13.1 --enablerepo=elasticsearch \
|
||||
mysql-server \
|
||||
nginx \
|
||||
supervisor \
|
||||
|
@ -42,7 +42,6 @@ done
|
||||
echo "== BACK-END-BUILD =="
|
||||
|
||||
cd ${SRC_PATH}
|
||||
dotnet restore ASC.Web.sln${ARGS}
|
||||
dotnet build ASC.Web.sln ${ARGS}
|
||||
|
||||
echo "== Build ASC.Thumbnails =="
|
||||
|
@ -35,3 +35,4 @@ echo "== FRONT-END-BUILD =="
|
||||
cd ${SRC_PATH}
|
||||
yarn install
|
||||
yarn build
|
||||
yarn deploy
|
||||
|
@ -68,7 +68,7 @@ for i in ${!servers_products_name_backend[@]}; do
|
||||
echo "== Publish ${servers_products_name_backend[$i]}.csproj project =="
|
||||
SERVICE_DIR="$(dirname "$(find ${SRC_PATH} -type f -name "${servers_products_name_backend[$i]}".csproj)")"
|
||||
cd ${SERVICE_DIR}
|
||||
dotnet publish -c Release --self-contained ${SELF_CONTAINED} ${ARGS} -o ${BUILD_PATH}/products/${servers_products_name_backend[$i]}/server/
|
||||
dotnet publish -c Release --self-contained ${SELF_CONTAINED} ${ARGS} --no-build -o ${BUILD_PATH}/products/${servers_products_name_backend[$i]}/server/
|
||||
done
|
||||
|
||||
# Array of names backend services
|
||||
@ -91,7 +91,7 @@ for i in ${!services_name_backend[@]}; do
|
||||
echo "== Publish ${services_name_backend[$i]}.csproj project =="
|
||||
SERVICE_DIR="$(dirname "$(find ${SRC_PATH} -type f -name "${services_name_backend[$i]}".csproj)")"
|
||||
cd ${SERVICE_DIR}
|
||||
dotnet publish -c Release --self-contained ${SELF_CONTAINED} ${ARGS} -o ${BUILD_PATH}/services/${services_name_backend[$i]}/service/
|
||||
dotnet publish -c Release --self-contained ${SELF_CONTAINED} ${ARGS} --no-build -o ${BUILD_PATH}/services/${services_name_backend[$i]}/service/
|
||||
done
|
||||
|
||||
# Array of names backend services in directory common (Nodejs)
|
||||
|
@ -75,18 +75,18 @@ reassign_values (){
|
||||
EXEC_FILE="ASC.ApiSystem.dll"
|
||||
;;
|
||||
urlshortener )
|
||||
SERVICE_PORT="9999"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.UrlShortener/"
|
||||
SERVICE_PORT="9998"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.UrlShortener.Svc/"
|
||||
EXEC_FILE="ASC.UrlShortener.Svc.dll"
|
||||
;;
|
||||
thumbnails )
|
||||
SERVICE_PORT="9800"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.Thumbnails/"
|
||||
SERVICE_PORT="9799"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.Thumbnails.Svc/"
|
||||
EXEC_FILE="ASC.Thumbnails.Svc.dll"
|
||||
;;
|
||||
socket )
|
||||
SERVICE_PORT="9899"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.Socket.IO/"
|
||||
SERVICE_PORT="9898"
|
||||
WORK_DIR="${BASE_DIR}/services/ASC.Socket.IO.Svc/"
|
||||
EXEC_FILE="ASC.Socket.IO.Svc.dll"
|
||||
;;
|
||||
studio-notify )
|
||||
|
@ -7,6 +7,8 @@ ARG REPO=mcr.microsoft.com/dotnet/sdk
|
||||
FROM $REPO:$REPO_TAG AS base
|
||||
ARG RELEASE_DATE="2016-06-21"
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG PRODUCT_VERSION=0.0.0
|
||||
ARG BUILD_NUMBER=0
|
||||
ARG GIT_BRANCH=master
|
||||
ARG SRC_PATH
|
||||
ARG BUILD_PATH
|
||||
@ -27,8 +29,10 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
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
|
||||
apt-get install -yq git apt-utils npm && \
|
||||
npm install --global yarn && \
|
||||
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} && \
|
||||
@ -36,15 +40,15 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
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 -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} && \
|
||||
bash build-backend.sh -sp ${SRC_PATH} -ar "--disable-parallel" && \
|
||||
bash publish-backend.sh -sp ${SRC_PATH} -bp ${BUILD_PATH} -ar "--disable-parallel" && \
|
||||
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/ && \
|
||||
rm -rf ${SRC_PATH}/common/* && \
|
||||
rm -rf ${SRC_PATH}/web/ASC.Web.Core/* && \
|
||||
@ -112,17 +116,9 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
# 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 ${BUILD_PATH}/products/ASC.CRM/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Editor/dist ${BUILD_PATH}/products/ASC.Files/editor
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Files/Client/dist ${BUILD_PATH}/products/ASC.Files/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Login/dist ${BUILD_PATH}/studio/login
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.People/Client/dist ${BUILD_PATH}/products/ASC.People/client
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Projects/Client/dist ${BUILD_PATH}/products/ASC.Projects/client
|
||||
COPY --from=base ${SRC_PATH}/web/ASC.Web.Client/dist ${BUILD_PATH}/studio/client
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Calendar/Client/dist ${BUILD_PATH}/products/ASC.Calendar/client
|
||||
COPY --from=base ${SRC_PATH}/products/ASC.Mail/Client/dist ${BUILD_PATH}/products/ASC.Mail/client
|
||||
|
||||
COPY --from=base ${SRC_PATH}/build/deploy/products ${BUILD_PATH}/products
|
||||
COPY --from=base ${SRC_PATH}/build/deploy/public ${BUILD_PATH}/public
|
||||
COPY --from=base ${SRC_PATH}/build/deploy/studio ${BUILD_PATH}/studio
|
||||
COPY /config/nginx/templates/upstream.conf.template /etc/nginx/templates/upstream.conf.template
|
||||
COPY /config/nginx/templates/nginx.conf.template /etc/nginx/nginx.conf.template
|
||||
COPY prepare-nginx-proxy.sh /docker-entrypoint.d/prepare-nginx-proxy.sh
|
||||
|
@ -1,3 +1,7 @@
|
||||
#!/bin/bash
|
||||
export SRV_VERSION=$DOCKER_TAG
|
||||
docker-compose -f build.yml build --build-arg GIT_BRANCH=$SOURCE_BRANCH
|
||||
BUILD_NUMBER="$(date "+%Y%m%d%H")"
|
||||
docker-compose -f build.yml build \
|
||||
--build-arg GIT_BRANCH=$SOURCE_BRANCH \
|
||||
--build-arg PRODUCT_VERSION=$PRODUCT_VERSION \
|
||||
--build-arg BUILD_NUMBER=$BUILD_NUMBER
|
||||
|
@ -13,7 +13,7 @@ Packager: Ascensio System SIA <support@onlyoffice.com>
|
||||
ExclusiveArch: x86_64
|
||||
AutoReq: no
|
||||
AutoProv: no
|
||||
License: GPLv3
|
||||
License: AGPLv3
|
||||
Source0: https://github.com/ONLYOFFICE/%{product}/archive/%GIT_BRANCH.tar.gz
|
||||
BuildRequires: nodejs >= 12.0
|
||||
BuildRequires: yarn
|
||||
|
@ -166,18 +166,21 @@
|
||||
%files urlshortener
|
||||
%defattr(-, onlyoffice, onlyoffice, -)
|
||||
%{buildpath}/services/ASC.UrlShortener/
|
||||
%{buildpath}/services/ASC.UrlShortener.Svc/
|
||||
%{_sysconfdir}/systemd/system/%{product}-urlshortener.service
|
||||
%dir %{buildpath}/services/
|
||||
|
||||
%files thumbnails
|
||||
%defattr(-, onlyoffice, onlyoffice, -)
|
||||
%{buildpath}/services/ASC.Thumbnails/
|
||||
%{buildpath}/services/ASC.Thumbnails.Svc/
|
||||
%{_sysconfdir}/systemd/system/%{product}-thumbnails.service
|
||||
%dir %{buildpath}/services/
|
||||
|
||||
%files socket
|
||||
%defattr(-, onlyoffice, onlyoffice, -)
|
||||
%{buildpath}/services/ASC.Socket.IO/
|
||||
%{buildpath}/services/ASC.Socket.IO.Svc/
|
||||
%{buildpath}/products/ASC.Files/server/
|
||||
%{buildpath}/products/ASC.People/server/
|
||||
%{buildpath}/products/ASC.CRM/server/
|
||||
|
@ -13,7 +13,7 @@ mkdir -p "%{buildroot}%{buildpath}/products/ASC.CRM/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.CRM/server/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Files/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Files/editor/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Files/server/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Files/server/DocStore/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Files/service/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Mail/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Mail/server/"
|
||||
@ -23,6 +23,7 @@ mkdir -p "%{buildroot}%{buildpath}/products/ASC.Projects/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/products/ASC.Projects/server/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/public/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Socket.IO/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Socket.IO.Svc/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.ApiSystem/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Data.Backup/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Notify/"
|
||||
@ -30,8 +31,10 @@ mkdir -p "%{buildroot}%{buildpath}/services/ASC.Data.Storage.Encryption/service"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Data.Storage.Migration/service"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Studio.Notify/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.TelegramService/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Thumbnails/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.UrlShortener/client/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Thumbnails/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.UrlShortener/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.UrlShortener.Svc/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/services/ASC.Thumbnails.Svc/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/sql/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/studio/api/"
|
||||
mkdir -p "%{buildroot}%{buildpath}/studio/client/"
|
||||
@ -48,15 +51,15 @@ cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.ApiSystem/service/* "%{bu
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Data.Backup/service/* "%{buildroot}%{buildpath}/services/ASC.Data.Backup/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Notify/service/* "%{buildroot}%{buildpath}/services/ASC.Notify/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Socket.IO/service/* "%{buildroot}%{buildpath}/services/ASC.Socket.IO/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Socket.IO.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.Socket.IO/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Socket.IO.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.Socket.IO.Svc/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Data.Storage.Encryption/service/* "%{buildroot}%{buildpath}/services/ASC.Data.Storage.Encryption/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Data.Storage.Migration/service/* "%{buildroot}%{buildpath}/services/ASC.Data.Storage.Migration/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Studio.Notify/service/* "%{buildroot}%{buildpath}/services/ASC.Studio.Notify/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.TelegramService/service/* "%{buildroot}%{buildpath}/services/ASC.TelegramService/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Thumbnails/service/* "%{buildroot}%{buildpath}/services/ASC.Thumbnails/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Thumbnails.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.Thumbnails/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.UrlShortener/service/* "%{buildroot}%{buildpath}/services/ASC.UrlShortener/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.UrlShortener.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.UrlShortener/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Thumbnails/service/* "%{buildroot}%{buildpath}/services/ASC.Thumbnails/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Thumbnails.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.Thumbnails.Svc/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.UrlShortener/service/* "%{buildroot}%{buildpath}/services/ASC.UrlShortener/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.UrlShortener.Svc/service/* "%{buildroot}%{buildpath}/services/ASC.UrlShortener.Svc/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Web.Api/service/* "%{buildroot}%{buildpath}/studio/api/"
|
||||
cp -rf %{_builddir}/%{sourcename}/publish/services/ASC.Web.Studio/service/* "%{buildroot}%{buildpath}/studio/server/"
|
||||
cp -rf %{_builddir}/%{sourcename}/build/install/common/systemd/modules/* "%{buildroot}%{_sysconfdir}/systemd/system/"
|
||||
@ -67,6 +70,7 @@ cp -rf %{_builddir}/%{sourcename}/config/nginx/includes/onlyoffice*.conf "%{buil
|
||||
cp -rf %{_builddir}/%{sourcename}/config/nginx/onlyoffice*.conf "%{buildroot}%{_sysconfdir}/nginx/conf.d/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.CRM/Client/dist/* "%{buildroot}%{buildpath}/products/ASC.CRM/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.Files/Client/dist/* "%{buildroot}%{buildpath}/products/ASC.Files/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.Files/Server/DocStore/* "%{buildroot}%{buildpath}/products/ASC.Files/server/DocStore/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.People/Client/dist/* "%{buildroot}%{buildpath}/products/ASC.People/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.Projects/Client/dist/* "%{buildroot}%{buildpath}/products/ASC.Projects/client/"
|
||||
cp -rf %{_builddir}/%{sourcename}/products/ASC.Calendar/Client/dist/* "%{buildroot}%{buildpath}/products/ASC.Calendar/client/"
|
||||
|
@ -31,7 +31,6 @@ ELK_PORT="9200"
|
||||
|
||||
JSON="json -I -f"
|
||||
JSON_USERCONF="$JSON $USER_CONF -e"
|
||||
JSON_DSCONF="$JSON $DS_CONF -e"
|
||||
|
||||
[ $(id -u) -ne 0 ] && { echo "Root privileges required"; exit 1; }
|
||||
|
||||
@ -129,7 +128,7 @@ while [ "$1" != "" ]; do
|
||||
echo " -zkp, --zookeeperport zookeeper port (default 2181)"
|
||||
echo " -esh, --elastichost elasticsearch ip"
|
||||
echo " -esp, --elasticport elasticsearch port (default 9200)"
|
||||
echo " -e, --environment environment (default 'production')"
|
||||
echo " -e, --environment environment (default 'production')"
|
||||
echo " -?, -h, --help this help"
|
||||
echo
|
||||
exit 0
|
||||
@ -167,8 +166,8 @@ install_json() {
|
||||
|
||||
set_core_machinekey
|
||||
$JSON_USERCONF "this.core={'base-domain': \"$APP_HOST\", 'machinekey': \"$CORE_MACHINEKEY\" }" \
|
||||
-e "this.urlshortener={ 'path': 'client/index.js' }" -e "this.thumb={ 'path': 'client/' }" \
|
||||
-e "this.socket={ 'path': '../ASC.Socket.IO' }" >/dev/null 2>&1
|
||||
-e "this.urlshortener={ 'path': '../ASC.UrlShortener/index.js' }" -e "this.thumb={ 'path': '../ASC.Thumbnails/' }" \
|
||||
-e "this.socket={ 'path': '../ASC.Socket.IO/' }" >/dev/null 2>&1
|
||||
$JSON $APP_DIR/appsettings.json -e "this.core.products.subfolder='server'" >/dev/null 2>&1
|
||||
$JSON $APP_DIR/appsettings.services.json -e "this.core={ 'products': { 'folder': '../../products', 'subfolder': 'server'} }" >/dev/null 2>&1
|
||||
|
||||
@ -178,23 +177,21 @@ install_json() {
|
||||
restart_services() {
|
||||
echo -n "Restarting services... "
|
||||
|
||||
sed -i "s/ENVIRONMENT=.*/ENVIRONMENT=$ENVIRONMENT/" $SYSTEMD_DIR/${PRODUCT}*.service >/dev/null 2>&1
|
||||
systemctl daemon-reload
|
||||
|
||||
for SVC in nginx mysqld ${PRODUCT}-api ${PRODUCT}-api-system ${PRODUCT}-urlshortener ${PRODUCT}-thumbnails \
|
||||
${PRODUCT}-socket ${PRODUCT}-studio-notify ${PRODUCT}-notify ${PRODUCT}-people-server ${PRODUCT}-files \
|
||||
${PRODUCT}-files-services ${PRODUCT}-studio ${PRODUCT}-backup ${PRODUCT}-storage-encryption \
|
||||
${PRODUCT}-storage-migration ${PRODUCT}-projects-server ${PRODUCT}-telegram-service ${PRODUCT}-crm \
|
||||
${PRODUCT}-calendar ${PRODUCT}-mail elasticsearch kafka zookeeper
|
||||
do
|
||||
sed -i "s/ENVIRONMENT=.*/ENVIRONMENT=$ENVIRONMENT/" $SYSTEMD_DIR/$SVC.service >/dev/null 2>&1
|
||||
|
||||
if systemctl is-active $SVC | grep -q "active"; then
|
||||
systemctl restart $SVC.service >/dev/null 2>&1
|
||||
else
|
||||
systemctl enable $SVC.service >/dev/null 2>&1
|
||||
systemctl start $SVC.service >/dev/null 2>&1
|
||||
fi
|
||||
if systemctl is-active $SVC | grep -v "active" >/dev/null; then
|
||||
echo -e "\033[31m $SVC not started \033[0m"
|
||||
fi
|
||||
done
|
||||
echo "OK"
|
||||
}
|
||||
@ -418,6 +415,7 @@ setup_nginx(){
|
||||
setup_docs() {
|
||||
echo -n "Configuring Docs... "
|
||||
local DS_CONF="/etc/onlyoffice/documentserver/local.json"
|
||||
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
|
||||
@ -504,7 +502,7 @@ setup_elasticsearch() {
|
||||
echo -n "Configuring elasticsearch... "
|
||||
|
||||
#Save elasticsearch parameters in .json
|
||||
$JSON_USERCONF "this.elastic={'Scheme': \"${ELK_SHEME}\",'Host': \"${ELK_HOST}\",'Port': \"${ELK_PORT}\" }" >/dev/null 2>&1
|
||||
$JSON $APP_DIR/elastic.json -e "this.elastic={'Scheme': \"${ELK_SHEME}\",'Host': \"${ELK_HOST}\",'Port': \"${ELK_PORT}\",'Threads': \"1\" }" >/dev/null 2>&1
|
||||
|
||||
change_elasticsearch_config
|
||||
|
||||
@ -515,12 +513,14 @@ setup_kafka() {
|
||||
|
||||
local KAFKA_SERVICE=$(systemctl --type=service | grep 'kafka' | tr -d '●' | awk '{print $1;}')
|
||||
|
||||
if [ $KAFKA_SERVICE ]; then
|
||||
if [ -n ${KAFKA_SERVICE} ]; then
|
||||
|
||||
echo -n "Configuring kafka... "
|
||||
|
||||
local KAFKA_DIR="$(cat $SYSTEMD_DIR/$KAFKA_SERVICE | grep ExecStop= | cut -c 10- | rev | cut -c 26- | rev)"
|
||||
local KAFKA_CONF="${KAFKA_DIR}/config"
|
||||
|
||||
#Change kafka config
|
||||
local KAFKA_CONF="$(cat $SYSTEMD_DIR/$KAFKA_SERVICE | grep ExecStop= | cut -c 10- | rev | cut -c 26- | rev)/config"
|
||||
sed -i "s/clientPort=.*/clientPort=${ZOOKEEPER_PORT}/g" $KAFKA_CONF/zookeeper.properties
|
||||
sed -i "s/zookeeper.connect=.*/zookeeper.connect=${ZOOKEEPER_HOST}:${ZOOKEEPER_PORT}/g" $KAFKA_CONF/server.properties
|
||||
sed -i "s/bootstrap.servers=.*/bootstrap.servers=${KAFKA_HOST}:${KAFKA_PORT}/g" $KAFKA_CONF/consumer.properties
|
||||
@ -532,6 +532,17 @@ setup_kafka() {
|
||||
#Save kafka parameters in .json
|
||||
$JSON_USERCONF "this.kafka={'BootstrapServers': \"${KAFKA_HOST}:${KAFKA_PORT}\"}" >/dev/null 2>&1
|
||||
|
||||
#Add topics for kafka
|
||||
KAFKA_TOPICS=( ascchannelQuotaCacheItemAny
|
||||
ascchannelTariffCacheItemRemove
|
||||
ascchannelTenantCacheItemInsertOrUpdate
|
||||
ascchannelTenantSettingRemove )
|
||||
|
||||
for i in "${KAFKA_TOPICS[@]}"
|
||||
do
|
||||
${KAFKA_DIR}/bin/kafka-topics.sh --create --zookeeper ${ZOOKEEPER_HOST}:${ZOOKEEPER_PORT} --topic $i --replication-factor 1 --partitions 3 >/dev/null 2>&1
|
||||
done
|
||||
|
||||
echo "OK"
|
||||
fi
|
||||
|
||||
|
2
build/run/Radicale.bat
Normal file
2
build/run/Radicale.bat
Normal file
@ -0,0 +1,2 @@
|
||||
echo "RUN ASC.Radicale"
|
||||
call dotnet run --project ..\..\common\services\ASC.Radicale\ASC.Radicale.csproj --no-build --$STORAGE_ROOT=..\..\Data --log__dir=..\..\Logs --log__name=radicale
|
@ -8,7 +8,6 @@ using ASC.Api.Core.Middleware;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Mapping;
|
||||
|
||||
using Autofac;
|
||||
@ -34,10 +33,11 @@ namespace ASC.Api.Core
|
||||
{
|
||||
public IConfiguration Configuration { get; }
|
||||
public IHostEnvironment HostEnvironment { get; }
|
||||
public virtual string[] LogParams { get; }
|
||||
public virtual JsonConverter[] Converters { get; }
|
||||
public virtual bool AddControllersAsServices { get; } = false;
|
||||
public virtual bool ConfirmAddScheme { get; } = false;
|
||||
protected DIHelper DIHelper { get; }
|
||||
public virtual bool AddAndUseSession { get; } = false;
|
||||
protected DIHelper DIHelper { get; }
|
||||
protected bool LoadProducts { get; } = true;
|
||||
protected bool LoadConsumers { get; } = true;
|
||||
|
||||
@ -49,27 +49,30 @@ namespace ASC.Api.Core
|
||||
}
|
||||
|
||||
public virtual void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
{
|
||||
services.AddCustomHealthCheck(Configuration);
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddMemoryCache();
|
||||
|
||||
if(AddAndUseSession)
|
||||
services.AddSession();
|
||||
|
||||
DIHelper.Configure(services);
|
||||
|
||||
services.AddControllers()
|
||||
.AddXmlSerializerFormatters()
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.WriteIndented = false;
|
||||
options.JsonSerializerOptions.IgnoreNullValues = true;
|
||||
services.AddControllers()
|
||||
.AddXmlSerializerFormatters()
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.WriteIndented = false;
|
||||
options.JsonSerializerOptions.IgnoreNullValues = true;
|
||||
options.JsonSerializerOptions.Converters.Add(new ApiDateTimeConverter());
|
||||
|
||||
if (Converters != null)
|
||||
{
|
||||
{
|
||||
foreach (var c in Converters)
|
||||
{
|
||||
options.JsonSerializerOptions.Converters.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -83,19 +86,22 @@ namespace ASC.Api.Core
|
||||
|
||||
DIHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
|
||||
DIHelper.RegisterProducts(Configuration, HostEnvironment.ContentRootPath);
|
||||
if (LoadProducts)
|
||||
{
|
||||
DIHelper.RegisterProducts(Configuration, HostEnvironment.ContentRootPath);
|
||||
}
|
||||
|
||||
var builder = services.AddMvcCore(config =>
|
||||
{
|
||||
{
|
||||
config.Conventions.Add(new ControllerNameAttributeConvention());
|
||||
|
||||
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
|
||||
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
|
||||
|
||||
config.Filters.Add(new AuthorizeFilter(policy));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter)));
|
||||
config.Filters.Add(new AuthorizeFilter(policy));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter)));
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter)));
|
||||
config.Filters.Add(new CustomResponseFilterAttribute());
|
||||
config.Filters.Add(new CustomExceptionFilterAttribute());
|
||||
config.Filters.Add(new TypeFilterAttribute(typeof(FormatFilter)));
|
||||
@ -113,11 +119,6 @@ namespace ASC.Api.Core
|
||||
authBuilder.AddScheme<AuthenticationSchemeOptions, ConfirmAuthHandler>("confirm", a => { });
|
||||
}
|
||||
|
||||
if (LogParams != null)
|
||||
{
|
||||
LogNLogExtension.ConfigureLog(DIHelper, LogParams);
|
||||
}
|
||||
|
||||
services.AddAutoMapper(Assembly.GetAssembly(typeof(MappingProfile)));
|
||||
}
|
||||
|
||||
@ -129,6 +130,9 @@ namespace ASC.Api.Core
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
if (AddAndUseSession)
|
||||
app.UseSession();
|
||||
|
||||
app.UseAuthentication();
|
||||
|
||||
@ -141,7 +145,7 @@ namespace ASC.Api.Core
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapCustom();
|
||||
endpoints.MapCustom();
|
||||
|
||||
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
||||
{
|
||||
|
@ -98,7 +98,9 @@ namespace ASC.Common.Logging
|
||||
void FatalFormat(IFormatProvider provider, string format, params object[] args);
|
||||
|
||||
string LogDirectory { get; }
|
||||
string Name { get; set; }
|
||||
string Name { get; set; }
|
||||
|
||||
void Configure(string name);
|
||||
}
|
||||
|
||||
public class Log : ILog
|
||||
@ -108,7 +110,7 @@ namespace ASC.Common.Logging
|
||||
XmlConfigurator.Configure(log4net.LogManager.GetRepository(Assembly.GetCallingAssembly()));
|
||||
}
|
||||
|
||||
private readonly log4net.ILog loger;
|
||||
private log4net.ILog loger;
|
||||
|
||||
public bool IsDebugEnabled { get; private set; }
|
||||
|
||||
@ -124,6 +126,11 @@ namespace ASC.Common.Logging
|
||||
|
||||
public Log(string name)
|
||||
{
|
||||
Configure(name);
|
||||
}
|
||||
|
||||
public void Configure(string name)
|
||||
{
|
||||
loger = log4net.LogManager.GetLogger(Assembly.GetCallingAssembly(), name);
|
||||
|
||||
IsDebugEnabled = loger.IsDebugEnabled;
|
||||
@ -131,8 +138,8 @@ namespace ASC.Common.Logging
|
||||
IsWarnEnabled = loger.IsWarnEnabled;
|
||||
IsErrorEnabled = loger.IsErrorEnabled;
|
||||
IsFatalEnabled = loger.IsFatalEnabled;
|
||||
IsTraceEnabled = loger.Logger.IsEnabledFor(Level.Trace);
|
||||
}
|
||||
IsTraceEnabled = loger.Logger.IsEnabledFor(Level.Trace);
|
||||
}
|
||||
|
||||
public void Trace(object message)
|
||||
{
|
||||
@ -401,14 +408,21 @@ namespace ASC.Common.Logging
|
||||
NLog.Targets.Target.Register<SelfCleaningTarget>("SelfCleaning");
|
||||
}
|
||||
|
||||
public void Configure(LogNLog options)
|
||||
{
|
||||
|
||||
public void Configure(LogNLog options)
|
||||
{
|
||||
options.Configure("ASC");
|
||||
}
|
||||
|
||||
public void Configure(string name, LogNLog options)
|
||||
{
|
||||
Configure(options);
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
Configure(options);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Configure(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +457,12 @@ namespace ASC.Common.Logging
|
||||
|
||||
public bool IsFatalEnabled { get; private set; }
|
||||
|
||||
public bool IsTraceEnabled { get; private set; }
|
||||
public bool IsTraceEnabled { get; private set; }
|
||||
|
||||
public void Configure(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public void Trace(object message)
|
||||
{
|
||||
@ -850,19 +869,23 @@ namespace ASC.Common.Logging
|
||||
|
||||
public void DebugWithProps(string message, KeyValuePair<string, object> prop1, KeyValuePair<string, object> prop2, KeyValuePair<string, object> prop3)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Configure(string name)
|
||||
{
|
||||
}
|
||||
|
||||
public string LogDirectory { get { return ""; } }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
|
||||
[Singletone]
|
||||
public class LogManager<T> : OptionsMonitor<T> where T : class, ILog, new()
|
||||
{
|
||||
public LogManager(IOptionsFactory<T> factory, IEnumerable<IOptionsChangeTokenSource<T>> sources, IOptionsMonitorCache<T> cache) : base(factory, sources, cache)
|
||||
{
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override T Get(string name)
|
||||
@ -881,21 +904,8 @@ namespace ASC.Common.Logging
|
||||
public class LoggerExtension<T> where T : class, ILog, new()
|
||||
{
|
||||
public static void RegisterLog(DIHelper services)
|
||||
{
|
||||
const string baseName = "ASC";
|
||||
var baseSqlName = $"{baseName}.SQL";
|
||||
services.Configure<T>(r => r.Name = baseName);
|
||||
services.Configure<T>(baseName, r => r.Name = baseName);
|
||||
services.Configure<T>(baseSqlName, r => r.Name = baseSqlName);
|
||||
services.TryAdd(typeof(IOptionsMonitor<ILog>), typeof(LogManager<T>));
|
||||
}
|
||||
|
||||
public static void ConfigureLog(DIHelper services, params string[] additionalLoggers)
|
||||
{
|
||||
foreach (var l in additionalLoggers)
|
||||
{
|
||||
services.Configure<T>(l, r => r.Name = l);
|
||||
}
|
||||
services.TryAdd(typeof(IOptionsMonitor<ILog>), typeof(LogManager<T>));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,8 @@ namespace ASC.Common.Utils
|
||||
{
|
||||
try
|
||||
{
|
||||
var payloadParts = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(signature)).Split('?');
|
||||
var rightSignature = signature.Replace("\"", "");
|
||||
var payloadParts = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(rightSignature)).Split('?');
|
||||
if (GetHashBase64(payloadParts[1] + secret) == payloadParts[0])
|
||||
{
|
||||
//Sig correct
|
||||
|
@ -147,6 +147,11 @@ namespace ASC.Common.Utils
|
||||
public TimeZoneInfo GetTimeZone(string timeZoneId, bool defaultIfNoMatch = true)
|
||||
{
|
||||
var defaultTimezone = GetTimeZoneDefault();
|
||||
|
||||
if (string.IsNullOrEmpty(timeZoneId))
|
||||
{
|
||||
return defaultIfNoMatch ? defaultTimezone : null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -262,7 +262,8 @@ namespace ASC.Core
|
||||
|
||||
public string AuthenticateMe(Guid userId, List<Claim> additionalClaims = null)
|
||||
{
|
||||
return AuthenticateMe(Authentication.GetAccountByID(TenantManager.GetCurrentTenant().TenantId, userId), additionalClaims);
|
||||
var account = Authentication.GetAccountByID(TenantManager.GetCurrentTenant().TenantId, userId);
|
||||
return AuthenticateMe(account, additionalClaims);
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
|
@ -40,10 +40,12 @@ namespace ASC.Core.Data
|
||||
{
|
||||
private Expression<Func<Subscription, SubscriptionRecord>> FromSubscriptionToSubscriptionRecord { get; set; }
|
||||
private Expression<Func<DbSubscriptionMethod, SubscriptionMethod>> FromDbSubscriptionMethodToSubscriptionMethod { get; set; }
|
||||
private UserDbContext UserDbContext { get; set; }
|
||||
private Lazy<UserDbContext> LazyUserDbContext { get; }
|
||||
private UserDbContext UserDbContext { get => LazyUserDbContext.Value; }
|
||||
|
||||
public DbSubscriptionService(DbContextManager<UserDbContext> dbContextManager)
|
||||
{
|
||||
UserDbContext = dbContextManager.Value;
|
||||
LazyUserDbContext = new Lazy<UserDbContext>(() => dbContextManager.Value);
|
||||
|
||||
FromSubscriptionToSubscriptionRecord = r => new SubscriptionRecord
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ namespace ASC.Core.Common.EF
|
||||
switch (Provider)
|
||||
{
|
||||
case Provider.MySql:
|
||||
optionsBuilder.UseMySql(ConnectionStringSettings.ConnectionString, ServerVersion.AutoDetect(ConnectionStringSettings.ConnectionString), r=>
|
||||
optionsBuilder.UseMySql(ConnectionStringSettings.ConnectionString, ServerVersion.Parse("8.0.25"), r=>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MigrateAssembly))
|
||||
{
|
||||
|
@ -40,7 +40,8 @@ using ASC.Core.Users;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Core
|
||||
{
|
||||
{
|
||||
[Scope]
|
||||
class ConfigureHostedSolution : IConfigureNamedOptions<HostedSolution>
|
||||
{
|
||||
private UserFormatter UserFormatter { get; }
|
||||
|
@ -48,12 +48,13 @@ namespace ASC.Feed.Data
|
||||
private AuthContext AuthContext { get; }
|
||||
private TenantManager TenantManager { get; }
|
||||
private TenantUtil TenantUtil { get; }
|
||||
private FeedDbContext FeedDbContext { get; }
|
||||
private Lazy<FeedDbContext> LazyFeedDbContext { get; }
|
||||
private FeedDbContext FeedDbContext { get => LazyFeedDbContext.Value; }
|
||||
|
||||
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbContextManager<FeedDbContext> dbContextManager)
|
||||
: this(authContext, tenantManager, tenantUtil)
|
||||
{
|
||||
FeedDbContext = dbContextManager.Get(Constants.FeedDbId);
|
||||
LazyFeedDbContext = new Lazy<FeedDbContext>(() => dbContextManager.Get(Constants.FeedDbId));
|
||||
}
|
||||
|
||||
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil)
|
||||
|
@ -41,13 +41,14 @@ namespace ASC.Feed.Data
|
||||
|
||||
private AuthContext AuthContext { get; }
|
||||
private TenantManager TenantManager { get; }
|
||||
private FeedDbContext FeedDbContext { get; }
|
||||
private Lazy<FeedDbContext> LazyFeedDbContext { get; }
|
||||
private FeedDbContext FeedDbContext { get => LazyFeedDbContext.Value; }
|
||||
|
||||
public FeedReadedDataProvider(AuthContext authContext, TenantManager tenantManager, DbContextManager<FeedDbContext> dbContextManager)
|
||||
{
|
||||
AuthContext = authContext;
|
||||
TenantManager = tenantManager;
|
||||
FeedDbContext = dbContextManager.Get(dbId);
|
||||
LazyFeedDbContext = new Lazy<FeedDbContext>(() => dbContextManager.Get(dbId));
|
||||
}
|
||||
|
||||
public DateTime GetTimeReaded()
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -39,11 +40,12 @@ namespace ASC.IPSecurity
|
||||
{
|
||||
private const string dbId = "core";
|
||||
|
||||
private TenantDbContext TenantDbContext { get; }
|
||||
private Lazy<TenantDbContext> LazyTenantDbContext { get; }
|
||||
private TenantDbContext TenantDbContext { get => LazyTenantDbContext.Value; }
|
||||
|
||||
public IPRestrictionsRepository(DbContextManager<TenantDbContext> dbContextManager)
|
||||
{
|
||||
TenantDbContext = dbContextManager.Get(dbId);
|
||||
LazyTenantDbContext = new Lazy<TenantDbContext>(() => dbContextManager.Get(dbId));
|
||||
}
|
||||
|
||||
public List<IPRestriction> Get(int tenant)
|
||||
|
@ -36,11 +36,12 @@ namespace ASC.VoipService.Dao
|
||||
{
|
||||
private readonly string dbid = "default";
|
||||
|
||||
protected VoipDbContext VoipDbContext { get; set; }
|
||||
private Lazy<VoipDbContext> LazyVoipDbContext { get; }
|
||||
protected VoipDbContext VoipDbContext { get => LazyVoipDbContext.Value; }
|
||||
|
||||
protected AbstractDao(DbContextManager<VoipDbContext> dbOptions, TenantManager tenantManager)
|
||||
{
|
||||
VoipDbContext = dbOptions.Get(dbid);
|
||||
LazyVoipDbContext = new Lazy<VoipDbContext>(() => dbOptions.Get(dbid));
|
||||
TenantID = tenantManager.GetCurrentTenant().TenantId;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ using ASC.ApiSystem.Controllers;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
|
||||
using Autofac;
|
||||
|
||||
@ -82,8 +81,6 @@ namespace ASC.ApiSystem
|
||||
services.AddAuthentication()
|
||||
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth.allowskip", _ => { })
|
||||
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth.allowskip.registerportal", _ => { });
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Apisystem");
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -44,14 +44,15 @@ namespace ASC.AuditTrail
|
||||
{
|
||||
private MessageTarget MessageTarget { get; set; }
|
||||
private UserFormatter UserFormatter { get; set; }
|
||||
private AuditTrailContext AuditTrailContext { get; }
|
||||
private Lazy<AuditTrailContext> LazyAuditTrailContext { get; }
|
||||
private AuditTrailContext AuditTrailContext { get => LazyAuditTrailContext.Value; }
|
||||
private AuditActionMapper AuditActionMapper { get; }
|
||||
|
||||
public AuditEventsRepository(MessageTarget messageTarget, UserFormatter userFormatter, DbContextManager<AuditTrailContext> dbContextManager, AuditActionMapper auditActionMapper)
|
||||
{
|
||||
MessageTarget = messageTarget;
|
||||
UserFormatter = userFormatter;
|
||||
AuditTrailContext = dbContextManager.Value;
|
||||
LazyAuditTrailContext = new Lazy<AuditTrailContext>(() => dbContextManager.Value );
|
||||
AuditActionMapper = auditActionMapper;
|
||||
}
|
||||
|
||||
|
@ -43,14 +43,15 @@ namespace ASC.AuditTrail.Data
|
||||
[Scope]
|
||||
public class LoginEventsRepository
|
||||
{
|
||||
private UserFormatter UserFormatter { get; }
|
||||
private AuditTrailContext AuditTrailContext { get; }
|
||||
private UserFormatter UserFormatter { get; }
|
||||
private Lazy<AuditTrailContext> LazyAuditTrailContext { get; }
|
||||
private AuditTrailContext AuditTrailContext { get => LazyAuditTrailContext.Value; }
|
||||
private AuditActionMapper AuditActionMapper { get; }
|
||||
|
||||
public LoginEventsRepository(UserFormatter userFormatter, DbContextManager<AuditTrailContext> dbContextManager, AuditActionMapper auditActionMapper)
|
||||
{
|
||||
UserFormatter = userFormatter;
|
||||
AuditTrailContext = dbContextManager.Value;
|
||||
LazyAuditTrailContext = new Lazy<AuditTrailContext>(() => dbContextManager.Value);
|
||||
AuditActionMapper = auditActionMapper;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ using System.Threading.Tasks;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
@ -84,7 +83,6 @@ namespace ASC.Thumbnails.Svc
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.ClearEvents");
|
||||
services.AddHostedService<ClearEventsServiceLauncher>();
|
||||
diHelper.TryAdd<ClearEventsServiceLauncher>();
|
||||
})
|
||||
|
@ -38,8 +38,6 @@ namespace ASC.Data.Backup
|
||||
{
|
||||
public class Startup : BaseStartup
|
||||
{
|
||||
public override string[] LogParams { get => new string[] { "ASC.Data.Backup" }; }
|
||||
|
||||
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment)
|
||||
{
|
||||
|
||||
|
@ -37,12 +37,13 @@ namespace ASC.Data.Backup.Storage
|
||||
{
|
||||
[Scope]
|
||||
public class BackupRepository : IBackupRepository
|
||||
{
|
||||
private BackupsContext BackupContext { get; }
|
||||
{
|
||||
private Lazy<BackupsContext> LazyBackupsContext { get; }
|
||||
private BackupsContext BackupContext { get => LazyBackupsContext.Value; }
|
||||
|
||||
public BackupRepository(DbContextManager<BackupsContext> backupContext)
|
||||
{
|
||||
BackupContext = backupContext.Value;
|
||||
LazyBackupsContext = new Lazy<BackupsContext>(() => backupContext.Value);
|
||||
}
|
||||
|
||||
public void SaveBackupRecord(BackupRecord backup)
|
||||
|
@ -63,7 +63,8 @@ namespace ASC.Data.Backup.Tasks
|
||||
private bool Dump { get; set; }
|
||||
private TenantManager TenantManager { get; set; }
|
||||
private TempStream TempStream { get; }
|
||||
private BackupsContext BackupRecordContext { get; set; }
|
||||
private Lazy<BackupsContext> LazyBackupsContext { get; }
|
||||
private BackupsContext BackupRecordContext { get => LazyBackupsContext.Value; }
|
||||
|
||||
public BackupPortalTask(DbFactory dbFactory, DbContextManager<BackupsContext> dbContextManager, IOptionsMonitor<ILog> options, TenantManager tenantManager, CoreBaseSettings coreBaseSettings, StorageFactory storageFactory, StorageFactoryConfig storageFactoryConfig, ModuleProvider moduleProvider, TempStream tempStream)
|
||||
: base(dbFactory, options, storageFactory, storageFactoryConfig, moduleProvider)
|
||||
@ -71,7 +72,7 @@ namespace ASC.Data.Backup.Tasks
|
||||
Dump = coreBaseSettings.Standalone;
|
||||
TenantManager = tenantManager;
|
||||
TempStream = tempStream;
|
||||
BackupRecordContext = dbContextManager.Get(DbFactory.ConnectionStringSettings.ConnectionString);
|
||||
LazyBackupsContext = new Lazy<BackupsContext>(() => dbContextManager.Get(DbFactory.ConnectionStringSettings.ConnectionString));
|
||||
}
|
||||
|
||||
public void Init(int tenantId, string fromConfigPath, string toFilePath, int limit)
|
||||
|
@ -34,8 +34,6 @@ namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public class Startup : BaseStartup
|
||||
{
|
||||
public override string[] LogParams { get => new string[] { "ASC.Data.Storage.Encryption" }; }
|
||||
|
||||
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment)
|
||||
{
|
||||
|
||||
|
@ -6,7 +6,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
@ -64,7 +63,6 @@ namespace ASC.Data.Storage.Migration
|
||||
{
|
||||
services.AddMemoryCache();
|
||||
var diHelper = new DIHelper(services);
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Data.Storage.Migration", "ASC.Migration");
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
@ -92,8 +92,9 @@ namespace ASC.ElasticSearch
|
||||
private TenantManager TenantManager { get; }
|
||||
private BaseIndexerHelper BaseIndexerHelper { get; }
|
||||
private Settings Settings { get; }
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
private WebstudioDbContext WebstudioDbContext { get; }
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
private Lazy<WebstudioDbContext> LazyWebstudioDbContext { get; }
|
||||
private WebstudioDbContext WebstudioDbContext { get => LazyWebstudioDbContext.Value; }
|
||||
|
||||
public BaseIndexer(
|
||||
Client client,
|
||||
@ -110,7 +111,7 @@ namespace ASC.ElasticSearch
|
||||
BaseIndexerHelper = baseIndexerHelper;
|
||||
Settings = settings;
|
||||
ServiceProvider = serviceProvider;
|
||||
WebstudioDbContext = dbContextManager.Value;
|
||||
LazyWebstudioDbContext = new Lazy<WebstudioDbContext>(() => dbContextManager.Value);
|
||||
}
|
||||
|
||||
internal void Index(T data, bool immediately = true)
|
||||
|
@ -34,8 +34,6 @@ using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.ElasticSearch.Service;
|
||||
|
||||
using Autofac;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -49,7 +47,6 @@ namespace ASC.ElasticSearch
|
||||
private ICacheNotify<AscCacheItem> Notify { get; }
|
||||
private ICacheNotify<IndexAction> IndexNotify { get; }
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
public ILifetimeScope Container { get; }
|
||||
private bool IsStarted { get; set; }
|
||||
private CancellationTokenSource CancellationTokenSource { get; set; }
|
||||
private Timer Timer { get; set; }
|
||||
@ -60,14 +57,12 @@ namespace ASC.ElasticSearch
|
||||
ICacheNotify<AscCacheItem> notify,
|
||||
ICacheNotify<IndexAction> indexNotify,
|
||||
IServiceProvider serviceProvider,
|
||||
ILifetimeScope container,
|
||||
Settings settings)
|
||||
{
|
||||
Log = options.Get("ASC.Indexer");
|
||||
Notify = notify;
|
||||
IndexNotify = indexNotify;
|
||||
ServiceProvider = serviceProvider;
|
||||
Container = container;
|
||||
CancellationTokenSource = new CancellationTokenSource();
|
||||
Period = TimeSpan.FromMinutes(settings.Period.Value);
|
||||
}
|
||||
@ -137,13 +132,19 @@ namespace ASC.ElasticSearch
|
||||
Timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
IsStarted = true;
|
||||
|
||||
using var scope = Container.BeginLifetimeScope();
|
||||
var wrappers = scope.Resolve<IEnumerable<IFactoryIndexer>>();
|
||||
|
||||
Parallel.ForEach(wrappers, w =>
|
||||
using (var scope = ServiceProvider.CreateScope())
|
||||
{
|
||||
IndexProduct(w, reindex);
|
||||
});
|
||||
var wrappers = scope.ServiceProvider.GetService<IEnumerable<IFactoryIndexer>>();
|
||||
|
||||
Parallel.ForEach(wrappers, wrapper =>
|
||||
{
|
||||
using (var scope = ServiceProvider.CreateScope())
|
||||
{
|
||||
var w = (IFactoryIndexer)scope.ServiceProvider.GetService(wrapper.GetType());
|
||||
IndexProduct(w, reindex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Timer.Change(Period, Period);
|
||||
IndexNotify.Publish(new IndexAction() { Indexing = "", LastIndexed = DateTime.Now.Ticks }, CacheNotifyAction.Any);
|
||||
|
@ -64,18 +64,15 @@ namespace ASC.Feed.Aggregator
|
||||
|
||||
private ConfigurationExtension Configuration { get; }
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
public ILifetimeScope Container { get; }
|
||||
|
||||
public FeedAggregatorService(
|
||||
ConfigurationExtension configuration,
|
||||
IServiceProvider serviceProvider,
|
||||
ILifetimeScope container,
|
||||
IOptionsMonitor<ILog> optionsMonitor,
|
||||
IOptionsSnapshot<SignalrServiceClient> optionsSnapshot)
|
||||
{
|
||||
Configuration = configuration;
|
||||
ServiceProvider = serviceProvider;
|
||||
Container = container;
|
||||
Log = optionsMonitor.Get("ASC.Feed.Agregator");
|
||||
SignalrServiceClient = optionsSnapshot.Get("counters");
|
||||
}
|
||||
@ -129,8 +126,7 @@ namespace ASC.Feed.Aggregator
|
||||
Log.DebugFormat("Start of collecting feeds...");
|
||||
|
||||
var unreadUsers = new Dictionary<int, Dictionary<Guid, int>>();
|
||||
using var autofacScope = Container.BeginLifetimeScope();
|
||||
var modules = autofacScope.Resolve<IEnumerable<IFeedModule>>();
|
||||
var modules = scope.ServiceProvider.GetService<IEnumerable<IFeedModule>>();
|
||||
|
||||
foreach (var module in modules)
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core.Notify.Senders;
|
||||
using ASC.Notify.Config;
|
||||
@ -67,7 +66,6 @@ namespace ASC.Notify
|
||||
services.AddMemoryCache();
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages");
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
||||
|
42
common/services/ASC.Radicale/ASC.Radicale.csproj
Normal file
42
common/services/ASC.Radicale/ASC.Radicale.csproj
Normal file
@ -0,0 +1,42 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<ApplicationIcon />
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="radicale.log.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="https://json.schemastore.org/local.settings.json" /></VisualStudio></ProjectExtensions>
|
||||
|
||||
|
||||
</Project>
|
103
common/services/ASC.Radicale/Program.cs
Normal file
103
common/services/ASC.Radicale/Program.cs
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
namespace ASC.Radicale
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSystemd()
|
||||
.UseWindowsService()
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureAppConfiguration((hostContext, config) =>
|
||||
{
|
||||
var buided = config.Build();
|
||||
var path = buided["pathToConf"];
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path));
|
||||
}
|
||||
config.SetBasePath(path);
|
||||
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
|
||||
config
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile("storage.json")
|
||||
.AddJsonFile("kafka.json")
|
||||
.AddJsonFile($"appsettings.services.json", true)
|
||||
//.AddJsonFile("radicale.json")
|
||||
.AddJsonFile($"kafka.{env}.json", true)
|
||||
.AddJsonFile($"appsettings.{env}.json", true)
|
||||
.AddJsonFile($"radicale.{env}.json", true)
|
||||
.AddEnvironmentVariables()
|
||||
.AddCommandLine(args)
|
||||
.AddInMemoryCollection(new Dictionary<string, string>
|
||||
{
|
||||
{"pathToConf", path }
|
||||
}
|
||||
);
|
||||
})
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
services.AddMemoryCache();
|
||||
var diHelper = new DIHelper(services);
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
||||
services.AddHostedService<RadicaleServiceLauncher>();
|
||||
diHelper.TryAdd<RadicaleServiceLauncher>();
|
||||
})
|
||||
.ConfigureContainer<ContainerBuilder>((context, builder) =>
|
||||
{
|
||||
builder.Register(context.Configuration, false, false);
|
||||
});
|
||||
}
|
||||
}
|
29
common/services/ASC.Radicale/Properties/launchSettings.json
Normal file
29
common/services/ASC.Radicale/Properties/launchSettings.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Kestrel WebServer": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"$STORAGE_ROOT": "../../../Data",
|
||||
"log__name": "radicale",
|
||||
"log__dir": "../../../Logs",
|
||||
"core__products__folder": "../../../products",
|
||||
"ASPNETCORE_URLS": "http://localhost:5024",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"WSL 2 : Ubuntu 20.04": {
|
||||
"commandName": "WSL2",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"$STORAGE_ROOT": "../../../Data",
|
||||
"log__name": "radicale",
|
||||
"log__dir": "../../../Logs",
|
||||
"core__products__folder": "../../../products",
|
||||
"ASPNETCORE_URLS": "http://localhost:5024",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"distributionName": "Ubuntu-20.04"
|
||||
}
|
||||
}
|
||||
}
|
129
common/services/ASC.Radicale/RadicaleServiceLauncher.cs
Normal file
129
common/services/ASC.Radicale/RadicaleServiceLauncher.cs
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Radicale
|
||||
{
|
||||
[Scope]
|
||||
public class RadicaleServiceLauncher : IHostedService
|
||||
{
|
||||
private Process Proc { get; set; }
|
||||
private ProcessStartInfo StartInfo { get; set; }
|
||||
private ILog Logger { get; set; }
|
||||
//private ConfigurationExtension ConfigurationExtension { get; }
|
||||
//private IHostEnvironment HostEnvironment { get; set; }
|
||||
|
||||
public RadicaleServiceLauncher(
|
||||
IOptionsMonitor<ILog> options,
|
||||
ConfigurationExtension configurationExtension,
|
||||
IHostEnvironment hostEnvironment)
|
||||
{
|
||||
Logger = options.CurrentValue;
|
||||
//ConfigurationExtension = configurationExtension;
|
||||
//HostEnvironment = hostEnvironment;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var pythonName = "python";
|
||||
|
||||
var configPath = Path.GetFullPath(CrossPlatform.PathCombine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "radicale.config"));
|
||||
|
||||
if (WorkContext.IsMono)
|
||||
{
|
||||
pythonName = "python3";
|
||||
}
|
||||
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
CreateNoWindow = false,
|
||||
UseShellExecute = false,
|
||||
FileName = pythonName,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Arguments = $"-m radicale --config \"{configPath}\"",
|
||||
WorkingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
|
||||
};
|
||||
|
||||
StartRedicale();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
StopRadicale();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void StartRedicale()
|
||||
{
|
||||
StopRadicale();
|
||||
Proc = Process.Start(StartInfo);
|
||||
}
|
||||
|
||||
private void StopRadicale()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Proc != null && !Proc.HasExited)
|
||||
{
|
||||
Proc.Kill();
|
||||
if (!Proc.WaitForExit(10000))
|
||||
{
|
||||
Logger.Warn("The process does not wait for completion.");
|
||||
}
|
||||
Proc.Close();
|
||||
Proc.Dispose();
|
||||
Proc = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Radicale failed stop", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
common/services/ASC.Radicale/appsettings.json
Normal file
3
common/services/ASC.Radicale/appsettings.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"pathToConf": "..\\..\\..\\config"
|
||||
}
|
124
common/services/ASC.Radicale/radicale.config
Normal file
124
common/services/ASC.Radicale/radicale.config
Normal file
@ -0,0 +1,124 @@
|
||||
# -*- mode: conf -*-
|
||||
# vim:ft=cfg
|
||||
|
||||
# Config file for Radicale - A simple calendar server
|
||||
#
|
||||
# Place it into /etc/radicale/config (global)
|
||||
# or ~/.config/radicale/config (user)
|
||||
#
|
||||
# The current values are the default ones
|
||||
|
||||
|
||||
[server]
|
||||
|
||||
# CalDAV server hostnames separated by a comma
|
||||
# IPv4 syntax: address:port
|
||||
# IPv6 syntax: [address]:port
|
||||
# For example: 0.0.0.0:9999, [::]:9999
|
||||
hosts = localhost:5232
|
||||
|
||||
# Max parallel connections
|
||||
#max_connections = 8
|
||||
|
||||
# Max size of request body (bytes)
|
||||
#max_content_length = 100000000
|
||||
|
||||
# Socket timeout (seconds)
|
||||
#timeout = 30
|
||||
|
||||
# SSL flag, enable HTTPS protocol
|
||||
#ssl = False
|
||||
|
||||
# SSL certificate path
|
||||
#certificate = /etc/ssl/radicale.cert.pem
|
||||
|
||||
# SSL private key
|
||||
#key = /etc/ssl/radicale.key.pem
|
||||
|
||||
# CA certificate for validating clients. This can be used to secure
|
||||
# TCP traffic between Radicale and a reverse proxy
|
||||
#certificate_authority =
|
||||
|
||||
|
||||
[encoding]
|
||||
|
||||
# Encoding for responding requests
|
||||
#request = utf-8
|
||||
|
||||
# Encoding for storing local collections
|
||||
#stock = utf-8
|
||||
|
||||
|
||||
[auth]
|
||||
|
||||
# Authentication method
|
||||
# Value: none | htpasswd | remote_user | http_x_remote_user
|
||||
type = app_auth_plugin
|
||||
portal_url = http://localhost/apisystem/caldav
|
||||
machine_key = 1123askdasjklasbnd
|
||||
|
||||
# Htpasswd filename
|
||||
#htpasswd_filename = /etc/radicale/users
|
||||
|
||||
# Htpasswd encryption method
|
||||
# Value: plain | bcrypt | md5
|
||||
# bcrypt requires the installation of radicale[bcrypt].
|
||||
#htpasswd_encryption = md5
|
||||
|
||||
# Incorrect authentication delay (seconds)
|
||||
#delay = 1
|
||||
|
||||
# Message displayed in the client when a password is needed
|
||||
#realm = Radicale - Password Required
|
||||
|
||||
|
||||
[rights]
|
||||
|
||||
# Rights backend
|
||||
# Value: none | authenticated | owner_only | owner_write | from_file
|
||||
type = app_rights_plugin
|
||||
|
||||
# File for rights management from_file
|
||||
file = radicale.rights
|
||||
|
||||
|
||||
[storage]
|
||||
|
||||
# Storage backend
|
||||
# Value: multifilesystem
|
||||
# type = multifilesystem
|
||||
type = app_store_plugin
|
||||
portal_url = http://localhost/apisystem/caldav
|
||||
|
||||
# Folder for storing local collections, created if not present
|
||||
filesystem_folder = ..\..\Data\radicale\collections\
|
||||
|
||||
# Delete sync token that are older (seconds)
|
||||
#max_sync_token_age = 2592000
|
||||
|
||||
# Command that is run after changes to storage
|
||||
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
|
||||
#hook =
|
||||
|
||||
|
||||
[web]
|
||||
|
||||
# Web interface backend
|
||||
# Value: none | internal
|
||||
type = none
|
||||
|
||||
|
||||
[logging]
|
||||
|
||||
# Threshold for the logger
|
||||
# Value: debug | info | warning | error | critical
|
||||
level = info
|
||||
|
||||
# Don't include passwords in logs
|
||||
#mask_passwords = True
|
||||
|
||||
|
||||
[headers]
|
||||
|
||||
# Additional HTTP headers
|
||||
Access-Control-Allow-Origin = *
|
22
common/services/ASC.Radicale/radicale.log.config
Normal file
22
common/services/ASC.Radicale/radicale.log.config
Normal file
@ -0,0 +1,22 @@
|
||||
[loggers]
|
||||
keys = root
|
||||
|
||||
[handlers]
|
||||
keys = file
|
||||
|
||||
[formatters]
|
||||
keys = full
|
||||
|
||||
[logger_root]
|
||||
# Change this to DEBUG or INFO for higher verbosity.
|
||||
level = WARNING
|
||||
handlers = file
|
||||
|
||||
[handler_file]
|
||||
class = handlers.TimedRotatingFileHandler
|
||||
# Specify the output file here.
|
||||
args = ('../../../../../../Logs/radicale.log','midnight', 1, 7)
|
||||
formatter = full
|
||||
|
||||
[formatter_full]
|
||||
format = %(asctime)s - [%(thread)x] %(levelname)s: %(message)s
|
14
common/services/ASC.Radicale/radicale.rights
Normal file
14
common/services/ASC.Radicale/radicale.rights
Normal file
@ -0,0 +1,14 @@
|
||||
[admin]
|
||||
user: admin@ascsystem@.+
|
||||
collection: .*
|
||||
permissions: RWrw
|
||||
|
||||
[allow-shared-read]
|
||||
user: .+
|
||||
collection: %(user)s/.+-shared$
|
||||
permissions: Rr
|
||||
|
||||
[owner-write]
|
||||
user: .+
|
||||
collection: %(user)s.*$
|
||||
permissions: RWrw
|
@ -32,7 +32,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
@ -93,8 +92,7 @@ namespace ASC.Socket.IO.Svc
|
||||
var diHelper = new DIHelper(services);
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Socket.IO.Svc");
|
||||
|
||||
services.AddHostedService<SocketServiceLauncher>();
|
||||
diHelper.TryAdd<SocketServiceLauncher>();
|
||||
})
|
||||
|
@ -32,7 +32,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.SsoAuth.Svc;
|
||||
|
||||
@ -94,8 +93,7 @@ namespace ASC.Socket.IO.Svc
|
||||
var diHelper = new DIHelper(services);
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.SsoAuth.Svc");
|
||||
|
||||
services.AddHostedService<Launcher>();
|
||||
diHelper.TryAdd<Launcher>();
|
||||
})
|
||||
|
@ -6,7 +6,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core.Notify;
|
||||
using ASC.Notify;
|
||||
@ -69,7 +68,6 @@ namespace ASC.Studio.Notify
|
||||
var diHelper = new DIHelper(services);
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages");
|
||||
services.AddHostedService<ServiceLauncher>();
|
||||
diHelper.TryAdd<ServiceLauncher>();
|
||||
NotifyConfigurationExtension.Register(diHelper);
|
||||
|
@ -34,8 +34,6 @@ namespace ASC.TelegramService
|
||||
{
|
||||
public class Startup : BaseStartup
|
||||
{
|
||||
public override string[] LogParams { get => new string[] { "ASC.TelegramService" }; }
|
||||
|
||||
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment)
|
||||
{
|
||||
|
||||
|
@ -32,7 +32,6 @@ using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
@ -92,8 +91,7 @@ namespace ASC.Thumbnails.Svc
|
||||
services.AddMemoryCache();
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Thumbnails.Svc");
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
services.AddHostedService<ThumbnailsServiceLauncher>();
|
||||
diHelper.TryAdd<ThumbnailsServiceLauncher>();
|
||||
})
|
||||
|
@ -31,7 +31,6 @@ using System.Threading.Tasks;
|
||||
using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
@ -93,8 +92,7 @@ namespace ASC.UrlShortener.Svc
|
||||
services.AddMemoryCache();
|
||||
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.UrlShortener.Svc");
|
||||
|
||||
services.AddHostedService<UrlShortenerServiceLauncher>();
|
||||
diHelper.TryAdd<UrlShortenerServiceLauncher>();
|
||||
})
|
||||
|
@ -45,6 +45,7 @@
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"version": {
|
||||
"number": "1.0.0",
|
||||
"release": {
|
||||
"date": "",
|
||||
"sign": ""
|
||||
|
@ -52,7 +52,7 @@
|
||||
"type": "ASC.Web.Core.IWebItem, ASC.Web.Core"
|
||||
}
|
||||
],
|
||||
"instanceScope": "InstancePerLifetimeScope"
|
||||
"instanceScope": "InstancePerLifetimeScope"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ map $request_uri $header_x_frame_options {
|
||||
default "SAMEORIGIN";
|
||||
}
|
||||
|
||||
map $request_uri $cache_control {
|
||||
default "";
|
||||
~*^/(api\/2\.0.*|storage|login\.ashx|products\/.+\/httphandlers\/filehandler\.ashx|ChunkedUploader.ashx|apisystem|sh) "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
|
||||
include /etc/nginx/includes/onlyoffice-*.conf;
|
||||
|
||||
server {
|
||||
@ -29,6 +34,8 @@ server {
|
||||
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header X-Frame-Options $header_x_frame_options;
|
||||
add_header Cache-Control $cache_control;
|
||||
etag on;
|
||||
|
||||
large_client_header_buffers 4 16k;
|
||||
|
||||
@ -74,10 +81,9 @@ server {
|
||||
}
|
||||
|
||||
location / {
|
||||
|
||||
proxy_pass http://localhost:5001;
|
||||
expires 365d;
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
location ~* /(manifest.json|sw.js|appIcon.png|bg-error.png) {
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
@ -88,24 +94,26 @@ server {
|
||||
}
|
||||
|
||||
location ~* /static/images/ {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /images/$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/fonts/ {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /fonts/$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/offline/ {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /offline/$basename /index.html =404;
|
||||
}
|
||||
location ~* /thirdparty/ {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /thirdparty/third-party.html /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/locales/(?<content>[^/]+) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /locales/$content/$basename /index.html =404;
|
||||
}
|
||||
@ -113,12 +121,10 @@ server {
|
||||
|
||||
location /login {
|
||||
#rewrite login/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5011;
|
||||
}
|
||||
|
||||
location /sockjs-node {
|
||||
expires 365d;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
@ -133,26 +139,22 @@ server {
|
||||
}
|
||||
|
||||
location /api/2.0 {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
location ~* /(files|encryption|privacyroom) {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /(people|group) {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5004;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /(authentication|modules|portal|security|settings|smtpsettings|capabilities|thirdparty) {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* portal/(.*)(backup|restore)(.*) {
|
||||
expires -1;
|
||||
rewrite (.*)/portal/(.*) $1/backup/$2 break;
|
||||
proxy_redirect off;
|
||||
|
||||
@ -163,44 +165,39 @@ server {
|
||||
}
|
||||
|
||||
location ~* /backup {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5012;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /project {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5020;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /crm {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5021;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /mail {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5022;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /calendar {
|
||||
expires -1;
|
||||
proxy_pass http://localhost:5023;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
}
|
||||
|
||||
location /storage {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5003;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location /login.ashx {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5003;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -209,12 +206,10 @@ server {
|
||||
location /products {
|
||||
location ~* /people {
|
||||
#rewrite products/people/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5002;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /(sockjs-node) {
|
||||
expires 365d;
|
||||
rewrite products/people(.*)/(sockjs-node)/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -231,7 +226,6 @@ server {
|
||||
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
@ -239,7 +233,6 @@ server {
|
||||
|
||||
location ~* /files/doceditor {
|
||||
#rewrite products/files/doceditor/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5013;
|
||||
proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
@ -253,12 +246,10 @@ server {
|
||||
|
||||
location ~* /files {
|
||||
#rewrite products/files/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5008;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /sockjs-node {
|
||||
expires 365d;
|
||||
rewrite products/files(.*)/sockjs-node/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -273,13 +264,12 @@ server {
|
||||
}
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* (/httphandlers/filehandler.ashx|ChunkedUploader.ashx) {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -287,12 +277,10 @@ server {
|
||||
|
||||
location ~* /crm {
|
||||
#rewrite products/crm/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5014;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /sockjs-node {
|
||||
expires 365d;
|
||||
rewrite products/crm(.*)/sockjs-node/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -308,13 +296,12 @@ server {
|
||||
}
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* (/httphandlers/filehandler.ashx|ChunkedUploader.ashx) {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -322,12 +309,10 @@ server {
|
||||
|
||||
location ~* /projects {
|
||||
#rewrite products/projects/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5015;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /sockjs-node {
|
||||
expires 365d;
|
||||
rewrite products/projects(.*)/sockjs-node/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -343,13 +328,12 @@ server {
|
||||
}
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* (/httphandlers/filehandler.ashx|ChunkedUploader.ashx) {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -357,12 +341,10 @@ server {
|
||||
|
||||
location ~* /mail {
|
||||
#rewrite products/mail/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5016;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /sockjs-node {
|
||||
expires 365d;
|
||||
rewrite products/projects(.*)/sockjs-node/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -378,13 +360,12 @@ server {
|
||||
}
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* (/httphandlers/filehandler.ashx|ChunkedUploader.ashx) {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -392,12 +373,10 @@ server {
|
||||
|
||||
location ~* /calendar {
|
||||
#rewrite products/calendar/(.*) /$1 break;
|
||||
expires 365d;
|
||||
proxy_pass http://localhost:5017;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
||||
location ~* /sockjs-node {
|
||||
expires 365d;
|
||||
rewrite products/projects(.*)/sockjs-node/(.*) /$2/$3 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@ -413,13 +392,12 @@ server {
|
||||
}
|
||||
|
||||
location ~* /(manifest.json|service-worker.js|appIcon.png|bg-error.png) {
|
||||
expires 365d;
|
||||
root $public_root;
|
||||
try_files /$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* (/httphandlers/filehandler.ashx|ChunkedUploader.ashx) {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
proxy_pass http://localhost:5007;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
@ -427,16 +405,23 @@ server {
|
||||
}
|
||||
|
||||
location /apisystem {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
rewrite apisystem/(.*) /$1 break;
|
||||
proxy_pass http://localhost:5010;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location /sh {
|
||||
expires -1;
|
||||
add_header Cache-Control $cache_control;
|
||||
rewrite sh/(.*) /$1 break;
|
||||
proxy_pass http://localhost:9999;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
}
|
||||
|
||||
location /caldav {
|
||||
rewrite caldav/(.*) /$1 break;
|
||||
proxy_pass http://localhost:5232;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
}
|
9
config/workbox-config.js
Normal file
9
config/workbox-config.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
globDirectory: 'build/deploy/',
|
||||
globPatterns: [
|
||||
"**/*.{js,css}"
|
||||
],
|
||||
globIgnores: ['**/remoteEntry.js'],
|
||||
swSrc: 'packages/asc-web-common/utils/sw-template.js',
|
||||
swDest: 'build/deploy/public/sw.js'
|
||||
};
|
11
config/workbox-dev-config.js
Normal file
11
config/workbox-dev-config.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
globDirectory: 'build/deploy/',
|
||||
globPatterns: [
|
||||
'**/*.{ico,woff2,svg,html,json,js,png}'
|
||||
],
|
||||
ignoreURLParametersMatching: [
|
||||
/^utm_/,
|
||||
/^fbclid$/
|
||||
],
|
||||
swDest: 'build/deploy/public/sw.js'
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.1.10",
|
||||
"version": "1.0.0",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/asc-web-components",
|
||||
|
24
package.json
24
package.json
@ -18,6 +18,19 @@
|
||||
"scripts": {
|
||||
"wipe": "rimraf node_modules yarn.lock web/**/node_modules products/**/node_modules",
|
||||
"build": "concurrently \"wsrun --parallel build\"",
|
||||
"sw-build": "workbox injectManifest config/workbox-config.js && yarn sw-modify && yarn sw-minimize",
|
||||
"sw-calendar-replace": "replace-in-files --string='products/ASC.Calendar/client/' --replacement='products/calendar/' build/deploy/public/sw.js",
|
||||
"sw-crm-replace": "replace-in-files --string='products/ASC.CRM/client/' --replacement='products/crm/' build/deploy/public/sw.js",
|
||||
"sw-files-replace": "replace-in-files --string='products/ASC.Files/client/' --replacement='products/files/' build/deploy/public/sw.js",
|
||||
"sw-files-editor-replace": "replace-in-files --string='products/ASC.Files/editor/' --replacement='products/files/doceditor/' build/deploy/public/sw.js",
|
||||
"sw-mail-replace": "replace-in-files --string='products/ASC.Mail/client/' --replacement='products/mail/' build/deploy/public/sw.js",
|
||||
"sw-people-replace": "replace-in-files --string='products/ASC.People/client/' --replacement='products/people/' build/deploy/public/sw.js",
|
||||
"sw-projects-replace": "replace-in-files --string='products/ASC.Projects/client/' --replacement='products/projects/' build/deploy/public/sw.js",
|
||||
"sw-studio-replace": "replace-in-files --string='studio/client/' --replacement='/' build/deploy/public/sw.js",
|
||||
"sw-studio-login-replace": "replace-in-files --string='studio/login/' --replacement='login/' build/deploy/public/sw.js",
|
||||
"sw-public-replace": "replace-in-files --string='public/' --replacement='static/' build/deploy/public/sw.js",
|
||||
"sw-modify": "yarn sw-calendar-replace && yarn sw-crm-replace && yarn sw-crm-replace && yarn sw-files-replace && yarn sw-files-editor-replace && yarn sw-mail-replace && yarn sw-people-replace && yarn sw-projects-replace && yarn sw-studio-replace && yarn sw-studio-login-replace && yarn sw-public-replace",
|
||||
"sw-minimize": "yarn terser --compress --mangle -- build/deploy/public/sw.js --output build/deploy/public/sw.js",
|
||||
"start": "concurrently \"wsrun --parallel start\"",
|
||||
"start-prod": "concurrently \"wsrun --parallel start-prod\"",
|
||||
"serve": "concurrently \"wsrun --parallel serve\"",
|
||||
@ -26,12 +39,15 @@
|
||||
"storybook": "yarn workspace @appserver/components storybook",
|
||||
"storybook-build": "yarn workspace @appserver/components run storybook-build",
|
||||
"bump": "lerna version --no-push --no-git-tag-version",
|
||||
"deploy": "rimraf build/deploy && concurrently \"wsrun --parallel deploy\""
|
||||
"deploy": "rimraf build/deploy && concurrently \"wsrun --parallel deploy\" && cp -r public build/deploy && yarn sw-build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"lerna": "^3.22.1",
|
||||
"concurrently": "^5.3.0",
|
||||
"wsrun": "^5.2.4",
|
||||
"rimraf": "^3.0.2"
|
||||
"lerna": "^3.22.1",
|
||||
"replace-in-files-cli": "^1.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"terser": "^5.7.1",
|
||||
"workbox-cli": "^6.1.5",
|
||||
"wsrun": "^5.2.4"
|
||||
}
|
||||
}
|
||||
|
@ -364,7 +364,14 @@ class PageLayout extends React.Component {
|
||||
|
||||
{isSectionFilterAvailable && (
|
||||
<>
|
||||
<div id="main-bar" style={{ display: "grid" }}></div>
|
||||
<div
|
||||
id="main-bar"
|
||||
style={{
|
||||
display: "grid",
|
||||
paddingRight: "20px",
|
||||
paddingTop: "10px",
|
||||
}}
|
||||
></div>
|
||||
<SubSectionFilter className="section-header_filter">
|
||||
{sectionFilterContent
|
||||
? sectionFilterContent.props.children
|
||||
|
@ -5,76 +5,70 @@ $font-family-base: "Open Sans", sans-serif;
|
||||
font-family: "Open Sans";
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
src: url("../../public/fonts/light/open-sans-light.woff2") format("woff2");
|
||||
src: url("/static/fonts/open-sans-light.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
src: url("../../public/fonts/light-italic/open-sans-light-italic.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-light-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url("../../public/fonts/regular/open-sans-regular.woff2") format("woff2");
|
||||
src: url("/static/fonts/open-sans-regular.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
src: url("../../public/fonts/italic/open-sans-italic.woff2") format("woff2");
|
||||
src: url("/static/fonts/open-sans-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
src: url("../../public/fonts/semibold/open-sans-semibold.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-semibold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
src: url("../../public/fonts/semibold-italic/open-sans-semibold-italic.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-semibold-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
src: url("../../public/fonts/bold/open-sans-bold.woff2") format("woff2");
|
||||
src: url("/static/fonts/open-sans-bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
src: url("../../public/fonts/bold-italic/open-sans-bold-italic.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-bold-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
src: url("../../public/fonts/extra-bold/open-sans-extra-bold.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-extra-bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
src: url("../../public/fonts/extra-bold-italic/open-sans-extra-bold-italic.woff2")
|
||||
format("woff2");
|
||||
src: url("/static/fonts/open-sans-extra-bold-italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
html,
|
||||
@ -115,3 +109,12 @@ body.desktop {
|
||||
-o-user-select: none;
|
||||
mozuserselect: none;
|
||||
}
|
||||
|
||||
#snackbar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
width: calc(100vw - 60px);
|
||||
padding: 30px;
|
||||
bottom: 15px;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/common",
|
||||
"version": "0.1.10",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "echo 'skip it'",
|
||||
@ -18,6 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"global": "^4.4.0",
|
||||
"react-selecto": "^1.12.0"
|
||||
"react-selecto": "^1.12.0",
|
||||
"workbox-window": "^6.1.5"
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,7 @@ class SettingsStore {
|
||||
appId: "",
|
||||
measurementId: "",
|
||||
};
|
||||
version = "";
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
|
@ -1,8 +1,60 @@
|
||||
import { Workbox } from "workbox-window";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
export function registerSW(homepage) {
|
||||
import { Workbox } from "workbox-window";
|
||||
import SnackBar from "@appserver/components/snackbar";
|
||||
import i18n from "i18next";
|
||||
import { useTranslation, initReactI18next } from "react-i18next";
|
||||
import Backend from "i18next-http-backend";
|
||||
import { LANGUAGE } from "../constants";
|
||||
import { loadLanguagePath } from "./";
|
||||
|
||||
i18n
|
||||
.use(Backend)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
lng: localStorage.getItem(LANGUAGE) || "en",
|
||||
fallbackLng: "en",
|
||||
load: "all",
|
||||
//debug: true,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // not needed for react as it escapes by default
|
||||
format: function (value, format) {
|
||||
if (format === "lowercase") return value.toLowerCase();
|
||||
return value;
|
||||
},
|
||||
},
|
||||
|
||||
backend: {
|
||||
loadPath: loadLanguagePath(""),
|
||||
},
|
||||
|
||||
react: {
|
||||
useSuspense: false,
|
||||
},
|
||||
});
|
||||
|
||||
const SnackBarWrapper = (props) => {
|
||||
const { t, ready } = useTranslation("Common", { i18n });
|
||||
|
||||
if (ready) {
|
||||
const barConfig = {
|
||||
parentElementId: "snackbar",
|
||||
text: t("NewVersionAvailable"),
|
||||
btnText: t("Load"),
|
||||
onAction: () => props.onButtonClick(),
|
||||
opacity: 1,
|
||||
};
|
||||
|
||||
return <SnackBar {...barConfig} />;
|
||||
}
|
||||
return <></>;
|
||||
};
|
||||
|
||||
const registerSW = () => {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
const wb = new Workbox(`${homepage}/sw.js`);
|
||||
const wb = new Workbox(`/sw.js`);
|
||||
|
||||
//TODO: watch https://developers.google.com/web/tools/workbox/guides/advanced-recipes and https://github.com/webmaxru/prog-web-news/blob/5ff94b45c9d317409c21c0fbb7d76e92f064471b/src/app/app-shell/app-shell.component.ts
|
||||
|
||||
@ -12,16 +64,34 @@ export function registerSW(homepage) {
|
||||
`until all tabs running the current version have fully unloaded.`
|
||||
);
|
||||
|
||||
// Assuming the user accepted the update, set up a listener
|
||||
// that will reload the page as soon as the previously waiting
|
||||
// service worker has taken control.
|
||||
wb.addEventListener("controlling", () => {
|
||||
window.location.reload();
|
||||
});
|
||||
try {
|
||||
const snackbarNode = document.createElement("div");
|
||||
snackbarNode.id = "snackbar";
|
||||
document.body.appendChild(snackbarNode);
|
||||
|
||||
// This will postMessage() to the waiting service worker.
|
||||
wb.messageSkipWaiting();
|
||||
ReactDOM.render(
|
||||
<SnackBarWrapper
|
||||
onButtonClick={() => {
|
||||
snackbarNode.remove();
|
||||
|
||||
wb.addEventListener("controlling", () => {
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
wb.messageSkipWaiting();
|
||||
}}
|
||||
/>,
|
||||
document.getElementById("snackbar")
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("showSkipWaitingPrompt", e);
|
||||
wb.addEventListener("controlling", () => {
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
// This will postMessage() to the waiting service worker.
|
||||
wb.messageSkipWaiting();
|
||||
}
|
||||
// let snackBarRef = this.snackBar.open(
|
||||
|
||||
// "A new version of the website available",
|
||||
@ -58,4 +128,10 @@ export function registerSW(homepage) {
|
||||
} else {
|
||||
console.log("SKIP registerSW because of DEV mode");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.SW = {
|
||||
registerSW: registerSW,
|
||||
};
|
||||
|
||||
export { registerSW };
|
||||
|
@ -1,48 +1,36 @@
|
||||
import {
|
||||
precacheAndRoute,
|
||||
cleanupOutdatedCaches,
|
||||
//createHandlerBoundToURL,
|
||||
} from "workbox-precaching";
|
||||
import { setCacheNameDetails } from "workbox-core";
|
||||
import { clientsClaim } from "workbox-core";
|
||||
import { /*NavigationRoute,*/ registerRoute } from "workbox-routing";
|
||||
import { googleFontsCache, imageCache, offlineFallback } from "workbox-recipes";
|
||||
import {
|
||||
//CacheFirst,
|
||||
//NetworkFirst,
|
||||
StaleWhileRevalidate,
|
||||
} from "workbox-strategies";
|
||||
//import { ExpirationPlugin } from "workbox-expiration";
|
||||
//import { BroadcastUpdatePlugin } from "workbox-broadcast-update";
|
||||
importScripts(
|
||||
"https://storage.googleapis.com/workbox-cdn/releases/6.1.5/workbox-sw.js"
|
||||
);
|
||||
|
||||
workbox.setConfig({
|
||||
debug: false,
|
||||
});
|
||||
|
||||
// This will trigger the importScripts() for workbox.strategies and its dependencies:
|
||||
const { precacheAndRoute, cleanupOutdatedCaches } = workbox.precaching;
|
||||
const { setCacheNameDetails, clientsClaim } = workbox.core;
|
||||
const { registerRoute } = workbox.routing;
|
||||
const { googleFontsCache, imageCache, offlineFallback } = workbox.recipes;
|
||||
const { StaleWhileRevalidate } = workbox.strategies;
|
||||
|
||||
// SETTINGS
|
||||
|
||||
// Claiming control to start runtime caching asap
|
||||
clientsClaim();
|
||||
|
||||
// Use to update the app after user triggered refresh (without prompt)
|
||||
//self.skipWaiting();
|
||||
|
||||
// PRECACHING
|
||||
|
||||
// Setting custom cache name
|
||||
setCacheNameDetails({ precache: "wb6-precache", runtime: "wb6-runtime" });
|
||||
|
||||
// We inject manifest here using "workbox-build" in workbox-inject.js
|
||||
precacheAndRoute(self.__WB_MANIFEST);
|
||||
const precachRoutes = self.__WB_MANIFEST;
|
||||
|
||||
precacheAndRoute(precachRoutes);
|
||||
|
||||
// Remove cache from the previous WB versions
|
||||
cleanupOutdatedCaches();
|
||||
|
||||
// NAVIGATION ROUTING
|
||||
|
||||
// This assumes /index.html has been precached.
|
||||
// const navHandler = createHandlerBoundToURL("/index.html");
|
||||
// const navigationRoute = new NavigationRoute(navHandler, {
|
||||
// denylist: [new RegExp("/out-of-spa/")], // Also might be specified explicitly via allowlist
|
||||
// });
|
||||
// registerRoute(navigationRoute);
|
||||
|
||||
// STATIC RESOURCES
|
||||
|
||||
googleFontsCache({ cachePrefix: "wb6-gfonts" });
|
||||
@ -77,24 +65,3 @@ offlineFallback({
|
||||
imageFallback: "/static/offline/offline.svg",
|
||||
fontFallback: false,
|
||||
});
|
||||
|
||||
// ALL OTHER EVENTS
|
||||
|
||||
// Receive push and show a notification
|
||||
// self.addEventListener("push", function (event) {
|
||||
// console.log("[Service Worker]: Received push event", event);
|
||||
|
||||
// var notificationData = {};
|
||||
|
||||
// if (event.data.json()) {
|
||||
// notificationData = event.data.json();
|
||||
// } else {
|
||||
// notificationData = {
|
||||
// title: "Something Has Happened",
|
||||
// message: "Something you might want to check out",
|
||||
// icon: "/assets/img/pwa-logo.png",
|
||||
// };
|
||||
// }
|
||||
|
||||
// self.registration.showNotification(notificationData.title, notificationData);
|
||||
// });
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/components",
|
||||
"version": "0.1.10",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "echo 'skip it'",
|
||||
|
@ -1,217 +1,140 @@
|
||||
import "./snackbar.css";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import PropType from "prop-types";
|
||||
import StyledSnackBar from "./styled-snackbar";
|
||||
import StyledCrossIcon from "./styled-snackbar-action";
|
||||
import StyledLogoIcon from "./styled-snackbar-logo";
|
||||
import Box from "../box";
|
||||
import Heading from "../heading";
|
||||
import Text from "../text";
|
||||
|
||||
export const Snackbar = {
|
||||
current: null,
|
||||
snackbar: null,
|
||||
show(params) {
|
||||
let options = extend(true, defaultConfig, params);
|
||||
class SnackBar extends React.Component {
|
||||
static show(barConfig) {
|
||||
const { parentElementId, ...rest } = barConfig;
|
||||
|
||||
if (Snackbar.current) {
|
||||
Snackbar.current.style.opacity = 0;
|
||||
setTimeout(
|
||||
function () {
|
||||
let parent = this.parentElement;
|
||||
if (parent)
|
||||
// possible null if too many/fast snackbars
|
||||
parent.removeChild(this);
|
||||
}.bind(Snackbar.current),
|
||||
500
|
||||
);
|
||||
let parentElementNode =
|
||||
parentElementId && document.getElementById(parentElementId);
|
||||
|
||||
if (!parentElementNode) {
|
||||
const snackbarNode = document.createElement("div");
|
||||
snackbarNode.id = "snackbar";
|
||||
document.body.appendChild(snackbarNode);
|
||||
parentElementNode = snackbarNode;
|
||||
}
|
||||
|
||||
Snackbar.snackbar = document.createElement("div");
|
||||
Snackbar.snackbar.className = `snackbar-container ${
|
||||
options.parentElementId && "inline"
|
||||
} ${options.customClass}`;
|
||||
Snackbar.snackbar.style.width = options.width;
|
||||
window.snackbar = barConfig;
|
||||
|
||||
if (options.logoImg) {
|
||||
let logoImg = document.createElement("div");
|
||||
logoImg.src = options.logoImg;
|
||||
logoImg.className = "logo";
|
||||
logoImg.alt = "logo";
|
||||
logoImg.innerHTML = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15ZM7 6V4H9V6H7ZM7 12V7H9V12H7Z" fill="black"/>
|
||||
</svg>`;
|
||||
Snackbar.snackbar.appendChild(logoImg);
|
||||
}
|
||||
|
||||
let textContainer = document.createElement("div");
|
||||
textContainer.className = "text-container";
|
||||
Snackbar.snackbar.appendChild(textContainer);
|
||||
|
||||
if (options.textHeader) {
|
||||
let header = document.createElement("p");
|
||||
header.style.margin = 0;
|
||||
header.style.padding = 0;
|
||||
header.style.color = options.textColor;
|
||||
header.style.fontSize = "12px";
|
||||
header.style.fontWeight = 600;
|
||||
header.style.lineHeight = "16px";
|
||||
header.innerHTML = options.textHeader;
|
||||
textContainer.appendChild(header);
|
||||
}
|
||||
|
||||
let body = document.createElement("p");
|
||||
body.style.margin = 0;
|
||||
body.style.padding = 0;
|
||||
body.style.color = options.textColor;
|
||||
body.style.fontSize = "12px";
|
||||
body.style.lineHeight = "16px";
|
||||
body.innerHTML = options.textBody;
|
||||
textContainer.appendChild(body);
|
||||
|
||||
Snackbar.snackbar.appendChild(textContainer);
|
||||
Snackbar.snackbar.style.background = options.backgroundColor;
|
||||
|
||||
if (options.showSecondButton) {
|
||||
let secondButton = document.createElement("button");
|
||||
secondButton.className = "action";
|
||||
secondButton.innerHTML = options.secondButtonText;
|
||||
secondButton.style.color = options.secondButtonTextColor;
|
||||
secondButton.addEventListener("click", () => {
|
||||
options.onSecondButtonClick(Snackbar.snackbar);
|
||||
});
|
||||
Snackbar.snackbar.appendChild(secondButton);
|
||||
}
|
||||
|
||||
if (options.showAction) {
|
||||
let actionButton = document.createElement("button");
|
||||
actionButton.className = "action";
|
||||
|
||||
if (options.actionIcon) {
|
||||
actionButton.innerHTML = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.76288 6.35869C7.56764 6.16343 7.56764 5.84687 7.76288 5.65161L10.9493 2.46498C11.1445 2.26973 11.1445 1.95316 10.9493 1.75791L10.2422 1.05077C10.0469 0.855489 9.73031 0.855489 9.53504 1.05077L6.34878 4.23729C6.15352 4.43257 5.83691 4.43257 5.64165 4.23729L2.46017 1.05556C2.26491 0.860275 1.9483 0.860275 1.75304 1.05556L1.04596 1.76269C0.850716 1.95795 0.850716 2.27451 1.04596 2.46977L4.22755 5.65161C4.42279 5.84687 4.42279 6.16343 4.22755 6.35869L1.0501 9.53639C0.854858 9.73165 0.854858 10.0482 1.0501 10.2435L1.75718 10.9506C1.95245 11.1459 2.26905 11.1459 2.46432 10.9506L5.64165 7.77302C5.83691 7.57774 6.15352 7.57774 6.34878 7.77302L9.5309 10.9554C9.72616 11.1507 10.0428 11.1507 10.238 10.9554L10.9451 10.2483C11.1404 10.053 11.1404 9.73644 10.9451 9.54118L7.76288 6.35869Z" fill="#999976"/>
|
||||
</svg>`; //`<img src="${options.actionIcon}" alt="${options.actionText}" class="action-icon">`;
|
||||
} else {
|
||||
actionButton.innerHTML = options.actionText;
|
||||
actionButton.style.color = options.actionTextColor;
|
||||
}
|
||||
|
||||
actionButton.addEventListener("click", function () {
|
||||
options.onActionClick(Snackbar.snackbar);
|
||||
});
|
||||
Snackbar.snackbar.appendChild(actionButton);
|
||||
}
|
||||
|
||||
if (options.duration) {
|
||||
setTimeout(
|
||||
function () {
|
||||
if (Snackbar.current === this) {
|
||||
Snackbar.current.style.opacity = 0;
|
||||
// When natural remove event occurs let's move the snackbar to its origins
|
||||
Snackbar.current.style.top = "-100px";
|
||||
Snackbar.current.style.bottom = "-100px";
|
||||
}
|
||||
}.bind(Snackbar.snackbar),
|
||||
options.duration
|
||||
);
|
||||
}
|
||||
|
||||
Snackbar.snackbar.addEventListener(
|
||||
"transitionend",
|
||||
function (event) {
|
||||
if (event.propertyName === "opacity" && this.style.opacity === "0") {
|
||||
if (typeof options.onClose === "function") options.onClose(this);
|
||||
|
||||
this.parentElement.removeChild(this);
|
||||
if (Snackbar.current === this) {
|
||||
Snackbar.current = null;
|
||||
}
|
||||
}
|
||||
}.bind(Snackbar.snackbar)
|
||||
);
|
||||
|
||||
Snackbar.current = Snackbar.snackbar;
|
||||
|
||||
var parentElm =
|
||||
options.parentElementId &&
|
||||
document.getElementById(options.parentElementId);
|
||||
|
||||
if (parentElm) {
|
||||
parentElm.appendChild(Snackbar.snackbar);
|
||||
} else {
|
||||
document.body.appendChild(Snackbar.snackbar);
|
||||
}
|
||||
|
||||
//let bottom = getComputedStyle(Snackbar.snackbar).bottom;
|
||||
//let top = getComputedStyle(Snackbar.snackbar).top;
|
||||
Snackbar.snackbar.style.opacity = 1;
|
||||
|
||||
Snackbar.snackbar.className = `snackbar-container ${
|
||||
options.parentElementId && "inline"
|
||||
} ${options.customClass} ${
|
||||
!options.parentElementId && ` snackbar-pos ${options.position}`
|
||||
}`;
|
||||
},
|
||||
close() {
|
||||
if (Snackbar.current) {
|
||||
Snackbar.current.style.opacity = 0;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const defaultConfig = {
|
||||
parentElementId: null,
|
||||
backgroundColor: "#F8F7BF",
|
||||
textColor: "#000",
|
||||
width: "auto",
|
||||
textHeader: null,
|
||||
textBody: "Default Body text",
|
||||
logoImg: "/static/images/info.react.svg",
|
||||
|
||||
showAction: false,
|
||||
actionIcon: "/static/images/cross.react.svg",
|
||||
actionText: "Close",
|
||||
actionTextColor: "#0F4071",
|
||||
|
||||
showSecondButton: false,
|
||||
secondButtonText: "Reload",
|
||||
secondButtonTextColor: "#0F4071",
|
||||
|
||||
position: "bottom-center",
|
||||
duration: null,
|
||||
customClass: "",
|
||||
|
||||
onActionClick: (element) => {
|
||||
element.style.opacity = 0;
|
||||
},
|
||||
onSecondButtonClick: () => {
|
||||
location.reload();
|
||||
},
|
||||
onClose: () => {},
|
||||
};
|
||||
|
||||
const extend = function () {
|
||||
let extended = {};
|
||||
let deep = false;
|
||||
let i = 0;
|
||||
let length = arguments.length;
|
||||
|
||||
if (Object.prototype.toString.call(arguments[0]) === "[object Boolean]") {
|
||||
deep = arguments[0];
|
||||
i++;
|
||||
ReactDOM.render(<SnackBar {...rest} />, parentElementNode);
|
||||
}
|
||||
|
||||
const merge = function (obj) {
|
||||
for (let prop in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
||||
if (
|
||||
deep &&
|
||||
Object.prototype.toString.call(obj[prop]) === "[object Object]"
|
||||
) {
|
||||
extended[prop] = extend(true, extended[prop], obj[prop]);
|
||||
} else {
|
||||
extended[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
static close() {
|
||||
if (window.snackbar && window.snackbar.parentElementId) {
|
||||
const bar = document.querySelector(`#${window.snackbar.parentElementId}`);
|
||||
bar.remove();
|
||||
//ReactDOM.unmountComponentAtNode(window.snackbar.parentElementId);
|
||||
} else {
|
||||
console.error("Not found snackbar");
|
||||
}
|
||||
}
|
||||
|
||||
onActionClick = (e) => {
|
||||
this.props.onAction && this.props.onAction(e);
|
||||
};
|
||||
|
||||
for (; i < length; i++) {
|
||||
let obj = arguments[i];
|
||||
merge(obj);
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
text,
|
||||
headerText,
|
||||
btnText,
|
||||
textColor,
|
||||
showIcon,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
textAlign,
|
||||
htmlContent,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
return extended;
|
||||
const headerStyles = headerText ? {} : { display: "none" };
|
||||
|
||||
return (
|
||||
<StyledSnackBar {...rest}>
|
||||
{htmlContent ? (
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: htmlContent,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{showIcon && (
|
||||
<Box className="logo">
|
||||
<StyledLogoIcon size="medium" color={textColor} />
|
||||
</Box>
|
||||
)}
|
||||
<Box className="text-container" textAlign={textAlign}>
|
||||
<Heading
|
||||
size="xsmall"
|
||||
isInline={true}
|
||||
className="text-header"
|
||||
style={headerStyles}
|
||||
color={textColor}
|
||||
>
|
||||
{headerText}
|
||||
</Heading>
|
||||
<div className="text-body" textAlign={textAlign}>
|
||||
<Text
|
||||
as="p"
|
||||
color={textColor}
|
||||
fontSize={fontSize}
|
||||
fontWeight={fontWeight}
|
||||
>
|
||||
{text}
|
||||
</Text>
|
||||
|
||||
{btnText && (
|
||||
<button className="button" onClick={this.onActionClick}>
|
||||
<Text color={textColor}>{btnText}</Text>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{!btnText && (
|
||||
<button className="action" onClick={this.onActionClick}>
|
||||
<StyledCrossIcon size="medium" />
|
||||
</button>
|
||||
)}
|
||||
)
|
||||
</StyledSnackBar>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SnackBar.propTypes = {
|
||||
text: PropType.string,
|
||||
headerText: PropType.string,
|
||||
btnText: PropType.string,
|
||||
backgroundImg: PropType.string,
|
||||
backgroundColor: PropType.string,
|
||||
textColor: PropType.string,
|
||||
showIcon: PropType.bool,
|
||||
onAction: PropType.func,
|
||||
fontSize: PropType.string,
|
||||
fontWeight: PropType.string,
|
||||
textAlign: PropType.string,
|
||||
htmlContent: PropType.string,
|
||||
};
|
||||
|
||||
SnackBar.defaultProps = {
|
||||
backgroundColor: "#f8f7bf",
|
||||
textColor: "#000",
|
||||
showIcon: true,
|
||||
fontSize: "13px",
|
||||
fontWeight: "400",
|
||||
textAlign: "left",
|
||||
htmlContent: "",
|
||||
};
|
||||
|
||||
export default SnackBar;
|
||||
|
@ -1,125 +0,0 @@
|
||||
.snackbar-container {
|
||||
transition: all 500ms ease;
|
||||
transition-property: top, right, bottom, left, opacity;
|
||||
font-family: Open Sans, sans-serif, Arial;
|
||||
font-size: 12px;
|
||||
min-height: 14px;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
color: white;
|
||||
line-height: 16px;
|
||||
padding: 12px;
|
||||
bottom: -100px;
|
||||
top: -100px;
|
||||
opacity: 0;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.snackbar-container.inline {
|
||||
position: relative;
|
||||
z-index: initial;
|
||||
top: initial;
|
||||
bottom: initial;
|
||||
margin: 16px 24px 0 0;
|
||||
max-width: initial;
|
||||
justify-content: initial;
|
||||
}
|
||||
|
||||
.snackbar-container.inline button:last-child {
|
||||
margin-left: auto;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.snackbar-container .action {
|
||||
background: inherit;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
font-size: inherit;
|
||||
color: #4caf50;
|
||||
margin: 0 0 0 24px;
|
||||
padding: 0;
|
||||
min-width: min-content;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.snackbar-container {
|
||||
min-width: 400px;
|
||||
max-width: 568px;
|
||||
display: inline-flex;
|
||||
border-radius: 6px;
|
||||
margin: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.snackbar-container {
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 769px) {
|
||||
.snackbar-container.inline {
|
||||
margin: 16px 0px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.snackbar-pos.bottom-center {
|
||||
top: auto !important;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.snackbar-pos.bottom-left {
|
||||
top: auto !important;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.snackbar-pos.bottom-right {
|
||||
top: auto !important;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.snackbar-pos.top-left {
|
||||
bottom: auto !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.snackbar-pos.top-center {
|
||||
bottom: auto !important;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.snackbar-pos.top-right {
|
||||
bottom: auto !important;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.snackbar-pos.bottom-center,
|
||||
.snackbar-pos.top-center {
|
||||
left: 0;
|
||||
transform: none;
|
||||
}
|
||||
}
|
51
packages/asc-web-components/snackbar/snackbar.stories.js
Normal file
51
packages/asc-web-components/snackbar/snackbar.stories.js
Normal file
@ -0,0 +1,51 @@
|
||||
import React from "react";
|
||||
import Box from "../box";
|
||||
import SnackBar from "./";
|
||||
|
||||
export default {
|
||||
title: "Components/SnackBar",
|
||||
component: SnackBar,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "SnackBar is used for displaying important messages.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onAction: {
|
||||
action: "onAction",
|
||||
},
|
||||
textColor: { control: "color" },
|
||||
backgroundColor: { control: "color" },
|
||||
showIcon: { control: "boolean" },
|
||||
},
|
||||
};
|
||||
|
||||
const Wrapper = ({ children }) => (
|
||||
<Box id="main-bar" displayProp="grid">
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
|
||||
const BaseTemplate = (args) => (
|
||||
<Wrapper>
|
||||
<SnackBar {...args} onClose={(e) => alert("OnClose handled!", e)} />
|
||||
</Wrapper>
|
||||
);
|
||||
|
||||
export const base = BaseTemplate.bind({});
|
||||
base.args = {
|
||||
backgroundImg: "",
|
||||
backgroundColor: "#f8f7bf",
|
||||
textColor: "#000",
|
||||
opacity: 1,
|
||||
headerText: "Attention",
|
||||
text:
|
||||
"We apologize for any short-term technical issues in service functioning, that may appear on 22.06.2021 during the update of Onlyoffice Personal.",
|
||||
showIcon: true,
|
||||
fontSize: "13px",
|
||||
fontWeight: "400",
|
||||
textAlign: "left",
|
||||
htmlContent: "",
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
import styled from "styled-components";
|
||||
import CrossIcon from "../../../public/images/cross.react.svg";
|
||||
import commonIconsStyles from "../utils/common-icons-style";
|
||||
|
||||
const StyledCrossIcon = styled(CrossIcon)`
|
||||
${commonIconsStyles}
|
||||
|
||||
path {
|
||||
fill: #999976;
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledCrossIcon;
|
13
packages/asc-web-components/snackbar/styled-snackbar-logo.js
Normal file
13
packages/asc-web-components/snackbar/styled-snackbar-logo.js
Normal file
@ -0,0 +1,13 @@
|
||||
import styled from "styled-components";
|
||||
import InfoIcon from "../../../public/images/info.react.svg";
|
||||
import commonIconsStyles from "../utils/common-icons-style";
|
||||
|
||||
const StyledLogoIcon = styled(InfoIcon)`
|
||||
${commonIconsStyles}
|
||||
|
||||
path {
|
||||
fill: ${(props) => props.color};
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledLogoIcon;
|
73
packages/asc-web-components/snackbar/styled-snackbar.js
Normal file
73
packages/asc-web-components/snackbar/styled-snackbar.js
Normal file
@ -0,0 +1,73 @@
|
||||
import styled from "styled-components";
|
||||
import Box from "../box";
|
||||
|
||||
const StyledSnackBar = styled(Box)`
|
||||
transition: all 500ms ease;
|
||||
transition-property: top, right, bottom, left, opacity;
|
||||
font-family: Open Sans, sans-serif, Arial;
|
||||
font-size: 12px;
|
||||
min-height: 14px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
color: white;
|
||||
line-height: 16px;
|
||||
padding: 12px;
|
||||
margin: 0 0 8px 0;
|
||||
opacity: ${(props) => props.opacity || 0};
|
||||
width: 100%;
|
||||
background-color: ${(props) => props.backgroundColor};
|
||||
background-image: url(${(props) => props.backgroundImg || ""});
|
||||
border-radius: 6px;
|
||||
|
||||
.logo {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
text-align: ${(props) => props.textAlign};
|
||||
|
||||
.text-header {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.text-body {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
justify-content: ${(props) => props.textAlign};
|
||||
}
|
||||
}
|
||||
|
||||
.action {
|
||||
background: inherit;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
font-size: inherit;
|
||||
color: "#000";
|
||||
margin: 0 0 0 24px;
|
||||
padding: 0;
|
||||
min-width: min-content;
|
||||
cursor: pointer;
|
||||
margin-left: auto;
|
||||
padding-left: 8px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: inherit;
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
color: "#000";
|
||||
cursor: pointer;
|
||||
line-height: 12px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledSnackBar;
|
@ -1,22 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.ElasticSearch;
|
||||
using ASC.Web.CRM.Core.Search;
|
||||
|
||||
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using ASC.Common.DependencyInjection;
|
||||
|
||||
|
||||
namespace ASC.CRM.BackgroundTasks
|
||||
@ -73,9 +71,6 @@ namespace ASC.CRM.BackgroundTasks
|
||||
|
||||
services.AddHostedService<ServiceLauncher>();
|
||||
diHelper.TryAdd<ServiceLauncher>();
|
||||
|
||||
LogNLogExtension.ConfigureLog(diHelper, "ASC.Files", "ASC.Feed.Agregator");
|
||||
|
||||
diHelper.TryAdd<FactoryIndexerCase>();
|
||||
diHelper.TryAdd<FactoryIndexerContact>();
|
||||
diHelper.TryAdd<FactoryIndexerContactInfo>();
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/crm",
|
||||
"version": "0.1.10",
|
||||
"version": "1.0.0",
|
||||
"homepage": "/products/crm",
|
||||
"title": "ONLYOFFICE",
|
||||
"id": "6743007c-6f95-4d20-8c88-a8601ce5e76d",
|
||||
@ -24,6 +24,7 @@
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"external-remotes-plugin": "^1.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"json-loader": "^0.5.7",
|
||||
@ -35,8 +36,7 @@
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"webpack": "5.14.0",
|
||||
"webpack-cli": "4.5.0",
|
||||
"webpack-dev-server": "3.11.2",
|
||||
"workbox-webpack-plugin": "^6.1.1"
|
||||
"webpack-dev-server": "3.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
|
3
products/ASC.CRM/Client/src/bootstrap.js
vendored
3
products/ASC.CRM/Client/src/bootstrap.js
vendored
@ -1,9 +1,8 @@
|
||||
import App from "./App";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import config from "../package.json";
|
||||
import { registerSW } from "@appserver/common/utils/sw-helper";
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
|
||||
registerSW(config.homepage);
|
||||
registerSW();
|
||||
|
@ -3,8 +3,8 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const ExternalTemplateRemotesPlugin = require("external-remotes-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const { InjectManifest } = require("workbox-webpack-plugin");
|
||||
const combineUrl = require("@appserver/common/utils/combineUrl");
|
||||
const AppServerConfig = require("@appserver/common/constants/AppServerConfig");
|
||||
|
||||
@ -91,17 +91,6 @@ var config = {
|
||||
],
|
||||
},
|
||||
{ test: /\.json$/, loader: "json-loader" },
|
||||
{
|
||||
test: /\.(woff(2)?)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
name: "fonts/[hash].[ext]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ["style-loader", "css-loader"],
|
||||
@ -165,6 +154,7 @@ var config = {
|
||||
},
|
||||
},
|
||||
}),
|
||||
new ExternalTemplateRemotesPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
@ -194,14 +184,6 @@ module.exports = (env, argv) => {
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
config.plugins.push(
|
||||
new InjectManifest({
|
||||
mode: "production", //"development",
|
||||
swSrc: "@appserver/common/utils/sw-template.js", // this is your sw template file
|
||||
swDest: "sw.js", // this will be created in the build step
|
||||
exclude: [/\.map$/, /manifest$/, /service-worker\.js$/],
|
||||
})
|
||||
);
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
@ -136,11 +136,6 @@ namespace ASC.CRM.ApiModels
|
||||
Data = "support@onlyoffice.com",
|
||||
InfoType = ContactInfoType.Email
|
||||
};
|
||||
}
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<ContactInfo, ContactInfoDto>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -374,6 +374,7 @@ namespace ASC.CRM.ApiModels
|
||||
|
||||
protected ListItemDto(ListItem listItem)
|
||||
{
|
||||
Id = listItem.ID;
|
||||
Title = listItem.Title;
|
||||
Description = listItem.Description;
|
||||
Color = listItem.Color;
|
||||
|
@ -78,7 +78,10 @@ namespace ASC.CRM.Api
|
||||
SharingOptions = new SharingOptions();
|
||||
// SharingOptions.PublicItems.Add(new SharingOptions.PublicItem { Id = userId, IsGroup = false });
|
||||
}
|
||||
|
||||
public override List<ITodo> LoadTodos(Guid userId, DateTime utcStartDate, DateTime utcEndDate)
|
||||
{
|
||||
return new List<ITodo>();
|
||||
}
|
||||
public override List<IEvent> LoadEvents(Guid userId, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var events = new List<IEvent>();
|
||||
|
@ -31,7 +31,7 @@ using System.Linq;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Web;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Common.EF;
|
||||
using ASC.Core.Common.EF;
|
||||
using ASC.CRM.Resources;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Web.Core;
|
||||
@ -44,8 +44,10 @@ namespace ASC.Web.CRM.Configuration
|
||||
[Scope]
|
||||
public class CrmSpaceUsageStatManager : SpaceUsageStatManager
|
||||
{
|
||||
private int _tenantId;
|
||||
private FilesDbContext _filesDbContext;
|
||||
private int _tenantId;
|
||||
private Lazy<FilesDbContext> LazyFilesDbContext { get; }
|
||||
private FilesDbContext _filesDbContext { get => LazyFilesDbContext.Value; }
|
||||
|
||||
private PathProvider _pathProvider;
|
||||
|
||||
public CrmSpaceUsageStatManager(DbContextManager<FilesDbContext> filesDbContext,
|
||||
@ -53,7 +55,7 @@ namespace ASC.Web.CRM.Configuration
|
||||
TenantManager tenantManager)
|
||||
{
|
||||
_pathProvider = pathProvider;
|
||||
_filesDbContext = filesDbContext.Value;
|
||||
LazyFilesDbContext = new Lazy<FilesDbContext>(() => filesDbContext.Value);
|
||||
_tenantId = tenantManager.GetCurrentTenant().TenantId;
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,11 @@ namespace ASC.CRM.Core.Dao
|
||||
{
|
||||
public class AbstractDao
|
||||
{
|
||||
protected readonly List<EntityType> _supportedEntityType = new List<EntityType>();
|
||||
public CrmDbContext CrmDbContext { get; }
|
||||
protected readonly List<EntityType> _supportedEntityType = new List<EntityType>();
|
||||
|
||||
private Lazy<CrmDbContext> LazyCrmDbContext { get; }
|
||||
public CrmDbContext CrmDbContext { get => LazyCrmDbContext.Value; }
|
||||
|
||||
protected readonly SecurityContext _securityContext;
|
||||
protected readonly ICache _cache;
|
||||
protected ILog _logger;
|
||||
@ -66,7 +69,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
_cache = ascCache;
|
||||
|
||||
CrmDbContext = dbContextManager.Get(CrmConstants.DatabaseId);
|
||||
LazyCrmDbContext = new Lazy<CrmDbContext>(() => dbContextManager.Get(CrmConstants.DatabaseId));
|
||||
|
||||
TenantID = tenantManager.GetCurrentTenant().TenantId;
|
||||
_securityContext = securityContext;
|
||||
|
@ -390,7 +390,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -326,7 +326,7 @@ namespace ASC.CRM.Core.Dao
|
||||
}
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromMinutes(1));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromMinutes(1));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -544,7 +544,7 @@ namespace ASC.CRM.Core.Dao
|
||||
}
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -397,7 +397,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -73,13 +73,11 @@ namespace ASC.CRM.Core.Dao
|
||||
private CurrencyInfo _defaultCurrency;
|
||||
private TenantUtil _tenantUtil;
|
||||
private DaoFactory _daoFactory;
|
||||
private UserDbContext _userDbContext;
|
||||
private DisplayUserSettingsHelper _displayUserSettings;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ReportDao(DbContextManager<CrmDbContext> dbContextManager,
|
||||
DbContextManager<UserDbContext> dbUserContextManager,
|
||||
TenantManager tenantManager,
|
||||
SecurityContext securityContext,
|
||||
FilesIntegration filesIntegration,
|
||||
@ -112,8 +110,6 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
var crmSettings = settingsManager.Load<CrmSettings>();
|
||||
|
||||
_userDbContext = dbUserContextManager.Get(CrmConstants.DatabaseId);
|
||||
|
||||
_defaultCurrency = currencyProvider.Get(crmSettings.DefaultCurrency);
|
||||
|
||||
_displayUserSettings = displayUserSettingsHelper;
|
||||
@ -313,7 +309,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
var file = _daoFactory.GetFileDao().SaveFile(document, stream);
|
||||
|
||||
SaveFile((int)file.ID, -1);
|
||||
SaveFile(file.ID, -1);
|
||||
|
||||
result.Add(file);
|
||||
}
|
||||
|
@ -52,10 +52,12 @@ namespace ASC.CRM.Core.Dao
|
||||
[Scope]
|
||||
public class TaskDao : AbstractDao
|
||||
{
|
||||
private readonly UserDbContext _userDbContext;
|
||||
private readonly FactoryIndexerTask _factoryIndexer;
|
||||
private readonly TenantUtil _tenantUtil;
|
||||
private readonly CrmSecurity _crmSecurity;
|
||||
|
||||
private Lazy<UserDbContext> LazyUserDbContext { get; }
|
||||
private UserDbContext _userDbContext { get => LazyUserDbContext.Value; }
|
||||
|
||||
public TaskDao(DbContextManager<CrmDbContext> dbContextManager,
|
||||
TenantManager tenantManager,
|
||||
@ -77,7 +79,7 @@ namespace ASC.CRM.Core.Dao
|
||||
_crmSecurity = crmSecurity;
|
||||
_tenantUtil = tenantUtil;
|
||||
_factoryIndexer = factoryIndexer;
|
||||
_userDbContext = userDbContext.Value;
|
||||
LazyUserDbContext = new Lazy<UserDbContext>(() => userDbContext.Value);
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
@ -510,7 +512,7 @@ namespace ASC.CRM.Core.Dao
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromMinutes(1));
|
||||
_cache.Insert(cacheKey, result.ToString(), TimeSpan.FromMinutes(1));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -27,10 +27,13 @@
|
||||
using System;
|
||||
|
||||
using ASC.Common.Mapping;
|
||||
using ASC.CRM.ApiModels;
|
||||
using ASC.CRM.Classes;
|
||||
using ASC.CRM.Core.EF;
|
||||
using ASC.CRM.Core.Enums;
|
||||
|
||||
using AutoMapper;
|
||||
|
||||
namespace ASC.CRM.Core
|
||||
{
|
||||
public class ContactInfo : DomainObject, IMapFrom<DbContactInfo>
|
||||
@ -78,5 +81,12 @@ namespace ASC.CRM.Core
|
||||
return typeof(ContactInfoBaseCategory);
|
||||
}
|
||||
}
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbContactInfo, ContactInfo>()
|
||||
.ForMember(x => x.InfoType, opt => opt.MapFrom(x => x.Type));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/calendar",
|
||||
"version": "0.1.10",
|
||||
"version": "1.0.0",
|
||||
"homepage": "/products/calendar",
|
||||
"id": "32d24cb5-7ece-4606-9c94-19216ba42086",
|
||||
"title": "ONLYOFFICE",
|
||||
@ -24,6 +24,7 @@
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"external-remotes-plugin": "^1.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"json-loader": "^0.5.7",
|
||||
@ -35,8 +36,7 @@
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"webpack": "5.14.0",
|
||||
"webpack-cli": "4.5.0",
|
||||
"webpack-dev-server": "3.11.2",
|
||||
"workbox-webpack-plugin": "^6.1.1"
|
||||
"webpack-dev-server": "3.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
|
@ -1,9 +1,8 @@
|
||||
import App from "./App";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import config from "../package.json";
|
||||
import { registerSW } from "@appserver/common/utils/sw-helper";
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
|
||||
registerSW(config.homepage);
|
||||
registerSW();
|
||||
|
@ -3,8 +3,8 @@ const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const ExternalTemplateRemotesPlugin = require("external-remotes-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const { InjectManifest } = require("workbox-webpack-plugin");
|
||||
const combineUrl = require("@appserver/common/utils/combineUrl");
|
||||
const AppServerConfig = require("@appserver/common/constants/AppServerConfig");
|
||||
|
||||
@ -91,17 +91,6 @@ var config = {
|
||||
],
|
||||
},
|
||||
{ test: /\.json$/, loader: "json-loader" },
|
||||
{
|
||||
test: /\.(woff(2)?)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
name: "fonts/[hash].[ext]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ["style-loader", "css-loader"],
|
||||
@ -165,6 +154,7 @@ var config = {
|
||||
},
|
||||
},
|
||||
}),
|
||||
new ExternalTemplateRemotesPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
@ -194,14 +184,6 @@ module.exports = (env, argv) => {
|
||||
minimize: true,
|
||||
minimizer: [new TerserPlugin()],
|
||||
};
|
||||
config.plugins.push(
|
||||
new InjectManifest({
|
||||
mode: "production", //"development",
|
||||
swSrc: "@appserver/common/utils/sw-template.js", // this is your sw template file
|
||||
swDest: "sw.js", // this will be created in the build step
|
||||
exclude: [/\.map$/, /manifest$/, /service-worker\.js$/],
|
||||
})
|
||||
);
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
232
products/ASC.Calendar/Server/.gitignore
vendored
Normal file
232
products/ASC.Calendar/Server/.gitignore
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
bin/
|
||||
Bin/
|
||||
obj/
|
||||
Obj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
/wwwroot/dist/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
/node_modules
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
@ -6,25 +6,56 @@
|
||||
<GenerateMvcApplicationPartsAssemblyAttributes>false</GenerateMvcApplicationPartsAssemblyAttributes>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<NoWarn>1701;1702;NU1701</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ical.Net" Version="4.1.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.5" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Data.Reassigns\ASC.Data.Reassigns.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.MessagingSystem\ASC.MessagingSystem.csproj" />
|
||||
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{7BCED72B-1DDE-4732-8EB3-2CF7002D7305}" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Resources\CalendarAddonResource.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>CalendarAddonResource.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Resources\CalendarResource.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>CalendarResource.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\CalendarResource.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>CalendarResource.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\CalendarResource.ru.resx">
|
||||
<DependentUpon>CalendarResource.resx</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\CalendarAddonResource.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>CalendarAddonResource.Designer.cs</LastGenOutput>
|
||||
@ -45,5 +76,8 @@
|
||||
<DependentUpon>CalendarAddonResource.resx</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Core\Dao\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
42
products/ASC.Calendar/Server/AccessRights.cs
Normal file
42
products/ASC.Calendar/Server/AccessRights.cs
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Action = ASC.Common.Security.Authorizing.Action;
|
||||
|
||||
namespace ASC.Calendar
|
||||
{
|
||||
public class CalendarAccessRights
|
||||
{
|
||||
public static readonly Action FullAccessAction = new Action(
|
||||
new Guid("{0d68b142-e20a-446e-a832-0d6b0b65a164}"),
|
||||
"Full Access", false, false);
|
||||
|
||||
}
|
||||
}
|
242
products/ASC.Calendar/Server/BusinessObjects/Calendar.cs
Normal file
242
products/ASC.Calendar/Server/BusinessObjects/Calendar.cs
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using ASC.Core;
|
||||
using ASC.Api.Core;
|
||||
using ASC.Common.Security;
|
||||
using ASC.Common.Security.Authorizing;
|
||||
using ASC.Web.Core.Calendars;
|
||||
using ASC.Calendar.Models;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using ASC.Calendar.iCalParser;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
namespace ASC.Calendar.BusinessObjects
|
||||
{
|
||||
|
||||
public static class CalendarExtention
|
||||
{
|
||||
public static bool IsiCalStream(this BaseCalendar calendar)
|
||||
{
|
||||
return (calendar is BusinessObjects.Calendar && !String.IsNullOrEmpty((calendar as BusinessObjects.Calendar).iCalUrl));
|
||||
}
|
||||
public static bool IsExistTodo(this BaseCalendar calendar)
|
||||
{
|
||||
return (calendar is BusinessObjects.Calendar && (calendar as BusinessObjects.Calendar).IsTodo != 0);
|
||||
}
|
||||
|
||||
public static BaseCalendar GetUserCalendar(this BaseCalendar calendar, UserViewSettings userViewSettings)
|
||||
{
|
||||
var cal = (BaseCalendar)calendar.Clone();
|
||||
|
||||
if (userViewSettings == null)
|
||||
return cal;
|
||||
|
||||
//name
|
||||
if (!String.IsNullOrEmpty(userViewSettings.Name))
|
||||
cal.Name = userViewSettings.Name;
|
||||
|
||||
//backgroundColor
|
||||
if (!String.IsNullOrEmpty(userViewSettings.BackgroundColor))
|
||||
cal.Context.HtmlBackgroundColor = userViewSettings.BackgroundColor;
|
||||
|
||||
//textColor
|
||||
if (!String.IsNullOrEmpty(userViewSettings.TextColor))
|
||||
cal.Context.HtmlTextColor = userViewSettings.TextColor;
|
||||
|
||||
//TimeZoneInfo
|
||||
if (userViewSettings.TimeZone != null)
|
||||
cal.TimeZone = userViewSettings.TimeZone;
|
||||
|
||||
//alert type
|
||||
cal.EventAlertType = userViewSettings.EventAlertType;
|
||||
|
||||
return cal;
|
||||
}
|
||||
|
||||
public static List<EventWrapper> GetEventWrappers(this BaseCalendar calendar, Guid userId, ApiDateTime startDate, ApiDateTime endDate, EventWrapperHelper eventWrapperHelper)
|
||||
{new List<EventWrapper>();
|
||||
var result = new List<EventWrapper>();
|
||||
if (calendar != null)
|
||||
{
|
||||
var events = calendar.LoadEvents(userId, startDate.UtcTime, endDate.UtcTime);
|
||||
foreach (var e in events)
|
||||
{
|
||||
var wrapper = eventWrapperHelper.Get(e, userId, calendar.TimeZone);
|
||||
var listWrapper = eventWrapperHelper.GetList(startDate.UtcTime, endDate.UtcTime, userId, e);
|
||||
result.AddRange(listWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public static List<TodoWrapper> GetTodoWrappers(this BaseCalendar calendar, Guid userId, ApiDateTime startDate, ApiDateTime endDate, TodoWrapperHelper todoWrapperHelper)
|
||||
{
|
||||
var result = new List<TodoWrapper>();
|
||||
if (calendar != null)
|
||||
{
|
||||
var events = calendar.LoadTodos(userId, startDate.UtcTime, endDate.UtcTime);
|
||||
foreach (var e in events)
|
||||
{
|
||||
var wrapper = todoWrapperHelper.Get(e, userId, calendar.TimeZone);
|
||||
result.Add(wrapper);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DataContract(Name = "calendar", Namespace = "")]
|
||||
public class Calendar : BaseCalendar, ISecurityObject
|
||||
{
|
||||
public static string DefaultTextColor { get { return "#000000"; } }
|
||||
public static string DefaultBackgroundColor { get { return "#9bb845"; } }
|
||||
public static string DefaultTodoBackgroundColor { get { return "#ffb45e"; } }
|
||||
|
||||
public iCalendar ICalendar { get; }
|
||||
public DataProvider DataProvider { get; }
|
||||
|
||||
|
||||
public Calendar(
|
||||
AuthContext context,
|
||||
TimeZoneConverter timeZoneConverter,
|
||||
iCalendar iCalendar,
|
||||
DataProvider dataProvider)
|
||||
: base(context, timeZoneConverter)
|
||||
{
|
||||
ICalendar = iCalendar;
|
||||
DataProvider = dataProvider;
|
||||
this.ViewSettings = new List<UserViewSettings>();
|
||||
this.Context.CanChangeAlertType = true;
|
||||
this.Context.CanChangeTimeZone = true;
|
||||
}
|
||||
|
||||
public int TenantId { get; set; }
|
||||
|
||||
public List<UserViewSettings> ViewSettings { get; set; }
|
||||
|
||||
public string iCalUrl { get; set; }
|
||||
|
||||
public string calDavGuid { get; set; }
|
||||
|
||||
public int IsTodo { get; set; }
|
||||
|
||||
#region ISecurityObjectId Members
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object SecurityId
|
||||
{
|
||||
get { return this.Id; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Type ObjectType
|
||||
{
|
||||
get { return typeof(Calendar); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISecurityObjectProvider Members
|
||||
|
||||
public IEnumerable<ASC.Common.Security.Authorizing.IRole> GetObjectRoles(ASC.Common.Security.Authorizing.ISubject account, ISecurityObjectId objectId, SecurityCallContext callContext)
|
||||
{
|
||||
List<IRole> roles = new List<IRole>();
|
||||
if (account.ID.Equals(this.OwnerId))
|
||||
roles.Add(ASC.Common.Security.Authorizing.Constants.Owner);
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public ISecurityObjectId InheritFrom(ISecurityObjectId objectId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool InheritSupported
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool ObjectRolesSupported
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override List<IEvent> LoadEvents(Guid userId, DateTime utcStartDate, DateTime utcEndDate)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(iCalUrl))
|
||||
{
|
||||
try
|
||||
{
|
||||
var cal = ICalendar.GetFromUrl(iCalUrl, this.Id);
|
||||
return cal.LoadEvents(userId, utcStartDate, utcEndDate);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<IEvent>();
|
||||
}
|
||||
}
|
||||
|
||||
return DataProvider.LoadEvents(Convert.ToInt32(this.Id), userId, TenantId, utcStartDate, utcEndDate)
|
||||
.Cast<IEvent>()
|
||||
.ToList();
|
||||
|
||||
}
|
||||
|
||||
public override List<ITodo> LoadTodos(Guid userId, DateTime utcStartDate, DateTime utcEndDate)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(iCalUrl))
|
||||
{
|
||||
try
|
||||
{
|
||||
var cal = ICalendar.GetFromUrl(iCalUrl, this.Id);
|
||||
return cal.LoadTodos(userId, utcStartDate, utcEndDate);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<ITodo>();
|
||||
}
|
||||
}
|
||||
|
||||
return DataProvider.LoadTodos(Convert.ToInt32(this.Id), userId, TenantId, utcStartDate, utcEndDate)
|
||||
.Cast<ITodo>()
|
||||
.ToList();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
1945
products/ASC.Calendar/Server/BusinessObjects/DataProvider.cs
Normal file
1945
products/ASC.Calendar/Server/BusinessObjects/DataProvider.cs
Normal file
File diff suppressed because it is too large
Load Diff
112
products/ASC.Calendar/Server/BusinessObjects/Event.cs
Normal file
112
products/ASC.Calendar/Server/BusinessObjects/Event.cs
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using ASC.Common.Security;
|
||||
using ASC.Common.Security.Authorizing;
|
||||
using ASC.Calendar.Models;
|
||||
using ASC.Web.Core.Calendars;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Core;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Calendar.iCalParser;
|
||||
|
||||
namespace ASC.Calendar.BusinessObjects
|
||||
{
|
||||
|
||||
[AllDayLongUTCAttribute]
|
||||
public class Event : BaseEvent, ISecurityObject
|
||||
{
|
||||
private AuthContext AuthContext { get; }
|
||||
private TimeZoneConverter TimeZoneConverter { get; }
|
||||
private iCalendar ICalendar { get; }
|
||||
private DataProvider DataProvider { get; }
|
||||
|
||||
public Event(AuthContext context,
|
||||
TimeZoneConverter timeZoneConverter,
|
||||
iCalendar iCalendar,
|
||||
DataProvider dataProvider)
|
||||
{
|
||||
AuthContext = context;
|
||||
ICalendar = iCalendar;
|
||||
TimeZoneConverter = timeZoneConverter;
|
||||
DataProvider = dataProvider;
|
||||
}
|
||||
|
||||
public int TenantId { get; set; }
|
||||
|
||||
#region ISecurityObjectId Members
|
||||
|
||||
public object SecurityId
|
||||
{
|
||||
get { return this.Id; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Type ObjectType
|
||||
{
|
||||
get { return typeof(Event); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISecurityObjectProvider Members
|
||||
|
||||
public IEnumerable<ASC.Common.Security.Authorizing.IRole> GetObjectRoles(ASC.Common.Security.Authorizing.ISubject account, ISecurityObjectId objectId, SecurityCallContext callContext)
|
||||
{
|
||||
List<IRole> roles = new List<IRole>();
|
||||
if (account.ID.Equals(this.OwnerId))
|
||||
roles.Add(ASC.Common.Security.Authorizing.Constants.Owner);
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public ISecurityObjectId InheritFrom(ISecurityObjectId objectId)
|
||||
{
|
||||
int calId;
|
||||
if (int.TryParse(this.CalendarId, out calId))
|
||||
return new Calendar(AuthContext, TimeZoneConverter, ICalendar, DataProvider) { Id = this.CalendarId };
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool InheritSupported
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool ObjectRolesSupported
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
213
products/ASC.Calendar/Server/BusinessObjects/EventHistory.cs
Normal file
213
products/ASC.Calendar/Server/BusinessObjects/EventHistory.cs
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
|
||||
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
|
||||
*
|
||||
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ASC.Calendar.iCalParser;
|
||||
using ASC.Common;
|
||||
|
||||
namespace ASC.Calendar.BusinessObjects
|
||||
{
|
||||
[Scope]
|
||||
public class EventHistory
|
||||
{
|
||||
|
||||
public int CalendarId { get; set; }
|
||||
public string EventUid { get; set; }
|
||||
public int EventId { get; set; }
|
||||
public string Ics { get; set; }
|
||||
|
||||
public List<Ical.Net.Calendar> History { get; set; }
|
||||
}
|
||||
|
||||
[Scope]
|
||||
public class EventHistoryHelper
|
||||
{
|
||||
public DDayICalParser DDayICalParser { get; }
|
||||
public EventHistoryHelper(
|
||||
DDayICalParser dDayICalParser)
|
||||
{
|
||||
DDayICalParser = dDayICalParser;
|
||||
}
|
||||
|
||||
public EventHistory Get(int calendarId, string eventUid, int eventId, string ics)
|
||||
{
|
||||
var eventHistory = new EventHistory();
|
||||
|
||||
eventHistory.CalendarId = calendarId;
|
||||
eventHistory.EventUid = eventUid;
|
||||
eventHistory.EventId = eventId;
|
||||
eventHistory.Ics = ics;
|
||||
|
||||
var history = DDayICalParser.DeserializeCalendar(ics);
|
||||
|
||||
eventHistory.History = history == null ? new List<Ical.Net.Calendar>() : history.ToList();
|
||||
|
||||
return eventHistory;
|
||||
}
|
||||
|
||||
public bool Contains(Ical.Net.Calendar calendar, EventHistory eventHistory)
|
||||
{
|
||||
if (!eventHistory.History.Any() || calendar == null || calendar.Events == null || calendar.Events.FirstOrDefault() == null)
|
||||
return false;
|
||||
|
||||
var eventObj = calendar.Events.First();
|
||||
|
||||
var isExist = eventHistory.History
|
||||
.Where(x => x.Method == calendar.Method)
|
||||
.Select(x => x.Events.First())
|
||||
.Any(x => x.Sequence == eventObj.Sequence && DDayICalParser.ToUtc(x.DtStamp) == DDayICalParser.ToUtc(eventObj.DtStamp));
|
||||
|
||||
return isExist;
|
||||
}
|
||||
|
||||
public Ical.Net.Calendar GetMerged(EventHistory eventHistory)
|
||||
{
|
||||
if (!eventHistory.History.Any()) return null;
|
||||
|
||||
var allCalendars = eventHistory.History
|
||||
.Where(x => x != null && x.Events != null && x.Events.FirstOrDefault() != null)
|
||||
.ToList();
|
||||
|
||||
if (!allCalendars.Any()) return null;
|
||||
|
||||
var recurrenceIdCalendars = new List<Ical.Net.Calendar>();
|
||||
var calendars = new List<Ical.Net.Calendar>();
|
||||
|
||||
foreach (var cal in allCalendars)
|
||||
{
|
||||
if (cal.Events.First().RecurrenceId == null)
|
||||
calendars.Add(cal);
|
||||
else
|
||||
recurrenceIdCalendars.Add(cal);
|
||||
}
|
||||
|
||||
recurrenceIdCalendars = recurrenceIdCalendars
|
||||
.OrderByDescending(x => x.Events.First().DtStamp)
|
||||
.ToList();
|
||||
|
||||
if (!calendars.Any())
|
||||
{
|
||||
return recurrenceIdCalendars.FirstOrDefault(x => x.Method != Ical.Net.CalendarMethods.Reply) ?? recurrenceIdCalendars.First();
|
||||
}
|
||||
|
||||
recurrenceIdCalendars = recurrenceIdCalendars
|
||||
.Where(x => x.Method == Ical.Net.CalendarMethods.Cancel)
|
||||
.ToList();
|
||||
|
||||
var sequence = calendars
|
||||
.Select(x => x.Events.First())
|
||||
.Max(x => x.Sequence);
|
||||
|
||||
calendars = calendars
|
||||
.Where(x => x.Events.First().Sequence == sequence)
|
||||
.OrderByDescending(x => x.Events.First().DtStamp)
|
||||
.ToList();
|
||||
|
||||
var targetCalendar = calendars.FirstOrDefault(x => x.Method != Ical.Net.CalendarMethods.Reply) ?? calendars.First();
|
||||
|
||||
if (targetCalendar == null) return null;
|
||||
|
||||
var targetEvent = targetCalendar.Events.First();
|
||||
|
||||
if (targetCalendar.Method == Ical.Net.CalendarMethods.Cancel)
|
||||
targetEvent.Status = Ical.Net.EventStatus.Cancelled;
|
||||
|
||||
calendars = calendars
|
||||
.Where(x => x.Method == Ical.Net.CalendarMethods.Reply)
|
||||
.OrderBy(x => x.Events.First().DtStamp)
|
||||
.ToList();
|
||||
|
||||
foreach (var calendar in calendars)
|
||||
{
|
||||
var tmpEvent = calendar.Events.First();
|
||||
|
||||
foreach (var tmpAttendee in tmpEvent.Attendees)
|
||||
{
|
||||
var exist = false;
|
||||
|
||||
foreach (var targetAttendee in targetEvent.Attendees)
|
||||
{
|
||||
if (!targetAttendee.Value.OriginalString.Equals(tmpAttendee.Value.OriginalString, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
var parameters = new Ical.Net.ParameterList();
|
||||
|
||||
foreach (var param in targetAttendee.Parameters)
|
||||
{
|
||||
switch (param.Group)
|
||||
{
|
||||
case "PARTSTAT":
|
||||
parameters.Add(new Ical.Net.CalendarParameter(param.Group, tmpAttendee.ParticipationStatus));
|
||||
break;
|
||||
case "RSVP":
|
||||
parameters.Add(new Ical.Net.CalendarParameter(param.Group, tmpAttendee.Rsvp.ToString().ToUpper()));
|
||||
break;
|
||||
default:
|
||||
parameters.Add(param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
targetAttendee.Parameters.Clear();
|
||||
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
targetAttendee.Parameters.Add(param);
|
||||
}
|
||||
|
||||
targetAttendee.ParticipationStatus = tmpAttendee.ParticipationStatus;
|
||||
targetAttendee.Rsvp = tmpAttendee.Rsvp;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!exist)
|
||||
targetEvent.Attendees.Add(tmpAttendee);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var recurrenceIdCalendar in recurrenceIdCalendars)
|
||||
{
|
||||
var removedEvent = recurrenceIdCalendar.Events.First();
|
||||
|
||||
if (targetEvent.ExceptionDates.All(x => !x.First().Contains(removedEvent.RecurrenceId)))
|
||||
{
|
||||
targetEvent.ExceptionDates.Add(new Ical.Net.DataTypes.PeriodList
|
||||
{
|
||||
removedEvent.RecurrenceId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
targetCalendar.Events.Clear();
|
||||
targetCalendar.Events.Add(targetEvent);
|
||||
|
||||
return targetCalendar;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user