diff --git a/.env.example b/.env.example index c482c128e..20e1ae2ae 100644 --- a/.env.example +++ b/.env.example @@ -27,6 +27,16 @@ E2E_TEST_AUTHENTICATE_USERNAME="Test User" E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com" E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123" +# [[SIGNING]] +# OPTIONAL: Defines the signing transport to use. Available options: local (default) +NEXT_PRIVATE_SIGNING_TRANSPORT="local" +# OPTIONAL: Defines the passphrase for the signing certificate. +NEXT_PRIVATE_SIGNING_PASSPHRASE= +# OPTIONAL: Defines the file contents for the signing certificate as a base64 encoded string. +NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS= +# OPTIONAL: Defines the file path for the signing certificate. defaults to ./example/cert.p12 +NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH= + # [[STORAGE]] # OPTIONAL: Defines the storage transport to use. Available options: database (default) | s3 NEXT_PUBLIC_UPLOAD_TRANSPORT="database" diff --git a/apps/marketing/package.json b/apps/marketing/package.json index 1cfb7337f..f6af3a9ff 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -36,7 +36,7 @@ "react-hook-form": "^7.43.9", "react-icons": "^4.11.0", "recharts": "^2.7.2", - "sharp": "0.33.1", + "sharp": "^0.33.1", "typescript": "5.2.2", "zod": "^3.22.4" }, diff --git a/apps/web/package.json b/apps/web/package.json index 41caec804..e72f4898a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -43,7 +43,7 @@ "react-icons": "^4.11.0", "react-rnd": "^10.4.1", "remeda": "^1.27.1", - "sharp": "0.33.1", + "sharp": "^0.33.1", "ts-pattern": "^5.0.5", "ua-parser-js": "^1.0.37", "uqr": "^0.1.2", diff --git a/apps/web/src/app/(dashboard)/documents/data-table.tsx b/apps/web/src/app/(dashboard)/documents/data-table.tsx index d36860032..ec595641e 100644 --- a/apps/web/src/app/(dashboard)/documents/data-table.tsx +++ b/apps/web/src/app/(dashboard)/documents/data-table.tsx @@ -82,6 +82,7 @@ export const DocumentsDataTable = ({ header: 'Status', accessorKey: 'status', cell: ({ row }) => , + size: 140, }, { header: 'Actions', diff --git a/apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx b/apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx index 27560c073..d7a8f6553 100644 --- a/apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx +++ b/apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import { useEffect, useMemo } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { useForm } from 'react-hook-form'; @@ -149,6 +149,13 @@ export const EnableAuthenticatorAppDialog = ({ } }; + useEffect(() => { + // Reset the form when the Dialog closes + if (!open) { + setupTwoFactorAuthenticationForm.reset(); + } + }, [open, setupTwoFactorAuthenticationForm]); + return ( diff --git a/apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx b/apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx index 376a8939c..48e343e8d 100644 --- a/apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx +++ b/apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import { useEffect, useMemo } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { useForm } from 'react-hook-form'; @@ -92,6 +92,13 @@ export const ViewRecoveryCodesDialog = ({ open, onOpenChange }: ViewRecoveryCode } }; + useEffect(() => { + // Reset the form when the Dialog closes + if (!open) { + viewRecoveryCodesForm.reset(); + } + }, [open, viewRecoveryCodesForm]); + return ( diff --git a/docker/README.md b/docker/README.md index ba942ac1c..bda1638a2 100644 --- a/docker/README.md +++ b/docker/README.md @@ -29,7 +29,16 @@ NEXT_PRIVATE_SMTP_USERNAME="" NEXT_PRIVATE_SMTP_PASSWORD="" ``` -4. Run the following command to start the containers: +4. Update the volume binding for the cert file in the `compose.yml` file to point to your own key file: + +Since the `cert.p12` file is required for signing and encrypting documents, you will need to provide your own key file. Update the volume binding in the `compose.yml` file to point to your key file: + +```yaml +volumes: + - /path/to/your/keyfile.p12:/opt/documenso/cert.p12 +``` + +1. Run the following command to start the containers: ``` docker-compose --env-file ./.env -d up @@ -70,6 +79,7 @@ docker run -d \ -e NEXT_PRIVATE_SMTP_TRANSPORT="" -e NEXT_PRIVATE_SMTP_FROM_NAME="" -e NEXT_PRIVATE_SMTP_FROM_ADDRESS="" + -v /path/to/your/keyfile.p12:/opt/documenso/cert.p12 documenso/documenso ``` @@ -99,6 +109,10 @@ Here's a markdown table documenting all the provided environment variables: | `NEXT_PUBLIC_WEBAPP_URL` | The URL for the web application. | | `NEXT_PRIVATE_DATABASE_URL` | The URL for the primary database connection (with connection pooling). | | `NEXT_PRIVATE_DIRECT_DATABASE_URL` | The URL for the direct database connection (without connection pooling). | +| `NEXT_PRIVATE_SIGNING_TRANSPORT` | The signing transport to use. Available options: local (default) | +| `NEXT_PRIVATE_SIGNING_PASSPHRASE` | The passphrase for the key file. | +| `NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS` | The base64-encoded contents of the key file, will be used instead of file path. | +| `NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH` | The path to the key file, default `/opt/documenso/cert.p12`. | | `NEXT_PUBLIC_UPLOAD_TRANSPORT` | The transport to use for file uploads (database or s3). | | `NEXT_PRIVATE_UPLOAD_ENDPOINT` | The endpoint for the S3 storage transport (for third-party S3-compatible providers). | | `NEXT_PRIVATE_UPLOAD_REGION` | The region for the S3 storage transport (defaults to us-east-1). | diff --git a/docker/production/compose.yml b/docker/production/compose.yml index 08abcf050..02acc655d 100644 --- a/docker/production/compose.yml +++ b/docker/production/compose.yml @@ -57,8 +57,11 @@ services: - NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=${NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT} - NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY} - NEXT_PUBLIC_DISABLE_SIGNUP=${NEXT_PUBLIC_DISABLE_SIGNUP} + - NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=${NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH?:-/opt/documenso/cert.p12} ports: - ${PORT:-3000}:${PORT:-3000} + volumes: + - /opt/documenso/cert.p12:/opt/documenso/cert.p12 volumes: database: diff --git a/docker/testing/compose.yml b/docker/testing/compose.yml index cecb5bf14..28ec055c1 100644 --- a/docker/testing/compose.yml +++ b/docker/testing/compose.yml @@ -47,5 +47,8 @@ services: - NEXT_PRIVATE_SMTP_PASSWORD=password - NEXT_PRIVATE_SMTP_FROM_NAME="No Reply @ Documenso" - NEXT_PRIVATE_SMTP_FROM_ADDRESS=noreply@documenso.com + - NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12 ports: - 3000:3000 + volumes: + - ../../apps/web/example/cert.p12:/opt/documenso/cert.p12 diff --git a/package-lock.json b/package-lock.json index 72d06b98a..d7615e179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "react-hook-form": "^7.43.9", "react-icons": "^4.11.0", "recharts": "^2.7.2", - "sharp": "0.33.1", + "sharp": "^0.33.1", "typescript": "5.2.2", "zod": "^3.22.4" }, @@ -74,45 +74,6 @@ "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "dev": true }, - "apps/marketing/node_modules/sharp": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", - "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.2", - "semver": "^7.5.4" - }, - "engines": { - "libvips": ">=8.15.0", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.1", - "@img/sharp-darwin-x64": "0.33.1", - "@img/sharp-libvips-darwin-arm64": "1.0.0", - "@img/sharp-libvips-darwin-x64": "1.0.0", - "@img/sharp-libvips-linux-arm": "1.0.0", - "@img/sharp-libvips-linux-arm64": "1.0.0", - "@img/sharp-libvips-linux-s390x": "1.0.0", - "@img/sharp-libvips-linux-x64": "1.0.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", - "@img/sharp-libvips-linuxmusl-x64": "1.0.0", - "@img/sharp-linux-arm": "0.33.1", - "@img/sharp-linux-arm64": "0.33.1", - "@img/sharp-linux-s390x": "0.33.1", - "@img/sharp-linux-x64": "0.33.1", - "@img/sharp-linuxmusl-arm64": "0.33.1", - "@img/sharp-linuxmusl-x64": "0.33.1", - "@img/sharp-wasm32": "0.33.1", - "@img/sharp-win32-ia32": "0.33.1", - "@img/sharp-win32-x64": "0.33.1" - } - }, "apps/marketing/node_modules/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", @@ -159,7 +120,7 @@ "react-icons": "^4.11.0", "react-rnd": "^10.4.1", "remeda": "^1.27.1", - "sharp": "0.33.1", + "sharp": "^0.33.1", "ts-pattern": "^5.0.5", "ua-parser-js": "^1.0.37", "uqr": "^0.1.2", @@ -182,45 +143,6 @@ "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "dev": true }, - "apps/web/node_modules/sharp": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", - "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.2", - "semver": "^7.5.4" - }, - "engines": { - "libvips": ">=8.15.0", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.1", - "@img/sharp-darwin-x64": "0.33.1", - "@img/sharp-libvips-darwin-arm64": "1.0.0", - "@img/sharp-libvips-darwin-x64": "1.0.0", - "@img/sharp-libvips-linux-arm": "1.0.0", - "@img/sharp-libvips-linux-arm64": "1.0.0", - "@img/sharp-libvips-linux-s390x": "1.0.0", - "@img/sharp-libvips-linux-x64": "1.0.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", - "@img/sharp-libvips-linuxmusl-x64": "1.0.0", - "@img/sharp-linux-arm": "0.33.1", - "@img/sharp-linux-arm64": "0.33.1", - "@img/sharp-linux-s390x": "0.33.1", - "@img/sharp-linux-x64": "0.33.1", - "@img/sharp-linuxmusl-arm64": "0.33.1", - "@img/sharp-linuxmusl-x64": "0.33.1", - "@img/sharp-wasm32": "0.33.1", - "@img/sharp-win32-ia32": "0.33.1", - "@img/sharp-win32-x64": "0.33.1" - } - }, "apps/web/node_modules/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", @@ -18560,6 +18482,45 @@ "sha.js": "bin.js" } }, + "node_modules/sharp": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", + "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "semver": "^7.5.4" + }, + "engines": { + "libvips": ">=8.15.0", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.1", + "@img/sharp-darwin-x64": "0.33.1", + "@img/sharp-libvips-darwin-arm64": "1.0.0", + "@img/sharp-libvips-darwin-x64": "1.0.0", + "@img/sharp-libvips-linux-arm": "1.0.0", + "@img/sharp-libvips-linux-arm64": "1.0.0", + "@img/sharp-libvips-linux-s390x": "1.0.0", + "@img/sharp-libvips-linux-x64": "1.0.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", + "@img/sharp-libvips-linuxmusl-x64": "1.0.0", + "@img/sharp-linux-arm": "0.33.1", + "@img/sharp-linux-arm64": "0.33.1", + "@img/sharp-linux-s390x": "0.33.1", + "@img/sharp-linux-x64": "0.33.1", + "@img/sharp-linuxmusl-arm64": "0.33.1", + "@img/sharp-linuxmusl-x64": "0.33.1", + "@img/sharp-wasm32": "0.33.1", + "@img/sharp-win32-ia32": "0.33.1", + "@img/sharp-win32-x64": "0.33.1" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/packages/eslint-config/index.cjs b/packages/eslint-config/index.cjs index 57cecf40d..aef6a944e 100644 --- a/packages/eslint-config/index.cjs +++ b/packages/eslint-config/index.cjs @@ -20,7 +20,7 @@ module.exports = { parserOptions: { tsconfigRootDir: __dirname, - project: ['../../apps/*/tsconfig.json', '../../packages/*/tsconfig.json'], + project: ['../../tsconfig.eslint.json'], ecmaVersion: 2022, ecmaFeatures: { jsx: true, diff --git a/packages/ui/primitives/data-table.tsx b/packages/ui/primitives/data-table.tsx index 9cc14a684..0d8556d89 100644 --- a/packages/ui/primitives/data-table.tsx +++ b/packages/ui/primitives/data-table.tsx @@ -115,7 +115,12 @@ export function DataTable({ table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( - + {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} diff --git a/packages/ui/primitives/toast.tsx b/packages/ui/primitives/toast.tsx index b42cadc27..bddf33165 100644 --- a/packages/ui/primitives/toast.tsx +++ b/packages/ui/primitives/toast.tsx @@ -79,7 +79,7 @@ const ToastClose = React.forwardRef<