Client:Pages:Confirm:delete old pages
This commit is contained in:
parent
5431148168
commit
e5d2d8ede3
@ -1,96 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { isIOS, isFirefox, isMobileOnly } from "react-device-detect";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { getBgPattern } from "@docspace/shared/utils/common";
|
||||
import { mobile } from "@docspace/shared/utils";
|
||||
import { Scrollbar } from "@docspace/shared/components/scrollbar";
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
height: ${(props) =>
|
||||
props.height
|
||||
? props.height
|
||||
: isIOS && !isFirefox
|
||||
? "calc(var(--vh, 1vh) * 100)"
|
||||
: "100vh"};
|
||||
width: 100vw;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
|
||||
@media ${mobile} {
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const BgBlock = styled.div`
|
||||
background-image: ${(props) => props.bgPattern};
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
|
||||
@media ${mobile} {
|
||||
background-image: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const ConfirmWrapper = (props) => {
|
||||
const { children, currentColorScheme, height } = props;
|
||||
const bgPattern = getBgPattern(currentColorScheme?.id);
|
||||
const content = (
|
||||
<>
|
||||
<BgBlock bgPattern={bgPattern} />
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledWrapper height={height}>
|
||||
{!!height ? content : <Scrollbar>{content}</Scrollbar>}
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => {
|
||||
const { currentColorScheme } = settingsStore;
|
||||
|
||||
return {
|
||||
currentColorScheme,
|
||||
};
|
||||
})(observer(ConfirmWrapper));
|
@ -1,36 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
|
||||
const Confirm = () => {
|
||||
//console.log("Confirm render");
|
||||
|
||||
return <Outlet />;
|
||||
};
|
||||
|
||||
export default Confirm;
|
@ -1,83 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
|
||||
import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import ArrowIcon from "PUBLIC_DIR/images/arrow.left.react.svg?url";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const DEFAULT_CREATION_TEXT =
|
||||
"A {{productName}} account will be created for {{email}}. Please, complete your registration:";
|
||||
|
||||
const GreetingUserContainer = ({
|
||||
email,
|
||||
onClickBack,
|
||||
emailFromLink,
|
||||
type,
|
||||
defaultText,
|
||||
}) => {
|
||||
const { t } = useTranslation(["Confirm", "Common"]);
|
||||
|
||||
return (
|
||||
<div className="greeting-container">
|
||||
<div className="back-sign-in-container">
|
||||
{type === "LinkInvite" && !emailFromLink && (
|
||||
<div className="back-button">
|
||||
<IconButton size={16} iconName={ArrowIcon} onClick={onClickBack} />
|
||||
<Text fontWeight={600} onClick={onClickBack}>
|
||||
{t("Common:Back")}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Text fontWeight={600} fontSize={"16px"}>
|
||||
{t("SignUp")}
|
||||
</Text>
|
||||
</div>
|
||||
<Text>
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="AccountWillBeCreated"
|
||||
ns="Confirm"
|
||||
defaults={DEFAULT_CREATION_TEXT}
|
||||
values={{
|
||||
email,
|
||||
}}
|
||||
portalName={PRODUCT_NAME}
|
||||
components={{
|
||||
1: <ColorTheme tag="a" themeId={ThemeId.Link} isHovered={false} />,
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GreetingUserContainer;
|
@ -1,69 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { setLanguageForUnauthorized } from "@docspace/shared/utils/common";
|
||||
import { LanguageCombobox } from "@docspace/shared/components/language-combobox";
|
||||
import { TPortalCultures } from "@docspace/shared/api/settings/types";
|
||||
import { DeviceType } from "@docspace/shared/enums";
|
||||
|
||||
export interface TLanguageCombobox {
|
||||
cultures: TPortalCultures;
|
||||
currentDeviceType: string;
|
||||
currentCultureName: string;
|
||||
}
|
||||
|
||||
const LanguageComboboxWrapper = (props: TLanguageCombobox) => {
|
||||
const { cultures, currentCultureName, currentDeviceType } = props;
|
||||
|
||||
const onLanguageSelect = (culture: { key: string }) => {
|
||||
const { key } = culture;
|
||||
|
||||
setLanguageForUnauthorized(key);
|
||||
};
|
||||
|
||||
const isMobileView = currentDeviceType === DeviceType.mobile;
|
||||
|
||||
if (isMobileView) return <></>;
|
||||
|
||||
return (
|
||||
<LanguageCombobox
|
||||
className="language-combo-box"
|
||||
onSelectLanguage={onLanguageSelect}
|
||||
cultures={cultures}
|
||||
selectedCulture={currentCultureName}
|
||||
withBorder={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject<TStore>(({ settingsStore }) => {
|
||||
const { currentDeviceType } = settingsStore;
|
||||
|
||||
return {
|
||||
currentDeviceType,
|
||||
};
|
||||
})(observer(LanguageComboboxWrapper));
|
@ -1,170 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import styled from "styled-components";
|
||||
import {
|
||||
mobile,
|
||||
tablet,
|
||||
getCorrectFourValuesStyle,
|
||||
} from "@docspace/shared/utils";
|
||||
|
||||
export const StyledPage = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
max-width: 960px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@media ${tablet} {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
padding: ${({ theme }) =>
|
||||
getCorrectFourValuesStyle("32px 8px 0 16px", theme.interfaceDirection)};
|
||||
|
||||
.language-combo-box {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.password-form {
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.language-combo-box {
|
||||
position: absolute;
|
||||
right: 28px;
|
||||
top: 28px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledContent = styled.div`
|
||||
min-height: 100vh;
|
||||
flex: 1 0 auto;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
justify-content: start;
|
||||
min-height: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledHeader = styled.div`
|
||||
.title {
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.portal-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
margin-top: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledBody = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 56px auto;
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.portal-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.password-field-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.password-change-form {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.phone-input {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.delete-profile-confirm {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.phone-title {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ButtonsWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
`;
|
@ -1,176 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import styled, { css } from "styled-components";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { mobile, tablet } from "@docspace/shared/utils";
|
||||
|
||||
const DESKTOP_WIDTH = 384;
|
||||
const TABLET_WIDTH = 480;
|
||||
|
||||
export const StyledCreateUserContent = styled.div`
|
||||
margin: 88px auto;
|
||||
|
||||
@media ${mobile} {
|
||||
margin-top: 0px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const GreetingContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: left;
|
||||
height: 100%;
|
||||
width: ${DESKTOP_WIDTH}px;
|
||||
|
||||
margin-bottom: 32px;
|
||||
|
||||
@media ${tablet} {
|
||||
width: 100%;
|
||||
max-width: ${TABLET_WIDTH}px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
padding: 0 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.portal-logo {
|
||||
width: 100%;
|
||||
padding-bottom: 16px;
|
||||
height: 26.56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.injected-svg {
|
||||
height: 26.56px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const RegisterContainer = styled.div`
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.or-label {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
|
||||
.line {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
color: ${(props) => props.theme.invitePage.borderColor};;
|
||||
padding-top: 35px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.line:before,
|
||||
.line:after {
|
||||
content: "";
|
||||
flex-grow: 1;
|
||||
background: ${(props) => props.theme.invitePage.borderColor};
|
||||
height: 1px;
|
||||
font-size: 0px;
|
||||
line-height: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.auth-form-fields {
|
||||
width: 100%;
|
||||
|
||||
.password-field{
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.email-container{
|
||||
${(props) => props.registrationForm && "display:none"};
|
||||
}
|
||||
@media ${tablet} {
|
||||
width: 100%;
|
||||
}
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.password-field-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.greeting-container{
|
||||
margin-bottom: 32px;
|
||||
p{
|
||||
text-align: center;
|
||||
}
|
||||
.back-sign-in-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
margin-bottom: 16px;
|
||||
.back-button {
|
||||
position: absolute;
|
||||
max-width: 60px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
right: 0;
|
||||
`
|
||||
: css`
|
||||
left: 0;
|
||||
`};
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
svg {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl" &&
|
||||
" transform: rotate(180deg)"};
|
||||
}
|
||||
|
||||
p {
|
||||
color: ${(props) => props.theme.login.backTitle.color};
|
||||
}
|
||||
|
||||
p:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
@ -1,97 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import tryRedirectTo from "@docspace/shared/utils/tryRedirectTo";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { EmployeeActivationStatus } from "@docspace/shared/enums";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
|
||||
const ActivateEmail = ({ updateEmailActivationStatus, linkData }) => {
|
||||
const [email, uid, key] = [
|
||||
linkData.email,
|
||||
linkData.uid,
|
||||
linkData.confirmHeader,
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
updateEmailActivationStatus(EmployeeActivationStatus.Activated, uid, key)
|
||||
.then((res) => {
|
||||
tryRedirectTo(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/login?confirmedEmail=${email}`,
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
// console.log('activate email error', e);
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
|
||||
tryRedirectTo(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/login/error?message=${errorMessage}`,
|
||||
),
|
||||
);
|
||||
});
|
||||
}, [email, key, updateEmailActivationStatus, uid]);
|
||||
|
||||
// console.log('Activate email render');
|
||||
return <Loader className="pageLoader" type="rombs" size="40px" />;
|
||||
};
|
||||
|
||||
ActivateEmail.propTypes = {
|
||||
location: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const ActivateEmailForm = (props) => (
|
||||
<SectionWrapper>
|
||||
<Section.SectionBody>
|
||||
<ActivateEmail {...props} />
|
||||
</Section.SectionBody>
|
||||
</SectionWrapper>
|
||||
);
|
||||
|
||||
export default inject(({ userStore }) => {
|
||||
const { updateEmailActivationStatus } = userStore;
|
||||
return {
|
||||
updateEmailActivationStatus,
|
||||
};
|
||||
})(observer(ActivateEmailForm));
|
@ -1,302 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { EmployeeActivationStatus } from "@docspace/shared/enums";
|
||||
import {
|
||||
changePassword,
|
||||
updateActivationStatus,
|
||||
updateUser,
|
||||
} from "@docspace/shared/api/people";
|
||||
import { createPasswordHash } from "@docspace/shared/utils/common";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { getPasswordErrorMessage } from "@docspace/shared/utils/getPasswordErrorMessage";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
|
||||
import { StyledPage, StyledHeader } from "./StyledConfirm";
|
||||
import withLoader from "../withLoader";
|
||||
|
||||
import {
|
||||
GreetingContainer,
|
||||
RegisterContainer,
|
||||
StyledCreateUserContent,
|
||||
} from "./StyledCreateUser";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import GreetingUserContainer from "./GreetingUserContainer";
|
||||
|
||||
const ActivateUserForm = (props) => {
|
||||
const { t, settings, linkData, hashSettings, defaultPage, login } = props;
|
||||
|
||||
const emailFromLink = linkData?.email ? linkData.email : "";
|
||||
const [name, setName] = useState(linkData.firstname);
|
||||
const [nameValid, setNameValid] = useState(true);
|
||||
const [surName, setSurName] = useState(linkData.lastname);
|
||||
const [surNameValid, setSurNameValid] = useState(true);
|
||||
const [password, setPassword] = useState("");
|
||||
const [passwordValid, setPasswordValid] = useState(true);
|
||||
const [isPasswordErrorShow, setIsPasswordErrorShow] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const onChangeName = (e) => {
|
||||
setName(e.target.value);
|
||||
setNameValid(true);
|
||||
};
|
||||
|
||||
const onChangeSurName = (e) => {
|
||||
setSurName(e.target.value);
|
||||
setSurNameValid(true);
|
||||
};
|
||||
|
||||
const onChangePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
};
|
||||
|
||||
const onValidatePassword = (res) => {
|
||||
setPasswordValid(res);
|
||||
};
|
||||
|
||||
const onBlurPassword = () => {
|
||||
setIsPasswordErrorShow(true);
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
setIsLoading(true);
|
||||
if (!name.trim()) setNameValid(false);
|
||||
if (!surName.trim()) setSurNameValid(false);
|
||||
if (!password.trim()) {
|
||||
setPasswordValid(false);
|
||||
setIsPasswordErrorShow(true);
|
||||
}
|
||||
|
||||
if (!nameValid || !surNameValid || !password.trim() || !passwordValid) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const hash = createPasswordHash(password, hashSettings);
|
||||
|
||||
const loginData = {
|
||||
userName: linkData.email,
|
||||
passwordHash: hash,
|
||||
};
|
||||
|
||||
const personalData = {
|
||||
firstname: name,
|
||||
lastname: surName,
|
||||
};
|
||||
|
||||
try {
|
||||
await activateConfirmUser(
|
||||
personalData,
|
||||
loginData,
|
||||
linkData.confirmHeader,
|
||||
linkData.uid,
|
||||
EmployeeActivationStatus.Activated,
|
||||
);
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
window.location.replace(defaultPage);
|
||||
} catch (error) {
|
||||
//console.error(error);
|
||||
setIsLoading(false);
|
||||
toastr.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const activateConfirmUser = async (
|
||||
personalData,
|
||||
loginData,
|
||||
key,
|
||||
userId,
|
||||
activationStatus,
|
||||
) => {
|
||||
const changedData = {
|
||||
id: userId,
|
||||
FirstName: personalData.firstname,
|
||||
LastName: personalData.lastname,
|
||||
};
|
||||
|
||||
const { userName, passwordHash } = loginData;
|
||||
|
||||
const res1 = await changePassword(userId, loginData.passwordHash, key);
|
||||
const res2 = await updateActivationStatus(activationStatus, userId, key);
|
||||
const res3 = await login(userName, passwordHash);
|
||||
const res4 = await updateUser(changedData);
|
||||
};
|
||||
|
||||
const onKeyPress = (event) => {
|
||||
if (event.key === "Enter") {
|
||||
onSubmit();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledCreateUserContent>
|
||||
<StyledHeader>
|
||||
<GreetingContainer>
|
||||
<PortalLogo className="portal-logo" />
|
||||
</GreetingContainer>
|
||||
</StyledHeader>
|
||||
|
||||
<FormWrapper>
|
||||
<RegisterContainer>
|
||||
<form className="auth-form-container">
|
||||
<GreetingUserContainer
|
||||
emailFromLink={!!emailFromLink}
|
||||
email={emailFromLink}
|
||||
/>
|
||||
|
||||
<FieldContainer
|
||||
className="form-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={!nameValid}
|
||||
errorMessage={t("Common:RequiredField")}
|
||||
>
|
||||
<TextInput
|
||||
id="name"
|
||||
name="name"
|
||||
value={name}
|
||||
placeholder={t("Common:FirstName")}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={1}
|
||||
isAutoFocussed={true}
|
||||
autoComplete="given-name"
|
||||
onChange={onChangeName}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
|
||||
<FieldContainer
|
||||
className="form-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={!surNameValid}
|
||||
errorMessage={t("Common:RequiredField")}
|
||||
>
|
||||
<TextInput
|
||||
id="surname"
|
||||
name="surname"
|
||||
value={surName}
|
||||
placeholder={t("Common:LastName")}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={2}
|
||||
autoComplete="family-name"
|
||||
onChange={onChangeSurName}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
|
||||
<FieldContainer
|
||||
className="form-field password-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
errorMessage={`${t(
|
||||
"Common:PasswordLimitMessage",
|
||||
)}: ${getPasswordErrorMessage(t, settings)}`}
|
||||
>
|
||||
<PasswordInput
|
||||
className="confirm-input"
|
||||
simpleView={false}
|
||||
passwordSettings={settings}
|
||||
id="password"
|
||||
inputName="password"
|
||||
placeholder={t("Common:Password")}
|
||||
type="password"
|
||||
inputValue={password}
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={1}
|
||||
autoComplete="current-password"
|
||||
onChange={onChangePassword}
|
||||
onValidateInput={onValidatePassword}
|
||||
onBlur={onBlurPassword}
|
||||
onKeyDown={onKeyPress}
|
||||
tooltipPasswordTitle={`${t("Common:PasswordLimitMessage")}:`}
|
||||
tooltipPasswordLength={`${t("Common:PasswordMinimumLength")}: ${
|
||||
settings ? settings.minLength : 8
|
||||
}`}
|
||||
tooltipPasswordDigits={`${t("Common:PasswordLimitDigits")}`}
|
||||
tooltipPasswordCapital={`${t("Common:PasswordLimitUpperCase")}`}
|
||||
tooltipPasswordSpecial={`${t(
|
||||
"Common:PasswordLimitSpecialSymbols",
|
||||
)}`}
|
||||
generatePasswordTitle={t("Wizard:GeneratePassword")}
|
||||
// If need copy credentials use t("EmailAndPasswordCopiedToClipboard")
|
||||
/>
|
||||
</FieldContainer>
|
||||
|
||||
<Button
|
||||
scale
|
||||
className="confirm-button"
|
||||
primary
|
||||
size="medium"
|
||||
label={t("LoginRegistryButton")}
|
||||
tabIndex={5}
|
||||
onClick={onSubmit}
|
||||
isDisabled={isLoading}
|
||||
/>
|
||||
</form>
|
||||
</RegisterContainer>
|
||||
</FormWrapper>
|
||||
</StyledCreateUserContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ authStore, settingsStore }) => {
|
||||
const {
|
||||
greetingSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
passwordSettings,
|
||||
theme,
|
||||
} = settingsStore;
|
||||
|
||||
return {
|
||||
theme,
|
||||
settings: passwordSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
login: authStore.login,
|
||||
};
|
||||
})(
|
||||
withTranslation(["Confirm", "Common", "Wizard"])(
|
||||
withLoader(observer(ActivateUserForm)),
|
||||
),
|
||||
);
|
@ -1,84 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { loginWithConfirmKey } from "@docspace/shared/api/user";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { frameCallEvent } from "@docspace/shared/utils/common";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
const Auth = (props) => {
|
||||
//console.log("Auth render");
|
||||
const { linkData } = props;
|
||||
let [searchParams, setSearchParams] = useSearchParams();
|
||||
useEffect(() => {
|
||||
loginWithConfirmKey({
|
||||
ConfirmData: {
|
||||
Email: linkData.email,
|
||||
Key: linkData.key,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
//console.log("Login with confirm key success", res);
|
||||
frameCallEvent({ event: "onAuthSuccess" });
|
||||
|
||||
const url = searchParams.get("referenceUrl");
|
||||
|
||||
if (url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return window.location.replace(url);
|
||||
} catch {
|
||||
return window.location.replace(
|
||||
combineUrl(window.location.origin, url),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof res === "string") window.location.replace(res);
|
||||
else window.location.replace("/");
|
||||
})
|
||||
.catch((error) => {
|
||||
frameCallEvent({ event: "onAppError", data: error });
|
||||
toastr.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
return <Loader className="pageLoader" type="rombs" size="40px" />;
|
||||
};
|
||||
|
||||
const AuthPage = (props) => (
|
||||
<SectionWrapper>
|
||||
<Section.SectionBody>
|
||||
<Auth {...props} />
|
||||
</Section.SectionBody>
|
||||
</SectionWrapper>
|
||||
);
|
||||
|
||||
export default AuthPage;
|
@ -1,117 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import tryRedirectTo from "@docspace/shared/utils/tryRedirectTo";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
class ChangeEmail extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
const { changeEmail, isLoaded, linkData } = this.props;
|
||||
if (isLoaded) {
|
||||
const { email, uid, confirmHeader } = linkData;
|
||||
changeEmail(uid, email, confirmHeader)
|
||||
.then((res) => {
|
||||
console.log("change client email success", res);
|
||||
tryRedirectTo(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/profile?email_change=success`,
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
|
||||
console.log("change client email error", e);
|
||||
tryRedirectTo(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/error=${errorMessage}`,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { changeEmail, isLoaded, linkData, defaultPage } = this.props;
|
||||
if (isLoaded) {
|
||||
const { email, uid, confirmHeader } = linkData;
|
||||
changeEmail(uid, email, confirmHeader)
|
||||
.then((res) => {
|
||||
console.log("change client email success", res);
|
||||
tryRedirectTo(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/profile?email_change=success`,
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((e) => console.log("change client email error", e));
|
||||
} else {
|
||||
tryRedirectTo(defaultPage);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("Change email render");
|
||||
return <Loader className="pageLoader" type="rombs" size="40px" />;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeEmail.propTypes = {
|
||||
changeEmail: PropTypes.func.isRequired,
|
||||
};
|
||||
const ChangeEmailForm = (props) => (
|
||||
<SectionWrapper>
|
||||
<Section.SectionBody>
|
||||
<ChangeEmail {...props} />
|
||||
</Section.SectionBody>
|
||||
</SectionWrapper>
|
||||
);
|
||||
|
||||
export default inject(({ authStore, settingsStore, userStore }) => {
|
||||
const { isLoaded } = authStore;
|
||||
return {
|
||||
isLoaded,
|
||||
changeEmail: userStore.changeEmail,
|
||||
defaultPage: settingsStore.defaultPage,
|
||||
};
|
||||
})(observer(ChangeEmailForm));
|
@ -1,137 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
StyledPage,
|
||||
StyledBody,
|
||||
ButtonsWrapper,
|
||||
StyledContent,
|
||||
} from "./StyledConfirm";
|
||||
import withLoader from "../withLoader";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { ownerChange } from "@docspace/shared/api/settings";
|
||||
import { getUserFromConfirm } from "@docspace/shared/api/people";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const ChangeOwnerForm = (props) => {
|
||||
const { t, greetingTitle, linkData, history } = props;
|
||||
const [newOwner, setNewOwner] = useState("");
|
||||
const [isOwnerChanged, setIsOwnerChanged] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const ownerId = linkData.uid;
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const confirmKey = linkData.confirmHeader;
|
||||
const user = await getUserFromConfirm(ownerId, confirmKey);
|
||||
setNewOwner(user?.displayName);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const onChangeOwnerClick = async () => {
|
||||
try {
|
||||
await ownerChange(ownerId, linkData.confirmHeader);
|
||||
setIsOwnerChanged(true);
|
||||
setTimeout(() => (location.href = "/"), 10000);
|
||||
} catch (error) {
|
||||
toastr.error(e);
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const onCancelClick = () => {
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
{isOwnerChanged ? (
|
||||
<Text>
|
||||
{t("ConfirmOwnerPortalSuccessMessage", {
|
||||
productName: PRODUCT_NAME,
|
||||
})}
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<Text className="subtitle">
|
||||
{t("ConfirmOwnerPortalTitle", {
|
||||
newOwner: newOwner,
|
||||
productName: PRODUCT_NAME,
|
||||
})}
|
||||
</Text>
|
||||
<ButtonsWrapper>
|
||||
<Button
|
||||
primary
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:SaveButton")}
|
||||
tabIndex={2}
|
||||
isDisabled={false}
|
||||
onClick={onChangeOwnerClick}
|
||||
/>
|
||||
<Button
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:CancelButton")}
|
||||
tabIndex={2}
|
||||
isDisabled={false}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</ButtonsWrapper>
|
||||
</>
|
||||
)}
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
defaultPage: settingsStore.defaultPage,
|
||||
}))(
|
||||
withTranslation(["Confirm", "Common"])(withLoader(observer(ChangeOwnerForm))),
|
||||
);
|
@ -1,235 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
|
||||
import { createPasswordHash } from "@docspace/shared/utils/common";
|
||||
import { login } from "@docspace/shared/utils/loginUtils";
|
||||
import { getPasswordErrorMessage } from "@docspace/shared/utils/getPasswordErrorMessage";
|
||||
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import withLoader from "../withLoader";
|
||||
import { StyledPage, StyledBody, StyledContent } from "./StyledConfirm";
|
||||
|
||||
const ChangePasswordForm = (props) => {
|
||||
const {
|
||||
t,
|
||||
greetingTitle,
|
||||
settings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
changePassword,
|
||||
linkData,
|
||||
getSettings,
|
||||
history,
|
||||
} = props;
|
||||
|
||||
const [password, setPassword] = useState("");
|
||||
const [passwordValid, setPasswordValid] = useState(true);
|
||||
const [isPasswordErrorShow, setIsPasswordErrorShow] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hashSettings) getSettings(true);
|
||||
}, []);
|
||||
|
||||
const onChangePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
};
|
||||
|
||||
const onValidatePassword = (res) => {
|
||||
setPasswordValid(res);
|
||||
};
|
||||
|
||||
const onBlurPassword = () => {
|
||||
setIsPasswordErrorShow(true);
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!password.trim()) {
|
||||
setPasswordValid(false);
|
||||
setIsPasswordErrorShow(true);
|
||||
}
|
||||
if (!passwordValid || !password.trim()) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const hash = createPasswordHash(password, hashSettings);
|
||||
const { email, uid, confirmHeader } = linkData;
|
||||
await changePassword(uid, hash, confirmHeader);
|
||||
setIsLoading(false);
|
||||
toastr.success(t("ChangePasswordSuccess"));
|
||||
|
||||
login(email, hash).then((res) => {
|
||||
const isConfirm = typeof res === "string" && res.includes("confirm");
|
||||
const redirectPath = sessionStorage.getItem("referenceUrl");
|
||||
if (redirectPath && !isConfirm) {
|
||||
sessionStorage.removeItem("referenceUrl");
|
||||
window.location.href = redirectPath;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof res === "string") window.location.replace(res);
|
||||
else window.location.replace("/");
|
||||
});
|
||||
} catch (error) {
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
console.error(errorMessage);
|
||||
|
||||
if (errorMessage === "Invalid params") {
|
||||
toastr.error(t("Common:SomethingWentWrong"));
|
||||
} else {
|
||||
toastr.error(t(`${errorMessage}`));
|
||||
}
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyPress = (event) => {
|
||||
if (event.key === "Enter") {
|
||||
onSubmit();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
<div className="password-form">
|
||||
<Text fontSize="16px" fontWeight="600" className="subtitle">
|
||||
{t("PassworResetTitle")}
|
||||
</Text>
|
||||
<FieldContainer
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
errorMessage={`${t(
|
||||
"Common:PasswordLimitMessage",
|
||||
)}: ${getPasswordErrorMessage(t, settings)}`}
|
||||
>
|
||||
<PasswordInput
|
||||
simpleView={false}
|
||||
passwordSettings={settings}
|
||||
id="password"
|
||||
inputName="password"
|
||||
placeholder={t("Common:Password")}
|
||||
type="password"
|
||||
inputValue={password}
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
size="large"
|
||||
scale
|
||||
tabIndex={1}
|
||||
autoComplete="current-password"
|
||||
onChange={onChangePassword}
|
||||
onValidateInput={onValidatePassword}
|
||||
onBlur={onBlurPassword}
|
||||
onKeyDown={onKeyPress}
|
||||
tooltipPasswordTitle={`${t("Common:PasswordLimitMessage")}:`}
|
||||
tooltipPasswordLength={`${t(
|
||||
"Common:PasswordMinimumLength",
|
||||
)}: ${settings ? settings.minLength : 8}`}
|
||||
tooltipPasswordDigits={`${t("Common:PasswordLimitDigits")}`}
|
||||
tooltipPasswordCapital={`${t(
|
||||
"Common:PasswordLimitUpperCase",
|
||||
)}`}
|
||||
tooltipPasswordSpecial={`${t(
|
||||
"Common:PasswordLimitSpecialSymbols",
|
||||
)}`}
|
||||
generatePasswordTitle={t("Wizard:GeneratePassword")}
|
||||
/>
|
||||
</FieldContainer>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
primary
|
||||
size="medium"
|
||||
scale
|
||||
label={t("Common:Create")}
|
||||
tabIndex={5}
|
||||
onClick={onSubmit}
|
||||
isDisabled={isLoading}
|
||||
/>
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ authStore, settingsStore, setup }) => {
|
||||
const {
|
||||
greetingSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
passwordSettings,
|
||||
theme,
|
||||
getSettings,
|
||||
} = settingsStore;
|
||||
const { changePassword } = setup;
|
||||
|
||||
return {
|
||||
theme,
|
||||
settings: passwordSettings,
|
||||
greetingTitle: greetingSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
changePassword,
|
||||
isAuthenticated: authStore.isAuthenticated,
|
||||
getSettings,
|
||||
};
|
||||
})(
|
||||
withTranslation(["Confirm", "Common", "Wizard"])(
|
||||
withLoader(observer(ChangePasswordForm)),
|
||||
),
|
||||
);
|
@ -1,94 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { StyledPage, StyledBody, StyledContent } from "./StyledConfirm";
|
||||
import withLoader from "../withLoader";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const ChangePhoneForm = (props) => {
|
||||
const { t, greetingTitle } = props;
|
||||
const [currentNumber, setCurrentNumber] = useState("+00000000000");
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
<div className="subtitle">
|
||||
<Text fontSize="16px" fontWeight="600" className="phone-title">
|
||||
{t("EnterPhone")}
|
||||
</Text>
|
||||
<Text>
|
||||
{t("CurrentNumber")}: {currentNumber}
|
||||
</Text>
|
||||
<Text>{t("PhoneSubtitle", { productName: PRODUCT_NAME })}</Text>
|
||||
</div>
|
||||
|
||||
<TextInput
|
||||
className="phone-input"
|
||||
id="phone"
|
||||
name="phone"
|
||||
type="phone"
|
||||
size="large"
|
||||
scale={true}
|
||||
isAutoFocussed={true}
|
||||
tabIndex={1}
|
||||
hasError={false}
|
||||
guide={false}
|
||||
/>
|
||||
|
||||
<Button
|
||||
primary
|
||||
scale
|
||||
size="medium"
|
||||
label={t("GetCode")}
|
||||
tabIndex={2}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
}))(withTranslation("Confirm")(withLoader(observer(ChangePhoneForm))));
|
@ -1,125 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Trans, withTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { continuePortal } from "@docspace/shared/api/portal";
|
||||
import {
|
||||
StyledPage,
|
||||
StyledBody,
|
||||
StyledContent,
|
||||
ButtonsWrapper,
|
||||
} from "./StyledConfirm";
|
||||
|
||||
import withLoader from "../withLoader";
|
||||
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const ContinuePortal = (props) => {
|
||||
const { t, greetingTitle, linkData } = props;
|
||||
const [isReactivate, setIsReactivate] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onRestoreClick = async () => {
|
||||
try {
|
||||
await continuePortal(linkData.confirmHeader);
|
||||
setIsReactivate(true);
|
||||
setTimeout(() => (window.location.href = "/"), 10000);
|
||||
} catch (e) {
|
||||
toastr.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const onCancelClick = () => {
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
{isReactivate ? (
|
||||
<Text>
|
||||
<Trans t={t} i18nKey="SuccessReactivate" ns="Confirm">
|
||||
Your account has been successfully reactivated. In 10 seconds
|
||||
you will be redirected to the
|
||||
<Link isHovered href="/">
|
||||
portal
|
||||
</Link>
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<Text className="subtitle">
|
||||
{t("PortalContinueTitle", { productName: PRODUCT_NAME })}
|
||||
</Text>
|
||||
<ButtonsWrapper>
|
||||
<Button
|
||||
primary
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Reactivate")}
|
||||
tabIndex={1}
|
||||
onClick={onRestoreClick}
|
||||
/>
|
||||
<Button
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:CancelButton")}
|
||||
tabIndex={1}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</ButtonsWrapper>
|
||||
</>
|
||||
)}
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
theme: settingsStore.theme,
|
||||
}))(
|
||||
withTranslation(["Confirm", "Common"])(withLoader(observer(ContinuePortal))),
|
||||
);
|
@ -1,768 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import SsoReactSvgUrl from "PUBLIC_DIR/images/sso.react.svg?url";
|
||||
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { SocialButtonsGroup } from "@docspace/shared/components/social-buttons-group";
|
||||
import { EmailInput } from "@docspace/shared/components/email-input";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
|
||||
import {
|
||||
getUserFromConfirm,
|
||||
createUser,
|
||||
signupOAuth,
|
||||
getUserByEmail,
|
||||
} from "@docspace/shared/api/people";
|
||||
import {
|
||||
createPasswordHash,
|
||||
getOAuthToken,
|
||||
getLoginLink,
|
||||
} from "@docspace/shared/utils/common";
|
||||
import { login } from "@docspace/shared/utils/loginUtils";
|
||||
import {
|
||||
COOKIE_EXPIRATION_YEAR,
|
||||
LANGUAGE,
|
||||
PRODUCT_NAME,
|
||||
PROVIDERS_DATA,
|
||||
} from "@docspace/shared/constants";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
||||
import { getPasswordErrorMessage } from "@docspace/shared/utils/getPasswordErrorMessage";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import withLoader from "../withLoader";
|
||||
|
||||
import { StyledPage } from "./StyledConfirm";
|
||||
import {
|
||||
GreetingContainer,
|
||||
RegisterContainer,
|
||||
StyledCreateUserContent,
|
||||
} from "./StyledCreateUser";
|
||||
import GreetingUserContainer from "./GreetingUserContainer";
|
||||
import LanguageComboboxWrapper from "./LanguageCombobox";
|
||||
import withCultureNames from "SRC_DIR/HOCs/withCultureNames";
|
||||
|
||||
import { setCookie } from "@docspace/shared/utils/cookie";
|
||||
|
||||
const DEFAULT_ROOM_TEXT =
|
||||
"<strong>{{firstName}} {{lastName}}</strong> invites you to join the room <strong>{{roomName}}</strong> for secure document collaboration.";
|
||||
const DEFAULT_PORTAL_TEXT =
|
||||
"<strong>{{firstName}} {{lastName}}</strong> invites you to join the room <strong>{{roomName}}</strong> for secure document collaboration.";
|
||||
|
||||
const RegistrationFormGreeting = ({
|
||||
email,
|
||||
setRegistrationForm,
|
||||
type,
|
||||
emailFromLink,
|
||||
}) => {
|
||||
const onClickBack = () => {
|
||||
setRegistrationForm(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<GreetingUserContainer
|
||||
type={type}
|
||||
emailFromLink={!!emailFromLink}
|
||||
email={email}
|
||||
onClickBack={onClickBack}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const CreateUserForm = (props) => {
|
||||
const {
|
||||
settings,
|
||||
t,
|
||||
providers,
|
||||
isDesktop,
|
||||
linkData,
|
||||
roomData,
|
||||
capabilities,
|
||||
currentColorScheme,
|
||||
userNameRegex,
|
||||
defaultPage,
|
||||
cultures,
|
||||
i18n,
|
||||
} = props;
|
||||
|
||||
const currentCultureName = i18n.language;
|
||||
|
||||
const inputRef = React.useRef(null);
|
||||
|
||||
const emailFromLink = linkData?.email ? linkData.email : "";
|
||||
const roomName = roomData?.title;
|
||||
|
||||
const [email, setEmail] = useState(emailFromLink);
|
||||
const [emailValid, setEmailValid] = useState(true);
|
||||
const [emailErrorText, setEmailErrorText] = useState("");
|
||||
|
||||
const [password, setPassword] = useState("");
|
||||
const [passwordValid, setPasswordValid] = useState(true);
|
||||
|
||||
const [fname, setFname] = useState("");
|
||||
const [fnameValid, setFnameValid] = useState(true);
|
||||
const [sname, setSname] = useState("");
|
||||
const [snameValid, setSnameValid] = useState(true);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const [errorText, setErrorText] = useState("");
|
||||
|
||||
const [user, setUser] = useState("");
|
||||
|
||||
const [isEmailErrorShow, setIsEmailErrorShow] = useState(false);
|
||||
const [isPasswordErrorShow, setIsPasswordErrorShow] = useState(false);
|
||||
|
||||
const [registrationForm, setRegistrationForm] = useState(emailFromLink);
|
||||
|
||||
const focusInput = () => {
|
||||
if (inputRef) {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const nameRegex = new RegExp(userNameRegex, "gu");
|
||||
|
||||
useEffect(() => {
|
||||
const { linkData } = props;
|
||||
|
||||
const fetchData = async () => {
|
||||
if (linkData.type === "LinkInvite") {
|
||||
const uid = linkData.uid;
|
||||
const confirmKey = linkData.confirmHeader;
|
||||
const user = await getUserFromConfirm(uid, confirmKey);
|
||||
setUser(user);
|
||||
}
|
||||
window.authCallback = authCallback;
|
||||
|
||||
focusInput();
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const onContinue = async () => {
|
||||
const { linkData } = props;
|
||||
setIsLoading(true);
|
||||
|
||||
let hasError = false;
|
||||
|
||||
const emailRegex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$";
|
||||
const validationEmail = new RegExp(emailRegex);
|
||||
|
||||
if (!validationEmail.test(email.trim())) {
|
||||
hasError = true;
|
||||
setEmailValid(!hasError);
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const headerKey = linkData.confirmHeader;
|
||||
|
||||
try {
|
||||
const toBinaryStr = (str) => {
|
||||
const encoder = new TextEncoder();
|
||||
const charCodes = encoder.encode(str);
|
||||
return String.fromCharCode(...charCodes);
|
||||
};
|
||||
|
||||
const loginData = window.btoa(
|
||||
toBinaryStr(
|
||||
JSON.stringify({
|
||||
type: "invitation",
|
||||
email,
|
||||
roomName,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
await getUserByEmail(email, headerKey);
|
||||
|
||||
setCookie(LANGUAGE, currentCultureName, {
|
||||
"max-age": COOKIE_EXPIRATION_YEAR,
|
||||
});
|
||||
|
||||
window.location.href = combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
"/login",
|
||||
`?loginData=${loginData}`,
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
const status = err?.response?.status;
|
||||
const isNotExistUser = status === 404;
|
||||
|
||||
if (isNotExistUser) {
|
||||
setRegistrationForm(true);
|
||||
}
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
};
|
||||
const onSubmit = () => {
|
||||
const { linkData, hashSettings } = props;
|
||||
const type = parseInt(linkData.emplType);
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
setErrorText("");
|
||||
|
||||
let hasError = false;
|
||||
|
||||
if (!fname.trim() || !fnameValid) {
|
||||
hasError = true;
|
||||
setFnameValid(!hasError);
|
||||
}
|
||||
|
||||
if (!sname.trim() || !snameValid) {
|
||||
hasError = true;
|
||||
setSnameValid(!hasError);
|
||||
}
|
||||
|
||||
const emailRegex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$";
|
||||
const validationEmail = new RegExp(emailRegex);
|
||||
|
||||
if (!validationEmail.test(email.trim())) {
|
||||
hasError = true;
|
||||
setEmailValid(!hasError);
|
||||
}
|
||||
|
||||
if (!passwordValid || !password.trim()) {
|
||||
hasError = true;
|
||||
setPasswordValid(!hasError);
|
||||
setIsPasswordErrorShow(true);
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
setIsLoading(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
const hash = createPasswordHash(password, hashSettings);
|
||||
|
||||
const loginData = {
|
||||
userName: email,
|
||||
passwordHash: hash,
|
||||
};
|
||||
|
||||
const personalData = {
|
||||
firstname: fname.trim(),
|
||||
lastname: sname.trim(),
|
||||
email: email,
|
||||
cultureName: currentCultureName,
|
||||
};
|
||||
|
||||
if (!!type) {
|
||||
personalData.type = type;
|
||||
}
|
||||
|
||||
if (!!linkData.key) {
|
||||
personalData.key = linkData.key;
|
||||
}
|
||||
|
||||
const headerKey = linkData.confirmHeader;
|
||||
|
||||
createConfirmUser(personalData, loginData, headerKey).catch((error) => {
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
|
||||
console.error("confirm error", errorMessage);
|
||||
setIsEmailErrorShow(true);
|
||||
setEmailErrorText(errorMessage);
|
||||
setEmailValid(false);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const authCallback = (profile) => {
|
||||
const signupAccount = {
|
||||
EmployeeType: linkData.emplType || null,
|
||||
Email: linkData.email,
|
||||
Key: linkData.key,
|
||||
SerializedProfile: profile,
|
||||
culture: currentCultureName,
|
||||
};
|
||||
|
||||
signupOAuth(signupAccount)
|
||||
.then(() => {
|
||||
const url = roomData.roomId
|
||||
? `/rooms/shared/filter?folder=${roomData.roomId}/`
|
||||
: defaultPage;
|
||||
window.location.replace(url);
|
||||
})
|
||||
.catch((e) => {
|
||||
toastr.error(e);
|
||||
});
|
||||
};
|
||||
|
||||
const createConfirmUser = async (registerData, loginData, key) => {
|
||||
const { defaultPage } = props;
|
||||
|
||||
const fromInviteLink =
|
||||
linkData.type === "LinkInvite" || linkData.type === "EmpInvite"
|
||||
? true
|
||||
: false;
|
||||
|
||||
const data = Object.assign({ fromInviteLink }, registerData, loginData);
|
||||
|
||||
await createUser(data, key);
|
||||
|
||||
const { userName, passwordHash } = loginData;
|
||||
|
||||
const res = await login(userName, passwordHash);
|
||||
|
||||
//console.log({ res });
|
||||
|
||||
const finalUrl = roomData.roomId
|
||||
? `/rooms/shared/filter?folder=${roomData.roomId}`
|
||||
: defaultPage;
|
||||
|
||||
const isConfirm = typeof res === "string" && res.includes("confirm");
|
||||
|
||||
if (isConfirm) {
|
||||
sessionStorage.setItem("referenceUrl", finalUrl);
|
||||
|
||||
return window.location.replace(typeof res === "string" ? res : "/");
|
||||
}
|
||||
|
||||
window.location.replace(finalUrl);
|
||||
};
|
||||
|
||||
const onChangeEmail = (e) => {
|
||||
setEmail(e.target.value);
|
||||
setIsEmailErrorShow(false);
|
||||
};
|
||||
const onChangeFname = (e) => {
|
||||
setFname(e.target.value);
|
||||
setFnameValid(nameRegex.test(e.target.value.trim()));
|
||||
setErrorText("");
|
||||
};
|
||||
|
||||
const onChangeSname = (e) => {
|
||||
setSname(e.target.value);
|
||||
setSnameValid(nameRegex.test(e.target.value.trim()));
|
||||
setErrorText("");
|
||||
};
|
||||
|
||||
const onChangePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
setErrorText("");
|
||||
setIsPasswordErrorShow(false);
|
||||
};
|
||||
|
||||
const onKeyPress = (event) => {
|
||||
if (event.key === "Enter") {
|
||||
registrationForm ? onSubmit() : onContinue();
|
||||
}
|
||||
};
|
||||
const onValidatePassword = (res) => {
|
||||
setPasswordValid(res);
|
||||
};
|
||||
|
||||
const onBlurEmail = () => {
|
||||
setIsEmailErrorShow(true);
|
||||
};
|
||||
|
||||
const onBlurPassword = () => {
|
||||
setIsPasswordErrorShow(true);
|
||||
};
|
||||
|
||||
const onSocialButtonClick = useCallback((e) => {
|
||||
const { target } = e;
|
||||
let targetElement = target;
|
||||
|
||||
if (!(targetElement instanceof HTMLButtonElement) && target.parentElement) {
|
||||
targetElement = target.parentElement;
|
||||
}
|
||||
|
||||
const providerName = targetElement.dataset.providername;
|
||||
const url = targetElement.dataset.url || "";
|
||||
|
||||
try {
|
||||
const tokenGetterWin = isDesktop
|
||||
? (window.location.href = url)
|
||||
: window.open(
|
||||
url,
|
||||
"login",
|
||||
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no",
|
||||
);
|
||||
|
||||
getOAuthToken(tokenGetterWin).then((code) => {
|
||||
const token = window.btoa(
|
||||
JSON.stringify({
|
||||
auth: providerName,
|
||||
mode: "popup",
|
||||
callback: "authCallback",
|
||||
}),
|
||||
);
|
||||
|
||||
tokenGetterWin.location.href = getLoginLink(token, code);
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const oauthDataExists = () => {
|
||||
if (!capabilities?.oauthEnabled) return false;
|
||||
|
||||
let existProviders = 0;
|
||||
providers && providers.length > 0;
|
||||
providers.map((item) => {
|
||||
if (!PROVIDERS_DATA[item.provider]) return;
|
||||
existProviders++;
|
||||
});
|
||||
|
||||
return !!existProviders;
|
||||
};
|
||||
|
||||
const ssoExists = () => {
|
||||
if (capabilities?.ssoUrl) return true;
|
||||
else return false;
|
||||
};
|
||||
|
||||
const onValidateEmail = (res) => {
|
||||
setEmailValid(res.isValid);
|
||||
setEmailErrorText(res.errors[0]);
|
||||
};
|
||||
|
||||
const ssoProps = ssoExists()
|
||||
? {
|
||||
ssoUrl: capabilities?.ssoUrl,
|
||||
ssoLabel: capabilities?.ssoLabel,
|
||||
ssoSVG: SsoReactSvgUrl,
|
||||
}
|
||||
: {};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<LanguageComboboxWrapper
|
||||
cultures={cultures}
|
||||
currentCultureName={currentCultureName}
|
||||
/>
|
||||
|
||||
<StyledCreateUserContent>
|
||||
<GreetingContainer>
|
||||
<PortalLogo className="portal-logo" />
|
||||
{linkData.type === "LinkInvite" && (
|
||||
<div className="tooltip">
|
||||
<Text fontSize="16px">
|
||||
{roomName ? (
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="InvitationToRoom"
|
||||
ns="Common"
|
||||
defaults={DEFAULT_ROOM_TEXT}
|
||||
values={{
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
...(roomName
|
||||
? { roomName }
|
||||
: { spaceAddress: window.location.host }),
|
||||
}}
|
||||
components={{
|
||||
1: <Text fontWeight={600} as="strong" fontSize="16px" />,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="InvitationToPortal"
|
||||
ns="Common"
|
||||
defaults={DEFAULT_PORTAL_TEXT}
|
||||
values={{
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
productName: PRODUCT_NAME,
|
||||
...(roomName
|
||||
? { roomName }
|
||||
: { spaceAddress: window.location.host }),
|
||||
}}
|
||||
components={{
|
||||
1: <Text fontWeight={600} as="strong" fontSize="16px" />,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</GreetingContainer>
|
||||
|
||||
<FormWrapper>
|
||||
<RegisterContainer registrationForm={registrationForm}>
|
||||
<div className="auth-form-fields">
|
||||
<div className="email-container">
|
||||
<FieldContainer
|
||||
className="form-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={isEmailErrorShow && !emailValid}
|
||||
errorMessage={
|
||||
emailErrorText
|
||||
? t(`Common:${emailErrorText}`)
|
||||
: t("Common:RequiredField")
|
||||
}
|
||||
>
|
||||
<EmailInput
|
||||
id="login"
|
||||
name="login"
|
||||
type="email"
|
||||
hasError={isEmailErrorShow && !emailValid}
|
||||
value={email}
|
||||
placeholder={t("Common:Email")}
|
||||
size="large"
|
||||
scale={true}
|
||||
isAutoFocussed={true}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading || !!emailFromLink}
|
||||
autoComplete="username"
|
||||
onChange={onChangeEmail}
|
||||
onBlur={onBlurEmail}
|
||||
onValidateInput={onValidateEmail}
|
||||
forwardedRef={inputRef}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
<Button
|
||||
className="login-button"
|
||||
primary
|
||||
size="medium"
|
||||
scale={true}
|
||||
label={t("Common:ContinueButton")}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={onContinue}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{registrationForm && (
|
||||
<div>
|
||||
<RegistrationFormGreeting
|
||||
email={email}
|
||||
setRegistrationForm={setRegistrationForm}
|
||||
type={linkData.type}
|
||||
emailFromLink={emailFromLink}
|
||||
/>
|
||||
<FieldContainer
|
||||
className="form-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={!fnameValid}
|
||||
errorMessage={
|
||||
errorText
|
||||
? errorText
|
||||
: fname.trim().length === 0
|
||||
? t("Common:RequiredField")
|
||||
: t("Common:IncorrectFirstName")
|
||||
}
|
||||
>
|
||||
<TextInput
|
||||
id="first-name"
|
||||
name="first-name"
|
||||
type="text"
|
||||
hasError={!fnameValid}
|
||||
value={fname}
|
||||
placeholder={t("Common:FirstName")}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
onChange={onChangeFname}
|
||||
onKeyDown={onKeyPress}
|
||||
isAutoFocussed
|
||||
/>
|
||||
</FieldContainer>
|
||||
<FieldContainer
|
||||
className="form-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={!snameValid}
|
||||
errorMessage={
|
||||
errorText
|
||||
? errorText
|
||||
: sname.trim().length === 0
|
||||
? t("Common:RequiredField")
|
||||
: t("Common:IncorrectLastName")
|
||||
}
|
||||
>
|
||||
<TextInput
|
||||
id="last-name"
|
||||
name="last-name"
|
||||
type="text"
|
||||
hasError={!snameValid}
|
||||
value={sname}
|
||||
placeholder={t("Common:LastName")}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
onChange={onChangeSname}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
<FieldContainer
|
||||
className="form-field password-field"
|
||||
isVertical={true}
|
||||
labelVisible={false}
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
errorMessage={`${t(
|
||||
"Common:PasswordLimitMessage",
|
||||
)}: ${getPasswordErrorMessage(t, settings)}`}
|
||||
>
|
||||
<PasswordInput
|
||||
simpleView={false}
|
||||
hideNewPasswordButton
|
||||
showCopyLink={false}
|
||||
passwordSettings={settings}
|
||||
id="password"
|
||||
inputName="password"
|
||||
placeholder={t("Common:Password")}
|
||||
type="password"
|
||||
hasError={isPasswordErrorShow && !passwordValid}
|
||||
inputValue={password}
|
||||
size="large"
|
||||
scale={true}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
autoComplete="current-password"
|
||||
onChange={onChangePassword}
|
||||
onBlur={onBlurPassword}
|
||||
onKeyDown={onKeyPress}
|
||||
onValidateInput={onValidatePassword}
|
||||
tooltipPasswordTitle={`${t(
|
||||
"Common:PasswordLimitMessage",
|
||||
)}:`}
|
||||
tooltipPasswordLength={`${t(
|
||||
"Common:PasswordMinimumLength",
|
||||
)}: ${settings ? settings.minLength : 8}`}
|
||||
tooltipPasswordDigits={`${t(
|
||||
"Common:PasswordLimitDigits",
|
||||
)}`}
|
||||
tooltipPasswordCapital={`${t(
|
||||
"Common:PasswordLimitUpperCase",
|
||||
)}`}
|
||||
tooltipPasswordSpecial={`${t(
|
||||
"Common:PasswordLimitSpecialSymbols",
|
||||
)}`}
|
||||
generatePasswordTitle={t("Wizard:GeneratePassword")}
|
||||
/>
|
||||
</FieldContainer>
|
||||
|
||||
<Button
|
||||
className="login-button"
|
||||
primary
|
||||
size="medium"
|
||||
scale={true}
|
||||
label={
|
||||
isLoading ? t("Common:LoadingProcessing") : t("SignUp")
|
||||
}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={onSubmit}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{!emailFromLink && (oauthDataExists() || ssoExists()) && (
|
||||
<>
|
||||
<div className="line">
|
||||
<Text color="#A3A9AE" className="or-label">
|
||||
{t("Common:orContinueWith")}
|
||||
</Text>
|
||||
</div>
|
||||
<SocialButtonsGroup
|
||||
providers={providers}
|
||||
onClick={onSocialButtonClick}
|
||||
t={t}
|
||||
isDisabled={isLoading}
|
||||
{...ssoProps}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</RegisterContainer>
|
||||
</FormWrapper>
|
||||
</StyledCreateUserContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore, authStore }) => {
|
||||
const { providers, thirdPartyLogin, capabilities } = authStore;
|
||||
const {
|
||||
passwordSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
getSettings,
|
||||
getPortalPasswordSettings,
|
||||
currentColorScheme,
|
||||
userNameRegex,
|
||||
cultures,
|
||||
} = settingsStore;
|
||||
return {
|
||||
settings: passwordSettings,
|
||||
hashSettings,
|
||||
defaultPage,
|
||||
|
||||
getSettings,
|
||||
getPortalPasswordSettings,
|
||||
thirdPartyLogin,
|
||||
providers,
|
||||
capabilities,
|
||||
currentColorScheme,
|
||||
userNameRegex,
|
||||
cultures,
|
||||
};
|
||||
})(
|
||||
withCultureNames(
|
||||
withTranslation(["Confirm", "Common", "Wizard"])(
|
||||
withLoader(observer(CreateUserForm)),
|
||||
),
|
||||
),
|
||||
);
|
@ -1,132 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Trans, withTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { suspendPortal } from "@docspace/shared/api/portal";
|
||||
import {
|
||||
StyledPage,
|
||||
StyledBody,
|
||||
StyledContent,
|
||||
ButtonsWrapper,
|
||||
} from "./StyledConfirm";
|
||||
|
||||
import withLoader from "../withLoader";
|
||||
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const DeactivatePortal = (props) => {
|
||||
const { t, greetingTitle, linkData, companyInfoSettingsData } = props;
|
||||
const [isDeactivate, setIsDeactivate] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const url = companyInfoSettingsData?.site
|
||||
? companyInfoSettingsData.site
|
||||
: "https://onlyoffice.com";
|
||||
|
||||
const onDeactivateClick = async () => {
|
||||
try {
|
||||
await suspendPortal(linkData.confirmHeader);
|
||||
setIsDeactivate(true);
|
||||
setTimeout(() => (window.location.href = url), 10000);
|
||||
} catch (e) {
|
||||
toastr.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const onCancelClick = () => {
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
{isDeactivate ? (
|
||||
<Text>
|
||||
<Trans t={t} i18nKey="SuccessDeactivate" ns="Confirm">
|
||||
Your account has been successfully deactivated. In 10 seconds
|
||||
you will be redirected to the
|
||||
<Link isHovered href={url}>
|
||||
site
|
||||
</Link>
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<Text className="subtitle">
|
||||
{t("PortalDeactivateTitle", { productName: PRODUCT_NAME })}
|
||||
</Text>
|
||||
<ButtonsWrapper>
|
||||
<Button
|
||||
scale
|
||||
primary
|
||||
size="medium"
|
||||
label={t("Settings:Deactivate")}
|
||||
tabIndex={1}
|
||||
onClick={onDeactivateClick}
|
||||
/>
|
||||
<Button
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:CancelButton")}
|
||||
tabIndex={1}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</ButtonsWrapper>
|
||||
</>
|
||||
)}
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
theme: settingsStore.theme,
|
||||
companyInfoSettingsData: settingsStore.companyInfoSettingsData,
|
||||
}))(
|
||||
withTranslation(["Confirm", "Settings", "Common"])(
|
||||
withLoader(observer(DeactivatePortal)),
|
||||
),
|
||||
);
|
@ -1,158 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { deleteSelf } from "@docspace/shared/api/people";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { StyledPage, StyledBody, StyledContent } from "./StyledConfirm";
|
||||
import withLoader from "../withLoader";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
|
||||
const ProfileRemoveForm = (props) => {
|
||||
const { t, greetingTitle, linkData, legalTerms, currentColorScheme } = props;
|
||||
const [isProfileDeleted, setIsProfileDeleted] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
console.log(legalTerms);
|
||||
|
||||
const onDeleteProfile = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
deleteSelf(linkData.confirmHeader)
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
setIsProfileDeleted(true);
|
||||
})
|
||||
.catch((e) => {
|
||||
setIsLoading(false);
|
||||
toastr.error(e);
|
||||
});
|
||||
};
|
||||
|
||||
if (isProfileDeleted) {
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody style={{ whiteSpace: "pre-wrap" }}>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{t("DeleteProfileSuccessMessage")}
|
||||
</Text>
|
||||
<Text fontSize="16px" fontWeight="600" className="confirm-subtitle">
|
||||
<Trans
|
||||
i18nKey="DeleteProfileSuccessMessageInfo"
|
||||
ns="Confirm"
|
||||
t={t}
|
||||
>
|
||||
Your DocSpace account is successfully disabled. The DocSpace
|
||||
owner or admin can permanently delete your disabled account.
|
||||
\n\nPlease check our
|
||||
<Link
|
||||
fontSize="16px"
|
||||
fontWeight="600"
|
||||
type="page"
|
||||
href={legalTerms}
|
||||
color={currentColorScheme?.main?.accent}
|
||||
target="_blank"
|
||||
>
|
||||
Privacy policy
|
||||
</Link>
|
||||
to learn more about deleting your account and associated data.
|
||||
</Trans>
|
||||
</Text>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
<div className="subtitle">
|
||||
<Text
|
||||
fontSize="16px"
|
||||
fontWeight="600"
|
||||
className="delete-profile-confirm"
|
||||
>
|
||||
{t("DeleteProfileConfirmation")}
|
||||
</Text>
|
||||
<Text>
|
||||
<Trans
|
||||
i18nKey="DeleteProfileConfirmationInfo"
|
||||
ns="Confirm"
|
||||
t={t}
|
||||
>
|
||||
By clicking \"Disable my account\" you agree with our Privacy
|
||||
policy
|
||||
<Link
|
||||
type="page"
|
||||
href={legalTerms}
|
||||
color={currentColorScheme?.main?.accent}
|
||||
target="_blank"
|
||||
>
|
||||
Privacy policy.
|
||||
</Link>
|
||||
</Trans>
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
primary
|
||||
scale
|
||||
size="medium"
|
||||
label={t("DeleteProfileBtn")}
|
||||
tabIndex={1}
|
||||
isDisabled={isLoading}
|
||||
onClick={onDeleteProfile}
|
||||
/>
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
theme: settingsStore.theme,
|
||||
legalTerms: settingsStore.legalTerms,
|
||||
currentColorScheme: settingsStore.currentColorScheme,
|
||||
}))(withTranslation("Confirm")(withLoader(observer(ProfileRemoveForm))));
|
@ -1,128 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
|
||||
import { deletePortal } from "@docspace/shared/api/portal";
|
||||
import {
|
||||
StyledPage,
|
||||
StyledBody,
|
||||
StyledContent,
|
||||
ButtonsWrapper,
|
||||
} from "./StyledConfirm";
|
||||
|
||||
import withLoader from "../withLoader";
|
||||
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const RemovePortal = (props) => {
|
||||
const { t, greetingTitle, linkData, companyInfoSettingsData } = props;
|
||||
const [isRemoved, setIsRemoved] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const url = companyInfoSettingsData?.site
|
||||
? companyInfoSettingsData.site
|
||||
: "https://onlyoffice.com";
|
||||
|
||||
const onDeleteClick = async () => {
|
||||
try {
|
||||
await deletePortal(linkData.confirmHeader);
|
||||
setIsRemoved(true);
|
||||
setTimeout(() => (location.href = url), 10000);
|
||||
} catch (e) {
|
||||
toastr.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const onCancelClick = () => {
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledBody>
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text fontSize="23px" fontWeight="700" className="title">
|
||||
{greetingTitle}
|
||||
</Text>
|
||||
|
||||
<FormWrapper>
|
||||
{isRemoved ? (
|
||||
<Text>
|
||||
<Trans t={t} i18nKey="SuccessRemoved" ns="Confirm">
|
||||
Your account has been successfully removed. In 10 seconds you
|
||||
will be redirected to the
|
||||
<Link isHovered href={url}>
|
||||
site
|
||||
</Link>
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<Text className="subtitle">
|
||||
{t("PortalRemoveTitle", { productName: PRODUCT_NAME })}
|
||||
</Text>
|
||||
<ButtonsWrapper>
|
||||
<Button
|
||||
primary
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:Delete")}
|
||||
tabIndex={1}
|
||||
onClick={onDeleteClick}
|
||||
/>
|
||||
<Button
|
||||
scale
|
||||
size="medium"
|
||||
label={t("Common:CancelButton")}
|
||||
tabIndex={1}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</ButtonsWrapper>
|
||||
</>
|
||||
)}
|
||||
</FormWrapper>
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore }) => ({
|
||||
greetingTitle: settingsStore.greetingSettings,
|
||||
theme: settingsStore.theme,
|
||||
companyInfoSettingsData: settingsStore.companyInfoSettingsData,
|
||||
}))(withTranslation(["Confirm", "Common"])(withLoader(observer(RemovePortal))));
|
@ -1,356 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Trans, withTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import withLoader from "../withLoader";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import ErrorContainer from "@docspace/shared/components/error-container/ErrorContainer";
|
||||
import { mobile, tablet } from "@docspace/shared/utils";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { StyledPage, StyledContent } from "./StyledConfirm";
|
||||
import {
|
||||
getTfaSecretKeyAndQR,
|
||||
validateTfaCode,
|
||||
} from "@docspace/shared/api/settings";
|
||||
import { loginWithTfaCode } from "@docspace/shared/api/user";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import { PRODUCT_NAME } from "@docspace/shared/constants";
|
||||
|
||||
const StyledForm = styled(Box)`
|
||||
margin: 56px auto;
|
||||
display: flex;
|
||||
flex: 1fr 1fr;
|
||||
gap: 80px;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
margin: 0 auto;
|
||||
flex-direction: column;
|
||||
gap: 0px;
|
||||
|
||||
${({ theme }) =>
|
||||
theme.interfaceDirection === "rtl"
|
||||
? `padding-left: 8px;`
|
||||
: `padding-right: 8px;`}
|
||||
}
|
||||
|
||||
.app-code-wrapper {
|
||||
width: 100%;
|
||||
|
||||
@media ${tablet} {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.portal-logo {
|
||||
padding-bottom: 40px;
|
||||
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.set-app-description {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.set-app-title {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.set-app-text {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.qrcode-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0px 80px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 32px;
|
||||
|
||||
@media ${mobile} {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.app-code-continue-btn {
|
||||
margin-top: 8px;
|
||||
}
|
||||
`;
|
||||
const PROXY_BASE_URL = combineUrl(window.ClientConfig?.proxy?.url, "/profile");
|
||||
|
||||
const TfaActivationForm = withLoader((props) => {
|
||||
const {
|
||||
t,
|
||||
secretKey,
|
||||
qrCode,
|
||||
|
||||
location,
|
||||
currentColorScheme,
|
||||
} = props;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [code, setCode] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
const { user, hash } = (location && location.state) || {};
|
||||
const { linkData } = props;
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
if (user && hash) {
|
||||
await loginWithTfaCode(user, hash, code);
|
||||
} else {
|
||||
await validateTfaCode(code, linkData.confirmHeader);
|
||||
}
|
||||
|
||||
// const referenceUrl = sessionStorage.getItem("referenceUrl");
|
||||
|
||||
// if (referenceUrl) {
|
||||
// sessionStorage.removeItem("referenceUrl");
|
||||
// }
|
||||
|
||||
// window.location.replace(referenceUrl || defaultPage);
|
||||
navigate(PROXY_BASE_URL, {
|
||||
state: { openBackupCodesDialog: true },
|
||||
});
|
||||
} catch (err) {
|
||||
let errorMessage = "";
|
||||
if (typeof err === "object") {
|
||||
errorMessage =
|
||||
err?.response?.data?.error?.message ||
|
||||
err?.statusText ||
|
||||
err?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = err;
|
||||
}
|
||||
setError(errorMessage);
|
||||
toastr.error(errorMessage);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyPress = (target) => {
|
||||
if (target.code === "Enter" || target.code === "NumpadEnter") onSubmit();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledForm className="set-app-container">
|
||||
<Box className="set-app-description" marginProp="0 0 32px 0">
|
||||
<PortalLogo className="portal-logo" />
|
||||
<Text isBold fontSize="14px" className="set-app-title">
|
||||
{t("SetAppTitle")}
|
||||
</Text>
|
||||
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="SetAppDescription"
|
||||
ns="Confirm"
|
||||
portalName={PRODUCT_NAME}
|
||||
>
|
||||
The two-factor authentication is enabled to provide additional
|
||||
portal security. Configure your authenticator application to
|
||||
continue work on the portal. For example you could use Google
|
||||
Authenticator for
|
||||
<Link
|
||||
color={currentColorScheme?.main?.accent}
|
||||
href={props.tfaAndroidAppUrl}
|
||||
target="_blank"
|
||||
>
|
||||
Android
|
||||
</Link>
|
||||
and{" "}
|
||||
<Link
|
||||
color={currentColorScheme?.main?.accent}
|
||||
href={props.tfaIosAppUrl}
|
||||
target="_blank"
|
||||
>
|
||||
iOS
|
||||
</Link>{" "}
|
||||
or Authenticator for{" "}
|
||||
<Link
|
||||
color={currentColorScheme?.main?.accent}
|
||||
href={props.tfaWinAppUrl}
|
||||
target="_blank"
|
||||
>
|
||||
Windows Phone
|
||||
</Link>{" "}
|
||||
.
|
||||
</Trans>
|
||||
|
||||
<Text className="set-app-text">
|
||||
<Trans
|
||||
t={t}
|
||||
i18nKey="SetAppInstallDescription"
|
||||
ns="Confirm"
|
||||
key={secretKey}
|
||||
>
|
||||
To connect your apllication scan the QR code or manually enter
|
||||
your secret key <strong>{{ secretKey }}</strong> then enter
|
||||
6-digit code from your application in the field below.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Box>
|
||||
<FormWrapper>
|
||||
<Box
|
||||
displayProp="flex"
|
||||
flexDirection="column"
|
||||
className="app-code-wrapper"
|
||||
>
|
||||
<div className="qrcode-wrapper">
|
||||
<img
|
||||
src={qrCode}
|
||||
height="180px"
|
||||
width="180px"
|
||||
alt="QR-code"
|
||||
></img>
|
||||
</div>
|
||||
<Box className="app-code-input">
|
||||
<FieldContainer
|
||||
labelVisible={false}
|
||||
hasError={error ? true : false}
|
||||
errorMessage={error}
|
||||
>
|
||||
<TextInput
|
||||
id="code"
|
||||
name="code"
|
||||
type="text"
|
||||
size="large"
|
||||
scale
|
||||
isAutoFocussed
|
||||
tabIndex={1}
|
||||
placeholder={t("EnterCodePlaceholder")}
|
||||
isDisabled={isLoading}
|
||||
maxLength={6}
|
||||
onChange={(e) => {
|
||||
setCode(e.target.value);
|
||||
setError("");
|
||||
}}
|
||||
value={code}
|
||||
hasError={error ? true : false}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
</Box>
|
||||
<Box className="app-code-continue-btn">
|
||||
<Button
|
||||
scale
|
||||
primary
|
||||
size="medium"
|
||||
tabIndex={3}
|
||||
label={
|
||||
isLoading
|
||||
? t("Common:LoadingProcessing")
|
||||
: t("SetAppButton")
|
||||
}
|
||||
isDisabled={!code.length || isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={onSubmit}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</FormWrapper>
|
||||
</StyledForm>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
});
|
||||
|
||||
const TfaActivationWrapper = (props) => {
|
||||
const { linkData, setIsLoaded, setIsLoading } = props;
|
||||
|
||||
const [secretKey, setSecretKey] = useState("");
|
||||
const [qrCode, setQrCode] = useState("");
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const getSecretKeyAndQRAction = useCallback(async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const confirmKey = linkData.confirmHeader;
|
||||
const res = await getTfaSecretKeyAndQR(confirmKey);
|
||||
const { manualEntryKey, qrCodeSetupImageUrl } = res;
|
||||
|
||||
setSecretKey(manualEntryKey);
|
||||
setQrCode(qrCodeSetupImageUrl);
|
||||
} catch (e) {
|
||||
setError(e.error);
|
||||
toastr.error(e);
|
||||
}
|
||||
setIsLoaded(true);
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
getSecretKeyAndQRAction();
|
||||
}, []);
|
||||
|
||||
return error ? (
|
||||
<ErrorContainer bodyText={error} />
|
||||
) : (
|
||||
<TfaActivationForm secretKey={secretKey} qrCode={qrCode} {...props} />
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore, confirm, tfaStore }) => ({
|
||||
setIsLoaded: confirm.setIsLoaded,
|
||||
setIsLoading: confirm.setIsLoading,
|
||||
tfaAndroidAppUrl: tfaStore.tfaAndroidAppUrl,
|
||||
tfaIosAppUrl: tfaStore.tfaIosAppUrl,
|
||||
tfaWinAppUrl: tfaStore.tfaWinAppUrl,
|
||||
currentColorScheme: settingsStore.currentColorScheme,
|
||||
}))(withTranslation(["Confirm", "Common"])(observer(TfaActivationWrapper)));
|
@ -1,213 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import withLoader from "../withLoader";
|
||||
import { mobile } from "@docspace/shared/utils";
|
||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import { StyledPage, StyledContent } from "./StyledConfirm";
|
||||
import { validateTfaCode } from "@docspace/shared/api/settings";
|
||||
import { loginWithTfaCode } from "@docspace/shared/api/user";
|
||||
|
||||
const StyledForm = styled(Box)`
|
||||
margin: 56px auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1fr;
|
||||
|
||||
@media ${mobile} {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.portal-logo {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.app-code-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.app-code-text {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.app-code-continue-btn {
|
||||
margin-top: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TfaAuthForm = withLoader((props) => {
|
||||
const { t } = props;
|
||||
|
||||
const [code, setCode] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
const { user, hash } = (location && location.state) || {};
|
||||
const { linkData, defaultPage } = props;
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
if (user && hash) {
|
||||
await loginWithTfaCode(user, hash, code);
|
||||
} else {
|
||||
await validateTfaCode(code, linkData.confirmHeader);
|
||||
}
|
||||
|
||||
const referenceUrl = sessionStorage.getItem("referenceUrl");
|
||||
|
||||
if (referenceUrl) {
|
||||
sessionStorage.removeItem("referenceUrl");
|
||||
}
|
||||
|
||||
window.location.replace(referenceUrl || defaultPage);
|
||||
} catch (err) {
|
||||
let errorMessage = "";
|
||||
if (typeof err === "object") {
|
||||
errorMessage =
|
||||
err?.response?.data?.error?.message ||
|
||||
err?.statusText ||
|
||||
err?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = err;
|
||||
}
|
||||
setError(errorMessage);
|
||||
toastr.error(errorMessage);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyPress = (target) => {
|
||||
if (target.code === "Enter" || target.code === "NumpadEnter") onSubmit();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPage>
|
||||
<StyledContent>
|
||||
<StyledForm className="app-code-container">
|
||||
<PortalLogo className="portal-logo" />
|
||||
<FormWrapper>
|
||||
<Box className="app-code-description" marginProp="0 0 32px 0">
|
||||
<Text isBold fontSize="14px" className="app-code-text">
|
||||
{t("EnterAppCodeTitle")}
|
||||
</Text>
|
||||
<Text>{t("EnterAppCodeDescription")}</Text>
|
||||
</Box>
|
||||
<Box
|
||||
displayProp="flex"
|
||||
flexDirection="column"
|
||||
className="app-code-wrapper"
|
||||
>
|
||||
<Box className="app-code-input">
|
||||
<FieldContainer
|
||||
labelVisible={false}
|
||||
hasError={error ? true : false}
|
||||
errorMessage={error}
|
||||
>
|
||||
<TextInput
|
||||
id="code"
|
||||
name="code"
|
||||
type="text"
|
||||
size="large"
|
||||
scale
|
||||
isAutoFocussed
|
||||
tabIndex={1}
|
||||
placeholder={t("EnterCodePlaceholder")}
|
||||
isDisabled={isLoading}
|
||||
maxLength={6}
|
||||
onChange={(e) => {
|
||||
setCode(e.target.value);
|
||||
setError("");
|
||||
}}
|
||||
value={code}
|
||||
hasError={error ? true : false}
|
||||
onKeyDown={onKeyPress}
|
||||
/>
|
||||
</FieldContainer>
|
||||
</Box>
|
||||
<Box className="app-code-continue-btn">
|
||||
<Button
|
||||
scale
|
||||
primary
|
||||
size="medium"
|
||||
tabIndex={3}
|
||||
label={
|
||||
isLoading
|
||||
? t("Common:LoadingProcessing")
|
||||
: t("Common:ContinueButton")
|
||||
}
|
||||
isDisabled={!code.length || isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={onSubmit}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</FormWrapper>
|
||||
</StyledForm>
|
||||
</StyledContent>
|
||||
</StyledPage>
|
||||
);
|
||||
});
|
||||
|
||||
const TfaAuthFormWrapper = (props) => {
|
||||
const { setIsLoaded, setIsLoading } = props;
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoaded(true);
|
||||
setIsLoading(false);
|
||||
}, []);
|
||||
|
||||
return <TfaAuthForm {...props} />;
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore, confirm }) => ({
|
||||
setIsLoaded: confirm.setIsLoaded,
|
||||
setIsLoading: confirm.setIsLoading,
|
||||
|
||||
defaultPage: settingsStore.defaultPage,
|
||||
}))(withTranslation(["Confirm", "Common"])(observer(TfaAuthFormWrapper)));
|
@ -1,196 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2009-2024
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import axios from "axios";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import ConfirmWrapper from "./ConfirmWrapper";
|
||||
import { getUserByEmail } from "@docspace/shared/api/people";
|
||||
|
||||
let loadTimeout = null;
|
||||
export default function withLoader(WrappedComponent) {
|
||||
const withLoader = (props) => {
|
||||
const {
|
||||
tReady,
|
||||
isLoading,
|
||||
linkData,
|
||||
passwordSettings,
|
||||
getSettings,
|
||||
getPortalPasswordSettings,
|
||||
|
||||
getAuthProviders,
|
||||
getCapabilities,
|
||||
} = props;
|
||||
const [inLoad, setInLoad] = useState(false);
|
||||
|
||||
const type = linkData ? linkData.type : null;
|
||||
const confirmHeader = linkData ? linkData.confirmHeader : null;
|
||||
const email = linkData ? linkData.email : null;
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const fetch = async () => {
|
||||
if (type === "EmpInvite" && email) {
|
||||
try {
|
||||
await getUserByEmail(email, confirmHeader);
|
||||
|
||||
const loginData = window.btoa(
|
||||
JSON.stringify({
|
||||
type: "invitation",
|
||||
email: email,
|
||||
}),
|
||||
);
|
||||
|
||||
window.location.href = combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
"/login",
|
||||
`?loginData=${loginData}`,
|
||||
);
|
||||
|
||||
return;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
try {
|
||||
await getPortalPasswordSettings(confirmHeader);
|
||||
} catch (error) {
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
|
||||
console.error(errorMessage);
|
||||
navigate(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/login/error?message=${errorMessage}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
(type === "PasswordChange" ||
|
||||
type === "LinkInvite" ||
|
||||
type === "Activation" ||
|
||||
type === "EmpInvite") &&
|
||||
!passwordSettings
|
||||
) {
|
||||
fetch();
|
||||
}
|
||||
}, [passwordSettings]);
|
||||
|
||||
useEffect(() => {
|
||||
if (type === "LinkInvite" || type === "EmpInvite") {
|
||||
axios.all([getAuthProviders(), getCapabilities()]).catch((error) => {
|
||||
let errorMessage = "";
|
||||
if (typeof error === "object") {
|
||||
errorMessage =
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.statusText ||
|
||||
error?.message ||
|
||||
"";
|
||||
} else {
|
||||
errorMessage = error;
|
||||
}
|
||||
console.error(errorMessage);
|
||||
navigate(
|
||||
combineUrl(
|
||||
window.ClientConfig?.proxy?.url,
|
||||
`/login/error?message=${errorMessage}`,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const isLoaded =
|
||||
type === "TfaActivation" || type === "TfaAuth"
|
||||
? props.isLoaded
|
||||
: type === "PasswordChange" ||
|
||||
type === "LinkInvite" ||
|
||||
type === "Activation" ||
|
||||
type === "EmpInvite"
|
||||
? !!passwordSettings
|
||||
: true;
|
||||
|
||||
const cleanTimer = () => {
|
||||
loadTimeout && clearTimeout(loadTimeout);
|
||||
loadTimeout = null;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) {
|
||||
cleanTimer();
|
||||
loadTimeout = setTimeout(() => {
|
||||
setInLoad(true);
|
||||
}, 500);
|
||||
} else {
|
||||
cleanTimer();
|
||||
setInLoad(false);
|
||||
}
|
||||
|
||||
return () => {
|
||||
cleanTimer();
|
||||
};
|
||||
}, [isLoading]);
|
||||
|
||||
return !isLoaded || !tReady ? (
|
||||
<Loader className="pageLoader" type="rombs" size="40px" />
|
||||
) : (
|
||||
<ConfirmWrapper>
|
||||
<WrappedComponent {...props} />
|
||||
</ConfirmWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
return inject(({ authStore, settingsStore, confirm }) => {
|
||||
const { isLoaded, isLoading } = confirm;
|
||||
const { passwordSettings, getSettings, getPortalPasswordSettings } =
|
||||
settingsStore;
|
||||
const { getAuthProviders, getCapabilities } = authStore;
|
||||
|
||||
return {
|
||||
isLoaded,
|
||||
isLoading,
|
||||
getSettings,
|
||||
passwordSettings,
|
||||
getPortalPasswordSettings,
|
||||
getAuthProviders,
|
||||
getCapabilities,
|
||||
};
|
||||
})(observer(withLoader));
|
||||
}
|
Loading…
Reference in New Issue
Block a user