Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions components/view/DataroomViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from "next/link";

import { useState } from "react";
import { useEffect, useState } from "react";
import React from "react";

import { Brand, Dataroom, DataroomBrand, DataroomFolder } from "@prisma/client";
Expand Down Expand Up @@ -32,6 +32,7 @@ import DocumentCard from "./dataroom/document-card";
import FolderCard from "./dataroom/folder-card";
import DataroomNav from "./dataroom/nav-dataroom";
import Nav from "./nav";
import { useRouter } from "next/router";

type DataroomDocument = {
dataroomDocumentId: string;
Expand All @@ -53,6 +54,7 @@ export default function DataroomViewer({
dataroom,
setViewType,
setDocumentData,
setDataroomVerified,
}: {
brand: Partial<DataroomBrand>;
viewId: string;
Expand All @@ -71,14 +73,39 @@ export default function DataroomViewer({
documentVersionNumber: number;
} | null>
>;
setDataroomVerified: React.Dispatch<React.SetStateAction<boolean>>;
}) {
const router = useRouter();
const [folderId, setFolderId] = useState<string | null>(null);
const { documents, folders } = dataroom as {
documents: DataroomDocument[];
folders: DataroomFolder[];
};

console.log("dataroom", dataroom);
useEffect(() => {
// Remove token and email query parameters on component mount
const removeQueryParams = () => {
const currentQuery = { ...router.query };

if (!currentQuery.token && !currentQuery.email) return;

setDataroomVerified(true);
delete currentQuery.token;
delete currentQuery.email;

router.replace(
{
pathname: router.pathname,
query: currentQuery,
},
undefined,
{ shallow: true },
);
};

removeQueryParams();
}, []); // Run once on mount

return (
<>
<DataroomNav brand={brand} viewId={viewId} dataroom={dataroom} />
Expand Down Expand Up @@ -161,7 +188,6 @@ export default function DataroomViewer({
folders
.filter((folder) => folder.id === folderId)
.map((folder, index: number, array) => {
console.log("folder", folder);
return (
<React.Fragment key={index}>
<BreadcrumbSeparator />
Expand Down
26 changes: 24 additions & 2 deletions components/view/PagesViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,29 @@ export default function PagesViewer({
index < DEFAULT_PRELOADED_IMAGES_NUM ? true : loaded,
),
);
}, []);
}, []); // Run once on mount

useEffect(() => {
// Remove token and email query parameters on component mount
const removeQueryParams = () => {
const currentQuery = { ...router.query };
delete currentQuery.token;
delete currentQuery.email;

router.replace(
{
pathname: router.pathname,
query: currentQuery,
},
undefined,
{ shallow: true },
);
};

if (!dataroomId) {
removeQueryParams();
}
}, []); // Run once on mount

const handleKeyDown = (event: KeyboardEvent) => {
switch (event.key) {
Expand Down Expand Up @@ -331,7 +353,7 @@ export default function PagesViewer({
</div>
) : null}
</div>
{feedbackEnabled && pageNumber !== numPagesWithFeedback ? (
{feedbackEnabled && pageNumber !== numPages + 1 ? (
<Toolbar viewId={viewId} pageNumber={pageNumber} />
) : null}
{screenshotProtectionEnabled ? <ScreenProtector /> : null}
Expand Down
24 changes: 20 additions & 4 deletions components/view/dataroom/dataroom-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export default function DataroomView({
);
const [verificationRequested, setVerificationRequested] =
useState<boolean>(false);
const [dataroomVerified, setDataroomVerified] = useState<boolean>(false);
const [documentData, setDocumentData] = useState<{
id: string;
name: string;
Expand Down Expand Up @@ -98,6 +99,7 @@ export default function DataroomView({
hasPages: documentData?.hasPages,
token: token ?? null,
verifiedEmail: verifiedEmail ?? null,
dataroomVerified: dataroomVerified,
dataroomId: dataroom?.id,
linkType: linkType,
dataroomViewId: viewData.dataroomViewId ?? null,
Expand Down Expand Up @@ -139,8 +141,23 @@ export default function DataroomView({
setIsLoading(false);
}
} else {
const { message } = await response.json();
toast.error(message);
const data = await response.json();
toast.error(data.message);

if (data.resetVerification) {
const currentQuery = { ...router.query };
delete currentQuery.token;
delete currentQuery.email;

router.replace(
{
pathname: router.pathname,
query: currentQuery,
},
undefined,
{ shallow: true },
);
}
setIsLoading(false);
}
};
Expand All @@ -155,7 +172,6 @@ export default function DataroomView({
// If token is present, run handle submit which will verify token and get document
// If link is not submitted and does not have email / password protection, show the access form
useEffect(() => {
console.log("viewData", viewData);
if (!didMount.current) {
if ((!submitted && !isProtected) || token || viewData.dataroomViewId) {
handleSubmission();
Expand All @@ -165,7 +181,6 @@ export default function DataroomView({
}, [submitted, isProtected, token, viewData.dataroomViewId]);

useEffect(() => {
console.log("documentData", documentData);
// Ensure we're not running this logic on initial mount, but only when `documentData` changes thereafter
if (didMount.current) {
if (documentData !== null) {
Expand Down Expand Up @@ -263,6 +278,7 @@ export default function DataroomView({
dataroom={dataroom}
setDocumentData={setDocumentData}
setViewType={setViewType}
setDataroomVerified={setDataroomVerified}
/>
</div>
);
Expand Down
19 changes: 17 additions & 2 deletions components/view/document-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,23 @@ export default function DocumentView({
setIsLoading(false);
}
} else {
const { message } = await response.json();
toast.error(message);
const data = await response.json();
toast.error(data.message);

if (data.resetVerification) {
const currentQuery = { ...router.query };
delete currentQuery.token;
delete currentQuery.email;

router.replace(
{
pathname: router.pathname,
query: currentQuery,
},
undefined,
{ shallow: true },
);
}
setIsLoading(false);
}
};
Expand Down
26 changes: 21 additions & 5 deletions pages/api/views-dataroom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default async function handle(
token,
ownerId,
verifiedEmail,
dataroomVerified,
linkType,
dataroomViewId,
viewType,
Expand All @@ -47,6 +48,7 @@ export default async function handle(
token: string | null;
ownerId: string | null;
verifiedEmail: string | null;
dataroomVerified: boolean | undefined;
linkType: string;
dataroomViewId?: string;
viewType: "DATAROOM_VIEW" | "DOCUMENT_VIEW";
Expand Down Expand Up @@ -152,10 +154,10 @@ export default async function handle(
}

// Check if email verification is required for visiting the link
if (link.emailAuthenticated && !token) {
if (link.emailAuthenticated && !token && !dataroomVerified) {
const token = newId("email");
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 1); // token expires in 1 hour
expiresAt.setMinutes(expiresAt.getMinutes() + 20); // token expires in 20 minutes

await prisma.verificationToken.create({
data: {
Expand All @@ -166,7 +168,7 @@ export default async function handle(
});

// set the default verification url
let verificationUrl: string = `${process.env.NEXT_PUBLIC_BASE_URL}/view/d/${linkId}/?token=${token}&email=${encodeURIComponent(email)}`;
let verificationUrl: string = `${process.env.NEXT_PUBLIC_BASE_URL}/view/${linkId}/?token=${token}&email=${encodeURIComponent(email)}`;

if (link.domainSlug && link.slug) {
// if custom domain is enabled, use the custom domain
Expand All @@ -182,7 +184,7 @@ export default async function handle(
}

let isEmailVerified: boolean = false;
if (link.emailAuthenticated && token) {
if (link.emailAuthenticated && token && !dataroomVerified) {
const verification = await prisma.verificationToken.findUnique({
where: {
token: token,
Expand All @@ -191,7 +193,10 @@ export default async function handle(
});

if (!verification) {
res.status(401).json({ message: "Unauthorized access" });
res.status(401).json({
message: "Unauthorized access. Request new access.",
resetVerification: true,
});
return;
}

Expand All @@ -201,6 +206,17 @@ export default async function handle(
return;
}

// delete the token after verification
await prisma.verificationToken.delete({
where: {
token: token,
},
});

isEmailVerified = true;
}

if (link.emailAuthenticated && dataroomVerified) {
isEmailVerified = true;
}

Expand Down
14 changes: 12 additions & 2 deletions pages/api/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default async function handle(
if (link.emailAuthenticated && !token) {
const token = newId("email");
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 1); // token expires in 1 hour
expiresAt.setMinutes(expiresAt.getMinutes() + 20); // token expires in 20 minutes

await prisma.verificationToken.create({
data: {
Expand Down Expand Up @@ -179,7 +179,10 @@ export default async function handle(
});

if (!verification) {
res.status(401).json({ message: "Unauthorized access" });
res.status(401).json({
message: "Unauthorized access. Request new access.",
resetVerification: true,
});
return;
}

Expand All @@ -189,6 +192,13 @@ export default async function handle(
return;
}

// delete the token after verification
await prisma.verificationToken.delete({
where: {
token: token,
},
});

isEmailVerified = true;
}

Expand Down