From 80c758fb6283b7bf3183740033a25436694c82fa Mon Sep 17 00:00:00 2001 From: Timur Ercan Date: Fri, 12 Apr 2024 15:37:08 +0200 Subject: [PATCH 1/4] chore: audit log menu item label (#1102) --- .../(dashboard)/documents/[id]/document-page-view-dropdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx b/apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx index 7b6bb8a91..0fb592ea1 100644 --- a/apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx +++ b/apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx @@ -118,7 +118,7 @@ export const DocumentPageViewDropdown = ({ document, team }: DocumentPageViewDro - Logs + Audit Log From 0f87dc047b475a65b9c76cf2735dad8c406fde28 Mon Sep 17 00:00:00 2001 From: Catalin Pit <25515812+catalinpit@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:27:46 +0300 Subject: [PATCH 2/4] fix: swagger documentation authentication (#1037) ## Summary by CodeRabbit - **Refactor** - Enhanced the API specification generation process to include operation IDs, security schemes, and security definitions more efficiently. --------- Co-authored-by: Lucas Smith --- packages/api/v1/openapi.ts | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/api/v1/openapi.ts b/packages/api/v1/openapi.ts index af0582195..55ec4d7fd 100644 --- a/packages/api/v1/openapi.ts +++ b/packages/api/v1/openapi.ts @@ -2,16 +2,34 @@ import { generateOpenApi } from '@ts-rest/open-api'; import { ApiContractV1 } from './contract'; -export const OpenAPIV1 = generateOpenApi( - ApiContractV1, - { - info: { - title: 'Documenso API', - version: '1.0.0', - description: 'The Documenso API for retrieving, creating, updating and deleting documents.', +export const OpenAPIV1 = Object.assign( + generateOpenApi( + ApiContractV1, + { + info: { + title: 'Documenso API', + version: '1.0.0', + description: 'The Documenso API for retrieving, creating, updating and deleting documents.', + }, }, - }, + { + setOperationId: true, + }, + ), { - setOperationId: true, + components: { + securitySchemes: { + authorization: { + type: 'apiKey', + in: 'header', + name: 'Authorization', + }, + }, + }, + security: [ + { + authorization: [], + }, + ], }, ); From c8a09099a372568ed1c2b0ac47acac3ceb2be243 Mon Sep 17 00:00:00 2001 From: Catalin Pit <25515812+catalinpit@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:29:56 +0300 Subject: [PATCH 3/4] fix: mask recipient token (#1051) The searchDocuments function is used for the shortcuts commands, afaik. The function returns the documents that match the user query (if any), alongside all their recipients. The reason for that is so it can build the path for the document. E.g. if you're the document owner, the document path will be `..../documents/{id}`. But if you're a signer for example, the document path (link) will be `..../sign/{token}`. So instead of doing that on the frontend, I moved it to the backend. At least that's what I understood. If I'm wrong, please correct me. ## Summary by CodeRabbit - **New Features** - Enhanced the `CommandMenu` component to simplify search result generation and improve document link management based on user roles. - **Refactor** - Updated document search logic to include recipient token masking and refined document mapping. - **Style** - Minor formatting improvement in document routing code. --- .../(dashboard)/common/command-menu.tsx | 20 +++-------------- .../document/search-documents-with-keyword.ts | 22 ++++++++++++------- .../trpc/server/document-router/router.ts | 1 + 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/apps/web/src/components/(dashboard)/common/command-menu.tsx b/apps/web/src/components/(dashboard)/common/command-menu.tsx index bdc6c2064..812efd4b9 100644 --- a/apps/web/src/components/(dashboard)/common/command-menu.tsx +++ b/apps/web/src/components/(dashboard)/common/command-menu.tsx @@ -5,7 +5,6 @@ import { useCallback, useMemo, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Loader, Monitor, Moon, Sun } from 'lucide-react'; -import { useSession } from 'next-auth/react'; import { useTheme } from 'next-themes'; import { useHotkeys } from 'react-hotkeys-hook'; @@ -18,7 +17,6 @@ import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION, SKIP_QUERY_BATCH_META, } from '@documenso/lib/constants/trpc'; -import type { Document, Recipient } from '@documenso/prisma/client'; import { trpc as trpcReact } from '@documenso/trpc/react'; import { CommandDialog, @@ -71,7 +69,6 @@ export type CommandMenuProps = { export function CommandMenu({ open, onOpenChange }: CommandMenuProps) { const { setTheme } = useTheme(); - const { data: session } = useSession(); const router = useRouter(); @@ -93,17 +90,6 @@ export function CommandMenu({ open, onOpenChange }: CommandMenuProps) { }, ); - const isOwner = useCallback( - (document: Document) => document.userId === session?.user.id, - [session?.user.id], - ); - - const getSigningLink = useCallback( - (recipients: Recipient[]) => - `/sign/${recipients.find((r) => r.email === session?.user.email)?.token}`, - [session?.user.email], - ); - const searchResults = useMemo(() => { if (!searchDocumentsData) { return []; @@ -111,10 +97,10 @@ export function CommandMenu({ open, onOpenChange }: CommandMenuProps) { return searchDocumentsData.map((document) => ({ label: document.title, - path: isOwner(document) ? `/documents/${document.id}` : getSigningLink(document.Recipient), - value: [document.id, document.title, ...document.Recipient.map((r) => r.email)].join(' '), + path: document.path, + value: document.value, })); - }, [searchDocumentsData, isOwner, getSigningLink]); + }, [searchDocumentsData]); const currentPage = pages[pages.length - 1]; diff --git a/packages/lib/server-only/document/search-documents-with-keyword.ts b/packages/lib/server-only/document/search-documents-with-keyword.ts index 8125ae900..a9139f5d3 100644 --- a/packages/lib/server-only/document/search-documents-with-keyword.ts +++ b/packages/lib/server-only/document/search-documents-with-keyword.ts @@ -1,7 +1,6 @@ import { prisma } from '@documenso/prisma'; import { DocumentStatus } from '@documenso/prisma/client'; - -import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document'; +import type { Document, Recipient, User } from '@documenso/prisma/client'; export type SearchDocumentsWithKeywordOptions = { query: string; @@ -79,12 +78,19 @@ export const searchDocumentsWithKeyword = async ({ take: limit, }); - const maskedDocuments = documents.map((document) => - maskRecipientTokensForDocument({ - document, - user, - }), - ); + const isOwner = (document: Document, user: User) => document.userId === user.id; + const getSigningLink = (recipients: Recipient[], user: User) => + `/sign/${recipients.find((r) => r.email === user.email)?.token}`; + + const maskedDocuments = documents.map((document) => { + const { Recipient, ...documentWithoutRecipient } = document; + + return { + ...documentWithoutRecipient, + path: isOwner(document, user) ? `/documents/${document.id}` : getSigningLink(Recipient, user), + value: [document.id, document.title, ...document.Recipient.map((r) => r.email)].join(' '), + }; + }); return maskedDocuments; }; diff --git a/packages/trpc/server/document-router/router.ts b/packages/trpc/server/document-router/router.ts index 3cc61bef2..d12002674 100644 --- a/packages/trpc/server/document-router/router.ts +++ b/packages/trpc/server/document-router/router.ts @@ -358,6 +358,7 @@ export const documentRouter = router({ query, userId: ctx.user.id, }); + return documents; } catch (err) { console.error(err); From aa4b6f1723c43ff6461950598a203222c2c127aa Mon Sep 17 00:00:00 2001 From: Adithya Krishna Date: Mon, 15 Apr 2024 14:22:34 +0530 Subject: [PATCH 4/4] feat: updated mobile header (#1004) **Description:** - Updated mobile header with respect to latest designs ## Summary by CodeRabbit - **New Features** - Added a new `showText` property to the `MenuSwitcher` component to control text visibility. - Added a `textSectionClassName` property to the `AvatarWithText` component for conditional text section styling. - Updated the `CommandDialog` and `DialogContent` components with new positioning and styling properties. - **Style Updates** - Adjusted text size responsiveness in the `Hero` component for various screen sizes. - Modified text truncation and input styling in the `Widget` component. - Changed the width of the `SheetContent` element in `MobileNavigation` and adjusted footer layout. - **Documentation** - Added instructions for certificate placement in `SIGNING.md`. - **Refactor** - Standardized type imports across various components and utilities for improved type checking. --------- Signed-off-by: Adithya Krishna Signed-off-by: Adithya Krishna Co-authored-by: David Nguyen --- SIGNING.md | 3 +- apps/marketing/src/api/claim-plan/fetcher.ts | 3 +- .../src/app/(marketing)/open/bar-metrics.tsx | 1 + .../app/(marketing)/open/funding-raised.tsx | 1 + .../src/app/(marketing)/open/metric-card.tsx | 2 +- .../src/app/(marketing)/open/salary-bands.tsx | 2 +- .../app/(marketing)/oss-friends/container.tsx | 5 +- apps/marketing/src/app/robots.ts | 2 +- apps/marketing/src/app/sitemap.ts | 2 +- .../src/components/(marketing)/hero.tsx | 2 +- .../(marketing)/open-build-template-bento.tsx | 2 +- .../src/components/(marketing)/widget.tsx | 4 +- .../components/form/form-error-message.tsx | 2 +- .../src/components/ui/background.tsx | 2 +- apps/marketing/src/providers/next-theme.tsx | 2 +- .../(dashboard)/layout/menu-switcher.tsx | 5 +- .../(dashboard)/layout/mobile-navigation.tsx | 4 +- packages/ui/primitives/avatar.tsx | 5 +- packages/ui/primitives/command.tsx | 6 ++- packages/ui/primitives/dialog.tsx | 49 +++++++++++-------- 20 files changed, 62 insertions(+), 42 deletions(-) diff --git a/SIGNING.md b/SIGNING.md index d1942ed8a..d8f664cee 100644 --- a/SIGNING.md +++ b/SIGNING.md @@ -17,7 +17,8 @@ For the digital signature of your documents you need a signing certificate in .p `openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt` 4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**) -5. Place the certificate `/apps/web/resources/certificate.p12` + +5. Place the certificate `/apps/web/resources/certificate.p12` (If the path does not exist, it needs to be created) ## Docker diff --git a/apps/marketing/src/api/claim-plan/fetcher.ts b/apps/marketing/src/api/claim-plan/fetcher.ts index 0e533be5e..629ab7270 100644 --- a/apps/marketing/src/api/claim-plan/fetcher.ts +++ b/apps/marketing/src/api/claim-plan/fetcher.ts @@ -1,4 +1,5 @@ -import { TClaimPlanRequestSchema, ZClaimPlanResponseSchema } from './types'; +import type { TClaimPlanRequestSchema } from './types'; +import { ZClaimPlanResponseSchema } from './types'; export const claimPlan = async ({ name, diff --git a/apps/marketing/src/app/(marketing)/open/bar-metrics.tsx b/apps/marketing/src/app/(marketing)/open/bar-metrics.tsx index fb9c61f11..2d93b2e34 100644 --- a/apps/marketing/src/app/(marketing)/open/bar-metrics.tsx +++ b/apps/marketing/src/app/(marketing)/open/bar-metrics.tsx @@ -55,6 +55,7 @@ export const BarMetric = & { export const FundingRaised = ({ className, data, ...props }: FundingRaisedProps) => { const formattedData = data.map((item) => ({ amount: Number(item.amount), + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions date: formatMonth(item.date as string), })); diff --git a/apps/marketing/src/app/(marketing)/open/metric-card.tsx b/apps/marketing/src/app/(marketing)/open/metric-card.tsx index 6235f4f5e..f7bf59e62 100644 --- a/apps/marketing/src/app/(marketing)/open/metric-card.tsx +++ b/apps/marketing/src/app/(marketing)/open/metric-card.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes } from 'react'; +import type { HTMLAttributes } from 'react'; import { cn } from '@documenso/ui/lib/utils'; diff --git a/apps/marketing/src/app/(marketing)/open/salary-bands.tsx b/apps/marketing/src/app/(marketing)/open/salary-bands.tsx index 31c254157..41754cff6 100644 --- a/apps/marketing/src/app/(marketing)/open/salary-bands.tsx +++ b/apps/marketing/src/app/(marketing)/open/salary-bands.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes } from 'react'; +import type { HTMLAttributes } from 'react'; import { cn } from '@documenso/ui/lib/utils'; import { diff --git a/apps/marketing/src/app/(marketing)/oss-friends/container.tsx b/apps/marketing/src/app/(marketing)/oss-friends/container.tsx index 0f1f66664..f2ea4e855 100644 --- a/apps/marketing/src/app/(marketing)/oss-friends/container.tsx +++ b/apps/marketing/src/app/(marketing)/oss-friends/container.tsx @@ -2,13 +2,14 @@ import Link from 'next/link'; -import { Variants, motion } from 'framer-motion'; +import type { Variants } from 'framer-motion'; +import { motion } from 'framer-motion'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '@documenso/ui/primitives/button'; import { Card, CardContent, CardTitle } from '@documenso/ui/primitives/card'; -import { TOSSFriendsSchema } from './schema'; +import type { TOSSFriendsSchema } from './schema'; const ContainerVariants: Variants = { initial: { diff --git a/apps/marketing/src/app/robots.ts b/apps/marketing/src/app/robots.ts index cc718ff25..a222a892e 100644 --- a/apps/marketing/src/app/robots.ts +++ b/apps/marketing/src/app/robots.ts @@ -1,4 +1,4 @@ -import { MetadataRoute } from 'next'; +import type { MetadataRoute } from 'next'; import { getBaseUrl } from '@documenso/lib/universal/get-base-url'; diff --git a/apps/marketing/src/app/sitemap.ts b/apps/marketing/src/app/sitemap.ts index b9becde3b..4913402f9 100644 --- a/apps/marketing/src/app/sitemap.ts +++ b/apps/marketing/src/app/sitemap.ts @@ -1,4 +1,4 @@ -import { MetadataRoute } from 'next'; +import type { MetadataRoute } from 'next'; import { allBlogPosts, allGenericPages } from 'contentlayer/generated'; diff --git a/apps/marketing/src/components/(marketing)/hero.tsx b/apps/marketing/src/components/(marketing)/hero.tsx index f416cc4ca..5809bd695 100644 --- a/apps/marketing/src/components/(marketing)/hero.tsx +++ b/apps/marketing/src/components/(marketing)/hero.tsx @@ -96,7 +96,7 @@ export const Hero = ({ className, ...props }: HeroProps) => { variants={HeroTitleVariants} initial="initial" animate="animate" - className="text-center text-4xl font-bold leading-tight tracking-tight lg:text-[64px]" + className="text-center text-4xl font-bold leading-tight tracking-tight md:text-[48px] lg:text-[64px]" > Document signing, finally open source. diff --git a/apps/marketing/src/components/(marketing)/open-build-template-bento.tsx b/apps/marketing/src/components/(marketing)/open-build-template-bento.tsx index 3c76c3547..4d4d6ad8a 100644 --- a/apps/marketing/src/components/(marketing)/open-build-template-bento.tsx +++ b/apps/marketing/src/components/(marketing)/open-build-template-bento.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes } from 'react'; +import type { HTMLAttributes } from 'react'; import Image from 'next/image'; diff --git a/apps/marketing/src/components/(marketing)/widget.tsx b/apps/marketing/src/components/(marketing)/widget.tsx index 8b6c3cd8e..c4611746a 100644 --- a/apps/marketing/src/components/(marketing)/widget.tsx +++ b/apps/marketing/src/components/(marketing)/widget.tsx @@ -346,7 +346,7 @@ export const Widget = ({ className, children, ...props }: WidgetProps) => { {signatureText && (

{signatureText} @@ -360,7 +360,7 @@ export const Widget = ({ className, children, ...props }: WidgetProps) => { > , 'viewBox'>; diff --git a/apps/marketing/src/providers/next-theme.tsx b/apps/marketing/src/providers/next-theme.tsx index 6e9122e5a..d15114606 100644 --- a/apps/marketing/src/providers/next-theme.tsx +++ b/apps/marketing/src/providers/next-theme.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { ThemeProvider as NextThemesProvider } from 'next-themes'; -import { ThemeProviderProps } from 'next-themes/dist/types'; +import type { ThemeProviderProps } from 'next-themes/dist/types'; export function ThemeProvider({ children, ...props }: ThemeProviderProps) { return {children}; diff --git a/apps/web/src/components/(dashboard)/layout/menu-switcher.tsx b/apps/web/src/components/(dashboard)/layout/menu-switcher.tsx index 95f959ab2..bb8429adc 100644 --- a/apps/web/src/components/(dashboard)/layout/menu-switcher.tsx +++ b/apps/web/src/components/(dashboard)/layout/menu-switcher.tsx @@ -93,7 +93,7 @@ export const MenuSwitcher = ({ user, teams: initialTeamsData }: MenuSwitcherProp diff --git a/apps/web/src/components/(dashboard)/layout/mobile-navigation.tsx b/apps/web/src/components/(dashboard)/layout/mobile-navigation.tsx index a6009e7b5..ff5428298 100644 --- a/apps/web/src/components/(dashboard)/layout/mobile-navigation.tsx +++ b/apps/web/src/components/(dashboard)/layout/mobile-navigation.tsx @@ -46,7 +46,7 @@ export const MobileNavigation = ({ isMenuOpen, onMenuOpenChange }: MobileNavigat return ( - +

- © {new Date().getFullYear()} Documenso, Inc. All rights reserved. + © {new Date().getFullYear()} Documenso, Inc.
All rights reserved.

diff --git a/packages/ui/primitives/avatar.tsx b/packages/ui/primitives/avatar.tsx index c80e3a658..aa2f522fe 100644 --- a/packages/ui/primitives/avatar.tsx +++ b/packages/ui/primitives/avatar.tsx @@ -55,6 +55,8 @@ type AvatarWithTextProps = { primaryText: React.ReactNode; secondaryText?: React.ReactNode; rightSideComponent?: React.ReactNode; + // Optional class to hide/show the text beside avatar + textSectionClassName?: string; }; const AvatarWithText = ({ @@ -64,6 +66,7 @@ const AvatarWithText = ({ primaryText, secondaryText, rightSideComponent, + textSectionClassName, }: AvatarWithTextProps) => (
{avatarFallback} -
+
{primaryText} {secondaryText}
diff --git a/packages/ui/primitives/command.tsx b/packages/ui/primitives/command.tsx index 89777d417..89084ac12 100644 --- a/packages/ui/primitives/command.tsx +++ b/packages/ui/primitives/command.tsx @@ -32,7 +32,11 @@ type CommandDialogProps = DialogProps & { const CommandDialog = ({ children, commandProps, ...props }: CommandDialogProps) => { return ( - + & { position?: 'start' | 'end' | 'center'; hideClose?: boolean; + /* Below prop is to add additional classes to the overlay */ + overlayClassName?: string; } ->(({ className, children, position = 'start', hideClose = false, ...props }, ref) => ( - - - - {children} - {!hideClose && ( - - - Close - - )} - - -)); +>( + ( + { className, children, overlayClassName, position = 'start', hideClose = false, ...props }, + ref, + ) => ( + + + + {children} + {!hideClose && ( + + + Close + + )} + + + ), +); DialogContent.displayName = DialogPrimitive.Content.displayName;