Login(nextjs): add some components

This commit is contained in:
Timofey Boyko 2024-03-29 11:51:23 +03:00
parent 7c550614fd
commit 42ce320369
25 changed files with 1488 additions and 49 deletions

View File

@ -24,6 +24,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"babel-plugin-styled-components": "^2.1.4",
"eslint": "^8",
"eslint-config-next": "14.0.4",
"prettier": "^3.2.4",

View File

@ -30,7 +30,6 @@ import { useCallback, useState, useLayoutEffect, useMemo } from "react";
import { ThemeProvider } from "@docspace/shared/components/theme-provider";
import { Error520SSR } from "@docspace/shared/components/errors/Error520";
import { getUser } from "@docspace/shared/api/people";
import { getSettings } from "@docspace/shared/api/settings";
import type { TUser } from "@docspace/shared/api/people/types";
import type {
@ -47,15 +46,14 @@ import FirebaseHelper from "@docspace/shared/utils/firebase";
import pkg from "../../package.json";
export default function GlobalError({ error }: { error: Error }) {
const [user, setUser] = useState<TUser>();
const [settings, setSettings] = useState<TSettings>();
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setError] = useState<boolean>(false);
const { i18n } = useI18N({ settings, user });
const { i18n } = useI18N({ settings });
const { currentDeviceType } = useDeviceType();
const { logoUrls } = useWhiteLabel();
const { theme } = useTheme({ user });
const { theme } = useTheme({});
const firebaseHelper = useMemo(() => {
return new FirebaseHelper(settings?.firebase ?? ({} as TFirebaseSettings));
}, [settings?.firebase]);
@ -63,13 +61,9 @@ export default function GlobalError({ error }: { error: Error }) {
const getData = useCallback(async () => {
try {
setIsLoading(true);
const [userData, settingsData] = await Promise.all([
getUser(),
getSettings(),
]);
const settingsData = await getSettings();
setSettings(settingsData);
setUser(userData);
} catch (error) {
setError(true);
console.error(error);
@ -93,7 +87,7 @@ export default function GlobalError({ error }: { error: Error }) {
i18nProp={i18n}
errorLog={error}
version={pkg.version}
user={user ?? ({} as TUser)}
user={{} as TUser}
whiteLabelLogoUrls={logoUrls}
firebaseHelper={firebaseHelper}
currentDeviceType={currentDeviceType}

View File

@ -24,21 +24,93 @@
// 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 "../styles/globals.scss";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
// import StyledComponentsRegistry from "@/utils/registry";
import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants";
import { getLanguage } from "@docspace/shared/utils/banner";
import StyledComponentsRegistry from "@/utils/registry";
import { DataContextProvider } from "@/providers/DataProvider";
import { checkIsAuthenticated, getData, updateCookie } from "@/utils/actions";
import SimpleNav from "@/components/SimpleNav";
import "../styles/globals.scss";
import { Toast } from "@docspace/shared/components/toast";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const cookieStore = cookies();
const isAuth = await checkIsAuthenticated();
if (isAuth) redirect("/");
const [
settings,
versionBuild,
colorTheme,
whiteLabel,
thirdPartyProvider,
capabilities,
ssoSettings,
] = await getData();
const ssoUrl = capabilities ? capabilities.ssoUrl : "";
const hideAuthPage = ssoSettings ? ssoSettings.hideAuthPage : false;
if (ssoUrl && hideAuthPage) {
redirect(ssoUrl);
}
if (settings.wizardToken) {
redirect("/wizard");
}
let currentLanguage: string = settings.culture ?? "en";
let standalone: boolean = settings.standalone ? true : false;
const cookieLang = cookieStore.get(LANGUAGE) as string | undefined;
if (cookieLang) {
currentLanguage = cookieLang;
} else {
// updateCookie(LANGUAGE, currentLanguage, {
// maxAge: COOKIE_EXPIRATION_YEAR,
// });
}
currentLanguage = getLanguage(currentLanguage);
return (
<html lang="en">
<head>
<link id="favicon" rel="shortcut icon" type="image/x-icon" />
</head>
<body>{children}</body>
<body>
<StyledComponentsRegistry>
<DataContextProvider
value={{
settings,
versionBuild,
colorTheme,
whiteLabel,
thirdPartyProvider,
capabilities,
ssoSettings,
currentLanguage,
standalone,
}}
>
<SimpleNav logoUrls={whiteLabel} />
<Toast isSSR />
{children}
</DataContextProvider>
</StyledComponentsRegistry>
</body>
</html>
);
}

View File

@ -24,18 +24,16 @@
// 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 { redirect } from "next/navigation";
"use server";
import { checkIsAuthenticated, getData } from "@/utils/actions";
import Login from "@/components/Login";
async function Page({}) {
const isAuth = await checkIsAuthenticated();
if (isAuth) redirect("/");
getData();
return <p>MAIN</p>;
async function Page({
searchParams,
}: {
searchParams: { [key: string]: string };
}) {
return <Login searchParams={searchParams} />;
}
export default Page;

View File

@ -0,0 +1,86 @@
/* eslint-disable @next/next/no-img-element */
// (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 { Trans, useTranslation } from "react-i18next";
import { Text } from "@docspace/shared/components/text";
import { GreetingContainersProps } from "@/types";
import { DEFAULT_PORTAL_TEXT, DEFAULT_ROOM_TEXT } from "@/utils/constants";
const GreetingContainer = ({
roomName,
firstName,
lastName,
greetingSettings,
logoUrl,
type,
}: GreetingContainersProps) => {
const { t } = useTranslation();
return (
<>
<img src={logoUrl} className="logo-wrapper" alt="greeting-logo" />
{type !== "invitation" && (
<Text
fontSize="23px"
fontWeight={700}
textAlign="center"
className="greeting-title"
>
{greetingSettings}
</Text>
)}
{type === "invitation" && (
<div className="greeting-container">
<Text fontSize="16px">
<Trans
t={t}
i18nKey={roomName ? "InvitationToRoom" : "InvitationToPortal"}
ns="Common"
defaults={roomName ? DEFAULT_ROOM_TEXT : DEFAULT_PORTAL_TEXT}
values={{
firstName,
lastName,
...(roomName
? { roomName }
: { spaceAddress: window.location.host }),
}}
components={{
1: <Text fontWeight={600} as="strong" fontSize="16px" />,
}}
/>
</Text>
</div>
)}
</>
);
};
export default GreetingContainer;

View File

@ -0,0 +1,143 @@
// (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 { Base } from "@docspace/shared/themes";
import { mobile, tablet } from "@docspace/shared/utils/device";
export const LoginFormWrapper = styled.div<{ bgPattern: string }>`
width: 100%;
height: 100vh;
box-sizing: border-box;
@media ${mobile} {
height: calc(100% - 48px);
}
.bg-cover {
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;
@media ${mobile} {
background-image: none;
}
}
.greeting-container {
margin-bottom: 40px;
max-width: 380px;
min-width: 380px;
@media ${tablet} {
max-width: 480px;
min-width: 480px;
}
@media ${mobile} {
max-width: 100%;
min-width: 100%;
}
p {
text-align: center;
}
}
.invitation-info-container {
margin-bottom: 16px;
.sign-in-container {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-bottom: 16px;
.back-title {
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;
}
}
}
}
`;
LoginFormWrapper.defaultProps = { theme: Base };
export const LoginContent = styled.div`
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;
height: 100%;
margin-top: 88px;
@media ${mobile} {
width: 100%;
justify-content: start;
margin-top: 34px;
}
`;
LoginContent.defaultProps = { theme: Base };

View File

@ -0,0 +1,199 @@
// (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
"use client";
import { useContext, useState, useCallback } from "react";
import { useTheme } from "styled-components";
import { TenantStatus } from "@docspace/shared/enums";
import { PROVIDERS_DATA } from "@docspace/shared/constants";
import {
getBgPattern,
getLoginLink,
getLogoFromPath,
getOAuthToken,
} from "@docspace/shared/utils/common";
import { checkIsSSR } from "@docspace/shared/utils/device";
import RecoverAccessModalDialog from "@docspace/shared/components/recover-access-modal-dialog/RecoverAccessModalDialog";
import { Scrollbar } from "@docspace/shared/components/scrollbar";
import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme";
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
import { DataContext } from "@/providers/DataProvider";
import { LoginProps } from "@/types";
import useRecoverDialog from "@/hooks/useRecoverDialog";
import GreetingContainer from "../GreetingContainer";
import { LoginContent, LoginFormWrapper } from "./Login.styled";
const Login = ({ searchParams }: LoginProps) => {
const [isLoading, setIsLoading] = useState(false);
const [invitationLinkData, setInvitationLinkData] = useState({
email: "",
roomName: "",
firstName: "",
lastName: "",
type: "",
});
const theme = useTheme();
const { settings, capabilities, thirdPartyProvider, whiteLabel } =
useContext(DataContext);
const {
recoverDialogVisible,
recoverDialogEmailPlaceholder,
recoverDialogTextBody,
openRecoverDialog,
closeRecoverDialog,
} = useRecoverDialog({});
const isRestoringPortal =
settings?.tenantStatus === TenantStatus.PortalRestore;
const ssoExists = () => {
if (capabilities?.ssoUrl) return true;
else return false;
};
const oauthDataExists = () => {
if (!capabilities?.oauthEnabled) return false;
let existProviders = 0;
if (thirdPartyProvider && thirdPartyProvider.length > 0)
thirdPartyProvider?.map((item) => {
if (!(item.provider in PROVIDERS_DATA)) return;
existProviders++;
});
return !!existProviders;
};
const onSocialButtonClick = useCallback(
async (e: React.MouseEvent<HTMLButtonElement | HTMLElement>) => {
const target = e.target as HTMLElement;
let targetElement = target;
if (
!(targetElement instanceof HTMLButtonElement) &&
target.parentElement
) {
targetElement = target.parentElement;
}
const providerName = targetElement.dataset.providername;
let url = targetElement.dataset.url || "";
try {
//Lifehack for Twitter
if (providerName == "twitter") {
url += "authCallback";
}
const tokenGetterWin =
window["AscDesktopEditor"] !== undefined
? (window.location.href = url)
: window.open(
url,
"login",
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no",
);
const code: string = await getOAuthToken(tokenGetterWin);
const token = window.btoa(
JSON.stringify({
auth: providerName,
mode: "popup",
callback: "authCallback",
}),
);
if (tokenGetterWin && typeof tokenGetterWin !== "string")
tokenGetterWin.location.href = getLoginLink(token, code);
} catch (err) {
console.log(err);
}
},
[],
);
const bgPattern = getBgPattern(theme.currentColorScheme?.id);
const isRegisterContainerVisible = !checkIsSSR() && settings.enabledJoin;
const logo = whiteLabel && Object.values(whiteLabel)[1];
const logoUrl = !logo
? undefined
: !theme?.isBase
? getLogoFromPath(logo.path.dark)
: getLogoFromPath(logo.path.light);
return (
<LoginFormWrapper id="login-page" bgPattern={bgPattern}>
<div className="bg-cover" />
<Scrollbar id="customScrollBar">
<LoginContent>
<ColorTheme
themeId={ThemeId.LinkForgotPassword}
isRegisterContainerVisible={isRegisterContainerVisible}
>
<GreetingContainer
roomName={invitationLinkData.roomName}
firstName={invitationLinkData.firstName}
lastName={invitationLinkData.lastName}
logoUrl={logoUrl}
greetingSettings={settings.greetingSettings}
type={invitationLinkData.type}
/>
<FormWrapper id="login-form">asd</FormWrapper>
</ColorTheme>
</LoginContent>
{isRegisterContainerVisible && (
<Register
id="login_register"
enabledJoin={enabledJoin}
currentColorScheme={currentColorScheme}
trustedDomains={portalSettings?.trustedDomains}
trustedDomainsType={portalSettings?.trustedDomainsType}
/>
)}
</Scrollbar>
{recoverDialogVisible && (
<RecoverAccessModalDialog
visible={recoverDialogVisible}
onClose={closeRecoverDialog}
textBody={recoverDialogTextBody}
emailPlaceholderText={recoverDialogEmailPlaceholder}
id="recover-access-modal"
/>
)}
</LoginFormWrapper>
);
};
export default Login;

View File

@ -0,0 +1,59 @@
// (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 { ModalDialog } from "@docspace/shared/components/modal-dialog";
import { tablet } from "@docspace/shared/utils";
const ModalDialogContainer = styled(ModalDialog)`
.modal-dialog-aside {
padding: 0;
}
.modal-dialog-aside-body {
padding: 0;
margin: 0;
}
.modal-dialog-aside-footer {
@media ${tablet} {
width: 90%;
}
}
.modal-dialog-button {
display: inline-block;
}
.field-body {
margin-top: 16px;
}
.email-reg-field {
margin: 0;
}
`;
export default ModalDialogContainer;

View File

@ -0,0 +1,49 @@
// (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 { Box } from "@docspace/shared/components/box";
import { Base } from "@docspace/shared/themes";
export const StyledRegister = styled(Box)`
position: absolute;
display: flex;
align-items: center;
justify-content: center;
z-index: 184;
width: 100%;
height: 68px;
padding: 1.5em;
bottom: 0;
${({ theme }) =>
theme.interfaceDirection === "rtl" ? `left: 0;` : `right: 0;`}
background-color: ${(props) => props.theme.login.register.backgroundColor};
cursor: pointer;
`;
StyledRegister.defaultProps = { theme: Base };

View File

@ -0,0 +1,149 @@
// (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 { useTranslation } from "react-i18next";
import { useTheme } from "styled-components";
import { Text } from "@docspace/shared/components/text";
import { toastr } from "@docspace/shared/components/toast";
import { TValidate } from "@docspace/shared/components/email-input/EmailInput.types";
import { sendRegisterRequest } from "@docspace/shared/api/settings";
import { RegisterProps } from "@/types";
import RegisterModalDialog from "./sub-components/RegisterModalDialog";
import { StyledRegister } from "./Register.styled";
const Register = (props: RegisterProps) => {
const {
enabledJoin,
isAuthenticated,
trustedDomainsType,
trustedDomains,
id,
} = props;
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const [email, setEmail] = useState("");
const [emailErr, setEmailErr] = useState(false);
const [errorText, setErrorText] = useState("");
const [isShowError, setIsShowError] = useState(false);
const theme = useTheme();
const { t } = useTranslation("Login");
const onRegisterClick = () => {
setVisible(true);
};
const onRegisterModalClose = () => {
setVisible(false);
setEmail("");
setEmailErr(false);
};
const onChangeEmail = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e) {
setEmail(e.currentTarget.value);
setEmailErr(false);
setIsShowError(false);
}
};
const onValidateEmail = (res: TValidate) => {
setEmailErr(!res.isValid);
setErrorText(res.errors ? res.errors[0] : "");
return undefined;
};
const onBlurEmail = () => {
setIsShowError(true);
};
const onSendRegisterRequest = async () => {
if (!email.trim() || emailErr) {
setEmailErr(true);
setIsShowError(true);
} else {
setLoading(true);
try {
const res = await sendRegisterRequest(email);
setLoading(false);
toastr.success(res as string);
} catch (e) {
setLoading(false);
toastr.error(e as string);
} finally {
onRegisterModalClose();
}
}
};
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === "Enter") {
onSendRegisterRequest();
e.preventDefault();
}
};
return enabledJoin && !isAuthenticated ? (
<>
<StyledRegister id={id} onClick={onRegisterClick}>
<Text as="span" color={theme.currentColorScheme?.main?.accent}>
{t("Register")}
</Text>
</StyledRegister>
{visible && (
<RegisterModalDialog
visible={visible}
loading={loading}
email={email}
emailErr={emailErr}
trustedDomainsType={trustedDomainsType}
trustedDomains={trustedDomains}
onChangeEmail={onChangeEmail}
onValidateEmail={onValidateEmail}
onBlurEmail={onBlurEmail}
onRegisterModalClose={onRegisterModalClose}
onSendRegisterRequest={onSendRegisterRequest}
onKeyDown={onKeyDown}
errorText={errorText}
isShowError={isShowError}
/>
)}
</>
) : (
<></>
);
};
export default Register;

View File

@ -0,0 +1,173 @@
// (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 { useTranslation } from "react-i18next";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { EmailInput } from "@docspace/shared/components/email-input";
import { Text } from "@docspace/shared/components/text";
import {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { FieldContainer } from "@docspace/shared/components/field-container";
import { TenantTrustedDomainsType } from "@docspace/shared/enums";
import ModalDialogContainer from "../../ModalDialogContainer";
import { RegisterModalDialogProps } from "@/types";
import { InputSize, InputType } from "@docspace/shared/components/text-input";
const RegisterModalDialog = ({
visible,
loading,
email,
emailErr,
onChangeEmail,
onValidateEmail,
onBlurEmail,
onRegisterModalClose,
onSendRegisterRequest,
onKeyDown,
trustedDomainsType,
trustedDomains,
errorText,
isShowError,
}: RegisterModalDialogProps) => {
const { t } = useTranslation(["Login", "Common"]);
React.useEffect(() => {
window.addEventListener("keydown", onKeyDown);
return () => {
window.removeEventListener("keydown", onKeyDown);
};
}, [onKeyDown]);
const getDomains = () => {
if (trustedDomains)
return trustedDomains.map((domain, i) => (
<span key={i}>
<b>
{domain}
{i === trustedDomains.length - 1 ? "." : ", "}
</b>
</span>
));
};
const getDomainsBlock = () => {
return trustedDomainsType === TenantTrustedDomainsType.Custom ? (
<>
{t("RegisterTextBodyBeforeDomainsList")} {getDomains()}{" "}
</>
) : (
<></>
);
};
return (
<ModalDialogContainer
id="registration-modal"
displayType={ModalDialogType.modal}
visible={visible}
onClose={onRegisterModalClose}
isLarge
>
<ModalDialog.Header>
<Text isBold fontSize="21px">
{t("RegisterTitle")}
</Text>
</ModalDialog.Header>
<ModalDialog.Body>
<Text key="text-body" isBold={false} fontSize="13px" noSelect>
{getDomainsBlock()}
{t("RegisterTextBodyAfterDomainsList")}
</Text>
<FieldContainer
className="email-reg-field"
key="e-mail"
isVertical
hasError={isShowError && emailErr}
labelVisible={false}
errorMessage={
errorText ? t(`Common:${errorText}`) : t("Common:RequiredField")
}
>
<EmailInput
hasError={isShowError && emailErr}
placeholder={t("Common:RegistrationEmail")}
isAutoFocussed
id="registration-modal_email"
name="e-mail"
type={InputType.email}
size={InputSize.base}
scale
tabIndex={1}
isDisabled={loading}
value={email}
onChange={onChangeEmail}
onValidateInput={onValidateEmail}
onBlur={onBlurEmail}
autoComplete="username"
/>
</FieldContainer>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
id="registration-modal_send"
className="modal-dialog-button"
key="RegisterSendBtn"
label={loading ? t("Common:Sending") : t("Common:SendRequest")}
size={ButtonSize.normal}
scale={false}
primary
onClick={onSendRegisterRequest}
isLoading={loading}
isDisabled={loading}
tabIndex={3}
/>
<Button
id="registration-modal_cancel"
className="modal-dialog-button"
key="CancelBtn"
label={t("Common:CancelButton")}
size={ButtonSize.normal}
scale={false}
primary={false}
onClick={onRegisterModalClose}
isLoading={loading}
isDisabled={loading}
tabIndex={2}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
};
export default RegisterModalDialog;

View File

@ -0,0 +1,81 @@
/* eslint-disable @next/next/no-img-element */
// (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
"use client";
import React, { useContext } from "react";
import styled from "styled-components";
import { mobile } from "@docspace/shared/utils/device";
import { getLogoFromPath, getSystemTheme } from "@docspace/shared/utils/common";
import { Base, Dark } from "@docspace/shared/themes";
import { TWhiteLabel } from "@docspace/shared/utils/whiteLabelHelper";
import { ThemeKeys } from "@docspace/shared/enums";
import { DataContext } from "@/providers/DataProvider";
const StyledSimpleNav = styled.div`
display: none;
height: 48px;
align-items: center;
justify-content: center;
background-color: ${(props) => props.theme?.login?.navBackground};
svg {
path:last-child {
fill: ${(props) => props.theme.client?.home?.logoColor};
}
}
@media ${mobile} {
display: flex;
}
`;
StyledSimpleNav.defaultProps = { theme: Base };
interface SimpleNavProps {
logoUrls: TWhiteLabel[];
}
const SimpleNav = ({ logoUrls }: SimpleNavProps) => {
const { theme } = useContext(DataContext);
const logo = logoUrls && Object.values(logoUrls)[0];
const logoUrl = !logo
? undefined
: ThemeKeys.BaseStr !== theme
? getLogoFromPath(logo.path.dark)
: getLogoFromPath(logo.path.light);
return (
<StyledSimpleNav id="login-header">
<img src={logoUrl} alt="logo-url" />
</StyledSimpleNav>
);
};
export default SimpleNav;

View File

@ -27,17 +27,17 @@
import React from "react";
import { i18n } from "i18next";
import { TSettings } from "@docspace/shared/api/settings/types";
import { TUser } from "@docspace/shared/api/people/types";
import { getI18NInstance } from "@/utils/i18n";
interface UseI18NProps {
settings?: TSettings;
user?: TUser;
}
const useI18N = ({ settings, user }: UseI18NProps) => {
const [i18n, setI18N] = React.useState<i18n>({} as i18n);
const useI18N = ({ settings }: UseI18NProps) => {
const [i18n, setI18N] = React.useState<i18n>(
getI18NInstance(settings?.culture ?? "en") ?? ({} as i18n),
);
const isInit = React.useRef(false);
@ -52,7 +52,7 @@ const useI18N = ({ settings, user }: UseI18NProps) => {
const instance = getI18NInstance(settings?.culture ?? "en");
if (instance) setI18N(instance);
}, [settings?.culture, user?.cultureName]);
}, [settings?.culture]);
return { i18n };
};

View File

@ -0,0 +1,58 @@
// (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 { useState } from "react";
import { useTranslation } from "react-i18next";
const useRecoverDialog = ({}) => {
const [recoverDialogVisible, setRecoverDialogVisible] = useState(false);
const { t } = useTranslation(["Login"]);
const openRecoverDialog = () => {
setRecoverDialogVisible(true);
};
const closeRecoverDialog = () => {
setRecoverDialogVisible(false);
};
const recoverDialogEmailPlaceholder = t(
"Login:RecoverContactEmailPlaceholder",
);
const recoverDialogTextBody = t("Login:RecoverTextBody");
return {
recoverDialogVisible,
recoverDialogEmailPlaceholder,
recoverDialogTextBody,
openRecoverDialog,
closeRecoverDialog,
};
};
export default useRecoverDialog;

View File

@ -30,15 +30,15 @@ import { Base, Dark, TColorScheme, TTheme } from "@docspace/shared/themes";
import { getSystemTheme } from "@docspace/shared/utils";
import { ThemeKeys } from "@docspace/shared/enums";
import { getAppearanceTheme } from "@docspace/shared/api/settings";
import { TUser } from "@docspace/shared/api/people/types";
import { TGetColorTheme } from "@docspace/shared/api/settings/types";
const SYSTEM_THEME = getSystemTheme();
export interface UseThemeProps {
user?: TUser;
colorTheme?: TGetColorTheme;
}
const useTheme = ({ user }: UseThemeProps) => {
const useTheme = ({ colorTheme }: UseThemeProps) => {
const [currentColorTheme, setCurrentColorTheme] =
React.useState<TColorScheme>({} as TColorScheme);
@ -52,23 +52,18 @@ const useTheme = ({ user }: UseThemeProps) => {
const getCurrentColorTheme = React.useCallback(async () => {
if (isRequestRunning.current) return;
isRequestRunning.current = true;
const colorThemes = await getAppearanceTheme();
const colorThemes = colorTheme ? colorTheme : await getAppearanceTheme();
const colorTheme = colorThemes.themes.find(
const currColorTheme = colorThemes.themes.find(
(t) => t.id === colorThemes.selected,
);
isRequestRunning.current = false;
if (colorTheme) setCurrentColorTheme(colorTheme);
}, []);
if (currColorTheme) setCurrentColorTheme(currColorTheme);
}, [colorTheme]);
const getUserTheme = React.useCallback(() => {
if (!user?.theme) return;
let theme = user.theme;
if (user.theme === ThemeKeys.SystemStr) theme = SYSTEM_THEME;
if (theme === ThemeKeys.BaseStr) {
if (SYSTEM_THEME === ThemeKeys.BaseStr) {
setTheme({
...Base,
currentColorScheme: currentColorTheme,
@ -83,7 +78,7 @@ const useTheme = ({ user }: UseThemeProps) => {
currentColorScheme: currentColorTheme,
interfaceDirection: "ltr",
});
}, [currentColorTheme, user?.theme]);
}, [currentColorTheme]);
React.useEffect(() => {
getCurrentColorTheme();

View File

@ -0,0 +1,66 @@
// (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
"use client";
import React from "react";
import { createContext } from "react";
import { I18nextProvider } from "react-i18next";
import { i18n } from "i18next";
import { getSystemTheme } from "@docspace/shared/utils";
import { ThemeProvider } from "@docspace/shared/components/theme-provider";
import { Base, Dark } from "@docspace/shared/themes";
import { ThemeKeys } from "@docspace/shared/enums";
import { TDataContext } from "@/types";
import { getI18NInstance } from "@/utils/i18n";
import useI18N from "@/hooks/useI18N";
import useTheme from "@/hooks/useTheme";
export const DataContext = createContext<TDataContext>({} as TDataContext);
export const DataContextProvider = ({
children,
value,
}: {
children: React.ReactNode;
value: TDataContext;
}) => {
const { i18n } = useI18N({ settings: value.settings });
const { theme } = useTheme({ colorTheme: value.colorTheme });
return (
<ThemeProvider theme={theme}>
<I18nextProvider i18n={i18n}>
<DataContext.Provider value={{ ...value, i18n }}>
{children}
</DataContext.Provider>
</I18nextProvider>
</ThemeProvider>
);
};

View File

@ -41,6 +41,8 @@ body {
padding: 0;
margin: 0;
overflow: hidden;
}
#root {
@ -56,4 +58,3 @@ body {
body.loading * {
cursor: wait !important;
}

View File

@ -23,3 +23,69 @@
// 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 { i18n } from "i18next";
import {
TCapabilities,
TGetColorTheme,
TGetSsoSettings,
TSettings,
TThirdPartyProvider,
TVersionBuild,
} from "@docspace/shared/api/settings/types";
import { TWhiteLabel } from "@docspace/shared/utils/whiteLabelHelper";
import { TValidate } from "@docspace/shared/components/email-input/EmailInput.types";
export type TDataContext = {
settings: TSettings;
versionBuild: TVersionBuild;
colorTheme: TGetColorTheme;
whiteLabel: TWhiteLabel[];
thirdPartyProvider: TThirdPartyProvider[] | undefined;
capabilities: TCapabilities | undefined;
ssoSettings: TGetSsoSettings | undefined;
currentLanguage: string;
standalone: boolean;
i18n?: i18n;
};
export type GreetingContainersProps = {
roomName?: string;
firstName?: string;
lastName?: string;
greetingSettings?: string;
logoUrl: string;
type: string;
};
export type LoginProps = {
searchParams: { [key: string]: string };
};
export type RegisterProps = {
language?: string;
isAuthenticated?: boolean;
enabledJoin: boolean;
trustedDomainsType?: number;
trustedDomains?: string[];
id?: string;
};
export type RegisterModalDialogProps = {
visible: boolean;
loading: boolean;
email?: string;
emailErr: boolean;
onChangeEmail: (e: React.ChangeEvent<HTMLInputElement>) => void;
onValidateEmail: (res: TValidate) => undefined;
onBlurEmail: () => void;
onSendRegisterRequest: () => void;
onKeyDown: (e: KeyboardEvent) => void;
onRegisterModalClose: () => void;
trustedDomainsType?: number;
trustedDomains?: string[];
errorText?: string;
isShowError?: boolean;
};

View File

@ -26,11 +26,12 @@
"use server";
import { headers } from "next/headers";
import { headers, cookies } from "next/headers";
import {
TCapabilities,
TGetColorTheme,
TGetSsoSettings,
TSettings,
TThirdPartyProvider,
TVersionBuild,
@ -132,6 +133,14 @@ export const getData = async () => {
TWhiteLabel[],
TThirdPartyProvider[] | undefined,
TCapabilities | undefined,
any,
TGetSsoSettings | undefined,
];
};
export const updateCookie = (name: string, value: string, options: object) => {
"use server";
const cookieStore = cookies();
cookieStore.set(name, value, options);
};

View File

@ -0,0 +1,30 @@
// (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
export const DEFAULT_ROOM_TEXT =
"<strong>{{firstName}} {{lastName}}</strong> invites you to join the room <strong>{{roomName}}</strong> for secure document collaboration.";
export const DEFAULT_PORTAL_TEXT =
"<strong>{{firstName}} {{lastName}}</strong> invites you to join the room <strong>{{roomName}}</strong> for secure document collaboration.";

View File

@ -0,0 +1,49 @@
// (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
export enum MessageKey {
"None",
"Error",
"ErrorUserNotFound",
"ErrorExpiredActivationLink",
"ErrorInvalidActivationLink",
"ErrorConfirmURLError",
"ErrorNotCorrectEmail",
"LoginWithBruteForce",
"RecaptchaInvalid",
"LoginWithAccountNotFound",
"InvalidUsernameOrPassword",
"SsoSettingsDisabled",
"ErrorNotAllowedOption",
"SsoSettingsEmptyToken",
"SsoSettingsNotValidToken",
"SsoSettingsCantCreateUser",
"SsoSettingsUserTerminated",
"SsoError",
"SsoAuthFailed",
"SsoAttributesNotFound",
"QuotaPaidUserLimitError",
}

View File

@ -33,10 +33,9 @@ import { translations } from "./autoGeneratedTranslations";
export const getI18NInstance = (portalLng: string) => {
if (typeof window === "undefined") return;
const currentLng = portalLng;
i18n.use(initReactI18next).init({
lng: portalLng,
// lng: portalLng,
lng: "ru",
fallbackLng: "en",
load: "currentOnly",

View File

@ -0,0 +1,105 @@
// (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 { thirdPartyLogin } from "@docspace/shared/utils/loginUtils";
import { TTranslation } from "@docspace/shared/types";
import { MessageKey } from "./enums";
export async function oAuthLogin(profile: string) {
let isSuccess = false;
try {
await thirdPartyLogin(profile);
isSuccess = true;
const redirectPath = localStorage.getItem("redirectPath");
if (redirectPath) {
localStorage.removeItem("redirectPath");
window.location.href = redirectPath;
}
} catch (e) {
isSuccess = false;
return isSuccess;
}
localStorage.removeItem("profile");
localStorage.removeItem("code");
return isSuccess;
}
export const getMessageFromKey = (messageKey: number) => {
return MessageKey[messageKey];
};
export const getMessageKeyTranslate = (t: TTranslation, message: string) => {
switch (message) {
case "Error":
return t("Common:Error");
case "None":
return t("Common:UnknownError");
case "ErrorUserNotFound":
return t("Errors:ErrorUserNotFound");
case "ErrorExpiredActivationLink":
return t("Errors:ErrorExpiredActivationLink");
case "ErrorInvalidActivationLink":
return t("Errors:ErrorInvalidActivationLink");
case "ErrorConfirmURLError":
return t("Errors:ErrorConfirmURLError");
case "ErrorNotCorrectEmail":
return t("Common:IncorrectEmail");
case "LoginWithBruteForce":
return t("Errors:LoginWithBruteForce");
case "RecaptchaInvalid":
return t("Errors:RecaptchaInvalid");
case "LoginWithAccountNotFound":
return t("Errors:LoginWithAccountNotFound");
case "InvalidUsernameOrPassword":
return t("Errors:InvalidUsernameOrPassword");
case "SsoSettingsDisabled":
return t("Errors:SsoSettingsDisabled");
case "ErrorNotAllowedOption":
return t("Errors:ErrorNotAllowedOption");
case "SsoSettingsEmptyToken":
return t("Errors:SsoSettingsEmptyToken");
case "SsoSettingsNotValidToken":
return t("Errors:SsoSettingsNotValidToken");
case "SsoSettingsCantCreateUser":
return t("Errors:SsoSettingsCantCreateUser");
case "SsoSettingsUserTerminated":
return t("Errors:SsoSettingsUserTerminated");
case "SsoError":
return t("Errors:SsoError");
case "SsoAuthFailed":
return t("Errors:SsoAuthFailed");
case "SsoAttributesNotFound":
return t("Errors:SsoAttributesNotFound");
case "QuotaPaidUserLimitError":
return t("Common:QuotaPaidUserLimitError");
default:
return t("Common:Error");
}
};

View File

@ -0,0 +1,56 @@
// (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
"use client";
import React, { useState } from "react";
import { ServerStyleSheet, StyleSheetManager } from "styled-components";
import { useServerInsertedHTML } from "next/navigation";
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode;
}) {
// Only create stylesheet once with lazy initial state
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement();
styledComponentsStyleSheet.instance.clearTag();
return <>{styles}</>;
});
if (typeof window !== "undefined") return <>{children}</>;
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
);
}

View File

@ -3191,6 +3191,7 @@ __metadata:
"@types/node": "npm:^20"
"@types/react": "npm:^18"
"@types/react-dom": "npm:^18"
babel-plugin-styled-components: "npm:^2.1.4"
eslint: "npm:^8"
eslint-config-next: "npm:14.0.4"
i18next: "npm:^20.6.1"
@ -11244,7 +11245,7 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-styled-components@npm:>= 1.12.0":
"babel-plugin-styled-components@npm:>= 1.12.0, babel-plugin-styled-components@npm:^2.1.4":
version: 2.1.4
resolution: "babel-plugin-styled-components@npm:2.1.4"
dependencies: