Compare commits

...

427 Commits

Author SHA1 Message Date
5f17288af6 fix: rebase 2025-06-12 17:46:03 +10:00
e3ce7f94e6 chore: update build 2025-06-11 14:52:23 +10:00
cad04f26e7 feat: sitemap auto-generation for docs (#1822) 2025-06-11 14:09:45 +10:00
d27f0ee0ef fix: duplicate field bugs (#1685) 2025-06-11 13:26:19 +10:00
fd2b413ed9 chore: increase wait times for tests (#1778) 2025-06-11 13:25:21 +10:00
d11ec8fa2a feat: show field coordinates in devmode (#1802)
Show the fields coordinates when the `devmode` search param is present.
It's meant to help API users understand where to position the fields.
2025-06-11 12:28:39 +10:00
b1127b4f0d chore: update readme 2025-06-11 10:42:32 +10:00
be4244fb62 chore: add translations (#1832)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-06-11 10:39:33 +10:00
504a0893ab chore: add organisation docs (#1831) 2025-06-10 20:54:36 +10:00
22a37409c1 v1.12.0-rc.3 2025-06-10 12:49:37 +10:00
50605d5912 chore: add translations (#1830)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-06-10 12:30:36 +10:00
4609fc852d chore: extract translations 2025-06-10 11:52:59 +10:00
e6dc237ad2 feat: add organisations (#1820) 2025-06-10 11:49:52 +10:00
0b37f19641 chore: add translations (#1774) 2025-06-09 16:00:03 +10:00
64c6a51e04 v1.12.0-rc.2 2025-06-07 02:25:14 +10:00
d1eddb02c4 fix: add missing awaits for font normalization 2025-06-07 02:24:59 +10:00
60a623fafd v1.12.0-rc.1 2025-06-07 00:56:40 +10:00
6059b79a8e fix: type error 2025-06-07 00:56:33 +10:00
c73d61955b v1.12.0-rc.0 2025-06-07 00:47:49 +10:00
7c3ca72359 fix: track uninserted fields for multisign 2025-06-07 00:44:41 +10:00
55c8632620 feat: password reauthentication for documents and recipients (#1827)
Adds password reauthentication to our existing reauth providers,
additionally swaps from an exclusive provider to an inclusive type where
multiple methods can be selected to offer a this or that experience.
2025-06-07 00:27:19 +10:00
ce66da0055 feat: multisign embedding (#1823)
Adds the ability to use a multisign embedding for cases where multiple
documents need to be signed in a convenient manner.
2025-06-05 12:58:52 +10:00
695ed418e2 fix: documents failing to seal (#1821)
During our field rework that makes fields appear
more accurately between signing and the completed pdf we swapped to
using text fields. Unfortunately as part of that we dropped using the
Noto font for the text field causing ANSI encoding issues when
encountering certain characters.

This change restores the font and handles a nasty issue we had with our
form flattening reverting our selected font.
2025-06-04 23:29:36 +10:00
93aece9644 chore: dependency updates (#1808) 2025-05-22 14:30:22 +10:00
abd4fddf31 chore: test reo integration (#1806)
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---

## Description

Experimental Short-Term Reo Integration
2025-05-21 15:24:46 +02:00
44bc769e60 v1.11.1 2025-05-20 22:37:46 +10:00
c8f80f7be0 fix: reverse original document logic for api endpoint 2025-05-20 22:37:17 +10:00
8540f24de0 v1.11.0 2025-05-19 15:44:10 +10:00
67203d4bd7 fix: show powered by logic (#1801)
Previous powered by display logic was incorrect, likely due to a merge
conflict.
2025-05-19 14:31:24 +10:00
9d1e638f0f fix: pending tooltip click triggers field (#1800)
Makes it so clicking on the pending field tooltip will trigger the
underlying field it refers to on click if the field can be found within
the DOM.
2025-05-19 10:27:13 +10:00
bd64ad9fef fix: improve multiselect for webhook triggers (#1795)
Replaces https://github.com/documenso/documenso/pull/1660 with the same
code but targeting our main branch.

## Demo

![CleanShot 2025-02-18 at 18 01
05](https://github.com/user-attachments/assets/5afeab95-1a80-4d54-b845-b32cb2e33266)
2025-05-15 13:01:45 +10:00
99b0ad574e feat: bulk add fields (#1683)
## Demo

![CleanShot 2025-03-04 at 02 17
47](https://github.com/user-attachments/assets/2cffaee3-9933-49e9-bdab-eadfd4c35030)

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2025-05-14 19:35:32 +00:00
9594e1fee8 chore: minor ui fixes (#1793) 2025-05-14 20:08:03 +10:00
5e3a2b8f76 fix: allow prefilling date field (#1794)
Allows the prefilling of date fields when creating a document from a
template.

Current implementation is super dirty and should be replaced asap.
2025-05-14 20:06:53 +10:00
f928503a33 chore: update dropdown icons (#1790)
### Before

![CleanShot 2025-05-12 at 11 11
05@2x](https://github.com/user-attachments/assets/af2a60bf-9676-405d-8c3d-e6b2256b53ae)

### After

![CleanShot 2025-05-12 at 11 10
25@2x](https://github.com/user-attachments/assets/aec67e9c-f0f2-4b0d-9baa-7aa327680cf1)
2025-05-14 16:44:13 +10:00
c389670785 fix: trigger webhook for duplicated documents (#1789) 2025-05-14 16:43:31 +10:00
99ad2eb645 fix: allow download of original document via api (#1788) 2025-05-14 08:22:11 +10:00
2f48679b0b fix: make lang cookie httpOnly (#1783) 2025-05-08 15:59:43 +10:00
e40c5d9d24 v1.10.3 2025-05-03 09:23:25 +10:00
ab323f149f fix: resolve issue with uploading templates 2025-05-03 09:23:17 +10:00
bf1c1ff9dc v1.10.2 2025-05-03 08:11:27 +10:00
516e237966 fix: resolve issue with uploading templates 2025-05-03 08:09:44 +10:00
ac7d24eb12 v1.10.1 2025-05-03 07:39:19 +10:00
0931c472a7 fix: resolve issue with uploading templates 2025-05-03 07:38:48 +10:00
8c9dd5e372 v1.10.0 2025-05-02 12:03:08 +10:00
e108da546d fix: incorrect data for postMessage 2025-05-02 10:50:13 +10:00
17370749b4 feat: add folders (#1711) 2025-05-02 02:46:59 +10:00
12ada567f5 feat: embed authoring part two (#1768) 2025-05-01 23:32:56 +10:00
bdb0b0ea88 feat: certificate qrcode (#1755)
Adds document access tokens and QR code functionality to enable secure
document sharing via URLs. It includes a new document access page that
allows viewing and downloading documents through tokenized links.
2025-04-28 11:30:09 +10:00
6a41a37bd4 feat: download original documents (#1742)
## Preview
![CleanShot 2025-04-10 at 14 26
11@2x](https://github.com/user-attachments/assets/d4984d85-ab40-4d38-8d5c-a1085bde21a2)
2025-04-25 22:44:03 +10:00
d78cfec00e fix: branding logos (#1759) 2025-04-24 16:15:06 +10:00
f0dcf7e9bf fix: signing volume query (#1753)
This pull request updates the implementation of the admin leaderboard,
enhancing data handling and improving type safety. It introduces clearer
differentiation between users and teams, adds additional fields to track
more relevant information, and refactors the querying logic to optimize
performance and maintainability.
2025-04-24 16:14:38 +10:00
6540291055 feat: migrate webhook execution to background jobs (#1694) 2025-04-24 06:00:53 +00:00
193325717d fix: rework fields (#1697)
Rework:
- Field styling to improve visibility
- Field insertions, better alignment, centering and overflows

## Changes

General changes:

- Set default text alignment to left if no meta found
- Reduce borders and rings around fields to allow smaller fields
- Removed lots of redundant duplicated code surrounding field rendering
- Make fields more consistent across viewing, editing and signing
- Add more transparency to fields to allow users to see under fields
- No more optional/required/etc colors when signing, required fields
will be highlighted as orange when form is "validating"

Highlighted internal changes:

- Utilize native PDF fields to insert text, instead of drawing text 
- Change font auto scaling to only apply to when the height overflows
AND no custom font is set

⚠️ Multiline changes:

Multi line is enabled for a field under these conditions

1. Field content exceeds field width
2. Field includes a new line
3. Field type is TEXT

## [BEFORE] Field UI Signing 


![image](https://github.com/user-attachments/assets/ea002743-faeb-477c-a239-3ed240b54f55)

## [AFTER] Field UI Signing 


![image](https://github.com/user-attachments/assets/0f8eb252-4cf3-4d96-8d4f-cd085881b78c)

## [BEFORE] Signing a checkbox


![image](https://github.com/user-attachments/assets/4567d745-e1da-4202-a758-5d3c178c930e)

![image](https://github.com/user-attachments/assets/c25068e7-fe80-40f5-b63a-e8a0d4b38b6c)

## [AFTER] Signing a checkbox


![image](https://github.com/user-attachments/assets/effa5e3d-385a-4c35-bc8a-405386dd27d6)

![image](https://github.com/user-attachments/assets/64be34a9-0b32-424d-9264-15361c03eca5)

## [BEFORE] What a 2nd recipient sees once someone else signed a
document


![image](https://github.com/user-attachments/assets/21c21ae2-fc62-4ccc-880a-46aab012aa70)

## [AFTER] What a 2nd recipient sees once someone else signed a document


![image](https://github.com/user-attachments/assets/ae51677b-f1d5-4008-a7fd-756533166542)

## **[BEFORE]** Inserting fields


![image](https://github.com/user-attachments/assets/1a8bb8da-9a15-4deb-bc28-eb349414465c)

## **[AFTER]** Inserting fields


![image](https://github.com/user-attachments/assets/c52c5238-9836-45aa-b8a4-bc24a3462f40)

## Overflows, multilines and field alignments testing

Debugging borders:
- Red border = The original field placement without any modifications
- Blue border = The available space to overflow

### Single line overflows and field alignments 

This is left aligned fields, overflow will always go to the end of the
page and will not wrap


![image](https://github.com/user-attachments/assets/47003658-783e-4f9c-adbf-c4686804d98f)

This is center aligned fields, the max width is the closest edge to the
page * 2


![image](https://github.com/user-attachments/assets/05a38093-75d6-4600-bae2-21ecff63e115)

This is right aligned text, the width will extend all the way to the
left hand side of the page


![image](https://github.com/user-attachments/assets/6a9d84a8-4166-4626-9fb3-1577fac2571e)

### Multiline line overflows and field alignments 

These are text fields that can be overflowed


![image](https://github.com/user-attachments/assets/f7b5456e-2c49-48b2-8d4c-ab1dc3401644)

Another example of left aligned text overflows with more text


![image](https://github.com/user-attachments/assets/3db6b35e-4c8d-4ffe-8036-0da760d9c167)
2025-04-23 21:40:42 +10:00
b94645a451 fix: optional fields being required in direct links (#1752) 2025-04-21 16:34:29 +10:00
7e6704faae chore: update tests 2025-04-21 16:23:50 +10:00
cf17fc61bc chore: update tests 2025-04-21 16:07:19 +10:00
6df8b3aac8 chore: update ci 2025-04-21 14:29:40 +10:00
fdb31772db chore: update tests 2025-04-21 14:13:12 +10:00
a3dfd81870 chore: update playwright config 2025-04-21 13:27:19 +10:00
755ef697ba chore: update playwright config 2025-04-21 13:03:29 +10:00
37cc41d713 fix: skip immediate expiration presign test 2025-04-21 12:41:38 +10:00
dd2ef3a657 v1.10.0-rc.5 2025-04-17 23:01:43 +10:00
435b3ca4f8 chore: remove legacy document update route (#1751)
Remove deprecated route
2025-04-17 16:36:10 +10:00
278cd8a9de fix: always show ip and useragent in certificate 2025-04-17 12:55:03 +10:00
f1526315f5 feat: limit free teams platform plan (#1673)
This pull request removes the `id` field from
`IsDocumentPlatformOptions` in `is-document-platform.ts` and updates the
billing logic in `create-team.ts`: platform plan users create their
first team free, but pay for subsequent teams; non-platform users need
an active team subscription if billing is enabled.
2025-04-15 21:32:15 +10:00
353a7e8e0d fix: dynamic route for team transfer (#1730)
fix: dynamic route handling for /team/verify/transfer/:token
2025-04-15 21:30:44 +10:00
34b2504268 chore: husky (#1706) 2025-04-15 21:29:03 +10:00
566abda36b chore: update render build command (#1748) 2025-04-15 19:06:06 +10:00
9121a062b3 chore: add docs for authoring 2025-04-14 11:31:54 +10:00
e613e0e347 feat: support embedded authoring for creation (#1741)
Adds support for creating documents and templates
using our embed components.

Support is super primitive at the moment and is being polished.
2025-04-11 00:20:39 +10:00
95aae52fa4 chore: add translations (#1715)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-10 12:24:07 +10:00
5958f38719 chore: set the default value on the top (#1734) 2025-04-08 23:35:32 +10:00
419bc02171 docs: prefill fields (#1688) 2025-04-04 00:03:37 +11:00
5e4956f3a2 fix: zero month addition (#1733)
- Add zero month at the begining of each metric on the open page
2025-04-01 11:12:41 +00:00
da71613c9f v1.10.0-rc.4 2025-03-31 20:02:22 +11:00
4d6efe091e fix: pass document meta to readonly field component (#1737)
## Description

Previously we weren't passing the DocumentMeta to our readonly field
component which is used for displaying completed fields by other
recipients.

Due to this dates that were not using the default format were displaying
as invalid date adding confusion to the signing process.

## Related Issue

Reported via support email.

## Changes Made

- Pass the document meta to the readonly field component.
- Support showing completed fields within the embedding UI.

## Testing Performed

- Manual testing
2025-03-31 17:14:56 +11:00
7e6ac4db40 fix: direct template redirects (#1727) 2025-03-28 14:45:54 +11:00
a87af910c7 v1.10.0-rc.2 2025-03-28 01:50:59 +11:00
e37b005d7f chore: update dockerfile 2025-03-28 01:28:49 +11:00
73f8518b47 chore: update tests 2025-03-28 01:21:48 +11:00
ac3deb113e chore: update ci 2025-03-27 22:49:59 +11:00
c82388c40a fix: remove console.log embed document completed (#1723) 2025-03-25 16:36:52 +02:00
31be548939 fix: duplicate webhook calls on document complete (#1721)
Fix webhooks being sent twice due to duplicate frontend calls

Updated the assistant confirmation dialog so the next signer is always
visible (if dictate is enabled). Because if the form is invalid (due to
no name) there is no visual queue that the form is invalid (since it's
hidden)

## Notes

Didn't bother to remove the weird assistants form since it currently
works for now


![image](https://github.com/user-attachments/assets/47910fec-e05e-486a-a61d-16078d948893)

## Tests

- Currently running locally
- Tested webhooks via network tab and via webhook.site
2025-03-25 21:59:13 +11:00
063fd32f18 feat: add signature configurations (#1710)
Add ability to enable or disable allowed signature types:
- Drawn
- Typed
- Uploaded

**Tabbed style signature dialog**

![image](https://github.com/user-attachments/assets/a816fab6-b071-42a5-bb5c-6d4a2572431e)

**Document settings**

![image](https://github.com/user-attachments/assets/f0c1bff1-6be1-4c87-b384-1666fa25d7a6)

**Team preferences**

![image](https://github.com/user-attachments/assets/8767b05e-1463-4087-8672-f3f43d8b0f2c)

- Add multiselect to select allowed signatures in document and templates
settings tab
- Add multiselect to select allowed signatures in teams preferences
- Removed "Enable typed signatures" from document/template edit page
- Refactored signature pad to use tabs instead of an all in one
signature pad

Added E2E tests to check settings are applied correctly for documents
and templates
2025-03-24 17:13:11 +11:00
231f51bd1f v1.10.0-rc.1 2025-03-22 17:34:33 +11:00
a8de8368a2 fix: hide powered by on certificate for platform documents 2025-03-22 12:04:08 +11:00
7dd331addf fix: allow blank rejection reasons 2025-03-22 12:01:18 +11:00
c6743a7cec v1.10.0-rc.0 2025-03-22 03:23:23 +11:00
efbc097191 fix: unblock last signer when using dictation 2025-03-22 02:34:12 +11:00
f1525991dc feat: dictate next signer (#1719)
Adds next recipient dictation functionality to document signing flow,
allowing assistants and signers to update the next recipient's
information during the signing process.

## Related Issue

N/A

## Changes Made

- Added form handling for next recipient dictation in signing dialogs
- Implemented UI for updating next recipient information
- Added e2e tests covering dictation scenarios:
  - Regular signing with dictation enabled
  - Assistant role with dictation
  - Parallel signing flow
  - Disabled dictation state

## Testing Performed

- Added comprehensive e2e tests covering:
  - Sequential signing with dictation
  - Assistant role dictation
  - Parallel signing without dictation
  - Form validation and state management
- Tested on Chrome and Firefox
- Verified recipient state updates in database
2025-03-21 13:27:04 +11:00
fb173e4d0e chore: update docker build scripts 2025-03-20 10:52:33 +11:00
d422ffa873 chore: add terms and privacy policy link (#1707) 2025-03-19 19:29:09 +11:00
55b7697316 chore: update d script in package.json (#1703)
Add the `translate:compile` command to the `d` script.
2025-03-14 16:15:57 +11:00
67bbb6c6f4 fix: autosigning fields with direct links (#1696)
## Description

The changes in `sign-direct-template.tsx` automatically fill in field
values for text, number, and dropdown fields when default values are
present or if the fields are read-only. In `checkbox-field.tsx`, the
changes fix the checkbox signing by checking if the validation is met
and improving how it saves or removes checkbox choices.

## Testing Performed

I tested the code locally with a variety of documents/fields.

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [x] 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.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.
2025-03-13 11:18:01 +02:00
63a4bab0fe feat: better document rejection (#1702)
Improves the existing document rejection process by actually marking a
document as completed cancelling further actions.

## Related Issue

N/A

## Changes Made

- Added a new rejection status for documents
- Updated a million areas that check for document completion
- Updated email sending, so rejection is confirmed for the rejecting
recipient while other recipients are notified that the document is now
cancelled.

## Testing Performed

- Ran the testing suite to ensure there are no regressions.
- Performed manual testing of current core flows.
2025-03-13 15:08:57 +11:00
9f17c1e48e fix: adjust desktop nav search button width and spacing (#1699) 2025-03-13 10:52:01 +11:00
91ae818213 fix: missing prefillfields property from the api v2 documentation (#1700) 2025-03-12 22:54:58 +11:00
a0ace803cf fix: admin signing page crash 2025-03-12 16:53:09 +11:00
b3db3be8e9 fix: signing field disabled when pointer is out of canvas (#1652) 2025-03-12 16:44:21 +11:00
44cdbeecb4 fix: improve layout and truncate document information in logs page (#1656) 2025-03-12 16:31:03 +11:00
Tom
7214965c0c chore: update French translations (#1679) 2025-03-12 16:22:06 +11:00
8d6bf91d12 fix: persist theme cookie for a much longer time (#1693) 2025-03-12 16:09:37 +11:00
fec078081b fix: correct signer deletion (#1596) 2025-03-12 16:05:45 +11:00
c646afcd97 fix: tests 2025-03-09 15:10:19 +11:00
63d990ce8d fix: optional fields in embeds (#1691) 2025-03-09 14:41:17 +11:00
aa7d6b28a4 docs: Update documentation to match reality. colorPrimary, colorBackground,… (#1666)
Update documentation to match reality. colorPrimary, colorBackground,
and borderRadius do not exist according to the schema:
280251cfdd/packages/react/src/css-vars.ts
2025-03-09 14:38:51 +11:00
b990532633 fix: remove refresh on focus 2025-03-08 15:30:13 +11:00
65be37514f fix: prefill fields (#1689)
Users can now selectively choose which properties to pre-fill for each
field - from just a label to all available properties.
2025-03-07 09:09:15 +11:00
0df29fce36 fix: invalid request body (#1686)
Fix the invalid request body so the webhooks work again.
2025-03-06 19:47:24 +11:00
ba5b7ce480 feat: hide signature ui when theres no signature field (#1676) 2025-03-06 19:47:02 +11:00
422770a8c7 feat: allow fields prefill when generating a document from a template (#1615)
This change allows API users to pre-fill fields with values by
passing the data in the request body. Example body for V2 API endpoint
`/api/v2-beta/template/use`:

```json
{
    "templateId": 1,
    "recipients": [
        {
            "id": 1,
            "email": "signer1@mail.com",
            "name": "Signer 1"
        },
        {
            "id": 2,
            "email": "signer2@mail.com",
            "name": "Signer 2"
        }
    ],
    "prefillValues": [
        {
            "id": 14,
            "fieldMeta": {
                "type": "text",
                "label": "my label",
                "placeholder": "text placeholder test",
                "text": "auto-sign value",
                "characterLimit": 25,
                "textAlign": "right",
                "fontSize": 94,
                "required": true
            }
        },
        {
            "id": 15,
            "fieldMeta": {
                "type": "radio",
                "label": "radio label",
                "placeholder": "new radio placeholder",
                "required": false,
                "readOnly": true,
                "values": [
                    {
                        "id": 2,
                        "checked": true,
                        "value": "radio val 1"
                    },
                    {
                        "id": 3,
                        "checked": false,
                        "value": "radio val 2"
                    }
                ]
            }
        },
        {
            "id": 16,
            "fieldMeta": {
                "type": "dropdown",
                "label": "dropdown label",
                "placeholder": "DD placeholder",
                "required": false,
                "readOnly": false,
                "values": [
                    {
                        "value": "option 1"
                    },
                    {
                        "value": "option 2"
                    },
                    {
                        "value": "option 3"
                    }
                ],
                "defaultValue": "option 2"
            }
        }
    ],
    "distributeDocument": false,
    "customDocumentDataId": ""
}
```
2025-03-06 19:45:33 +11:00
083a706373 fix: duplex and 2fa refresh 2025-03-04 11:41:38 +11:00
db326cb4a9 fix: posthog reverse proxy 2025-03-04 10:48:19 +11:00
d664f571d6 fix: posthog reverse proxy 2025-03-04 10:46:59 +11:00
7c38970ee8 fix: update error logging 2025-03-04 01:41:39 +11:00
e08d62c844 fix: remove invalid prisma zod schemas 2025-03-04 01:20:13 +11:00
25bb6ffe77 fix: imports 2025-03-03 14:49:28 +11:00
e79d762710 chore: add label for checkbox and radio fields (#1607) 2025-03-03 13:46:29 +11:00
d970976299 fix: remove auto-expand in embeddding 2025-02-28 14:46:15 +11:00
3dce814ab2 fix: stripe price fetch (#1677)
Currently Stripe prices search is omitting a price for an unknown
reason.

Changed our fetch logic to use `list` instead of `search` allows us to
work around the issue.

It's unknown on the performance impact of using `list` vs `search`
2025-02-28 14:44:06 +11:00
ad520bb032 fix: remove oauth from embeds 2025-02-27 14:08:59 +11:00
596d30e2e5 fix: remove lazy pdf loader 2025-02-26 21:48:06 +11:00
6474b4a524 fix: add preferred team middleware 2025-02-26 19:42:42 +11:00
5b4db51051 fix: react-pdf canvas build 2025-02-26 18:39:21 +11:00
cf58c80e31 fix: handle empty field meta for checkboxes 2025-02-26 15:30:51 +11:00
11dbb8873e docs: add the v2 api staging base url (#1671) 2025-02-26 15:30:32 +11:00
bc7907271b fix: unbreak build for docker 2025-02-25 21:46:51 +11:00
9b376d34cf feat: add stripe dev cli 2025-02-25 21:22:28 +11:00
deea99d865 feat: search by externalId 2025-02-25 20:07:47 +11:00
3328074f51 fix: early adopters can use platform features 2025-02-25 20:07:40 +11:00
5e69665e00 fix: rr7 github build 2025-02-25 16:52:10 +11:00
c1c7cfaf8b chore: cleanup 2025-02-25 16:37:36 +11:00
7e8955b89c fix: add posthog error monitor 2025-02-25 15:14:45 +11:00
cedd5e87b1 chore: update API documentation 2025-02-25 02:36:08 +11:00
5255e8671f chore: refactor pdf worker loader 2025-02-24 21:47:06 +11:00
d4c1bad407 fix: add default oauth user url 2025-02-23 18:49:22 +11:00
01dccb7916 chore: flattern routes 2025-02-21 15:53:23 +11:00
483d7caef7 feat: allow document rejection in embeds (#1662) 2025-02-21 01:27:03 +11:00
139bc265c7 fix: migrate billing to RR7 2025-02-21 01:16:23 +11:00
991ce5ff46 fix: update teams API tokens logic 2025-02-21 00:34:50 +11:00
7728c8641c fix: share opengraph 2025-02-20 15:38:06 +11:00
50a41d0799 fix: pdf viewer and embeds 2025-02-20 15:06:36 +11:00
250381fec8 fix: billing 2025-02-20 12:17:55 +11:00
d2f3d24542 chore: update docs 2025-02-19 22:36:17 +11:00
ec07092bf6 fix: session refresh 2025-02-19 22:29:30 +11:00
63e2ef0abf fix: static caching 2025-02-19 21:35:35 +11:00
90ce52164c chore: add password tests 2025-02-19 18:41:53 +11:00
ac30654913 fix: add auth session lifetime 2025-02-19 18:04:36 +11:00
24f3ecd94f fix: remove marketing url 2025-02-19 16:45:54 +11:00
a319ea0f5e fix: add public profiles tests 2025-02-19 16:07:04 +11:00
5ce2bae39d fix: resolve internal pdf translations 2025-02-19 14:43:35 +11:00
5d86e84217 fix: prepare auth migration (#1648)
Add schema session migration in preparation for auth migration.
2025-02-18 15:19:42 +11:00
79e26a9a46 fix: remove session migration 2025-02-18 15:19:39 +11:00
dd602a7e1c fix: themes 2025-02-18 15:17:13 +11:00
fb16214dc5 chore: add asssitant role to the docs (#1638) 2025-02-17 23:28:00 +11:00
5fc724b247 fix: rework sessions 2025-02-17 22:46:36 +11:00
1ed1cb0773 chore: refactor sessions 2025-02-16 00:44:01 +11:00
8d5fafec27 feat: add static cache 2025-02-15 00:08:36 +11:00
0f6f236e0c fix: firefox fouc 2025-02-14 23:02:45 +11:00
e518985833 fix: migrate 2fa to custom auth 2025-02-14 22:00:55 +11:00
595e901bc2 fix: make auth migration more flexible 2025-02-14 19:22:11 +11:00
df8ea09021 fix: add oidc env variables 2025-02-14 18:11:54 +11:00
180656978b feat: add themes 2025-02-14 17:50:23 +11:00
28f5177064 fix: dialogs with search params 2025-02-14 16:14:02 +11:00
31de86e425 feat: add oidc 2025-02-14 16:01:16 +11:00
113ab293bb chore: make all the docker stuff work 2025-02-14 14:53:01 +11:00
1c4878e526 fix: documentation build 2025-02-13 21:21:51 +11:00
92db4d68db fix: cleanup env variables 2025-02-13 20:56:44 +11:00
7379391f92 fix: migrate translations 2025-02-13 20:24:27 +11:00
ebc2b00067 fix: add sign up hook 2025-02-13 20:21:23 +11:00
87dcdd44cd chore: update local seed data (#1622)
Add multiple example documents, pending documents, and templates for
both admin and example users
2025-02-13 19:50:05 +11:00
b205f7e5f3 fix: typed signature not working (#1635)
The `typedSignatureEnabled` prop was removed from the `SignatureField`
component, which broke the typed signature meaning that nobody could
sign documents by typing their signature.
2025-02-13 19:47:38 +11:00
c5d5355cf7 fix: assistant mode breaks for number fields 2025-02-13 19:46:14 +11:00
5fac29a07f fix: add css targets for embeds 2025-02-13 19:45:54 +11:00
1aaacab6ca fix: temp field label/text truncation (#1565)
TEMP: Fix the truncation of the field label/text.
2025-02-13 19:43:35 +11:00
06076c1809 fix: unable to check on the checkbox field (#1593)
This change prevents race conditions between state updates and API
operations by updating local state immediately before making async
calls.
2025-02-13 19:42:08 +11:00
c0ae68c28b feat: assistant role (#1588)
Introduces the ability for users with the **Assistant** role to prefill
fields on behalf of other signers. Assistants can fill in various field
types such as text, checkboxes, dates, and more, streamlining the
document preparation process before it reaches the final signers.
2025-02-13 19:37:34 +11:00
3e106c1a2d chore: api v2 docs (#1620)
chore update docs for api v2 announce
2025-02-13 18:49:37 +11:00
741639ee78 fix: improve move to team display logic 2025-02-13 18:49:03 +11:00
0b3638c42c feat: add Polish and Italian (#1618) 2025-02-13 18:48:37 +11:00
0f50110853 fix: create global settings on team creation (#1601)
The global team settings weren't created when creating a new team.

## Changes Made

The global team settings are now created when a new team is created.
2025-02-13 18:47:59 +11:00
b0f8c83134 chore: add cancelled webhook event (#1608) 2025-02-13 18:47:43 +11:00
c9e8a32471 feat: bulk send templates via csv (#1578)
Implements a bulk send feature allowing users to upload a CSV file to
create multiple documents from a template. Includes CSV template
generation, background processing, and email notifications.
2025-02-13 18:44:29 +11:00
84b193d99c fix: tidy document invite email render logic (#1597)
Updates one of our confusing ternaries to use `ts-pattern` for rendering
the conditional blocks making it easy to follow the logic occurring.
2025-02-13 18:34:38 +11:00
b03c5ab1a7 fix: admin leaderboard query sorting (#1548) 2025-02-13 18:32:38 +11:00
9db42accf3 feat: add text align option to fields (#1610)
Adds the ability to align text to the left, center or right for relevant
fields.

Previously text was always centered which can be less desirable.

See attached debug document which has left, center and right text
alignments set for fields.

<img width="614" alt="image"
src="https://github.com/user-attachments/assets/361a030e-813d-458b-9c7a-ff4c9fa5e33c"
/>

N/A

- Added text align option
- Update the insert in pdf method to support different alignments
- Added a debug mode to field insertion

- Ran manual tests using the debug mode
2025-02-13 18:28:33 +11:00
383b5f78f0 feat: migrate nextjs to rr7 2025-02-13 14:10:38 +11:00
9183f668d3 chore: bump node version for docker 2025-01-27 12:20:04 +11:00
54ea96391a fix: correct redirect after document duplication (#1595) 2025-01-23 16:34:22 +11:00
42d24fd1a1 feat: copy, paste, duplicate template fields (#1594) 2025-01-23 14:28:26 +11:00
dc36a8182c v1.9.0-rc.11 2025-01-21 09:49:22 +11:00
0ef85b47b1 fix: handle empty object as fieldMeta 2025-01-21 09:46:54 +11:00
058d9dd0ba v1.9.0-rc.10 2025-01-20 19:54:39 +11:00
74bb230247 fix: add empty success responses (#1600) 2025-01-20 19:47:39 +11:00
7c1e0f34e8 v1.9.0-rc.9 2025-01-20 16:08:15 +11:00
7e31323faa fix: add team context to more vanilla client usages 2025-01-20 15:53:28 +11:00
a28cdf437b feat: add get field endpoints (#1599) 2025-01-20 15:53:12 +11:00
80dfbeb16f feat: add angular embedding docs (#1592) 2025-01-20 09:35:47 +11:00
9de3a32ceb fix: pass team id to vanilla trpc client 2025-01-20 09:30:36 +11:00
0d3864548c fix: bump trpc and openapi packages (#1591) 2025-01-19 22:07:02 +11:00
9e03747e43 feat: add create document beta endpoint (#1584) 2025-01-16 13:36:00 +11:00
5750f2b477 feat: add prisma json types (#1583) 2025-01-15 13:46:45 +11:00
901be70f97 feat: add consistent response schemas (#1582) 2025-01-14 00:43:35 +11:00
7d0a9c6439 fix: refactor prisma relations (#1581) 2025-01-13 13:41:53 +11:00
48b55758e3 feat: ignore unrecognized fields from authorization response (#1479)
When authenticating using OIDC some IDPs send additional fields in their
authorization response. 

This leads to an error because these fields can't be persisted to the DB 
through the auth.js prisma adapter. 

This PR solves this by deleting all unrecognized fields from the 
authorization response before persisting. 

This behaviour is also compliant to 
[RFC6749 Section 4.1.2](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2)
2025-01-13 11:05:37 +11:00
dcaccb65f2 v1.9.0-rc.8 2025-01-13 10:21:05 +11:00
723e1b4ea2 fix: include all template meta in findTemplates 2025-01-13 09:34:23 +11:00
08a69c6168 fix: pending document edit (#1580)
Fix issue where you cannot edit a pending document when there is a CCer
recipient.
2025-01-11 22:31:59 +11:00
948d9c24cf fix: broken direct template webhook (#1579) 2025-01-11 21:42:33 +11:00
ebbe922982 feat: add template and field endpoints (#1572) 2025-01-11 15:33:20 +11:00
6520bbd5e3 Update FEATURES
chore: typo
2025-01-10 14:25:39 +01:00
4e197ac24c v1.9.0-rc.7 2025-01-09 15:07:11 +11:00
f707e5fb10 fix: update template field schema (#1575)
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2025-01-09 12:06:17 +11:00
6fc5e565d0 fix: add document visibility to template (#1566)
Adds the visibility property to templates
2025-01-09 10:14:24 +11:00
07c852744b v1.9.0-rc.6 2025-01-08 20:18:09 +11:00
4fab98c633 feat: allow switching document when using templates (#1571)
Adds the ability to upload a custom document when using a template.

This is useful when you have a given fixed template with placeholder
values that you want to decorate with Documenso fields but will then
create a final specialised document when sending it out to a given
recipient.
2025-01-07 16:13:35 +11:00
18ca0cf3d6 chore: add translations (#1564) 2025-01-02 10:36:05 +11:00
b3e044e278 fix: label stable releases as latest (#1567)
adds missing 'v' in regex  #1405
2025-01-02 10:07:25 +11:00
e2a250063f fix: crowdin config 2024-12-31 17:25:33 +11:00
4085151f80 fix: merge common and web po files (#1563) 2024-12-31 17:20:58 +11:00
0d3681e26a fix: remove marketing remains 2024-12-31 15:53:15 +11:00
cfe7b3a51f fix: remove marketing (#1562) 2024-12-31 15:45:22 +11:00
08d3d6a80a fix: improve recipient status display
Improves the display of the recipients status when
distribution method is set to none.

Previously we had a ton of checks for sendStatus = SENT
which will never trigger when distributing manually causing
some confusion.
2024-12-31 14:54:19 +11:00
9d83bda12c fix: standardise checkboxes
Checkboxes were previously styled super wonky due to
the usage of checkboxClassName which styled the checkbox
trigger.

This change reverts all that and leaves it with sensible defaults
across dark and light mode.
2024-12-31 11:55:49 +11:00
22fd1b5be1 fix: default to user timezone (#1559)
Passes the timezone of the user uploading the document/template via the
UI to the server.

If the user uploads a document/template via the API and doesn't set a
timezone, it defaults to `Etc/UTC`.
2024-12-31 10:27:24 +11:00
df33fbf91b feat: admin ui for disabling users (#1547) 2024-12-30 14:45:33 +11:00
ee6efc4cca fix: avoid having a drawn and typed signature at the same time (#1516) 2024-12-27 20:29:12 +11:00
6da15ab12b feat: open the advanced settings automatically (#1508) 2024-12-27 19:57:24 +11:00
Tom
7ef2a8769b chore: update French translations (#1555) 2024-12-27 19:39:57 +11:00
487f52e194 feat: enable optional fields (#1470) 2024-12-27 19:30:44 +11:00
39b1c5bbec feat: additional valid password (#1456) 2024-12-27 16:02:45 +11:00
32857bbfeb fix: make small fields draggable (#1551) 2024-12-27 15:22:56 +11:00
41218e2585 chore: extract translations 2024-12-26 22:08:52 +11:00
a1a2d0801b feat: notify owner when a recipient signs (#1549) 2024-12-26 22:04:13 +11:00
c588c09b26 fix: remove unwanted semicolon (#1545) 2024-12-26 17:28:22 +11:00
74382e21e7 feat: add get recipient route (#1553) 2024-12-26 17:25:14 +11:00
8a7ec7e982 fix: billing page formatting (#1554) 2024-12-26 17:20:08 +11:00
2948a33bf9 fix: tests (#1556) 2024-12-26 17:00:55 +11:00
98b2da5018 v1.9.0-rc.5 2024-12-26 13:41:04 +11:00
fc1f76b543 fix: checkbox logic (#1537)
## 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. -->
2024-12-23 12:06:47 +02:00
22c9fb777b fix: perf improvements 2024-12-18 15:01:57 +11:00
2da051a7f9 v1.9.0-rc.4 2024-12-18 08:14:50 +11:00
390a317bd3 fix: normalize pdf on the server 2024-12-18 08:14:14 +11:00
c161553d1d feat: add disabled property for user (#1546) 2024-12-17 22:35:59 +11:00
c960a48b4f fix: z-index of field settings (#1469) 2024-12-17 17:09:58 +11:00
9502f4361d fix: fieldtooltip blocking the field click (#1538)
## Before (error)


https://github.com/user-attachments/assets/525e6c04-fc03-41a7-8299-2a753e9e9fa6

## After (fixed)


https://github.com/user-attachments/assets/67f7e592-c5ca-47f4-962c-e4a848522d43
2024-12-17 17:04:20 +11:00
82deab41f4 fix: move permission check outside the document visibility component (#1543)
PR created because of this comment
https://github.com/documenso/documenso/pull/1521#discussion_r1881895305.
2024-12-17 17:03:08 +11:00
2245812f0b fix: document visibility logic (#1521)
Update the logic of document visibility logic and added some tests &
updated some existing ones.
2024-12-16 09:10:40 +02:00
861e9c976b v1.9.0-rc.3 2024-12-16 09:35:33 +11:00
f55808199b feat: make enterprise billing dynamic (#1539) 2024-12-14 13:44:25 +09:00
b4a7f1887d feat: add trpc openapi (#1535) 2024-12-14 01:23:35 +09:00
f73441ee85 chore: prevent user selection within signature pad (#1530)
adds a `select-none` class to the signature pad in order to
prevent iPadOS from becoming too trigger happy with the context menu and
auto corrects. Please ensure this doesn't break anything by accident.
2024-12-13 16:02:26 +11:00
d7de3b08c1 fix: darkmode on radio button and checkbox labels (#1518)
Fixed Radio Button and Checkbox Appearance in Dark Mode
2024-12-13 15:55:40 +11:00
7d201f05d9 fix: admin leaderboard query (#1522)
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2024-12-13 15:50:52 +11:00
a21ee2cea6 v1.9.0-rc.2 2024-12-13 15:16:26 +11:00
4ad46b81c9 fix: prevent hidden layers from being toggled in pdf viewers (#1528)
https://github.com/user-attachments/assets/e10194ca-212b-40ee-b9a1-85ef54829a40

---------

Co-authored-by: Mythie <me@lucasjamessmith.me>
2024-12-13 14:19:55 +11:00
10b8e785e0 fix: clear invalid drawn signature when switching to typed signature (#1536) 2024-12-13 10:40:22 +11:00
5fbed783fc feat: add controls for sending completion emails to document owners (#1534)
Adds a new `ownerDocumentCompleted` to the email settings that controls
whether a document will be sent to the owner upon completion.

This was previously the only email you couldn't disable and didn't
account for users integrating with just the API and Webhooks.

Also adds a flag to the public `sendDocument` endpoint which will adjust
this setting while sendint the document for users who aren't using
`emailSettings` on the `createDocument` endpoint.
2024-12-12 14:24:07 +11:00
c9fe134852 v1.9.0-rc.1 2024-12-12 10:31:44 +11:00
f2149719e3 fix: resolve issue with embed css injection 2024-12-12 10:14:23 +11:00
161d40cde7 fix: secure passkey cookies (#1533) 2024-12-12 01:16:29 +09:00
76028771b8 fix: add billing leeway (#1532) 2024-12-12 01:10:01 +09:00
5df1a6602e fix: refactor search routes (#1529)
Refactor find endpoints to be consistent in terms of input and output.
2024-12-11 19:39:50 +09:00
3d7b28a92b chore: update tailwind config 2024-12-11 13:52:34 +11:00
ed862413b1 v1.9.0-rc.0 2024-12-11 09:48:01 +11:00
9d02ab4a5e feat: open page api (#1419) 2024-12-10 21:19:05 +11:00
34c0868d77 chore: add openapi description for enterprise field (#1520) 2024-12-10 20:26:28 +11:00
fae9c0ca24 fix: refactor routers (#1523) 2024-12-10 16:11:20 +09:00
dd162205fa fix: prevent accidental signatures (#1515)
![CleanShot 2024-12-06 at 03 30
39](https://github.com/user-attachments/assets/d47dc820-f19d-43b7-a60d-914fc9ab24b8)

![CleanShot 2024-12-06 at 03 32
34](https://github.com/user-attachments/assets/0db98735-8c91-469b-873c-adb19d0fff7b)
2024-12-08 14:17:58 +11:00
a88ae1cc1e chore: extract translations 2024-12-06 16:11:54 +09:00
904948e2bc fix: refactor trpc errors (#1511) 2024-12-06 16:01:24 +09:00
3b6b96f551 chore: remove redundant translations on upload (#1510)
## Description

Clean redundant translations by default.

This should stop the AI from doing strange things to commented out
translations.
2024-12-06 09:04:15 +11:00
67e49c82a3 feat: return fields in GET /documents/:id endpoint (#1317)
To be able to use the PATCH `/api/v1/documents/{id}/fields/{fieldId}`
endpoint, we need to know the fields ID of a particular document. The
issue #1178 suggested to create a new endpoint for this. To be
consistent with the `/templates` endpoint, I propose in this PR to
directly add the `fields` field to the `/documents/:id` endpoint.
2024-12-06 09:03:32 +11:00
9f45fe62e4 fix: refactor teams router (#1500) 2024-12-05 22:14:47 +09:00
9e8094e34c Update README.md (#1509)
🚨 WE ARE LIVE ON PH WITH OUR LATEST LAUNCH 🚀
2024-12-05 13:51:49 +01:00
0e7e9e17c9 v1.8.1 2024-12-05 13:57:05 +11:00
b3ccb3d26f v1.8.1-rc.9 2024-12-05 13:53:35 +11:00
b17370c153 chore: reword some german translations to increase clarity (#1507) 2024-12-05 09:42:10 +11:00
0c53f5b061 v1.8.1-rc.8 2024-12-04 23:29:15 +11:00
ed6157de80 feat: upload signature as img (#1496)
Allow users to upload their signature as an image.

https://github.com/user-attachments/assets/375faad2-f0db-4f44-83d2-d969c5ab4442
2024-12-04 23:22:18 +11:00
5e08d0cffb v1.8.1-rc.7 2024-12-04 22:43:41 +11:00
5565aff7a3 fix: docs content (#1495) 2024-12-04 19:49:44 +09:00
428acf4ac3 fix: dateformat api bug (#1506) 2024-12-04 19:48:44 +09:00
f4b1e5104e feat: add platform plan pricing (#1505)
Add platform plan to the billing page.
2024-12-04 15:42:03 +09:00
a687064a42 v1.8.1-rc.6 2024-12-04 14:58:29 +11:00
8ec69388a5 fix: add document rejection webhook
Adds the document rejection webhook since it was missing.

Additionally, normalises and standardises the webhook body.
2024-12-04 14:35:20 +11:00
f3da11b3e7 fix: e2e tests failing due to same-site cookies 2024-12-04 14:33:21 +11:00
fc84ee8ec2 fix: use default nextauth logic for secure cookies 2024-12-03 21:35:09 +11:00
4282a96ee7 v1.8.1-rc.5 2024-12-03 15:44:10 +11:00
2aae7435f8 fix: auth cookies across iframes (#1501) 2024-12-03 15:28:30 +11:00
bdd33bd335 feat: signing volume (#1358)
adds a signing volume and leaderboard section to the admin panel
2024-12-03 11:27:22 +11:00
9e8d0ac906 v1.8.1-rc.4 2024-12-02 22:07:31 +11:00
f27d0f342c fix: putPdfFile to always include file extension 2024-12-02 22:06:53 +11:00
4326e27a2a v1.8.1-rc.3 2024-12-02 07:48:03 +11:00
62806298cf fix: wrong signing invitation message (#1497) 2024-12-02 07:47:11 +11:00
87186e08b1 v1.8.1-rc.2 2024-11-29 15:09:03 +11:00
b27fd800ed fix: add distribution settings to external api 2024-11-29 14:10:48 +11:00
98d85b086d feat: add initial api logging (#1494)
Improve API logging and error handling between client and server side.
2024-11-28 16:05:37 +07:00
04293968c6 chore: update embedding docs 2024-11-28 15:55:17 +11:00
e6d4005cd1 fix: document title truncation (#1467)
Truncates the document title across various instances where it previously hadn't been truncated.
2024-11-27 10:53:48 +11:00
337bdb3553 v1.8.0-rc.1 2024-11-26 21:26:12 +11:00
ab654a63d8 chore: enable typed signature by default (#1436)
Enable typed signature by default and also add the option to set a typed
signature in the profile page.
2024-11-26 21:03:44 +11:00
dcb7c2436f fix: update prettier and tailwind 2024-11-26 11:47:28 +11:00
fa33f83696 feat: download doc without signing certificate (#1477)
## Description

I added the option of downloading a document without the signing
certificate for teams. They can disable/enable the option in the
preferences tab.

The signing certificate can still be downloaded separately from the
`logs` page.
2024-11-25 15:47:26 +11:00
b15e1d6c47 feat: support whitelabelling in the embedding (#1491)
## Description

Adds support for customising the theme and CSS for the embedding
components which is restricted to platform customers and above.

Additionally adds proper support for the platform plan which will let us
update our stripe products.

<img width="1040" alt="image"
src="https://github.com/user-attachments/assets/f694cd1e-ac93-4dc0-9f78-92fa813f6404">
<img width="1015" alt="image"
src="https://github.com/user-attachments/assets/4209972a-b2bd-40c9-9049-0367382a4de5">
<img width="1065" alt="image"
src="https://github.com/user-attachments/assets/fdbaaaa5-a028-4b1d-a58a-ea6224e21abe">


## Related Issue

N/A

## Changes Made

- Added support for using CSS Vars and CSS within the embedding route
- Added a guard for platform and enterprise plans to activate the custom
css
- Added support for the platform plan

## Testing Performed
Yes
2024-11-25 15:47:00 +11:00
cd5adce7df fix: hardcode delete confirmation text to avoid translation mismatch (#1487) 2024-11-22 14:22:31 +07:00
11e483f1c4 chore: update changelog 2024-11-21 13:10:31 +11:00
2e2bc8382f v1.8.1-rc.0 2024-11-20 23:02:32 +11:00
1f3a9b578b chore: add translations (#1485)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced German, Spanish, French, and Polish translations for various
document management and marketing phrases.

- **Improvements**
- Updated translations for clarity and accuracy across multiple
languages, including user notifications and document actions.
- Added new translation entries to improve user experience and
localization in the Documenso application.

- **Chores**
- Updated revision dates in translation files to reflect recent changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-11-20 23:00:59 +11:00
83e7a3c222 fix: improve field sizing (#1486)
## Description

Allows for smaller field sizing in addition to improving our styling
when displaying labels on smaller fields.

This is the minimum currently supported field size until we perform a
more extensive refactor of our current drag and drop system.

## Related Issue

Reported via support channels

## Changes Made

- Updated our minimum size constraints
- Attempted to add a general autosizing component for text and failed
- Updated styling in a bunch of places to use the css `clamp()` method
for dynamic sizing.
2024-11-20 22:49:30 +11:00
9ef8b1f0c3 feat: automatically sign fields in large documents (#1484)
## Description

Adds a dialog that will display when a certain field threshold is
reached asking the user if they would like to sign non-critical fields
such as name, date, initials, and email with information that is already
available.

This has not been added to direct templates since we would often not
have all the pre-requisite knowledge since users are mostly anonymous.
Additionally, this has not been added to the embedding view since it may
detract from the experience for some.

Will not prompt the user if there is action authentication on the
document.

See the below demo:


https://github.com/user-attachments/assets/71739b5c-1323-4da9-89fd-a1145c9714d5

## Related Issue

#1281 (Older PR relating to the feature)

## Changes Made

- Added a new auto-sign dialog that will automatically trigger once
certain criteria is met.

## Testing Performed

- Tested that the dialog displays when the threshold is met
- Tested that the dialog is hidden when the threshold is not met
- Tested that the messaging during errors is correct
- Tested that the dialog does not display when 2FA or Passkeys are
required
2024-11-20 10:59:09 +11:00
0eff336175 v1.8.0-rc.4 2024-11-19 16:44:25 +11:00
9bdd5c31cc fix: sort recipients for template with signing order (#1468) 2024-11-18 15:54:51 +07:00
57ad7c150b chore: add translations (#1474) 2024-11-18 08:40:25 +11:00
b0829e6cdf v1.8.0-rc.3 2024-11-16 09:23:05 +11:00
08a446fefd feat: support windows for 2fa tokens (#1478)
## Description

When using 2fa enabled authentication on direct templates we run into an
issue where a 2fa token has been attached to a field but it's submitted
at a later point.

To better facilitate this we have introduced the ability to have a
window of valid tokens.

This won't affect other signing methods since tokens are verified
immediately after they're entered.

## Related Issue

N/A

## Changes Made

- Updated our validate2FAToken method to use a window based approach
rather than the default verify method.

## Testing Performed

- Created a series of tokens and tested upon different intervals and
windows to confirm functionality works as expected.
2024-11-16 09:17:45 +11:00
f15f9ecdd1 chore: update docs 2024-11-15 21:47:22 +07:00
979e3f3e71 fix: always allow access to billing (#1476) 2024-11-15 21:34:39 +07:00
876803b5db fix: handle team invites being accepted but not added 2024-11-15 13:27:36 +11:00
1c87cb1e0d v1.8.0-rc.2 2024-11-15 01:56:22 +11:00
5398026b80 feat: signature rejection (#1472)
## Description

Adds support for rejecting a given document informing the document
owner.

Flows for resolving a rejection don't currently exist so it's up to the
document owner to reach out to the recipient and work out a way to move
forward via a new document or offline agreement.

## Related Issue


## Changes Made

- Added new rejection properties to the recipient schema
- Added API endpoints to support rejection
- Added email templates for notifying the document owner and recipient
- Added a dialog on the signing page to start the rejection flow.

## Testing Performed

- Manually tested the flow end to end
- Automated tests are planned
2024-11-14 21:37:42 +11:00
f2439abbc9 chore: update docs 2024-11-12 23:12:13 +07:00
5a6e031c90 chore: add translations (#1463) 2024-11-12 15:50:22 +07:00
bcc3b70335 fix: errors moving fields (#1429) 2024-11-12 15:49:31 +07:00
5a26610a01 fix: update publish workfow to only tag stable versions latest (#1405)
## Description

This pull request introduces modifications to the GitHub Actions
workflow to ensure that the `latest` Docker tag is only pushed for
stable releases. It prevents the `latest` tag from being assigned to
release candidates (`-rc`), beta versions, or other pre-release tags.
This enhancement improves version management by keeping the `latest` tag
reserved exclusively for fully stable versions (e.g., `1.0.0`).

## Related Issue

Fixes #1404

## Changes Made

- Added a conditional check to verify if the release version follows the
format `X.Y.Z` (stable release format).
- Updated the Docker manifest creation steps to only push the `latest`
tag if the version is a stable full release.
- Modified both DockerHub and GitHub Container Registry push steps to
reflect the new versioning conditions.
2024-11-12 17:37:34 +11:00
5d7a979baf chore: add translations (#1461) 2024-11-12 13:00:56 +07:00
552825b79e chore: extract translations 2024-11-12 12:37:34 +07:00
786566bae4 fix: certificate translations (#1460)
## Description

Currently certificate translations on production sometimes does not show
the required language.

This could not be replicated when creating certificates on staging
(Browserless.io) and local development (Chromium), which means this fix
ultimately cannot be tested unless on live.

This is an attempt to fix it by isolating the certificate generation
into it's own context, and applying a cookie to define the required
language.

This fix is based on the assumption that there is some sort of error
which pushes the certificate to be generated on the client side, which
ultimately will render in English due to constraints on nextjs.

## Changes Made

- Apply language into cookie instead purely dynamically on SSR
- Minor unrelated fixes

## Testing Performed

Tested to ensure certificates could still be generated
2024-11-12 15:26:14 +11:00
cb23357b42 fix: document url in the command menu search (#1453) 2024-11-12 00:12:15 +07:00
0078162159 chore: project babel (#1420)
blogpost babel
2024-11-08 16:42:25 +01:00
19e23d8ef3 v1.8.0-rc.0 2024-11-08 23:09:56 +11:00
e3b7ec82a3 chore: add translations (#1451) 2024-11-08 23:06:57 +11:00
23a0537648 feat: add global settings for teams (#1391)
## Description

This PR introduces global settings for teams. At the moment, it allows
team admins to configure the following:
* The default visibility of the documents uploaded to the team account
* Whether to include the document owner (sender) details when sending
emails to the recipients.

### Include Sender Details

If the Sender Details setting is enabled, the emails sent by the team
will include the sender's name:

> "Example User" on behalf of "Example Team" has invited you to sign
"document.pdf"

Otherwise, the email will say:

> "Example Team" has invited you to sign "document.pdf"

### Default Document Visibility

This new option allows users to set the default visibility for the
documents uploaded to the team account. It can have the following
values:
* Everyone
* Manager and above
* Admins only

If the default document visibility isn't set, the document will be set
to the role of the user who created the document:
* If a user with the "User" role creates a document, the document's
visibility is set to "Everyone".
* Manager role -> "Manager and above"
* Admin role -> "Admins only"

Otherwise, if there is a default document visibility value, it uses that
value.

#### Gotcha

To avoid issues, the `document owner` and the `recipient` can access the
document irrespective of their role. For example:
* If a team member with the role "Member" uploads a document and the
default document visibility is "Admins", only the document owner and
admins can access the document.
  * Similar to the other scenarios.

* If an admin uploads a document and the default document visibility is
"Admins", the recipient can access the document.

* The admins have access to all the documents.
* Managers have access to documents with the visibility set to
"Everyone" and "Manager and above"
* Members have access only to the documents with the visibility set to
"Everyone".

## Testing Performed

Tested it locally.
2024-11-08 22:50:49 +11:00
f6bcf921d5 feat: add document distribution setting (#1437)
Add a document distribution setting which will allow us to further
configure how recipients currently receive documents.
2024-11-08 13:32:13 +09:00
451723a8ab chore: extract translations 2024-11-08 00:34:25 +09:00
9b769e7e33 fix: email translations (#1454) 2024-11-08 00:33:48 +09:00
61ea4971ad fix: custom team email subject (#1450)
Fixed issue where custom email subjects for teams were being ignored.
2024-11-06 22:16:31 +09:00
ffc61af904 chore: extract translations 2024-11-06 22:03:51 +09:00
efbe94aea8 feat: add signing link copy (#1449) 2024-11-06 21:34:06 +09:00
1b10c55758 fix: update docker environment (#1438) 2024-11-06 19:21:52 +09:00
3da4603a47 fix: content pages breaking during ssr on vercel 2024-11-06 21:02:35 +11:00
dcc2ac8a71 feat(email): support configurable SMTP service (#1447) 2024-11-06 19:00:59 +09:00
5158584955 fix: checkout loading button (#1445) 2024-11-05 20:10:10 +09:00
54c0c6be14 fix: open page 2024-11-05 19:36:36 +09:00
927a24249c chore: add translations (#1444) 2024-11-05 18:53:33 +09:00
a50c758b07 chore: extract translations 2024-11-05 18:26:09 +09:00
cc249357b3 feat: add certificate translations (#1440)
Add translations for audit logs and certificates.
2024-11-05 18:25:23 +09:00
011dabcc04 chore: extract translations 2024-11-05 17:37:05 +09:00
4fa6dc1e21 feat: add template page (#1395)
Add a template page view to allow users to see more details about a
template at a glance.
2024-11-05 17:36:30 +09:00
32b65c4d49 fix: blog posts breaking during ssr on vercel 2024-11-05 18:34:27 +11:00
de880aa821 v1.7.2-rc.4 2024-11-05 13:50:01 +11:00
dc5723c386 chore: add i18n lang to document deleted email 2024-11-05 13:44:00 +11:00
c57d1dc55d chore: add translations (#1443)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-11-05 13:07:55 +11:00
4dd95016b1 feat: i18n for emails (#1442)
## Description

Support setting a document language that will control the language used
for sending emails to recipients. Additional work has been done to
convert all emails to using our i18n implementation so we can later add
controls for sending other kinds of emails in a users target language.

## Related Issue

N/A

## Changes Made

- Added `<Trans>` and `msg` macros to emails
- Introduced a new `renderEmailWithI18N` utility in the lib package
- Updated all emails to use the `<Tailwind>` component at the top level
due to rendering constraints
- Updated the `i18n.server.tsx` file to not use a top level await

## Testing Performed

- Configured document language and verified emails were sent in the
expected language
- Created a document from a template and verified that the templates
language was transferred to the document
2024-11-05 11:52:54 +11:00
04b1ce1aab fix: missing not found page for deleted documents (#1424) 2024-11-04 22:09:52 +09:00
885349ad94 fix: missing signing order when using templates (#1425) 2024-11-03 20:17:41 +09:00
28514ba2e7 fix: duplicate templates (#1434) 2024-11-01 21:29:38 +11:00
8aa6d8e602 chore: add translations (#1433) 2024-11-01 13:22:51 +09:00
378e515843 chore: extract translations 2024-11-01 12:56:07 +09:00
f42e600e3f chore: update workflow 2024-11-01 12:37:54 +09:00
88eaec91c9 chore: extract translations 2024-11-01 11:27:09 +09:00
f199183c78 feat: improve translation coverage (#1427)
Improves translation coverage across the app.
2024-11-01 10:57:32 +11:00
0cee07aed3 v1.7.2-rc.3 2024-10-31 15:33:03 +11:00
f76f87ff1c fix: use key for expansion on embeds 2024-10-31 15:31:40 +11:00
6020336792 v1.7.2-rc.2 2024-10-30 14:37:50 +11:00
634b30aa54 fix: signature flickering during embed 2024-10-30 14:36:35 +11:00
7fc497a642 fix: translation upload token (#1423) 2024-10-29 19:55:49 +09:00
e30ceeb038 style: update common.po (#1402)
Update translations
2024-10-28 11:26:12 +09:00
872762661a style: Update web.po (#1403)
Update translations
2024-10-28 11:23:08 +09:00
5fcd8610c9 fix: translate extract command (#1394)
Change how the translate extract command is run on build
2024-10-28 11:21:49 +09:00
b8310237e4 v1.7.2-rc.1 2024-10-23 13:28:54 +11:00
4a6238dc52 chore: show signing order when creating a document from template (#1410)
### Templates without signing order
![CleanShot 2024-10-18 at 01 27
24@2x](https://github.com/user-attachments/assets/222181e4-25a8-409b-aa8b-8452ddd32f6b)


### Template with signing order
![CleanShot 2024-10-18 at 01 26
12@2x](https://github.com/user-attachments/assets/bcee6213-20b5-44d8-90ed-881825f49756)
2024-10-23 10:20:27 +11:00
6fa5f63b69 fix: trigger webhook when a direct link signer signs a document (#1409) 2024-10-23 09:50:23 +11:00
c7564ba8f7 chore: enable spanish (#1417)
Enables the spanish translation of the application:


![image](https://github.com/user-attachments/assets/eacf4800-272e-4458-abcc-4d6c6f3071cf)
2024-10-23 09:01:14 +11:00
eafd7c551b feat: add team user management endpoints to api (#1416)
## Description

Adds user management capabilities to our current API. Allows for adding,
removing, listing and updating members of a given team using a valid API
token.

## Related Issue

N/A

## Changes Made

- Added an endpoint for inviting a team member
- Added an endpoint for removing a team member
- Added an endpoint for updating a team member
- Added an endpoint for listing team members

## Testing Performed

Tests were written for this feature request
2024-10-22 22:53:31 +11:00
514edf01d3 chore: add translations (#1406) 2024-10-22 14:02:51 +11:00
1a73c68d07 fix: close direct link dialog when you click on save (#1412) 2024-10-21 15:33:21 +11:00
1a9dcadba5 feat: add typed signature (#1357)
Add the ability to insert typed signatures.

Once the signature field is placed on the document, a checkbox appears
in the document editor where the document owner can allow signers to add
typed signatures. Typed signatures are disabled by default.

![CleanShot 2024-09-30 at 14 57
54](https://github.com/user-attachments/assets/c388abb5-bcb1-49d0-aad8-9148c3020420)
2024-10-18 14:25:19 +11:00
e0c948c2ac feat: add custom font sizes to fields (#1376)
Adds custom font sizes to fields

https://github.com/user-attachments/assets/1473a4d7-8dc6-4ead-acf5-dd78be7782a0
2024-10-16 16:05:41 +11:00
0bd2760792 feat: start the work on the API reference (#1392)
`later`

## 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. -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
	- Introduced comprehensive documentation for the Documenso public API.
	- Added detailed guides for the following API endpoints:
		- Uploading documents
		- Generating documents from templates
		- Adding fields to documents
- Included example payloads and response structures for better
understanding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-15 14:05:39 +03:00
abc559d923 chore: cal.com customer story article (#1396)
We got cal.com 🚀

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a new blog post detailing Cal.com's use of Documenso for
enhancing DPA and BAA processes.
- The blog outlines the challenges and solutions related to compliance
document management.
- Features images and captions to illustrate key points and improve
engagement.

- **Documentation**
- Added insights into Cal.com's journey as an open-source scheduling
solution and their commitment to transparency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-11 16:01:57 +02:00
9ffdbe9c81 fix: improve lingui configuration (#1388)
## Description

Currently merge conflicts arise due to the compiled JS and PO
translation files.

This PR is a rework on how we handle extracting and compiling
translations to streamline PRs and merging branches.

## Changes Made

- Remove compiled translation files from being committed
- Extract and compile translations only on build
- Extract will still occur when commits land on main to sync and pull
new translations with Crowdin
2024-10-09 14:13:52 +11:00
2c1a18bafc fix: stacked avatar colors (#1361) 2024-10-09 12:25:56 +11:00
a2db5e9642 chore: update changelog 2024-10-09 12:23:38 +11:00
4ec9dc78c1 chore: add translations (#1359) 2024-10-09 10:55:21 +11:00
faf2bd5384 v1.7.2-rc.0 2024-10-08 21:56:44 +11:00
d40ed94b74 feat: highlight problematic fields (#1330) 2024-10-08 21:55:20 +11:00
cd3d9b701b fix: external id null for documents created from templates (#1362) 2024-10-08 21:45:16 +11:00
e40f47a73c feat: search documents by name or recipient name or recipient email (#1384) 2024-10-08 21:44:02 +11:00
64ea4a6f9f chore: add translation contribution docs (#1379) 2024-10-08 14:05:55 +11:00
18115e95d7 feat: add recipient email in activity log (#1386) 2024-10-08 14:05:12 +11:00
e736261056 fix: show the full count of documents (#1382)
![doc-count](https://github.com/user-attachments/assets/aad4fe92-e2d8-4b78-ac93-5f6ada73b03a)

A client requested it, and it makes sense showing the full count.

This is how it was before.

![CleanShot 2024-10-04 at 08 47
16@2x](https://github.com/user-attachments/assets/bd4c97a5-1805-4faa-bae7-feeb932ed614)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Updated document status tab counts to display actual numbers without
capping at 99 or using '+' symbols.

- **Bug Fixes**
- Improved clarity and accuracy of document status counts in the user
interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-04 16:07:20 +10:00
2e57da7549 chore: open page data update (#1380) 2024-10-04 13:14:54 +10:00
574454db0a chore: Go Fork Yourself blog article (#1375)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new blog post titled "Go Fork Yourself," discussing the
philosophy of open-source software and the significance of forking
within the OSS community, along with real-world examples and an
invitation for reader engagement.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-03 14:25:32 +02:00
f05b670d93 fix: carousel slide change handling and video reset (#1364) 2024-10-03 10:52:43 +10:00
318149fbf3 chore: field fonts (#1350)
Before
![CleanShot 2024-09-16 at 12 25
44](https://github.com/user-attachments/assets/9ca7672d-b132-4c24-80b0-03fa13822e50)


After
![CleanShot 2024-09-16 at 12 24
07](https://github.com/user-attachments/assets/9e17b025-8064-4151-a9e2-817108b8da2a)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a new font style for signature fields, enhancing visual
distinction.
	- Increased text size for signature fields to improve prominence.

- **Bug Fixes**
- Adjusted the text size for signature display on larger screens for
better visual hierarchy.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-02 17:45:16 +10:00
5f19dcf25c fix: dateformat bug (#1372)
## Description

It used the wrong property for finding the document's dateFormat in the
`DATE_FORMATS` array.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Improved date format selection in the settings form to ensure accurate
formatting based on value.
- Default timezone now automatically set to the user's local timezone
for better user experience.

- **Bug Fixes**
- Corrected initialization of the timezone field to enhance form
accuracy.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-10-02 17:42:15 +10:00
c99cf4b848 chore: prisma customer story on blog (#1366)
prisma customer story on blog

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a customer story blog post detailing why Prisma chose
Documenso for their signing needs, highlighting four key reasons.
- Added author information and metadata for enhanced content engagement.
- Included links to additional resources and social media for reader
interaction.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-09-27 18:35:50 +02:00
18ec40f6af fix: set lang cookie expiry (#1365)
## Description

Currently the language cookie is set to session, so restarting browser
will reset it.

This sets the expiry for two years.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced language preference functionality with extended cookie
lifespan for improved user experience.
  
- **Bug Fixes**
	- Resolved issues related to cookie expiration for language settings.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-09-25 13:10:24 +10:00
ddee8a8272 feat: allow editing pending documents (#1346)
## Description

Adds the ability for the document owner to edit recipients and their
fields after the document has been sent.

A recipient can only be updated or deleted if:
- The recipient has not inserted any fields
- Has not completed the document

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Added new localization messages to clarify user actions regarding
document signing.
  - Enhanced French translations for improved user interaction.

- **Improvements**
- Updated localization strings in German and English for clearer
feedback on signer and recipient statuses.
- Improved overall structure of localization files for better
maintainability.

- **Dependency Updates**
- Upgraded `next-axiom` and `remeda` libraries to their latest versions,
potentially enhancing performance and stability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Mythie <me@lucasjamessmith.me>
2024-09-20 13:58:21 +10:00
efb2bc94ab feat: add french (#1355)
## Description

Add initial French translations

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for the French language, enhancing accessibility for
French-speaking users.
- Introduced localized French messages for various application
functionalities, improving user experience.
  
- **Bug Fixes**
- Minor formatting updates in French translation files to remove
extraneous newline characters.

- **Chores**
- Updated line references in French translation files to maintain
alignment with code changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@documenso.com>
2024-09-19 19:37:17 +10:00
97ee69e7a0 chore: add translations (#1354)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@documenso.com>
2024-09-19 16:17:16 +10:00
3da344fc5f v1.7.1-rc.3 2024-09-19 13:55:35 +10:00
404ca3202f chore: update action auth 2024-09-19 13:45:39 +10:00
c043fa9c06 fix: add check for invalid locales (#1353)
## Description

Currently invalid or missing `accept-language` headers will cause issues
rendering Plural components since we do not validate them.

This adds a check to try filter out invalid locales.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced locale filtering process to ensure only valid locales are
processed.
  
- **Bug Fixes**
- Improved data integrity by preventing invalid locales from affecting
application functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-09-19 09:58:59 +10:00
9852e8971f v1.7.1-rc.2 2024-09-18 11:05:19 +10:00
5091112e4b fix: dont nullify externalId if not passed to update document settings 2024-09-18 11:00:48 +10:00
e76f732990 fix: completed signing page layout (#1349) 2024-09-18 10:54:00 +10:00
b7c3deb6cd chore: smaller text in signature pad (#1351) 2024-09-18 10:44:12 +10:00
08114f7b97 chore: add translations (#1327) 2024-09-18 10:43:43 +10:00
6e368cc333 chore: add document visibility section (#1352) 2024-09-18 02:41:57 +10:00
4ce4ca3f34 v1.7.1-rc.1 2024-09-17 15:26:38 +10:00
7644c0d855 feat: support smaller field bounds (#1344)
Currently this won't always display super well since
our insertion solution isn't amazing but our current
minimum bounds within the UI are a bit large and can be
smaller.

This change makes it smaller and uses container queries to
support dynamically displaying labels based on the container
size.
2024-09-17 00:29:42 +10:00
fa6453e811 feat: document visibility (#1262)
Adds the ability to set a visibility scope for documents within teams.
2024-09-17 00:14:16 +10:00
f7a20113e5 fix: fix passkeys page-breaking error (#1348) 2024-09-16 22:57:31 +10:00
3d644db286 feat: signing order (#1290)
Adds the ability to specify an optional signing order for documents.
When specified a document will be considered sequential with recipients
only being allowed to sign in the order that they were specified in.
2024-09-16 22:36:45 +10:00
357bdd374f feat: add language switcher (#1337)
## Description

Web changes:

- Enabled i18n for web
- Add option to change language in command menu
- Add option to change language in menu-switcher

Web and marketing changes:

- Stop setting 'en' preference into cookie if the user's language is not
supported
- Dropped middleware changes
- Rotated cookie from 'i18n' to 'language'

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a language switcher in the footer for improved language
selection.
	- Added dynamic language change functionality in the command menu.
- Implemented a dropdown menu item for quick access to the language
switcher.

- **Bug Fixes**
- Resolved issues related to language change notifications and state
management.

- **Translations**
- Added new translation entries for improved language support, including
"Search languages..." in English and German.
	- Updated existing translations to enhance clarity and accuracy.

- **Chores**
	- Simplified internationalization handling in middleware.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions <github-actions@documenso.com>
2024-09-11 13:22:43 +10:00
7b06b68572 v1.7.1-rc.0 2024-09-10 23:15:02 +10:00
9ee89346b1 fix: template with empty advanced fields backend (#1340)
extension of https://github.com/documenso/documenso/pull/1339
2024-09-10 21:35:35 +10:00
77da7847d9 fix: template with empty advanced fields (#1339)
Templates can be created and sent with advanced fields that have empty
values. That will cause an error when the user tries to sign the
document.

For example, you can create a template with a checkbox field and save
it. Then, you can click the "Use template" button and send the document
by clicking "Send document." However, this shouldn't be possible if the
advanced field doesn't have any values.
2024-09-10 16:23:16 +10:00
c36306d2c9 feat: add authOptions to the API (#1338)
Add the authOptions property to the document and
recipient related API endpoints.

These were previously missing so the only way API
users could set the authOptions was via templates
and using the generateTemplate endpoint.
2024-09-10 15:07:40 +10:00
f6f893fbf7 fix: prefill advanced field settings in templates (#1332)
## Description

Seems like I was overconfident in #1323 and I did not test properly.
Currently, the advanced settings for a field in a **template** is not
pre-filled with the current fieldMeta, although it is correctly
pre-filled in a **draft document** (That's probably where I messed up my
testing).

In this PR, I propose to directly use the fieldMeta provided by the
field prop in `FieldAdvancedSettings`, instead of multiplying tRPCs to
request the fieldMeta while we already have it.

I apologize for the wasted time in reviewing my previous PR which was
only correcting the display of the field label in the template view.

## Testing Performed

- This time, I correctly checked that the advanced settings for a field
is correctly pre-filled both in a document draft and in a template.
- `npm run build` builds correctly.
2024-09-10 13:22:03 +10:00
e1b2206d28 fix: select field ux (#1334)
When the Select field has a default value, it automatically signs with
it. If you change it, you need to refresh the page to re-sign again with
that value. This PR improves the UX by making the default value
"selectable" in the dropdown menu.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Updated the `DropdownField` component to simplify the handling of
default values, ensuring the dropdown starts without a pre-selected
option.
- Improved the clarity of the placeholder text in the dropdown,
enhancing user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-09-10 13:15:47 +10:00
ad135b72d8 feat: marketing cta (#1335)
---
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. -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a new `CallToAction` component to enhance user engagement
in the self-hosting documentation.
- Added interactive call-to-action elements in the self-hosting
documentation pages to guide users towards specific actions.

- **Documentation**
- Updated self-hosting documentation to include the new call-to-action
feature, improving usability and interactivity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-09-10 12:42:12 +10:00
e81023f8d4 fix: refactor dates (#1321)
## Description

Refactor the current date formatting system to utilize Lingui.

## Changes Made

- Remove redundant `LocaleData` component with Lingui dates

## Important notes

For the internal pages for certificates, default to en-US to format any
dates.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Enhanced internationalization support across various components by
utilizing the `i18n` object for date formatting.
- Streamlined locale management by removing cookie-based language
handling and adopting a more centralized approach.

- **Bug Fixes**
- Improved date formatting consistency by replacing the `LocaleDate`
component with direct calls to `i18n.date()` in multiple components.

- **Documentation**
- Updated localization strings in the `web.po` files to reflect recent
changes in the source code structure.

- **Chores**
- Minor formatting adjustments and code organization improvements across
various files to enhance readability and maintainability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions <github-actions@documenso.com>
2024-09-10 12:38:08 +10:00
bfb09e7928 v1.7.0 2024-09-09 11:20:33 +10:00
1830 changed files with 170699 additions and 71727 deletions

75
.cursorrules Normal file
View File

@ -0,0 +1,75 @@
You are an expert in TypeScript, Node.js, Remix, React, Shadcn UI and Tailwind.
Code Style and Structure:
- Write concise, technical TypeScript code with accurate examples
- Use functional and declarative programming patterns; avoid classes
- Prefer iteration and modularization over code duplication
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
- Structure files: exported component, subcomponents, helpers, static content, types
Naming Conventions:
- Use lowercase with dashes for directories (e.g., components/auth-wizard)
- Favor named exports for components
TypeScript Usage:
- Use TypeScript for all code; prefer types over interfaces
- Use functional components with TypeScript interfaces
Syntax and Formatting:
- Create functions using `const fn = () => {}`
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
- Use declarative JSX
- Never use 'use client'
- Never use 1 line if statements
Error Handling and Validation:
- Prioritize error handling: handle errors and edge cases early
- Use early returns and guard clauses
- Implement proper error logging and user-friendly messages
- Use Zod for form validation
- Model expected errors as return values in Server Actions
- Use error boundaries for unexpected errors
UI and Styling:
- Use Shadcn UI, Radix, and Tailwind Aria for components and styling
- Implement responsive design with Tailwind CSS; use a mobile-first approach
- When using Lucide icons, prefer the longhand names, for example HomeIcon instead of Home
React forms
- Use zod for form validation react-hook-form for forms
- Look at TeamCreateDialog.tsx as an example of form usage
- Use <Form> <FormItem> elements, and also wrap the contents of form in a fieldset which should have the :disabled attribute when the form is loading
TRPC Specifics
- Every route should be in it's own file, example routers/teams/create-team.ts
- Every route should have a types file associated with it, example routers/teams/create-team.types.ts. These files should have the OpenAPI meta, and request/response zod schemas
- The request/response schemas should be named like Z[RouteName]RequestSchema and Z[RouteName]ResponseSchema
- Use create-team.ts and create-team.types.ts as an example when creating new routes.
- When creating the OpenAPI meta, only use GET and POST requests, do not use any other REST methods
- Deconstruct the input argument on it's one line of code.
Toast usage
- Use the t`string` macro from @lingui/react/macro to display toast messages
Remix/ReactRouter Usage
- Use (params: Route.Params) to get the params from the route
- Use (loaderData: Route.LoaderData) to get the loader data from the route
- When using loaderdata, deconstruct the data you need from the loader data inside the function body
- Do not use json() to return data, directly return the data
Translations
- Use <Trans>string</Trans> to display translations in jsx code, this should be imported from @lingui/react/macro
- Use the t`string` macro from @lingui/react/macro to display translations in typescript code
- t should be imported as const { t } = useLingui() where useLingui is imported from @lingui/react/macro
- String in constants should be using the t`string` macro

View File

@ -10,13 +10,7 @@
"ghcr.io/devcontainers/features/node:1": {}
},
"onCreateCommand": "./.devcontainer/on-create.sh",
"forwardPorts": [
3000,
54320,
9000,
2500,
1100
],
"forwardPorts": [3000, 54320, 9000, 2500, 1100],
"customizations": {
"vscode": {
"extensions": [
@ -35,4 +29,4 @@
]
}
}
}
}

View File

@ -1,5 +1,4 @@
# [[AUTH]]
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="secret"
# [[CRYPTO]]
@ -19,14 +18,10 @@ NEXT_PRIVATE_OIDC_WELL_KNOWN=""
NEXT_PRIVATE_OIDC_CLIENT_ID=""
NEXT_PRIVATE_OIDC_CLIENT_SECRET=""
NEXT_PRIVATE_OIDC_PROVIDER_LABEL="OIDC"
# This can be used to still allow signups for OIDC connections
# when signup is disabled via `NEXT_PUBLIC_DISABLE_SIGNUP`
NEXT_PRIVATE_OIDC_ALLOW_SIGNUP=""
NEXT_PRIVATE_OIDC_SKIP_VERIFY=""
# [[URLS]]
NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
NEXT_PUBLIC_MARKETING_URL="http://localhost:3001"
# URL used by the web app to request itself (e.g. local background jobs)
NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000"
@ -93,6 +88,8 @@ NEXT_PRIVATE_SMTP_UNSAFE_IGNORE_TLS=
NEXT_PRIVATE_SMTP_FROM_NAME="Documenso"
# REQUIRED: Defines the email address to use as the from address.
NEXT_PRIVATE_SMTP_FROM_ADDRESS="noreply@documenso.com"
# OPTIONAL: Defines the service for nodemailer
NEXT_PRIVATE_SMTP_SERVICE=
# OPTIONAL: The API key to use for Resend.com
NEXT_PRIVATE_RESEND_API_KEY=
# OPTIONAL: The API key to use for MailChannels.
@ -111,13 +108,9 @@ NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5
# [[STRIPE]]
NEXT_PRIVATE_STRIPE_API_KEY=
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET=
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID=
NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID=
# [[BACKGROUND JOBS]]
NEXT_PRIVATE_JOBS_PROVIDER="local"
NEXT_PRIVATE_TRIGGER_API_KEY=
NEXT_PRIVATE_TRIGGER_API_URL=
NEXT_PRIVATE_INNGEST_EVENT_KEY=
# [[FEATURES]]
@ -133,7 +126,5 @@ E2E_TEST_AUTHENTICATE_USERNAME="Test User"
E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
# This is only required for the marketing site
# [[REDIS]]
NEXT_PRIVATE_REDIS_URL=
NEXT_PRIVATE_REDIS_TOKEN=
# [[LOGGER]]
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=

View File

@ -5,6 +5,7 @@ module.exports = {
rules: {
'@next/next/no-img-element': 'off',
'no-unreachable': 'error',
'react-hooks/exhaustive-deps': 'off',
},
settings: {
next: {

View File

@ -1,24 +0,0 @@
name: Cache production build binaries
description: 'Cache or restore if necessary'
inputs:
node_version:
required: false
default: v20.x
runs:
using: 'composite'
steps:
- name: Cache production build
uses: actions/cache@v3
id: production-build-cache
with:
path: |
${{ github.workspace }}/apps/web/.next
${{ github.workspace }}/apps/marketing/.next
**/.turbo/**
**/dist/**
key: prod-build-${{ github.run_id }}-${{ hashFiles('package-lock.json') }}
restore-keys: prod-build-
- run: npm run build
shell: bash

View File

@ -2,7 +2,7 @@ name: 'Setup node and cache node_modules'
inputs:
node_version:
required: false
default: v20.x
default: v22.x
runs:
using: 'composite'

View File

@ -11,16 +11,6 @@ updates:
- 'ci'
open-pull-requests-limit: 0
- package-ecosystem: 'npm'
directory: '/apps/marketing'
schedule:
interval: 'weekly'
target-branch: 'main'
labels:
- 'npm dependencies'
- 'frontend'
open-pull-requests-limit: 0
- package-ecosystem: 'npm'
directory: '/apps/web'
schedule:

3
.github/labeler.yml vendored
View File

@ -1,6 +1,3 @@
'apps: marketing':
- apps/marketing/**
'apps: web':
- apps/web/**

View File

@ -26,7 +26,8 @@ jobs:
- name: Copy env
run: cp .env.example .env
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
build_docker:
name: Build Docker Image

View File

@ -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

View File

@ -30,7 +30,8 @@ jobs:
- uses: ./.github/actions/node-install
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
- name: Initialize CodeQL
uses: github/codeql-action/init@v3

View File

@ -1,14 +1,14 @@
name: Playwright Tests
on:
push:
branches: ['main']
branches: ['main', 'feat/rr7']
pull_request:
branches: ['main']
jobs:
e2e_tests:
name: 'E2E Tests'
timeout-minutes: 60
runs-on: ubuntu-latest
runs-on: warp-ubuntu-2204-x64-16x
steps:
- uses: actions/checkout@v4
@ -28,7 +28,11 @@ jobs:
- name: Seed the database
run: npm run prisma:seed
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
- name: Install playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npm run ci

View File

@ -89,22 +89,35 @@ jobs:
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 \
# Check if the version is stable (no rc or beta in the version)
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
docker manifest create \
documenso/documenso:latest \
--amend documenso/documenso-amd64:latest \
--amend documenso/documenso-arm64:latest
docker manifest push documenso/documenso:latest
fi
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
docker manifest create \
documenso/documenso:rc \
--amend documenso/documenso-amd64:rc \
--amend documenso/documenso-arm64:rc
docker manifest push documenso/documenso:rc
fi
docker manifest create \
documenso/documenso:$GIT_SHA \
--amend documenso/documenso-amd64:$GIT_SHA \
--amend documenso/documenso-arm64:$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 \
--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
@ -113,21 +126,34 @@ jobs:
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 \
# Check if the version is stable (no rc or beta in the version)
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
docker manifest create \
ghcr.io/documenso/documenso:latest \
--amend ghcr.io/documenso/documenso-amd64:latest \
--amend ghcr.io/documenso/documenso-arm64:latest
docker manifest push ghcr.io/documenso/documenso:latest
fi
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
docker manifest create \
ghcr.io/documenso/documenso:rc \
--amend ghcr.io/documenso/documenso-amd64:rc \
--amend ghcr.io/documenso/documenso-arm64:rc
docker manifest push ghcr.io/documenso/documenso:rc
fi
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 \
--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 \
--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

View File

@ -1,38 +0,0 @@
# Extract and compile translations for all PRs.
name: 'Extract and compile translations'
on:
workflow_call:
pull_request:
branches: ['main']
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
extract_translations:
name: Extract and compile translations
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- uses: ./.github/actions/node-install
- name: Extract and compile translations
run: |
npm run translate:extract
npm run translate:compile
- name: Check and commit any files created
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@documenso.com'
git add packages/lib/translations
git diff --staged --quiet --exit-code || (git commit -m "chore: extract translations" && git push)

View File

@ -21,14 +21,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ secrets.GH_PAT }}
- uses: ./.github/actions/node-install
- name: Extract and compile translations
run: |
npm run translate:extract
npm run translate:compile
- name: Extract translations
run: npm run translate:extract
- name: Check and commit any files created
run: |

View File

@ -4,9 +4,7 @@ tasks:
npm run dx:up &&
cp .env.example .env &&
set -a; source .env &&
export NEXTAUTH_URL="$(gp url 3000)" &&
export NEXT_PUBLIC_WEBAPP_URL="$(gp url 3000)" &&
export NEXT_PUBLIC_MARKETING_URL="$(gp url 3001)"
command: npm run d
ports:

View File

@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run commitlint -- $1

View File

@ -1,21 +1,9 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
echo "Copying pdf.js"
npm run copy:pdfjs --workspace apps/**
echo "Copying .well-known/ contents"
node "$MONOREPO_ROOT/scripts/copy-wellknown.cjs"
git add "$MONOREPO_ROOT/apps/web/public/"
git add "$MONOREPO_ROOT/apps/marketing/public/"
echo "Extract and compile translations"
npm run translate:extract
npm run translate:compile
git add "$MONOREPO_ROOT/packages/lib/translations/"
git add "$MONOREPO_ROOT/apps/remix/public/"
npx lint-staged

2
.npmrc
View File

@ -1 +1,3 @@
auto-install-peers = true
legacy-peer-deps = true
prefer-dedupe = true

View File

@ -69,9 +69,9 @@ Contact us if you are interested in our Enterprise plan for large organizations
<a href="https://cal.com/timurercan/enterprise-customers?utm_source=banner&utm_campaign=oss"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>
## Tech Stack
<p align="left">
<a href="https://www.typescriptlang.org"><img src="https://shields.io/badge/TypeScript-3178C6?logo=TypeScript&logoColor=FFF&style=flat-square" alt="TypeScript"></a>
<a href="https://nextjs.org/"><img src="https://img.shields.io/badge/next.js-000000?style=flat-square&logo=nextdotjs&logoColor=white" alt="NextJS"></a>
<a href="https://prisma.io"><img width="122" height="20" src="http://made-with.prisma.io/indigo.svg" alt="Made with Prisma" /></a>
<a href="https://tailwindcss.com/"><img src="https://img.shields.io/badge/tailwindcss-0F172A?&logo=tailwindcss" alt="Tailwind CSS"></a>
<a href=""><img src="" alt=""></a>
@ -81,20 +81,17 @@ Contact us if you are interested in our Enterprise plan for large organizations
<a href=""><img src="" alt=""></a>
</p>
- [Typescript](https://www.typescriptlang.org/) - Language
- [Next.js](https://nextjs.org/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [ReactRouter](https://reactrouter.com/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [Tailwind](https://tailwindcss.com/) - CSS
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
- [NextAuth.js](https://next-auth.js.org/) - Authentication
- [react-email](https://react.email/) - Email Templates
- [tRPC](https://trpc.io/) - API
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures (launching soon)
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
- [Stripe](https://stripe.com/) - Payments
- [Vercel](https://vercel.com) - Hosting
<!-- - Support for [opensignpdf (requires Java on server)](https://github.com/open-pdf-sign) is currently planned. -->
@ -104,7 +101,7 @@ Contact us if you are interested in our Enterprise plan for large organizations
To run Documenso locally, you will need
- Node.js (v18 or above)
- Node.js (v22 or above)
- Postgres SQL Database
- Docker (optional)
@ -167,10 +164,8 @@ git clone https://github.com/<your-username>/documenso
4. Set the following environment variables:
- NEXTAUTH_URL
- NEXTAUTH_SECRET
- NEXT_PUBLIC_WEBAPP_URL
- NEXT_PUBLIC_MARKETING_URL
- NEXT_PRIVATE_DATABASE_URL
- NEXT_PRIVATE_DIRECT_DATABASE_URL
- NEXT_PRIVATE_SMTP_FROM_NAME
@ -239,29 +234,27 @@ cp .env.example .env
The following environment variables must be set:
- `NEXTAUTH_URL`
- `NEXTAUTH_SECRET`
- `NEXT_PUBLIC_WEBAPP_URL`
- `NEXT_PUBLIC_MARKETING_URL`
- `NEXT_PRIVATE_DATABASE_URL`
- `NEXT_PRIVATE_DIRECT_DATABASE_URL`
- `NEXT_PRIVATE_SMTP_FROM_NAME`
- `NEXT_PRIVATE_SMTP_FROM_ADDRESS`
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for both `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for the `NEXT_PUBLIC_WEBAPP_URL` variable!
Now you can install the dependencies and build it:
```
npm i
npm run build:web
npm run build
npm run prisma:migrate-deploy
```
Finally, you can start it with:
```
cd apps/web
cd apps/remix
npm run start
```
@ -282,7 +275,7 @@ After=network.target
Environment=PATH=/path/to/your/node/binaries
Type=simple
User=www-data
WorkingDirectory=/var/www/documenso/apps/web
WorkingDirectory=/var/www/documenso/apps/remix
ExecStart=/usr/bin/next start -p 3500
TimeoutSec=15
Restart=always

View File

@ -34,3 +34,8 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
# next-sitemap output
/public/sitemap.xml
/public/robots.txt
/public/sitemap-*.xml

View File

@ -1,36 +1 @@
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:3002](http://localhost:3002) 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.
# @documenso/documentation

View File

@ -0,0 +1,35 @@
import Link from 'next/link';
import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card';
type CallToActionProps = {
className?: string;
utmSource?: string;
};
export const CallToAction = ({ className, utmSource = 'generic-cta' }: CallToActionProps) => {
return (
<Card spotlight className={className}>
<CardContent className="flex flex-col items-center justify-center p-12">
<h2 className="text-center text-2xl font-bold">Looking for the managed solution?</h2>
<p className="text-muted-foreground mt-4 max-w-[55ch] text-center leading-normal">
You can get started with Documenso in minutes. We handle the infrastructure, so you can
focus on signing documents.
</p>
<Button
className="focus-visible:ring-ring ring-offset-background bg-primary text-primary-foreground hover:bg-primary/90text-sm mt-8 inline-flex items-center justify-center rounded-full border font-medium no-underline transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
variant="default"
size="lg"
asChild
>
<Link href={`https://app.documenso.com/signup?utm_source=${utmSource}`} target="_blank">
Get started
</Link>
</Button>
</CardContent>
</Card>
);
};

View File

@ -0,0 +1,5 @@
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://docs.documenso.com', // Replace with your actual site URL
generateRobotsTxt: true, // Generates robots.txt
};

View File

@ -1,3 +1,5 @@
import nextra from 'nextra';
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: [
@ -9,9 +11,10 @@ const nextConfig = {
],
};
const withNextra = require('nextra')({
const withNextra = nextra({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx',
codeHighlight: true,
});
module.exports = withNextra(nextConfig);
export default withNextra(nextConfig);

View File

@ -4,11 +4,10 @@
"private": true,
"scripts": {
"dev": "next dev -p 3002",
"build": "next build",
"build": "next build && next-sitemap",
"start": "next start -p 3002",
"lint:fix": "next lint --fix",
"clean": "rimraf .next && rimraf node_modules",
"copy:pdfjs": "node ../../scripts/copy-pdfjs.cjs"
"clean": "rimraf .next && rimraf node_modules"
},
"dependencies": {
"@documenso/assets": "*",
@ -16,7 +15,7 @@
"@documenso/tailwind-config": "*",
"@documenso/trpc": "*",
"@documenso/ui": "*",
"next": "14.2.6",
"next": "14.2.28",
"next-plausible": "^3.12.0",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
@ -27,9 +26,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
"next-sitemap": "^4.2.3",
"typescript": "5.6.2"
}
}
}

View File

@ -4,7 +4,7 @@ import '../styles.css';
export default function App({ Component, pageProps }) {
return (
<PlausibleProvider>
<Component {...pageProps} />;
<Component {...pageProps} />
</PlausibleProvider>
);
}

View File

@ -5,6 +5,7 @@
"title": "Development & Deployment"
},
"local-development": "Local Development",
"developer-mode": "Developer Mode",
"self-hosting": "Self Hosting",
"contributing": "Contributing",
"-- API & Integration Guides": {
@ -14,4 +15,4 @@
"public-api": "Public API",
"embedding": "Embedding",
"webhooks": "Webhooks"
}
}

View File

@ -0,0 +1,4 @@
{
"index": "Getting Started",
"contributing-translations": "Contributing Translations"
}

View File

@ -0,0 +1,64 @@
---
title: Contributing Translations
description: Learn how to contribute translations to Documenso and become part of our community.
---
import { Callout, Steps } from 'nextra/components';
# Contributing Translations
We are always open for help with translations! Currently we utilise AI to generate the initial translations for new languages, which are then improved over time by our awesome community.
If you are looking for development notes on translations, you can find them [here](/developers/local-development/translations).
<Callout type="info">
Contributions are made through GitHub Pull Requests, so you will need a GitHub account to
contribute.
</Callout>
## Overview
We store our translations in PO files, which are located in our GitHub repository [here](https://github.com/documenso/documenso/tree/main/packages/lib/translations).
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc).
Each PO file contains translations which look like this:
```po
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:61
msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüfen Sie Documenso.</0>"
```
- `msgid`: The original text in English (never edit this manually)
- `msgstr`: The translated text in the target language
<Callout type="warning">
Notice the `<0>` tags? These represent HTML elements and must remain in both the `msgid` and `msgstr`. Make sure to translate the content between these tags while keeping the tags intact.
</Callout>
## How to Contribute
### Updating Existing Translations
1. Fork the repository.
2. Navigate to the appropriate language folder and open the PO file you want to update.
3. Make your changes, ensuring you follow the PO file format.
4. Commit your changes with a message such as `chore: update German translations`
5. Create a Pull Request.
### Adding a New Language
If you want to add translations for a language that doesn't exist yet:
1. Create an issue in our GitHub repository requesting the addition of the new language.
2. Wait for our team to review and approve the request.
3. Once approved, we will set up the necessary files and kickstart the translations with AI to provide initial coverage.
## Need Help?
<Callout type="info">
If you have any questions, hop into our [Discord](https://documen.so/discord) and ask us directly!
</Callout>
Thank you for helping make Documenso more accessible to users around the world!

View File

@ -1,5 +1,5 @@
---
title: Contributing Guide
title: Getting started
description: Learn how to contribute to Documenso and become part of our community.
---

View File

@ -0,0 +1,18 @@
---
title: Field Coordinates
description: Learn how to get the coordinates of a field in a document.
---
## Field Coordinates
Field coordinates represent the position of a field in a document. They are returned in the `pageX` and `pageY` properties of the field.
To enable field coordinates, you can use the `devmode` query parameter.
```bash
https://app.documenso.com/documents/<document-id>/edit?devmode=true
```
You should then see the coordinates on top of each field.
![Field Coordinates](/developer-mode/field-coordinates.webp)

View File

@ -0,0 +1,11 @@
{
"index": "Get Started",
"react": "React Integration",
"vue": "Vue Integration",
"svelte": "Svelte Integration",
"solid": "Solid Integration",
"preact": "Preact Integration",
"angular": "Angular Integration",
"css-variables": "CSS Variables",
"authoring": "Authoring"
}

View File

@ -0,0 +1,90 @@
---
title: Angular Integration
description: Learn how to use our embedding SDK within your Angular application.
---
# Angular Integration
Our Angular SDK provides a simple way to embed a signing experience within your Angular application. It supports both direct link templates and signing tokens.
## Installation
To install the SDK, run the following command:
```bash
npm install @documenso/embed-angular
```
## Usage
To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case.
### Direct Link Template
If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component.
```typescript
import { Component } from '@angular/core';
import { EmbedDirectTemplate } from '@documenso/embed-angular';
@Component({
selector: 'app-embedding',
template: `
<embed-direct-template [token]="token" />
`,
standalone: true,
imports: [EmbedDirectTemplate],
})
export class EmbeddingComponent {
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
}
```
#### Props
| Prop | Type | Description |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
| token | string | The token for the document you want to embed |
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
| name | string (optional) | The name the signer that will be used by default for signing |
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
| onFieldSigned | function (optional) | A callback function that will be called when a field is signed |
| onFieldUnsigned | function (optional) | A callback function that will be called when a field is unsigned |
### Signing Token
If you have a signing token, you can provide it to the `EmbedSignDocument` component.
```typescript
import { Component } from '@angular/core';
import { EmbedSignDocument } from '@documenso/embed-angular';
@Component({
selector: 'app-embedding',
template: `
<embed-sign-document [token]="token" />
`,
standalone: true,
imports: [EmbedSignDocument],
})
export class EmbeddingComponent {
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
}
```
#### Props
| Prop | Type | Description |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
| token | string | The token for the document you want to embed |
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
| name | string (optional) | The name the signer that will be used by default for signing |
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |

View File

@ -0,0 +1,167 @@
---
title: Authoring
description: Learn how to use embedded authoring to create documents and templates in your application
---
# Embedded Authoring
In addition to embedding signing experiences, Documenso now supports embedded authoring, allowing you to integrate document and template creation directly within your application.
## How Embedded Authoring Works
The embedded authoring feature enables your users to create new documents without leaving your application. This process works through secure presign tokens that authenticate the embedding session and manage permissions.
## Creating Documents with Embedded Authoring
To implement document creation in your application, use the `EmbedCreateDocument` component from our SDK:
```jsx
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
const DocumentCreator = () => {
// You'll need to obtain a presign token using your API key
const presignToken = 'YOUR_PRESIGN_TOKEN';
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocument
presignToken={presignToken}
externalId="order-12345"
onDocumentCreated={(data) => {
console.log('Document created with ID:', data.documentId);
console.log('External reference ID:', data.externalId);
}}
/>
</div>
);
};
```
## Obtaining a Presign Token
Before using the `EmbedCreateDocument` component, you'll need to obtain a presign token from your backend. This token authorizes the embedding session.
You can create a presign token by making a request to:
```
POST /api/v2-beta/embedding/create-presign-token
```
This API endpoint requires authentication with your Documenso API key. The token has a default expiration of 1 hour, but you can customize this duration based on your security requirements.
You can find more details on this request at our [API Documentation](https://openapi.documenso.com/reference#tag/embedding)
## Configuration Options
The `EmbedCreateDocument` component accepts several configuration options:
| Option | Type | Description |
| ------------------ | ------- | ------------------------------------------------------------------ |
| `presignToken` | string | **Required**. The authentication token for the embedding session. |
| `externalId` | string | Optional reference ID from your system to link with the document. |
| `host` | string | Optional custom host URL. Defaults to `https://app.documenso.com`. |
| `css` | string | Optional custom CSS to style the embedded component. |
| `cssVars` | object | Optional CSS variables for colors, spacing, and more. |
| `darkModeDisabled` | boolean | Optional flag to disable dark mode. |
| `className` | string | Optional CSS class name for the iframe. |
## Feature Toggles
You can customize the authoring experience by enabling or disabling specific features:
```jsx
<EmbedCreateDocument
presignToken="YOUR_PRESIGN_TOKEN"
features={{
allowConfigureSignatureTypes: true,
allowConfigureLanguage: true,
allowConfigureDateFormat: true,
allowConfigureTimezone: true,
allowConfigureRedirectUrl: true,
allowConfigureCommunication: true,
}}
/>
```
## Handling Document Creation Events
The `onDocumentCreated` callback is triggered when a document is successfully created, providing both the document ID and your external reference ID:
```jsx
<EmbedCreateDocument
presignToken="YOUR_PRESIGN_TOKEN"
externalId="order-12345"
onDocumentCreated={(data) => {
// Navigate to a success page
navigate(`/documents/success?id=${data.documentId}`);
// Or update your database with the document ID
updateOrderDocument(data.externalId, data.documentId);
}}
/>
```
## Styling the Embedded Component
You can customize the appearance of the embedded component using standard CSS classes:
```jsx
<EmbedCreateDocument
className="h-screen w-full rounded-lg border-none shadow-md"
presignToken="YOUR_PRESIGN_TOKEN"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
/>
```
## Complete Integration Example
Here's a complete example of integrating document creation in a React application:
```tsx
import { useState } from 'react';
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
function DocumentCreator() {
// In a real application, you would fetch this token from your backend
// using your API key at /api/v2-beta/embedding/create-presign-token
const presignToken = 'YOUR_PRESIGN_TOKEN';
const [documentId, setDocumentId] = useState<number | null>(null);
if (documentId) {
return (
<div>
<h2>Document Created Successfully!</h2>
<p>Document ID: {documentId}</p>
<button onClick={() => setDocumentId(null)}>Create Another Document</button>
</div>
);
}
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocument
presignToken={presignToken}
externalId="order-12345"
onDocumentCreated={(data) => {
setDocumentId(data.documentId);
}}
/>
</div>
);
}
export default DocumentCreator;
```
With embedded authoring, your users can seamlessly create documents within your application, enhancing the overall user experience and streamlining document workflows.

View File

@ -0,0 +1,197 @@
---
title: CSS Variables
description: Learn about all available CSS variables for customizing your embedded signing experience
---
# CSS Variables
Platform customers have access to a comprehensive set of CSS variables that can be used to customize the appearance of the embedded signing experience. These variables control everything from colors to spacing and can be used to match your application's design system.
## Available Variables
### Colors
| Variable | Description | Default |
| ----------------------- | ---------------------------------- | -------------- |
| `background` | Base background color | System default |
| `foreground` | Base text color | System default |
| `muted` | Muted/subtle background color | System default |
| `mutedForeground` | Muted/subtle text color | System default |
| `popover` | Popover/dropdown background color | System default |
| `popoverForeground` | Popover/dropdown text color | System default |
| `card` | Card background color | System default |
| `cardBorder` | Card border color | System default |
| `cardBorderTint` | Card border tint/highlight color | System default |
| `cardForeground` | Card text color | System default |
| `fieldCard` | Field card background color | System default |
| `fieldCardBorder` | Field card border color | System default |
| `fieldCardForeground` | Field card text color | System default |
| `widget` | Widget background color | System default |
| `widgetForeground` | Widget text color | System default |
| `border` | Default border color | System default |
| `input` | Input field border color | System default |
| `primary` | Primary action/button color | System default |
| `primaryForeground` | Primary action/button text color | System default |
| `secondary` | Secondary action/button color | System default |
| `secondaryForeground` | Secondary action/button text color | System default |
| `accent` | Accent/highlight color | System default |
| `accentForeground` | Accent/highlight text color | System default |
| `destructive` | Destructive/danger action color | System default |
| `destructiveForeground` | Destructive/danger text color | System default |
| `ring` | Focus ring color | System default |
| `warning` | Warning/alert color | System default |
### Spacing and Layout
| Variable | Description | Default |
| -------- | ------------------------------- | -------------- |
| `radius` | Border radius size in REM units | System default |
## Usage Example
Here's how to use these variables in your embedding implementation:
```jsx
const cssVars = {
// Colors
background: '#ffffff',
foreground: '#000000',
primary: '#0000ff',
primaryForeground: '#ffffff',
accent: '#4f46e5',
destructive: '#ef4444',
// Spacing
radius: '0.5rem'
};
// React/Preact
<EmbedDirectTemplate
token={token}
cssVars={cssVars}
/>
// Vue
<EmbedDirectTemplate
:token="token"
:cssVars="cssVars"
/>
// Svelte
<EmbedDirectTemplate
{token}
cssVars={cssVars}
/>
// Solid
<EmbedDirectTemplate
token={token}
cssVars={cssVars}
/>
```
## Color Format
Colors can be specified in any valid CSS color format:
- Hexadecimal: `#ff0000`
- RGB: `rgb(255, 0, 0)`
- HSL: `hsl(0, 100%, 50%)`
- Named colors: `red`
The colors will be automatically converted to the appropriate format internally.
## Best Practices
1. **Maintain Contrast**: When customizing colors, ensure there's sufficient contrast between background and foreground colors for accessibility.
2. **Test Dark Mode**: If you haven't disabled dark mode, test your color variables in both light and dark modes.
3. **Use Your Brand Colors**: Align the primary and accent colors with your brand's color scheme for a cohesive look.
4. **Consistent Radius**: Use a consistent border radius value that matches your application's design system.
## CSS Class Targets
In addition to CSS variables, specific components in the embedded experience can be targeted using CSS classes for more granular styling:
### Component Classes
| Class Name | Description |
| --------------------------------- | ----------------------------------------------------------------------- |
| `.embed--Root` | Main container for the embedded signing experience |
| `.embed--DocumentContainer` | Container for the document and signing widget |
| `.embed--DocumentViewer` | Container for the document viewer |
| `.embed--DocumentWidget` | The signing widget container |
| `.embed--DocumentWidgetContainer` | Outer container for the signing widget, handles positioning |
| `.embed--DocumentWidgetHeader` | Header section of the signing widget |
| `.embed--DocumentWidgetContent` | Main content area of the signing widget |
| `.embed--DocumentWidgetForm` | Form section within the signing widget |
| `.embed--DocumentWidgetFooter` | Footer section of the signing widget |
| `.embed--WaitingForTurn` | Container for the waiting screen when it's not the user's turn to sign |
| `.embed--DocumentCompleted` | Container for the completion screen after signing |
| `.field--FieldRootContainer` | Base container for document fields (signatures, text, checkboxes, etc.) |
Field components also expose several data attributes that can be used for styling different states:
| Data Attribute | Values | Description |
| ------------------- | ---------------------------------------------- | ------------------------------------ |
| `[data-field-type]` | `SIGNATURE`, `TEXT`, `CHECKBOX`, `RADIO`, etc. | The type of field |
| `[data-inserted]` | `true`, `false` | Whether the field has been filled |
| `[data-validate]` | `true`, `false` | Whether the field is being validated |
### Field Styling Example
```css
/* Style all field containers */
.field--FieldRootContainer {
transition: all 200ms ease;
}
/* Style specific field types */
.field--FieldRootContainer[data-field-type='SIGNATURE'] {
background-color: rgba(0, 0, 0, 0.02);
}
/* Style inserted fields */
.field--FieldRootContainer[data-inserted='true'] {
background-color: var(--primary);
opacity: 0.2;
}
/* Style fields being validated */
.field--FieldRootContainer[data-validate='true'] {
border-color: orange;
}
```
### Example Usage
```css
/* Custom styles for the document widget */
.embed--DocumentWidget {
background-color: #ffffff;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
/* Custom styles for the waiting screen */
.embed--WaitingForTurn {
background-color: #f9fafb;
padding: 2rem;
}
/* Responsive adjustments for the document container */
@media (min-width: 768px) {
.embed--DocumentContainer {
gap: 2rem;
}
}
```
## Related
- [React Integration](/developers/embedding/react)
- [Vue Integration](/developers/embedding/vue)
- [Svelte Integration](/developers/embedding/svelte)
- [Solid Integration](/developers/embedding/solid)
- [Preact Integration](/developers/embedding/preact)

View File

@ -5,13 +5,17 @@ description: Learn how to use embedding to bring signing to your own website or
# Embedding
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, or using generalized web components, this guide will help you get started with embedding Documenso.
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, Angular, or using generalized web components, this guide will help you get started with embedding Documenso.
## Availability
Embedding is currently available for all users on a **Teams Plan** and above, as well as **Early Adopter's** within a team (Early Adopters can create a team for free).
In the future, we will roll out a **Platform Plan** that will offer additional enhancements for embedding, including the option to remove Documenso branding for a more customized experience.
Our **Platform Plan** offers enhanced customization features including:
- Custom CSS and styling variables
- Dark mode controls
- The removal of Documenso branding from the embedding experience
## How Embedding Works
@ -22,17 +26,61 @@ Embedding with Documenso allows you to handle document signing in two main ways:
_For most use-cases we recommend using direct templates, however if you have a need for a more advanced integration, we are happy to help you get started._
## Customization Options
### Styling and Theming
Platform customers have access to advanced styling options to customize the embedding experience:
1. **Custom CSS**: You can provide custom CSS to style the embedded component:
```jsx
<EmbedDirectTemplate
token={token}
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
/>
```
2. **CSS Variables**: Fine-tune the appearance using CSS variables for colors, spacing, and more:
```jsx
<EmbedDirectTemplate
token={token}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
/>
```
For a complete list of available CSS variables and their usage, see our [CSS Variables](/developers/embedding/css-variables) documentation.
3. **Dark Mode Control**: Disable dark mode if it doesn't match your application's theme:
```jsx
<EmbedDirectTemplate token={token} darkModeDisabled={true} />
```
These customization options are available for both Direct Templates and Signing Token embeds.
## Supported Frameworks
We support embedding across a range of popular JavaScript frameworks, including:
| Framework | Package |
| --------- | -------------------------------------------------------------------------------- |
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
| Framework | Package |
| --------- | ---------------------------------------------------------------------------------- |
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
| Angular | [@documenso/embed-angular](https://www.npmjs.com/package/@documenso/embed-angular) |
Additionally, we provide **web components** for more generalized use. However, please note that web components are still in their early stages and haven't been extensively tested.
@ -80,7 +128,7 @@ This will show a dialog which will ask you to configure which recipient should b
## Embedding with Signing Tokens
To embed the signing process for an ordinary document, youll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
To embed the signing process for an ordinary document, you'll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
#### Instructions
@ -117,15 +165,30 @@ Once you've obtained the appropriate tokens, you can integrate the signing exper
- [Vue](/developers/embedding/vue)
- [Svelte](/developers/embedding/svelte)
- [Solid](/developers/embedding/solid)
- [Angular](/developers/embedding/angular)
If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases.
## Stay Tuned for the Platform Plan
## Embedded Authoring
While embedding is already a powerful tool, we're working on a **Platform Plan** that will introduce even more functionality. This plan will offer:
In addition to embedding signing experiences, Documenso now supports **embedded authoring**, allowing your users to create documents and templates directly within your application.
- Additional customization options
- The ability to remove Documenso branding
- Additional controls for the signing experience
With embedded authoring, you can:
More details will be shared as we approach the release.
- Create new documents with custom fields
- Configure document properties and settings
- Set up recipients and signing workflows
- Customize the authoring experience
For detailed implementation instructions and code examples, see our [Embedded Authoring](/developers/embedding/authoring) guide.
## Related
- [React Integration](/developers/embedding/react)
- [Vue Integration](/developers/embedding/vue)
- [Svelte Integration](/developers/embedding/svelte)
- [Solid Integration](/developers/embedding/solid)
- [Preact Integration](/developers/embedding/preact)
- [Angular Integration](/developers/embedding/angular)
- [CSS Variables](/developers/embedding/css-variables)
- [Embedded Authoring](/developers/embedding/authoring)

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,30 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-preact';
const MyEmbeddingComponent = () => {
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
return (
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
);
};
```

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,34 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-react';
const MyEmbeddingComponent = () => {
return (
<EmbedDirectTemplate
token="your-token"
// Custom CSS
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
// CSS Variables
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
// Dark Mode Control
darkModeDisabled={true}
/>
);
};
```

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,30 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-solid';
const MyEmbeddingComponent = () => {
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
return (
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
);
};
```

View File

@ -46,6 +46,9 @@ If you have a direct link template, you can simply provide the token for the tem
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -77,3 +80,28 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```html
<script lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-svelte';
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<EmbedDirectTemplate {token} css="{customCss}" cssVars="{cssVars}" darkModeDisabled="{true}" />
```

View File

@ -46,6 +46,9 @@ If you have a direct link template, you can simply provide the token for the tem
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -77,3 +80,35 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```html
<script setup lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-vue';
const token = ref('your-token');
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<template>
<EmbedDirectTemplate
:token="token"
:css="customCss"
:cssVars="cssVars"
:darkModeDisabled="true"
/>
</template>
```

View File

@ -16,18 +16,16 @@ Pick the one that fits your needs the best.
## Tech Stack
- [Typescript](https://www.typescriptlang.org/) - Language
- [Next.js](https://nextjs.org/) - Framework
- [React Router](https://reactrouter.com/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [Tailwind](https://tailwindcss.com/) - CSS
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
- [NextAuth.js](https://next-auth.js.org/) - Authentication
- [react-email](https://react.email/) - Email Templates
- [tRPC](https://trpc.io/) - API
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
- [Stripe](https://stripe.com/) - Payments
- [Vercel](https://vercel.com) - Hosting
<div className="mt-16 flex items-center justify-center gap-4">
<a href="https://documen.so/discord">

View File

@ -32,10 +32,8 @@ Run `npm i` in the root directory to install the dependencies required for the p
Set up the following environment variables in the `.env` file:
```bash
NEXTAUTH_URL
NEXTAUTH_SECRET
NEXT_PUBLIC_WEBAPP_URL
NEXT_PUBLIC_MARKETING_URL
NEXT_PRIVATE_DATABASE_URL
NEXT_PRIVATE_DIRECT_DATABASE_URL
NEXT_PRIVATE_SMTP_FROM_NAME

View File

@ -11,6 +11,10 @@ Digitally signing documents requires a signing certificate in `.p12` format. You
Follow the steps below to create a free, self-signed certificate for local development.
<Callout type="warning">
These steps should be run on a UNIX based system, otherwise you may run into an error.
</Callout>
<Steps>
### Generate Private Key
@ -38,11 +42,17 @@ You will be prompted to enter some information, such as the certificate's Common
Combine the private key and the self-signed certificate to create a `.p12` certificate. Use the following command:
```bash
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt -legacy
```
<Callout type="warning">
If you get the error "Error: Failed to get private key bags", add the `-legacy` flag to the command `openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt -legacy`.
When running the application in Docker, you may encounter permission issues when attempting to sign documents using your certificate (.p12) file. This happens because the application runs as a non-root user inside the container and needs read access to the certificate.
To resolve this, you'll need to update the certificate file permissions to allow the container user 1001, which runs NextJS, to read it:
```bash
sudo chown 1001 certificate.p12
```
</Callout>
@ -54,8 +64,8 @@ Note that for local development, the password can be left empty.
### Add Certificate to the Project
Finally, add the certificate to the project. Place the `certificate.p12` file in the `/apps/web/resources` directory. If the directory doesn't exist, create it.
Use the `NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH` environment variable to point at the certificate you created.
The final file path should be `/apps/web/resources/certificate.p12`.
Details about environment variables associated with certificates can be found [here](/developers/self-hosting/signing-certificate#configure-documenso-to-use-the-certificate).
</Steps>

View File

@ -13,35 +13,13 @@ Documenso uses the following stack to handle translations:
Additional reading can be found in the [Lingui documentation](https://lingui.dev/introduction).
## Requirements
You **must** insert **`setupI18nSSR()`** when creating any of the following files:
- Server layout.tsx
- Server page.tsx
- Server loading.tsx
Server meaning it does not have `'use client'` in it.
```tsx
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
export default function SomePage() {
setupI18nSSR(); // Required if there are translations within the page, or nested in components.
// Rest of code...
}
```
Additional information can be found [here.](https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui)
## Quick guide
If you require more in-depth information, please see the [Lingui documentation](https://lingui.dev/introduction).
### HTML
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/macro** (not @lingui/react).
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/react/macro**.
```html
<h1>
@ -64,8 +42,9 @@ For text that is broken into elements, but represent a whole sentence, you must
### Constants outside of react components
```tsx
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
// Wrap text in msg`text to translate` when it's in a constant here, or another file/package.
export const CONSTANT_WITH_MSG = {
@ -98,31 +77,13 @@ Lingui provides a Plural component to make it easy. See full documentation [here
Lingui provides a [DateTime instance](https://lingui.dev/ref/core#i18n.date) with the configured locale.
#### Server components
Note that the i18n instance is coming from **setupI18nSSR**.
```tsx
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
const { i18n } = setupI18nSSR();
const { i18n } = useLingui();
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};
```
#### Client components
Note that the i18n instance is coming from the **import**.
```tsx
import { i18n } from '@lingui/core';
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};
```

View File

@ -3,6 +3,8 @@ title: Public API
description: Learn how to interact with your documents programmatically using the Documenso public API.
---
import { Callout, Steps } from 'nextra/components';
# Public API
Documenso provides a public REST API enabling you to interact with your documents programmatically. The API exposes various HTTP endpoints that allow you to perform operations such as:
@ -13,10 +15,35 @@ Documenso provides a public REST API enabling you to interact with your document
The documentation walks you through creating API keys and using them to authenticate your API requests. You'll also learn about the available endpoints, request and response formats, and how to use the API.
## Swagger Documentation
## API V1 - Stable
The [Swagger documentation](https://app.documenso.com/api/v1/openapi) also provides information about the API endpoints, request parameters, response formats, and authentication methods.
Check out the [API V1 documentation](https://app.documenso.com/api/v1/openapi) for details about the API endpoints, request parameters, response formats, and authentication methods.
## API V2 - Beta
<Callout type="warning">API V2 is currently beta, and will be subject to breaking changes</Callout>
Check out the [API V2 documentation](https://documen.so/api-v2-docs) for details about the API endpoints, request parameters, response formats, and authentication methods.
Our new API V2 supports the following typed SDKs:
- [TypeScript](https://github.com/documenso/sdk-typescript)
- [Python](https://github.com/documenso/sdk-python)
- [Go](https://github.com/documenso/sdk-go)
<Callout type="info">
For the staging API, please use the following base URL:
`https://stg-app.documenso.dev/api/v2-beta/`
</Callout>
🚀 [V2 Announcement](https://documen.so/sdk-blog)
📖 [Documentation](https://documen.so/api-v2-docs)
💬 [Leave Feedback](https://documen.so/sdk-feedback)
🔔 [Breaking Changes](https://documen.so/sdk-breaking)
## Availability
The API is available to individual users and teams.
The API is available to individual users, teams and higher plans. [Fair Use](https://documen.so/fair) applies.

View File

@ -0,0 +1,624 @@
---
title: API Reference
description: Reference documentation for the Documenso public API.
---
import { Callout, Steps } from 'nextra/components';
# API Reference
The Swagger UI for the API is available at [/api/v1/openapi](https://app.documenso.com/api/v1/openapi). This page provides detailed information about the API endpoints, request and response formats, and authentication requirements.
## Upload a Document
Uploading a document to your Documenso account requires a two-step process.
<Steps>
### Create Document
First, you need to make a `POST` request to the `/api/v1/documents` endpoint, which takes a JSON payload with the following fields:
```json
{
"title": "string",
"externalId": "string",
"recipients": [
{
"name": "string",
"email": "user@example.com",
"role": "SIGNER",
"signingOrder": 0
}
],
"meta": {
"subject": "string",
"message": "string",
"timezone": "Etc/UTC",
"dateFormat": "yyyy-MM-dd hh:mm a",
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "ACCOUNT"
},
"formValues": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
- `title` _(required)_ - This represents the document's title.
- `externalId` - This is an optional field that you can use to store an external identifier for the document. This can be useful for tracking the document in your system.
- `recipients` _(required)_ - This is an array of recipient objects. Each recipient object has the following fields:
- `name` - The name of the recipient.
- `email` - The email address of the recipient.
- `role` - The role of the recipient. See the [available roles](/users/signing-documents#roles).
- `signingOrder` - The order in which the recipient should sign the document. This is an integer value starting from 0.
- `meta` - This object contains additional metadata for the document. It has the following fields:
- `subject` - The subject of the email that will be sent to the recipients.
- `message` - The message of the email that will be sent to the recipients.
- `timezone` - The timezone in which the document should be signed.
- `dateFormat` - The date format that should be used in the document.
- `redirectUrl` - The URL to which the user should be redirected after signing the document.
- `signingOrder` - The signing order for the document. This can be either `SEQUENTIAL` or `PARALLEL`.
- `authOptions` - This object contains authentication options for the document. It has the following fields:
- `globalAccessAuth` - The authentication level required to access the document. This can be either `ACCOUNT` or `null`.
- If the document is set to `ACCOUNT`, all recipients must authenticate with their Documenso account to access it.
- The document can be accessed without a Documenso account if it's set to `null`.
- `globalActionAuth` - The authentication level required to perform actions on the document. This can be `ACCOUNT`, `PASSKEY`, `TWO_FACTOR_AUTH`, or `null`.
- If the document is set to `ACCOUNT`, all recipients must authenticate with their Documenso account to perform actions on the document.
- If it's set to `PASSKEY`, all recipients must have the passkey active to perform actions on the document.
- If it's set to `TWO_FACTOR_AUTH`, all recipients must have the two-factor authentication active to perform actions on the document.
- If it's set to `null`, all the recipients can perform actions on the document without any authentication.
- `formValues` - This object contains additional form values for the document. This property only works with native PDF fields and accepts three types: number, text and boolean.
<Callout type="info">
The `globalActionAuth` property is only available for Enterprise accounts.
</Callout>
Here's an example of the JSON payload for uploading a document:
```json
{
"title": "my-document.pdf",
"externalId": "12345",
"recipients": [
{
"name": "Alex Blake",
"email": "alexblake@email.com",
"role": "SIGNER",
"signingOrder": 1
},
{
"name": "Ash Drew",
"email": "ashdrew@email.com",
"role": "SIGNER",
"signingOrder": 0
}
],
"meta": {
"subject": "Sign the document",
"message": "Hey there, please sign this document.",
"timezone": "Europe/London",
"dateFormat": "Day, Month Year",
"redirectUrl": "https://mysite.com/welcome",
"signingOrder": "SEQUENTIAL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "PASSKEY"
}
}
```
### Upload to S3
A successful API call to the `/api/v1/documents` endpoint returns a JSON response containing the upload URL, document ID, and recipient information.
The upload URL is a pre-signed S3 URL that you can use to upload the document to the Documenso (or your) S3 bucket. You need to make a `PUT` request to this URL to upload the document.
```json
{
"uploadUrl": "https://<url>/<bucket-name>/<id>/my-document.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<credentials>&X-Amz-Date=<date>&X-Amz-Expires=3600&X-Amz-Signature=<signature>&X-Amz-SignedHeaders=host&x-id=PutObject",
"documentId": 51,
"recipients": [
{
"recipientId": 11,
"name": "Alex Blake",
"email": "alexblake@email.com",
"token": "<unique-signer-token>",
"role": "SIGNER",
"signingOrder": 1,
"signingUrl": "https://app.documenso.com/sign/<unique-signer-token>"
},
{
"recipientId": 12,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"token": "<unique-signer-token>",
"role": "SIGNER",
"signingOrder": 0,
"signingUrl": "https://app.documenso.com/sign/<unique-signer-token>"
}
]
}
```
When you make the `PUT` request to the pre-signed URL, you need to include the document file you want to upload. The image below shows how to upload a document to the S3 bucket via Postman.
![Upload document to S3](/api-reference/upload-document-to-s3.webp)
Here's an example of how to upload a document using cURL:
```bash
curl --location --request PUT 'https://<url>/<bucket-name>/<id>/my-document.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<credentials>&X-Amz-Date=<date>&X-Amz-Expires=3600&X-Amz-Signature=<signature>&X-Amz-SignedHeaders=host&x-id=PutObject' \
--form '=@"/Users/my-user/Documents/documenso.pdf"'
```
Once the document is successfully uploaded, you can access it in your Documenso account dashboard. The screenshot below shows the document that was uploaded via the API.
![Uploaded Document](/api-reference/document-uploaded-to-documenso-via-api.webp)
</Steps>
## Generate Document From Template
Documenso allows you to generate documents from templates. This is useful when you have a standard document format you want to reuse.
The API endpoint for generating a document from a template is `/api/v1/templates/{templateId}/generate-document`, and it takes a JSON payload with the following fields:
```json
{
"title": "string",
"externalId": "string",
"recipients": [
{
"id": 0,
"name": "string",
"email": "user@example.com",
"signingOrder": 0
}
],
"meta": {
"subject": "string",
"message": "string",
"timezone": "string",
"dateFormat": "string",
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "ACCOUNT"
},
"formValues": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
The JSON payload is identical to the payload for uploading a document, so you can read more about the fields in the [Create Document](/developers/public-api/reference#create-document) step. For this API endpoint, the `recipients` property is required.
<Steps>
### Grab the Template ID
The first step is to retrieve the template ID from the Documenso dashboard. You can find the template ID in the URL by navigating to the template details page.
![Template ID](/api-reference/documenso-template-id.webp)
In this case, the template ID is "99999".
### Retrieve the Recipient(s) ID(s)
Once you have the template ID, the next step involves retrieving the ID(s) of the recipient(s) from the template. You can do this by making a GET request to `/api/v1/templates/{template-id}`.
A successful response looks as follows:
```json
{
"id": 0,
"externalId": "string",
"type": "PUBLIC",
"title": "string",
"userId": 0,
"teamId": 0,
"templateDocumentDataId": "string",
"createdAt": "2024-10-11T08:46:58.247Z",
"updatedAt": "2024-10-11T08:46:58.247Z",
"templateMeta": {
"id": "string",
"subject": "string",
"message": "string",
"timezone": "string",
"dateFormat": "string",
"templateId": 0,
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"directLink": {
"token": "string",
"enabled": true
},
"templateDocumentData": {
"id": "string",
"type": "S3_PATH",
"data": "string"
},
"Field": [
{
"id": 0,
"recipientId": 0,
"type": "SIGNATURE",
"page": 0,
"positionX": "string",
"positionY": "string",
"width": "string",
"height": "string"
}
],
"Recipient": [
{
"id": 0,
"email": "user@example.com",
"name": "string",
"signingOrder": 0,
"authOptions": "string",
"role": "CC"
}
]
}
```
You'll need the recipient(s) ID(s) for the next step.
### Generate the Document
To generate a document from the template, you need to make a POST request to the `/api/v1/templates/{template-id}/generate-document` endpoint.
At the minimum, you must provide the `recipients` array in the JSON payload. Here's an example of the JSON payload:
```json
{
"recipients": [
{
"id": 0,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"signingOrder": 0
}
]
}
```
Filling the `recipients` array with the corresponding recipient for each template placeholder recipient is recommended. For example, if the template has two placeholders, you should provide at least two recipients in the `recipients` array. Otherwise, the document will be sent to inexistent recipients such as `<recipient.1@documenso.com>`. However, the recipients can always be edited via the API or the web app.
A successful response will contain the document ID and recipient(s) information.
```json
{
"documentId": 999,
"recipients": [
{
"recipientId": 0,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"token": "<signing-token>",
"role": "SIGNER",
"signingOrder": null,
"signingUrl": "https://app.documenso.com/sign/<signing-token>"
}
]
}
```
You can now access the document in your Documenso account dashboard. The screenshot below shows the document that was generated from the template.
![Generated Document](/api-reference/document-generated-from-template.webp)
</Steps>
## Add Fields to Document
The API allows you to add fields to a document via the `/api/v1/documents/{documentId}/fields` endpoint. This is useful when you want to add fields to a document before sending it to recipients.
To add fields to a document, you need to make a `POST` request with a JSON payload containing the field(s) information.
```json
{
"recipientId": 0,
"type": "SIGNATURE",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0,
"fieldMeta": {
"label": "string",
"placeholder": "string",
"required": true,
"readOnly": true,
"type": "text",
"text": "string",
"characterLimit": 0
}
}
// or
[
{
"recipientId": 0,
"type": "SIGNATURE",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0
},
{
"recipientId": 0,
"type": "TEXT",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0,
"fieldMeta": {
"label": "string",
"placeholder": "string",
"required": true,
"readOnly": true,
"type": "text",
"text": "string",
"characterLimit": 0
}
}
]
```
<Callout type="info">This endpoint accepts either one field or an array of fields.</Callout>
Before adding fields to a document, you need each recipient's ID. If the document already has recipients, you can query the document to retrieve the recipient's details. If the document has no recipients, you need to add a recipient via the UI or API before adding a field.
<Steps>
### Retrieve the Recipient(s) ID(s)
Perform a `GET` request to the `/api/v1/documents/{id}` to retrieve the details of a specific document, including the recipient's information.
An example response would look like this:
```json
{
"id": 137,
"externalId": null,
"userId": 3,
"teamId": null,
"title": "documenso.pdf",
"status": "DRAFT",
"documentDataId": "<document-data-id>",
"createdAt": "2024-10-11T12:29:12.725Z",
"updatedAt": "2024-10-11T12:29:12.725Z",
"completedAt": null,
"recipients": [
{
"id": 55,
"documentId": 137,
"email": "ashdrew@email.com",
"name": "Ash Drew",
"role": "SIGNER",
"signingOrder": null,
"token": "<signing-token>",
"signedAt": null,
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "NOT_SENT",
"signingUrl": "https://app.documenso.com/sign/<signing-token>"
}
]
}
```
From this response, you'll only need the recipient ID, which is `55` in this case.
### (OR) Add a Recipient
If the document doesn't already have recipient(s), you can add recipient(s) via the API. Make a `POST` request to the `/api/v1/documents/{documentId}/recipients` endpoint with the recipient information. This endpoint takes the following JSON payload:
```json
{
"name": "string",
"email": "user@example.com",
"role": "SIGNER",
"signingOrder": 0,
"authOptions": {
"actionAuth": "ACCOUNT"
}
}
```
<Callout type="info">The `authOptions` property is only available for Enterprise accounts.</Callout>
Here's an example of the JSON payload for adding a recipient:
```json
{
"name": "Ash Drew",
"email": "ashdrew@email.com",
"role": "SIGNER",
"signingOrder": 0
}
```
A successful request will return a JSON response with the newly added recipient. You can now use the recipient ID to add fields to the document.
### Add Field(s)
Now you can make a `POST` request to the `/api/v1/documents/{documentId}/fields` endpoint with the field(s) information. Here's an example:
```json
[
{
"recipientId": 55,
"type": "SIGNATURE",
"pageNumber": 1,
"pageX": 50,
"pageY": 20,
"pageWidth": 25,
"pageHeight": 5
},
{
"recipientId": 55,
"type": "TEXT",
"pageNumber": 1,
"pageX": 20,
"pageY": 50,
"pageWidth": 30,
"pageHeight": 7.5,
"fieldMeta": {
"label": "Address",
"placeholder": "32 New York Street, 41241",
"required": true,
"readOnly": false,
"type": "text",
"text": "32 New York Street, 41241",
"characterLimit": 40
}
}
]
```
<Callout type="info">
The `text` field represents the default value of the field. If the user doesn't provide any other
value, this is the value that will be used to sign the field.
</Callout>
<Callout type="warning">
It's important to pass the `type` in the `fieldMeta` property for the advanced fields. [Read more
here](#a-note-on-advanced-fields)
</Callout>
A successful request will return a JSON response with the newly added fields. The image below illustrates the fields added to the document via the API.
![A screenshot of the document in the Documenso editor](/api-reference/fields-added-via-api.webp)
</Steps>
#### A Note on Advanced Fields
The advanced fields are: text, checkbox, radio, number, and select. Whenever you append any of these advanced fields to a document, you need to pass the `type` in the `fieldMeta` property:
```json
...
"fieldMeta": {
"type": "text",
}
...
```
Replace the `text` value with the corresponding field type:
- For the `TEXT` field it should be `text`.
- For the `CHECKBOX` field it should be `checkbox`.
- For the `RADIO` field it should be `radio`.
- For the `NUMBER` field it should be `number`.
- For the `SELECT` field it should be `select`. (check this before merge)
You must pass this property at all times, even if you don't need to set any other properties. If you don't, the endpoint will throw an error.
## Pre-fill Fields On Document Creation
The API allows you to pre-fill fields on document creation. This is useful when you want to create a document from an existing template and pre-fill the fields with specific values.
To pre-fill a field, you need to make a `POST` request to the `/api/v1/templates/{templateId}/generate-document` endpoint with the field information. Here's an example:
```json
{
"title": "my-document.pdf",
"recipients": [
{
"id": 3,
"name": "Example User",
"email": "example@documenso.com",
"signingOrder": 1,
"role": "SIGNER"
}
],
"prefillFields": [
{
"id": 21,
"type": "text",
"label": "my-label",
"placeholder": "my-placeholder",
"value": "my-value"
},
{
"id": 22,
"type": "number",
"label": "my-label",
"placeholder": "my-placeholder",
"value": "123"
},
{
"id": 23,
"type": "checkbox",
"label": "my-label",
"placeholder": "my-placeholder",
"value": ["option-1", "option-2"]
}
]
}
```
Check out the endpoint in the [API V1 documentation](https://app.documenso.com/api/v1/openapi#:~:text=/%7BtemplateId%7D/-,generate,-%2Ddocument).
### API V2
For API V2, you need to make a `POST` request to the `/api/v2-beta/template/use` endpoint with the field(s) information. Here's an example:
```json
{
"templateId": 111,
"recipients": [
{
"id": 3,
"name": "Example User",
"email": "example@documenso.com",
"signingOrder": 1,
"role": "SIGNER"
}
],
"prefillFields": [
{
"id": 21,
"type": "text",
"label": "my-label",
"placeholder": "my-placeholder",
"value": "my-value"
},
{
"id": 22,
"type": "number",
"label": "my-label",
"placeholder": "my-placeholder",
"value": "123"
},
{
"id": 23,
"type": "checkbox",
"label": "my-label",
"placeholder": "my-placeholder",
"value": ["option-1", "option-2"]
}
]
}
```
Check out the endpoint in the [API V2 documentation](https://openapi.documenso.com/reference#tag/template/POST/template/use).

View File

@ -5,6 +5,8 @@ description: Learn how to self-host Documenso on your server or cloud infrastruc
import { Callout, Steps } from 'nextra/components';
import { CallToAction } from '../../../components/call-to-action';
# Self Hosting
We support various deployment methods and are actively working on adding more. Please let us know if you have a specific deployment method in mind!
@ -33,10 +35,8 @@ cp .env.example .env
Open the `.env` file and fill in the following variables:
```bash
- NEXTAUTH_URL
- NEXTAUTH_SECRET
- NEXT_PUBLIC_WEBAPP_URL
- NEXT_PUBLIC_MARKETING_URL
- NEXT_PRIVATE_DATABASE_URL
- NEXT_PRIVATE_DIRECT_DATABASE_URL
- NEXT_PRIVATE_SMTP_FROM_NAME
@ -44,8 +44,8 @@ Open the `.env` file and fill in the following variables:
```
<Callout type="info">
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for both
the `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for the
`NEXT_PUBLIC_WEBAPP_URL` variable!
</Callout>
### Install the Dependencies
@ -131,7 +131,7 @@ volumes:
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
docker-compose --env-file ./.env up -d
```
The command will start the PostgreSQL database and the Documenso application containers.
@ -169,7 +169,6 @@ Run the Docker container with the required environment variables:
```bash
docker run -d \
-p 3000:3000 \
-e NEXTAUTH_URL="<your-nextauth-url>"
-e NEXTAUTH_SECRET="<your-nextauth-secret>"
-e NEXT_PRIVATE_ENCRYPTION_KEY="<your-next-private-encryption-key>"
-e NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="<your-next-private-encryption-secondary-key>"
@ -198,7 +197,6 @@ The environment variables listed above are a subset of those available for confi
| Variable | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `PORT` | The port on which the Documenso application runs. It defaults to `3000`. |
| `NEXTAUTH_URL` | The URL for the NextAuth.js authentication service. |
| `NEXTAUTH_SECRET` | The secret key used by NextAuth.js for encryption and signing. |
| `NEXT_PRIVATE_ENCRYPTION_KEY` | The primary encryption key for symmetric encryption and decryption (at least 32 characters). |
| `NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY` | The secondary encryption key for symmetric encryption and decryption (at least 32 characters). |
@ -273,3 +271,5 @@ We offer several alternative deployment methods for Documenso if you need more o
## Koyeb
[![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/documenso/documenso&branch=main&name=documenso-app&builder=dockerfile&dockerfile=/docker/Dockerfile)
<CallToAction className="mt-12" utmSource="self-hosting" />

View File

@ -3,6 +3,10 @@ title: Getting Started with Self-Hosting
description: A step-by-step guide to setting up and hosting your own Documenso instance.
---
import { CallToAction } from '../../../components/call-to-action';
# Getting Started with Self-Hosting
This is a step-by-step guide to setting up and hosting your own Documenso instance. Before getting started, [select the right license for you](/users/licenses).
<CallToAction className="mt-12" utmSource="self-hosting" />

View File

@ -20,6 +20,8 @@ Documenso supports Webhooks and allows you to subscribe to the following events:
- `document.opened`
- `document.signed`
- `document.completed`
- `document.rejected`
- `document.cancelled`
## Create a webhook subscription
@ -36,7 +38,7 @@ Clicking on the "**Create Webhook**" button opens a modal to create a new webhoo
To create a new webhook subscription, you need to provide the following information:
- Enter the webhook URL that will receive the event payload.
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`.
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`, `document.rejected`, `document.cancelled`.
- Optionally, you can provide a secret key that will be used to sign the payload. This key will be included in the `X-Documenso-Secret` header of the request.
![A screenshot of the Create Webhook modal that shows the URL input field and the event checkboxes](/webhook-images/webhooks-page-create-webhook-modal.webp)
@ -53,45 +55,55 @@ You can edit or delete your webhook subscriptions by clicking the "**Edit**" or
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.
| Field | Type | Description |
| -------------------------------------------- | --------- | ----------------------------------------------------- |
| `event` | string | The type of event that triggered the webhook. |
| `payload.id` | number | The id of the document. |
| `payload.externalId` | string? | External identifier for 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.visibility` | string | Document visibility (e.g., EVERYONE). |
| `payload.title` | string | The title 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 if document belongs to a team. |
| `payload.templateId` | number? | The id of the template if created from template. |
| `payload.source` | string | The source of the document (e.g., DOCUMENT, TEMPLATE) |
| `payload.documentMeta.id` | string | The id of the document metadata. |
| `payload.documentMeta.subject` | string? | The subject of the document. |
| `payload.documentMeta.message` | string? | The message associated with the document. |
| `payload.documentMeta.timezone` | string | The timezone setting for the document. |
| `payload.documentMeta.password` | string? | The password protection if set. |
| `payload.documentMeta.dateFormat` | string | The date format used in the document. |
| `payload.documentMeta.redirectUrl` | string? | The URL to redirect after signing. |
| `payload.documentMeta.signingOrder` | string | The signing order (e.g., PARALLEL, SEQUENTIAL). |
| `payload.documentMeta.typedSignatureEnabled` | boolean | Whether typed signatures are enabled. |
| `payload.documentMeta.language` | string | The language of the document. |
| `payload.documentMeta.distributionMethod` | string | The method of distributing the document. |
| `payload.documentMeta.emailSettings` | json? | Email notification settings. |
| `payload.Recipient[].id` | number | The id of the recipient. |
| `payload.Recipient[].documentId` | number? | The id of the document for this recipient. |
| `payload.Recipient[].templateId` | number? | The template id if from a template. |
| `payload.Recipient[].email` | string | The email address of the recipient. |
| `payload.Recipient[].name` | string | The name of the recipient. |
| `payload.Recipient[].token` | string | The unique token for this recipient. |
| `payload.Recipient[].documentDeletedAt` | datetime? | When the document was deleted for this recipient. |
| `payload.Recipient[].expired` | datetime? | When the recipient's access expired. |
| `payload.Recipient[].signedAt` | datetime? | When the recipient signed the document. |
| `payload.Recipient[].authOptions` | json? | Authentication options for this recipient. |
| `payload.Recipient[].signingOrder` | number? | The order in which this recipient should sign. |
| `payload.Recipient[].rejectionReason` | string? | The reason if the recipient rejected the document. |
| `payload.Recipient[].role` | string | The role of the recipient (e.g., SIGNER, VIEWER). |
| `payload.Recipient[].readStatus` | string | Whether the recipient has read the document. |
| `payload.Recipient[].signingStatus` | string | The signing status of this recipient. |
| `payload.Recipient[].sendStatus` | string | The sending status for this recipient. |
| `createdAt` | datetime | The creation date and time of the webhook event. |
| `webhookEndpoint` | string | The endpoint URL where the webhook is sent. |
## Example payloads
@ -104,9 +116,11 @@ Example payload for the `document.created` event:
"event": "DOCUMENT_CREATED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "DRAFT",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -114,7 +128,43 @@ Example payload for the `document.created` event:
"updatedAt": "2024-04-22T11:44:43.341Z",
"completedAt": null,
"deletedAt": null,
"teamId": null
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
"documentId": 10,
"templateId": null,
"email": "signer@documenso.com",
"name": "John Doe",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": null,
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "NOT_SENT"
}
]
},
"createdAt": "2024-04-22T11:44:44.779Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
@ -128,9 +178,11 @@ Example payload for the `document.sent` event:
"event": "DOCUMENT_SENT",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -139,6 +191,22 @@ Example payload for the `document.sent` event:
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
@ -147,12 +215,12 @@ Example payload for the `document.sent` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 1,
"rejectionReason": null,
"role": "VIEWER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
@ -165,12 +233,12 @@ Example payload for the `document.sent` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 2,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
@ -190,9 +258,11 @@ Example payload for the `document.opened` event:
"event": "DOCUMENT_OPENED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -201,6 +271,22 @@ Example payload for the `document.opened` event:
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
@ -209,24 +295,18 @@ Example payload for the `document.opened` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 1,
"rejectionReason": 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"
@ -240,9 +320,11 @@ Example payload for the `document.signed` event:
"event": "DOCUMENT_SIGNED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "COMPLETED",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -251,6 +333,22 @@ Example payload for the `document.signed` event:
"completedAt": "2024-04-22T11:52:05.707Z",
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 51,
@ -259,12 +357,15 @@ Example payload for the `document.signed` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:52:05.688Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -284,9 +385,11 @@ Example payload for the `document.completed` event:
"event": "DOCUMENT_COMPLETED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "COMPLETED",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -295,11 +398,21 @@ Example payload for the `document.completed` event:
"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"
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
@ -309,12 +422,15 @@ Example payload for the `document.completed` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:51:10.055Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": null,
"role": "VIEWER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -327,12 +443,15 @@ Example payload for the `document.completed` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:52:05.688Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 2,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -345,6 +464,161 @@ Example payload for the `document.completed` event:
}
```
Example payload for the `document.rejected` event:
```json
{
"event": "DOCUMENT_REJECTED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"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,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
"documentId": 10,
"templateId": null,
"email": "signer@documenso.com",
"name": "Signer",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:48:07.569Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": "I do not agree with the terms",
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "REJECTED",
"sendStatus": "SENT"
}
]
},
"createdAt": "2024-04-22T11:48:07.945Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
}
```
Example payload for the `document.rejected` event:
```json
{
"event": "DOCUMENT_CANCELLED",
"payload": {
"id": 7,
"externalId": null,
"userId": 3,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "cm6exvn93006hi02ru90a265a",
"createdAt": "2025-01-27T11:02:14.393Z",
"updatedAt": "2025-01-27T11:03:16.387Z",
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "cm6exvn96006ji02rqvzjvwoy",
"subject": "",
"message": "",
"timezone": "Etc/UTC",
"password": null,
"dateFormat": "yyyy-MM-dd hh:mm a",
"redirectUrl": "",
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": {
"documentDeleted": true,
"documentPending": true,
"recipientSigned": true,
"recipientRemoved": true,
"documentCompleted": true,
"ownerDocumentCompleted": true,
"recipientSigningRequest": true
}
},
"recipients": [
{
"id": 7,
"documentId": 7,
"templateId": null,
"email": "mybirihix@mailinator.com",
"name": "Zorita Baird",
"token": "XkKx1HCs6Znm2UBJA2j6o",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": { "accessAuth": null, "actionAuth": null },
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
],
"Recipient": [
{
"id": 7,
"documentId": 7,
"templateId": null,
"email": "signer@documenso.com",
"name": "Signer",
"token": "XkKx1HCs6Znm2UBJA2j6o",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": { "accessAuth": null, "actionAuth": null },
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
]
},
"createdAt": "2025-01-27T11:03:27.730Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
}
```
## Availability
Webhooks are available to individual users and teams.

View File

@ -6,9 +6,11 @@
"title": "How To Use"
},
"get-started": "Get Started",
"profile": "User Profile",
"signing-documents": "Signing Documents",
"profile": "Public Profile",
"organisations": "Organisations",
"documents": "Documents",
"templates": "Templates",
"branding": "Branding",
"direct-links": "Direct Signing Links",
"-- Legal Overview": {
"type": "separator",
@ -17,4 +19,4 @@
"fair-use": "Fair Use Policy",
"licenses": "Licenses",
"compliance": "Compliance"
}
}

View File

@ -0,0 +1,28 @@
---
title: Branding Preferences
description: Learn how to set the branding preferences for your team account.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Branding Preferences
Branding preferences allow you to set the default settings when emailing documents to your recipients.
## Preferences
Branding preferences can be set on either the organisation or team level.
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
To access the preferences, navigate to either the organisation or teams settings page and click the **Preferences** tab. This page contains both the preferences for documents and branding, the branding section is located at the bottom of the page.
![A screenshot of the organisation's document preferences page](/organisations/organisation-branding.webp)
On this page, you can:
- **Upload a Logo** - Upload your team's logo to be displayed instead of the default Documenso logo.
- **Set the Brand Website** - Enter the URL of your team's website to be displayed in the email communications sent by the team.
- **Add Additional Brand Details** - You can add additional information to display at the bottom of the emails sent by the team. This can include contact information, social media links, and other relevant details.

View File

@ -0,0 +1,5 @@
{
"sending-documents": "Sending Documents",
"document-preferences": "Document Preferences",
"document-visibility": "Document Visibility"
}

View File

@ -0,0 +1,42 @@
---
title: Preferences
description: Learn how to manage your team's global preferences.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Document Preferences
Document preferences allow you to set the default settings when creating new documents and templates.
For example, you can set the default language for documents sent by the team, or set the allowed signatures types.
## Preferences
Document preferences can be set on either the organisation or team level.
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
To access the preferences, navigate to either the organisation or teams settings page and click the **Preferences** tab.
![A screenshot of the organisation's document preferences page](/organisations/organisation-document-preferences.webp)
- **Document Visibility** - Set the default visibility of the documents created by team members. Learn more about [document visibility](/users/documents/document-visibility).
- **Default Document Language** - This setting allows you to set the default language for the documents uploaded in the organisation. The default language is used as the default language in the email communications with the document recipients.
- **Signature Settings** - Controls what signatures are allowed to be used when signing the documents.
- **Sender Details** - Set whether the sender's name should be included in the emails sent by the team. See more below [sender details](/users/documents/document-preferences#sender-details).
- **Include the Signing Certificate** - This setting controls whether the signing certificate should be included in the signed documents. If enabled, the signing certificate is included in the signed documents. If disabled, the signing certificate is not included in the signed documents. Regardless of this setting, the signing certificate is always available in the document's audit log page.
Document visibility, language and signature settings can be overriden on a per document basis.
### Sender Details
If the **Sender Details** setting is enabled, the emails sent by the team will include the sender's name. The email will say:
> "Example User" on behalf of "Example Team" has invited you to sign "document.pdf"
If the **Sender Details** setting is disabled, the emails sent by the team will not include the sender's name. The email will say:
> "Example Team" has invited you to sign "document.pdf"

View File

@ -0,0 +1,53 @@
---
title: Document Visibility
description: Learn how to control the visibility of your team documents.
---
import { Callout } from 'nextra/components';
# Document Visibility
The default document visibility option allows you to control who can view and access the documents uploaded within a team.
This value can either be set in the [document preferences](/users/documents/document-preferences), or when you [create the document](/users/documents/send-document)
## Document Visibility Options
The document visibility can be set to one of the following options:
- **Everyone** - The document is visible to all team members.
- **Managers and above** - The document is visible to team members with the role of _Manager or above_ and _Admin_.
- **Admin only** - The document is only visible to the team's admins.
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [document preferences page](/users/documents/document-preferences) and selecting a different visibility option.
![Document visibility preference](/organisations/organisation-document-visibility.webp)
## How it works
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_".
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Admin_" or "_Managers and above_" in this case).
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Everyone_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Everyone_" or "_Managers and above_" in this case).
- The user can change the visibility of the document to any of these options, except "_Admin_", in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Admin_".
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Admin_" role creates a document, and the default document visibility is set to "_Everyone_", "_Managers and above_", or "_Admin_", the document's visibility is set to the default document visibility.
- The user can change the visibility of the document to any of these options in the document editor.
You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
![A screenshot of the Documenso's document editor page where you can update the document visibility](/teams/document-visibility-settings.webp)
<Callout type="warning">
Updating the default document visibility in the team's general preferences will not affect the
visibility of existing documents. You will need to update the visibility of each document
individually.
</Callout>
## A Note on Document Access
The `document owner` (the user who created the document) always has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the document owner can still view and edit the document.
The `recipient` (the user who receives the document for signature, approval, etc.) also has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the recipient can still view and sign the document.

View File

@ -85,12 +85,13 @@ You can also set the recipient's role, which determines their actions and permis
Documenso has 4 roles for recipients with different permissions and actions.
| Role | Function | Action required | Signature |
| :------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
| Signer | Needs to sign signatures fields assigned to them. | Yes | Yes |
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
| Viewer | Needs to confirm they viewed the document. | Yes | No |
| BCC | Receives a copy of the signed document after completion. No action is required. | No | No |
| Role | Function | Action required | Signature |
| :-------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
| Signer | Needs to sign signatures fields assigned to them. | Yes | Yes |
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
| Viewer | Needs to confirm they viewed the document. | Yes | No |
| Assistant | Can help prepare the document by filling in fields on behalf of other signers. | Yes | No |
| CC | Receives a copy of the signed document after completion. No action is required. | No | No |
### Fields
@ -114,7 +115,7 @@ All fields can be placed anywhere on the document and resized as needed.
<Callout type="info">
Learn more about the available field types and how to use them on the [Fields
page](signing-documents/fields).
page](/users/documents/fields).
</Callout>
#### Signature Required

View File

@ -10,7 +10,7 @@ import { Callout, Steps } from 'nextra/components';
<Steps>
### Pick a Plan
The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, and Teams.
The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, Teams and Platform.
Explore each plan's features and choose the one that best suits your needs. The [pricing page](https://documen.so/pricing) has more information about the plans.
@ -28,6 +28,6 @@ You can claim a premium username by upgrading to a paid plan. After upgrading to
### Optional: Create a Team
If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/get-started/teams).
If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/organisations/teams).
</Steps>

View File

@ -1,99 +0,0 @@
---
title: Teams
description: Learn how to create and manage teams in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Teams
Documenso allows you to create teams to collaborate with others on creating and signing documents.
<Steps>
### Create a New Team
Anyone can create a team from their account by clicking on the "+" (plus) button in the "Teams" section from the account dropdown.
![Documenso account dropdown menu](/get-started-images/add-team.webp)
Each team is a separate entity with its members, documents, and templates. You can create as many teams as you like but remember that each team is billed separately.
<Callout type="info">You can transfer the ownership of the team at any time.</Callout>
### Name and URL
Clicking the "+" button will open a modal where you must pick your team's name and URL. The URL is the team's identifier and will link to the team's page and settings. An example URL would be:
```bash
https://app.documenso.com/t/<your-team-name>
```
![Documenso create team modal](/get-started-images/add-team-2.webp)
You can select a different name and URL for your team, but we recommend using the same or similar name.
### Invite Team Members
After creating the team, you can invite team members by navigating to the "Members" tab in the team settings and clicking the "Invite member" button.
To access the team settings, click on the team's name in the account dropdown and select the appropriate team. Lastly, click again on the avatar and then "Team Settings".
Or you can copy this URL:
```bash
https://app.documenso.com/t/<your-team-name>/settings/members
```
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
![Invite team members in Documenso dashboard](/get-started-images/add-team-members-documenso.webp)
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
The table below shows how the CSV file should be structured:
| Email address | Role |
| -------------------------- | ------- |
| team-admin@documenso.com | Admin |
| team-manager@documenso.com | Manager |
| team-member@documenso.com | Member |
<Callout type="info">
The basic team plan includes 5 members. You can invite as many members as you like by upgrading
your team's seats on the team's billing page.
</Callout>
#### Roles
You can assign different permissions to team members based on their roles. The roles available are:
| Role | Create, Edit, Send Documents | Manage Users | Manage Admins | Settings | Billing | Delete/ Transfer |
| :-----: | :--------------------------: | :----------: | :-----------: | :------: | :-----: | :--------------: |
| Member | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Manager | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Admin | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Owner | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
### Set a Team Email
You can add a team email to make signing and sending documents easier. Adding a team email allows you to:
- See a signing request sent to this email (Team Inbox)
- See all documents sent on behalf of the team
### (Optional) Transfer Team Ownership
You can transfer the team's ownership at any time. To do this, navigate to the "General" tab in the team settings and click the "Transfer team" button.
Use this URL to get to the team settings:
```bash
https://app.documenso.com/t/<your-team-name>/settings
```
### [Send your First Document](https://app.documenso.com/)
</Steps>

View File

@ -0,0 +1,7 @@
{
"index": "Introduction",
"members": "Members",
"groups": "Groups",
"teams": "Teams",
"billing": "Billing"
}

View File

@ -0,0 +1,19 @@
---
title: Billing
description: Learn how to manage your organisation's billing and subscription.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
### Billing and Subscription Management
Organisations handle billing centrally, making it easier to manage:
- **Unified Billing**: One subscription covers all teams in the organisation
- **Seat Management**: Add or remove seats across all teams automatically (Teams plan)
You can change plans, view invoices and manage your subscription from the billing page which is accessible from the organisation settings.
![A screenshot of the organisation's billing page](/organisations/organisations-billing.webp)

View File

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

View File

@ -0,0 +1,65 @@
---
title: Organisations
description: Learn how to create and manage organisations in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisations
Organisations allow you to manage multiple teams and users under a single managed entity. This powerful feature enables enterprise-level collaboration and streamlined management across your entire organisation.
## What are Organisations?
Organisations are the top-level entity in Documenso's hierarchy structure:
![Organisations diagram](/organisations/organisations-basic-diagram.webp)
Each organisation can contain multiple teams, and each team can have multiple members. This structure provides:
- **Centralized Management**: Control multiple teams from a single organisational dashboard
- **Unified Billing**: Manage billing and subscriptions at the organisation level
- **Access Control**: Define roles and groups across the entire organisation
- **Group Management**: Create custom groups to organise members and control team access
- **Global Settings**: Apply consistent settings across all teams in your organisation
## Create a new organisation
You can create multiple organisations, but each organisation will be billed separately.
<Steps>
### Creating Organisations
To create a new organisation, navigate to the organisation section in your account settings and click the "Create Organisation" button.
![Create organisation in Documenso dashboard](/organisations/organisations-create.webp)
### Select your plan
Choose from our range of plans for your new organisation. If you want to instead upgrade your current organisation, you can do so by going into your settings billing page and upgrade it there.
### Name setup
When creating an organisation, you'll need to provide:
- **Organisation Name**: The display name for your organisation
</Steps>
Once your organisation is established, you can create teams to organise your work and collaborate effectively. Each team operates independently but inherits organisation-level settings and branding.
## Best Practices for Organisation Management
1. **Use groups effectively**: Leverage groups to simplify permission management
2. **Set default settings**: Configure organisation-wide settings for consistency
## What's next?
- [Create Your First Team](/users/organisations/teams)
- [Invite Organisation Members](/users/organisations/members)
- [Create Organisation Groups](/users/organisations/groups)
- [Manage Default Settings](/users/documents/document-preferences)
- [Manage Default Branding](/users/branding)

View File

@ -0,0 +1,65 @@
---
title: Members
description: Learn how to invite and manage your organisation's members.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisation Members
Organisation members are the core users of your organisation. They are the ones who can access the team resources and collaborate with other members.
## Organisation Roles
You can assign different permissions to organisation members by using roles. The roles available are:
| Role | Manage Settings/Teams/Members | Billing | Delete Organisation |
| :------------------: | :---------------------------: | :-----: | ------------------- |
| Organisation Owner | ✅ | ✅ | ✅ |
| Organisation Admin | ✅ | ✅ | ✅ |
| Organisation Manager | ✅ | ❌ | ❌ |
| Organisation Member | ❌ | ❌ | ❌ |
<Callout type="info">
Organisation admins and managers will automatically have access to all teams as the "Team Admin"
role. When creating a team you can also decide whether to automatically allow normal members to
access it by default as well.
</Callout>
## Invite Organisation Members
To invite organisation members, you need to be an organisation owner, admin or manager.
1. Open the menu switcher top right
2. Hover over your new organisation and click the settings icon
3. Navigate to the "Members" tab
4. Click "Invite Member"
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
![Invite organisation members](/organisations/organisations-member-invite.webp)
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
The table below shows how the CSV file should be structured:
| Email address | Role |
| ------------------------- | ------- |
| org-admin@documenso.com | Admin |
| org-manager@documenso.com | Manager |
| org-member@documenso.com | Member |
<Callout type="info">
The basic team plan includes 5 organisation members. Going over the 5 members will charge your
organisation according to the seat plan pricing.
</Callout>
## Manage Organisation Members
On the same page, you can change the organisation member's roles or remove them from the organisation.
## What's next?
- [Use groups to organise your members](/users/organisations/groups)

View File

@ -0,0 +1,121 @@
---
title: Teams
description: Learn how to create and manage teams in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Teams
Documenso teams allow you to collaborate with others on creating, sending and receiving documents within your organisation. Teams operate within the organisational structure and inherit settings and branding from their parent organisation.
## Team Structure
Teams provide focused collaboration spaces while benefiting from organisation-level management and settings.
Each team within an organisation has its own:
- Team members and roles
- Documents and templates
- Team-specific settings (that can override organisation defaults)
- Team email and branding (if enabled)
## Creating a Team
Only members with the "Organisation Admin" or "Organisation Manager" role can create teams.
<Steps>
### Create Team
To create a team, navigate to the organisation settings page and click the "Teams" tab. Then you can click the "Create Team" button.
![Create Team Dialog](/teams/team-create.webp)
### Name and URL
When creating a team, you'll need to provide:
- **Team Name**: The display name for your team
- **Team URL**: A unique identifier for your team
The team URL will follow this format:
```bash
https://app.documenso.com/t/<team-url>
```
You can select different names and URLs for your team, but we recommend using the same or similar names for consistency.
![Documenso create team modal](/teams/team-create-dialog.webp)
You can also decide whether to automatically inherit members from the organisation into the team. This means that all members of the organisation will have access to this team.
Members with the "Organisation Admin" or "Organisation Manager" role will be assigned as "Team Admin" regardless of this setting. This will only affect members with the "Organisation Member" role, who will be added to the team as a "Team Member".
Disabling this setting will remove all these members automatically. This can always be turned on or off later in the teams member settings page.
</Steps>
## Team Members
After creating the team, you can add organisation members into your team using two methods:
- Directly adding members to the team
- Add members using groups
### Directly adding members
1. Navigate to the team settings member page
2. Click the "Add Members" button
3. Choose which members you want to add
4. Assign the team roles for each team member
If you want to add people outside of the organisation, you will need to invite them to the organisation first.
See the [organisation members](/users/organisations/members#invite-organisation-members) page for more information.
### Adding members using groups
1. Navigate to the teams settings groups page
2. Click the "Add groups" button
3. Choose which groups you want to add
4. Assign the team roles for each group
See the [organisation groups](/users/organisations/groups) page for more information.
### Team Member Roles
You can assign different permissions to team members based on their roles. The roles available are:
| Role | Manage Documents | Manage Team | Delete Team |
| :----------: | :--------------: | :---------: | :---------: |
| Team Admin | ✅ | ✅ | ✅ |
| Team Manager | ✅ | ✅ | ❌ |
| Team Member | ✅ | ❌ | ❌ |
These roles can be used for document visibility and management as well.
## Set a Team Email
You can add a team email which allows you to:
- See signing requests sent to this email (Team Inbox)
- See documents sent from this email
- Send documents on behalf of the team
- Maintain consistent team branding in communications
## Team Settings and Branding
You can override preferences and settings from the Organisation on the Team level. See the following pages for more information:
- [Document preferences](/users/documents/document-preferences)
- [Branding preferences](/users/branding/branding-preferences)
## What's next?
- [Send your first document](/users/documents/sending-documents)
- [Setup your default document preferences](/users/documents/document-preferences)
- [Setup your default branding preferences](/users/branding)

View File

@ -1,5 +1,5 @@
---
title: User Profile
title: Public Profile
description: Learn how to set up your public profile on Documenso.
---
@ -15,7 +15,7 @@ Documenso allows you to create a public profile to share your templates for anyo
### Navigate to Your Profile Settings
Click on your profile picture in the top right corner and select "User settings". Then, navigate to the "Public Profile" tab to configure your profile.
Click on your profile picture in the top right corner and select "Settings" or "Team Settings". Then, navigate to the "Public Profile" tab to configure your profile.
![The profile settings page](/public-profile/documenso-public-profile-settings.webp)
@ -45,6 +45,8 @@ You can choose to make your profile public or private. Only you can access it if
To make your profile public, toggle the switch to the right ("Show") at the top right-hand side of the page.
![An example of a enabling a public profile on Documenso](/public-profile/documenso-enable-public-profile-settings.webp)
### (Optional) Link Templates
Linking templates to your profile is optional, but it's what makes your profile helpful. Linking templates allow people to sign documents directly from your profile. As a result, we recommend linking at least one template you want to share with others.

View File

@ -1,4 +0,0 @@
{
"index": "Send Documents",
"fields": "Document Fields"
}

View File

@ -1,5 +1,3 @@
'use client';
import React from 'react';
import NextPlausibleProvider from 'next-plausible';

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -19,6 +19,22 @@ const themeConfig: DocsThemeConfig = {
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<script
dangerouslySetInnerHTML={{
__html: `
!function(){
if (location.hostname === 'localhost') return;
var e="6c236490c9a68c1",
t=function(){Reo.init({ clientID: e })},
n=document.createElement("script");
n.src="https://static.reo.dev/"+e+"/reo.js";
n.defer=true;
n.onload=t;
document.head.appendChild(n);
}();
`,
}}
/>
</>
);
},

View File

@ -1 +0,0 @@
# @documenso/marketing

View File

@ -1 +0,0 @@
declare module '@documenso/tailwind-config';

View File

@ -1,63 +0,0 @@
---
title: Launching Direct Links
description: Today, we are launching direct links to templates, a new and async way to get documents signed.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-17
tags:
- Announcement
- Direct Links
- Profiles
---
<figure>
<MdxNextImage
src="/blog/direct-links.png"
width="1400"
height="884"
alt="Direct Links in Templats List View"
/>
<figcaption className="text-center">Direct Template Links - Async signing, anytime.</figcaption>
</figure>
> TLDR; We are launching direct links to templates. With direct links, a document is created from a template every time anyone signs the link. Links can be public.
## Sync or Async?
> Quick refresher on Sync vs. Async: Sync means everyone has to wait for me until they can continue their work. Async means everyone can and does their work at the time that fits best.
Digital signing has become almost as normalized as email when doing business. While not 100% of companies are onboarded on digital signatures yet, hardly anyone is surprised when receiving a link to sign something digitally. As we got used to the user experience of sending emails, we also got used to the experience of sending document signature requests, with all the downsides:
- I have to become active each time before anything can happen: I need to send a signature request
- My counterpart has to wait for me to send: "Did you send the signing link yet?"
- I need to monitor the requests I started for completion: "I sent you a link yesterday; please check it out."
## Introducing Direct Links
Today, we are introducing a new paradigm to signing: Async Direct Signing Links. Direct links are attached to a template and can be used anytime by anyone using the link. You set up the signature experience and flow once using all existing template mechanisms and you are done. You can provide anyone with the link so they can sign whenever they need to. You can even post the link publicly if you want to maximize its reach, i.e. for sales contracts.
<video
id="vid"
width="100%"
src="https://github.com/documenso/design/assets/1309312/129f690b-29b4-4a11-b9a0-14fc6648e611"
autoPlay
loop
muted
></video>
## Embrace Async
So, how does this help anyone? You may still need to send a signature request to people, but in the cases you don't, you are not forced to anymore. Need an NDA? Check out our standing NDA link. A customer needs an updated Form W-9? Just use the company W-9 Link; it always has the most up-to-date form. You can even go as far as publicly posting a link to a software development or design contract any potential customer can sign anytime. Can they talk to you first? Sure, but if they don't need to or already have to, they go straight to the link. The process of actively sending has gotten us used to using a sync paradigm (I send, you receive and sign, and I get the result), whereas an async one (you sign whenever it suits you, and I become active only then, if at all) is way better suited. Adding more approval and signature steps makes sure you still control the outcome, but the process becomes a lot more efficient. For example, you can grab your own copy of the early adopter's pledge here if you missed it: [documen.so/pledge](https://documen.so/pledge).
> Take a minute to think about every signing request you send and whether they really require you to be part of the transaction. Could they be outsourced to the recipient and only reviewed once their part is done?
## Coming Soon: Profiles
The best place to put your public links will be your **Documenso profile**, which is also close to launching. We want to get a feel for how links are used and move on to profiles shortly after. Want to try out direct links? Grab a free account here to get started: [documen.so/free](https://documen.so/free).
As always, we want to hear from you on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
Best from Hamburg\
Timur

Some files were not shown because too many files have changed in this diff Show More