Fix Bug 69046 - Rooms. Added password dialog for public files
This commit is contained in:
parent
f23c55c98e
commit
35edf993ca
@ -54,14 +54,7 @@ export const ConfirmType = Object.freeze({
|
|||||||
* Enum for result of validation public room keys.
|
* Enum for result of validation public room keys.
|
||||||
* @readonly
|
* @readonly
|
||||||
*/
|
*/
|
||||||
export const ValidationStatus = Object.freeze({
|
|
||||||
Ok: 0,
|
|
||||||
Invalid: 1,
|
|
||||||
Expired: 2,
|
|
||||||
Password: 3,
|
|
||||||
InvalidPassword: 4,
|
|
||||||
ExternalAccessDenied: 5,
|
|
||||||
});
|
|
||||||
export const GUID_EMPTY = "00000000-0000-0000-0000-000000000000";
|
export const GUID_EMPTY = "00000000-0000-0000-0000-000000000000";
|
||||||
export const ID_NO_GROUP_MANAGER = "4a515a15-d4d6-4b8e-828e-e0586f18f3a3";
|
export const ID_NO_GROUP_MANAGER = "4a515a15-d4d6-4b8e-828e-e0586f18f3a3";
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { observer, inject } from "mobx-react";
|
|||||||
import { useParams, useSearchParams } from "react-router-dom";
|
import { useParams, useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
import api from "@docspace/shared/api";
|
import api from "@docspace/shared/api";
|
||||||
import { UrlActionType } from "@docspace/shared/enums";
|
import { UrlActionType, ValidationStatus } from "@docspace/shared/enums";
|
||||||
import { toastr } from "@docspace/shared/components/toast";
|
import { toastr } from "@docspace/shared/components/toast";
|
||||||
import MediaViewer from "@docspace/shared/components/media-viewer/MediaViewer";
|
import MediaViewer from "@docspace/shared/components/media-viewer/MediaViewer";
|
||||||
import { ViewerLoader } from "@docspace/shared/components/media-viewer/sub-components/ViewerLoader";
|
import { ViewerLoader } from "@docspace/shared/components/media-viewer/sub-components/ViewerLoader";
|
||||||
@ -17,8 +17,6 @@ import type {
|
|||||||
PlaylistType,
|
PlaylistType,
|
||||||
} from "@docspace/shared/components/media-viewer/MediaViewer.types";
|
} from "@docspace/shared/components/media-viewer/MediaViewer.types";
|
||||||
|
|
||||||
import { ValidationStatus } from "SRC_DIR/helpers/constants";
|
|
||||||
|
|
||||||
import type { PublicPreviewProps } from "./PublicPreview.types";
|
import type { PublicPreviewProps } from "./PublicPreview.types";
|
||||||
import { DEFAULT_EXTS_IMAGE } from "./PublicPreview.constants";
|
import { DEFAULT_EXTS_IMAGE } from "./PublicPreview.constants";
|
||||||
import { isAxiosError, useDeviceType } from "./PublicPreview.helpers";
|
import { isAxiosError, useDeviceType } from "./PublicPreview.helpers";
|
||||||
|
@ -29,7 +29,7 @@ import { observer, inject } from "mobx-react";
|
|||||||
import { useNavigate, useLocation, useSearchParams } from "react-router-dom";
|
import { useNavigate, useLocation, useSearchParams } from "react-router-dom";
|
||||||
import Section from "@docspace/shared/components/section";
|
import Section from "@docspace/shared/components/section";
|
||||||
import { Loader } from "@docspace/shared/components/loader";
|
import { Loader } from "@docspace/shared/components/loader";
|
||||||
import { ValidationStatus } from "../../helpers/constants";
|
import { ValidationStatus } from "@docspace/shared/enums";
|
||||||
import SectionWrapper from "SRC_DIR/components/Section";
|
import SectionWrapper from "SRC_DIR/components/Section";
|
||||||
import RoomPassword from "./sub-components/RoomPassword";
|
import RoomPassword from "./sub-components/RoomPassword";
|
||||||
import RoomErrors from "./sub-components/RoomErrors";
|
import RoomErrors from "./sub-components/RoomErrors";
|
||||||
|
@ -37,7 +37,7 @@ import { frameCallCommand } from "@docspace/shared/utils/common";
|
|||||||
import { toastr } from "@docspace/shared/components/toast";
|
import { toastr } from "@docspace/shared/components/toast";
|
||||||
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||||
import { ValidationStatus } from "../../../helpers/constants";
|
import { ValidationStatus } from "@docspace/shared/enums";
|
||||||
|
|
||||||
import PublicRoomIcon from "PUBLIC_DIR/images/icons/32/room/public.svg";
|
import PublicRoomIcon from "PUBLIC_DIR/images/icons/32/room/public.svg";
|
||||||
|
|
||||||
@ -167,6 +167,7 @@ const RoomPassword = (props) => {
|
|||||||
isDisabled={isLoading}
|
isDisabled={isLoading}
|
||||||
isDisableTooltip
|
isDisableTooltip
|
||||||
forwardedRef={inputRef}
|
forwardedRef={inputRef}
|
||||||
|
isAutoFocussed
|
||||||
/>
|
/>
|
||||||
</FieldContainer>
|
</FieldContainer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +38,8 @@ import {
|
|||||||
import { CategoryType } from "SRC_DIR/helpers/constants";
|
import { CategoryType } from "SRC_DIR/helpers/constants";
|
||||||
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
||||||
|
|
||||||
import { LinkType, ValidationStatus } from "../helpers/constants";
|
import { LinkType } from "../helpers/constants";
|
||||||
|
import { ValidationStatus } from "@docspace/shared/enums";
|
||||||
|
|
||||||
class PublicRoomStore {
|
class PublicRoomStore {
|
||||||
externalLinks = [];
|
externalLinks = [];
|
||||||
|
@ -29,9 +29,11 @@ import { headers } from "next/headers";
|
|||||||
|
|
||||||
import { getSelectorsByUserAgent } from "react-device-detect";
|
import { getSelectorsByUserAgent } from "react-device-detect";
|
||||||
|
|
||||||
import { getData } from "@/utils/actions";
|
import { getData, validatePublicRoomKey } from "@/utils/actions";
|
||||||
import { RootPageProps } from "@/types";
|
import { RootPageProps } from "@/types";
|
||||||
import Root from "@/components/Root";
|
import Root from "@/components/Root";
|
||||||
|
import FilePassword from "@/components/file-password";
|
||||||
|
import { ValidationStatus } from "@docspace/shared/enums";
|
||||||
|
|
||||||
const initialSearchParams: RootPageProps["searchParams"] = {
|
const initialSearchParams: RootPageProps["searchParams"] = {
|
||||||
fileId: undefined,
|
fileId: undefined,
|
||||||
@ -58,6 +60,17 @@ async function Page({ searchParams }: RootPageProps) {
|
|||||||
if (isMobile) type = "mobile";
|
if (isMobile) type = "mobile";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (share) {
|
||||||
|
const roomData = await validatePublicRoomKey(share, fileId ?? fileid ?? "");
|
||||||
|
if (!roomData) return;
|
||||||
|
|
||||||
|
const { status } = roomData.response;
|
||||||
|
|
||||||
|
if (status === ValidationStatus.Password) {
|
||||||
|
return <FilePassword {...roomData.response} shareKey={share} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const startDate = new Date();
|
const startDate = new Date();
|
||||||
|
|
||||||
const data = await getData(
|
const data = await getData(
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
// (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 { mobile, tablet } from "@docspace/shared/utils";
|
||||||
|
import { isIOS, isFirefox } from "react-device-detect";
|
||||||
|
|
||||||
|
import BackgroundPatternReactSvgUrl from "PUBLIC_DIR/images/background.pattern.react.svg?url";
|
||||||
|
|
||||||
|
export const StyledPage = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-image: url("${BackgroundPatternReactSvgUrl}");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
.logo-wrapper {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media ${mobile} {
|
||||||
|
background-image: none;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
.logo-wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
height: ${isIOS && !isFirefox ? "calc(var(--vh, 1vh) * 100)" : "100vh"};
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
@media ${tablet} {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media ${mobile} {
|
||||||
|
${(props) =>
|
||||||
|
props.theme.interfaceDirection === "rtl"
|
||||||
|
? css`
|
||||||
|
padding: 0 16px 0 8px;
|
||||||
|
`
|
||||||
|
: css`
|
||||||
|
padding: 0 8px 0 16px;
|
||||||
|
`}
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-form {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-room-content {
|
||||||
|
padding-top: 9%;
|
||||||
|
justify-content: unset;
|
||||||
|
min-height: unset;
|
||||||
|
|
||||||
|
.public-room-text {
|
||||||
|
margin: 8px 0;
|
||||||
|
white-space: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-room-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-room-icon {
|
||||||
|
min-width: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
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} {
|
||||||
|
justify-content: start;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
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: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 StyledSimpleNav = styled.div`
|
||||||
|
display: none;
|
||||||
|
height: 48px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: ${(props) => props.theme?.login?.navBackground};
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media ${mobile} {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.language-combo-box {
|
||||||
|
position: absolute;
|
||||||
|
top: 7px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
@ -0,0 +1,34 @@
|
|||||||
|
// (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 interface FilePasswordProps {
|
||||||
|
shareKey: string;
|
||||||
|
title: string;
|
||||||
|
id: string;
|
||||||
|
status: string;
|
||||||
|
roomType: string;
|
||||||
|
entryTitle: string;
|
||||||
|
}
|
212
packages/doceditor/src/components/file-password/index.tsx
Normal file
212
packages/doceditor/src/components/file-password/index.tsx
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
// (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 { Trans, useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { Text } from "@docspace/shared/components/text";
|
||||||
|
import { Button, ButtonSize } from "@docspace/shared/components/button";
|
||||||
|
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||||
|
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||||
|
import { FormWrapper } from "@docspace/shared/components/form-wrapper";
|
||||||
|
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||||
|
|
||||||
|
import {
|
||||||
|
StyledPage,
|
||||||
|
StyledContent,
|
||||||
|
StyledBody,
|
||||||
|
StyledSimpleNav,
|
||||||
|
} from "./FilePassword.styled";
|
||||||
|
import { FilePasswordProps } from "./FilePassword.types";
|
||||||
|
|
||||||
|
import PublicRoomIcon from "PUBLIC_DIR/images/icons/32/room/public.svg";
|
||||||
|
import { InputSize, InputType } from "@docspace/shared/components/text-input";
|
||||||
|
import { toastr } from "@docspace/shared/components/toast";
|
||||||
|
import { TData } from "@docspace/shared/components/toast/Toast.type";
|
||||||
|
|
||||||
|
import { getLogoUrl } from "@docspace/shared/utils";
|
||||||
|
import { useTheme } from "styled-components";
|
||||||
|
import { ValidationStatus, WhiteLabelLogoType } from "@docspace/shared/enums";
|
||||||
|
import { validatePublicRoomPassword } from "@docspace/shared/api/rooms";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
const FilesPassword = ({ shareKey, title, entryTitle }: FilePasswordProps) => {
|
||||||
|
const { t } = useTranslation(["Common"]);
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [passwordValid, setPasswordValid] = useState(true);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
|
|
||||||
|
const onChangePassword = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPassword(e.target.value);
|
||||||
|
!passwordValid && setPasswordValid(true);
|
||||||
|
};
|
||||||
|
const onKeyPress = (event: React.KeyboardEvent) => {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
onSubmit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (!password.trim()) {
|
||||||
|
setPasswordValid(false);
|
||||||
|
setErrorMessage(t("Common:RequiredField"));
|
||||||
|
} else {
|
||||||
|
setErrorMessage("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passwordValid || !password.trim()) {
|
||||||
|
setIsLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await validatePublicRoomPassword(shareKey, password);
|
||||||
|
|
||||||
|
if (res?.status === ValidationStatus.Ok) {
|
||||||
|
return window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(false);
|
||||||
|
|
||||||
|
if (res?.status === ValidationStatus.InvalidPassword) {
|
||||||
|
setErrorMessage(t("Common:IncorrectPassword"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
toastr.error(error as TData);
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const logoUrl = getLogoUrl(WhiteLabelLogoType.LoginPage, !theme.isBase);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<StyledSimpleNav id="login-header">
|
||||||
|
<Image
|
||||||
|
className="logo"
|
||||||
|
src={logoUrl}
|
||||||
|
priority
|
||||||
|
alt="mobile-icon"
|
||||||
|
width={211}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</StyledSimpleNav>
|
||||||
|
<StyledPage>
|
||||||
|
<StyledContent className="public-room-content">
|
||||||
|
<StyledBody>
|
||||||
|
<Image
|
||||||
|
priority
|
||||||
|
src={logoUrl}
|
||||||
|
className="logo-wrapper"
|
||||||
|
alt="icon"
|
||||||
|
width={416}
|
||||||
|
height={200}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormWrapper>
|
||||||
|
<div className="password-form">
|
||||||
|
<Text fontSize="16px" fontWeight="600">
|
||||||
|
{t("Common:PasswordRequired")}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
fontSize="13px"
|
||||||
|
fontWeight="400"
|
||||||
|
className="public-room-text"
|
||||||
|
>
|
||||||
|
<Trans
|
||||||
|
t={t}
|
||||||
|
ns="Common"
|
||||||
|
i18nKey="EnterPasswordDescription"
|
||||||
|
values={{ fileName: entryTitle }}
|
||||||
|
components={{ 1: <span className="bold" /> }}
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
<div className="public-room-name">
|
||||||
|
<PublicRoomIcon className="public-room-icon" />
|
||||||
|
<Text
|
||||||
|
className="public-room-text"
|
||||||
|
fontSize="15px"
|
||||||
|
fontWeight="600"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FieldContainer
|
||||||
|
isVertical={true}
|
||||||
|
labelVisible={false}
|
||||||
|
hasError={!!errorMessage}
|
||||||
|
errorMessage={errorMessage}
|
||||||
|
>
|
||||||
|
<PasswordInput
|
||||||
|
simpleView
|
||||||
|
id="password"
|
||||||
|
inputName="password"
|
||||||
|
placeholder={t("Common:Password")}
|
||||||
|
type={InputType.password}
|
||||||
|
inputValue={password}
|
||||||
|
hasError={!!errorMessage}
|
||||||
|
size={InputSize.large}
|
||||||
|
scale
|
||||||
|
tabIndex={1}
|
||||||
|
autoComplete="current-password"
|
||||||
|
onChange={onChangePassword}
|
||||||
|
onKeyDown={onKeyPress}
|
||||||
|
isDisabled={isLoading}
|
||||||
|
isDisableTooltip
|
||||||
|
isAutoFocussed
|
||||||
|
// forwardedRef={inputRef}
|
||||||
|
/>
|
||||||
|
</FieldContainer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
size={ButtonSize.medium}
|
||||||
|
scale
|
||||||
|
label={t("Common:ContinueButton")}
|
||||||
|
tabIndex={5}
|
||||||
|
onClick={onSubmit}
|
||||||
|
isDisabled={isLoading}
|
||||||
|
/>
|
||||||
|
</FormWrapper>
|
||||||
|
</StyledBody>
|
||||||
|
</StyledContent>
|
||||||
|
</StyledPage>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilesPassword;
|
@ -393,6 +393,22 @@ export const checkIsAuthenticated = async () => {
|
|||||||
return isAuth.response as boolean;
|
return isAuth.response as boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export async function validatePublicRoomKey(key: string, fileId?: string) {
|
||||||
|
const [validatePublicRoomKey] = createRequest(
|
||||||
|
[`/files/share/${key}?fileid=${fileId}`],
|
||||||
|
[key ? ["Request-Token", key] : ["", ""]],
|
||||||
|
"GET",
|
||||||
|
);
|
||||||
|
|
||||||
|
const res = await fetch(validatePublicRoomKey);
|
||||||
|
if (res.status === 401) return undefined;
|
||||||
|
if (!res.ok) return;
|
||||||
|
|
||||||
|
const room = await res.json();
|
||||||
|
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
// export async function checkFillFromDraft(
|
// export async function checkFillFromDraft(
|
||||||
// templateFileId: number,
|
// templateFileId: number,
|
||||||
// share?: string,
|
// share?: string,
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
toUrlParams,
|
toUrlParams,
|
||||||
} from "../../utils/common";
|
} from "../../utils/common";
|
||||||
import RoomsFilter from "./filter";
|
import RoomsFilter from "./filter";
|
||||||
import { TGetRooms } from "./types";
|
import { TGetRooms, TPublicRoomPassword } from "./types";
|
||||||
|
|
||||||
export async function getRooms(filter: RoomsFilter, signal?: AbortSignal) {
|
export async function getRooms(filter: RoomsFilter, signal?: AbortSignal) {
|
||||||
let params;
|
let params;
|
||||||
@ -452,12 +452,17 @@ export function validatePublicRoomKey(key) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validatePublicRoomPassword(key, passwordHash) {
|
export async function validatePublicRoomPassword(
|
||||||
return request({
|
key: string,
|
||||||
|
passwordHash: string,
|
||||||
|
) {
|
||||||
|
const res = (await request({
|
||||||
method: "post",
|
method: "post",
|
||||||
url: `files/share/${key}/password`,
|
url: `files/share/${key}/password`,
|
||||||
data: { password: passwordHash },
|
data: { password: passwordHash },
|
||||||
});
|
})) as TPublicRoomPassword;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setCustomRoomQuota(roomIds, quota) {
|
export function setCustomRoomQuota(roomIds, quota) {
|
||||||
|
@ -25,7 +25,12 @@
|
|||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
import { TFile, TFolder } from "../files/types";
|
import { TFile, TFolder } from "../files/types";
|
||||||
import { FolderType, RoomsType, ShareAccessRights } from "../../enums";
|
import {
|
||||||
|
FolderType,
|
||||||
|
RoomsType,
|
||||||
|
ShareAccessRights,
|
||||||
|
ValidationStatus,
|
||||||
|
} from "../../enums";
|
||||||
import { TCreatedBy, TPathParts } from "../../types";
|
import { TCreatedBy, TPathParts } from "../../types";
|
||||||
|
|
||||||
export type TLogo = {
|
export type TLogo = {
|
||||||
@ -91,3 +96,10 @@ export type TGetRooms = {
|
|||||||
total: number;
|
total: number;
|
||||||
new: number;
|
new: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TPublicRoomPassword = {
|
||||||
|
linkId: string;
|
||||||
|
shared: boolean;
|
||||||
|
status: ValidationStatus;
|
||||||
|
tenantId: string | number;
|
||||||
|
};
|
||||||
|
@ -593,3 +593,12 @@ export enum FileExtensions {
|
|||||||
XLSX = "xlsx",
|
XLSX = "xlsx",
|
||||||
PPTX = "pptx",
|
PPTX = "pptx",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ValidationStatus {
|
||||||
|
Ok = 0,
|
||||||
|
Invalid = 1,
|
||||||
|
Expired = 2,
|
||||||
|
Password = 3,
|
||||||
|
InvalidPassword = 4,
|
||||||
|
ExternalAccessDenied = 5,
|
||||||
|
}
|
||||||
|
@ -277,6 +277,8 @@
|
|||||||
"MyDocuments": "My documents",
|
"MyDocuments": "My documents",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"NeedPassword": "You need a password to access the room",
|
"NeedPassword": "You need a password to access the room",
|
||||||
|
"EnterPasswordDescription": "File «<1>{{fileName}}</1>» is located in the password-protected room. Please enter a password for the room",
|
||||||
|
"PasswordRequired": "Password required",
|
||||||
"NewDocument": "New document",
|
"NewDocument": "New document",
|
||||||
"NewFolder": "New folder",
|
"NewFolder": "New folder",
|
||||||
"NewMasterForm": "New form template",
|
"NewMasterForm": "New form template",
|
||||||
|
Loading…
Reference in New Issue
Block a user