diff --git a/build/install/docker/Dockerfile.dev b/build/install/docker/Dockerfile.dev
index 63fdf1c20f..365c287085 100644
--- a/build/install/docker/Dockerfile.dev
+++ b/build/install/docker/Dockerfile.dev
@@ -150,7 +150,7 @@ RUN dos2unix /docker-entrypoint.d/prepare-nginx-proxy.sh && \
RUN chown nginx:nginx /etc/nginx/* -R && \
chown nginx:nginx /docker-entrypoint.d/* && \
# changes for upstream configure
- # sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
+ sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5012/$service_backup/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5007/$service_files/' /etc/nginx/conf.d/onlyoffice.conf && \
sed -i 's/127.0.0.1:5004/$service_people_server/' /etc/nginx/conf.d/onlyoffice.conf && \
@@ -175,13 +175,13 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.B
CMD ["ASC.Data.Backup.BackgroundTasks.dll", "ASC.Data.Backup.BackgroundTasks"]
# ASC.ApiSystem ##
-# FROM dotnetrun AS api_system
-# WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
+FROM dotnetrun AS api_system
+WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
-# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
-# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
+COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
+COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
-# CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
+CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
## ASC.ClearEvents ##
FROM dotnetrun AS clear-events
diff --git a/build/install/docker/build.dev.yml b/build/install/docker/build.dev.yml
index 34b3811d7b..6a3fc51d5e 100644
--- a/build/install/docker/build.dev.yml
+++ b/build/install/docker/build.dev.yml
@@ -92,12 +92,12 @@ services:
target: api
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
- # onlyoffice-api-system:
- # build:
- # context: ./
- # dockerfile: "${DOCKERFILE}"
- # target: api_system
- # image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
+ onlyoffice-api-system:
+ build:
+ context: ./
+ dockerfile: "${DOCKERFILE}"
+ target: api_system
+ image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
onlyoffice-studio:
build:
diff --git a/build/install/docker/docspace.dev.yml b/build/install/docker/docspace.dev.yml
index e8a89e3988..1b69434a79 100644
--- a/build/install/docker/docspace.dev.yml
+++ b/build/install/docker/docspace.dev.yml
@@ -116,10 +116,10 @@ services:
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
container_name: ${API_HOST}
- # onlyoffice-api-system:
- # <<: *x-service-base
- # image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
- # container_name: ${API_SYSTEM_HOST}
+ onlyoffice-api-system:
+ <<: *x-service-base
+ image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
+ container_name: ${API_SYSTEM_HOST}
onlyoffice-studio:
<<: *x-service-base
@@ -163,7 +163,7 @@ services:
# - onlyoffice-telegram-service
# - onlyoffice-urlshortener
- onlyoffice-api
- # - onlyoffice-api-system
+ - onlyoffice-api-system
- onlyoffice-studio
- onlyoffice-ssoauth
environment:
diff --git a/packages/client/src/pages/Confirm/index.js b/packages/client/src/pages/Confirm/index.js
index ecc4ce66bf..0e35bb6209 100644
--- a/packages/client/src/pages/Confirm/index.js
+++ b/packages/client/src/pages/Confirm/index.js
@@ -20,6 +20,7 @@ const DeactivatePortal = lazy(() =>
import("./sub-components/deactivatePortal")
);
const ContinuePortal = lazy(() => import("./sub-components/continuePortal"));
+const Auth = lazy(() => import("./sub-components/auth"));
const Confirm = ({ match }) => {
//console.log("Confirm render");
@@ -88,6 +89,7 @@ const Confirm = ({ match }) => {
path={`${path}/PortalContinue`}
component={ContinuePortal}
/>
+
{/* */}
diff --git a/packages/client/src/pages/Confirm/sub-components/auth.js b/packages/client/src/pages/Confirm/sub-components/auth.js
new file mode 100644
index 0000000000..7a8385d78c
--- /dev/null
+++ b/packages/client/src/pages/Confirm/sub-components/auth.js
@@ -0,0 +1,38 @@
+import React, { useEffect } from "react";
+import { withRouter } from "react-router";
+import Loader from "@docspace/components/loader";
+import Section from "@docspace/common/components/Section";
+import { loginWithConfirmKey } from "@docspace/common/api/user";
+import toastr from "@docspace/components/toast/toastr";
+
+const Auth = (props) => {
+ console.log("Auth render");
+ const { linkData } = props;
+
+ useEffect(() => {
+ loginWithConfirmKey({
+ ConfirmData: {
+ Email: linkData.email,
+ Key: linkData.confirmHeader,
+ },
+ })
+ .then((res) => {
+ console.log("Login with confirm key success", res);
+ if (typeof res === "string") window.location.replace(res);
+ else window.location.replace("/");
+ })
+ .catch((error) => toastr.error(error));
+ });
+
+ return ;
+};
+
+const AuthPage = (props) => (
+
+);
+
+export default withRouter(AuthPage);
diff --git a/packages/common/api/user/index.js b/packages/common/api/user/index.js
index 4aa6b18133..2da5b878b1 100644
--- a/packages/common/api/user/index.js
+++ b/packages/common/api/user/index.js
@@ -63,3 +63,12 @@ export function loginWithTfaCode(userName, passwordHash, code) {
data,
});
}
+
+export function loginWithConfirmKey(data) {
+ return request({
+ method: "post",
+ url: `/authentication.json`,
+ skipLogout: true,
+ data,
+ });
+}
diff --git a/web/ASC.Web.Api/Api/AuthenticationController.cs b/web/ASC.Web.Api/Api/AuthenticationController.cs
index 6b30e01119..6ad39bd2a5 100644
--- a/web/ASC.Web.Api/Api/AuthenticationController.cs
+++ b/web/ASC.Web.Api/Api/AuthenticationController.cs
@@ -42,7 +42,8 @@ public class AuthenticationController : ControllerBase
private readonly CookiesManager _cookiesManager;
private readonly PasswordHasher _passwordHasher;
private readonly EmailValidationKeyModelHelper _emailValidationKeyModelHelper;
- private readonly ICache _cache;
+ private readonly ICache _cache;
+ private readonly SetupInfo _setupInfo;
private readonly MessageService _messageService;
private readonly ProviderManager _providerManager;
private readonly AccountLinker _accountLinker;
@@ -66,7 +67,8 @@ public class AuthenticationController : ControllerBase
private readonly CookieStorage _cookieStorage;
private readonly DbLoginEventsManager _dbLoginEventsManager;
private readonly UserManagerWrapper _userManagerWrapper;
- private readonly TfaAppAuthSettingsHelper _tfaAppAuthSettingsHelper;
+ private readonly TfaAppAuthSettingsHelper _tfaAppAuthSettingsHelper;
+ private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
private readonly BruteForceLoginManager _bruteForceLoginManager;
public AuthenticationController(
@@ -103,7 +105,8 @@ public class AuthenticationController : ControllerBase
CookieStorage cookieStorage,
DbLoginEventsManager dbLoginEventsManager,
BruteForceLoginManager bruteForceLoginManager,
- TfaAppAuthSettingsHelper tfaAppAuthSettingsHelper)
+ TfaAppAuthSettingsHelper tfaAppAuthSettingsHelper,
+ EmailValidationKeyProvider emailValidationKeyProvider)
{
_userManager = userManager;
_tenantManager = tenantManager;
@@ -112,7 +115,8 @@ public class AuthenticationController : ControllerBase
_cookiesManager = cookiesManager;
_passwordHasher = passwordHasher;
_emailValidationKeyModelHelper = emailValidationKeyModelHelper;
- _cache = cache;
+ _cache = cache;
+ _setupInfo = setupInfo;
_messageService = messageService;
_providerManager = providerManager;
_accountLinker = accountLinker;
@@ -137,7 +141,8 @@ public class AuthenticationController : ControllerBase
_dbLoginEventsManager = dbLoginEventsManager;
_userManagerWrapper = userManagerWrapper;
_bruteForceLoginManager = bruteForceLoginManager;
- _tfaAppAuthSettingsHelper = tfaAppAuthSettingsHelper;
+ _tfaAppAuthSettingsHelper = tfaAppAuthSettingsHelper;
+ _emailValidationKeyProvider = emailValidationKeyProvider;
}
[AllowNotPayment]
@@ -215,7 +220,12 @@ public class AuthenticationController : ControllerBase
{
var wrapper = await GetUser(inDto);
var viaEmail = wrapper.ViaEmail;
- var user = wrapper.UserInfo;
+ var user = wrapper.UserInfo;
+
+ if (user == null || Equals(user, Constants.LostUser))
+ {
+ throw new Exception(Resource.ErrorUserNotFound);
+ }
if (_studioSmsNotificationSettingsHelper.IsVisibleAndAvailableSettings() && _studioSmsNotificationSettingsHelper.TfaEnabledForUser(user.Id))
{
@@ -347,12 +357,34 @@ public class AuthenticationController : ControllerBase
var wrapper = new UserInfoWrapper
{
ViaEmail = true
- };
+ };
+
var action = MessageAction.LoginFailViaApi;
- UserInfo user;
+ UserInfo user = null;
+
try
- {
- if ((string.IsNullOrEmpty(inDto.Provider) && string.IsNullOrEmpty(inDto.SerializedProfile)) || inDto.Provider == "email")
+ {
+ if (inDto.ConfirmData != null)
+ {
+ var email = inDto.ConfirmData.Email;
+
+ var checkKeyResult = _emailValidationKeyProvider.ValidateEmailKey(email + ConfirmType.Auth + inDto.ConfirmData.First + inDto.ConfirmData.Module + inDto.ConfirmData.Sms, inDto.ConfirmData.Key, _setupInfo.ValidAuthKeyInterval);
+
+ if (checkKeyResult == ValidationResult.Ok)
+ {
+ user = email.Contains("@")
+ ? _userManager.GetUserByEmail(email)
+ : _userManager.GetUsers(new Guid(email));
+
+ if (_securityContext.IsAuthenticated && _securityContext.CurrentAccount.ID != user.Id)
+ {
+ _securityContext.Logout();
+ _cookiesManager.ClearCookies(CookiesType.AuthKey);
+ _cookiesManager.ClearCookies(CookiesType.SocketIO);
+ }
+ }
+ }
+ else if ((string.IsNullOrEmpty(inDto.Provider) && string.IsNullOrEmpty(inDto.SerializedProfile)) || inDto.Provider == "email")
{
inDto.UserName.ThrowIfNull(new ArgumentException(@"userName empty", "userName"));
if (!string.IsNullOrEmpty(inDto.Password))
diff --git a/web/ASC.Web.Api/ApiModels/RequestsDto/AuthRequestsDto.cs b/web/ASC.Web.Api/ApiModels/RequestsDto/AuthRequestsDto.cs
index 0c77cf38e4..c4c818cf0d 100644
--- a/web/ASC.Web.Api/ApiModels/RequestsDto/AuthRequestsDto.cs
+++ b/web/ASC.Web.Api/ApiModels/RequestsDto/AuthRequestsDto.cs
@@ -36,10 +36,21 @@ public class AuthRequestsDto
public string SerializedProfile { get; set; }
public string Code { get; set; }
public string CodeOAuth { get; set; }
- public bool Session { get; set; }
+ public bool Session { get; set; }
+
+ public ConfirmData ConfirmData { get; set; }
}
public class MobileRequestsDto
{
public string MobilePhone { get; set; }
+}
+
+public class ConfirmData
+{
+ public string Email { get; set; }
+ public string Module { get; set; }
+ public bool? First { get; set; }
+ public bool? Sms { get; set; }
+ public string Key { get; set; }
}