Compare commits
260 Commits
v1.9.0-rc.
...
v1.12.0-rc
| Author | SHA1 | Date | |
|---|---|---|---|
| 58d97518c8 | |||
| 20c8969272 | |||
| 85ac65e405 | |||
| e07a497b69 | |||
| 21dc4eee62 | |||
| dc2042a1ee | |||
| bb9ba80edb | |||
| bfe8c674f2 | |||
| ebe1baf0a0 | |||
| 2345de679b | |||
| 1be0e2842c | |||
| 29a03d4ec7 | |||
| 039cd7d449 | |||
| 484f6c8b85 | |||
| 4fd8a767b2 | |||
| b8e08e88ac | |||
| 031a7b9e36 | |||
| 12fe045195 | |||
| 614106a5e4 | |||
| 8be7137b59 | |||
| 31e2a6443e | |||
| 400d2a2b1a | |||
| e3ce7f94e6 | |||
| cad04f26e7 | |||
| d27f0ee0ef | |||
| fd2b413ed9 | |||
| d11ec8fa2a | |||
| b1127b4f0d | |||
| be4244fb62 | |||
| 504a0893ab | |||
| 22a37409c1 | |||
| 50605d5912 | |||
| 4609fc852d | |||
| e6dc237ad2 | |||
| 0b37f19641 | |||
| 64c6a51e04 | |||
| d1eddb02c4 | |||
| 60a623fafd | |||
| 6059b79a8e | |||
| c73d61955b | |||
| 7c3ca72359 | |||
| 55c8632620 | |||
| ce66da0055 | |||
| 695ed418e2 | |||
| 93aece9644 | |||
| abd4fddf31 | |||
| 44bc769e60 | |||
| c8f80f7be0 | |||
| 8540f24de0 | |||
| 67203d4bd7 | |||
| 9d1e638f0f | |||
| bd64ad9fef | |||
| 99b0ad574e | |||
| 9594e1fee8 | |||
| 5e3a2b8f76 | |||
| f928503a33 | |||
| c389670785 | |||
| 99ad2eb645 | |||
| 2f48679b0b | |||
| e40c5d9d24 | |||
| ab323f149f | |||
| bf1c1ff9dc | |||
| 516e237966 | |||
| ac7d24eb12 | |||
| 0931c472a7 | |||
| 8c9dd5e372 | |||
| e108da546d | |||
| 17370749b4 | |||
| 12ada567f5 | |||
| bdb0b0ea88 | |||
| 6a41a37bd4 | |||
| d78cfec00e | |||
| f0dcf7e9bf | |||
| 6540291055 | |||
| 193325717d | |||
| b94645a451 | |||
| 7e6704faae | |||
| cf17fc61bc | |||
| 6df8b3aac8 | |||
| fdb31772db | |||
| a3dfd81870 | |||
| 755ef697ba | |||
| 37cc41d713 | |||
| dd2ef3a657 | |||
| 435b3ca4f8 | |||
| 278cd8a9de | |||
| f1526315f5 | |||
| 353a7e8e0d | |||
| 34b2504268 | |||
| 566abda36b | |||
| 9121a062b3 | |||
| e613e0e347 | |||
| 95aae52fa4 | |||
| 5958f38719 | |||
| 419bc02171 | |||
| 5e4956f3a2 | |||
| da71613c9f | |||
| 4d6efe091e | |||
| 7e6ac4db40 | |||
| a87af910c7 | |||
| e37b005d7f | |||
| 73f8518b47 | |||
| ac3deb113e | |||
| c82388c40a | |||
| 31be548939 | |||
| 063fd32f18 | |||
| 231f51bd1f | |||
| a8de8368a2 | |||
| 7dd331addf | |||
| c6743a7cec | |||
| efbc097191 | |||
| f1525991dc | |||
| fb173e4d0e | |||
| d422ffa873 | |||
| 55b7697316 | |||
| 67bbb6c6f4 | |||
| 63a4bab0fe | |||
| 9f17c1e48e | |||
| 91ae818213 | |||
| a0ace803cf | |||
| b3db3be8e9 | |||
| 44cdbeecb4 | |||
| 7214965c0c | |||
| 8d6bf91d12 | |||
| fec078081b | |||
| c646afcd97 | |||
| 63d990ce8d | |||
| aa7d6b28a4 | |||
| b990532633 | |||
| 65be37514f | |||
| 0df29fce36 | |||
| ba5b7ce480 | |||
| 422770a8c7 | |||
| 083a706373 | |||
| db326cb4a9 | |||
| d664f571d6 | |||
| 7c38970ee8 | |||
| e08d62c844 | |||
| 25bb6ffe77 | |||
| e79d762710 | |||
| d970976299 | |||
| 3dce814ab2 | |||
| ad520bb032 | |||
| 596d30e2e5 | |||
| 6474b4a524 | |||
| 5b4db51051 | |||
| cf58c80e31 | |||
| 11dbb8873e | |||
| bc7907271b | |||
| 9b376d34cf | |||
| deea99d865 | |||
| 3328074f51 | |||
| 5e69665e00 | |||
| c1c7cfaf8b | |||
| 7e8955b89c | |||
| cedd5e87b1 | |||
| 5255e8671f | |||
| d4c1bad407 | |||
| 01dccb7916 | |||
| 483d7caef7 | |||
| 139bc265c7 | |||
| 991ce5ff46 | |||
| 7728c8641c | |||
| 50a41d0799 | |||
| 250381fec8 | |||
| d2f3d24542 | |||
| ec07092bf6 | |||
| 63e2ef0abf | |||
| 90ce52164c | |||
| ac30654913 | |||
| 24f3ecd94f | |||
| a319ea0f5e | |||
| 5ce2bae39d | |||
| 5d86e84217 | |||
| 79e26a9a46 | |||
| dd602a7e1c | |||
| fb16214dc5 | |||
| 5fc724b247 | |||
| 1ed1cb0773 | |||
| 8d5fafec27 | |||
| 0f6f236e0c | |||
| e518985833 | |||
| 595e901bc2 | |||
| df8ea09021 | |||
| 180656978b | |||
| 28f5177064 | |||
| 31de86e425 | |||
| 113ab293bb | |||
| 1c4878e526 | |||
| 92db4d68db | |||
| 7379391f92 | |||
| ebc2b00067 | |||
| 87dcdd44cd | |||
| b205f7e5f3 | |||
| c5d5355cf7 | |||
| 5fac29a07f | |||
| 1aaacab6ca | |||
| 06076c1809 | |||
| c0ae68c28b | |||
| 3e106c1a2d | |||
| 741639ee78 | |||
| 0b3638c42c | |||
| 0f50110853 | |||
| b0f8c83134 | |||
| c9e8a32471 | |||
| 84b193d99c | |||
| b03c5ab1a7 | |||
| 9db42accf3 | |||
| 383b5f78f0 | |||
| 9183f668d3 | |||
| 54ea96391a | |||
| 42d24fd1a1 | |||
| dc36a8182c | |||
| 0ef85b47b1 | |||
| 058d9dd0ba | |||
| 74bb230247 | |||
| 7c1e0f34e8 | |||
| 7e31323faa | |||
| a28cdf437b | |||
| 80dfbeb16f | |||
| 9de3a32ceb | |||
| 0d3864548c | |||
| 9e03747e43 | |||
| 5750f2b477 | |||
| 901be70f97 | |||
| 7d0a9c6439 | |||
| 48b55758e3 | |||
| dcaccb65f2 | |||
| 723e1b4ea2 | |||
| 08a69c6168 | |||
| 948d9c24cf | |||
| ebbe922982 | |||
| 6520bbd5e3 | |||
| 4e197ac24c | |||
| f707e5fb10 | |||
| 6fc5e565d0 | |||
| 07c852744b | |||
| 4fab98c633 | |||
| 18ca0cf3d6 | |||
| b3e044e278 | |||
| e2a250063f | |||
| 4085151f80 | |||
| 0d3681e26a | |||
| cfe7b3a51f | |||
| 08d3d6a80a | |||
| 9d83bda12c | |||
| 22fd1b5be1 | |||
| df33fbf91b | |||
| ee6efc4cca | |||
| 6da15ab12b | |||
| 7ef2a8769b | |||
| 487f52e194 | |||
| 39b1c5bbec | |||
| 32857bbfeb | |||
| 41218e2585 | |||
| a1a2d0801b | |||
| c588c09b26 | |||
| 74382e21e7 | |||
| 8a7ec7e982 | |||
| 2948a33bf9 |
59
.cursorrules
@ -1,4 +1,7 @@
|
||||
You are an expert in TypeScript, Node.js, Remix, React, Shadcn UI and Tailwind.
|
||||
|
||||
Code Style and Structure:
|
||||
|
||||
- Write concise, technical TypeScript code with accurate examples
|
||||
- Use functional and declarative programming patterns; avoid classes
|
||||
- Prefer iteration and modularization over code duplication
|
||||
@ -6,20 +9,25 @@ Code Style and Structure:
|
||||
- Structure files: exported component, subcomponents, helpers, static content, types
|
||||
|
||||
Naming Conventions:
|
||||
|
||||
- Use lowercase with dashes for directories (e.g., components/auth-wizard)
|
||||
- Favor named exports for components
|
||||
|
||||
TypeScript Usage:
|
||||
- Use TypeScript for all code; prefer interfaces over types
|
||||
- Avoid enums; use maps instead
|
||||
|
||||
- Use TypeScript for all code; prefer types over interfaces
|
||||
- Use functional components with TypeScript interfaces
|
||||
|
||||
Syntax and Formatting:
|
||||
- Use the "function" keyword for pure functions
|
||||
|
||||
- Create functions using `const fn = () => {}`
|
||||
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
|
||||
- Use declarative JSX
|
||||
- Never use 'use client'
|
||||
- Never use 1 line if statements
|
||||
|
||||
Error Handling and Validation:
|
||||
|
||||
- Prioritize error handling: handle errors and edge cases early
|
||||
- Use early returns and guard clauses
|
||||
- Implement proper error logging and user-friendly messages
|
||||
@ -28,21 +36,40 @@ Error Handling and Validation:
|
||||
- Use error boundaries for unexpected errors
|
||||
|
||||
UI and Styling:
|
||||
|
||||
- Use Shadcn UI, Radix, and Tailwind Aria for components and styling
|
||||
- Implement responsive design with Tailwind CSS; use a mobile-first approach
|
||||
- When using Lucide icons, prefer the longhand names, for example HomeIcon instead of Home
|
||||
|
||||
Performance Optimization:
|
||||
- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC)
|
||||
- Wrap client components in Suspense with fallback
|
||||
- Use dynamic loading for non-critical components
|
||||
- Optimize images: use WebP format, include size data, implement lazy loading
|
||||
React forms
|
||||
|
||||
Key Conventions:
|
||||
- Use 'nuqs' for URL search parameter state management
|
||||
- Optimize Web Vitals (LCP, CLS, FID)
|
||||
- Limit 'use client':
|
||||
- Favor server components and Next.js SSR
|
||||
- Use only for Web API access in small components
|
||||
- Avoid for data fetching or state management
|
||||
- Use zod for form validation react-hook-form for forms
|
||||
- Look at TeamCreateDialog.tsx as an example of form usage
|
||||
- Use <Form> <FormItem> elements, and also wrap the contents of form in a fieldset which should have the :disabled attribute when the form is loading
|
||||
|
||||
Follow Next.js docs for Data Fetching, Rendering, and Routing
|
||||
TRPC Specifics
|
||||
|
||||
- Every route should be in it's own file, example routers/teams/create-team.ts
|
||||
- Every route should have a types file associated with it, example routers/teams/create-team.types.ts. These files should have the OpenAPI meta, and request/response zod schemas
|
||||
- The request/response schemas should be named like Z[RouteName]RequestSchema and Z[RouteName]ResponseSchema
|
||||
- Use create-team.ts and create-team.types.ts as an example when creating new routes.
|
||||
- When creating the OpenAPI meta, only use GET and POST requests, do not use any other REST methods
|
||||
- Deconstruct the input argument on it's one line of code.
|
||||
|
||||
Toast usage
|
||||
|
||||
- Use the t`string` macro from @lingui/react/macro to display toast messages
|
||||
|
||||
Remix/ReactRouter Usage
|
||||
|
||||
- Use (params: Route.Params) to get the params from the route
|
||||
- Use (loaderData: Route.LoaderData) to get the loader data from the route
|
||||
- When using loaderdata, deconstruct the data you need from the loader data inside the function body
|
||||
- Do not use json() to return data, directly return the data
|
||||
|
||||
Translations
|
||||
|
||||
- Use <Trans>string</Trans> to display translations in jsx code, this should be imported from @lingui/react/macro
|
||||
- Use the t`string` macro from @lingui/react/macro to display translations in typescript code
|
||||
- t should be imported as const { t } = useLingui() where useLingui is imported from @lingui/react/macro
|
||||
- String in constants should be using the t`string` macro
|
||||
|
||||
14
.env.example
@ -1,5 +1,4 @@
|
||||
# [[AUTH]]
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
NEXTAUTH_SECRET="secret"
|
||||
|
||||
# [[CRYPTO]]
|
||||
@ -19,14 +18,10 @@ NEXT_PRIVATE_OIDC_WELL_KNOWN=""
|
||||
NEXT_PRIVATE_OIDC_CLIENT_ID=""
|
||||
NEXT_PRIVATE_OIDC_CLIENT_SECRET=""
|
||||
NEXT_PRIVATE_OIDC_PROVIDER_LABEL="OIDC"
|
||||
# This can be used to still allow signups for OIDC connections
|
||||
# when signup is disabled via `NEXT_PUBLIC_DISABLE_SIGNUP`
|
||||
NEXT_PRIVATE_OIDC_ALLOW_SIGNUP=""
|
||||
NEXT_PRIVATE_OIDC_SKIP_VERIFY=""
|
||||
|
||||
# [[URLS]]
|
||||
NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
|
||||
NEXT_PUBLIC_MARKETING_URL="http://localhost:3001"
|
||||
# URL used by the web app to request itself (e.g. local background jobs)
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000"
|
||||
|
||||
@ -113,13 +108,9 @@ NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5
|
||||
# [[STRIPE]]
|
||||
NEXT_PRIVATE_STRIPE_API_KEY=
|
||||
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET=
|
||||
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID=
|
||||
NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID=
|
||||
|
||||
# [[BACKGROUND JOBS]]
|
||||
NEXT_PRIVATE_JOBS_PROVIDER="local"
|
||||
NEXT_PRIVATE_TRIGGER_API_KEY=
|
||||
NEXT_PRIVATE_TRIGGER_API_URL=
|
||||
NEXT_PRIVATE_INNGEST_EVENT_KEY=
|
||||
|
||||
# [[FEATURES]]
|
||||
@ -135,10 +126,5 @@ E2E_TEST_AUTHENTICATE_USERNAME="Test User"
|
||||
E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
|
||||
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
||||
|
||||
# This is only required for the marketing site
|
||||
# [[REDIS]]
|
||||
NEXT_PRIVATE_REDIS_URL=
|
||||
NEXT_PRIVATE_REDIS_TOKEN=
|
||||
|
||||
# [[LOGGER]]
|
||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=
|
||||
|
||||
@ -5,6 +5,7 @@ module.exports = {
|
||||
rules: {
|
||||
'@next/next/no-img-element': 'off',
|
||||
'no-unreachable': 'error',
|
||||
'react-hooks/exhaustive-deps': 'off',
|
||||
},
|
||||
settings: {
|
||||
next: {
|
||||
|
||||
24
.github/actions/cache-build/action.yml
vendored
@ -1,24 +0,0 @@
|
||||
name: Cache production build binaries
|
||||
description: 'Cache or restore if necessary'
|
||||
inputs:
|
||||
node_version:
|
||||
required: false
|
||||
default: v20.x
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Cache production build
|
||||
uses: actions/cache@v3
|
||||
id: production-build-cache
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/apps/web/.next
|
||||
${{ github.workspace }}/apps/marketing/.next
|
||||
**/.turbo/**
|
||||
**/dist/**
|
||||
|
||||
key: prod-build-${{ github.run_id }}-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: prod-build-
|
||||
|
||||
- run: npm run build
|
||||
shell: bash
|
||||
2
.github/actions/node-install/action.yml
vendored
@ -2,7 +2,7 @@ name: 'Setup node and cache node_modules'
|
||||
inputs:
|
||||
node_version:
|
||||
required: false
|
||||
default: v20.x
|
||||
default: v22.x
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
|
||||
10
.github/dependabot.yml
vendored
@ -11,16 +11,6 @@ updates:
|
||||
- 'ci'
|
||||
open-pull-requests-limit: 0
|
||||
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/apps/marketing'
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
target-branch: 'main'
|
||||
labels:
|
||||
- 'npm dependencies'
|
||||
- 'frontend'
|
||||
open-pull-requests-limit: 0
|
||||
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/apps/web'
|
||||
schedule:
|
||||
|
||||
3
.github/labeler.yml
vendored
@ -1,6 +1,3 @@
|
||||
'apps: marketing':
|
||||
- apps/marketing/**
|
||||
|
||||
'apps: web':
|
||||
- apps/web/**
|
||||
|
||||
|
||||
3
.github/workflows/ci.yml
vendored
@ -26,7 +26,8 @@ jobs:
|
||||
- name: Copy env
|
||||
run: cp .env.example .env
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
- name: Build app
|
||||
run: npm run build
|
||||
|
||||
build_docker:
|
||||
name: Build Docker Image
|
||||
|
||||
29
.github/workflows/clean-cache.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: cleanup caches by a branch
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cleanup
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
|
||||
echo "Fetching list of cache key"
|
||||
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
|
||||
|
||||
## Setting this to not fail the workflow while deleting cache keys.
|
||||
set +e
|
||||
echo "Deleting caches..."
|
||||
for cacheKey in $cacheKeysForPR
|
||||
do
|
||||
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
|
||||
done
|
||||
echo "Done"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
3
.github/workflows/codeql-analysis.yml
vendored
@ -30,7 +30,8 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/node-install
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
- name: Build app
|
||||
run: npm run build
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
|
||||
10
.github/workflows/e2e-tests.yml
vendored
@ -1,14 +1,14 @@
|
||||
name: Playwright Tests
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
branches: ['main', 'feat/rr7']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
jobs:
|
||||
e2e_tests:
|
||||
name: 'E2E Tests'
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: warp-ubuntu-2204-x64-16x
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@ -28,7 +28,11 @@ jobs:
|
||||
- name: Seed the database
|
||||
run: npm run prisma:seed
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
- name: Build app
|
||||
run: npm run build
|
||||
|
||||
- name: Install playwright browsers
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: npm run ci
|
||||
|
||||
8
.github/workflows/publish.yml
vendored
@ -90,7 +90,7 @@ jobs:
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
# Check if the version is stable (no rc or beta in the version)
|
||||
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
docker manifest create \
|
||||
documenso/documenso:latest \
|
||||
--amend documenso/documenso-amd64:latest \
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
docker manifest push documenso/documenso:latest
|
||||
fi
|
||||
|
||||
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
|
||||
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
|
||||
docker manifest create \
|
||||
documenso/documenso:rc \
|
||||
--amend documenso/documenso-amd64:rc \
|
||||
@ -127,7 +127,7 @@ jobs:
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
# Check if the version is stable (no rc or beta in the version)
|
||||
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
docker manifest create \
|
||||
ghcr.io/documenso/documenso:latest \
|
||||
--amend ghcr.io/documenso/documenso-amd64:latest \
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
docker manifest push ghcr.io/documenso/documenso:latest
|
||||
fi
|
||||
|
||||
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
|
||||
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
|
||||
docker manifest create \
|
||||
ghcr.io/documenso/documenso:rc \
|
||||
--amend ghcr.io/documenso/documenso-amd64:rc \
|
||||
|
||||
@ -4,9 +4,7 @@ tasks:
|
||||
npm run dx:up &&
|
||||
cp .env.example .env &&
|
||||
set -a; source .env &&
|
||||
export NEXTAUTH_URL="$(gp url 3000)" &&
|
||||
export NEXT_PUBLIC_WEBAPP_URL="$(gp url 3000)" &&
|
||||
export NEXT_PUBLIC_MARKETING_URL="$(gp url 3001)"
|
||||
command: npm run d
|
||||
|
||||
ports:
|
||||
|
||||
@ -1,4 +1 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run commitlint -- $1
|
||||
|
||||
@ -1,16 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
|
||||
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
|
||||
|
||||
echo "Copying pdf.js"
|
||||
npm run copy:pdfjs --workspace apps/**
|
||||
|
||||
echo "Copying .well-known/ contents"
|
||||
node "$MONOREPO_ROOT/scripts/copy-wellknown.cjs"
|
||||
|
||||
git add "$MONOREPO_ROOT/apps/web/public/"
|
||||
git add "$MONOREPO_ROOT/apps/marketing/public/"
|
||||
git add "$MONOREPO_ROOT/apps/remix/public/"
|
||||
|
||||
npx lint-staged
|
||||
|
||||
2
.npmrc
@ -1 +1,3 @@
|
||||
auto-install-peers = true
|
||||
legacy-peer-deps = true
|
||||
prefer-dedupe = true
|
||||
29
README.md
@ -1,7 +1,3 @@
|
||||
> 🚨 We are live on Product Hunt 🎉 Check out our latest launch: <a href="documen.so/sign-everywhere">The Platform Plan</a>!
|
||||
|
||||
<a href="https://www.producthunt.com/posts/documenso-platform-plan?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-documenso-platform-plan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=670576&theme=light" alt="Documenso Platform Plan - Whitelabeled signing flows in your product | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
|
||||
<img src="https://github.com/documenso/documenso/assets/13398220/a643571f-0239-46a6-a73e-6bef38d1228b" alt="Documenso Logo">
|
||||
|
||||
<p align="center" style="margin-top: 20px">
|
||||
@ -53,8 +49,6 @@ Join us in creating the next generation of open trust infrastructure.
|
||||
|
||||
## Community and Next Steps 🎯
|
||||
|
||||
We're currently working on a redesign of the application, including a revamp of the codebase, so Documenso can be more intuitive to use and robust to develop upon.
|
||||
|
||||
- Check out the first source code release in this repository and test it.
|
||||
- Tell us what you think in the [Discussions](https://github.com/documenso/documenso/discussions).
|
||||
- Join the [Discord server](https://documen.so/discord) for any questions and getting to know to other community members.
|
||||
@ -73,9 +67,9 @@ Contact us if you are interested in our Enterprise plan for large organizations
|
||||
<a href="https://cal.com/timurercan/enterprise-customers?utm_source=banner&utm_campaign=oss"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>
|
||||
|
||||
## Tech Stack
|
||||
|
||||
<p align="left">
|
||||
<a href="https://www.typescriptlang.org"><img src="https://shields.io/badge/TypeScript-3178C6?logo=TypeScript&logoColor=FFF&style=flat-square" alt="TypeScript"></a>
|
||||
<a href="https://nextjs.org/"><img src="https://img.shields.io/badge/next.js-000000?style=flat-square&logo=nextdotjs&logoColor=white" alt="NextJS"></a>
|
||||
<a href="https://prisma.io"><img width="122" height="20" src="http://made-with.prisma.io/indigo.svg" alt="Made with Prisma" /></a>
|
||||
<a href="https://tailwindcss.com/"><img src="https://img.shields.io/badge/tailwindcss-0F172A?&logo=tailwindcss" alt="Tailwind CSS"></a>
|
||||
<a href=""><img src="" alt=""></a>
|
||||
@ -85,20 +79,17 @@ Contact us if you are interested in our Enterprise plan for large organizations
|
||||
<a href=""><img src="" alt=""></a>
|
||||
</p>
|
||||
|
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) - Language
|
||||
- [Next.js](https://nextjs.org/) - Framework
|
||||
- [Prisma](https://www.prisma.io/) - ORM
|
||||
- [ReactRouter](https://reactrouter.com/) - Framework
|
||||
- [Prisma](https://www.prisma.io/) - ORM
|
||||
- [Tailwind](https://tailwindcss.com/) - CSS
|
||||
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
|
||||
- [NextAuth.js](https://next-auth.js.org/) - Authentication
|
||||
- [react-email](https://react.email/) - Email Templates
|
||||
- [tRPC](https://trpc.io/) - API
|
||||
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures (launching soon)
|
||||
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
|
||||
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
|
||||
- [Stripe](https://stripe.com/) - Payments
|
||||
- [Vercel](https://vercel.com) - Hosting
|
||||
|
||||
<!-- - Support for [opensignpdf (requires Java on server)](https://github.com/open-pdf-sign) is currently planned. -->
|
||||
|
||||
@ -108,7 +99,7 @@ Contact us if you are interested in our Enterprise plan for large organizations
|
||||
|
||||
To run Documenso locally, you will need
|
||||
|
||||
- Node.js (v18 or above)
|
||||
- Node.js (v22 or above)
|
||||
- Postgres SQL Database
|
||||
- Docker (optional)
|
||||
|
||||
@ -171,10 +162,8 @@ git clone https://github.com/<your-username>/documenso
|
||||
|
||||
4. Set the following environment variables:
|
||||
|
||||
- NEXTAUTH_URL
|
||||
- NEXTAUTH_SECRET
|
||||
- NEXT_PUBLIC_WEBAPP_URL
|
||||
- NEXT_PUBLIC_MARKETING_URL
|
||||
- NEXT_PRIVATE_DATABASE_URL
|
||||
- NEXT_PRIVATE_DIRECT_DATABASE_URL
|
||||
- NEXT_PRIVATE_SMTP_FROM_NAME
|
||||
@ -243,29 +232,27 @@ cp .env.example .env
|
||||
|
||||
The following environment variables must be set:
|
||||
|
||||
- `NEXTAUTH_URL`
|
||||
- `NEXTAUTH_SECRET`
|
||||
- `NEXT_PUBLIC_WEBAPP_URL`
|
||||
- `NEXT_PUBLIC_MARKETING_URL`
|
||||
- `NEXT_PRIVATE_DATABASE_URL`
|
||||
- `NEXT_PRIVATE_DIRECT_DATABASE_URL`
|
||||
- `NEXT_PRIVATE_SMTP_FROM_NAME`
|
||||
- `NEXT_PRIVATE_SMTP_FROM_ADDRESS`
|
||||
|
||||
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for both `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
|
||||
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for the `NEXT_PUBLIC_WEBAPP_URL` variable!
|
||||
|
||||
Now you can install the dependencies and build it:
|
||||
|
||||
```
|
||||
npm i
|
||||
npm run build:web
|
||||
npm run build
|
||||
npm run prisma:migrate-deploy
|
||||
```
|
||||
|
||||
Finally, you can start it with:
|
||||
|
||||
```
|
||||
cd apps/web
|
||||
cd apps/remix
|
||||
npm run start
|
||||
```
|
||||
|
||||
@ -286,7 +273,7 @@ After=network.target
|
||||
Environment=PATH=/path/to/your/node/binaries
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/var/www/documenso/apps/web
|
||||
WorkingDirectory=/var/www/documenso/apps/remix
|
||||
ExecStart=/usr/bin/next start -p 3500
|
||||
TimeoutSec=15
|
||||
Restart=always
|
||||
|
||||
5
apps/documentation/.gitignore
vendored
@ -34,3 +34,8 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# next-sitemap output
|
||||
/public/sitemap.xml
|
||||
/public/robots.txt
|
||||
/public/sitemap-*.xml
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Button } from '../primitives/button';
|
||||
import { Card, CardContent } from '../primitives/card';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
|
||||
type CallToActionProps = {
|
||||
className?: string;
|
||||
5
apps/documentation/next-sitemap.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
/** @type {import('next-sitemap').IConfig} */
|
||||
module.exports = {
|
||||
siteUrl: 'https://docs.documenso.com', // Replace with your actual site URL
|
||||
generateRobotsTxt: true, // Generates robots.txt
|
||||
};
|
||||
@ -1,3 +1,5 @@
|
||||
import nextra from 'nextra';
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
transpilePackages: [
|
||||
@ -9,9 +11,10 @@ const nextConfig = {
|
||||
],
|
||||
};
|
||||
|
||||
const withNextra = require('nextra')({
|
||||
const withNextra = nextra({
|
||||
theme: 'nextra-theme-docs',
|
||||
themeConfig: './theme.config.tsx',
|
||||
codeHighlight: true,
|
||||
});
|
||||
|
||||
module.exports = withNextra(nextConfig);
|
||||
export default withNextra(nextConfig);
|
||||
|
||||
@ -4,11 +4,10 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3002",
|
||||
"build": "next build",
|
||||
"build": "next build && next-sitemap",
|
||||
"start": "next start -p 3002",
|
||||
"lint:fix": "next lint --fix",
|
||||
"clean": "rimraf .next && rimraf node_modules",
|
||||
"copy:pdfjs": "node ../../scripts/copy-pdfjs.cjs"
|
||||
"clean": "rimraf .next && rimraf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@documenso/assets": "*",
|
||||
@ -16,7 +15,7 @@
|
||||
"@documenso/tailwind-config": "*",
|
||||
"@documenso/trpc": "*",
|
||||
"@documenso/ui": "*",
|
||||
"next": "14.2.6",
|
||||
"next": "14.2.28",
|
||||
"next-plausible": "^3.12.0",
|
||||
"nextra": "^2.13.4",
|
||||
"nextra-theme-docs": "^2.13.4",
|
||||
@ -27,6 +26,7 @@
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"typescript": "^5"
|
||||
"next-sitemap": "^4.2.3",
|
||||
"typescript": "5.6.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import '../styles.css';
|
||||
export default function App({ Component, pageProps }) {
|
||||
return (
|
||||
<PlausibleProvider>
|
||||
<Component {...pageProps} />;
|
||||
<Component {...pageProps} />
|
||||
</PlausibleProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"title": "Development & Deployment"
|
||||
},
|
||||
"local-development": "Local Development",
|
||||
"developer-mode": "Developer Mode",
|
||||
"self-hosting": "Self Hosting",
|
||||
"contributing": "Contributing",
|
||||
"-- API & Integration Guides": {
|
||||
@ -14,4 +15,4 @@
|
||||
"public-api": "Public API",
|
||||
"embedding": "Embedding",
|
||||
"webhooks": "Webhooks"
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,11 +20,7 @@ If you are looking for development notes on translations, you can find them [her
|
||||
|
||||
We store our translations in PO files, which are located in our GitHub repository [here](https://github.com/documenso/documenso/tree/main/packages/lib/translations).
|
||||
|
||||
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc). Each language folder contains three PO files:
|
||||
|
||||
1. `web.po`: Translations for the web application
|
||||
2. `marketing.po`: Translations for the marketing application
|
||||
3. `common.po`: Shared translations between web and marketing
|
||||
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc).
|
||||
|
||||
Each PO file contains translations which look like this:
|
||||
|
||||
@ -46,11 +42,10 @@ msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüf
|
||||
### Updating Existing Translations
|
||||
|
||||
1. Fork the repository.
|
||||
2. Navigate to the appropriate language folder.
|
||||
3. Open the PO file you want to update (web.po, marketing.po, or common.po).
|
||||
4. Make your changes, ensuring you follow the PO file format.
|
||||
5. Commit your changes with a message such as `chore: update German translations`
|
||||
6. Create a Pull Request.
|
||||
2. Navigate to the appropriate language folder and open the PO file you want to update.
|
||||
3. Make your changes, ensuring you follow the PO file format.
|
||||
4. Commit your changes with a message such as `chore: update German translations`
|
||||
5. Create a Pull Request.
|
||||
|
||||
### Adding a New Language
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Field Coordinates
|
||||
description: Learn how to get the coordinates of a field in a document.
|
||||
---
|
||||
|
||||
## Field Coordinates
|
||||
|
||||
Field coordinates represent the position of a field in a document. They are returned in the `pageX` and `pageY` properties of the field.
|
||||
|
||||
To enable field coordinates, you can use the `devmode` query parameter.
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/documents/<document-id>/edit?devmode=true
|
||||
```
|
||||
|
||||
You should then see the coordinates on top of each field.
|
||||
|
||||

|
||||
@ -5,5 +5,7 @@
|
||||
"svelte": "Svelte Integration",
|
||||
"solid": "Solid Integration",
|
||||
"preact": "Preact Integration",
|
||||
"css-variables": "CSS Variables"
|
||||
"angular": "Angular Integration",
|
||||
"css-variables": "CSS Variables",
|
||||
"authoring": "Authoring"
|
||||
}
|
||||
90
apps/documentation/pages/developers/embedding/angular.mdx
Normal file
@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Angular Integration
|
||||
description: Learn how to use our embedding SDK within your Angular application.
|
||||
---
|
||||
|
||||
# Angular Integration
|
||||
|
||||
Our Angular SDK provides a simple way to embed a signing experience within your Angular application. It supports both direct link templates and signing tokens.
|
||||
|
||||
## Installation
|
||||
|
||||
To install the SDK, run the following command:
|
||||
|
||||
```bash
|
||||
npm install @documenso/embed-angular
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case.
|
||||
|
||||
### Direct Link Template
|
||||
|
||||
If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component.
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
import { EmbedDirectTemplate } from '@documenso/embed-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-embedding',
|
||||
template: `
|
||||
<embed-direct-template [token]="token" />
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [EmbedDirectTemplate],
|
||||
})
|
||||
export class EmbeddingComponent {
|
||||
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
|
||||
}
|
||||
```
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Description |
|
||||
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| token | string | The token for the document you want to embed |
|
||||
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
|
||||
| name | string (optional) | The name the signer that will be used by default for signing |
|
||||
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
|
||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||
| onFieldSigned | function (optional) | A callback function that will be called when a field is signed |
|
||||
| onFieldUnsigned | function (optional) | A callback function that will be called when a field is unsigned |
|
||||
|
||||
### Signing Token
|
||||
|
||||
If you have a signing token, you can provide it to the `EmbedSignDocument` component.
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
import { EmbedSignDocument } from '@documenso/embed-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-embedding',
|
||||
template: `
|
||||
<embed-sign-document [token]="token" />
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [EmbedSignDocument],
|
||||
})
|
||||
export class EmbeddingComponent {
|
||||
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
|
||||
}
|
||||
```
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Description |
|
||||
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| token | string | The token for the document you want to embed |
|
||||
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
|
||||
| name | string (optional) | The name the signer that will be used by default for signing |
|
||||
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
|
||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||
167
apps/documentation/pages/developers/embedding/authoring.mdx
Normal file
@ -0,0 +1,167 @@
|
||||
---
|
||||
title: Authoring
|
||||
description: Learn how to use embedded authoring to create documents and templates in your application
|
||||
---
|
||||
|
||||
# Embedded Authoring
|
||||
|
||||
In addition to embedding signing experiences, Documenso now supports embedded authoring, allowing you to integrate document and template creation directly within your application.
|
||||
|
||||
## How Embedded Authoring Works
|
||||
|
||||
The embedded authoring feature enables your users to create new documents without leaving your application. This process works through secure presign tokens that authenticate the embedding session and manage permissions.
|
||||
|
||||
## Creating Documents with Embedded Authoring
|
||||
|
||||
To implement document creation in your application, use the `EmbedCreateDocument` component from our SDK:
|
||||
|
||||
```jsx
|
||||
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
|
||||
|
||||
const DocumentCreator = () => {
|
||||
// You'll need to obtain a presign token using your API key
|
||||
const presignToken = 'YOUR_PRESIGN_TOKEN';
|
||||
|
||||
return (
|
||||
<div style={{ height: '800px', width: '100%' }}>
|
||||
<EmbedCreateDocument
|
||||
presignToken={presignToken}
|
||||
externalId="order-12345"
|
||||
onDocumentCreated={(data) => {
|
||||
console.log('Document created with ID:', data.documentId);
|
||||
console.log('External reference ID:', data.externalId);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Obtaining a Presign Token
|
||||
|
||||
Before using the `EmbedCreateDocument` component, you'll need to obtain a presign token from your backend. This token authorizes the embedding session.
|
||||
|
||||
You can create a presign token by making a request to:
|
||||
|
||||
```
|
||||
POST /api/v2-beta/embedding/create-presign-token
|
||||
```
|
||||
|
||||
This API endpoint requires authentication with your Documenso API key. The token has a default expiration of 1 hour, but you can customize this duration based on your security requirements.
|
||||
|
||||
You can find more details on this request at our [API Documentation](https://openapi.documenso.com/reference#tag/embedding)
|
||||
|
||||
## Configuration Options
|
||||
|
||||
The `EmbedCreateDocument` component accepts several configuration options:
|
||||
|
||||
| Option | Type | Description |
|
||||
| ------------------ | ------- | ------------------------------------------------------------------ |
|
||||
| `presignToken` | string | **Required**. The authentication token for the embedding session. |
|
||||
| `externalId` | string | Optional reference ID from your system to link with the document. |
|
||||
| `host` | string | Optional custom host URL. Defaults to `https://app.documenso.com`. |
|
||||
| `css` | string | Optional custom CSS to style the embedded component. |
|
||||
| `cssVars` | object | Optional CSS variables for colors, spacing, and more. |
|
||||
| `darkModeDisabled` | boolean | Optional flag to disable dark mode. |
|
||||
| `className` | string | Optional CSS class name for the iframe. |
|
||||
|
||||
## Feature Toggles
|
||||
|
||||
You can customize the authoring experience by enabling or disabling specific features:
|
||||
|
||||
```jsx
|
||||
<EmbedCreateDocument
|
||||
presignToken="YOUR_PRESIGN_TOKEN"
|
||||
features={{
|
||||
allowConfigureSignatureTypes: true,
|
||||
allowConfigureLanguage: true,
|
||||
allowConfigureDateFormat: true,
|
||||
allowConfigureTimezone: true,
|
||||
allowConfigureRedirectUrl: true,
|
||||
allowConfigureCommunication: true,
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Handling Document Creation Events
|
||||
|
||||
The `onDocumentCreated` callback is triggered when a document is successfully created, providing both the document ID and your external reference ID:
|
||||
|
||||
```jsx
|
||||
<EmbedCreateDocument
|
||||
presignToken="YOUR_PRESIGN_TOKEN"
|
||||
externalId="order-12345"
|
||||
onDocumentCreated={(data) => {
|
||||
// Navigate to a success page
|
||||
navigate(`/documents/success?id=${data.documentId}`);
|
||||
|
||||
// Or update your database with the document ID
|
||||
updateOrderDocument(data.externalId, data.documentId);
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Styling the Embedded Component
|
||||
|
||||
You can customize the appearance of the embedded component using standard CSS classes:
|
||||
|
||||
```jsx
|
||||
<EmbedCreateDocument
|
||||
className="h-screen w-full rounded-lg border-none shadow-md"
|
||||
presignToken="YOUR_PRESIGN_TOKEN"
|
||||
css={`
|
||||
.documenso-embed {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
`}
|
||||
cssVars={{
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## Complete Integration Example
|
||||
|
||||
Here's a complete example of integrating document creation in a React application:
|
||||
|
||||
```tsx
|
||||
import { useState } from 'react';
|
||||
|
||||
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
|
||||
|
||||
function DocumentCreator() {
|
||||
// In a real application, you would fetch this token from your backend
|
||||
// using your API key at /api/v2-beta/embedding/create-presign-token
|
||||
const presignToken = 'YOUR_PRESIGN_TOKEN';
|
||||
const [documentId, setDocumentId] = useState<number | null>(null);
|
||||
|
||||
if (documentId) {
|
||||
return (
|
||||
<div>
|
||||
<h2>Document Created Successfully!</h2>
|
||||
<p>Document ID: {documentId}</p>
|
||||
<button onClick={() => setDocumentId(null)}>Create Another Document</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: '800px', width: '100%' }}>
|
||||
<EmbedCreateDocument
|
||||
presignToken={presignToken}
|
||||
externalId="order-12345"
|
||||
onDocumentCreated={(data) => {
|
||||
setDocumentId(data.documentId);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DocumentCreator;
|
||||
```
|
||||
|
||||
With embedded authoring, your users can seamlessly create documents within your application, enhancing the overall user experience and streamlining document workflows.
|
||||
@ -111,6 +111,83 @@ The colors will be automatically converted to the appropriate format internally.
|
||||
|
||||
4. **Consistent Radius**: Use a consistent border radius value that matches your application's design system.
|
||||
|
||||
## CSS Class Targets
|
||||
|
||||
In addition to CSS variables, specific components in the embedded experience can be targeted using CSS classes for more granular styling:
|
||||
|
||||
### Component Classes
|
||||
|
||||
| Class Name | Description |
|
||||
| --------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `.embed--Root` | Main container for the embedded signing experience |
|
||||
| `.embed--DocumentContainer` | Container for the document and signing widget |
|
||||
| `.embed--DocumentViewer` | Container for the document viewer |
|
||||
| `.embed--DocumentWidget` | The signing widget container |
|
||||
| `.embed--DocumentWidgetContainer` | Outer container for the signing widget, handles positioning |
|
||||
| `.embed--DocumentWidgetHeader` | Header section of the signing widget |
|
||||
| `.embed--DocumentWidgetContent` | Main content area of the signing widget |
|
||||
| `.embed--DocumentWidgetForm` | Form section within the signing widget |
|
||||
| `.embed--DocumentWidgetFooter` | Footer section of the signing widget |
|
||||
| `.embed--WaitingForTurn` | Container for the waiting screen when it's not the user's turn to sign |
|
||||
| `.embed--DocumentCompleted` | Container for the completion screen after signing |
|
||||
| `.field--FieldRootContainer` | Base container for document fields (signatures, text, checkboxes, etc.) |
|
||||
|
||||
Field components also expose several data attributes that can be used for styling different states:
|
||||
|
||||
| Data Attribute | Values | Description |
|
||||
| ------------------- | ---------------------------------------------- | ------------------------------------ |
|
||||
| `[data-field-type]` | `SIGNATURE`, `TEXT`, `CHECKBOX`, `RADIO`, etc. | The type of field |
|
||||
| `[data-inserted]` | `true`, `false` | Whether the field has been filled |
|
||||
| `[data-validate]` | `true`, `false` | Whether the field is being validated |
|
||||
|
||||
### Field Styling Example
|
||||
|
||||
```css
|
||||
/* Style all field containers */
|
||||
.field--FieldRootContainer {
|
||||
transition: all 200ms ease;
|
||||
}
|
||||
|
||||
/* Style specific field types */
|
||||
.field--FieldRootContainer[data-field-type='SIGNATURE'] {
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
/* Style inserted fields */
|
||||
.field--FieldRootContainer[data-inserted='true'] {
|
||||
background-color: var(--primary);
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
/* Style fields being validated */
|
||||
.field--FieldRootContainer[data-validate='true'] {
|
||||
border-color: orange;
|
||||
}
|
||||
```
|
||||
|
||||
### Example Usage
|
||||
|
||||
```css
|
||||
/* Custom styles for the document widget */
|
||||
.embed--DocumentWidget {
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
/* Custom styles for the waiting screen */
|
||||
.embed--WaitingForTurn {
|
||||
background-color: #f9fafb;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Responsive adjustments for the document container */
|
||||
@media (min-width: 768px) {
|
||||
.embed--DocumentContainer {
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [React Integration](/developers/embedding/react)
|
||||
|
||||
@ -5,7 +5,7 @@ description: Learn how to use embedding to bring signing to your own website or
|
||||
|
||||
# Embedding
|
||||
|
||||
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, or using generalized web components, this guide will help you get started with embedding Documenso.
|
||||
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, Angular, or using generalized web components, this guide will help you get started with embedding Documenso.
|
||||
|
||||
## Availability
|
||||
|
||||
@ -52,9 +52,9 @@ Platform customers have access to advanced styling options to customize the embe
|
||||
<EmbedDirectTemplate
|
||||
token={token}
|
||||
cssVars={{
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
}}
|
||||
/>
|
||||
```
|
||||
@ -73,13 +73,14 @@ These customization options are available for both Direct Templates and Signing
|
||||
|
||||
We support embedding across a range of popular JavaScript frameworks, including:
|
||||
|
||||
| Framework | Package |
|
||||
| --------- | -------------------------------------------------------------------------------- |
|
||||
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
|
||||
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
|
||||
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
|
||||
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
|
||||
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
|
||||
| Framework | Package |
|
||||
| --------- | ---------------------------------------------------------------------------------- |
|
||||
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
|
||||
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
|
||||
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
|
||||
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
|
||||
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
|
||||
| Angular | [@documenso/embed-angular](https://www.npmjs.com/package/@documenso/embed-angular) |
|
||||
|
||||
Additionally, we provide **web components** for more generalized use. However, please note that web components are still in their early stages and haven't been extensively tested.
|
||||
|
||||
@ -127,7 +128,7 @@ This will show a dialog which will ask you to configure which recipient should b
|
||||
|
||||
## Embedding with Signing Tokens
|
||||
|
||||
To embed the signing process for an ordinary document, you’ll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
|
||||
To embed the signing process for an ordinary document, you'll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
|
||||
|
||||
#### Instructions
|
||||
|
||||
@ -164,9 +165,23 @@ Once you've obtained the appropriate tokens, you can integrate the signing exper
|
||||
- [Vue](/developers/embedding/vue)
|
||||
- [Svelte](/developers/embedding/svelte)
|
||||
- [Solid](/developers/embedding/solid)
|
||||
- [Angular](/developers/embedding/angular)
|
||||
|
||||
If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases.
|
||||
|
||||
## Embedded Authoring
|
||||
|
||||
In addition to embedding signing experiences, Documenso now supports **embedded authoring**, allowing your users to create documents and templates directly within your application.
|
||||
|
||||
With embedded authoring, you can:
|
||||
|
||||
- Create new documents with custom fields
|
||||
- Configure document properties and settings
|
||||
- Set up recipients and signing workflows
|
||||
- Customize the authoring experience
|
||||
|
||||
For detailed implementation instructions and code examples, see our [Embedded Authoring](/developers/embedding/authoring) guide.
|
||||
|
||||
## Related
|
||||
|
||||
- [React Integration](/developers/embedding/react)
|
||||
@ -174,4 +189,6 @@ If you're using **web components**, the integration process is slightly differen
|
||||
- [Svelte Integration](/developers/embedding/svelte)
|
||||
- [Solid Integration](/developers/embedding/solid)
|
||||
- [Preact Integration](/developers/embedding/preact)
|
||||
- [Angular Integration](/developers/embedding/angular)
|
||||
- [CSS Variables](/developers/embedding/css-variables)
|
||||
- [Embedded Authoring](/developers/embedding/authoring)
|
||||
|
||||
@ -95,9 +95,9 @@ const MyEmbeddingComponent = () => {
|
||||
}
|
||||
`;
|
||||
const cssVars = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -99,9 +99,9 @@ const MyEmbeddingComponent = () => {
|
||||
`}
|
||||
// CSS Variables
|
||||
cssVars={{
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
}}
|
||||
// Dark Mode Control
|
||||
darkModeDisabled={true}
|
||||
|
||||
@ -95,9 +95,9 @@ const MyEmbeddingComponent = () => {
|
||||
}
|
||||
`;
|
||||
const cssVars = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -97,9 +97,9 @@ Platform customers have access to advanced styling options:
|
||||
}
|
||||
`;
|
||||
const cssVars = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@ -97,9 +97,9 @@ Platform customers have access to advanced styling options:
|
||||
}
|
||||
`;
|
||||
const cssVars = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
primary: '#0000FF',
|
||||
background: '#F5F5F5',
|
||||
radius: '8px',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@ -16,18 +16,16 @@ Pick the one that fits your needs the best.
|
||||
## Tech Stack
|
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) - Language
|
||||
- [Next.js](https://nextjs.org/) - Framework
|
||||
- [React Router](https://reactrouter.com/) - Framework
|
||||
- [Prisma](https://www.prisma.io/) - ORM
|
||||
- [Tailwind](https://tailwindcss.com/) - CSS
|
||||
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
|
||||
- [NextAuth.js](https://next-auth.js.org/) - Authentication
|
||||
- [react-email](https://react.email/) - Email Templates
|
||||
- [tRPC](https://trpc.io/) - API
|
||||
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures
|
||||
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
|
||||
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
|
||||
- [Stripe](https://stripe.com/) - Payments
|
||||
- [Vercel](https://vercel.com) - Hosting
|
||||
|
||||
<div className="mt-16 flex items-center justify-center gap-4">
|
||||
<a href="https://documen.so/discord">
|
||||
|
||||
@ -32,10 +32,8 @@ Run `npm i` in the root directory to install the dependencies required for the p
|
||||
Set up the following environment variables in the `.env` file:
|
||||
|
||||
```bash
|
||||
NEXTAUTH_URL
|
||||
NEXTAUTH_SECRET
|
||||
NEXT_PUBLIC_WEBAPP_URL
|
||||
NEXT_PUBLIC_MARKETING_URL
|
||||
NEXT_PRIVATE_DATABASE_URL
|
||||
NEXT_PRIVATE_DIRECT_DATABASE_URL
|
||||
NEXT_PRIVATE_SMTP_FROM_NAME
|
||||
|
||||
@ -13,35 +13,13 @@ Documenso uses the following stack to handle translations:
|
||||
|
||||
Additional reading can be found in the [Lingui documentation](https://lingui.dev/introduction).
|
||||
|
||||
## Requirements
|
||||
|
||||
You **must** insert **`setupI18nSSR()`** when creating any of the following files:
|
||||
|
||||
- Server layout.tsx
|
||||
- Server page.tsx
|
||||
- Server loading.tsx
|
||||
|
||||
Server meaning it does not have `'use client'` in it.
|
||||
|
||||
```tsx
|
||||
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
|
||||
|
||||
export default function SomePage() {
|
||||
setupI18nSSR(); // Required if there are translations within the page, or nested in components.
|
||||
|
||||
// Rest of code...
|
||||
}
|
||||
```
|
||||
|
||||
Additional information can be found [here.](https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui)
|
||||
|
||||
## Quick guide
|
||||
|
||||
If you require more in-depth information, please see the [Lingui documentation](https://lingui.dev/introduction).
|
||||
|
||||
### HTML
|
||||
|
||||
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/macro** (not @lingui/react).
|
||||
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/react/macro**.
|
||||
|
||||
```html
|
||||
<h1>
|
||||
@ -64,8 +42,9 @@ For text that is broken into elements, but represent a whole sentence, you must
|
||||
### Constants outside of react components
|
||||
|
||||
```tsx
|
||||
import { Trans, msg } from '@lingui/macro';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
// Wrap text in msg`text to translate` when it's in a constant here, or another file/package.
|
||||
export const CONSTANT_WITH_MSG = {
|
||||
@ -98,31 +77,13 @@ Lingui provides a Plural component to make it easy. See full documentation [here
|
||||
|
||||
Lingui provides a [DateTime instance](https://lingui.dev/ref/core#i18n.date) with the configured locale.
|
||||
|
||||
#### Server components
|
||||
|
||||
Note that the i18n instance is coming from **setupI18nSSR**.
|
||||
|
||||
```tsx
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
|
||||
export const SomeComponent = () => {
|
||||
const { i18n } = setupI18nSSR();
|
||||
const { i18n } = useLingui();
|
||||
|
||||
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
|
||||
};
|
||||
```
|
||||
|
||||
#### Client components
|
||||
|
||||
Note that the i18n instance is coming from the **import**.
|
||||
|
||||
```tsx
|
||||
import { i18n } from '@lingui/core';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
|
||||
export const SomeComponent = () => {
|
||||
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
|
||||
};
|
||||
```
|
||||
|
||||
@ -3,6 +3,8 @@ title: Public API
|
||||
description: Learn how to interact with your documents programmatically using the Documenso public API.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Public API
|
||||
|
||||
Documenso provides a public REST API enabling you to interact with your documents programmatically. The API exposes various HTTP endpoints that allow you to perform operations such as:
|
||||
@ -13,10 +15,35 @@ Documenso provides a public REST API enabling you to interact with your document
|
||||
|
||||
The documentation walks you through creating API keys and using them to authenticate your API requests. You'll also learn about the available endpoints, request and response formats, and how to use the API.
|
||||
|
||||
## Swagger Documentation
|
||||
## API V1 - Stable
|
||||
|
||||
The [Swagger documentation](https://app.documenso.com/api/v1/openapi) also provides information about the API endpoints, request parameters, response formats, and authentication methods.
|
||||
Check out the [API V1 documentation](https://app.documenso.com/api/v1/openapi) for details about the API endpoints, request parameters, response formats, and authentication methods.
|
||||
|
||||
## API V2 - Beta
|
||||
|
||||
<Callout type="warning">API V2 is currently beta, and will be subject to breaking changes</Callout>
|
||||
|
||||
Check out the [API V2 documentation](https://documen.so/api-v2-docs) for details about the API endpoints, request parameters, response formats, and authentication methods.
|
||||
|
||||
Our new API V2 supports the following typed SDKs:
|
||||
|
||||
- [TypeScript](https://github.com/documenso/sdk-typescript)
|
||||
- [Python](https://github.com/documenso/sdk-python)
|
||||
- [Go](https://github.com/documenso/sdk-go)
|
||||
|
||||
<Callout type="info">
|
||||
For the staging API, please use the following base URL:
|
||||
`https://stg-app.documenso.dev/api/v2-beta/`
|
||||
</Callout>
|
||||
|
||||
🚀 [V2 Announcement](https://documen.so/sdk-blog)
|
||||
|
||||
📖 [Documentation](https://documen.so/api-v2-docs)
|
||||
|
||||
💬 [Leave Feedback](https://documen.so/sdk-feedback)
|
||||
|
||||
🔔 [Breaking Changes](https://documen.so/sdk-breaking)
|
||||
|
||||
## Availability
|
||||
|
||||
The API is available to individual users and teams.
|
||||
The API is available to individual users, teams and higher plans. [Fair Use](https://documen.so/fair) applies.
|
||||
|
||||
@ -532,3 +532,93 @@ Replace the `text` value with the corresponding field type:
|
||||
- For the `SELECT` field it should be `select`. (check this before merge)
|
||||
|
||||
You must pass this property at all times, even if you don't need to set any other properties. If you don't, the endpoint will throw an error.
|
||||
|
||||
## Pre-fill Fields On Document Creation
|
||||
|
||||
The API allows you to pre-fill fields on document creation. This is useful when you want to create a document from an existing template and pre-fill the fields with specific values.
|
||||
|
||||
To pre-fill a field, you need to make a `POST` request to the `/api/v1/templates/{templateId}/generate-document` endpoint with the field information. Here's an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "my-document.pdf",
|
||||
"recipients": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Example User",
|
||||
"email": "example@documenso.com",
|
||||
"signingOrder": 1,
|
||||
"role": "SIGNER"
|
||||
}
|
||||
],
|
||||
"prefillFields": [
|
||||
{
|
||||
"id": 21,
|
||||
"type": "text",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": "my-value"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": "number",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": "123"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"type": "checkbox",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": ["option-1", "option-2"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Check out the endpoint in the [API V1 documentation](https://app.documenso.com/api/v1/openapi#:~:text=/%7BtemplateId%7D/-,generate,-%2Ddocument).
|
||||
|
||||
### API V2
|
||||
|
||||
For API V2, you need to make a `POST` request to the `/api/v2-beta/template/use` endpoint with the field(s) information. Here's an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"templateId": 111,
|
||||
"recipients": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Example User",
|
||||
"email": "example@documenso.com",
|
||||
"signingOrder": 1,
|
||||
"role": "SIGNER"
|
||||
}
|
||||
],
|
||||
"prefillFields": [
|
||||
{
|
||||
"id": 21,
|
||||
"type": "text",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": "my-value"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": "number",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": "123"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"type": "checkbox",
|
||||
"label": "my-label",
|
||||
"placeholder": "my-placeholder",
|
||||
"value": ["option-1", "option-2"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Check out the endpoint in the [API V2 documentation](https://openapi.documenso.com/reference#tag/template/POST/template/use).
|
||||
|
||||
@ -5,7 +5,7 @@ description: Learn how to self-host Documenso on your server or cloud infrastruc
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
import { CallToAction } from '@documenso/ui/components/call-to-action';
|
||||
import { CallToAction } from '../../../components/call-to-action';
|
||||
|
||||
# Self Hosting
|
||||
|
||||
@ -35,10 +35,8 @@ cp .env.example .env
|
||||
Open the `.env` file and fill in the following variables:
|
||||
|
||||
```bash
|
||||
- NEXTAUTH_URL
|
||||
- NEXTAUTH_SECRET
|
||||
- NEXT_PUBLIC_WEBAPP_URL
|
||||
- NEXT_PUBLIC_MARKETING_URL
|
||||
- NEXT_PRIVATE_DATABASE_URL
|
||||
- NEXT_PRIVATE_DIRECT_DATABASE_URL
|
||||
- NEXT_PRIVATE_SMTP_FROM_NAME
|
||||
@ -46,8 +44,8 @@ Open the `.env` file and fill in the following variables:
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for both
|
||||
the `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
|
||||
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for the
|
||||
`NEXT_PUBLIC_WEBAPP_URL` variable!
|
||||
</Callout>
|
||||
|
||||
### Install the Dependencies
|
||||
@ -171,7 +169,6 @@ Run the Docker container with the required environment variables:
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 3000:3000 \
|
||||
-e NEXTAUTH_URL="<your-nextauth-url>"
|
||||
-e NEXTAUTH_SECRET="<your-nextauth-secret>"
|
||||
-e NEXT_PRIVATE_ENCRYPTION_KEY="<your-next-private-encryption-key>"
|
||||
-e NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="<your-next-private-encryption-secondary-key>"
|
||||
@ -200,7 +197,6 @@ The environment variables listed above are a subset of those available for confi
|
||||
| Variable | Description |
|
||||
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `PORT` | The port on which the Documenso application runs. It defaults to `3000`. |
|
||||
| `NEXTAUTH_URL` | The URL for the NextAuth.js authentication service. |
|
||||
| `NEXTAUTH_SECRET` | The secret key used by NextAuth.js for encryption and signing. |
|
||||
| `NEXT_PRIVATE_ENCRYPTION_KEY` | The primary encryption key for symmetric encryption and decryption (at least 32 characters). |
|
||||
| `NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY` | The secondary encryption key for symmetric encryption and decryption (at least 32 characters). |
|
||||
|
||||
@ -3,7 +3,7 @@ title: Getting Started with Self-Hosting
|
||||
description: A step-by-step guide to setting up and hosting your own Documenso instance.
|
||||
---
|
||||
|
||||
import { CallToAction } from '@documenso/ui/components/call-to-action';
|
||||
import { CallToAction } from '../../../components/call-to-action';
|
||||
|
||||
# Getting Started with Self-Hosting
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ Documenso supports Webhooks and allows you to subscribe to the following events:
|
||||
- `document.signed`
|
||||
- `document.completed`
|
||||
- `document.rejected`
|
||||
- `document.cancelled`
|
||||
|
||||
## Create a webhook subscription
|
||||
|
||||
@ -37,7 +38,7 @@ Clicking on the "**Create Webhook**" button opens a modal to create a new webhoo
|
||||
To create a new webhook subscription, you need to provide the following information:
|
||||
|
||||
- Enter the webhook URL that will receive the event payload.
|
||||
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`, `document.rejected`.
|
||||
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`, `document.rejected`, `document.cancelled`.
|
||||
- Optionally, you can provide a secret key that will be used to sign the payload. This key will be included in the `X-Documenso-Secret` header of the request.
|
||||
|
||||

|
||||
@ -528,6 +529,96 @@ Example payload for the `document.rejected` event:
|
||||
}
|
||||
```
|
||||
|
||||
Example payload for the `document.rejected` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_CANCELLED",
|
||||
"payload": {
|
||||
"id": 7,
|
||||
"externalId": null,
|
||||
"userId": 3,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"visibility": "EVERYONE",
|
||||
"title": "documenso.pdf",
|
||||
"status": "PENDING",
|
||||
"documentDataId": "cm6exvn93006hi02ru90a265a",
|
||||
"createdAt": "2025-01-27T11:02:14.393Z",
|
||||
"updatedAt": "2025-01-27T11:03:16.387Z",
|
||||
"completedAt": null,
|
||||
"deletedAt": null,
|
||||
"teamId": null,
|
||||
"templateId": null,
|
||||
"source": "DOCUMENT",
|
||||
"documentMeta": {
|
||||
"id": "cm6exvn96006ji02rqvzjvwoy",
|
||||
"subject": "",
|
||||
"message": "",
|
||||
"timezone": "Etc/UTC",
|
||||
"password": null,
|
||||
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||
"redirectUrl": "",
|
||||
"signingOrder": "PARALLEL",
|
||||
"typedSignatureEnabled": true,
|
||||
"language": "en",
|
||||
"distributionMethod": "EMAIL",
|
||||
"emailSettings": {
|
||||
"documentDeleted": true,
|
||||
"documentPending": true,
|
||||
"recipientSigned": true,
|
||||
"recipientRemoved": true,
|
||||
"documentCompleted": true,
|
||||
"ownerDocumentCompleted": true,
|
||||
"recipientSigningRequest": true
|
||||
}
|
||||
},
|
||||
"recipients": [
|
||||
{
|
||||
"id": 7,
|
||||
"documentId": 7,
|
||||
"templateId": null,
|
||||
"email": "mybirihix@mailinator.com",
|
||||
"name": "Zorita Baird",
|
||||
"token": "XkKx1HCs6Znm2UBJA2j6o",
|
||||
"documentDeletedAt": null,
|
||||
"expired": null,
|
||||
"signedAt": null,
|
||||
"authOptions": { "accessAuth": null, "actionAuth": null },
|
||||
"signingOrder": 1,
|
||||
"rejectionReason": null,
|
||||
"role": "SIGNER",
|
||||
"readStatus": "NOT_OPENED",
|
||||
"signingStatus": "NOT_SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
],
|
||||
"Recipient": [
|
||||
{
|
||||
"id": 7,
|
||||
"documentId": 7,
|
||||
"templateId": null,
|
||||
"email": "signer@documenso.com",
|
||||
"name": "Signer",
|
||||
"token": "XkKx1HCs6Znm2UBJA2j6o",
|
||||
"documentDeletedAt": null,
|
||||
"expired": null,
|
||||
"signedAt": null,
|
||||
"authOptions": { "accessAuth": null, "actionAuth": null },
|
||||
"signingOrder": 1,
|
||||
"rejectionReason": null,
|
||||
"role": "SIGNER",
|
||||
"readStatus": "NOT_OPENED",
|
||||
"signingStatus": "NOT_SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createdAt": "2025-01-27T11:03:27.730Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
## Availability
|
||||
|
||||
Webhooks are available to individual users and teams.
|
||||
|
||||
@ -6,11 +6,12 @@
|
||||
"title": "How To Use"
|
||||
},
|
||||
"get-started": "Get Started",
|
||||
"profile": "User Profile",
|
||||
"signing-documents": "Signing Documents",
|
||||
"profile": "Public Profile",
|
||||
"organisations": "Organisations",
|
||||
"documents": "Documents",
|
||||
"templates": "Templates",
|
||||
"branding": "Branding",
|
||||
"direct-links": "Direct Signing Links",
|
||||
"teams": "Teams",
|
||||
"-- Legal Overview": {
|
||||
"type": "separator",
|
||||
"title": "Legal Overview"
|
||||
@ -18,4 +19,4 @@
|
||||
"fair-use": "Fair Use Policy",
|
||||
"licenses": "Licenses",
|
||||
"compliance": "Compliance"
|
||||
}
|
||||
}
|
||||
28
apps/documentation/pages/users/branding.mdx
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Branding Preferences
|
||||
description: Learn how to set the branding preferences for your team account.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Branding Preferences
|
||||
|
||||
Branding preferences allow you to set the default settings when emailing documents to your recipients.
|
||||
|
||||
## Preferences
|
||||
|
||||
Branding preferences can be set on either the organisation or team level.
|
||||
|
||||
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
|
||||
|
||||
To access the preferences, navigate to either the organisation or teams settings page and click the **Preferences** tab. This page contains both the preferences for documents and branding, the branding section is located at the bottom of the page.
|
||||
|
||||

|
||||
|
||||
On this page, you can:
|
||||
|
||||
- **Upload a Logo** - Upload your team's logo to be displayed instead of the default Documenso logo.
|
||||
- **Set the Brand Website** - Enter the URL of your team's website to be displayed in the email communications sent by the team.
|
||||
- **Add Additional Brand Details** - You can add additional information to display at the bottom of the emails sent by the team. This can include contact information, social media links, and other relevant details.
|
||||
5
apps/documentation/pages/users/documents/_meta.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"sending-documents": "Sending Documents",
|
||||
"document-preferences": "Document Preferences",
|
||||
"document-visibility": "Document Visibility"
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Preferences
|
||||
description: Learn how to manage your team's global preferences.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Document Preferences
|
||||
|
||||
Document preferences allow you to set the default settings when creating new documents and templates.
|
||||
|
||||
For example, you can set the default language for documents sent by the team, or set the allowed signatures types.
|
||||
|
||||
## Preferences
|
||||
|
||||
Document preferences can be set on either the organisation or team level.
|
||||
|
||||
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
|
||||
|
||||
To access the preferences, navigate to either the organisation or teams settings page and click the **Preferences** tab.
|
||||
|
||||

|
||||
|
||||
- **Document Visibility** - Set the default visibility of the documents created by team members. Learn more about [document visibility](/users/documents/document-visibility).
|
||||
- **Default Document Language** - This setting allows you to set the default language for the documents uploaded in the organisation. The default language is used as the default language in the email communications with the document recipients.
|
||||
- **Signature Settings** - Controls what signatures are allowed to be used when signing the documents.
|
||||
- **Sender Details** - Set whether the sender's name should be included in the emails sent by the team. See more below [sender details](/users/documents/document-preferences#sender-details).
|
||||
- **Include the Signing Certificate** - This setting controls whether the signing certificate should be included in the signed documents. If enabled, the signing certificate is included in the signed documents. If disabled, the signing certificate is not included in the signed documents. Regardless of this setting, the signing certificate is always available in the document's audit log page.
|
||||
|
||||
Document visibility, language and signature settings can be overriden on a per document basis.
|
||||
|
||||
### Sender Details
|
||||
|
||||
If the **Sender Details** setting is enabled, the emails sent by the team will include the sender's name. The email will say:
|
||||
|
||||
> "Example User" on behalf of "Example Team" has invited you to sign "document.pdf"
|
||||
|
||||
If the **Sender Details** setting is disabled, the emails sent by the team will not include the sender's name. The email will say:
|
||||
|
||||
> "Example Team" has invited you to sign "document.pdf"
|
||||
@ -5,19 +5,25 @@ description: Learn how to control the visibility of your team documents.
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
# Team's Document Visibility
|
||||
# Document Visibility
|
||||
|
||||
The default document visibility option allows you to control who can view and access the documents uploaded to your team account. The document visibility can be set to one of the following options:
|
||||
The default document visibility option allows you to control who can view and access the documents uploaded within a team.
|
||||
|
||||
This value can either be set in the [document preferences](/users/documents/document-preferences), or when you [create the document](/users/documents/send-document)
|
||||
|
||||
## Document Visibility Options
|
||||
|
||||
The document visibility can be set to one of the following options:
|
||||
|
||||
- **Everyone** - The document is visible to all team members.
|
||||
- **Managers and above** - The document is visible to team members with the role of _Manager or above_ and _Admin_.
|
||||
- **Admin only** - The document is only visible to the team's admins.
|
||||
|
||||

|
||||
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [document preferences page](/users/documents/document-preferences) and selecting a different visibility option.
|
||||
|
||||
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option.
|
||||

|
||||
|
||||
Here's how it works:
|
||||
## How it works
|
||||
|
||||
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_".
|
||||
- The user can't change the visibility of the document in the document editor.
|
||||
@ -85,12 +85,13 @@ You can also set the recipient's role, which determines their actions and permis
|
||||
|
||||
Documenso has 4 roles for recipients with different permissions and actions.
|
||||
|
||||
| Role | Function | Action required | Signature |
|
||||
| :------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
|
||||
| Signer | Needs to sign signatures fields assigned to them. | Yes | Yes |
|
||||
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
|
||||
| Viewer | Needs to confirm they viewed the document. | Yes | No |
|
||||
| BCC | Receives a copy of the signed document after completion. No action is required. | No | No |
|
||||
| Role | Function | Action required | Signature |
|
||||
| :-------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
|
||||
| Signer | Needs to sign signatures fields assigned to them. | Yes | Yes |
|
||||
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
|
||||
| Viewer | Needs to confirm they viewed the document. | Yes | No |
|
||||
| Assistant | Can help prepare the document by filling in fields on behalf of other signers. | Yes | No |
|
||||
| CC | Receives a copy of the signed document after completion. No action is required. | No | No |
|
||||
|
||||
### Fields
|
||||
|
||||
@ -114,7 +115,7 @@ All fields can be placed anywhere on the document and resized as needed.
|
||||
|
||||
<Callout type="info">
|
||||
Learn more about the available field types and how to use them on the [Fields
|
||||
page](signing-documents/fields).
|
||||
page](/users/documents/fields).
|
||||
</Callout>
|
||||
|
||||
#### Signature Required
|
||||
@ -10,7 +10,7 @@ import { Callout, Steps } from 'nextra/components';
|
||||
<Steps>
|
||||
### Pick a Plan
|
||||
|
||||
The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, and Teams.
|
||||
The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, Teams and Platform.
|
||||
|
||||
Explore each plan's features and choose the one that best suits your needs. The [pricing page](https://documen.so/pricing) has more information about the plans.
|
||||
|
||||
@ -28,6 +28,6 @@ You can claim a premium username by upgrading to a paid plan. After upgrading to
|
||||
|
||||
### Optional: Create a Team
|
||||
|
||||
If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/get-started/teams).
|
||||
If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/organisations/teams).
|
||||
|
||||
</Steps>
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
---
|
||||
title: Teams
|
||||
description: Learn how to create and manage teams in Documenso.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Teams
|
||||
|
||||
Documenso allows you to create teams to collaborate with others on creating and signing documents.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a New Team
|
||||
|
||||
Anyone can create a team from their account by clicking on the "+" (plus) button in the "Teams" section from the account dropdown.
|
||||
|
||||

|
||||
|
||||
Each team is a separate entity with its members, documents, and templates. You can create as many teams as you like but remember that each team is billed separately.
|
||||
|
||||
<Callout type="info">You can transfer the ownership of the team at any time.</Callout>
|
||||
|
||||
### Name and URL
|
||||
|
||||
Clicking the "+" button will open a modal where you must pick your team's name and URL. The URL is the team's identifier and will link to the team's page and settings. An example URL would be:
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/t/<your-team-name>
|
||||
```
|
||||
|
||||

|
||||
|
||||
You can select a different name and URL for your team, but we recommend using the same or similar name.
|
||||
|
||||
### Invite Team Members
|
||||
|
||||
After creating the team, you can invite team members by navigating to the "Members" tab in the team settings and clicking the "Invite member" button.
|
||||
|
||||
To access the team settings, click on the team's name in the account dropdown and select the appropriate team. Lastly, click again on the avatar and then "Team Settings".
|
||||
|
||||
Or you can copy this URL:
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/t/<your-team-name>/settings/members
|
||||
```
|
||||
|
||||
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
|
||||
|
||||

|
||||
|
||||
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
|
||||
|
||||
The table below shows how the CSV file should be structured:
|
||||
|
||||
| Email address | Role |
|
||||
| -------------------------- | ------- |
|
||||
| team-admin@documenso.com | Admin |
|
||||
| team-manager@documenso.com | Manager |
|
||||
| team-member@documenso.com | Member |
|
||||
|
||||
<Callout type="info">
|
||||
The basic team plan includes 5 members. You can invite as many members as you like by upgrading
|
||||
your team's seats on the team's billing page.
|
||||
</Callout>
|
||||
|
||||
#### Roles
|
||||
|
||||
You can assign different permissions to team members based on their roles. The roles available are:
|
||||
|
||||
| Role | Create, Edit, Send Documents | Manage Users | Manage Admins | Settings | Billing | Delete/ Transfer |
|
||||
| :-----: | :--------------------------: | :----------: | :-----------: | :------: | :-----: | :--------------: |
|
||||
| Member | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| Manager | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
|
||||
| Admin | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| Owner | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
### Set a Team Email
|
||||
|
||||
You can add a team email to make signing and sending documents easier. Adding a team email allows you to:
|
||||
|
||||
- See a signing request sent to this email (Team Inbox)
|
||||
- See all documents sent on behalf of the team
|
||||
|
||||
### (Optional) Transfer Team Ownership
|
||||
|
||||
You can transfer the team's ownership at any time. To do this, navigate to the "General" tab in the team settings and click the "Transfer team" button.
|
||||
|
||||
Use this URL to get to the team settings:
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/t/<your-team-name>/settings
|
||||
```
|
||||
|
||||
### [Send your First Document](https://app.documenso.com/)
|
||||
|
||||
</Steps>
|
||||
7
apps/documentation/pages/users/organisations/_meta.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"index": "Introduction",
|
||||
"members": "Members",
|
||||
"groups": "Groups",
|
||||
"teams": "Teams",
|
||||
"billing": "Billing"
|
||||
}
|
||||
19
apps/documentation/pages/users/organisations/billing.mdx
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: Billing
|
||||
description: Learn how to manage your organisation's billing and subscription.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
### Billing and Subscription Management
|
||||
|
||||
Organisations handle billing centrally, making it easier to manage:
|
||||
|
||||
- **Unified Billing**: One subscription covers all teams in the organisation
|
||||
- **Seat Management**: Add or remove seats across all teams automatically (Teams plan)
|
||||
|
||||
You can change plans, view invoices and manage your subscription from the billing page which is accessible from the organisation settings.
|
||||
|
||||

|
||||
75
apps/documentation/pages/users/organisations/groups.mdx
Normal file
@ -0,0 +1,75 @@
|
||||
---
|
||||
title: Preferences
|
||||
description: Learn how to manage your team's global preferences.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Organisation Groups
|
||||
|
||||
Organisation groups are a powerful administrative tool that streamlines user management across your entire organisation. Instead of manually assigning individual users to multiple teams, groups allow you to manage access at scale.
|
||||
|
||||
This automated approach ensures consistent permissions while reducing administrative overhead for tasks like onboarding employees or managing contractor access.
|
||||
|
||||
## Understanding groups
|
||||
|
||||
### Key Benefits
|
||||
|
||||
- **Instant Access Management**: New hires get immediate, appropriate access across all relevant teams
|
||||
- **Bulk Operations**: Remove an entire group (like a departing contractor team) and all members lose access simultaneously
|
||||
- **Role Consistency**: Ensure the same role is applied consistently across teams—no more accidentally giving admin access when member access was intended
|
||||
- **Audit Trail**: Easily track which groups have access to which teams
|
||||
|
||||
### Example use case: Legal Compliance Team
|
||||
|
||||
Imagine you have a legal compliance team that needs access to review documents across all departments. Instead of manually adding each legal team member to every departmental team (Sales, Marketing, HR, Operations), you can:
|
||||
|
||||
1. Create a "Legal Compliance" group with the "Member" Organisation Role
|
||||
2. Add legal team members to this group
|
||||
3. Assign the "Legal Compliance" group to the required teams
|
||||
|
||||
Now, when Sarah from Legal joins the company, you can simply add her to the "Legal Compliance" group. Once added, she automatically gains access to all teams the "Legal Compliance" group is assigned to.
|
||||
|
||||
When John from Legal leaves the company, you remove him from the group and his access is instantly revoked across all teams.
|
||||
|
||||
## Getting started with groups
|
||||
|
||||
Navigate to the "Groups" section in your organisation settings to create and manage groups.
|
||||
|
||||
There are two types of roles when using groups:
|
||||
|
||||
- **Organisation Role**: A global organisation role given to all members of the group
|
||||
- **Team Role**: A team role you select when assigning the group to a team
|
||||
|
||||
You should generally have the "Organisation Role" set to "Organisation Member", otherwise these members would by default have access to all teams anyway due to the high organisation role.
|
||||
|
||||
### Creating Custom Groups
|
||||
|
||||
When creating a custom group, you can:
|
||||
|
||||
1. **Name the Group**: Give it a descriptive name that reflects its purpose
|
||||
2. **Set Organisation Role**: Define the default **organisation role** for group members
|
||||
3. **Add Members**: Include organisation members in the group
|
||||
|
||||

|
||||
|
||||
### Manage Custom Groups
|
||||
|
||||
By clicking the "Manage" button on a custom group, you can view all teams it is assigned to and modify the group's settings.
|
||||
|
||||

|
||||
|
||||
### Assigning a group to a team
|
||||
|
||||
To assign a group to a team, you need to navigate to the team settings and click the "Groups" tab.
|
||||
|
||||

|
||||
|
||||
From here, click the "Add groups" button to begin the process of assigning a group to a team. Once you have added the group you can see that the members have been automatically added to the team in the members tab.
|
||||
|
||||
## What's next?
|
||||
|
||||
- [Create Your First Team](/users/organisations/teams)
|
||||
- [Manage Default Settings](/users/documents/document-preferences)
|
||||
65
apps/documentation/pages/users/organisations/index.mdx
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Organisations
|
||||
description: Learn how to create and manage organisations in Documenso.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Organisations
|
||||
|
||||
Organisations allow you to manage multiple teams and users under a single managed entity. This powerful feature enables enterprise-level collaboration and streamlined management across your entire organisation.
|
||||
|
||||
## What are Organisations?
|
||||
|
||||
Organisations are the top-level entity in Documenso's hierarchy structure:
|
||||
|
||||

|
||||
|
||||
Each organisation can contain multiple teams, and each team can have multiple members. This structure provides:
|
||||
|
||||
- **Centralized Management**: Control multiple teams from a single organisational dashboard
|
||||
- **Unified Billing**: Manage billing and subscriptions at the organisation level
|
||||
- **Access Control**: Define roles and groups across the entire organisation
|
||||
- **Group Management**: Create custom groups to organise members and control team access
|
||||
- **Global Settings**: Apply consistent settings across all teams in your organisation
|
||||
|
||||
## Create a new organisation
|
||||
|
||||
You can create multiple organisations, but each organisation will be billed separately.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Creating Organisations
|
||||
|
||||
To create a new organisation, navigate to the organisation section in your account settings and click the "Create Organisation" button.
|
||||
|
||||

|
||||
|
||||
### Select your plan
|
||||
|
||||
Choose from our range of plans for your new organisation. If you want to instead upgrade your current organisation, you can do so by going into your settings billing page and upgrade it there.
|
||||
|
||||
### Name setup
|
||||
|
||||
When creating an organisation, you'll need to provide:
|
||||
|
||||
- **Organisation Name**: The display name for your organisation
|
||||
|
||||
</Steps>
|
||||
|
||||
Once your organisation is established, you can create teams to organise your work and collaborate effectively. Each team operates independently but inherits organisation-level settings and branding.
|
||||
|
||||
## Best Practices for Organisation Management
|
||||
|
||||
1. **Use groups effectively**: Leverage groups to simplify permission management
|
||||
2. **Set default settings**: Configure organisation-wide settings for consistency
|
||||
|
||||
## What's next?
|
||||
|
||||
- [Create Your First Team](/users/organisations/teams)
|
||||
- [Invite Organisation Members](/users/organisations/members)
|
||||
- [Create Organisation Groups](/users/organisations/groups)
|
||||
- [Manage Default Settings](/users/documents/document-preferences)
|
||||
- [Manage Default Branding](/users/branding)
|
||||
65
apps/documentation/pages/users/organisations/members.mdx
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Members
|
||||
description: Learn how to invite and manage your organisation's members.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Organisation Members
|
||||
|
||||
Organisation members are the core users of your organisation. They are the ones who can access the team resources and collaborate with other members.
|
||||
|
||||
## Organisation Roles
|
||||
|
||||
You can assign different permissions to organisation members by using roles. The roles available are:
|
||||
|
||||
| Role | Manage Settings/Teams/Members | Billing | Delete Organisation |
|
||||
| :------------------: | :---------------------------: | :-----: | ------------------- |
|
||||
| Organisation Owner | ✅ | ✅ | ✅ |
|
||||
| Organisation Admin | ✅ | ✅ | ✅ |
|
||||
| Organisation Manager | ✅ | ❌ | ❌ |
|
||||
| Organisation Member | ❌ | ❌ | ❌ |
|
||||
|
||||
<Callout type="info">
|
||||
Organisation admins and managers will automatically have access to all teams as the "Team Admin"
|
||||
role. When creating a team you can also decide whether to automatically allow normal members to
|
||||
access it by default as well.
|
||||
</Callout>
|
||||
|
||||
## Invite Organisation Members
|
||||
|
||||
To invite organisation members, you need to be an organisation owner, admin or manager.
|
||||
|
||||
1. Open the menu switcher top right
|
||||
2. Hover over your new organisation and click the settings icon
|
||||
3. Navigate to the "Members" tab
|
||||
4. Click "Invite Member"
|
||||
|
||||
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
|
||||
|
||||

|
||||
|
||||
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
|
||||
|
||||
The table below shows how the CSV file should be structured:
|
||||
|
||||
| Email address | Role |
|
||||
| ------------------------- | ------- |
|
||||
| org-admin@documenso.com | Admin |
|
||||
| org-manager@documenso.com | Manager |
|
||||
| org-member@documenso.com | Member |
|
||||
|
||||
<Callout type="info">
|
||||
The basic team plan includes 5 organisation members. Going over the 5 members will charge your
|
||||
organisation according to the seat plan pricing.
|
||||
</Callout>
|
||||
|
||||
## Manage Organisation Members
|
||||
|
||||
On the same page, you can change the organisation member's roles or remove them from the organisation.
|
||||
|
||||
## What's next?
|
||||
|
||||
- [Use groups to organise your members](/users/organisations/groups)
|
||||
121
apps/documentation/pages/users/organisations/teams.mdx
Normal file
@ -0,0 +1,121 @@
|
||||
---
|
||||
title: Teams
|
||||
description: Learn how to create and manage teams in Documenso.
|
||||
---
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Teams
|
||||
|
||||
Documenso teams allow you to collaborate with others on creating, sending and receiving documents within your organisation. Teams operate within the organisational structure and inherit settings and branding from their parent organisation.
|
||||
|
||||
## Team Structure
|
||||
|
||||
Teams provide focused collaboration spaces while benefiting from organisation-level management and settings.
|
||||
|
||||
Each team within an organisation has its own:
|
||||
|
||||
- Team members and roles
|
||||
- Documents and templates
|
||||
- Team-specific settings (that can override organisation defaults)
|
||||
- Team email and branding (if enabled)
|
||||
|
||||
## Creating a Team
|
||||
|
||||
Only members with the "Organisation Admin" or "Organisation Manager" role can create teams.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create Team
|
||||
|
||||
To create a team, navigate to the organisation settings page and click the "Teams" tab. Then you can click the "Create Team" button.
|
||||
|
||||

|
||||
|
||||
### Name and URL
|
||||
|
||||
When creating a team, you'll need to provide:
|
||||
|
||||
- **Team Name**: The display name for your team
|
||||
- **Team URL**: A unique identifier for your team
|
||||
|
||||
The team URL will follow this format:
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/t/<team-url>
|
||||
```
|
||||
|
||||
You can select different names and URLs for your team, but we recommend using the same or similar names for consistency.
|
||||
|
||||

|
||||
|
||||
You can also decide whether to automatically inherit members from the organisation into the team. This means that all members of the organisation will have access to this team.
|
||||
|
||||
Members with the "Organisation Admin" or "Organisation Manager" role will be assigned as "Team Admin" regardless of this setting. This will only affect members with the "Organisation Member" role, who will be added to the team as a "Team Member".
|
||||
|
||||
Disabling this setting will remove all these members automatically. This can always be turned on or off later in the teams member settings page.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Team Members
|
||||
|
||||
After creating the team, you can add organisation members into your team using two methods:
|
||||
|
||||
- Directly adding members to the team
|
||||
- Add members using groups
|
||||
|
||||
### Directly adding members
|
||||
|
||||
1. Navigate to the team settings member page
|
||||
2. Click the "Add Members" button
|
||||
3. Choose which members you want to add
|
||||
4. Assign the team roles for each team member
|
||||
|
||||
If you want to add people outside of the organisation, you will need to invite them to the organisation first.
|
||||
|
||||
See the [organisation members](/users/organisations/members#invite-organisation-members) page for more information.
|
||||
|
||||
### Adding members using groups
|
||||
|
||||
1. Navigate to the teams settings groups page
|
||||
2. Click the "Add groups" button
|
||||
3. Choose which groups you want to add
|
||||
4. Assign the team roles for each group
|
||||
|
||||
See the [organisation groups](/users/organisations/groups) page for more information.
|
||||
|
||||
### Team Member Roles
|
||||
|
||||
You can assign different permissions to team members based on their roles. The roles available are:
|
||||
|
||||
| Role | Manage Documents | Manage Team | Delete Team |
|
||||
| :----------: | :--------------: | :---------: | :---------: |
|
||||
| Team Admin | ✅ | ✅ | ✅ |
|
||||
| Team Manager | ✅ | ✅ | ❌ |
|
||||
| Team Member | ✅ | ❌ | ❌ |
|
||||
|
||||
These roles can be used for document visibility and management as well.
|
||||
|
||||
## Set a Team Email
|
||||
|
||||
You can add a team email which allows you to:
|
||||
|
||||
- See signing requests sent to this email (Team Inbox)
|
||||
- See documents sent from this email
|
||||
- Send documents on behalf of the team
|
||||
- Maintain consistent team branding in communications
|
||||
|
||||
## Team Settings and Branding
|
||||
|
||||
You can override preferences and settings from the Organisation on the Team level. See the following pages for more information:
|
||||
|
||||
- [Document preferences](/users/documents/document-preferences)
|
||||
- [Branding preferences](/users/branding/branding-preferences)
|
||||
|
||||
## What's next?
|
||||
|
||||
- [Send your first document](/users/documents/sending-documents)
|
||||
- [Setup your default document preferences](/users/documents/document-preferences)
|
||||
- [Setup your default branding preferences](/users/branding)
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: User Profile
|
||||
title: Public Profile
|
||||
description: Learn how to set up your public profile on Documenso.
|
||||
---
|
||||
|
||||
@ -15,7 +15,7 @@ Documenso allows you to create a public profile to share your templates for anyo
|
||||
|
||||
### Navigate to Your Profile Settings
|
||||
|
||||
Click on your profile picture in the top right corner and select "User settings". Then, navigate to the "Public Profile" tab to configure your profile.
|
||||
Click on your profile picture in the top right corner and select "Settings" or "Team Settings". Then, navigate to the "Public Profile" tab to configure your profile.
|
||||
|
||||

|
||||
|
||||
@ -45,6 +45,8 @@ You can choose to make your profile public or private. Only you can access it if
|
||||
|
||||
To make your profile public, toggle the switch to the right ("Show") at the top right-hand side of the page.
|
||||
|
||||

|
||||
|
||||
### (Optional) Link Templates
|
||||
|
||||
Linking templates to your profile is optional, but it's what makes your profile helpful. Linking templates allow people to sign documents directly from your profile. As a result, we recommend linking at least one template you want to share with others.
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"index": "Send Documents",
|
||||
"fields": "Document Fields"
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"preferences": "Preferences",
|
||||
"document-visibility": "Document Visibility",
|
||||
"sender-details": "Email Sender Details",
|
||||
"branding-preferences": "Branding Preferences"
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
title: Branding Preferences
|
||||
description: Learn how to set the branding preferences for your team account.
|
||||
---
|
||||
|
||||
# Branding Preferences
|
||||
|
||||
You can set the branding preferences for your team account by going to the **Branding Preferences** tab in the team's settings dashboard.
|
||||
|
||||

|
||||
|
||||
On this page, you can:
|
||||
|
||||
- **Upload a Logo** - Upload your team's logo to be displayed instead of the default Documenso logo.
|
||||
- **Set the Brand Website** - Enter the URL of your team's website to be displayed in the email communications sent by the team.
|
||||
- **Add Additional Brand Details** - You can add additional information to display at the bottom of the emails sent by the team. This can include contact information, social media links, and other relevant details.
|
||||
@ -1,19 +0,0 @@
|
||||
---
|
||||
title: Preferences
|
||||
description: Learn how to manage your team's global preferences.
|
||||
---
|
||||
|
||||
# Preferences
|
||||
|
||||
You can manage your team's global preferences by clicking on the **Preferences** tab in the team's settings dashboard.
|
||||
|
||||

|
||||
|
||||
The preferences page allows you to update the following settings:
|
||||
|
||||
- **Document Visibility** - Set the default visibility of the documents created by team members. Learn more about [document visibility](/users/teams/document-visibility).
|
||||
- **Default Document Language** - This setting allows you to set the default language for the documents uploaded in the team account. The default language is used as the default language in the email communications with the document recipients. You can change the language for individual documents when uploading them.
|
||||
- **Sender Details** - Set whether the sender's name should be included in the emails sent by the team. Learn more about [sender details](/users/teams/sender-details).
|
||||
- **Typed Signature** - It controls whether the document recipients can sign the documents with a typed signature or not. If enabled, the recipients can sign the document using either a drawn or a typed signature. If disabled, the recipients can only sign the documents usign a drawn signature. This setting can also be changed for individual documents when uploading them.
|
||||
- **Include the Signing Certificate** - This setting controls whether the signing certificate should be included in the signed documents. If enabled, the signing certificate is included in the signed documents. If disabled, the signing certificate is not included in the signed documents. Regardless of this setting, the signing certificate is always available in the document's audit log page.
|
||||
- **Branding Preferences** - Set the branding preferences and defaults for the team account. Learn more about [branding preferences](/users/teams/branding-preferences).
|
||||
@ -1,14 +0,0 @@
|
||||
---
|
||||
title: Email Sender Details
|
||||
description: Learn how to update the sender details for your team's email notifications.
|
||||
---
|
||||
|
||||
## Sender Details
|
||||
|
||||
If the **Sender Details** setting is enabled, the emails sent by the team will include the sender's name. The email will say:
|
||||
|
||||
> "Example User" on behalf of "Example Team" has invited you to sign "document.pdf"
|
||||
|
||||
If the **Sender Details** setting is disabled, the emails sent by the team will not include the sender's name. The email will say:
|
||||
|
||||
> "Example Team" has invited you to sign "document.pdf"
|
||||
@ -1,5 +1,3 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import NextPlausibleProvider from 'next-plausible';
|
||||
|
||||
BIN
apps/documentation/public/developer-mode/field-coordinates.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 97 KiB |
BIN
apps/documentation/public/teams/team-create-dialog.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
apps/documentation/public/teams/team-create.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 165 KiB |
@ -19,6 +19,22 @@ const themeConfig: DocsThemeConfig = {
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
!function(){
|
||||
if (location.hostname === 'localhost') return;
|
||||
var e="6c236490c9a68c1",
|
||||
t=function(){Reo.init({ clientID: e })},
|
||||
n=document.createElement("script");
|
||||
n.src="https://static.reo.dev/"+e+"/reo.js";
|
||||
n.defer=true;
|
||||
n.onload=t;
|
||||
document.head.appendChild(n);
|
||||
}();
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
},
|
||||
|
||||
@ -1 +0,0 @@
|
||||
# @documenso/marketing
|
||||
1
apps/marketing/ambient.d.ts
vendored
@ -1 +0,0 @@
|
||||
declare module '@documenso/tailwind-config';
|
||||
@ -1,63 +0,0 @@
|
||||
---
|
||||
title: Launching Direct Links
|
||||
description: Today, we are launching direct links to templates, a new and async way to get documents signed.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-06-17
|
||||
tags:
|
||||
- Announcement
|
||||
- Direct Links
|
||||
- Profiles
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/direct-links.png"
|
||||
width="1400"
|
||||
height="884"
|
||||
alt="Direct Links in Templats List View"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">Direct Template Links - Async signing, anytime.</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; We are launching direct links to templates. With direct links, a document is created from a template every time anyone signs the link. Links can be public.
|
||||
|
||||
## Sync or Async?
|
||||
|
||||
> Quick refresher on Sync vs. Async: Sync means everyone has to wait for me until they can continue their work. Async means everyone can and does their work at the time that fits best.
|
||||
|
||||
Digital signing has become almost as normalized as email when doing business. While not 100% of companies are onboarded on digital signatures yet, hardly anyone is surprised when receiving a link to sign something digitally. As we got used to the user experience of sending emails, we also got used to the experience of sending document signature requests, with all the downsides:
|
||||
|
||||
- I have to become active each time before anything can happen: I need to send a signature request
|
||||
- My counterpart has to wait for me to send: "Did you send the signing link yet?"
|
||||
- I need to monitor the requests I started for completion: "I sent you a link yesterday; please check it out."
|
||||
|
||||
## Introducing Direct Links
|
||||
|
||||
Today, we are introducing a new paradigm to signing: Async Direct Signing Links. Direct links are attached to a template and can be used anytime by anyone using the link. You set up the signature experience and flow once using all existing template mechanisms and you are done. You can provide anyone with the link so they can sign whenever they need to. You can even post the link publicly if you want to maximize its reach, i.e. for sales contracts.
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/129f690b-29b4-4a11-b9a0-14fc6648e611"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
## Embrace Async
|
||||
|
||||
So, how does this help anyone? You may still need to send a signature request to people, but in the cases you don't, you are not forced to anymore. Need an NDA? Check out our standing NDA link. A customer needs an updated Form W-9? Just use the company W-9 Link; it always has the most up-to-date form. You can even go as far as publicly posting a link to a software development or design contract any potential customer can sign anytime. Can they talk to you first? Sure, but if they don't need to or already have to, they go straight to the link. The process of actively sending has gotten us used to using a sync paradigm (I send, you receive and sign, and I get the result), whereas an async one (you sign whenever it suits you, and I become active only then, if at all) is way better suited. Adding more approval and signature steps makes sure you still control the outcome, but the process becomes a lot more efficient. For example, you can grab your own copy of the early adopter's pledge here if you missed it: [documen.so/pledge](https://documen.so/pledge).
|
||||
|
||||
> Take a minute to think about every signing request you send and whether they really require you to be part of the transaction. Could they be outsourced to the recipient and only reviewed once their part is done?
|
||||
|
||||
## Coming Soon: Profiles
|
||||
|
||||
The best place to put your public links will be your **Documenso profile**, which is also close to launching. We want to get a feel for how links are used and move on to profiles shortly after. Want to try out direct links? Grab a free account here to get started: [documen.so/free](https://documen.so/free).
|
||||
|
||||
As always, we want to hear from you on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,51 +0,0 @@
|
||||
---
|
||||
title: Announcing Documenso
|
||||
description: Launching an open-source document signing tool because trusted-based products should be built on openness. The first release will be in 2023. Sign up at documenso.com to be on board.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2022-12-29
|
||||
tags:
|
||||
- Announcement
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/blog-banner-announcing-documenso.webp"
|
||||
width="1400"
|
||||
height="884"
|
||||
alt="Documenso announcement blog banner"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">Documenso — The Open Source DocuSign Alternative.</figcaption>
|
||||
</figure>
|
||||
|
||||
## TL; DR;
|
||||
|
||||
I'm launching an open source document signing tool because trust-based products should be built on openness. The first release will be in 2023. Sign up at <a href="https://documenso.com" target="_blank">documenso.com</a> and get on board.
|
||||
|
||||
## Let’s build the world’s most trusted document-signing tool.
|
||||
|
||||
Today I'm excited to announce my new project Documenso. Documenso is an open source document signing tool you can host yourself and freely build upon because it's, you know, open source. Before I get more into the details of what and when will be launched I want to take a moment and talk about why.
|
||||
|
||||
## Digital signing is great
|
||||
|
||||
Signing Documents digitally has countless benefits: Less struggle with printing, less wasting paper, faster request delivery, easier changes, easier coordination of people far away, verifiable document integrity, and verifiable signer identity (this is a vast topic, will write more on soon), easier storage and search of signed documents, the list goes on. Digital Signatures take something very old and very trusted like personally signing documents into the digital space, adding the benefits listed above. It also introduces a new party to every signing transaction, the signing tool providers. What was peer to peer transaction before, now goes through an intermediary. While this isn't a problem in itself, it should make us think about how we want these providers of trust to work.
|
||||
|
||||
## How do we build trusted systems?
|
||||
|
||||
While doing research for Documenso I came upon a quote that expresses the current state of document signing pretty well:
|
||||
|
||||
> Document signing is NOT a technical problem. [Editor’s Note: Because it was solved technically a long time ago] It’s a legal acceptance problem — and everyone KNOWS DocuSign and friends and understands how they’re admissible. Anything else would have to compete with that and people would be suspicious of it for a long time.
|
||||
|
||||
While this may sound like a hurdle at first, it immediately gave me a sense of validation for a more open approach to signing. People will and should be suspicious of their tools and demand a high bar when it comes to trust. And the way to earn this trust is by being open. Trusted tools should be the result of thoughtful discussion and reviews. They should be the result of the needs and will of its community. They should be transparent, adaptable, and empowering while using. Open Source embodies these values very well for software, which makes it a perfect fit for this space and creating a high-trust tool.
|
||||
|
||||
## Next Steps
|
||||
|
||||
So, what can you expect from here on out? I've started to build Documenso 0.1 which is scheduled to release in “early” 2023. If you're interested in helping make this happen, let me know via [hi@documenso.com](mailto:hi@documenso.com). Getting working code into the hands of the perspective Documenso community is currently the #1 goal. Other than that I'll be releasing several articles about document signing and what something like Documenso should look like, in my humble opinion. So stay tuned!
|
||||
|
||||
If you think Documenso is worthy of support, please share <a href="https://documenso.com" target="_blank">documenso.com</a> with anyone interested, and sign up to be among the first to try out version 0.1 as soon as it launches.
|
||||
|
||||
Cheers from Hamburg
|
||||
|
||||
Timur
|
||||
@ -1,68 +0,0 @@
|
||||
---
|
||||
title: Documenso Profiles Are Here
|
||||
description: Today, we are launching Documenso Profiles, a new way to let your peers sign your documents.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-07-01
|
||||
tags:
|
||||
- Announcement
|
||||
- Direct Links
|
||||
- Profiles
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/profile1.png"
|
||||
width="1260"
|
||||
height="1260"
|
||||
alt="Documenso Profile of Timur"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">Let people sign anytime with Documenso Profiles. Try it [with my profile](https://app.documenso.com/p/timur).</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; We are launching a Documenso Profile where you can display your templates for everyone to sign at any time.
|
||||
|
||||
## Introducing Documenso Profiles
|
||||
|
||||
Today, I’m excited to announce that we are launching Documenso Profiles 🎉 While we have been focussing on the conventional signing experience so far, Direct Links and now profiles are our first steps to bring some long-awaited innovation back to digital signatures.
|
||||
|
||||
Documenso Profiles allows you to share any template with a public link in a very easy-to-understand way. Adding templates to your profiles allows everyone to sign your documents just when they need to. Forms, NDAs, Disclaimers, and even contracts are now available anytime they are needed. Profiles turn the classic signing flow on its head by letting the recipient sign first before the document’s owner becomes active. Booking links (e.g., Cal.com) and customer self-service portals (e.g., Stripe Billing Portal) are becoming the norm, so it’s time we did the same for signing.
|
||||
|
||||
## The Best Way to Share Your Singing Links
|
||||
|
||||
With profiles, we want to offer you the best way to share your standing Documenso Template Links in a public place. You can add your Documenso Profile to your social profiles, Email footer, Video Description, or wherever your audience, customers, and partners interact with you. The profile will be a public, trusted place to ensure you know who you are dealing with.
|
||||
|
||||
Looking at the classical social media fake profile problem, we know this is tricky to achieve. We will pay close attention to how profiles are used and how we can help the community use them easily and securely. As a first step towards this direction, we are introducing a trust badge next to your name. There will be 3 levels to start:
|
||||
|
||||
- Free Users: No Badge
|
||||
- Paid Users: Green Badge
|
||||
- Early Adopters: Gold Badge
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/profile2.png"
|
||||
width="1260"
|
||||
height="1260"
|
||||
alt="Documenso Profile Edit Screen"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">Add and remove templates anytime.</figcaption>
|
||||
</figure>
|
||||
|
||||
## An Open Economy built on Documenso
|
||||
|
||||
We see offering profiles as a first step towards creating a full economy on top of the open signing ecosystem we envision. While we want to keep building the product with the community, we also want an economy to grow on the open tech we create. This includes using the tech (profiles) or offering service on top of the tech (hosting and customization). Our ecosystem is still young, and the goal is not to have Documenso Inc. as the only commercial actor but to fill our own niche in a global and thriving open ecosystem. One of our guiding principles is solving things once and for all. While our focus will be on the core signing product, we want to enable others to offer templates for use on profiles or privately. A lot of contracts, forms, and other paperwork have been recreated countless times. Offering high-quality, peer-reviewed templates is a natural extension of the current platform. There will be free templates, offered as marketing for their creators, and paid templates, offered as actual products.
|
||||
|
||||
## What's next
|
||||
|
||||
While an open signing economy is really exciting, we know it will take time to mature. Building out a mature ecosystem for builders and entrepreneurs takes time. While this aspect of Documenso matures, we will be focussing on the core of the platform: Letting you integrate and embed Documenso wherever you want it.
|
||||
|
||||
If you already have a Documenso account, you can [activate your profile here](https://app.documenso.com/settings/public-profile).
|
||||
Don’t have an account and want to check out profiles? You can do so using our [free plan](https://documen.so/free).
|
||||
|
||||
As always, we want to hear from you on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,63 +0,0 @@
|
||||
---
|
||||
title: 21 CFR Part 11 is here, and so is Vial.com
|
||||
description: We launched Vial.com with a 21 CFR Part 11 compliant setup. Reach out if 21 CFR Part 11 compliance is among your needs.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-07-18
|
||||
tags:
|
||||
- Vial.com
|
||||
- 21 CFR Part 11
|
||||
- Compliance
|
||||
---
|
||||
|
||||
<video id="vid" width="100%" src="/blog/vial.webm" autoPlay loop muted></video>
|
||||
<figcaption className="text-center">
|
||||
Vial.com uses Documenso for 21 CFR Part 11 compliant signing.
|
||||
</figcaption>
|
||||
|
||||
> TLDR; We launched Vial.com on Documenso and are open for 21 CFR Part 11 business.
|
||||
|
||||
# What is 21 CFR
|
||||
|
||||
You have never heard of 21 CFR Part 11? You are in good company since most people haven't. If you have, you probably work in an industry regulated by the U.S. Food and Drug Administration (FDA). Title 21 of the Code of Federal Regulations (CFR) is dedicated to detailing FDA-regulated business, and sub-part 11 sets out guidelines for using electronic signatures in this highly regulated field. Hence, 21 CFR Part 11 is highly relevant for regulated industries that aim to employ digital signatures. The guidelines set out in 21 CFR Part 11 aim to provide trustworthy, reliable, and equivalent to paper records and handwritten signatures. All Industries that fall under the FDA's regulation, e.g. pharmaceuticals, biotechnology, medical devices, and biologics, must comply with these rules when choosing or creating systems for electronic signatures.
|
||||
|
||||
Compliance with 21 CFR Part 11 is crucial for companies to use electronic records and signatures in their operations legally. It affects how companies manage documentation, conduct audits, and maintain regulatory submissions. Non-compliance can result in legal penalties, rejected submissions, and delays in product approvals, emphasizing the importance of adhering to these guidelines in FDA-regulated activities.
|
||||
|
||||
# Vial.com
|
||||
|
||||
Vial is a technology company on a mission to advance programs to market through computationally designed therapeutics and cost-effective clinical trials. It is imperative that Vial manages this process securely, effectively, and highly compliant. By leveraging it's modern platform, Vial aims to accelerate drug development and, ultimately, time to market for new therapies. You can learn more about them [here](https://vial.com/about-us).
|
||||
|
||||
[Together](https://documen.so/vial-documenso), Documenso and Vial set out to create the first open-source, 21 CFR Part 11 compliant signing solution. After iterating over the product together, Vial moved their operation from DocuSign, a known legacy signing provider, to a Documenso Enterprise plan. We are very happy to be able to support Vial’s mission by fulfilling our own: bringing open signing and all its innovation to where it's needed.
|
||||
|
||||
# 21 CFR Part 11 on Documenso Highlights
|
||||
|
||||
21 CFR Part 11 is a highly complex statute, and going into the all design rationales and the following implementation details, deserves its own article later. For now, I want to share a few notable highlights.
|
||||
|
||||
## The Full Experience
|
||||
|
||||
We implemented 21 CFR Part 11, keeping the main user experience of Documenso intact. Our 21 CFR module is not separate but natively integrated into all Documenso flows, thus not sacrificing usability for compliance. This also means most (if not all) advanced features we offer are usable in a compliant way. This prevents customers from being trapped in an anti-innovation bubble, not allowing access to new features for fear of non-compliance.
|
||||
|
||||
## Action Reauth Using Passkeys
|
||||
|
||||
<video id="vid" width="100%" src="/blog/vial2.webm" autoPlay loop muted controls></video>
|
||||
<figcaption className="text-center">
|
||||
Using passkeys (used here via fingerprint scanner) is the smoothest way to re-authenticate.
|
||||
</figcaption>
|
||||
|
||||
One of the requirements affecting day-to-day life the most is the requirement to actually reauthenticate every signature placed on a document. While we can't change that, we can help make the reauthentication as painless as possible. To this end, we opted for passkeys. While Documenso supports passkeys to log in, they are also supported to authenticate signing on a per-signature level as part of the Documenso Enterprise Plan. The user still has to authenticate every signature but can now do so from the comfort of their passkey provider, be that 1Password, their browser, or any other provider.
|
||||
|
||||
## Direct Links
|
||||
|
||||
We recently launched [Direct Template Links](https://documen.so/direct-links), a new way to let people sign and fill out forms. Links can be completed anytime, creating a new document in the process. Direct Links are also 21 CFR part 11 compliant, using action reauthentication, audit log, and all other compliance requirements.
|
||||
|
||||
# Documenso Enterprise Plan
|
||||
|
||||
With the successful launch of Vial, we are now open for business. 21 CFR Part 11 compliance is part of the Documenso Enterprise plan, which includes all regulations we currently support and upcoming additions. While the pricing depends heavily on your needs and scale, we offer fixed-price plans for better predictability for both sides. In our experience, volume-based pricing is a legacy headache we want to avoid.
|
||||
|
||||
If you are FDA-regulated and looking for a modern signing solution, we are happy to discuss your requirements in detail. You can write us (hi@documenso.com) or contact [our enterprise team](https://documen.so/21cfr) at any time or stage.
|
||||
|
||||
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,98 +0,0 @@
|
||||
---
|
||||
title: 'Building Documenso — Part 1: Certificates'
|
||||
description: Let's take a look why you need a signing certificate and how Documenso does it.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2023-06-23
|
||||
tags:
|
||||
- Open Source
|
||||
- Document Signature
|
||||
- Certificates
|
||||
- Signing
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/blog-banner-building-documenso.webp"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="Building Documenso blog banner"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
What actually is a signature?
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> Disclaimer: I’m not a lawyer and this isn’t legal advice. We plan to publish a much more specific framework on the topic of signature validity.
|
||||
|
||||
This is the first installment of the new Building Documenso series, where I describe the challenges and design choices that we make while building the world’s most open signing platform.
|
||||
|
||||
As you may have heard, we launched the community-reviewed <a href="https://github.com/documenso/documenso" target="_blank">version 0.9 of Documenso on GitHub</a> recently and it’s now available through the early adopter’s plan. One of the most fundamental choices we had to make on this first release, was the choice of certificate. While it’s interesting to know what we opted for, this shall also serve as a guide for everyone facing the same choice for self-hosting Documenso.
|
||||
|
||||
> Question: Why do I need a document signing certificate to self-host?
|
||||
>
|
||||
> Short Answer: Inserting the images of a signature into the document is only part of the signing process.
|
||||
|
||||
To have an actual digitally signed document you need a document signing certificate that is used to create the digital signature that is inserted into the document, alongside the visible one¹.
|
||||
|
||||
When hosting a signature service yourself, as we do, there are four main choices for handling the certificate: Not using a certificate, creating your own, buying a trusted certificate, and becoming and trusted service provider to issue your own trusted certificate.
|
||||
|
||||
## 1\. No Certificate
|
||||
|
||||
A lot of signing services actually don’t employ actual digital signatures besides the inserted image. The only insert and image of the signatures into the document you sign. This can be done and is legally acceptable in many cases. This option isn’t directly supported by Documenso without changing the code.
|
||||
|
||||
## 2\. Create your own
|
||||
|
||||
Since the cryptography behind certificates is freely available as open source you could generate your own using OpenSSL for example. Since it’s hardly more work than option 1 (using Documenso at least), this would be my minimum effort recommendation. Having a self-created (“self-signed”) certificate doesn’t add much in terms of regulation but it guarantees the document’s integrity, meaning no changes have been made after signing². What this doesn’t give you, is the famous green checkmark in Adobe Acrobat. Why? Because you aren’t on the list of providers Adobe “trusts”.³
|
||||
|
||||
## 3\. Buy a “trusted” certificate.
|
||||
|
||||
There are Certificate Authorities (CAs) that can sell you a certificate⁴. The service they provide is, that they validate your name (personal certificates) or your organization’s name (corporate certificate) before creating your certificate for you, just like you did in option 2. The difference is, that they are listed on the previously mentioned trust lists (e.g. Adobe’s) and thus the resulting signatures get a nice, green checkmark in Adobe Reader⁵
|
||||
|
||||
## 4\. Becoming a Trusted Certificate Authority (CA) yourself and create your own certificate
|
||||
|
||||
This option is an incredibly complex endeavour, requiring a lot of effort and skill. It can be done, as there are multiple CAs around the world. Is it worth the effort? That depends a lot on what you’re trying to accomplish.
|
||||
|
||||
<center>. . .</center>
|
||||
|
||||
## What we did
|
||||
|
||||
Having briefly introduced the options, here is what we did: Since we aim to raise the bar on digital signature proliferation and trust, we opted to buy an “Advanced Personal Certificates for Companies/Organisations” from WiseKey. Thus, documents signed with Documenso’s hosted version look like this:
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/blog-fig-building-documenso.webp"
|
||||
width="1262"
|
||||
height="481"
|
||||
alt="Figure 1"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">The famous green checkmark: Signed by hosted Documenso</figcaption>
|
||||
</figure>
|
||||
|
||||
There weren’t any deeper reasons we choose WiseKey, other than they offered what we needed and there wasn’t any reason to look much further. While I didn’t map the entire certificate market offering (yet), I’m pretty sure something similar could be found elsewhere. While we opted for option 3, choosing option 2 might be perfectly reasonable considering your use case.⁶
|
||||
|
||||
> While this is our setup, for now, we have a bigger plan for this topic. While globally trusted SSL Certificates have been available for free, courtesy of Let’s Encrypt, for a while now, there is no such thing as document signing. And there should be. Not having free and trusted infrastructure for signing is blocking a completely new generation of signing products from being created. This is why we’ll start working on option 4 when the time is right.
|
||||
|
||||
Do you have questions or thoughts about this? As always, let me know in the comments, on <a href="http://twitter.com/eltimuro" target="_blank">twitter.com/eltimuro</a>
|
||||
or directly: <a href="https://documen.so/timur" target="_blank">documen.so/timur</a>
|
||||
|
||||
Join the self-hoster community here: <a href="https://documen.so/discord" target="_blank">https://documen.so/discord</a>
|
||||
|
||||
Best from Hamburg
|
||||
|
||||
Timur
|
||||
|
||||
\[1\] There are different approaches to signing a document. For the sake of simplicity, here we talk about a document with X inserted signature images, that is afterward signed once the by signing service, i.e. Documenso. If each visual signature should have its own digital one (e.g. QES — eIDAS Level 3), the case is a bit more complex.
|
||||
|
||||
\[2\] Of course, the signing service provider technically can change and resign the document, especially in the case mentioned in \[1\]. This can be countered by requiring actual digital signatures from each signer, that are bound to their identity/ account. Creating a completely trustless system in the context however is extremely hard to do and not the most pressing business need for the industry at this point, in my opinion. Though, this would be nice.
|
||||
|
||||
\[3\] Adobe, like the EU, has a list of organizations they trust. The Adobe green checkmark is powered by the Adobe trust list, if you want to be trusted by EU standards here: <a href="https://ec.europa.eu/digital-building-blocks/DSS/webapp-demo/validation" target="_blank">https://ec.europa.eu/digital-building-blocks/DSS/webapp-demo/validation</a>, you need to be on the EU trust list. Getting on each list is possible, though the latter is much more work.
|
||||
|
||||
\[4\] Technically, they sign your certificate creation request (created by you), containing your info with their certificate (which is trusted), making your certificate trusted. This way, everything you sign with your certificate is seen as trusted. They created their certificate just like you, the difference is they are on the lists, mentioned in \[3\]
|
||||
|
||||
\[5\] Why does Adobe get to say, what is trusted? They simply happen to have the most used pdf viewer. And since everyone checks there, whom they consider trusted carries weight. If it should be like this, is a different matter.
|
||||
|
||||
\[6\] Self-Signed signatures, even purely visual signatures, are fully legally binding. Why you use changes mainly your confidence in the signature and the burden of proof. Also, some industries require a certain level of signatures e.g. retail loans (QES/ eIDAS Level 3 in the EU).
|
||||
@ -1,117 +0,0 @@
|
||||
---
|
||||
title: 'Building Documenso — Part 2: Signature Validity'
|
||||
description: Is a signature valid? And what does that mean? It's a surprisingly complex question; let's take a look.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-04-05
|
||||
tags:
|
||||
- Document Signature
|
||||
- Certificates
|
||||
- Signing
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/eu-validate-1.png"
|
||||
width= "650"
|
||||
height= "650"
|
||||
alt= "A report card for signature validity."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
If a tree does not comply with the EU trust list, does it make a sound when validating?r
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Signatures can be valid and compliant for different signature levels, even if some validators show higher-level errors. Not all helpful security measures are mandated by law.
|
||||
|
||||
# A valid question
|
||||
|
||||
A few days ago, an early adopter brought up this question in our [Discord](https://documen.so/discord):
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/eu-validate-2.png"
|
||||
width= "650"
|
||||
height= "650"
|
||||
alt= "A report card for signature validity."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
You can check out the validator here: [https://documen.so/eu-validator](https://documen.so/eu-validator)
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
For those unfamiliar with the tool, he used the validator tool of the EU's Digital Signature Service (DSS) Framework to check the signature of a document signed with Documenso. The EU provides this tool to help users and providers check the validity level of their signatures.
|
||||
|
||||
A short refresher from [Building Documenso — Part 1: Certificates](https://documen.so/certs):
|
||||
|
||||
> Documenso inserts all visual signatures into the document and then seals it using the "Documenso Inc." corporate certificate. This makes the resulting PDF document tamper-proof and guarantees it hasn't changed since signing.
|
||||
|
||||
Before we answer if the document was signed correctly, we need to understand what the goal was.
|
||||
|
||||
There are three signature levels in the European eIDAS regulation:
|
||||
|
||||
1. **Simple Electronic Signatures (Level 1/ SES):** This is just a visual signature or even a checkbox on a document.
|
||||
|
||||
2. **Advanded Electronic Signatures (Level 2/ AES)**: An actual crypographic signature (not just a seal on the whole document, but a specific signature), using a certificate linked to the identification data of the signer.
|
||||
|
||||
3. **Qualified Electronic Signatures (Level 3/ QES):** Same as 2. but done by a government-certified entity on certified hardware and after identifying the signer with an official ID document (e.g., passport)
|
||||
|
||||
> 💡 Side Note: Number 2 (AES) is how most people imagine digital signatures. But most of the market uses 1. plus a seal on the whole document under the name of the signing provider (e.g., Documenso). The signer's data is only inserted visually, not in the actual signature. Why? One of the reasons is that it's much easier, and without a readily available open source framework to draw from, it is quite tricky to build. This is something we aim to build (which many have done) and open source (which no one has done).
|
||||
|
||||
From the perspective of eIDAS, Documenso offers Level 1/ SES signatures since it does not adhere to all of the requirements of Level 2/ AES. This means that, technically, there is no legal need to seal the document to achieve this level of validity (at least within eIDAS). We do it anyway since it improves the level of confidence users can have in the signed document. Sealing the document, even though not legally required, is a great example of Documenso's approach to signatures. First, we aim to provide all legal requirements for a given use case. Then, we add any protection that can be added without unwarranted friction to the creation of the signature.
|
||||
|
||||
## Not if valid, but how valid
|
||||
|
||||
**Q: So, is the signature in the image valid?**
|
||||
|
||||
A: Yes, as an eidas Level 1 SES.
|
||||
|
||||
**Q: Then why does it say "Unable to build a certificate chain up to a trusted list"**
|
||||
|
||||
A: The certificate we use to seal the document after inserting the signatures is not on the EU Trust list.
|
||||
|
||||
**Q: Does that mean it is less secure?**
|
||||
|
||||
A: No, it means the provider (Wisekey) is not on a list maintained by the EU. The cryptographic signature is just as strong as any other
|
||||
|
||||
For someone who does not deal with this stuff daily, this can be hard to comprehend. Whether you use a certificate you generated yourself, one generated by a certificate authority (CA) like Wisekey, or one by another on the EU trust list (e.g., Bundesdruckerei), the cryptographic security guaranteeing that the document has not been tampered with is always the same. Many providers like Documenso, DocuSign, PandaDoc, and Digisigner all use this method for their regular plans. That means if you were to run a document signed by them through the validator above, the result would be the same[1]. The interesting question is why? Why do it like this?
|
||||
|
||||
## Certificate Infrastructure is broken
|
||||
|
||||
While there are some actual expenses involved in providing AES and QES, the blunt reality is that it's just good business to charge for them per signature, making it unsuitable for the "standard offerings"; almost no one has the resources to set this up themselves. While this initial process of becoming a QES-certified entity is really expensive, selling the certificates afterward is very lucrative. This leads to less innovation in the space and only big players providing these high-compliance services. Even certificates only used to seal documents without being QES certified are sold for a large range of prices, and they cost almost nothing to produce.
|
||||
|
||||
## Why Though?
|
||||
|
||||
**Q: Why do people buy a certificate for money and not just generate one themselves? Isn't the cryptographic security the same?**
|
||||
|
||||
A: Self-generated certificates are not recognized for higher-level compliance signatures like QES
|
||||
|
||||
**Q: So if you don't need higher-level signatures, you could just generate one yourself?**
|
||||
|
||||
A: Yes, you could. Since eIDAS Level 1 does not require a cert, you could use your own.
|
||||
|
||||
**Q: Why don't more people?**
|
||||
|
||||
A: One reason is that apart from the EU trust list, there are others, like the Adobe trust list. While not legally required, being on that one (like Wisekey) gives you a green checkmark in Adobe PDF, which is how most people check signature validity.
|
||||
|
||||
**Q: Not a question, but all of this sounds weird**
|
||||
|
||||
A: It is. This is one of the reasons why Documenso exists. We plan to make this easier.
|
||||
|
||||
**Q: How?**
|
||||
|
||||
A: By explaining and providing easy-to-use tools and eventually free, highly compliant signature certificates for everyone.
|
||||
|
||||
Eventually, we plan to start a free certificate authority called Let's Sign, named after another instituion that broke the paid certificate paradigm to the benefit of the internet: [Let's Encrypt](https://letsencrypt.org/).
|
||||
|
||||
As always, feel free to connect on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments.
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
\
|
||||
\
|
||||
\
|
||||
[1] The signature format (e.g. PKCS7-B) will vary. It's the format what the signature inserted into the document looks like. eIDAS itself does not specifically require any given format, but the PAdES defined by the EU is mostly used by european providers.
|
||||
@ -1,82 +0,0 @@
|
||||
---
|
||||
title: Cal.com Chooses Documenso for DPA and BAA Scalability and Compliance
|
||||
description: Learn how Cal.com scales their Data Processing Agreement (DPA) and Business Associate Agreement (BAA) processes with Documenso’s open source platform as they grow.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-10-11
|
||||
tags:
|
||||
- Customer Story
|
||||
- Open Startup
|
||||
- Open Source
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/cal2.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Scheduling Infrastructure for Everyone"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Scheduling Infrastructure for Everyone.
|
||||
</figcaption>
|
||||
</figure>
|
||||
TL;DR: Cal.com uses Documenso’s template direct links to facilitate low-friction compliance paperwork, enhancing scalability and user experience.
|
||||
|
||||
## Cal.com – The Most Public Private Company
|
||||
|
||||
[Cal.com](Cal.com) is an open source company that needs no introduction. Founded in 2021 by Bailey Pumfleet and Peer Richelsen, it quickly evolved from an open source alternative to the widespread but limited scheduling platform Calendly into the internet’s most beloved scheduling solution. Starting with just two founders, Cal.com has grown into a team of 22, facilitating millions of bookings per year for its ever-growing user and customer base.
|
||||
|
||||
Their commitment to transparency is evident as they follow the [open startup movement](https://cal.com/open), opening up not only their source code but also providing insights into their business operations. Their Commercial Open Source Software (COSS) model, combining a company and an open source project, has inspired a whole cohort of startups joining the space—not least of which is Documenso.
|
||||
|
||||
## The Need
|
||||
|
||||
At this point, Cal.com serves customers of all sizes, from single users to large enterprises. To provide the best product for their customers, they are certified for SOC 2, HIPAA, GDPR, and many other compliance regulations. One challenge that comes with this is the increasing number of waivers that need to be signed when onboarding customers. Business Associate Agreements (BAAs) and Data Processing Agreements (DPAs) are two of the more commonly known examples. To get these signed with minimal effort for both sides, they were looking for a solution to handle these at scale.
|
||||
|
||||
> We love open source.
|
||||
|
||||
— Peer Richelsen, Co-Founder, Cal.com
|
||||
|
||||
Being an open source company, they also prefer open source in their vendors—for both the shared philosophy and the higher level of trust. The goal was to integrate signing into the checkout process as seamlessly as possible.
|
||||
|
||||
## The Solution
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/cal.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Cal.com direct link template to sign a DPA"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Sign a DPA with Cal by clicking a link anytime.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
Documenso offers exactly this solution through direct link templates, enabling Cal.com to:
|
||||
|
||||
- Provide Immediate Access: Customers can access and sign necessary compliance documents through direct links at any time.
|
||||
- Enhance User Experience: Users are immediately forwarded to onboarding after signing.
|
||||
- Ensure Easy Access: The documents are stored within the company’s team account, allowing easy access for anyone who needs them.
|
||||
|
||||
Direct Link templates can also easily be embedded, using the [Documenso widget](https://documen.so/embedded). Embedding anywhere, pre-Filling the templates and notfiying the compliance team at certain point of the flow are a few of the many option the team now has in continously enhanceing their onboard and compliance UX.
|
||||
|
||||
Read more about our direct link templates here: [Direct Link Signing](https://docs.documenso.com/users/direct-links).
|
||||
|
||||
## The Journey
|
||||
|
||||
Initially, Cal.com’s team approached the new solution with skepticism. As Bailey reflected:
|
||||
|
||||
> We were intrigued but skeptical at first, as we put a lot of thought into compliance and doing things right. Documenso’s documentation and support showcased how their direct link templates could meet our needs while being highly compliant.
|
||||
|
||||
This experience highlights Documenso’s trust philosophy. We strive to be transparent in everything we do and let people judge for themselves. It also shows that we neither want nor get trust by default. Doing things right is a conversation worth having, especially in a space as opaque as digital signatures. It goes without saying that the whole team is hyped to have Cal.com on board and yet another open source company joining the open signing movement 🚀
|
||||
|
||||
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
Thinking about switching to a modern signing platform? Reach out anytime: [https://documen.so/sales](https://documen.so/sales)
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,87 +0,0 @@
|
||||
---
|
||||
title: Commodifying Signing
|
||||
description: We are creating signing as a public good and are commoditizing it to make it cheaper and better.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-01-25
|
||||
tags:
|
||||
- Vision
|
||||
- Mission
|
||||
- Open Source
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/lighthouse.jpeg"
|
||||
width="650"
|
||||
height="650"
|
||||
alt="A lighthouse on a tiny island."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Lighthouses are often used as an example of a public good; As they benefit all maritime users, but no one can be excluded from using them as a navigational aid. Use by one person neither prevents access by other people, nor does it reduce availability to others.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
# Commodifying Signing
|
||||
|
||||
> TLDR; We are creating signing as a public good and are commoditizing it to make it cheaper and better.
|
||||
|
||||
While we are in full-on building mode with Documenso, I think a lot about the big picture of what we are attempting to do. One phrase that keeps popping up is, "We are commodifying signing." Let's dig deeper into what that means.
|
||||
|
||||
Let's start with why we are doing this. Documenso's mission is to solve the domain of signing once and for all for everyone. In so many calls, I hear stories about how organizations build their own solution because the existing ones are too expensive or need to be more flexible. That means not hundreds but probably thousands of companies worldwide have done the same. This is simply wasting humanity's time. Since digital signing systems are understood well enough that seemingly "everyone" can build them, given enough pain, It's time to do it once correctly.
|
||||
|
||||
## Is signing already a commodity?
|
||||
|
||||
> In economics, a **commodity** is an economic good, usually a resource, that has explicitly full or substantial fungibility: that is, the market treats instances of the good as equivalent or nearly so with no regard to who produced them.
|
||||
|
||||
That sounds like the signing market today. There is no shortage of signing providers, and you can get similar signing services from many places. So why is this different from what we want, and why does this not satisfy the market?
|
||||
|
||||
- Signing is expensive and painful when you are locked into your vendor, and they charge by signing volume.
|
||||
- Signing is also expensive and painful when you have to build it yourself since no vendor fits your requirements or you are not allowed to
|
||||
|
||||
To understand why, we need to look at the landscape as it is today:
|
||||
|
||||
- **Commodity**: Signing SaaS
|
||||
- **Private Goods**: Signing Code Base, Regulatory Know-How
|
||||
- **Public Goods**: Web Tech, Digital Signature Algorithms and Standards
|
||||
|
||||
What the current players have done is to commodify the listed public goods into commercial products:
|
||||
|
||||
> […]the action and process of transforming goods, services, ideas, nature, personal information, people, or animals into commodities.
|
||||
> (Let's ignore the end of that list for now and what it says about humanity, yikes)
|
||||
|
||||
While this paradigm brought digital signing to many businesses worldwide, we aim for a different future. To solve signing once and for all, we need to achieve two core points:
|
||||
|
||||
- Making it cheaper so it's profitable for everyone to use
|
||||
- Making it more accessible so everyone can use it (e.g. regulated industries) and flexible enough (extendable, open).
|
||||
|
||||
To achieve this, we must transform the landscape to look like this:
|
||||
|
||||
- **Commodities**: Enterprise Components, Support, Hosting, Self-Host Licenses
|
||||
- **Public Goods**: (no longer private): OS (Open Source) Signing Code Base, OS Regulatory Know-How
|
||||
- **Public Goods**: OS Web Tech, Digital Signature Algorithms and Standards
|
||||
|
||||
## Raising the Bar
|
||||
|
||||
Before creating a commodity, we are raising the bar of what the underlying public good is. Having an open source singing framework you can extend, self-host, and understand makes the resulting solution much more accessible and extendable for everyone. Now for the final feat of making signing cheaper:
|
||||
|
||||
As we have seen, signing has already been commodified. But since it was done by a closed source and, frankly, a very opaque industry, no downward price spiral has ensued. By building Documenso open source with an open culture, we can pierce the veil and trigger what the space has been missing for a long time: Commoditization. If you had to read that again, so did I:
|
||||
|
||||
> In business literature, **commoditization** is defined as the process by which goods that have economic value and are distinguishable in terms of attributes (uniqueness or brand) become simple commodities in the eyes of the market or consumers.
|
||||
|
||||
By only selling what creates value for the customer (hosting a highly available service, keeping it compliant, supporting with technical issues and challenges, preparing industry-specific components), we are commoditizing signing since everyone can do it now: The resources enabling it are public goods, aka. open source. A leveled playing field, as described above, is the perfect environment for a community-first, technology-first, and value-first company like Documenso to flourish.
|
||||
|
||||
## Changing the Game
|
||||
|
||||
In this new world, a company needing signing (literally every company) can decide if the ROI (Return on Investment) of building signing themselves is greater than simply paying for the value-added activities they will need anyway. Pricing our offering not on volume but fixed is a nice additional wedge into the market we intend to use here.
|
||||
|
||||
The market dynamic now changes to who can offer the greatest value added to the public goods, driving the price down as this can be done much more efficiently than locking customers into closed source SaaS. Documenso, being a lean company, which we intend to stay with for a long time, will help kickstart this effect. Open Source capital efficiency is real. Our planned enterprise components, hosting support, and partner ecosystem will all leverage this effect.
|
||||
|
||||
We will grow our community around the public good, the open-source repo, and create an ecosystem around the commodities built on top of it (components, hosting, compliance, support). We will solve signing once and for all, and the world will be better for it. Onwards.
|
||||
|
||||
As always, feel free to connect on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments.
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,96 +0,0 @@
|
||||
---
|
||||
title: Creating an Efficient Statement of Work Approval Process with Documenso
|
||||
description: Submitting statements of work can be a drag on morale and project efficiency. Let's look at how to create a modern, low-friction workflow for this.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-07-23
|
||||
tags:
|
||||
- Freelancer
|
||||
- Statement of Work
|
||||
- Productivity
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/sov.webp"
|
||||
width="1400"
|
||||
height="884"
|
||||
alt="Working papers image"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">Fine-tune your process using custom role for everyone involved.</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Statements of Work detail what needs to be done. Automate sending and approving them using Documenso and Zapier.
|
||||
|
||||
## What is a Statement of Work
|
||||
|
||||
A statement of work is a detailed document that outlines what needs to be done in a project. It covers the project's scope, objectives, and deliverables, laying out all the tasks, deadlines, and milestones. The statement of work also spells out who’s responsible for what, ensuring everyone’s on the same page. It’s a roadmap that keeps both clients and service providers aligned and ensures the project stays on track from start to finish.
|
||||
|
||||
In the context of freelance work, the statement of work is a document that outlines the details of a project between a freelancer and their client. It's a concrete work to be agreed upon and tracked after completion. The statement of work is created after the [proposal is accepted](https://documen.so/freelance-proposal) and the [contract signed](https://documen.so/freelance-contract).
|
||||
|
||||
## What does a good workflow look like?
|
||||
|
||||
### 1. Create the statement of work
|
||||
|
||||
The team at Zapier created a [excellent guide](https://zapier.com/blog/statement-of-work-template/), which goes into the statement of work. There is a short checklist:
|
||||
|
||||
- Project Context/ Current Scope
|
||||
- Objectives for this piece of work
|
||||
- Scope (tasks, activities, and limits)
|
||||
- Requirements (e.g., technical and regulatory)
|
||||
- Deliverables to be created
|
||||
- Roles and Responsibilities
|
||||
|
||||
### 2. Get approval from subject matter experts (optional)
|
||||
|
||||
Since a statements of work can be very technical, having professionals from either side approve it first can be sensible. This can avoid double or unnecessary work and minimize the chances of misunderstandings. If this makes sense, it depends heavily on the scale of the project and the level of insight of the professional providing it.
|
||||
|
||||
### 3. Let the client sign off
|
||||
|
||||
Having the client sign off on the concrete work is the central step of the statement of work workflow. Assuming the document’s content is correct, getting the go-ahead ensures everyone is aligned and clear on what should and will be worked on.
|
||||
|
||||
### 4. Inform other Stakeholders (optional)
|
||||
|
||||
Depending on the scale of the organizations working together, other people may need to be kept in the loop. This could be accounting on either side, project managers, or other interested parties.
|
||||
|
||||
## Fine-Tuning the Flow with Custom Roles
|
||||
|
||||
<figure>
|
||||
<MdxNextImage src="/blog/roles.webp" width="1400" height="884" alt="Documenso Roles UI" />
|
||||
<figcaption className="text-center">
|
||||
Let's take a look at what it would look like with Documenso.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
### 1. Creating the Document: Templates vs. Custom Document
|
||||
|
||||
[Creating a template](https://docs.documenso.com/users/templates) can make sense if you submit statements of work regularly. If you create a Documenso Template, you can add [dynamic text and number fields](https://docs.documenso.com/users/signing-documents/fields) to be filled out when using the template. Another approach to this is creating a template on a document service like Google Docs, filling out a new copy, and uploading the custom-created document to Documenso.
|
||||
|
||||
Different parts of this process can be automated using the [Zapier Documenso Integration](https://documen.so/zapier) as desired:
|
||||
|
||||
- Automatically sending out a template to be filled out and signed
|
||||
- Creating a document in Documenso from a newly created document in Google Docs
|
||||
- Triggering sending a document created from either template or automation
|
||||
|
||||
### 2. Approvals
|
||||
|
||||
Looping in subject matter experts can easily be done using the approver role. This role allows you to complete a document without blocking the signing. This means the client can sign a document, even if the approval is not yet in place, removing friction. However, having the approval denied will stop the document from being completed and let everyone know there are corrections to be made. A software version of this is possible, having the expert in a viewer role and marking the document as seen without the option to block.
|
||||
|
||||
### 3. Signers
|
||||
|
||||
Looping in the client is done by adding one or more signer roles. Signer roles require recipients to place at least one signature to fulfill their part in the flow.roles
|
||||
|
||||
### 4. BCC
|
||||
|
||||
You can add one or several BCC roles to inform interested parties, e.g., accounting or project managers. As the process finishes, BCC recipients receive a copy of the completed document (assuming it completes and is not blocked). Using BCC roles automates filling in everyone who is only interested in the outcome and wants to avoid involvement in the steps leading up to it.
|
||||
|
||||
### Conclusion
|
||||
|
||||
Streamlining your statement of work approval process with Documenso can significantly improve productivity and ease. Using templates, dynamic fields, and Zapier integrations, you can create a smooth, efficient workflow from start to finish. Adding roles for experts, signers, and BCC recipients tailors the process to fit your project's needs, ensuring everyone stays on the same page.
|
||||
|
||||
An efficient SOW process saves time and improves communication, letting you focus on delivering great work. We're excited to hear your thoughts and experiences—reach out on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,85 +0,0 @@
|
||||
---
|
||||
title: 'Customer Story Prisma: 4 Reasons why Prisma chose Documenso for Signatures'
|
||||
description: We are happy to welcome Prisma, another OSS company, as a customer. Read here why they choose us.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-09-26
|
||||
tags:
|
||||
- Prisma
|
||||
- Customer Story
|
||||
- Open Source
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/prisma.png"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="Primsa Landing Page We simplify database migration, connection pooling, database queries, and readable data models."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Prisma uses Documenso for collaborative team signing.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Prisma is now using Documenso, and [we added visibility scopes](https://docs.documenso.com/users/document-visibility)
|
||||
|
||||
# Prisma
|
||||
|
||||
Prisma is an open-source company known for its modern OSS ORM (Object-Relational Mapping) tools that simplify database interactions for developers. Their flagship product, Prisma ORM, provides a type-safe way to query databases like PostgreSQL, MySQL, and many more. With the addition of Prisma Studio, an intuitive database management interface, Prisma makes it easier and more efficient for developers to work with databases. With their new additions, Prisma Pulse and Accelerate, you can react to real-time database changes and optimize your queries. And they are completely [open source](https://github.com/prisma/prisma)!
|
||||
|
||||
# We choose Prisma too!
|
||||
|
||||
I discovered Prisma when planning the tech stack for the [first version of Documenso](https://github.com/documenso/documenso/releases/tag/0.9-developer-preview). Prisma has felt natural to use since day one and has been the base of our database architecture ever since. It's great to see them develop and grow with us.
|
||||
|
||||
# Why they choose us
|
||||
|
||||
## 1. Signature Flows
|
||||
|
||||
Documenso signing flows are highly configurable, designed to adapt to the needs of any document signing process. Whether you're working with different roles, varying settings, or specific delivery methods, Documenso offers the flexibility to suit your requirements. You can choose to send documents via email, share a manual link, generate a link through the API, or even use a static direct link for quick access—all while ensuring a smooth signing experience.
|
||||
|
||||
Additionally, you can create templates to streamline and reuse common workflows, saving valuable time. Direct link templates enable users to drive the flow themselves, providing a straightforward path for signing. For a seamless experience, Documenso also allows you to embed the signing process directly into your website, ensuring an uninterrupted, integrated workflow tailored to your needs.
|
||||
|
||||
## 2. Modern UX
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/dsux.png"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="A completed document in Documenso, ready to download."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
We call Documenso's design "Happy Minimalism"
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
We’ve crafted Documenso with a sleek, modern interface that makes it incredibly easy to use. Whether you’re signing documents, managing workflows, or fine-tuning settings, its intuitive design allows you to accomplish tasks quickly and effortlessly. More than just powerful, Documenso is a pleasure to navigate—designed to be accessible to everyone, no matter their level of tech experience.
|
||||
|
||||
## 3. Teams
|
||||
|
||||
### Teamwork Makes the Dream Work
|
||||
|
||||
Documenso makes teamwork a breeze with its team management features. You can easily set up and organize teams, making it simple to share and manage documents and workflows together. This is a lifesaver for larger organizations or teams spread across different departments, ensuring everyone stays in sync and on track. Different visibility scopes ensure private documents stay private and others are shared for easy collaboration.
|
||||
|
||||
### Document Visibility
|
||||
|
||||
Collaboration within a team often demands different levels of access to documents. For instance, the Documenso team at Prisma needed a way to set custom visibility on some documents while keeping others accessible to everyone. To address this need, we introduced role-based visibility scopes. This feature allows teams to manage documents more effectively. They can make certain documents visible only to managers or, in special cases, restricted to admins. This ensures sensitive information stays protected while general documents remain accessible to those who need them.
|
||||
|
||||
Learn more about visibility scopes and [how they can benefit your team here](https://docs.documenso.com/users/document-visibility).
|
||||
|
||||
## 4. OSS!
|
||||
|
||||
As you might know, we are open-source! This means you can peek under the hood, tweak things to your liking, and even contribute to making the platform better. We love the community-driven aspect of open-source, and it aligns perfectly with our goal to keep improving and innovating with input from our users.
|
||||
|
||||
So, whether you're looking to streamline your document workflows or just need a solid, reliable platform, Documenso has got your back. And we're thrilled to serve another OSS company and help make the space more open.
|
||||
|
||||
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
Thinking about switching to a modern signing platform? Reach out anytime: [https://documen.so/sales](https://documen.so/sales)
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||