Compare commits
13 Commits
fix/self-s
...
feat/add-d
| Author | SHA1 | Date | |
|---|---|---|---|
| ea85aac4a6 | |||
| 07c0b03a99 | |||
| eea09dcfac | |||
| 3aea62e898 | |||
| 76674523c5 | |||
| e0e2f3e440 | |||
| 05238f096b | |||
| dd83d4607c | |||
| 07d13c74f5 | |||
| 64d1d6df37 | |||
| 877a579533 | |||
| b0e364acf4 | |||
| 803ebccee3 |
@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "Documenso",
|
||||
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||
"version": "latest",
|
||||
"enableNonRootDocker": "true",
|
||||
"moby": "true"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {}
|
||||
},
|
||||
"onCreateCommand": "./.devcontainer/on-create.sh",
|
||||
"forwardPorts": [
|
||||
3000,
|
||||
54320,
|
||||
9000,
|
||||
2500,
|
||||
1100
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"aaron-bond.better-comments",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"mikestead.dotenv",
|
||||
"unifiedjs.vscode-mdx",
|
||||
"GitHub.copilot-chat",
|
||||
"GitHub.copilot-labs",
|
||||
"GitHub.copilot",
|
||||
"GitHub.vscode-pull-request-github",
|
||||
"Prisma.prisma",
|
||||
"VisualStudioExptTeam.vscodeintellicode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Copy the env file
|
||||
cp .env.example .env
|
||||
|
||||
# Run the dev setup
|
||||
npm run dx
|
||||
@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
npm run dev
|
||||
109
.env.example
@ -1,118 +1,19 @@
|
||||
# [[AUTH]]
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
NEXTAUTH_SECRET="secret"
|
||||
|
||||
# [[CRYPTO]]
|
||||
# Application Key for symmetric encryption and decryption
|
||||
# REQUIRED: This should be a random string of at least 32 characters
|
||||
NEXT_PRIVATE_ENCRYPTION_KEY="CAFEBABE"
|
||||
# REQUIRED: This should be a random string of at least 32 characters
|
||||
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="DEADBEEF"
|
||||
NEXT_PUBLIC_SITE_URL="http://localhost:3000"
|
||||
NEXT_PUBLIC_APP_URL="http://localhost:3000"
|
||||
|
||||
# [[AUTH OPTIONAL]]
|
||||
NEXT_PRIVATE_GOOGLE_CLIENT_ID=""
|
||||
NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=""
|
||||
|
||||
# [[URLS]]
|
||||
NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
|
||||
NEXT_PUBLIC_MARKETING_URL="http://localhost:3001"
|
||||
|
||||
# [[DATABASE]]
|
||||
NEXT_PRIVATE_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso"
|
||||
# Defines the URL to use for the database when running migrations and other commands that won't work with a connection pool.
|
||||
NEXT_PRIVATE_DIRECT_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso"
|
||||
|
||||
# [[SIGNING]]
|
||||
# The transport to use for document signing. Available options: local (default) | gcloud-hsm
|
||||
NEXT_PRIVATE_SIGNING_TRANSPORT="local"
|
||||
# OPTIONAL: The passphrase to use for the local file-based signing transport.
|
||||
NEXT_PRIVATE_SIGNING_PASSPHRASE=
|
||||
# OPTIONAL: The local file path to the .p12 file to use for the local signing transport.
|
||||
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=
|
||||
# OPTIONAL: The base64-encoded contents of the .p12 file to use for the local signing transport.
|
||||
NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS=
|
||||
# OPTIONAL: The path to the Google Cloud HSM key to use for the gcloud-hsm signing transport.
|
||||
NEXT_PRIVATE_SIGNING_GCLOUD_HSM_KEY_PATH=
|
||||
# OPTIONAL: The path to the Google Cloud HSM public certificate file to use for the gcloud-hsm signing transport.
|
||||
NEXT_PRIVATE_SIGNING_GCLOUD_HSM_PUBLIC_CRT_FILE_PATH=
|
||||
# OPTIONAL: The base64-encoded contents of the Google Cloud HSM public certificate file to use for the gcloud-hsm signing transport.
|
||||
NEXT_PRIVATE_SIGNING_GCLOUD_HSM_PUBLIC_CRT_FILE_CONTENTS=
|
||||
# OPTIONAL: The path to the Google Cloud Credentials file to use for the gcloud-hsm signing transport.
|
||||
NEXT_PRIVATE_SIGNING_GCLOUD_APPLICATION_CREDENTIALS_CONTENTS=
|
||||
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID=
|
||||
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_YEARLY_PRICE_ID=
|
||||
|
||||
# [[STORAGE]]
|
||||
# OPTIONAL: Defines the storage transport to use. Available options: database (default) | s3
|
||||
NEXT_PUBLIC_UPLOAD_TRANSPORT="database"
|
||||
# OPTIONAL: Defines the endpoint to use for the S3 storage transport. Relevant when using third-party S3-compatible providers.
|
||||
NEXT_PRIVATE_UPLOAD_ENDPOINT="http://127.0.0.1:9002"
|
||||
# OPTIONAL: Defines the force path style to use for the S3 storage transport. Relevant when using third-party S3-compatible providers.
|
||||
# This will change it from using virtual hosts <bucket>.domain.com/<path> to fully qualified paths domain.com/<bucket>/<path>
|
||||
NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE="false"
|
||||
# OPTIONAL: Defines the region to use for the S3 storage transport. Defaults to us-east-1.
|
||||
NEXT_PRIVATE_UPLOAD_REGION="unknown"
|
||||
# REQUIRED: Defines the bucket to use for the S3 storage transport.
|
||||
NEXT_PRIVATE_UPLOAD_BUCKET="documenso"
|
||||
# OPTIONAL: Defines the access key ID to use for the S3 storage transport.
|
||||
NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID="documenso"
|
||||
# OPTIONAL: Defines the secret access key to use for the S3 storage transport.
|
||||
NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY="password"
|
||||
|
||||
# [[SMTP]]
|
||||
# OPTIONAL: Defines the transport to use for sending emails. Available options: smtp-auth (default) | smtp-api | mailchannels
|
||||
NEXT_PRIVATE_SMTP_TRANSPORT="smtp-auth"
|
||||
# OPTIONAL: Defines the host to use for sending emails.
|
||||
NEXT_PRIVATE_SMTP_HOST="127.0.0.1"
|
||||
# OPTIONAL: Defines the port to use for sending emails.
|
||||
NEXT_PRIVATE_SMTP_PORT=2500
|
||||
# OPTIONAL: Defines the username to use with the SMTP server.
|
||||
NEXT_PRIVATE_SMTP_USERNAME="documenso"
|
||||
# OPTIONAL: Defines the password to use with the SMTP server.
|
||||
NEXT_PRIVATE_SMTP_PASSWORD="password"
|
||||
# OPTIONAL: Defines the API key user to use with the SMTP server.
|
||||
NEXT_PRIVATE_SMTP_APIKEY_USER=
|
||||
# OPTIONAL: Defines the API key to use with the SMTP server.
|
||||
NEXT_PRIVATE_SMTP_APIKEY=
|
||||
# OPTIONAL: Defines whether to force the use of TLS.
|
||||
NEXT_PRIVATE_SMTP_SECURE=
|
||||
# REQUIRED: Defines the sender name to use for the from address.
|
||||
NEXT_PRIVATE_SMTP_FROM_NAME="No Reply @ Documenso"
|
||||
# REQUIRED: Defines the email address to use as the from address.
|
||||
NEXT_PRIVATE_SMTP_FROM_ADDRESS="noreply@documenso.com"
|
||||
# OPTIONAL: The API key to use for Resend.com
|
||||
NEXT_PRIVATE_RESEND_API_KEY=
|
||||
# OPTIONAL: The API key to use for MailChannels.
|
||||
NEXT_PRIVATE_MAILCHANNELS_API_KEY=
|
||||
# OPTIONAL: The endpoint to use for the MailChannels API if using a proxy.
|
||||
NEXT_PRIVATE_MAILCHANNELS_ENDPOINT=
|
||||
# OPTIONAL: The domain to use for DKIM signing.
|
||||
NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN=
|
||||
# OPTIONAL: The selector to use for DKIM signing.
|
||||
NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR=
|
||||
# OPTIONAL: The private key to use for DKIM signing.
|
||||
NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY=
|
||||
# OPTIONAL: Displays the maximum document upload limit to the user in MBs
|
||||
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=
|
||||
|
||||
# [[FEATURES]]
|
||||
# OPTIONAL: Leave blank to disable PostHog and feature flags.
|
||||
NEXT_PUBLIC_POSTHOG_KEY=""
|
||||
# OPTIONAL: Leave blank to disable billing.
|
||||
NEXT_PUBLIC_FEATURE_BILLING_ENABLED=
|
||||
# OPTIONAL: Leave blank to allow users to signup through /signup page.
|
||||
NEXT_PUBLIC_DISABLE_SIGNUP=
|
||||
|
||||
# [[E2E Tests]]
|
||||
E2E_TEST_AUTHENTICATE_USERNAME="Test User"
|
||||
E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
|
||||
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
||||
NEXT_PUBLIC_SUBSCRIPTIONS_ENABLED=false
|
||||
|
||||
# This is only required for the marketing site
|
||||
# [[REDIS]]
|
||||
NEXT_PRIVATE_REDIS_URL=
|
||||
NEXT_PRIVATE_REDIS_TOKEN=
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
# Config files
|
||||
*.config.js
|
||||
*.config.cjs
|
||||
|
||||
# Statically hosted javascript files
|
||||
apps/*/public/*.js
|
||||
apps/*/public/*.cjs
|
||||
scripts/
|
||||
47
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -1,47 +0,0 @@
|
||||
name: 'Bug Report'
|
||||
labels: ['bug']
|
||||
description: Create a bug report to help us improve
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Thank you for reporting an issue.
|
||||
Please fill in as much of the form below as you're able to.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue Description
|
||||
description: Please provide a clear and concise description of the problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Please provide step-by-step instructions to reproduce the issue. Include code snippets, error messages, and any other relevant information.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: Describe what you expected to happen.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: Describe what is currently happening.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots (optional)
|
||||
description: If applicable, add screenshots to help explain the issue.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System [e.g., Windows 10]
|
||||
- type: input
|
||||
attributes:
|
||||
label: Browser [e.g., Chrome, Firefox]
|
||||
- type: input
|
||||
attributes:
|
||||
label: Version [e.g., 2.0.1]
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please check the boxes that apply to this issue report.
|
||||
options:
|
||||
- label: I have searched the existing issues to make sure this is not a duplicate.
|
||||
- label: I have provided steps to reproduce the issue.
|
||||
- label: I have included relevant environment information.
|
||||
- label: I have included any relevant screenshots.
|
||||
- label: I understand that this is a voluntary contribution and that there is no guarantee of resolution.
|
||||
- label: I want to work on creating a PR for this issue if approved
|
||||
36
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@ -1,36 +0,0 @@
|
||||
name: 'Feature Request'
|
||||
description: Suggest a new idea or enhancement for this project
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please provide a clear and concise title for your feature request
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: Describe the feature you are requesting in detail. Explain what problem it solves or what value it adds to the project.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Use Case
|
||||
description: Provide a scenario or use case where this feature would be beneficial. Explain how users would interact with this feature and why it's important.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed Solution
|
||||
description: If you have an idea of how this feature could be implemented, describe it here. Include any technical details, UI/UX considerations, or design suggestions.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives (optional)
|
||||
description: Are there any alternative ways to achieve the same goal? Describe other approaches that could be considered if this feature is not implemented.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Add any additional context or information that might be relevant to the feature request.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please check the boxes that apply to this feature request.
|
||||
options:
|
||||
- label: I have searched the existing feature requests to make sure this is not a duplicate.
|
||||
- label: I have provided a detailed description of the requested feature.
|
||||
- label: I have explained the use case or scenario for this feature.
|
||||
- label: I have included any relevant technical details or design suggestions.
|
||||
- label: I understand that this is a suggestion and that there is no guarantee of implementation.
|
||||
- label: I want to work on creating a PR for this issue if approved
|
||||
39
.github/ISSUE_TEMPLATE/improvement.yml
vendored
@ -1,39 +0,0 @@
|
||||
name: 'General Improvement Request'
|
||||
description: 'Suggest a minor enhancement or improvement for this project'
|
||||
title: '[Title for your improvement suggestion]'
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 'Describe the improvement you are suggesting in detail'
|
||||
description: 'Explain why this improvement would be beneficial. Share any context, pain points, or reasons for suggesting this change.'
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 'Additional Information & Alternatives (optional)'
|
||||
description: 'Are there any additional context or information that might be relevant to the improvement suggestion.'
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: assignee
|
||||
attributes:
|
||||
label: 'Do you want to work on this improvement?'
|
||||
multiple: false
|
||||
options:
|
||||
- 'No'
|
||||
- 'Yes'
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 'Please check the boxes that apply to this improvement suggestion.'
|
||||
options:
|
||||
- label: 'I have searched the existing issues and improvement suggestions to avoid duplication.'
|
||||
- label: 'I have provided a clear description of the improvement being suggested.'
|
||||
- label: 'I have explained the rationale behind this improvement.'
|
||||
- label: 'I have included any relevant technical details or design suggestions.'
|
||||
- label: 'I understand that this is a suggestion and that there is no guarantee of implementation.'
|
||||
validations:
|
||||
required: true
|
||||
49
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,49 +0,0 @@
|
||||
---
|
||||
name: Pull Request
|
||||
about: Submit changes to the project for review and inclusion
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!--- Describe the changes introduced by this pull request. -->
|
||||
<!--- Explain what problem it solves or what feature/fix it adds. -->
|
||||
|
||||
## Related Issue
|
||||
|
||||
<!--- If this pull request is related to a specific issue, reference it here using #issue_number. -->
|
||||
<!--- For example, "Fixes #123" or "Addresses #456". -->
|
||||
|
||||
## Changes Made
|
||||
|
||||
<!--- Provide a summary of the changes made in this pull request. -->
|
||||
<!--- Include any relevant technical details or architecture changes. -->
|
||||
|
||||
- Change 1
|
||||
- Change 2
|
||||
- ...
|
||||
|
||||
## Testing Performed
|
||||
|
||||
<!--- Describe the testing that you have performed to validate these changes. -->
|
||||
<!--- Include information about test cases, testing environments, and results. -->
|
||||
|
||||
- Tested feature X in scenario Y.
|
||||
- Ran unit tests for component Z.
|
||||
- Tested on browsers A, B, and C.
|
||||
- ...
|
||||
|
||||
## Checklist
|
||||
|
||||
<!--- Please check the boxes that apply to this pull request. -->
|
||||
<!--- You can add or remove items as needed. -->
|
||||
|
||||
- [ ] I have tested these changes locally and they work as expected.
|
||||
- [ ] I have added/updated tests that prove the effectiveness of these changes.
|
||||
- [ ] I have updated the documentation to reflect these changes, if applicable.
|
||||
- [ ] I have followed the project's coding style guidelines.
|
||||
- [ ] I have addressed the code review feedback from the previous submission, if applicable.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!--- Provide any additional context or notes for the reviewers. -->
|
||||
<!--- This might include details about design decisions, potential concerns, or anything else relevant. -->
|
||||
40
.github/PULL_REQUEST_TEMPLATE/test-addition.md
vendored
@ -1,40 +0,0 @@
|
||||
---
|
||||
name: Test Addition
|
||||
about: Submit a new test, either unit or end-to-end (E2E), for review and inclusion
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!--- Provide a clear and concise description of the new test you are adding. -->
|
||||
<!--- Explain the purpose of the test and what it aims to validate. -->
|
||||
|
||||
## Related Issue
|
||||
|
||||
<!--- If this test addition is related to a specific issue, reference it here using #issue_number. -->
|
||||
<!--- For example, "Fixes #123" or "Addresses #456". -->
|
||||
|
||||
## Test Details
|
||||
|
||||
<!--- Describe the details of the test you're adding. -->
|
||||
<!--- Include information about inputs, expected outputs, and any specific scenarios. -->
|
||||
|
||||
- Test Name: Name of the test
|
||||
- Type: [Unit / E2E]
|
||||
- Description: Brief description of what the test checks
|
||||
- Inputs: What inputs the test uses (if applicable)
|
||||
- Expected Output: What output or behavior the test expects
|
||||
|
||||
## Checklist
|
||||
|
||||
<!--- Please check the boxes that apply to this pull request. -->
|
||||
<!--- You can add or remove items as needed. -->
|
||||
|
||||
- [ ] I have written the new test and ensured it works as intended.
|
||||
- [ ] I have added necessary documentation to explain the purpose of the test.
|
||||
- [ ] I have followed the project's testing guidelines and coding style.
|
||||
- [ ] I have addressed any review feedback from previous submissions, if applicable.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!--- Provide any additional context or notes for the reviewers. -->
|
||||
<!--- This might include explanations about the testing approach or any potential concerns. -->
|
||||
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: v18.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 }}
|
||||
restore-keys: prod-build-
|
||||
|
||||
- run: npm run build
|
||||
shell: bash
|
||||
39
.github/actions/node-install/action.yml
vendored
@ -1,39 +0,0 @@
|
||||
name: 'Setup node and cache node_modules'
|
||||
inputs:
|
||||
node_version:
|
||||
required: false
|
||||
default: v18.x
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Set up Node ${{ inputs.node_version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: npm-
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
packages/*/node_modules
|
||||
apps/*/node_modules
|
||||
key: modules-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
npm ci --no-audit
|
||||
npm run prisma:generate
|
||||
env:
|
||||
HUSKY: '0'
|
||||
19
.github/actions/playwright-install/action.yml
vendored
@ -1,19 +0,0 @@
|
||||
name: Install playwright binaries
|
||||
description: 'Install playwright, cache and restore if necessary'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Cache playwright
|
||||
id: cache-playwright
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
${{ github.workspace }}/node_modules/playwright
|
||||
key: playwright-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: playwright-
|
||||
|
||||
- name: Install playwright
|
||||
if: steps.cache-playwright.outputs.cache-hit != 'true'
|
||||
run: npx playwright install --with-deps
|
||||
shell: bash
|
||||
32
.github/dependabot.yml
vendored
@ -1,32 +0,0 @@
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
target-branch: 'main'
|
||||
labels:
|
||||
- 'ci dependencies'
|
||||
- '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:
|
||||
interval: 'weekly'
|
||||
target-branch: 'main'
|
||||
labels:
|
||||
- 'npm dependencies'
|
||||
- 'frontend'
|
||||
open-pull-requests-limit: 0
|
||||
21
.github/labeler.yml
vendored
@ -1,21 +0,0 @@
|
||||
'apps: marketing':
|
||||
- apps/marketing/**
|
||||
|
||||
'apps: web':
|
||||
- apps/web/**
|
||||
|
||||
'version bump 👀':
|
||||
- '**/package.json'
|
||||
- '**/package-lock.json'
|
||||
|
||||
'🚨 migrations 🚨':
|
||||
- packages/prisma/migrations/**/migration.sql
|
||||
|
||||
'🚨 e2e changes 🚨':
|
||||
- packages/app-tests/e2e/**
|
||||
|
||||
'🚨 .env changes 🚨':
|
||||
- .env.example
|
||||
|
||||
'pkg: ee changes':
|
||||
- packages/ee/**
|
||||
67
.github/workflows/ci.yml
vendored
@ -1,67 +0,0 @@
|
||||
name: 'Continuous Integration'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
push:
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build_app:
|
||||
name: Build App
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- uses: ./.github/actions/node-install
|
||||
|
||||
- name: Copy env
|
||||
run: cp .env.example .env
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
|
||||
build_docker:
|
||||
name: Build Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
- name: Build Docker Image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: false
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
tags: documenso-${{ github.sha }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||
|
||||
- # Temp fix
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
name: Move cache
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
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
|
||||
41
.github/workflows/codeql-analysis.yml
vendored
@ -1,41 +0,0 @@
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: ['javascript']
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Copy env
|
||||
run: cp .env.example .env
|
||||
|
||||
- uses: ./.github/actions/node-install
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
24
.github/workflows/deploy.yml
vendored
@ -1,24 +0,0 @@
|
||||
name: Deploy to Production
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Push to release branch
|
||||
run: |
|
||||
git checkout release || git checkout -b release
|
||||
git merge --ff-only main
|
||||
git push origin release
|
||||
44
.github/workflows/e2e-tests.yml
vendored
@ -1,44 +0,0 @@
|
||||
name: Playwright Tests
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
jobs:
|
||||
e2e_tests:
|
||||
name: 'E2E Tests'
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Copy env
|
||||
run: cp .env.example .env
|
||||
|
||||
- uses: ./.github/actions/node-install
|
||||
|
||||
- name: Start Services
|
||||
run: npm run dx:up
|
||||
|
||||
- uses: ./.github/actions/playwright-install
|
||||
|
||||
- name: Create the database
|
||||
run: npm run prisma:migrate-dev
|
||||
|
||||
- name: Seed the database
|
||||
run: npm run prisma:seed
|
||||
|
||||
- uses: ./.github/actions/cache-build
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: npm run ci
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: test-results
|
||||
path: 'packages/app-tests/**/test-results/*'
|
||||
retention-days: 30
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
29
.github/workflows/first-interaction.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: 'Welcome New Contributors'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ['opened']
|
||||
issues:
|
||||
types: ['opened']
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
welcome-message:
|
||||
name: Welcome Contributors
|
||||
if: github.event.action == 'opened'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pr-message: |
|
||||
Thank you for creating your first Pull Request and for being a part of the open signing revolution! 💚🚀
|
||||
<br /> Feel free to hop into our community in [Discord](https://documen.so/discord)
|
||||
issue-message: |
|
||||
Thank you for opening your first issue and for being a part of the open signing revolution!
|
||||
<br /> One of our team members will review it and get back to you as soon as it possible 💚
|
||||
<br /> Meanwhile, please feel free to hop into our community in [Discord](https://documen.so/discord)
|
||||
63
.github/workflows/issue-assignee-check.yml
vendored
@ -1,63 +0,0 @@
|
||||
name: 'Issue Assignee Check'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: ['assigned']
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
countIssues:
|
||||
if: ${{ github.event.issue.assignee }} && github.event.action == 'assigned' && github.event.sender.type == 'User'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: npm
|
||||
|
||||
- name: Install Octokit
|
||||
run: npm install @octokit/rest@18
|
||||
|
||||
- name: Check Assigned User's Issue Count
|
||||
id: parse-comment
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { Octokit } = require("@octokit/rest");
|
||||
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
||||
|
||||
const username = context.payload.issue.assignee.login;
|
||||
console.log(`Username Extracted: ${username}`);
|
||||
|
||||
const { data: issues } = await octokit.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
assignee: username,
|
||||
state: 'open'
|
||||
});
|
||||
|
||||
const issueCount = issues.length;
|
||||
console.log(`Issue Count For ${username}: ${issueCount}`);
|
||||
|
||||
if (issueCount > 3) {
|
||||
let issueCountMessage = `### 🚨 Documenso Police 🚨`;
|
||||
issueCountMessage += `\n@${username} has ${issueCount} open issues assigned already. Consider whether this issue should be assigned to them or left open for another contributor.`;
|
||||
|
||||
await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: issueCountMessage,
|
||||
headers: {
|
||||
'Authorization': `token ${{ secrets.GITHUB_TOKEN }}`,
|
||||
}
|
||||
});
|
||||
}
|
||||
21
.github/workflows/issue-opened.yml
vendored
@ -1,21 +0,0 @@
|
||||
name: 'Label Issues'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: ['opened', 'reopened']
|
||||
|
||||
jobs:
|
||||
label_issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ["needs triage"]
|
||||
})
|
||||
20
.github/workflows/pr-labeler.yml
vendored
@ -1,20 +0,0 @@
|
||||
name: 'PR Labeler'
|
||||
|
||||
on:
|
||||
- pull_request_target
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
sync-labels: ''
|
||||
64
.github/workflows/pr-review-reminder.yml
vendored
@ -1,64 +0,0 @@
|
||||
name: 'PR Review Reminder'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ['opened', 'reopened', 'ready_for_review', 'review_requested']
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
checkPRs:
|
||||
if: ${{ github.event.pull_request.user.login }} && github.event.action == ('opened' || 'reopened' || 'ready_for_review' || 'review_requested')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: npm
|
||||
|
||||
- name: Install Octokit
|
||||
run: npm install @octokit/rest@18
|
||||
|
||||
- name: Check user's PRs awaiting review
|
||||
id: parse-prs
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { Octokit } = require("@octokit/rest");
|
||||
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
||||
|
||||
const username = context.payload.pull_request.user.login;
|
||||
console.log(`Username Extracted: ${username}`);
|
||||
|
||||
const { data: pullRequests } = await octokit.pulls.list({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
sort: 'created',
|
||||
direction: 'asc',
|
||||
});
|
||||
|
||||
const userPullRequests = pullRequests.filter(pr => pr.user.login === username && (pr.state === 'open' || pr.state === 'ready_for_review'));
|
||||
const prCount = userPullRequests.length;
|
||||
console.log(`PR Count for ${username}: ${prCount}`);
|
||||
|
||||
if (prCount > 3) {
|
||||
let prReminderMessage = `🚨 @${username} has ${prCount} pull requests awaiting review. Please consider reviewing them when possible. 🚨`;
|
||||
|
||||
await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
body: prReminderMessage,
|
||||
headers: {
|
||||
'Authorization': `token ${{ secrets.GITHUB_TOKEN }}`,
|
||||
}
|
||||
});
|
||||
}
|
||||
133
.github/workflows/publish.yml
vendored
@ -1,133 +0,0 @@
|
||||
name: Publish Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['release']
|
||||
|
||||
jobs:
|
||||
build_and_publish_platform_containers:
|
||||
name: Build and publish platform containers
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- warp-ubuntu-latest-x64-4x
|
||||
- warp-ubuntu-latest-arm64-4x
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build the docker image
|
||||
env:
|
||||
BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-4x' && 'arm64' || 'amd64' }}
|
||||
run: |
|
||||
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker build \
|
||||
-f ./docker/Dockerfile \
|
||||
--progress=plain \
|
||||
-t "documenso/documenso-$BUILD_PLATFORM:latest" \
|
||||
-t "documenso/documenso-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "documenso/documenso-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
-t "ghcr.io/documenso/documenso-$BUILD_PLATFORM:latest" \
|
||||
-t "ghcr.io/documenso/documenso-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "ghcr.io/documenso/documenso-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
.
|
||||
|
||||
- name: Push the docker image to DockerHub
|
||||
run: docker push --all-tags "documenso/documenso-$BUILD_PLATFORM"
|
||||
env:
|
||||
BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-4x' && 'arm64' || 'amd64' }}
|
||||
|
||||
- name: Push the docker image to GitHub Container Registry
|
||||
run: docker push --all-tags "ghcr.io/documenso/documenso-$BUILD_PLATFORM"
|
||||
env:
|
||||
BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-4x' && 'arm64' || 'amd64' }}
|
||||
|
||||
create_and_publish_manifest:
|
||||
name: Create and publish manifest
|
||||
runs-on: ubuntu-latest
|
||||
needs: build_and_publish_platform_containers
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Create and push DockerHub manifest
|
||||
run: |
|
||||
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker manifest create \
|
||||
documenso/documenso:latest \
|
||||
--amend documenso/documenso-amd64:latest \
|
||||
--amend documenso/documenso-arm64:latest \
|
||||
|
||||
docker manifest create \
|
||||
documenso/documenso:$GIT_SHA \
|
||||
--amend documenso/documenso-amd64:$GIT_SHA \
|
||||
--amend documenso/documenso-arm64:$GIT_SHA \
|
||||
|
||||
docker manifest create \
|
||||
documenso/documenso:$APP_VERSION \
|
||||
--amend documenso/documenso-amd64:$APP_VERSION \
|
||||
--amend documenso/documenso-arm64:$APP_VERSION \
|
||||
|
||||
docker manifest push documenso/documenso:latest
|
||||
docker manifest push documenso/documenso:$GIT_SHA
|
||||
docker manifest push documenso/documenso:$APP_VERSION
|
||||
|
||||
- name: Create and push Github Container Registry manifest
|
||||
run: |
|
||||
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/documenso/documenso:latest \
|
||||
--amend ghcr.io/documenso/documenso-amd64:latest \
|
||||
--amend ghcr.io/documenso/documenso-arm64:latest \
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/documenso/documenso:$GIT_SHA \
|
||||
--amend ghcr.io/documenso/documenso-amd64:$GIT_SHA \
|
||||
--amend ghcr.io/documenso/documenso-arm64:$GIT_SHA \
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/documenso/documenso:$APP_VERSION \
|
||||
--amend ghcr.io/documenso/documenso-amd64:$APP_VERSION \
|
||||
--amend ghcr.io/documenso/documenso-arm64:$APP_VERSION \
|
||||
|
||||
docker manifest push ghcr.io/documenso/documenso:latest
|
||||
docker manifest push ghcr.io/documenso/documenso:$GIT_SHA
|
||||
docker manifest push ghcr.io/documenso/documenso:$APP_VERSION
|
||||
62
.github/workflows/semantic-pull-requests.yml
vendored
@ -1,62 +0,0 @@
|
||||
name: 'Validate PR Name'
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
validate-pr:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check PR creator's previous activity
|
||||
id: check_activity
|
||||
run: |
|
||||
CREATOR=$(curl -s "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}" | jq -r '.user.login')
|
||||
ACTIVITY=$(curl -s "https://api.github.com/search/commits?q=author:${CREATOR}+repo:${{ github.repository }}" | jq -r '.total_count')
|
||||
if [ "$ACTIVITY" -eq 0 ]; then
|
||||
echo "::set-output name=is_new::true"
|
||||
else
|
||||
echo "::set-output name=is_new::false"
|
||||
fi
|
||||
|
||||
- name: Count PRs created by user
|
||||
id: count_prs
|
||||
run: |
|
||||
CREATOR=$(curl -s "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}" | jq -r '.user.login')
|
||||
PR_COUNT=$(curl -s "https://api.github.com/search/issues?q=type:pr+is:open+author:${CREATOR}+repo:${{ github.repository }}" | jq -r '.total_count')
|
||||
echo "::set-output name=pr_count::$PR_COUNT"
|
||||
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
id: lint_pr_title
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: marocchino/sticky-pull-request-comment@v2
|
||||
if: always() && (steps.lint_pr_title.outputs.error_message != null)
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
message: |
|
||||
Hey There! and thank you for opening this pull request! 📝👋🏼
|
||||
|
||||
We require pull request titles to follow the [Conventional Commits Spec](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
|
||||
|
||||
Details:
|
||||
|
||||
```
|
||||
${{ steps.lint_pr_title.outputs.error_message }}
|
||||
```
|
||||
|
||||
- if: ${{ steps.lint_pr_title.outputs.error_message == null && steps.check_activity.outputs.is_new == 'false' && steps.count_prs.outputs.pr_count < 2}}
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
message: |
|
||||
Thank you for following the naming conventions for pull request titles! 💚🚀
|
||||
24
.github/workflows/stale.yml
vendored
@ -1,24 +0,0 @@
|
||||
name: 'Mark Stale Issues and PRs'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */8 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-pr-stale: 90
|
||||
days-before-issue-stale: 90
|
||||
days-before-issue-close: 180
|
||||
stale-pr-message: 'This PR has not seen activitiy for a while. It will be closed in 30 days unless further activity is detected.'
|
||||
close-pr-message: 'This PR has been closed because of inactivity.'
|
||||
exempt-pr-labels: 'WIP,on-hold,needs review'
|
||||
exempt-issue-labels: 'WIP,on-hold,needs review,roadmap,assigned,needs triage'
|
||||
14
.gitignore
vendored
@ -31,20 +31,6 @@ yarn-error.log*
|
||||
|
||||
# turbo
|
||||
.turbo
|
||||
.turbo-cookie
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# contentlayer
|
||||
.contentlayer
|
||||
|
||||
# intellij
|
||||
.idea
|
||||
|
||||
# vscode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
55
.gitpod.yml
@ -1,55 +0,0 @@
|
||||
tasks:
|
||||
- init: |
|
||||
npm i &&
|
||||
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:
|
||||
- port: 3000
|
||||
visibility: public
|
||||
onOpen: open-preview
|
||||
- port: 3001
|
||||
visibility: public
|
||||
onOpen: open-preview
|
||||
- port: 9000
|
||||
visibility: public
|
||||
onOpen: ignore
|
||||
- port: 1100
|
||||
visibility: private
|
||||
onOpen: ignore
|
||||
- port: 2500
|
||||
visibility: private
|
||||
onOpen: ignore
|
||||
- port: 54320
|
||||
visibility: private
|
||||
onOpen: ignore
|
||||
|
||||
|
||||
github:
|
||||
prebuilds:
|
||||
master: true
|
||||
pullRequests: true
|
||||
pullRequestsFromForks: true
|
||||
addCheck: true
|
||||
addComment: true
|
||||
addBadge: true
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- aaron-bond.better-comments
|
||||
- bradlc.vscode-tailwindcss
|
||||
- dbaeumer.vscode-eslint
|
||||
- esbenp.prettier-vscode
|
||||
- mikestead.dotenv
|
||||
- unifiedjs.vscode-mdx
|
||||
- GitHub.copilot-chat
|
||||
- GitHub.copilot-labs
|
||||
- GitHub.copilot
|
||||
- GitHub.vscode-pull-request-github
|
||||
- Prisma.prisma
|
||||
- VisualStudioExptTeam.vscodeintellicode
|
||||
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run commitlint -- $1
|
||||
@ -1,16 +0,0 @@
|
||||
#!/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/"
|
||||
|
||||
npx lint-staged
|
||||
@ -1,16 +0,0 @@
|
||||
node_modules
|
||||
.next
|
||||
public
|
||||
**/**/node_modules
|
||||
**/**/.next
|
||||
**/**/public
|
||||
|
||||
*.lock
|
||||
*.log
|
||||
*.test.ts
|
||||
|
||||
.gitignore
|
||||
.npmignore
|
||||
.prettierignore
|
||||
.DS_Store
|
||||
.eslintignore
|
||||
9
.vscode/settings.json
vendored
@ -1,15 +1,10 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit"
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"eslint.validate": ["typescript", "typescriptreact", "javascript", "javascriptreact"],
|
||||
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||
"javascript.preferences.useAliasesForRenames": false,
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"files.eol": "\n",
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true
|
||||
}
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
# General Issues
|
||||
Contact: https://github.com/documenso/documenso/issues/new?assignees=&labels=bug&projects=&template=bug-report.yml
|
||||
|
||||
# Report critical issues privately to let us take appropriate action before publishing.
|
||||
Contact: mailto:security@documenso.com
|
||||
Preferred-Languages: en
|
||||
Canonical: https://documenso.com/.well-known/security.txt
|
||||
45
CLA.md
@ -1,45 +0,0 @@
|
||||
# Documenso Contributors License Agreement
|
||||
|
||||
This Contributors License Agreement ("CLA") is entered into between the Contributor, and Documenso Inc. ("Documenso"), collectively referred to as the "Parties."
|
||||
|
||||
## Background:
|
||||
|
||||
Documenso is an open-source project aimed at providing an open-source document signing platform for all parties. This CLA governs the rights and contributions made by the Contributor to the Documenso project.
|
||||
|
||||
## Agreement:
|
||||
|
||||
**Contributor Grant of License:**
|
||||
|
||||
By submitting code, documentation, or any other materials (collectively, "Contributions") to the Documenso project, the Contributor grants Documenso a perpetual, worldwide, non-exclusive, royalty-free, sublicensable license to use, modify, distribute, and otherwise exploit the Contributions, including any intellectual property rights therein, for the purposes of the Documenso project.
|
||||
|
||||
**Representation of Ownership and Right to Contribute:**
|
||||
|
||||
The Contributor represents that they have the legal right to grant the license stated in Section 1, and that the Contributions do not infringe upon the intellectual property rights of any third party. The Contributor also represents that they have the authority to submit the Contributions on their own behalf or, if applicable, on behalf of their employer or any other entity.
|
||||
|
||||
**Patent Grant:**
|
||||
|
||||
If the Contributions include any method, process, or apparatus that is covered by a patent, the Contributor agrees to grant Documenso a non-exclusive, worldwide, royalty-free license under any patent claims necessary to use, modify, distribute, and otherwise exploit the Contributions for the purposes of the Documenso project.
|
||||
|
||||
**No Implied Warranties or Support:**
|
||||
|
||||
The Contributor acknowledges that the Contributions are provided "as is," without any warranties or support of any kind. Documenso shall have no obligation to provide maintenance, updates, bug fixes, or support for the Contributions.
|
||||
|
||||
**Retention of Contributor Rights:**
|
||||
|
||||
The Contributor retains all right, title, and interest in and to their Contributions. This CLA does not restrict the Contributor from using their own Contributions for any other purpose.
|
||||
|
||||
**Governing Law:**
|
||||
|
||||
This CLA shall be governed by and construed in accordance with the laws of California (CA), without regard to its conflict of laws principles.
|
||||
|
||||
**Entire Agreement:**
|
||||
|
||||
This CLA constitutes the entire agreement between the Parties with respect to the subject matter hereof and supersedes all prior and contemporaneous understandings, agreements, representations, and warranties.
|
||||
|
||||
**Acceptance:**
|
||||
|
||||
By submitting Contributions to the Documenso project, the Contributor acknowledges and agrees to the terms and conditions of this CLA. If the Contributor is agreeing to this CLA on behalf of an entity, they represent that they have the necessary authority to bind that entity to these terms.
|
||||
|
||||
**Effective Date:**
|
||||
|
||||
This CLA is effective as of the date of the first Contribution made by the Contributor to the Documenso project.
|
||||
@ -1,126 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
support@documenso.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
@ -5,39 +5,22 @@ If you plan to contribute to Documenso, please take a moment to feel awesome ✨
|
||||
## Before getting started
|
||||
|
||||
- Before jumping into a PR be sure to search [existing PRs](https://github.com/documenso/documenso/pulls) or [issues](https://github.com/documenso/documenso/issues) for an open or closed item that relates to your submission.
|
||||
- Select an issue from [here](https://github.com/documenso/documenso/issues) or create a new one
|
||||
- Consider the results from the discussion on the issue
|
||||
- Accept the [Contributor License Agreement](https://documen.so/cla) to ensure we can accept your contributions.
|
||||
|
||||
## Taking issues
|
||||
|
||||
Before taking an issue, ensure that:
|
||||
|
||||
- The issue has been assigned the public label
|
||||
- The issue is clearly defined and understood
|
||||
- No one has been assigned to the issue
|
||||
- No one has expressed intention to work on it
|
||||
|
||||
You can then:
|
||||
|
||||
1. Comment on the issue with your intention to work on it
|
||||
2. Begin work on the issue
|
||||
|
||||
Always feel free to ask questions or seek clarification on the issue.
|
||||
- Select and issue from [here](https://github.com/documenso/documenso/issues) or create a new one
|
||||
- Consider the results from the discussion in the issue
|
||||
|
||||
## Developing
|
||||
|
||||
The development branch is <code>main</code>. All pull requests should be made against this branch. If you need help getting started, [join us on Discord](https://documen.so/discord).
|
||||
The development branch is <code>main</code>. All pull request should be made against this branch. If you need help getting started, [join us on Slack](https://join.slack.com/t/documenso/shared_invite/zt-1qwxxsvli-nDyojjt~wakhgBGl9JRl2w).
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your
|
||||
own GitHub account and then
|
||||
[clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||
2. Create a new branch:
|
||||
|
||||
- Create a new branch (include the issue id and something readable):
|
||||
- Create a new branch (include the issue id and somthing readable):
|
||||
|
||||
```sh
|
||||
git checkout -b feat/doc-999-somefeature-that-rocks
|
||||
git checkout -b doc-999-my-feature-or-fix
|
||||
```
|
||||
|
||||
3. See the [Developer Setup](https://github.com/documenso/documenso/blob/main/README.md#developer-setup) for more setup details.
|
||||
@ -45,7 +28,7 @@ The development branch is <code>main</code>. All pull requests should be made ag
|
||||
## Building
|
||||
|
||||
> **Note**
|
||||
> Please ensure you can make a full production build before pushing code or creating PRs.
|
||||
> Please be sure that you can make a full production build before pushing code or creating PRs.
|
||||
|
||||
You can build the project with:
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
# The Documenso Manifest
|
||||
Signing documents is a fundamental building block of private, economic, and government interactions. Access to easy and secure signing to participate in society should therefore be a fundamental right for everyone. The technology to enable this should be accessible and widespread.
|
||||
|
||||
We know that open source is the key to solving this need once and for all to benefit all humankind. Using open source kickstarts innovation by putting the open sharing of ideas and solutions first. With Documenso, we will create an open and globally accessible signing platform to empower users, customers, and developers to fulfill their needs. Documenso is built by and for the global community, listening and implementing what is needed. Being transparent with the code and the processes that use it brings trust and security to the platform.
|
||||
|
||||
We build Documenso for longevity and scale by embracing the capital efficiency and inclusiveness of the Commercial Open Source (COSS) movement. We are building a global commodity for the world.
|
||||
385
README.md
@ -1,310 +1,207 @@
|
||||
<img src="https://github.com/documenso/documenso/assets/13398220/a643571f-0239-46a6-a73e-6bef38d1228b" alt="Documenso Logo">
|
||||
<p align="center" style="margin-top: 120px">
|
||||
<a href="https://github.com/documenso/documenso.com">
|
||||
<img width="250px" src="https://github.com/documenso/documenso/assets/1309312/cd7823ec-4baa-40b9-be78-4acb3b1c73cb" alt="Documenso Logo">
|
||||
</a>
|
||||
|
||||
<h3 align="center">Open Source Signing Infrastructure</h3>
|
||||
|
||||
<p align="center" style="margin-top: 20px">
|
||||
<p align="center">
|
||||
The Open Source DocuSign Alternative.
|
||||
<br>
|
||||
The DocuSign Open Source Alternative.
|
||||
<br />
|
||||
<a href="https://documenso.com"><strong>Learn more »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://documen.so/discord">Discord</a>
|
||||
<a href="https://documen.so/slack">Slack</a>
|
||||
·
|
||||
<a href="https://documenso.com">Website</a>
|
||||
·
|
||||
<a href="https://github.com/documenso/documenso/issues">Issues</a>
|
||||
·
|
||||
<a href="https://documen.so/live">Upcoming Releases</a>
|
||||
·
|
||||
<a href="https://documen.so/roadmap">Roadmap</a>
|
||||
<a href="https://github.com/documenso/documenso/milestones">Roadmap</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://documen.so/discord"><img src="https://img.shields.io/badge/Discord-documen.so/discord-%235865F2" alt="Join Documenso on Discord"></a>
|
||||
<a href="https://documen.so/slack"><img src="https://img.shields.io/badge/Slack-documenso.slack.com-%234A154B" alt="Join Documenso on Slack"></a>
|
||||
<a href="https://github.com/documenso/documenso/stargazers"><img src="https://img.shields.io/github/stars/documenso/documenso" alt="Github Stars"></a>
|
||||
<a href="https://github.com/documenso/documenso/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-AGPLv3-purple" alt="License"></a>
|
||||
<a href="https://github.com/documenso/documenso/pulse"><img src="https://img.shields.io/github/commit-activity/m/documenso/documenso" alt="Commits-per-month"></a>
|
||||
<a href="https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/documenso/documenso">
|
||||
<img alt="open in devcontainer" src="https://img.shields.io/static/v1?label=Dev%20Containers&message=Enabled&color=blue&logo=visualstudiocode" />
|
||||
</a>
|
||||
<a href="CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg" alt="Contributor Covenant"></a>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://github.com/documenso/documenso/assets/13398220/d96ed533-6f34-4a97-be9b-442bdb189c69" style="width: 80%;" />
|
||||
# Documenso 0.9 - Developer Preview
|
||||
|
||||
<div>
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570645-167128ee-3e39-4578-85d2-5394d9a0379c.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570651-0afd12f8-cfe3-49d1-805e-e495af963d91.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570655-328d2279-058d-4a3e-b5c3-5cbd8a1f4e05.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224571617-1f3c2811-c1ac-4d7d-b9b0-4ab183731405.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570322-b2c76ea8-7482-4043-ad97-f1221220c591.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570325-a8055f24-9826-4a23-b116-4fbb0577581a.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224570318-f724bbd9-c394-4bdc-bace-2d78af92de44.png">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://user-images.githubusercontent.com/1309312/224571539-f019b860-f613-4b20-86e8-4437c5784265.png">
|
||||
</div>
|
||||
|
||||
> **Note**
|
||||
> This project is currently under community review and will publish it's first production release soon™.
|
||||
|
||||
## About this project
|
||||
|
||||
Signing documents digitally should be fast and easy and should be the best practice for every document signed worldwide.
|
||||
|
||||
This is technically quite easy today, but it also introduces a new party to every signature: The signing tool providers. While this is not a problem in itself, it should make us think about how we want these providers of trust to work.
|
||||
|
||||
Documenso aims to be the world's most trusted document-signing tool. This trust is built by empowering you to self-host Documenso and review how it works under the hood.
|
||||
|
||||
Join us in creating the next generation of open trust infrastructure.
|
||||
Signing documents digitally is fast, easy and should be best practice for every document signed worldwide. This is technically quite easy today, but it also introduces a new party to every signature: The signing tool providers. While this is not a problem in itself, it should make us think about how we want these providers of trust to work. Documenso aims to be the world's most trusted document signing tool. This trust is built by empowering you to self-host Documenso and review how it works under the hood. Join us in creating the next generation of open trust infrastructure.
|
||||
|
||||
## Recognition
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.producthunt.com/posts/documenso?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-documenso" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=395047&theme=light&period=daily" alt="Documenso - The open source DocuSign alternative | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
<a href="https://www.producthunt.com/posts/documenso?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-documenso" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=395047&theme=light" alt="Documenso - The Open Source DocuSign Alternative. | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
</p>
|
||||
<a href="https://www.producthunt.com/posts/documenso?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-documenso" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=395047&theme=light&period=daily" alt="Documenso - The open source DocuSign alternative | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
<a href="https://www.producthunt.com/posts/documenso?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-documenso" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=395047&theme=light" alt="Documenso - The Open Source DocuSign Alternative. | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
|
||||
## 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.
|
||||
The current project goal is to <b>[release a production ready version](https://github.com/documenso/documenso/milestone/1)</b> for self-hosting as soon as possible. If you want to help making that happen you can:
|
||||
|
||||
- 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.
|
||||
- ⭐ the repository to help us raise awareness.
|
||||
- Spread the word on Twitter that Documenso is working towards a more open signing tool.
|
||||
- Fix or create [issues](https://github.com/documenso/documenso/issues), that are needed for the first production release.
|
||||
- Check out the first source code release in this repository and test it
|
||||
- Tell us what you think in the current [Discussions](https://github.com/documenso/documenso/discussions)
|
||||
- Join the [Slack Channel](https://documen.so/slack) for any questions and getting to know to other community members
|
||||
- ⭐ the repository to help us raise awareness
|
||||
- Spread the word on Twitter, that Documenso is working towards a more open signing tool
|
||||
- Fix or create [issues](https://github.com/documenso/documenso/issues), that are needed for the first production release
|
||||
|
||||
## Contributing
|
||||
|
||||
- To contribute, please see our [contribution guide](https://github.com/documenso/documenso/blob/main/CONTRIBUTING.md).
|
||||
- To contribute please see our [contribution guide](https://github.com/documenso/documenso/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## Contact us
|
||||
# Tech
|
||||
|
||||
Contact us if you are interested in our Enterprise plan for large organizations that need extra flexibility and control.
|
||||
Documenso is built using awesome open source tech including:
|
||||
|
||||
<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>
|
||||
- [Typescript](https://www.typescriptlang.org/)
|
||||
- [Javascript (when necessary)](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
|
||||
- [NextJS (JS Fullstack Framework)](https://nextjs.org/)
|
||||
- [Postgres SQL (Database)](https://www.postgresql.org/)
|
||||
- [Prisma (ORM - Object-relational mapping)](https://www.prisma.io/)
|
||||
- [Tailwind CSS (Styling)](https://tailwindcss.com/)
|
||||
- [Node SignPDF (Digital Signature)](https://github.com/vbuch/node-signpdf)
|
||||
- [React-PDF for viewing PDFs](https://github.com/wojtekmaj/react-pdf)
|
||||
- [PDF-Lib for PDF manipulation](https://github.com/Hopding/pdf-lib)
|
||||
- Check out `/package.json` and `/apps/web/package.json` for more
|
||||
- Support for [opensignpdf (requires Java on server)](https://github.com/open-pdf-sign) is currently planned.
|
||||
|
||||
## Tech Stack
|
||||
# Getting Started
|
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) - Language
|
||||
- [Next.js](https://nextjs.org/) - 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
|
||||
## Requirements
|
||||
|
||||
<!-- - Support for [opensignpdf (requires Java on server)](https://github.com/open-pdf-sign) is currently planned. -->
|
||||
To run Documenso locally you need
|
||||
|
||||
## Local Development
|
||||
- [Node.js (Version: >=18.x)](https://nodejs.org/en/download/)
|
||||
- Node Package Manager NPM - included in Node.js
|
||||
- [PostgreSQL (local or remote)](https://www.postgresql.org/download/)
|
||||
|
||||
### Requirements
|
||||
|
||||
To run Documenso locally, you will need
|
||||
|
||||
- Node.js (v18 or above)
|
||||
- Postgres SQL Database
|
||||
- Docker (optional)
|
||||
|
||||
### Developer Quickstart
|
||||
## Developer Quickstart
|
||||
|
||||
> **Note**: This is a quickstart for developers. It assumes that you have both [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/) installed on your machine.
|
||||
|
||||
Want to get up and running quickly? Follow these steps:
|
||||
|
||||
1. [Fork this repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) to your GitHub account.
|
||||
- [Clone the repository](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||
|
||||
After forking the repository, clone it to your local device by using the following command:
|
||||
```sh
|
||||
git clone https://github.com/documenso/documenso
|
||||
```
|
||||
|
||||
```sh
|
||||
git clone https://github.com/<your-username>/documenso
|
||||
```
|
||||
- Set up your `.env` file using the recommendations in the `.env.example` file.
|
||||
- Run `npm run dx` in the root directory
|
||||
- This will spin up a postgres database and inbucket mail server in docker containers.
|
||||
- Run `npm run dev` in the root directory
|
||||
- Want it even faster? Just use
|
||||
```sh
|
||||
npm run d
|
||||
```
|
||||
|
||||
2. Set up your `.env` file using the recommendations in the `.env.example` file. Alternatively, just run `cp .env.example .env` to get started with our handpicked defaults.
|
||||
That's it! You should now be able to access the app at http://localhost:3000
|
||||
|
||||
3. Run `npm run dx` in the root directory
|
||||
Incoming mail will be available at http://localhost:9000
|
||||
|
||||
- This will spin up a postgres database and inbucket mailserver in a docker container.
|
||||
|
||||
4. Run `npm run dev` in the root directory
|
||||
|
||||
5. Want it even faster? Just use
|
||||
|
||||
```sh
|
||||
npm run d
|
||||
```
|
||||
|
||||
#### Access Points for Your Application
|
||||
|
||||
1. **App** - http://localhost:3000
|
||||
2. **Incoming Mail Access** - http://localhost:9000
|
||||
3. **Database Connection Details**
|
||||
|
||||
- **Port**: 54320
|
||||
- **Connection**: Use your favorite database client to connect using the provided port.
|
||||
|
||||
4. **S3 Storage Dashboard** - http://localhost:9001
|
||||
Your database will also be available on port `54320`. You can connect to it using your favorite database client.
|
||||
|
||||
## Developer Setup
|
||||
|
||||
### Manual Setup
|
||||
Follow these steps to setup documenso on you local machine:
|
||||
|
||||
Follow these steps to setup Documenso on your local machine:
|
||||
|
||||
1. [Fork this repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) to your GitHub account.
|
||||
|
||||
After forking the repository, clone it to your local device by using the following command:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/<your-username>/documenso
|
||||
```
|
||||
|
||||
2. Run `npm i` in the root directory
|
||||
|
||||
3. Create your `.env` from the `.env.example`. You can use `cp .env.example .env` to get started with our handpicked defaults.
|
||||
|
||||
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
|
||||
- NEXT_PRIVATE_SMTP_FROM_ADDRESS
|
||||
|
||||
5. Create the database schema by running `npm run prisma:migrate-dev`
|
||||
|
||||
6. Run `npm run dev` in the root directory to start
|
||||
|
||||
7. Register a new user at http://localhost:3000/signup
|
||||
- [Clone the repository](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||
```sh
|
||||
git clone https://github.com/documenso/documenso
|
||||
```
|
||||
- Run <code>npm i</code> in root directory
|
||||
- Rename <code>.env.example</code> to <code>.env</code>
|
||||
- Set DATABASE_URL value in .env file
|
||||
- You can use the provided test database url (may be wiped at any point)
|
||||
- Or setup a local postgres sql instance (recommended)
|
||||
- Create the database scheme by running <code>db-migrate:dev</code>
|
||||
- Setup your mail provider
|
||||
- Set <code>SENDGRID_API_KEY</code> value in .env file
|
||||
- You need a SendGrid account, which you can create [here](https://signup.sendgrid.com/).
|
||||
- Documenso uses [Nodemailer](https://nodemailer.com/about/) so you can easily use your own SMTP server by setting the <code>SMTP\_\* variables</code> in your .env
|
||||
- Run <code>npm run dev</code> root directory to start
|
||||
- Register a new user at http://localhost:3000/signup
|
||||
|
||||
---
|
||||
|
||||
- Optional: Seed the database using `npm run prisma:seed -w @documenso/prisma` to create a test user and document.
|
||||
- Optional: Create your own signing certificate.
|
||||
- To generate your own using these steps and a Linux Terminal or Windows Subsystem for Linux (WSL), see **[Create your own signing certificate](./SIGNING.md)**.
|
||||
- Optional: Seed the database using <code>npm run db-seed</code> to create a test user and document
|
||||
- Optional: Upload and sign <code>apps/web/resources/example.pdf</code> manually to test your setup
|
||||
|
||||
### Run in Gitpod
|
||||
- Optional: Create your own signing certificate
|
||||
- A demo certificate is provided in `/app/web/resources/certificate.p12`
|
||||
- To generate your own using these steps and a Linux Terminal or Windows Subsystem for Linux (WSL) see **[Create your own signing certificate](#creating-your-own-signing-certificate)**.
|
||||
|
||||
- Click below to launch a ready-to-use Gitpod workspace in your browser.
|
||||
## Updating
|
||||
|
||||
[](https://gitpod.io/#https://github.com/documenso/documenso)
|
||||
- If you pull the newest version from main, using <code>git pull</code>, it may be necessary to regenerate your database client
|
||||
- You can do this by running the generate command in `/packages/prisma`:
|
||||
```sh
|
||||
npx prisma generate
|
||||
```
|
||||
- This is not necessary on first clone.
|
||||
|
||||
### Run in DevContainer
|
||||
# Creating your own signing certificate
|
||||
|
||||
We support DevContainers for VSCode. [Click here to get started.](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/documenso/documenso)
|
||||
For the digital signature of your documents you need a signing certificate in .p12 format (public and private key). You can buy one (not recommended for dev) or use the steps to create a self-signed one:
|
||||
|
||||
### Video walkthrough
|
||||
1. Generate a private key using the OpenSSL command. You can run the following command to generate a 2048-bit RSA key:\
|
||||
<code>openssl genrsa -out private.key 2048</code>
|
||||
|
||||
If you're a visual learner and prefer to watch a video walkthrough of setting up Documenso locally, check out this video:
|
||||
2. Generate a self-signed certificate using the private key. You can run the following command to generate a self-signed certificate:\
|
||||
<code>openssl req -new -x509 -key private.key -out certificate.crt -days 365</code> \
|
||||
This will prompt you to enter some information, such as the Common Name (CN) for the certificate. Make sure you enter the correct information. The -days parameter sets the number of days for which the certificate is valid.
|
||||
3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following command to do this: \
|
||||
<code>openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt</code>
|
||||
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
|
||||
5. Place the certificate <code>/apps/web/resources/certificate.p12</code>
|
||||
|
||||
[](https://youtu.be/Y0ppIQrEnZs)
|
||||
# Docker
|
||||
|
||||
## Docker
|
||||
> We are still working on the publishing of docker images, in the meantime you can follow the steps below to create a production ready docker image.
|
||||
|
||||
We provide a Docker container for Documenso, which is published on both DockerHub and GitHub Container Registry.
|
||||
Want to create a production ready docker image? Follow these steps:
|
||||
|
||||
- DockerHub: [https://hub.docker.com/r/documenso/documenso](https://hub.docker.com/r/documenso/documenso)
|
||||
- GitHub Container Registry: [https://ghcr.io/documenso/documenso](https://ghcr.io/documenso/documenso)
|
||||
- Run `./docker/build.sh` in the root directory.
|
||||
- Publish the image to your docker registry of choice.
|
||||
|
||||
You can pull the Docker image from either of these registries and run it with your preferred container hosting provider.
|
||||
# Deploying - Coming Soon™
|
||||
|
||||
Please note that you will need to provide environment variables for connecting to the database, mailserver, and so forth.
|
||||
- Docker support
|
||||
- One-Click-Deploy on Render.com Deploy
|
||||
|
||||
For detailed instructions on how to configure and run the Docker container, please refer to the [Docker README](./docker/README.md) in the `docker` directory.
|
||||
# Troubleshooting
|
||||
|
||||
## Self Hosting
|
||||
## Support IPv6
|
||||
|
||||
We support a variety of deployment methods, and are actively working on adding more. Stay tuned for updates!
|
||||
|
||||
> Please note that the below deployment methods are for v0.9, we will update these to v1.0 once it has been released.
|
||||
|
||||
### Fetch, configure, and build
|
||||
|
||||
First, clone the code from Github:
|
||||
|
||||
```
|
||||
git clone https://github.com/documenso/documenso.git
|
||||
```
|
||||
|
||||
Then, inside the `documenso` folder, copy the example env file:
|
||||
|
||||
```
|
||||
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!
|
||||
|
||||
Now you can install the dependencies and build it:
|
||||
|
||||
```
|
||||
npm i
|
||||
npm run build:web
|
||||
npm run prisma:migrate-deploy
|
||||
```
|
||||
|
||||
Finally, you can start it with:
|
||||
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
|
||||
This will start the server on `localhost:3000`. For now, any reverse proxy can then do the frontend and SSL termination.
|
||||
|
||||
> If you want to run with another port than 3000, you can start the application with `next -p <ANY PORT>` from the `apps/web` folder.
|
||||
|
||||
### Run as a service
|
||||
|
||||
You can use a systemd service file to run the app. Here is a simple example of the service running on port 3500 (using 3000 by default):
|
||||
|
||||
```bash
|
||||
[Unit]
|
||||
Description=documenso
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Environment=PATH=/path/to/your/node/binaries
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/var/www/documenso/apps/web
|
||||
ExecStart=/usr/bin/next start -p 3500
|
||||
TimeoutSec=15
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Railway
|
||||
|
||||
[](https://railway.app/template/bG6D4p)
|
||||
|
||||
### Render
|
||||
|
||||
[](https://render.com/deploy?repo=https://github.com/documenso/documenso)
|
||||
|
||||
### Koyeb
|
||||
|
||||
[](https://app.koyeb.com/deploy?type=git&repository=github.com/documenso/documenso&branch=main&name=documenso-app&builder=dockerfile&dockerfile=/docker/Dockerfile)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### I'm not receiving any emails when using the developer quickstart.
|
||||
|
||||
When using the developer quickstart, an [Inbucket](https://inbucket.org/) server will be spun up in a docker container that will store all outgoing emails locally for you to view.
|
||||
|
||||
The Web UI can be found at http://localhost:9000, while the SMTP port will be on localhost:2500.
|
||||
|
||||
### Support IPv6
|
||||
|
||||
If you are deploying to a cluster that uses only IPv6, You can use a custom command to pass a parameter to the Next.js start command
|
||||
In case you are deploying to a cluster that uses only IPv6. You can use a custom command to pass a parameter to the NextJS start command
|
||||
|
||||
For local docker run
|
||||
|
||||
@ -326,25 +223,5 @@ containers:
|
||||
- start
|
||||
- --
|
||||
- -H
|
||||
- '::'
|
||||
- "::"
|
||||
```
|
||||
|
||||
### I can't see environment variables in my package scripts.
|
||||
|
||||
Wrap your package script with the `with:env` script like such:
|
||||
|
||||
```
|
||||
npm run with:env -- npm run myscript
|
||||
```
|
||||
|
||||
The same can be done when using `npx` for one of the bin scripts:
|
||||
|
||||
```
|
||||
npm run with:env -- npx myscript
|
||||
```
|
||||
|
||||
This will load environment variables from your `.env` and `.env.local` files.
|
||||
|
||||
## Repo Activity
|
||||
|
||||

|
||||
|
||||
56
SIGNING.md
@ -1,56 +0,0 @@
|
||||
# Creating your own signing certificate
|
||||
|
||||
For the digital signature of your documents you need a signing certificate in .p12 format (public and private key). You can buy one (not recommended for dev) or use the steps to create a self-signed one:
|
||||
|
||||
1. Generate a private key using the OpenSSL command. You can run the following command to generate a 2048-bit RSA key:
|
||||
|
||||
`openssl genrsa -out private.key 2048`
|
||||
|
||||
2. Generate a self-signed certificate using the private key. You can run the following command to generate a self-signed certificate:
|
||||
|
||||
`openssl req -new -x509 -key private.key -out certificate.crt -days 365`
|
||||
|
||||
This will prompt you to enter some information, such as the Common Name (CN) for the certificate. Make sure you enter the correct information. The -days parameter sets the number of days for which the certificate is valid.
|
||||
|
||||
3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following command to do this:
|
||||
|
||||
`openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt`
|
||||
|
||||
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
|
||||
|
||||
5. Place the certificate `/apps/web/resources/certificate.p12` (If the path does not exist, it needs to be created)
|
||||
|
||||
## Docker
|
||||
|
||||
> We are still working on the publishing of docker images, in the meantime you can follow the steps below to create a production ready docker image.
|
||||
|
||||
Want to create a production ready docker image? Follow these steps:
|
||||
|
||||
- cd into `docker` directory
|
||||
- Make `build.sh` executable by running `chmod +x build.sh`
|
||||
- Run `./build.sh` to start building the docker image.
|
||||
- Publish the image to your docker registry of choice (or) If you prefer running the image from local, run the below command
|
||||
|
||||
```
|
||||
docker run -d --restart=unless-stopped -p 3000:3000 -v documenso:/app/data --name documenso documenso:latest
|
||||
```
|
||||
|
||||
Command Breakdown:
|
||||
|
||||
- `-d` - Let's you run the container in background
|
||||
- `-p` - Passes down which ports to use. First half is the host port, Second half is the app port. You can change the first half anything you want and reverse proxy to that port.
|
||||
- `-v` - Volume let's you persist the data
|
||||
- `--name` - Name of the container
|
||||
- `documenso:latest` - Image you have built
|
||||
|
||||
## Deployment
|
||||
|
||||
We support a variety of deployment methods, and are actively working on adding more. Stay tuned for updates!
|
||||
|
||||
## Railway
|
||||
|
||||
[](https://railway.app/template/DjrRRX)
|
||||
|
||||
## Render
|
||||
|
||||
[](https://render.com/deploy?repo=https://github.com/documenso/documenso)
|
||||
36
apps/documentation/.gitignore
vendored
@ -1,36 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/install-state.gz
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
@ -1,36 +0,0 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
|
Before Width: | Height: | Size: 25 KiB |
@ -1,33 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
|
||||
const withNextra = require('nextra')({
|
||||
theme: 'nextra-theme-docs',
|
||||
themeConfig: './theme.config.tsx',
|
||||
});
|
||||
|
||||
module.exports = withNextra(nextConfig);
|
||||
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "@documenso/documentation",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3002",
|
||||
"build": "next build",
|
||||
"start": "next start -p 3002",
|
||||
"lint:fix": "next lint --fix",
|
||||
"clean": "rimraf .next && rimraf node_modules",
|
||||
"copy:pdfjs": "node ../../scripts/copy-pdfjs.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "14.0.3",
|
||||
"nextra": "^2.13.4",
|
||||
"nextra-theme-docs": "^2.13.4",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
import '../styles.css'
|
||||
|
||||
export default function App({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
|
||||
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
{
|
||||
"index": {
|
||||
"title": "Home",
|
||||
"type": "page",
|
||||
"theme": {
|
||||
"layout": "full",
|
||||
"sidebar": false
|
||||
},
|
||||
"display": "hidden"
|
||||
},
|
||||
"app": {
|
||||
"title": "Getting Started",
|
||||
"type": "page"
|
||||
},
|
||||
"faq": {
|
||||
"title": "FAQ",
|
||||
"type": "page"
|
||||
},
|
||||
"local-development": {
|
||||
"title": "Local Development",
|
||||
"type": "page"
|
||||
},
|
||||
"public-api": {
|
||||
"title": "Public API",
|
||||
"type": "page",
|
||||
"href": "/fcc/"
|
||||
},
|
||||
"webhooks": {
|
||||
"title": "Webhooks",
|
||||
"type": "page"
|
||||
},
|
||||
"contributing": {
|
||||
"title": "Contributing Guide",
|
||||
"type": "page"
|
||||
},
|
||||
"---": {
|
||||
"type": "separator"
|
||||
},
|
||||
"GitHub": {
|
||||
"title": "View on GitHub",
|
||||
"href": "https://documen.so/github",
|
||||
"newWindow": true
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
# Getting Started
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"index": {
|
||||
"title": "Get started",
|
||||
"theme": {
|
||||
"sidebar": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,115 +0,0 @@
|
||||
---
|
||||
title: Contributing Guide
|
||||
description: Learn how to contribute to Documenso and become part of our community.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Contributing to Documenso
|
||||
|
||||
If you plan to contribute to Documenso, please take a moment to feel awesome ✨. People like you are what open source is about ♥. Any contributions, no matter how big or small, are highly appreciated 🙏. This guide will help you get started with contributing to Documenso 💻.
|
||||
|
||||
## Before Getting Started
|
||||
|
||||
<Steps>
|
||||
|
||||
### Check the Existing Issues and Pull Requests
|
||||
|
||||
Search the existing [issues](https://github.com/documenso/documenso/issues) to see if someone else reported the same issue. Or, check the [existing PRs](https://github.com/documenso/documenso/pulls) to see if someone else is already working on the same thing.
|
||||
|
||||
### Creating a New Issue
|
||||
|
||||
If there is no issue or PR for the problem you are facing, feel free to create a new issue. Make sure to provide as much detail as possible, including the steps to reproduce the issue.
|
||||
|
||||
### Picking an Existing Issue
|
||||
|
||||
If you pick an existing issue, take into consideration the discussion on the issue.
|
||||
|
||||
### Contributor License Agreement
|
||||
|
||||
Accept the [Contributor License Agreement](https://documen.so/cla) to ensure we can accept your contributions.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Taking Issues
|
||||
|
||||
Before taking an issue, ensure that:
|
||||
|
||||
- The issue has been assigned the public label.
|
||||
- The issue is clearly defined and understood.
|
||||
- No one has been assigned to the issue.
|
||||
- No one has expressed the intention to work on it.
|
||||
|
||||
After that:
|
||||
|
||||
1. Comment on the issue with your intention to work on it.
|
||||
2. Start working on the issue.
|
||||
|
||||
Feel free to ask for help, clarification or guidance if needed. We are here to help you.
|
||||
|
||||
## Developing
|
||||
|
||||
The development branch is `main`, and all pull requests should be made against this branch. Here's how you can get started with developing:
|
||||
|
||||
<Steps>
|
||||
|
||||
### Set Up Documenso Locally
|
||||
|
||||
Check out the [local development](/local-development) guide to set up your local environment.
|
||||
|
||||
### Pick a Task
|
||||
|
||||
Find an issue to work on or create a new one.
|
||||
|
||||
- Before starting to work on an issue, ensure that no one else is working on it. If no one is assigned to the issue, feel free to pick it up by leaving a comment on the issue and asking to get it assigned to you.
|
||||
|
||||
Before creating a new issue, check the existing issues to see if someone else has already reported it.
|
||||
|
||||
### Create a New Branch
|
||||
|
||||
After you're assigned an issue, you can start working on it. Create a new branch for your feature or bug fix.
|
||||
|
||||
When creating a branch, make sure that the branch name:
|
||||
|
||||
- starts with the correct prefix: `feat/` for new features, `fix/` for bug fixes, etc.
|
||||
- includes the issue id you are working on (if applicable).
|
||||
- is descriptive.
|
||||
|
||||
```sh
|
||||
git checkout -b feat/issue-id-your-branch-name
|
||||
|
||||
## Example
|
||||
git checkout -b feat/1234-add-share-button-to-articles
|
||||
```
|
||||
|
||||
In the pull request description, include `references #yyyy` or `fixes #yyyy` to link it to the issue you are working on.
|
||||
|
||||
### Implement Your Changes
|
||||
|
||||
Start working on the issue you picked up and implement the changes. Make sure to test your changes locally and ensure that they work as expected.
|
||||
|
||||
### Open a Pull Request
|
||||
|
||||
After implementing your changes, open a pull request against the `main` branch.
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
If you need help getting started, [join us on Discord](https://documen.so/discord).
|
||||
</Callout>
|
||||
|
||||
## Building
|
||||
|
||||
Before pushing code or creating pull requests, please ensure you can successfully create a successful production build. You can build the project by running the following command in your terminal:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Once the project builds successfully, you can push your code changes or create a pull request.
|
||||
|
||||
<Callout type="info">
|
||||
Remember to run tests and perform any necessary checks before finalizing your changes. As a
|
||||
result, we can collaborate more effectively and maintain a high standard of code quality in our
|
||||
project.
|
||||
</Callout>
|
||||
@ -1 +0,0 @@
|
||||
# FAQ
|
||||
@ -1,78 +0,0 @@
|
||||
export const Wrapper = ({ children }) => {
|
||||
return <div className="p-24">{children}</div>;
|
||||
};
|
||||
|
||||
<Wrapper>
|
||||
|
||||
# Documentation
|
||||
|
||||
Welcome to the official Documenso documentation! This documentation is designed to help you get started with Documenso.
|
||||
|
||||
For users, we'll guide you through setting up your Documenso account, creating and organizing your documents, collaborating with team members, and leveraging our advanced features. You'll learn how to get the most out of Documenso.
|
||||
|
||||
If you're a developer, you'll find detailed information on how to set up your local development environment, work with our API, and utilize webhooks for seamless integration. We'll provide code examples, best practices, and troubleshooting tips to help you effectively incorporate Documenso's features into your applications.
|
||||
|
||||
We aim to make our documentation clear, concise, and easy to navigate. If you have any questions, feedback, or suggestions for improving our documentation, please don't hesitate to reach out to us. We want to make your experience with Documenso as smooth and enjoyable as possible.
|
||||
|
||||
Let's get started!
|
||||
|
||||
## About Documenso
|
||||
|
||||
Signing documents digitally should be fast and easy and should be the best practice for every document signed worldwide.
|
||||
|
||||
This is technically quite easy today, but it also introduces a new party to every signature: The signing tool providers. While this is not a problem in itself, it should make us think about how we want these providers of trust to work.
|
||||
|
||||
Documenso aims to be the world's most trusted document-signing tool. This trust is built by empowering you to self-host Documenso and review how it works under the hood.
|
||||
|
||||
Join us in creating the next generation of open trust infrastructure.
|
||||
|
||||
## Our tech stack:
|
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) - Language
|
||||
- [Next.js](https://nextjs.org/) - 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">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Discord-documen.so/discord-%235865F2"
|
||||
alt="Join Documenso on Discord"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://github.com/documenso/documenso/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/documenso/documenso" alt="Github Stars" />
|
||||
</a>
|
||||
<a href="https://github.com/documenso/documenso/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-AGPLv3-purple" alt="License" />
|
||||
</a>
|
||||
<a href="https://github.com/documenso/documenso/pulse">
|
||||
<img
|
||||
src="https://img.shields.io/github/commit-activity/m/documenso/documenso"
|
||||
alt="Commits-per-month"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/documenso/documenso">
|
||||
<img
|
||||
alt="open in devcontainer"
|
||||
src="https://img.shields.io/static/v1?label=Dev%20Containers&message=Enabled&color=blue&logo=visualstudiocode"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://github.com/documenso/documenso/blob/main/CODE_OF_CONDUCT.md">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg"
|
||||
alt="Contributor Covenant"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</Wrapper>
|
||||
@ -1,7 +0,0 @@
|
||||
{
|
||||
"index": "Home",
|
||||
"quickstart": "Developer Quickstart",
|
||||
"manual": "Manual Setup",
|
||||
"docker": "Docker",
|
||||
"gitpod": "Gitpod"
|
||||
}
|
||||
@ -1,177 +0,0 @@
|
||||
---
|
||||
title: Docker Development
|
||||
description: Set up Documenso using Docker for local development.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Docker
|
||||
|
||||
The following guide will walk you through setting up Documenso using Docker. You can choose between a Docker Compose production setup or a standalone container.
|
||||
|
||||
We provide a Docker container for Documenso, which is published on both DockerHub and GitHub Container Registry.
|
||||
|
||||
- DockerHub: [https://hub.docker.com/r/documenso/documenso](https://hub.docker.com/r/documenso/documenso)
|
||||
- GitHub Container Registry: [https://ghcr.io/documenso/documenso](https://ghcr.io/documenso/documenso)
|
||||
|
||||
You can pull the Docker image from either of these registries and run it with your preferred container hosting provider.
|
||||
|
||||
Please note that you will need to provide environment variables for connecting to the database, mail server, and other services.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure that you have the following installed:
|
||||
|
||||
- Docker
|
||||
- Docker Compose (if using the Docker Compose setup)
|
||||
|
||||
## Option 1: Production Docker Compose Setup
|
||||
|
||||
This setup includes a PostgreSQL database and the Documenso application. You will need to provide your own SMTP details using environment variables.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Download the Docker Compose File
|
||||
|
||||
Download the Docker Compose file from the Documenso repository - [compose.yml](https://raw.githubusercontent.com/documenso/documenso/release/docker/production/compose.yml).
|
||||
|
||||
### Navigate to the `compose.yml` File
|
||||
|
||||
Once downloaded, navigate to the directory containing the `compose.yml` file.
|
||||
|
||||
### Set Up Environment Variables
|
||||
|
||||
Create a `.env` file in the same directory as the `compose.yml` file.
|
||||
|
||||
Then add your SMTP details as well as the following environment variables:
|
||||
|
||||
```bash
|
||||
NEXTAUTH_SECRET="<your-secret>"
|
||||
NEXT_PRIVATE_ENCRYPTION_KEY="<your-key>"
|
||||
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="<your-secondary-key>"
|
||||
NEXT_PUBLIC_WEBAPP_URL="<your-url>"
|
||||
NEXT_PRIVATE_SMTP_TRANSPORT="smtp-auth"
|
||||
NEXT_PRIVATE_SMTP_HOST="<your-host>"
|
||||
NEXT_PRIVATE_SMTP_PORT=<your-port>
|
||||
NEXT_PRIVATE_SMTP_USERNAME="<your-username>"
|
||||
NEXT_PRIVATE_SMTP_PASSWORD="<your-password>"
|
||||
```
|
||||
|
||||
### Update the Volume Binding
|
||||
|
||||
The `cert.p12` file is required to sign and encrypt documents, so you must provide your key file. Update the volume binding in the `compose.yml` file to point to your key file:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /path/to/your/keyfile.p12:/opt/documenso/cert.p12
|
||||
```
|
||||
|
||||
After updating the volume binding, save the `compose.yml` file and run the following command to start the containers:
|
||||
|
||||
```bash
|
||||
docker-compose --env-file ./.env -d up
|
||||
```
|
||||
|
||||
The command will start the PostgreSQL database and the Documenso application containers.
|
||||
|
||||
### Access the Application
|
||||
|
||||
Access the Documenso application by visiting `http://localhost:3000` in your web browser.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Option 2: Standalone Docker Container
|
||||
|
||||
If you prefer to host the Documenso application on a specific container provider, you can use the pre-built Docker image from DockerHub or GitHub's Package Registry. Note that you will need to provide your own database and SMTP host.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Pull the Docker Image
|
||||
|
||||
Pull the Documenso Docker image from DockerHub:
|
||||
|
||||
```bash
|
||||
docker pull documenso/documenso
|
||||
```
|
||||
|
||||
Or, pull the image from GitHub Container Registry:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/documenso/documenso
|
||||
```
|
||||
|
||||
### Run the Docker Container
|
||||
|
||||
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>"
|
||||
-e NEXT_PUBLIC_WEBAPP_URL="<your-next-public-webapp-url>"
|
||||
-e NEXT_PRIVATE_DATABASE_URL="<your-next-private-database-url>"
|
||||
-e NEXT_PRIVATE_DIRECT_DATABASE_URL="<your-next-private-database-url>"
|
||||
-e NEXT_PRIVATE_SMTP_TRANSPORT="<your-next-private-smtp-transport>"
|
||||
-e NEXT_PRIVATE_SMTP_FROM_NAME="<your-next-private-smtp-from-name>"
|
||||
-e NEXT_PRIVATE_SMTP_FROM_ADDRESS="<your-next-private-smtp-from-address>"
|
||||
-v /path/to/your/keyfile.p12:/opt/documenso/cert.p12
|
||||
documenso/documenso
|
||||
```
|
||||
|
||||
Replace the placeholders with the actual values.
|
||||
|
||||
### Access the Application
|
||||
|
||||
Access the Documenso application by visiting the URL you provided for the `NEXT_PUBLIC_WEBAPP_URL` environment variable in your web browser.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
The environment variables listed above are a subset of those available for configuring Documenso. The table below provides a complete list of environment variables and their descriptions.
|
||||
|
||||
| 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). |
|
||||
| `NEXT_PRIVATE_GOOGLE_CLIENT_ID` | The Google client ID for Google authentication (optional). |
|
||||
| `NEXT_PRIVATE_GOOGLE_CLIENT_SECRET` | The Google client secret for Google authentication (optional). |
|
||||
| `NEXT_PUBLIC_WEBAPP_URL` | The URL for the web application. |
|
||||
| `NEXT_PRIVATE_DATABASE_URL` | The URL for the primary database connection (with connection pooling). |
|
||||
| `NEXT_PRIVATE_DIRECT_DATABASE_URL` | The URL for the direct database connection (without connection pooling). |
|
||||
| `NEXT_PRIVATE_SIGNING_TRANSPORT` | The signing transport to use. Available options: local (default) |
|
||||
| `NEXT_PRIVATE_SIGNING_PASSPHRASE` | The passphrase for the key file. |
|
||||
| `NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS` | The base64-encoded contents of the key file will be used instead of the file path. |
|
||||
| `NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH` | The path to the key file, default `/opt/documenso/cert.p12`. |
|
||||
| `NEXT_PUBLIC_UPLOAD_TRANSPORT` | The transport for file uploads (database or s3). |
|
||||
| `NEXT_PRIVATE_UPLOAD_ENDPOINT` | The endpoint for the S3 storage transport (for third-party S3-compatible providers). |
|
||||
| `NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE` | Whether to force path-style URLs for the S3 storage transport. |
|
||||
| `NEXT_PRIVATE_UPLOAD_REGION` | The region for the S3 storage transport (defaults to us-east-1). |
|
||||
| `NEXT_PRIVATE_UPLOAD_BUCKET` | The bucket to use for the S3 storage transport. |
|
||||
| `NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID` | The access key ID for the S3 storage transport. |
|
||||
| `NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY` | The secret access key for the S3 storage transport. |
|
||||
| `NEXT_PRIVATE_SMTP_TRANSPORT` | The transport to send emails (smtp-auth, smtp-api, resend, or mailchannels). |
|
||||
| `NEXT_PRIVATE_SMTP_HOST` | The host for the SMTP server for SMTP transports. |
|
||||
| `NEXT_PRIVATE_SMTP_PORT` | The port for the SMTP server for SMTP transports. |
|
||||
| `NEXT_PRIVATE_SMTP_USERNAME` | The username for the SMTP server for the `smtp-auth` transport. |
|
||||
| `NEXT_PRIVATE_SMTP_PASSWORD` | The password for the SMTP server for the `smtp-auth` transport. |
|
||||
| `NEXT_PRIVATE_SMTP_APIKEY_USER` | The API key user for the SMTP server for the `smtp-api` transport. |
|
||||
| `NEXT_PRIVATE_SMTP_APIKEY` | The API key for the SMTP server for the `smtp-api` transport. |
|
||||
| `NEXT_PRIVATE_SMTP_SECURE` | Whether to force the use of TLS for the SMTP server for SMTP transports. |
|
||||
| `NEXT_PRIVATE_SMTP_FROM_ADDRESS` | The email address for the "from" address. |
|
||||
| `NEXT_PRIVATE_SMTP_FROM_NAME` | The sender name for the "from" address. |
|
||||
| `NEXT_PRIVATE_RESEND_API_KEY` | The API key for Resend.com for the `resend` transport. |
|
||||
| `NEXT_PRIVATE_MAILCHANNELS_API_KEY` | The optional API key for MailChannels (if using a proxy) for the `mailchannels` transport. |
|
||||
| `NEXT_PRIVATE_MAILCHANNELS_ENDPOINT` | The optional endpoint for the MailChannels API (if using a proxy) for the `mailchannels` transport. |
|
||||
| `NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN` | The domain for DKIM signing with MailChannels for the `mailchannels` transport. |
|
||||
| `NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR` | The selector for DKIM signing with MailChannels for the `mailchannels` transport. |
|
||||
| `NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY` | The private key for DKIM signing with MailChannels for the `mailchannels` transport. |
|
||||
| `NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT` | The maximum document upload limit displayed to the user (in MB). |
|
||||
| `NEXT_PUBLIC_POSTHOG_KEY` | The optional PostHog key for analytics and feature flags. |
|
||||
| `NEXT_PUBLIC_DISABLE_SIGNUP` | Whether to disable user signups through the /signup page. |
|
||||
@ -1,10 +0,0 @@
|
||||
---
|
||||
title: Run in Gitpod
|
||||
description: Get started with Documenso in a ready-to-use Gitpod workspace in your browser.
|
||||
---
|
||||
|
||||
# Run in Gitpod
|
||||
|
||||
Click below to launch a ready-to-use Gitpod workspace in your browser.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/documenso/documenso)
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
title: Local development
|
||||
description: Learn how to set up Documenso for local development.
|
||||
---
|
||||
|
||||
# Local development
|
||||
|
||||
There are multiple ways of setting up Documenso for local development. At the moment of writing this documentation, there are 4 ways of running Documenso locally:
|
||||
|
||||
- [Using the developer quickstart](/local-development/quickstart)
|
||||
- [Manually setting up the development environment](/local-development/manual)
|
||||
- [Using the Docker image](/local-development/docker)
|
||||
- [Using Gitpod](/local-development/gitpod)
|
||||
|
||||
Pick the one that fits your needs the best.
|
||||
@ -1,77 +0,0 @@
|
||||
---
|
||||
title: Manual Setup
|
||||
description: Manually set up Documenso on your machine for local development.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Manual Setup
|
||||
|
||||
Follow these steps to set up Documenso on your local machine:
|
||||
|
||||
<Steps>
|
||||
|
||||
### Fork Documenso
|
||||
|
||||
Fork the [Documenso repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) to your GitHub account.
|
||||
|
||||
### Clone Repository
|
||||
|
||||
After forking the repository, clone it to your local device by using the following command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<your-username>/documenso
|
||||
```
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
Run `npm i` in the root directory to install the dependencies required for the project.
|
||||
|
||||
### Set Up Environment Variables
|
||||
|
||||
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
|
||||
NEXT_PRIVATE_SMTP_FROM_ADDRESS
|
||||
```
|
||||
|
||||
Alternatively, you can run `cp .env.example .env` to get started with our handpicked defaults.
|
||||
|
||||
### Create Database Schema
|
||||
|
||||
Create the database schema by running the following command:
|
||||
|
||||
```bash
|
||||
npm run prisma:migrate-dev
|
||||
```
|
||||
|
||||
### Optional: Seed the Database
|
||||
|
||||
Seed the database with test data by running the following command:
|
||||
|
||||
```bash
|
||||
npm run prisma:seed -w @documenso/prisma
|
||||
```
|
||||
|
||||
### Start the Application
|
||||
|
||||
Run `npm run dev` in the root directory to start the application.
|
||||
|
||||
### Access the Application
|
||||
|
||||
Access the Documenso application by visiting `http://localhost:3000` in your web browser.
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Optional: Create your signing certificate. To generate your own using these steps and a Linux
|
||||
Terminal or Windows Subsystem for Linux (WSL), see **[Create your signing
|
||||
certificate](./SIGNING.md)**.
|
||||
</Callout>
|
||||
@ -1,66 +0,0 @@
|
||||
---
|
||||
title: Developer Quickstart
|
||||
description: Quickly set up Documenso on your machine for local development with Docker and Docker Compose.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Developer Quickstart
|
||||
|
||||
<Callout type="info">
|
||||
**Note**: This guide assumes that you have both [docker](https://docs.docker.com/get-docker/) and
|
||||
[docker-compose](https://docs.docker.com/compose/) installed on your machine.
|
||||
</Callout>
|
||||
|
||||
Want to get up and running quickly? Follow these steps:
|
||||
|
||||
<Steps>
|
||||
|
||||
### Fork Documenso
|
||||
|
||||
Fork the [Documenso repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) to your GitHub account.
|
||||
|
||||
### Clone Repository
|
||||
|
||||
After forking the repository, clone it to your local device by using the following command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<your-username>/documenso
|
||||
```
|
||||
|
||||
### Set Up Environment Variables
|
||||
|
||||
Set up your environment variables in the `.env` file using the `.env.example` file as a reference.
|
||||
|
||||
Alternatively, you can run `cp .env.example .env` to get started with our handpicked defaults.
|
||||
|
||||
### Start Database and Mail Server
|
||||
|
||||
Run `npm run dx` in the root directory.
|
||||
|
||||
This will spin up a Postgres database and inbucket mailserver in a docker container.
|
||||
|
||||
### Start the Application
|
||||
|
||||
Run `npm run dev` in the root directory to start the application.
|
||||
|
||||
### Optional: Fasten the Process
|
||||
|
||||
Want it even faster? Just use:
|
||||
|
||||
```sh
|
||||
npm run d
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
### Access Points for the Project
|
||||
|
||||
You can access the following services:
|
||||
|
||||
- Main application - http://localhost:3000
|
||||
- Incoming Mail Access - http://localhost:9000
|
||||
- Database Connection Details:
|
||||
- Port: 54320
|
||||
- Connection: Use your favourite database client to connect to the database.
|
||||
- S3 Storage Dashboard - http://localhost:9001
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"intro": "Intro",
|
||||
"authentication": "Authentication",
|
||||
"versioning": "Versioning",
|
||||
"api-reference": "API Reference"
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
title: 'API Reference'
|
||||
description: 'Reference documentation for the Documenso public API.'
|
||||
---
|
||||
|
||||
# API Reference
|
||||
@ -1,67 +0,0 @@
|
||||
---
|
||||
title: 'API Authentication'
|
||||
description: 'Learn how to create a Documenso API key and authenticate your API requests.'
|
||||
---
|
||||
|
||||
# API Authentication
|
||||
|
||||
Documenso uses API keys for authentication. An API key is a unique token that is generated for each client. The client must provide the key whenever it makes an API call. This way, Documenso can identify the clients making the requests and authorize their access to the API.
|
||||
|
||||
## Creating an API Key
|
||||
|
||||
To create an API key, navigate to the user settings page. Click on your avatar in the top right corner of the dashboard and select "**[User settings](https://app.documenso.com/settings)**" from the dropdown menu.
|
||||
|
||||

|
||||
|
||||
Once you're on the user settings page, navigate to the "**[API Tokens](https://app.documenso.com/settings/tokens)**" tab. The "API Token" page lists your existing keys and enables you to create new ones.
|
||||
|
||||

|
||||
|
||||
To create a new API key, you must:
|
||||
|
||||
- Choose a name (e.g. "zapier-key")
|
||||
- we recommend using a descriptive name that helps you quickly identify the key and its purpose
|
||||
- Choose an expiration date
|
||||
- you can set the key to never expire or choose when to become invalid: 7 days, 1 month, 3 months, 6 months, or 1 year
|
||||
|
||||
After providing the required information, click the "Create token" button to generate the API key.
|
||||
|
||||

|
||||
|
||||
Once you've created the token, Documenso will display the key on the screen. Make sure to copy the key and store it securely. You won't be able to see the key again once you refresh/leave the page.
|
||||
|
||||
## Using the API Key
|
||||
|
||||
To authenticate your API requests, you must include the API key in the `Authorization` request header. The format is `Authorization: api_xxxxxxxxxxxxxxxx`.
|
||||
|
||||
Here's a sample API request using cURL:
|
||||
|
||||
```bash
|
||||
curl --location 'https://app.documenso.com/api/v1/documents?page=1&perPage=1' \
|
||||
--header 'Authorization: api_xxxxxxxxxxxxxxxx'
|
||||
```
|
||||
|
||||
Here's a sample response from the API based on the above cURL request:
|
||||
|
||||
```json
|
||||
{
|
||||
"documents": [
|
||||
{
|
||||
"id": 11,
|
||||
"userId": 2,
|
||||
"teamId": null,
|
||||
"title": "documenso",
|
||||
"status": "PENDING",
|
||||
"documentDataId": "ab2ecm1npk11rt5sp398waf7h",
|
||||
"createdAt": "2024-04-25T11:05:18.420Z",
|
||||
"updatedAt": "2024-04-25T11:05:36.328Z",
|
||||
"completedAt": null
|
||||
}
|
||||
],
|
||||
"totalPages": 1
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
The API key has access to your account and all its resources. Please keep it secure and do not share it with others. If you suspect that your key has been compromised, you can revoke it from the API Tokens page in your user settings.
|
||||
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: 'Public API'
|
||||
description: 'Learn how to interact with your documents programmatically using the Documenso public API.'
|
||||
---
|
||||
|
||||
# Public API
|
||||
|
||||
Documenso provides a public REST API that enables you to interact with your documents programmatically. The API exposes various HTTP endpoints that allow you to perform operations such as:
|
||||
|
||||
- retrieving, uploading, deleting, and sending documents for signing
|
||||
- creating, updating, and deleting recipients
|
||||
- creating, updating, and deleting document fields
|
||||
|
||||
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
|
||||
|
||||
There is also the [Swagger documentation](https://app.documenso.com/api/v1/openapi) available, which provides information about the API endpoints, request parameters, response formats, and authentication methods.
|
||||
|
||||
## Availability
|
||||
|
||||
The API is available to individual users and teams.
|
||||
@ -1,18 +0,0 @@
|
||||
---
|
||||
title: 'API Versioning'
|
||||
description: 'Versioning information for the Documenso public API.'
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
# API Versioning
|
||||
|
||||
Documenso uses API versioning to manage changes to the public API. This allows us to introduce new features, fix bugs, and make other changes without breaking existing integrations.
|
||||
|
||||
<Callout type="info">The current version of the API is `v1`.</Callout>
|
||||
|
||||
The API version is specified in the URL. For example, the base URL for the `v1` API is `https://app.documenso.com/api/v1`.
|
||||
|
||||
We may make changes to the API without incrementing the version number. We will always try to avoid breaking changes, but in some cases, it may be necessary to make changes that are not backward compatible. In these cases, we will increment the version number and provide information about the changes in the release notes.
|
||||
|
||||
Also, we may deprecate certain features or endpoints in the API. When we deprecate a feature or endpoint, we will provide information about the deprecation in the release notes and give a timeline for when the feature or endpoint will be removed.
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"intro": {
|
||||
"title": "Get started",
|
||||
"theme": {
|
||||
"sidebar": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,350 +0,0 @@
|
||||
---
|
||||
title: 'Webhooks'
|
||||
description: 'Learn how to use webhooks to receive real-time notifications about your documents.'
|
||||
---
|
||||
|
||||
# Webhooks
|
||||
|
||||
Webhooks are HTTP callbacks that are triggered by specific events. When the user subscribes to a specific event and that event occurs, the webhook makes an HTTP request to the URL provided by the user. The request can be a simple notification or can carry a payload with more information about the event.
|
||||
|
||||
Some of the common use cases for webhooks include:
|
||||
|
||||
1. **Real-time Data Syncing**: Webhooks provide a way to keep data in sync across different platforms. For example, you can keep your system up-to-date with your Documenso documents by subscribing to events like document creation or signing.
|
||||
2. **Automating Workflows**: They can trigger automated workflows that start when an event occurs. For example, the webhook could trigger an email when a document is signed.
|
||||
3. **Integrating Third-Party Services**: Webhooks can be used to integrate Documenso with third-party services. For example, you could use a webhook to send data to a CRM system when a document is signed.
|
||||
|
||||
Documenso supports Webhooks and allows you to subscribe to the following events:
|
||||
|
||||
- `document.created`
|
||||
- `document.sent`
|
||||
- `document.opened`
|
||||
- `document.signed`
|
||||
- `document.completed`
|
||||
|
||||
## Create a webhook subscription
|
||||
|
||||
You can create a webhook subscription from the user settings page. Click on your avatar in the top right corner of the dashboard and select "**[User settings](https://app.documenso.com/settings)**" from the dropdown menu.
|
||||
|
||||

|
||||
|
||||
Then, navigate to the "**[Webhooks](https://app.documenso.com/settings/webhooks)**" tab, where you can see a list of your existing webhooks and create new ones.
|
||||
|
||||

|
||||
|
||||
Clicking on the "**Create Webhook**" button opens a modal to create a new webhook subscription.
|
||||
|
||||
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`.
|
||||
- Optionally, you can provide a secret key that will be used to sign the payload. This key will be included in the `X-Documenso-Signature` header of the request.
|
||||
|
||||

|
||||
|
||||
After you have filled in the required information, click on the "**Create Webhook**" button to save your subscription.
|
||||
|
||||
The screenshot below illustrates a newly created webhook subscription.
|
||||
|
||||

|
||||
|
||||
You can edit or delete your webhook subscriptions by clicking the "**Edit**" or "**Delete**" buttons next to the webhook.
|
||||
|
||||
## Webhook fields
|
||||
|
||||
The payload sent to the webhook URL contains the following fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
| -------------------------------------------- | --------- | ---------------------------------------------------- |
|
||||
| `event` | string | The type of event that triggered the webhook. |
|
||||
| `payload.id` | number | The id of the document. |
|
||||
| `payload.userId` | number | The id of the user who owns the document. |
|
||||
| `payload.authOptions` | json? | Authentication options for the document. |
|
||||
| `payload.formValues` | json? | Form values for the document. |
|
||||
| `payload.title` | string | The name of the document. |
|
||||
| `payload.status` | string | The current status of the document. |
|
||||
| `payload.documentDataId` | string | The identifier for the document data. |
|
||||
| `payload.createdAt` | datetime | The creation date and time of the document. |
|
||||
| `payload.updatedAt` | datetime | The last update date and time of the document. |
|
||||
| `payload.completedAt` | datetime? | The completion date and time of the document. |
|
||||
| `payload.deletedAt` | datetime? | The deletion date and time of the document. |
|
||||
| `payload.teamId` | number? | The id of the team. |
|
||||
| `payload.documentData.id` | string | The id of the document data. |
|
||||
| `payload.documentData.type` | string | The type of the document data. |
|
||||
| `payload.documentData.data` | string | The data of the document. |
|
||||
| `payload.documentData.initialData` | string | The initial data of the document. |
|
||||
| `payload.Recipient[].id` | number | The id of the recipient. |
|
||||
| `payload.Recipient[].documentId` | number? | The id the document associated with the recipient. |
|
||||
| `payload.Recipient[].templateId` | number? | The template identifier for the recipient. |
|
||||
| `payload.Recipient[].email` | string | The email address of the recipient. |
|
||||
| `payload.Recipient[].name` | string | The name of the recipient. |
|
||||
| `payload.Recipient[].token` | string | The token associated with the recipient. |
|
||||
| `payload.Recipient[].expired` | datetime? | The expiration status of the recipient. |
|
||||
| `payload.Recipient[].signedAt` | datetime? | The date and time the recipient signed the document. |
|
||||
| `payload.Recipient[].authOptions.accessAuth` | json? | Access authentication options. |
|
||||
| `payload.Recipient[].authOptions.actionAuth` | json? | Action authentication options. |
|
||||
| `payload.Recipient[].role` | string | The role of the recipient. |
|
||||
| `payload.Recipient[].readStatus` | string | The read status of the document by the recipient. |
|
||||
| `payload.Recipient[].signingStatus` | string | The signing status of the recipient. |
|
||||
| `payload.Recipient[].sendStatus` | string | The send status of the document to the recipient. |
|
||||
| `createdAt` | datetime | The creation date and time of the webhook event. |
|
||||
| `webhookEndpoint` | string | The endpoint URL where the webhook is sent. |
|
||||
|
||||
## Webhook event payload example
|
||||
|
||||
When an event that you have subscribed to occurs, Documenso will send a POST request to the specified webhook URL with a payload containing information about the event.
|
||||
|
||||
## Example payloads
|
||||
|
||||
Below are examples of the payloads that are sent for each of the supported events. The payloads are sent as JSON data in the body of the POST request.
|
||||
|
||||
Example payload for the `document.created` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_CREATED",
|
||||
"payload": {
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"title": "documenso.pdf",
|
||||
"status": "DRAFT",
|
||||
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"createdAt": "2024-04-22T11:44:43.341Z",
|
||||
"updatedAt": "2024-04-22T11:44:43.341Z",
|
||||
"completedAt": null,
|
||||
"deletedAt": null,
|
||||
"teamId": null
|
||||
},
|
||||
"createdAt": "2024-04-22T11:44:44.779Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
Example payload for the `document.sent` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_SENT",
|
||||
"payload": {
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"title": "documenso.pdf",
|
||||
"status": "PENDING",
|
||||
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"createdAt": "2024-04-22T11:44:43.341Z",
|
||||
"updatedAt": "2024-04-22T11:48:07.569Z",
|
||||
"completedAt": null,
|
||||
"deletedAt": null,
|
||||
"teamId": null,
|
||||
"Recipient": [
|
||||
{
|
||||
"id": 52,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer2@documenso.com",
|
||||
"name": "Signer 2",
|
||||
"token": "vbT8hi3jKQmrFP_LN1WcS",
|
||||
"expired": null,
|
||||
"signedAt": null,
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "VIEWER",
|
||||
"readStatus": "NOT_OPENED",
|
||||
"signingStatus": "NOT_SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
},
|
||||
{
|
||||
"id": 53,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer1@documenso.com",
|
||||
"name": "Signer 1",
|
||||
"token": "HkrptwS42ZBXdRKj1TyUo",
|
||||
"expired": null,
|
||||
"signedAt": null,
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "SIGNER",
|
||||
"readStatus": "NOT_OPENED",
|
||||
"signingStatus": "NOT_SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createdAt": "2024-04-22T11:48:07.945Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
Example payload for the `document.opened` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_OPENED",
|
||||
"payload": {
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"title": "documenso.pdf",
|
||||
"status": "PENDING",
|
||||
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"createdAt": "2024-04-22T11:44:43.341Z",
|
||||
"updatedAt": "2024-04-22T11:48:07.569Z",
|
||||
"completedAt": null,
|
||||
"deletedAt": null,
|
||||
"teamId": null,
|
||||
"Recipient": [
|
||||
{
|
||||
"id": 52,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer2@documenso.com",
|
||||
"name": "Signer 2",
|
||||
"token": "vbT8hi3jKQmrFP_LN1WcS",
|
||||
"expired": null,
|
||||
"signedAt": null,
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "VIEWER",
|
||||
"readStatus": "OPENED",
|
||||
"signingStatus": "NOT_SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
],
|
||||
"documentData": {
|
||||
"id": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"type": "S3_PATH",
|
||||
"data": "9753/xzqrshtlpokm/documenso.pdf",
|
||||
"initialData": "9753/xzqrshtlpokm/documenso.pdf"
|
||||
}
|
||||
},
|
||||
"createdAt": "2024-04-22T11:50:26.174Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
Example payload for the `document.signed` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_SIGNED",
|
||||
"payload": {
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"title": "documenso.pdf",
|
||||
"status": "COMPLETED",
|
||||
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"createdAt": "2024-04-22T11:44:43.341Z",
|
||||
"updatedAt": "2024-04-22T11:52:05.708Z",
|
||||
"completedAt": "2024-04-22T11:52:05.707Z",
|
||||
"deletedAt": null,
|
||||
"teamId": null,
|
||||
"Recipient": [
|
||||
{
|
||||
"id": 51,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer1@documenso.com",
|
||||
"name": "Signer 1",
|
||||
"token": "HkrptwS42ZBXdRKj1TyUo",
|
||||
"expired": null,
|
||||
"signedAt": "2024-04-22T11:52:05.688Z",
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "SIGNER",
|
||||
"readStatus": "OPENED",
|
||||
"signingStatus": "SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createdAt": "2024-04-22T11:52:18.577Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
Example payload for the `document.completed` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "DOCUMENT_COMPLETED",
|
||||
"payload": {
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"authOptions": null,
|
||||
"formValues": null,
|
||||
"title": "documenso.pdf",
|
||||
"status": "COMPLETED",
|
||||
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"createdAt": "2024-04-22T11:44:43.341Z",
|
||||
"updatedAt": "2024-04-22T11:52:05.708Z",
|
||||
"completedAt": "2024-04-22T11:52:05.707Z",
|
||||
"deletedAt": null,
|
||||
"teamId": null,
|
||||
"documentData": {
|
||||
"id": "hs8qz1ktr9204jn7mg6c5dxy0",
|
||||
"type": "S3_PATH",
|
||||
"data": "bk9p1h7x0s3m/documenso-signed.pdf",
|
||||
"initialData": "9753/xzqrshtlpokm/documenso.pdf"
|
||||
},
|
||||
"Recipient": [
|
||||
{
|
||||
"id": 50,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer2@documenso.com",
|
||||
"name": "Signer 2",
|
||||
"token": "vbT8hi3jKQmrFP_LN1WcS",
|
||||
"expired": null,
|
||||
"signedAt": "2024-04-22T11:51:10.055Z",
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "VIEWER",
|
||||
"readStatus": "OPENED",
|
||||
"signingStatus": "SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"documentId": 10,
|
||||
"templateId": null,
|
||||
"email": "signer1@documenso.com",
|
||||
"name": "Signer 1",
|
||||
"token": "HkrptwS42ZBXdRKj1TyUo",
|
||||
"expired": null,
|
||||
"signedAt": "2024-04-22T11:52:05.688Z",
|
||||
"authOptions": {
|
||||
"accessAuth": null,
|
||||
"actionAuth": null
|
||||
},
|
||||
"role": "SIGNER",
|
||||
"readStatus": "OPENED",
|
||||
"signingStatus": "SIGNED",
|
||||
"sendStatus": "SENT"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createdAt": "2024-04-22T11:52:18.277Z",
|
||||
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
|
||||
}
|
||||
```
|
||||
|
||||
## Availability
|
||||
|
||||
Webhooks are available to individual users and teams.
|
||||
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
22
apps/documentation/public/pdf.worker.min.js
vendored
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 49 KiB |
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,20 +0,0 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
export default config;
|
||||
@ -1,49 +0,0 @@
|
||||
import { useConfig } from 'nextra-theme-docs';
|
||||
import type { DocsThemeConfig } from 'nextra-theme-docs';
|
||||
|
||||
const themeConfig: DocsThemeConfig = {
|
||||
logo: <span>Documenso Docs</span>,
|
||||
head: function useHead() {
|
||||
const config = useConfig<{ title?: string; description?: string }>();
|
||||
|
||||
const title = `${config.frontMatter.title} | Documenso Docs` || 'Documenso Docs';
|
||||
const description = config.frontMatter.description || 'The official Documenso documentation';
|
||||
|
||||
return (
|
||||
<>
|
||||
<meta httpEquiv="Content-Language" content="en" />
|
||||
<meta name="title" content={title} />
|
||||
<meta name="og:title" content={title} />
|
||||
<meta name="description" content={description} />
|
||||
<meta name="og:description" content={description} />
|
||||
</>
|
||||
);
|
||||
},
|
||||
project: {
|
||||
link: 'https://documen.so/github',
|
||||
},
|
||||
chat: {
|
||||
link: 'https://documen.so/discord',
|
||||
},
|
||||
docsRepositoryBase: 'https://github.com/documenso/documenso/tree/main/apps/documentation',
|
||||
footer: {
|
||||
text: (
|
||||
<span>
|
||||
{new Date().getFullYear()} ©{' '}
|
||||
<a href="https://documen.so" target="_blank">
|
||||
Documenso
|
||||
</a>
|
||||
.
|
||||
</span>
|
||||
),
|
||||
},
|
||||
primaryHue: 100,
|
||||
primarySaturation: 48.47,
|
||||
useNextSeoProps() {
|
||||
return {
|
||||
titleTemplate: '%s | Documenso Docs',
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default themeConfig;
|
||||
@ -1,27 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
},
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
1
apps/marketing/ambient.d.ts
vendored
@ -1 +0,0 @@
|
||||
declare module '@documenso/tailwind-config';
|
||||
@ -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,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,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,198 +0,0 @@
|
||||
---
|
||||
title: 'Deploying Documenso with Vercel, Supabase and Resend'
|
||||
description: This is the first part 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.
|
||||
authorName: 'Ephraim Atta-Duncan'
|
||||
authorImage: '/blog/blog-author-duncan.jpeg'
|
||||
authorRole: 'Software Engineer Intern'
|
||||
date: 2023-09-08
|
||||
tags:
|
||||
- Open Source
|
||||
- Self Hosting
|
||||
- Tutorial
|
||||
---
|
||||
|
||||
In this article, we'll walk you through how to deploy and self-host Documenso using Vercel, Supabase, and Resend.
|
||||
|
||||
You'll learn:
|
||||
|
||||
- How to set up a Postgres database using Supabase,
|
||||
- How to install SMTP with Resend,
|
||||
- How to deploy your project with Vercel.
|
||||
|
||||
If you don't know what [Documenso](https://documenso.com/) is, it's an open-source alternative to DocuSign, with the mission to create an open signing infrastructure while embracing openness, cooperation, and transparency.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before we start, make sure you have a [GitHub](https://github.com/signup) account. You also need [Node.js](https://nodejs.org/en) and [npm](https://www.npmjs.com/) installed on your local machine (note: you also have the option to host it on a cloud environment using Gitpod for example; that would be another post). If you need accounts on Vercel, Supabase, and Resend, create them by visiting the [Vercel](https://vercel.com/), [Supabase](https://supabase.com/), and [Resend](https://resend.com/) websites.
|
||||
|
||||
Checklist:
|
||||
|
||||
- [ ] Have a GitHub account
|
||||
- [ ] Install Node.js
|
||||
- [ ] Install npm
|
||||
- [ ] Have a Vercel account
|
||||
- [ ] Have a Supabase account
|
||||
- [ ] Have a Resend account
|
||||
|
||||
## Step-by-Step guide to deploying Documenso with Vercel, Supabase, and Resend
|
||||
|
||||
To deploy Documenso, we'll take the following steps:
|
||||
|
||||
1. Fork the Documenso repository
|
||||
2. Clone the forked repository and install dependencies
|
||||
3. Create a new project on Supabase
|
||||
4. Copy the Supabase Postgres database connection URL
|
||||
5. Create a `.env` file
|
||||
6. Run the migration on the Supabase Postgres Database
|
||||
7. Get your SMTP Keys on Resend
|
||||
8. Create a new project on Vercel
|
||||
9. Add Environment Variables to your Vercel project
|
||||
|
||||
So, you're ready? Let’s dive in!
|
||||
|
||||
### Step 1: Fork the Documenso repository
|
||||
|
||||
Start by creating a fork of Documenso on GitHub. You can do this by visiting the [Documenso repository](https://github.com/documenso/documenso) and clicking on the 'Fork' button. (Also, star the repo!)
|
||||
|
||||

|
||||
|
||||
Choose your GitHub profile as the owner and click on 'Create fork' to create a fork of the repo.
|
||||
|
||||

|
||||
|
||||
### Step 2: Clone the forked repository and install dependencies
|
||||
|
||||
Clone the forked repository to your local machine in any directory of your choice. Open your terminal and enter the following commands:
|
||||
|
||||
```bash
|
||||
# Clone the repo using Github CLI
|
||||
gh repo clone [your_github_username]/documenso
|
||||
|
||||
# Clone the repo using Git
|
||||
git clone <https://github.com/[your_github_username]/documenso.git>
|
||||
```
|
||||
|
||||
You can now navigate into the directory and install the project’s dependencies:
|
||||
|
||||
```bash
|
||||
cd documenso
|
||||
npm install
|
||||
```
|
||||
|
||||
### Step 3: Create a new project on Supabase
|
||||
|
||||
Now, let's set up the database.
|
||||
|
||||
If you haven't already, create a new project on Supabase. This will automatically create a new Postgres database for you.
|
||||
|
||||
On your Supabase dashboard, click the '**New project**' button and choose your organization.
|
||||
|
||||
On the '**Create a new project**' page, set a database name of **documenso** and a secure password for your database. Choose a region closer to you, a pricing plan, and click on '**Create new project**' to create your project.
|
||||
|
||||

|
||||
|
||||
### Step 4: Copy the Supabase Postgres database connection URL
|
||||
|
||||
In your project, click the '**Settings**' icon at the bottom left.
|
||||
|
||||
Under the '**Project Settings**' section, click '**Database**' and scroll down to the '**Connection string**' section. Copy the '**URI**' and update it with the password you chose in the previous step.
|
||||
|
||||

|
||||
|
||||
### Step 5: Create a `.env` file
|
||||
|
||||
Create a `.env` file in the root of your project by copying the contents of the `.env.example` file.
|
||||
|
||||
Add the connection string you copied from your Supabase dashboard to the `DATABASE_URL` variable in the `.env` file.
|
||||
|
||||
The `.env` should look like this:
|
||||
|
||||
```bash
|
||||
DATABASE_URL="postgres://postgres:[YOUR-PASSWORD]@db.[YOUR-PROJECT-REF].supabase.co:5432/postgres"
|
||||
```
|
||||
|
||||
### Step 6: Run the migration on the Supabase Postgres Database
|
||||
|
||||
Run the migration on the Supabase Postgres Database using the following command:
|
||||
|
||||
```bash
|
||||
npx prisma migrate deploy
|
||||
```
|
||||
|
||||
### Step 7: Get your SMTP Keys on Resend
|
||||
|
||||
So, you've just cloned Documenso, installed dependencies on your local machine, and set your database using Supabase. Now, SMTP is missing. Emails won't go out! Let's fix it with Resend.
|
||||
|
||||
In the **[Resend](https://resend.com/)** dashboard, click 'Add API Key' to create a key for Resend SMTP.
|
||||
|
||||

|
||||
|
||||
Next, add and verify your domain in the '**Domains**' section on the sidebar. This will allow you to send emails from any address associated with your domain.
|
||||
|
||||

|
||||
|
||||
You can update your `.env` file with the following:
|
||||
|
||||
```jsx
|
||||
SMTP_MAIL_HOST = 'smtp.resend.com';
|
||||
SMTP_MAIL_PORT = '25';
|
||||
SMTP_MAIL_USER = 'resend';
|
||||
SMTP_MAIL_PASSWORD = 'YOUR_RESEND_API_KEY';
|
||||
MAIL_FROM = 'noreply@[YOUR_DOMAIN]';
|
||||
```
|
||||
|
||||
### Step 8: Create a new project on Vercel
|
||||
|
||||
You set the database with Supabase and are SMTP-ready with Resend. Almost there! The next step is to deploy the project — we'll use Vercel for that.
|
||||
|
||||
On your Vercel dashboard, create a new project using the forked project from your GitHub repositories. Select the project among the options and click '**Import**' to start running Documenso.
|
||||
|
||||

|
||||
|
||||
### Step 9: Add Environment Variables to your Vercel project
|
||||
|
||||
In the '**Configure Project**' page, adding the required Environmental Variables is essential to ensure the application deploys without any errors.
|
||||
|
||||
Specifically, for the `NEXT_PUBLIC_WEBAPP_URL` and `NEXTAUTH_URL` variables, you must add `.vercel.app` to your Project Name. This will form the deployment URL, which will be in the format: `https://[project_name].vercel.app`.
|
||||
|
||||
For example, in my case, the deployment URL is `https://documenso-supabase-web.vercel.app`.
|
||||
|
||||

|
||||
|
||||
This is a sample `.env` to deploy. Copy and paste it to auto-populate the fields and click ‘**Deploy.’** Now, you only need to wait for your project to deploy. You’re going live — enjoy!
|
||||
|
||||
```bash
|
||||
DATABASE_URL='postgresql://postgres:typeinastrongpassword@db.njuigobjlbteahssqbtw.supabase.co:5432/postgres'
|
||||
|
||||
NEXT_PUBLIC_WEBAPP_URL='https://documenso-supabase-web.vercel.app'
|
||||
NEXTAUTH_SECRET='something gibrish to encrypt your jwt tokens'
|
||||
NEXTAUTH_URL='https://documenso-supabase-web.vercel.app'
|
||||
|
||||
# Get a Sendgrid Api key here: <https://signup.sendgrid.com>
|
||||
SENDGRID_API_KEY=''
|
||||
|
||||
# Set SMTP credentials to use SMTP instead of the Sendgrid API.
|
||||
SMTP_MAIL_HOST='smtp.resend.com'
|
||||
SMTP_MAIL_PORT='25'
|
||||
SMTP_MAIL_USER='resend'
|
||||
SMTP_MAIL_PASSWORD='YOUR_RESEND_API_KEY'
|
||||
MAIL_FROM='noreply@[YOUR_DOMAIN]'
|
||||
|
||||
NEXT_PUBLIC_ALLOW_SIGNUP=true
|
||||
```
|
||||
|
||||
## Wrapping up
|
||||
|
||||

|
||||
|
||||
Congratulations! 🎉 You've successfully deployed Documenso using Vercel, Supabase, and Resend. You're now ready to create and sign your own documents with your self-hosted Documenso!
|
||||
|
||||
In this step-by-step guide, you learned how to:
|
||||
|
||||
- set up a Postgres database using Supabase,
|
||||
- install SMTP with Resend,
|
||||
- deploy your project with Vercel.
|
||||
|
||||
Over to you! How was the tutorial? If you enjoyed it, [please do share](https://twitter.com/documenso/status/1700141802693480482)! And if you have any questions or comments, please reach out to me on [Twitter / X](https://twitter.com/EphraimDuncan_) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
We're building an open-source alternative to DocuSign and welcome every contribution. Head over to the GitHub repository and [leave us a Star](https://github.com/documenso/documenso)!
|
||||
@ -1,49 +0,0 @@
|
||||
---
|
||||
title: Open Sourcing Documenso's Design
|
||||
description: It's day 1 of our first launch week. We are kicking it off by open sourcing Documenso's design system! Let's go..
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2023-09-25
|
||||
tags:
|
||||
- Design
|
||||
- Open Source
|
||||
- Community
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/designsystem.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Documenso's Design System"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Documenso's Design System ✨
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Our design system is OSS under MIT at [design.documenso.com](https://design.documenso.com)
|
||||
|
||||
Today, we are open sourcing our design system, lovingly crafted by [Thilo](https://twitter.com/thilokonzok). The system is public on Figma and will be available at [design.documenso.com](https://design.documenso.com) from here on out.
|
||||
We are publishing it under the MIT License so everyone can share, remix, and use it as it helps them most.
|
||||
|
||||
We chose to start our first launch week with a design topic to emphasize the role design will play in Documenso's company and community culture. As it is historically difficult to bring together open-source software with great design, this is our first step towards encouraging a more design-driven COSS (Commercial Open Source) movement.
|
||||
|
||||
## Designers Welcome
|
||||
|
||||
We added a designer role in our Discord to create a space for designers to explore and discuss design-related topics of Documenso and signing in general. In the future, we want to foster more coding contributions and start a design culture around the product. As it is much more difficult to incorporate design contributions, we have yet to find a clear plan of what that will look like. I would like to see contributions around stuff we are NOT working on. Designs in that area can inspire and start discussions without the complexities of implementing them immediately — a free-thinking space around everything Documenso. Having a free mandate to design without restriction can create many exciting ideas. Some Ideas worth exploring:
|
||||
|
||||
## Areas for design contributions
|
||||
|
||||
- Explorations of exciting aspects of signing and document handling:
|
||||
- What does signing look like when we no longer have skeuomorphic signatures?
|
||||
- What is signing if we move beyond paper-inspired documents?
|
||||
- What would the government process look like using Documenso?
|
||||
- Solutions Concepts for features further down the roadmap, e.g., Widgets in websites
|
||||
|
||||
These are fascinating ideas for explorative design. They won't be built 1:1 but shape how we think about signing and where it can go, which is even more critical. If you are interested in product design, you are invited to join our [Discord](https://documen.so/discord) and discuss the future of signing design or the future of Documenso's design system. Also let me know what you think on [X (formerly Twitter)](https://x.com/eltimuro).
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,67 +0,0 @@
|
||||
---
|
||||
title: The Early Adopters Plan
|
||||
description: Launch Week Day 4 and we are still early! Early enough for you to get a sweet deal for supporting Documenso's Mission. Join the movement and get a shiny early adopter account in the process.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2023-09-28
|
||||
tags:
|
||||
- Paid Plan
|
||||
- Metrics
|
||||
- Open Startup
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/early.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="XKCD: Bug"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
"Being early is, uh, good." -Unknown
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> 🔔 UPDATE: We launched <a href="https://documen.so/day1" target="_blank">teams</a> and the early adopters plan will be replaced by the new teams pricing as soon as all availible early adopters seats are filled.
|
||||
|
||||
## Community-Driven Development
|
||||
|
||||
As we ramp up hiring and development speed for Documenso, I want to discuss how we plan to build its core version.
|
||||
As we want to be a highly community-driven product, we want to capture the thoughts and ideas of said community in two ways:
|
||||
|
||||
1. Everything we plan (i.e. documen.so/roadmap) and build (i.e. documen.so/repo) is public and open to comments and suggestions from everyone by design. We plan to have discussions, streams, and articles showcasing what we're up to, encouraging feedback and iterations on our plans.
|
||||
2. We're looking for 100 die-hard early adopters to get more deep hands-on feedback. If you want to be among the first to use and help shape Documenso, we have a special offer for you:
|
||||
|
||||
## The Early Adopter Plan
|
||||
|
||||
- All first 100 signups are entitled to the early adopter plan.
|
||||
- The plan includes everything we build in the next 12 months and unlimited<sup>1</sup> signatures
|
||||
- This plan is priced at $30/mo.
|
||||
- No matter what we add, the price is guaranteed for life as a thank you for supporting Documenso's mission<sup>2</sup>. And we plan to add a lot.
|
||||
- This also includes unlimited users<sup>3</sup> as part of the upcoming support for teams.
|
||||
- If you already claimed an early adopter account in the past and canceled, we are happy to reactivate your account with the early adopter pricing. Reach out to support@documenso.com
|
||||
|
||||
## Being an Early Adopter
|
||||
|
||||
Being eligible for the early adopter plan has no formal requirements like giving feedback or being active in the community. In good faith, we assume you sign the Documenso Supporter Pledge to be part of this. And if you want to use the newest version quietly, that's fine, too. Everything the die-hard community brings up will be carefully considered and prioritized <sup>4</sup>. Also, there will obviously be limited edition merch available for the first 100.
|
||||
Documenso currently runs the community reviewed 0.9.1 version. Getting from here to the globally loved and adopted signing tool we all deserve will take a lot of work, and we want you on board to help us create it. Join us in shaping the future of open signing and having fun doing it. [Malfunction Mania](https://documenso.com/blog/malfunction-mania) and releasing 1.0 will go a long way.
|
||||
|
||||
## Extending our open metrics
|
||||
|
||||
As part of our ongoing effort to be open and transparent in our doing, we are adding "Early Adopters" to our [/open page](https://documenso.com/open) page. After we exceed the early adopter slots, this metric will transition to "Customers". When no more early adopter seats can be claimed, the early adopter plan will transition to a standard paid plan. It will still be priced at $30/mo., but will no longer include upcoming features or unlimited seats.
|
||||
|
||||
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] Excluding signatures, we have to pay for i.e. third-party QES
|
||||
|
||||
[2] The Documenso Manifest
|
||||
|
||||
[3] Within reason. If you are unsure what that means, feel free to contact hi@documenso.com. But it should be fine if you don't plan to onboard a huge enterprise.
|
||||
|
||||
[4] We won't be able to build everything everyone asks for. But we firmly plan to listen and build in a way everyone's requirements are met as well as possible.
|
||||
@ -1,28 +0,0 @@
|
||||
---
|
||||
title: Jan 10th Email Provider Security Incident
|
||||
description: On January 10th, 2022, we were notified by our email provider that they had experienced a security incident.
|
||||
authorName: 'Lucas Smith'
|
||||
authorImage: '/blog/blog-author-lucas.png'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-01-17
|
||||
tags:
|
||||
- Security
|
||||
---
|
||||
|
||||
On January 10th, 2024 we were notified by our email provider that a security incident had occurred. This security incident which had started on January 7th led to a bad actor obtaining access to their database which contains ours and other customer’s data.
|
||||
|
||||
We understand that during this security incident the following has been accessed:
|
||||
|
||||
- Email addresses.
|
||||
- Metadata on emails sent excluding the email body.
|
||||
|
||||
While the incident is unfortunate we are pleased with the remediation and the processes that our email provider has put in place to help avoid this kind of situation in the future. Since the incident, our provider has rectified the issue and has engaged a security company to conduct an exhaustive investigation and to help improve their security posture moving forward.
|
||||
|
||||
We remain steadfast in our commitment to our current email provider, and will not be taking any further action with relation to changing providers.
|
||||
|
||||
We are now working with our legal counsel to ensure that we provide the appropriate notice to all our customers in each jurisdiction. If you have any further questions on this incident please feel free to contact our support team at [support@documenso.com](mailto:support@documenso.com).
|
||||
|
||||
We appreciate your ongoing support in this matter.
|
||||
|
||||
You can read more on the incident on our providers blog post below:
|
||||
[https://resend.com/blog/incident-report-for-january-10-2024](https://resend.com/blog/incident-report-for-january-10-2024)
|
||||
@ -1,64 +0,0 @@
|
||||
---
|
||||
title: Launch Week II - Day 1 - Teams
|
||||
description: Teams for Documenso are here. And they come free for early adopters!
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-02-26
|
||||
tags:
|
||||
- Launch Week
|
||||
- Teams
|
||||
- Early Adopter Perks
|
||||
---
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/12a85ec7-20bb-4813-9714-e4da42c9cfba"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
> TLDR; Docucmenso now supports teams that share documents, templates and a team mail address. Early Adopter get UNLIMITED<sup>1</sup> Users.
|
||||
|
||||
## Kicking off Launch Week II - "Connected"
|
||||
|
||||
The day has come! Roughly 5 months after kicked off our first launch week with open sourcing our design and Malfunction Mania, Launch Week #2 is here 🎉 This Launch Week's theme is "connected", since this is all about connecting humans, machines and documents.
|
||||
|
||||
Working with documents and getting that signature is a team sport. This is why we are kicking it off today with a very long-awaited feature: Documenso now supports teams!
|
||||
|
||||
## Introducing Teams for Documenso
|
||||
|
||||
You can now create teams next to your personal account: Simply invite your colleagues, and you can include everyone you like in working with your documents. With teams, you can:
|
||||
|
||||
- Send unlimited signature requests with unlimited recipients
|
||||
- Create, view, edit and sign documents owned by the team
|
||||
- Define a dedicated team email, to receive signing requests into a team inbox for the owner to sign
|
||||
- Manage team roles: Member (Create+Edit), Managers (+Manage Team Members), Owner (+Transfer Team +Delete Team + Sign Documents sent to team email)
|
||||
|
||||
## Pricing
|
||||
|
||||
Together with Teams, we are announcing the new teams pricing:
|
||||
|
||||
- $10 per seat per month
|
||||
- 5 seats minimum
|
||||
- You can add seats dynamically as needed
|
||||
|
||||
This pricing will take effect, as soon as the early adopter seats run out. Want to check out teams: [https://documen.so/teams](https://documen.so/teams).
|
||||
|
||||
## Early Adopter Perks
|
||||
|
||||
There is one more point on pricing I have been looking forward to for a long time:
|
||||
|
||||
All early adopter plans now include **UNLIMITED teams and users**<sup>1</sup> . We appreciate your support so far very much, and I'm happy to announce this first of more early adopter perks to come. We have roughly 48 early adopter plans left, so if you plan to onboard your team, now is a great time to [grab your early adopter seat.](https://documen.so/claim-early-adopters-plan)
|
||||
|
||||
We are eager to hear from all teams users how you like this addition and what we can add to make it even better. Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here, and we would love to hear from you :)
|
||||
|
||||
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 1! Teams just dropped. Check it out https://documen.so/day1 🚀"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
|
||||
\
|
||||
[1] Within reason. If you are unsure what that means, feel free to contact hi@documenso.com and ask for clarification if it's more than 100.
|
||||
@ -1,76 +0,0 @@
|
||||
---
|
||||
title: Launch Week II - Day 2 - Templates
|
||||
description: Templates help you prepare regular documents faster. And you can share them with your team!
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-02-27
|
||||
tags:
|
||||
- Launch Week
|
||||
- Templates
|
||||
---
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/c9504db1-26b7-4033-88ed-a95cabd02e92"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
> TLDR; You can now reuse documents via templates. More field types coming soon as well.
|
||||
|
||||
## Introducing Templates
|
||||
|
||||
It's day 2 of Launch Week, everybody 🙌 After introducing [Teams](https://documenso.com/blog/launch-week-2-day-1) yesterday, today we are looking at making Documenso faster for daily use:
|
||||
We are launching templates for Documenso! Templates are an easy way to reuse documents you send out often with just a few clicks. With templates, you can:
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/quickfill.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Template recipients quick fill view"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Quickly fill out recipients, when creating from a template
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
- Save often-uploaded documents for reuse
|
||||
- Pre-define fields, so you just have to send the document
|
||||
- Quickly fill out recipients and roles for new documents
|
||||
- Share templates with your team to make working together even easier
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/template.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Create from template view"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
POV: You are a diligent german and create custom receipts with Documenso
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Pricing
|
||||
|
||||
Templates are **included in all Documenso Plans!** That includes our free tier: The limit of 5 documents per month still applies, but you are free to reach it with less friction using templates. Sharing templates with other users is only possible with the teams plan. If you want to share templates with people not in your team, we might have something coming up later this week 👀
|
||||
|
||||
## What's Next for Templates
|
||||
|
||||
We have a lot of great stuff coming up for templates as well:
|
||||
|
||||
- More Field Types are in the pipeline
|
||||
- Sharing Templates Externally 👀
|
||||
|
||||
Check out templates [here](https://documen.so/templates) and let us know what you think and what we can improve. Which field types are you missing? Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
|
||||
|
||||
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 2! They just launched templates, and I'm pumped 🎉🚀🚀🚀. Check it out https://documen.so/day2"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,53 +0,0 @@
|
||||
---
|
||||
title: Launch Week II - Day 3 - API
|
||||
description: Documenso's mission is to create a plattform developers all around the world can build upon. Today we are releasing the first version of our public API, included in all plans!
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-02-28
|
||||
tags:
|
||||
- Launch Week
|
||||
- API
|
||||
---
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/cb74d6cb-a127-4cac-a166-ad6b56c6140d"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
> TLDR; The public API is now availible for all plans.
|
||||
|
||||
## Introducing the public Documenso API
|
||||
|
||||
Launch. Week. Day. 3 🎉 Documenso's mission is to create a platform that developers all around the world can build upon. Today we are releasing the first version of our public API, and we are pumped. Since this is the first version, we focused on the basics. With the new API you can:
|
||||
|
||||
- Get Documents (Individual or all Accessible)
|
||||
- Upload Documents
|
||||
- Delete Documents
|
||||
- Create Documents from Templates
|
||||
- Trigger Sending Documents for Singing
|
||||
|
||||
You can check out the detailed API documentation here:
|
||||
|
||||
> API DOCUMENTATION: [https://app.documenso.com/api/v1/openapi](https://app.documenso.com/api/v1/openapi)
|
||||
|
||||
## Pricing
|
||||
|
||||
We are building Documenso to be an open and extendable platform; therefore the API is included in all current plans. The API is authenticated via auth tokens, which every user can create at no extra cost, as can teams. Existing limits still apply (i.e., the number of included documents for the free plan). While we don't have all the details yet, we don't intend to price the API usage in itself (rather the accounts using it) since we want you to build on Documenso without being smothered by API costs.
|
||||
|
||||
> Try the API here for free: [https://documen.so/api](https://documen.so/api)
|
||||
|
||||
## What's next for the API
|
||||
|
||||
You tell us. This is by far the most requested feature, so we would like to hear from you. What should we add? How can we integrate even better?
|
||||
|
||||
Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
|
||||
|
||||
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 3! The public API is here 👀 Check it out https://documen.so/day3"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,63 +0,0 @@
|
||||
---
|
||||
title: Launch Week II - Day 4 - Webhooks and Zapier
|
||||
description: If you want to integrate Documenso without fiddling with the API, we got you as well. You can now integrate Documenso via Zapier, included in all plans!
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-02-29
|
||||
tags:
|
||||
- Launch Week
|
||||
- Zapier
|
||||
- Webhooks
|
||||
---
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/3b60789d-8d27-4c66-ae5c-179e33c2e3e6"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
> TLDR; Zapier Integration is now available for all plans.
|
||||
|
||||
## Introducing Zapier for Documenso
|
||||
|
||||
Day 4 🥳 Yesterday we introduced our [public API](https://documen.so/day3) for developers to build on Documenso. If you are not a developer or simple want a quicker integration this is for you: Documenso now support Zapier Integrations! Just connect your Documenso account via a simple login flow with Zapier and you will have access to Zapier's universe of integrations 💫 The integration currently supports:
|
||||
|
||||
- Document Created ([https://documen.so/zapier-created](https://documen.so/zapier-created))
|
||||
- Document Sent ([Chttps://documen.so/zapier-sent](https://documen.so/zapier-sent))
|
||||
- Document Opened ([https://documen.so/zapier-opened](https://documen.so/zapier-opened))
|
||||
- Document Signed ([https://documen.so/zapier-signed](https://documen.so/zapier-signed))
|
||||
- Document Completed ([https://documen.so/zapier-completed](https://documen.so/zapier-completed))
|
||||
|
||||
> ⚡️ You can create your own Zaps here: https://zapier.com/apps/documenso/integrations
|
||||
|
||||
Each event comes with extensive meta-data for you to use in Zapier. Missing something? Reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord). We're always here and would love to hear from you :)
|
||||
|
||||
## Also Introducing for Documenso: Webhooks
|
||||
|
||||
To build the Zapier Integration, we needed a good webhooks concept, so we added that as well. Together with your Zaps, you can also now create customer webhooks in Documenso. You can try webhooks here for free: [https://documen.so/webhooks](https://documen.so/webhooks)
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/hooks.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Webhooks UI"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Create unlimited custom webhooks with each plan.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Pricing
|
||||
|
||||
Just like the API, we consider the Zapier integration and webhooks part of the open Documenso platform. Zapier is **available for all Documenso plans**, including free! [Login now](https://documen.so/login) to check it out.
|
||||
|
||||
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 4! Documenso now supports @Zapier 🤯 https://documen.so/day4"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,61 +0,0 @@
|
||||
---
|
||||
title: Launch Week II - Day 5 - Documenso Profiles
|
||||
description: Documenso profiles allow you to send signing links to people so they can sign anytime and see who you are. Documenso Profile Usernames can be claimed starting today. Long ones free, short ones paid. Profiles will launch as soon as they are shiny.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-03-01
|
||||
tags:
|
||||
- Launch Week
|
||||
- Profiles
|
||||
---
|
||||
|
||||
<video
|
||||
id="vid"
|
||||
width="100%"
|
||||
src="https://github.com/documenso/design/assets/1309312/89643ae2-2aa9-484c-a522-a0e35097c469"
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
></video>
|
||||
|
||||
> TLDR; Documenso profiles allow you to send signing links to people so they can sign anytime and see who you are. Documenso Profile Usernames can be claimed starting today. Long ones free, short ones paid. Profiles launch as soon as they are shiny.
|
||||
|
||||
## Introducing Documenso Profile Links
|
||||
|
||||
Day 5 - The Finale 🔥
|
||||
|
||||
Signing documents has always been between humans, and signing something together should be as frictionless as possible. It should also be async, so you don't force your counterpart to jog to their device to send something when you are ready. Today we are announcing the new Documenso Profiles:
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/profile.png"
|
||||
width="1260"
|
||||
height="813"
|
||||
alt="Timur's Documenso Profile"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Async > Sync: Add public templates to your Documenso Link and let people sign whenever they are ready.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
Documenso profiles work with your existing templates. You can just add them to your public profile to let everyone with your link sign them. With profiles, we want to bring back the human aspect of signing.
|
||||
|
||||
By making profiles public, you can always access what your counterparty offers and make them more visible in the process. Long-term, we plan to add more to profiles to help you ensure the person you are dealing with is who they claim to be. Documenso wants to be the trust layer of the internet, and we want to start at the very fundamental level: The individual transaction.
|
||||
|
||||
Profiles are our first step towards bringing more trust into everything, simply by making the use of signing more frictionless. As there is more and more content of questionable origin out there, we want to support you in making it clear what you send out and what not.
|
||||
|
||||
## Pricing and Claiming
|
||||
|
||||
Documenso profile username can be claimed starting today. Documenso profiles will launch as soon as we are happy with the details ✨
|
||||
|
||||
- Long usernames (6 characters or more) come free with every account, e.g. **documenso.com/u/timurercan**
|
||||
- Short usernames (5 characters or fewer) or less require any paid account ([Early Adopter](https://documen.so/claim-early-adopters-plan), [Teams](https://documen.so/teams) or Enterprise): **e.g., documenso.com/u/timur**
|
||||
|
||||
You can claim your username here: [https://documen.so/claim](https://documen.so/claim)
|
||||
|
||||
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 5! You can now claim your username for the upcoming profile links 😮 https://documen.so/day5"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,115 +0,0 @@
|
||||
---
|
||||
title: Moving from Linear to GitHub & LIVE Roadmap 2.0
|
||||
description: We are leaving linear and are going all in on GitHub. Here is how we do it.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-01-10
|
||||
tags:
|
||||
- GitHub
|
||||
- Backlog
|
||||
- Roadmap
|
||||
---
|
||||
|
||||
# From Linear to GitHub
|
||||
|
||||
> TLDR; We are leaving Linear and are using only GitHub going forward. We no longer communicate feature timelines, only what we are working on and what's next.
|
||||
|
||||
If you follow us, you know we have been in full-on build mode. We are building, the community is building, it's great. Building is our daily business, so we think a lot about improving our approach to doing it.
|
||||
Our most recent approach is to reduce the number of tools and platforms we use. Every tool we use
|
||||
|
||||
- Reduces the average time you spend on the tool
|
||||
- Reduces your focus
|
||||
- Increases mental load to keep all points of interest in mind
|
||||
|
||||
We thought about where we spend the most time, and hardly surprising: it's GitHub. Not only do we spend a lot of time there, but we also WANT to spend a lot of time there because:
|
||||
|
||||
- It's where the community contributes, and we are all about community
|
||||
- It's where we show the world what we are working on
|
||||
|
||||
# The old structure
|
||||
|
||||
So far, we have been using Linear for our Backlog/ Task Management and synced issues we want to showcase or work on with the community via synclinear.com. Not only did we have our development issues there, but since
|
||||
we have our own resident founding designer, we created a proper design backlog to structure our design workflows.
|
||||
|
||||
# The new structure
|
||||
|
||||
We moved everything to GitHub once we realized our focus was already there. This has a few key benefits:
|
||||
|
||||
- Reducing dilution of attention and time: You can hang out on GitHub without risk of missing much
|
||||
- Putting different aspects of Documenso close to each other: Development, Design, Community
|
||||
- Keep long-term, niche, and very abstract issues out of the main repo so we don't get desensitized by large issue numbers
|
||||
|
||||
To achieve this, we created a few GitHub repositories to host issues, with the main repository remaining the central point of interest, especially for the community.
|
||||
|
||||
## 1. Main Repository - Day to day Issues and the shorter-term roadmap (LIVE Roadmap 2.0)
|
||||
|
||||
> [github.com/documenso/documenso](https://github.com/documenso/documenso)
|
||||
|
||||
Apart from the source code of the Documenso app and website, the main repo houses issues raised by the community and issues where we invite the community to participate.
|
||||
With the overhauling of our issue management, we are also updating our progress communication. While the software and product development process is highly complex,
|
||||
we try to give as much insight into what we do as possible. To that end, we went through 3 phases, three being what we do now.
|
||||
|
||||
1. **One extensive roadmap**: Initially we had one roadmap and were (very) slowly checking off boxes there (via a "Roadmap" milestone). While this is easy, it's also pretty imprecise and not practical as the project grows
|
||||
2. **Estimated releases per quarter**: To give better guidance, we tried communicating our goals for the quarter; a pretty big window we thought we could roughly "hit". While the idea of not being too detailed was good, it is tough to estimate when some significant things are done if you do a lot of minor/ other things in parallel,
|
||||
like working with the community and tuning things you go. Hitting time targets is tricky because there may be better things to do than sticking to that time target. This is always much easier to grasp for the people closely involved. The fallacy is to assume the thing you plan for exists in a vacuum.
|
||||
3. Since we do not want to limit ourselves in choosing the most effective course but still give some insight into what's going on and what's coming up, we updated the live roadmap [https://documen.so/live](https://documen.so/live). It now shows what we are currently working on and what we plan on doing next. We do not provide
|
||||
a specific timeline anymore since we couldn't even if we wanted to. Of course, we set our short-term goals based on what's best for the community. We give updates on the issues being worked on as well as possible.
|
||||
|
||||
## 2. Public Backlog - The longer-term roadmap
|
||||
|
||||
> [github.com/documenso/backlog](https://github.com/documenso/backlog)
|
||||
|
||||
The public backlog houses everything we want to build eventually. We do not provide a specific timeline of when that might happen. If we decide against something, it will be removed from the public backlog, as we consider this our long-term vision for Documenso. If you are interested in something on the roadmap, comment on the issue or post on Discord. This helps us gauge interest in specific features.
|
||||
**Issues in the public backlog are not** available to be worked on. For issues to work on, please check the main repository issues. The issues found here are scoped broader since they are not meant for immediate execution but rather give a sense of where Documenso is going and what we consider part of our domain.
|
||||
|
||||
## 3. Internal Backlog
|
||||
|
||||
> github.com/documenso/backlog-internal
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/gh1.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="GitHub: Development Board"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Our internal Kanban for development
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
This serves as the direct replacement for our Linear backlog. Here, we manage issues that are either too small or short-term for inclusion in the long-term roadmap, yet too specialized or fundamental to be integrated into the main repository. Our development Kanban board is implemented using a GitHub project.
|
||||
|
||||
## 4. Internal Design Backlog
|
||||
|
||||
> github.com/documenso/design-internal
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/gh2.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="GitHub: Design Board"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Our internal Kanban for design
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
This is the design equivalent of the internal backlog. The internal design backlog houses our design projects that include the exploration of new features, detailed UI designs, and improving the platform overall.
|
||||
It's similar to the Kanban board for the development backlog.
|
||||
|
||||
## 5. Public Design Repository
|
||||
|
||||
> [github.com/documenso/backlog-design](https://github.com/documenso/design)
|
||||
|
||||
While the internal design backlog also existed in Linear, the public design repository is new. Since designing in the open is tricky, we opted to publish the detailed design artifacts with the corresponding feature instead.
|
||||
We already have design.documenso.com housing our general design system. Here, we will publish the specifics of how we applied this to each feature. We will publish the first artifacts here soon, what may be in the cards can be found on the [LIVE Roadmap](https://documen.so/live).
|
||||
|
||||
Feel free to connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here to help and would love to hear from you :)
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@ -1,75 +0,0 @@
|
||||
---
|
||||
title: The 🔴 LIVE Roadmap
|
||||
description: It's the Launch Week Day finale, Day 5! We are going out with a bang and introducing the 🔴 LIVE roadmap, featuring our next Product Hunt Launch - Free Singleplayer Documenso - Sign without creating an account!
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2023-09-29
|
||||
tags:
|
||||
- Free Plan
|
||||
- Launch
|
||||
- Roadmap
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/roadmap.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="XKCD: Bug"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
"Being early is, uh, good." -Unknown
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; We are launching a [🔴 LIVE roadmap](https://documen.so/launches), that gets updated regularly.\
|
||||
> First upcoming launch: A free single signer experience.
|
||||
|
||||
## The Road Ahead
|
||||
|
||||
It's been quite a week, launching our [design system](https://documenso.com/blog/design-system), [kicking of a Malfunction Mania](https://documenso.com/blog/malfunction-mania), a [shiny new contributor perk](https://documenso.com/blog/shop) and our [early adopter deal](https://documenso.com/blog/early-adopters). After discussing Version 1.0 a lot, we want to close the week by looking ahead. As an open company, we want transparency about what we are working on and what to expect next. Especially for our Early Adopters, we want to paint a clear picture of what to expect in the near term.
|
||||
|
||||
Communicating software development progress and goals is historically tricky because of it's complex nature. Exact release dates are notoriously unreliable; if they are not, they force a particular style of development, forcing the team to make tradeoffs on scope and quality.
|
||||
|
||||
To give an appropriate insight into our work, we are launching our new [🔴 LIVE roadmap](https://documen.so/launches) today:
|
||||
|
||||
- A List of quarterly development and feature goals
|
||||
- That gets updated regularly (bi-weekly)
|
||||
- Has up-to-date insights from the team on where we stand
|
||||
|
||||
**While there are some great features planned, one stands out: Single Player Mode!**
|
||||
|
||||
## Announcing Documenso Singleplayer Mode
|
||||
|
||||
<a href="https://www.producthunt.com/products/documenso" target="_blank">
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/sp5.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center font-bold">
|
||||
🚨 We are going back to Product Hunt! Are you ready, player one?
|
||||
</figcaption>
|
||||
</figure>
|
||||
</a>
|
||||
|
||||
Single Player Mode will be a free, loginless signing experience for single signers. If you hate creating an account to sign a single, once-in-a-while-document yourself as much as we do, we've got you. Our new free tier will accompany Singleplayer. While you don't HAVE to create an account to sign sth. quickly, you can. A free tier Documenso Account will give you the following:
|
||||
|
||||
- A place to store all your sent and received Documenso-signed documents
|
||||
- Free forever
|
||||
- Unlimited recipients
|
||||
- 5 free signatures per month (for now, excluding third party types like QES)
|
||||
- The use of templates, as soon as we [release](https://documen.so/launches) them
|
||||
|
||||
Singleplayer will launch in the first half of October, shortly after the release of 1.0, **[ON PRODUCT HUNT!](https://www.producthunt.com/products/documenso)** That's right, we are going back to Product Hunt to kick of this new phase of Documenso and you are invited to join us once again :)
|
||||
|
||||
**[Subscribe on PH](https://www.producthunt.com/products/documenso)** to be notified when we launch.
|
||||
|
||||
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,57 +0,0 @@
|
||||
---
|
||||
title: Announcing Malfunction Mania
|
||||
description: Launch Week Day 2 Y'all! We're getting ready to release Documenso 1.0! Join in on the fun of making sure the open-source alternative to DocuSign is on point. We're calling a 'MALFUNCTION MANIA.'
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2023-09-26
|
||||
tags:
|
||||
- Testing
|
||||
- Rewrite
|
||||
- Bounties
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/mm.png"
|
||||
width="1260"
|
||||
height="630"
|
||||
alt="Malfunctioning Documenso Logo in broken colors"
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
We're calling a MALFUNCTION MANIA! 🚨
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Documenso 1.0 is in the [staging environment](https://documen.so/staging). Go check it out.
|
||||
|
||||
It's been a minute since Lucas proclaimed, ["We're doing a rewrite"](https://documenso.com/blog/why-were-doing-a-rewrite), and many of you have been asking when the new version will be available. I'm happy to say that the wait has come to an end. The work on Documenso 1.0 has reached a level we feel comfortable going into the next phase with. We had a lot of community feedback, contributions, and moral support to get us this far, which is why we're excited to announce the most extensive community project yet:
|
||||
|
||||
As Documenso 1.0 just hit the staging environment, we're calling a MALFUNCTION MANIA. An enormous, public testing phase, where we invite everyone to try out the new version, hunt down, report, and fix any malfunctions (aka bugs), and give feedback before release. Malfunction Mania will happen alongside our internal testing, and by combining the two, we want to ensure the best possible release we can have for Version 1.0. We know many of you have been eager to contribute; this is your chance (the first of many to come).
|
||||
|
||||
## As part of Malfunction Mania, we're offering special bug bounties
|
||||
|
||||
- We award $25 - $100 per report/ issue/ fix, depending on the severity and if the problem is already known
|
||||
- Bounties will be awarded for fixing reported or other critical issues via accepted Pull Requests (PR)
|
||||
- Just reporting issues in a reproducible way can also be awarded
|
||||
- Smaller but notable contributions like minor issues and documentation will be awarded with exclusive merch as we see fit.
|
||||
|
||||
## What you can do
|
||||
|
||||
- Head over to the [staging environment](https://documen.so/staging), check out the new version and give it a spin;
|
||||
- Check out the [source code](https://github.com/documenso/documenso) on GitHub and look it over;
|
||||
- Spin up the new version locally and try it out.
|
||||
|
||||
## How to get the bounties
|
||||
|
||||
- Report bugs by creating an issue here: [documen.so/issues](https://documen.so/issues);
|
||||
- Fix bugs by creating a Pull Request (PR);
|
||||
- Look over and add missing documentation/ Quickstarts and other useful resources.
|
||||
|
||||
Best from Hamburg
|
||||
Timur
|
||||
|
||||
We don't have a specific end date for Malfunction Mania. We plan to move the staging version into the production environment by the end of the month once we're happy with the results. Bug reports and fixes are, of course, always welcome going forward.
|
||||
|
||||
**[Follow Documenso on Twitter / X](https://documen.so/tw) and [join the Discord server](https://documen.so/discord) to get the latest about Malfunction Mania.**
|
||||