From d4e867ff27a30d51cb1a2a17af8e94bd27db1718 Mon Sep 17 00:00:00 2001 From: Marc Seitz Date: Sun, 12 Jan 2025 18:13:22 +0100 Subject: [PATCH] feat(notion): add signed file url script for new way how notion handles file signatures --- lib/notion/utils.ts | 75 ++++++++++++++++++++++++++++++++++ pages/api/file/notion/index.ts | 5 ++- pages/api/views-dataroom.ts | 5 ++- pages/view/[linkId]/index.tsx | 5 ++- 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 lib/notion/utils.ts diff --git a/lib/notion/utils.ts b/lib/notion/utils.ts new file mode 100644 index 000000000..730088e58 --- /dev/null +++ b/lib/notion/utils.ts @@ -0,0 +1,75 @@ +import { NotionAPI } from "notion-client"; +import { getPageContentBlockIds } from "notion-utils"; + +import notion from "./index"; + +export const addSignedUrls: NotionAPI["addSignedUrls"] = async ({ + recordMap, + contentBlockIds, + kyOptions, +}) => { + recordMap.signed_urls = {}; + + if (!contentBlockIds) { + contentBlockIds = getPageContentBlockIds(recordMap); + } + + const allFileInstances = contentBlockIds.flatMap((blockId) => { + const block = recordMap.block[blockId]?.value; + + if ( + block && + (block.type === "pdf" || + block.type === "audio" || + (block.type === "image" && block.file_ids?.length) || + block.type === "video" || + block.type === "file" || + block.type === "page") + ) { + const source = + block.type === "page" + ? block.format?.page_cover + : block.properties?.source?.[0]?.[0]; + + if (source) { + if ( + source.includes("secure.notion-static.com") || + source.includes("prod-files-secure") + ) { + return { + permissionRecord: { + table: "block", + id: block.id, + }, + url: source, + }; + } + } + } + + return []; + }); + + if (allFileInstances.length > 0) { + try { + const { signedUrls } = await notion.getSignedFileUrls( + allFileInstances, + kyOptions, + ); + + if (signedUrls.length === allFileInstances.length) { + for (const [i, file] of allFileInstances.entries()) { + const signedUrl = signedUrls[i]; + if (!signedUrl) continue; + + const blockId = file.permissionRecord.id; + if (!blockId) continue; + + recordMap.signed_urls[blockId] = signedUrl; + } + } + } catch (err) { + console.warn("NotionAPI getSignedfileUrls error", err); + } + } +}; diff --git a/pages/api/file/notion/index.ts b/pages/api/file/notion/index.ts index e0a55d8da..4f6aa7ca9 100644 --- a/pages/api/file/notion/index.ts +++ b/pages/api/file/notion/index.ts @@ -1,6 +1,7 @@ import { NextApiRequest, NextApiResponse } from "next"; import notion from "@/lib/notion"; +import { addSignedUrls } from "@/lib/notion/utils"; import { log } from "@/lib/utils"; export default async function handle( @@ -23,7 +24,9 @@ export default async function handle( const { pageId } = req.body as { pageId: string }; try { - const recordMap = await notion.getPage(pageId); + const recordMap = await notion.getPage(pageId, { signFileUrls: false }); + // TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817 + await addSignedUrls({ recordMap }); if (!recordMap) { res.status(500).json({ message: "Internal Server Error" }); diff --git a/pages/api/views-dataroom.ts b/pages/api/views-dataroom.ts index 46ec75888..64a49cb23 100644 --- a/pages/api/views-dataroom.ts +++ b/pages/api/views-dataroom.ts @@ -12,6 +12,7 @@ import { sendOtpVerificationEmail } from "@/lib/emails/send-email-otp-verificati import { getFile } from "@/lib/files/get-file"; import { newId } from "@/lib/id-helper"; import notion from "@/lib/notion"; +import { addSignedUrls } from "@/lib/notion/utils"; import prisma from "@/lib/prisma"; import { ratelimit } from "@/lib/redis"; import { parseSheet } from "@/lib/sheet"; @@ -650,7 +651,9 @@ export default async function handle( } const pageId = notionPageId; - recordMap = await notion.getPage(pageId); + recordMap = await notion.getPage(pageId, { signFileUrls: false }); + // TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817 + await addSignedUrls({ recordMap }); } if (documentVersion.type === "sheet") { diff --git a/pages/view/[linkId]/index.tsx b/pages/view/[linkId]/index.tsx index 7412588d9..7e90c9435 100644 --- a/pages/view/[linkId]/index.tsx +++ b/pages/view/[linkId]/index.tsx @@ -16,6 +16,7 @@ import DataroomView from "@/components/view/dataroom/dataroom-view"; import DocumentView from "@/components/view/document-view"; import notion from "@/lib/notion"; +import { addSignedUrls } from "@/lib/notion/utils"; import { CustomUser, LinkWithDataroom, @@ -93,7 +94,9 @@ export const getStaticProps = async (context: GetStaticPropsContext) => { } pageId = notionPageId; - recordMap = await notion.getPage(pageId); + recordMap = await notion.getPage(pageId, { signFileUrls: false }); + // TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817 + await addSignedUrls({ recordMap }); } const { team, teamId, advancedExcelEnabled, ...linkDocument } =