Compare commits
4 Commits
feat/delet
...
v1.8.1-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87186e08b1 | ||
|
|
b27fd800ed | ||
|
|
98d85b086d | ||
|
|
04293968c6 |
@@ -139,3 +139,6 @@ E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
||||
# [[REDIS]]
|
||||
NEXT_PRIVATE_REDIS_URL=
|
||||
NEXT_PRIVATE_REDIS_TOKEN=
|
||||
|
||||
# [[LOGGER]]
|
||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=
|
||||
|
||||
9
apps/documentation/pages/developers/embedding/_meta.json
Normal file
9
apps/documentation/pages/developers/embedding/_meta.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"index": "Get Started",
|
||||
"react": "React Integration",
|
||||
"vue": "Vue Integration",
|
||||
"svelte": "Svelte Integration",
|
||||
"solid": "Solid Integration",
|
||||
"preact": "Preact Integration",
|
||||
"css-variables": "CSS Variables"
|
||||
}
|
||||
120
apps/documentation/pages/developers/embedding/css-variables.mdx
Normal file
120
apps/documentation/pages/developers/embedding/css-variables.mdx
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
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.
|
||||
|
||||
## 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)
|
||||
@@ -11,7 +11,11 @@ Our embedding feature lets you integrate our document signing experience into yo
|
||||
|
||||
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,6 +26,49 @@ 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={{
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '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:
|
||||
@@ -120,12 +167,11 @@ Once you've obtained the appropriate tokens, you can integrate the signing exper
|
||||
|
||||
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
|
||||
## Related
|
||||
|
||||
While embedding is already a powerful tool, we're working on a **Platform Plan** that will introduce even more functionality. This plan will offer:
|
||||
|
||||
- Additional customization options
|
||||
- The ability to remove Documenso branding
|
||||
- Additional controls for the signing experience
|
||||
|
||||
More details will be shared as we approach the release.
|
||||
- [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)
|
||||
- [CSS Variables](/developers/embedding/css-variables)
|
||||
|
||||
@@ -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 = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
};
|
||||
|
||||
return (
|
||||
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
@@ -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={{
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
// Dark Mode Control
|
||||
darkModeDisabled={true}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
@@ -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 = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
};
|
||||
|
||||
return (
|
||||
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
@@ -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 = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
};
|
||||
</script>
|
||||
|
||||
<EmbedDirectTemplate {token} css="{customCss}" cssVars="{cssVars}" darkModeDisabled="{true}" />
|
||||
```
|
||||
|
||||
@@ -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 = {
|
||||
colorPrimary: '#0000FF',
|
||||
colorBackground: '#F5F5F5',
|
||||
borderRadius: '8px',
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EmbedDirectTemplate
|
||||
:token="token"
|
||||
:css="customCss"
|
||||
:cssVars="cssVars"
|
||||
:darkModeDisabled="true"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@documenso/marketing",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@documenso/web",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { buildLogger } from '@documenso/lib/utils/logger';
|
||||
import * as trpcNext from '@documenso/trpc/server/adapters/next';
|
||||
import { createTrpcContext } from '@documenso/trpc/server/context';
|
||||
import { appRouter } from '@documenso/trpc/server/router';
|
||||
@@ -11,7 +13,44 @@ export const config = {
|
||||
},
|
||||
};
|
||||
|
||||
const logger = buildLogger();
|
||||
|
||||
export default trpcNext.createNextApiHandler({
|
||||
router: appRouter,
|
||||
createContext: async ({ req, res }) => createTrpcContext({ req, res }),
|
||||
onError(opts) {
|
||||
const { error, path } = opts;
|
||||
|
||||
// Currently trialing changes with template and team router only.
|
||||
if (!path || (!path.startsWith('template') && !path.startsWith('team'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Always log the error for now.
|
||||
console.error(error);
|
||||
|
||||
const appError = AppError.parseError(error.cause || error);
|
||||
|
||||
const isAppError = error.cause instanceof AppError;
|
||||
|
||||
// Only log AppErrors that are explicitly set to 500 or the error code
|
||||
// is in the errorCodesToAlertOn list.
|
||||
const isLoggableAppError =
|
||||
isAppError && (appError.statusCode === 500 || errorCodesToAlertOn.includes(appError.code));
|
||||
|
||||
// Only log TRPC errors that are in the `errorCodesToAlertOn` list and is
|
||||
// not an AppError.
|
||||
const isLoggableTrpcError = !isAppError && errorCodesToAlertOn.includes(error.code);
|
||||
|
||||
if (isLoggableAppError || isLoggableTrpcError) {
|
||||
logger.error(error, {
|
||||
method: path,
|
||||
context: {
|
||||
appError: AppError.toJSON(appError),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const errorCodesToAlertOn = [AppErrorCode.UNKNOWN_ERROR, 'INTERNAL_SERVER_ERROR'];
|
||||
|
||||
144
package-lock.json
generated
144
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@documenso/root",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@documenso/root",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
@@ -77,7 +77,7 @@
|
||||
},
|
||||
"apps/marketing": {
|
||||
"name": "@documenso/marketing",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@documenso/assets": "*",
|
||||
@@ -438,7 +438,7 @@
|
||||
},
|
||||
"apps/web": {
|
||||
"name": "@documenso/web",
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@documenso/api": "*",
|
||||
@@ -3498,6 +3498,34 @@
|
||||
"resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
|
||||
"integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw=="
|
||||
},
|
||||
"node_modules/@honeybadger-io/core": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/core/-/core-6.6.0.tgz",
|
||||
"integrity": "sha512-B5X05huAsDs7NJOYm4bwHf2v0tMuTjBWLfumHH9DCblq8E1XrujlbbNkIdEHlzc01K9oAXuvsaBwVkE7G5+aLQ==",
|
||||
"dependencies": {
|
||||
"json-nd": "^1.0.0",
|
||||
"stacktrace-parser": "^0.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@honeybadger-io/js": {
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/js/-/js-6.10.1.tgz",
|
||||
"integrity": "sha512-T5WAhYHWHXFMxjY4NSawSY945i8ISIL5/gsjN3m0xO+oXrBAFaul3wY5p/FGH6r6RfCrjHoHl9Iu7Ed9aO9Ehg==",
|
||||
"dependencies": {
|
||||
"@honeybadger-io/core": "^6.6.0",
|
||||
"@types/aws-lambda": "^8.10.89",
|
||||
"@types/express": "^4.17.13"
|
||||
},
|
||||
"bin": {
|
||||
"honeybadger-checkins-sync": "scripts/check-ins-sync-bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@hookform/resolvers": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.2.tgz",
|
||||
@@ -10956,6 +10984,20 @@
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/aws-lambda": {
|
||||
"version": "8.10.146",
|
||||
"resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.146.tgz",
|
||||
"integrity": "sha512-3BaDXYTh0e6UCJYL/jwV/3+GRslSc08toAiZSmleYtkAUyV5rtvdPYxrG/88uqvTuT6sb27WE9OS90ZNTIuQ0g=="
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||
@@ -10968,6 +11010,14 @@
|
||||
"@types/responselike": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||
@@ -11090,6 +11140,28 @@
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-serve-static-core": {
|
||||
"version": "4.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/formidable": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz",
|
||||
@@ -11132,6 +11204,11 @@
|
||||
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/http-errors": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||
@@ -11201,6 +11278,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz",
|
||||
"integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg=="
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
|
||||
},
|
||||
"node_modules/@types/minimatch": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
|
||||
@@ -11338,6 +11420,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
||||
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz",
|
||||
"integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ=="
|
||||
},
|
||||
"node_modules/@types/ramda": {
|
||||
"version": "0.29.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.9.tgz",
|
||||
@@ -11346,6 +11433,11 @@
|
||||
"types-ramda": "^0.29.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.18.tgz",
|
||||
@@ -11401,6 +11493,25 @@
|
||||
"integrity": "sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/serve-static": {
|
||||
"version": "1.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
|
||||
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/node": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/swagger-ui-react": {
|
||||
"version": "4.18.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz",
|
||||
@@ -21011,6 +21122,11 @@
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"node_modules/json-nd": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-nd/-/json-nd-1.0.0.tgz",
|
||||
"integrity": "sha512-8TIp0HZAY0VVrwRQJJPb4+nOTSPoOWZeEKBTLizUfQO4oym5Fc/MKqN8vEbLCxcyxDf2vwNxOQ1q84O49GWPyQ=="
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
@@ -31249,6 +31365,25 @@
|
||||
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/stacktrace-parser": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
|
||||
"integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
|
||||
"dependencies": {
|
||||
"type-fest": "^0.7.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/stacktrace-parser/node_modules/type-fest": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
|
||||
"integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/stampit": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz",
|
||||
@@ -36484,6 +36619,7 @@
|
||||
"@documenso/email": "*",
|
||||
"@documenso/prisma": "*",
|
||||
"@documenso/signing": "*",
|
||||
"@honeybadger-io/js": "^6.10.1",
|
||||
"@lingui/core": "^4.11.3",
|
||||
"@lingui/macro": "^4.11.3",
|
||||
"@lingui/react": "^4.11.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "1.8.1-rc.1",
|
||||
"version": "1.8.1-rc.2",
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"build:web": "turbo run build --filter=@documenso/web",
|
||||
|
||||
@@ -303,6 +303,8 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
signingOrder: body.meta.signingOrder,
|
||||
language: body.meta.language,
|
||||
typedSignatureEnabled: body.meta.typedSignatureEnabled,
|
||||
distributionMethod: body.meta.distributionMethod,
|
||||
emailSettings: body.meta.emailSettings,
|
||||
requestMetadata: extractNextApiRequestMetadata(args.req),
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
ZDocumentActionAuthTypesSchema,
|
||||
ZRecipientActionAuthTypesSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
import {
|
||||
DocumentDataType,
|
||||
@@ -133,8 +134,12 @@ export const ZCreateDocumentMutationSchema = z.object({
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
|
||||
typedSignatureEnabled: z.boolean().optional().default(true),
|
||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod).optional(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||
})
|
||||
.partial(),
|
||||
.partial()
|
||||
.optional()
|
||||
.default({}),
|
||||
authOptions: z
|
||||
.object({
|
||||
globalAccessAuth: ZDocumentAccessAuthTypesSchema.optional(),
|
||||
@@ -257,6 +262,7 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
|
||||
language: z.enum(SUPPORTED_LANGUAGE_CODES),
|
||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
||||
typedSignatureEnabled: z.boolean(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema,
|
||||
})
|
||||
.partial()
|
||||
.optional(),
|
||||
|
||||
@@ -13,7 +13,9 @@ export const getTeamPrices = async () => {
|
||||
const priceIds = prices.map((price) => price.id);
|
||||
|
||||
if (!monthlyPrice || !yearlyPrice) {
|
||||
throw new AppError('INVALID_CONFIG', 'Missing monthly or yearly price');
|
||||
throw new AppError('INVALID_CONFIG', {
|
||||
message: 'Missing monthly or yearly price',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -43,7 +43,9 @@ export const transferTeamSubscription = async ({
|
||||
const teamCustomerId = team.customerId;
|
||||
|
||||
if (!teamCustomerId) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Missing customer ID.');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Missing customer ID.',
|
||||
});
|
||||
}
|
||||
|
||||
const [teamRelatedPlanPriceIds, teamSeatPrices] = await Promise.all([
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import type { TRPCError } from '@trpc/server';
|
||||
import { match } from 'ts-pattern';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -8,46 +8,69 @@ import { TRPCClientError } from '@documenso/trpc/client';
|
||||
* Generic application error codes.
|
||||
*/
|
||||
export enum AppErrorCode {
|
||||
'ALREADY_EXISTS' = 'AlreadyExists',
|
||||
'EXPIRED_CODE' = 'ExpiredCode',
|
||||
'INVALID_BODY' = 'InvalidBody',
|
||||
'INVALID_REQUEST' = 'InvalidRequest',
|
||||
'LIMIT_EXCEEDED' = 'LimitExceeded',
|
||||
'NOT_FOUND' = 'NotFound',
|
||||
'NOT_SETUP' = 'NotSetup',
|
||||
'UNAUTHORIZED' = 'Unauthorized',
|
||||
'UNKNOWN_ERROR' = 'UnknownError',
|
||||
'RETRY_EXCEPTION' = 'RetryException',
|
||||
'SCHEMA_FAILED' = 'SchemaFailed',
|
||||
'TOO_MANY_REQUESTS' = 'TooManyRequests',
|
||||
'PROFILE_URL_TAKEN' = 'ProfileUrlTaken',
|
||||
'PREMIUM_PROFILE_URL' = 'PremiumProfileUrl',
|
||||
'ALREADY_EXISTS' = 'ALREADY_EXISTS',
|
||||
'EXPIRED_CODE' = 'EXPIRED_CODE',
|
||||
'INVALID_BODY' = 'INVALID_BODY',
|
||||
'INVALID_REQUEST' = 'INVALID_REQUEST',
|
||||
'LIMIT_EXCEEDED' = 'LIMIT_EXCEEDED',
|
||||
'NOT_FOUND' = 'NOT_FOUND',
|
||||
'NOT_SETUP' = 'NOT_SETUP',
|
||||
'UNAUTHORIZED' = 'UNAUTHORIZED',
|
||||
'UNKNOWN_ERROR' = 'UNKNOWN_ERROR',
|
||||
'RETRY_EXCEPTION' = 'RETRY_EXCEPTION',
|
||||
'SCHEMA_FAILED' = 'SCHEMA_FAILED',
|
||||
'TOO_MANY_REQUESTS' = 'TOO_MANY_REQUESTS',
|
||||
'PROFILE_URL_TAKEN' = 'PROFILE_URL_TAKEN',
|
||||
'PREMIUM_PROFILE_URL' = 'PREMIUM_PROFILE_URL',
|
||||
}
|
||||
|
||||
const genericErrorCodeToTrpcErrorCodeMap: Record<string, TRPCError['code']> = {
|
||||
[AppErrorCode.ALREADY_EXISTS]: 'BAD_REQUEST',
|
||||
[AppErrorCode.EXPIRED_CODE]: 'BAD_REQUEST',
|
||||
[AppErrorCode.INVALID_BODY]: 'BAD_REQUEST',
|
||||
[AppErrorCode.INVALID_REQUEST]: 'BAD_REQUEST',
|
||||
[AppErrorCode.NOT_FOUND]: 'NOT_FOUND',
|
||||
[AppErrorCode.NOT_SETUP]: 'BAD_REQUEST',
|
||||
[AppErrorCode.UNAUTHORIZED]: 'UNAUTHORIZED',
|
||||
[AppErrorCode.UNKNOWN_ERROR]: 'INTERNAL_SERVER_ERROR',
|
||||
[AppErrorCode.RETRY_EXCEPTION]: 'INTERNAL_SERVER_ERROR',
|
||||
[AppErrorCode.SCHEMA_FAILED]: 'INTERNAL_SERVER_ERROR',
|
||||
[AppErrorCode.TOO_MANY_REQUESTS]: 'TOO_MANY_REQUESTS',
|
||||
[AppErrorCode.PROFILE_URL_TAKEN]: 'BAD_REQUEST',
|
||||
[AppErrorCode.PREMIUM_PROFILE_URL]: 'BAD_REQUEST',
|
||||
export const genericErrorCodeToTrpcErrorCodeMap: Record<
|
||||
string,
|
||||
{ code: TRPCError['code']; status: number }
|
||||
> = {
|
||||
[AppErrorCode.ALREADY_EXISTS]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.EXPIRED_CODE]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.INVALID_BODY]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.INVALID_REQUEST]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.NOT_FOUND]: { code: 'NOT_FOUND', status: 404 },
|
||||
[AppErrorCode.NOT_SETUP]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.UNAUTHORIZED]: { code: 'UNAUTHORIZED', status: 401 },
|
||||
[AppErrorCode.UNKNOWN_ERROR]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
||||
[AppErrorCode.RETRY_EXCEPTION]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
||||
[AppErrorCode.SCHEMA_FAILED]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
||||
[AppErrorCode.TOO_MANY_REQUESTS]: { code: 'TOO_MANY_REQUESTS', status: 429 },
|
||||
[AppErrorCode.PROFILE_URL_TAKEN]: { code: 'BAD_REQUEST', status: 400 },
|
||||
[AppErrorCode.PREMIUM_PROFILE_URL]: { code: 'BAD_REQUEST', status: 400 },
|
||||
};
|
||||
|
||||
export const ZAppErrorJsonSchema = z.object({
|
||||
code: z.string(),
|
||||
message: z.string().optional(),
|
||||
userMessage: z.string().optional(),
|
||||
statusCode: z.number().optional(),
|
||||
});
|
||||
|
||||
export type TAppErrorJsonSchema = z.infer<typeof ZAppErrorJsonSchema>;
|
||||
|
||||
type AppErrorOptions = {
|
||||
/**
|
||||
* An internal message for logging.
|
||||
*/
|
||||
message?: string;
|
||||
|
||||
/**
|
||||
* A message which can be potientially displayed to the user.
|
||||
*/
|
||||
userMessage?: string;
|
||||
|
||||
/**
|
||||
* The status code to be associated with the error.
|
||||
*
|
||||
* Mainly used for API -> Frontend communication and logging filtering.
|
||||
*/
|
||||
statusCode?: number;
|
||||
};
|
||||
|
||||
export class AppError extends Error {
|
||||
/**
|
||||
* The error code.
|
||||
@@ -59,6 +82,11 @@ export class AppError extends Error {
|
||||
*/
|
||||
userMessage?: string;
|
||||
|
||||
/**
|
||||
* The status code to be associated with the error.
|
||||
*/
|
||||
statusCode?: number;
|
||||
|
||||
/**
|
||||
* Create a new AppError.
|
||||
*
|
||||
@@ -66,10 +94,12 @@ export class AppError extends Error {
|
||||
* @param message An internal error message.
|
||||
* @param userMessage A error message which can be displayed to the user.
|
||||
*/
|
||||
public constructor(errorCode: string, message?: string, userMessage?: string) {
|
||||
super(message || errorCode);
|
||||
public constructor(errorCode: string, options?: AppErrorOptions) {
|
||||
super(options?.message || errorCode);
|
||||
|
||||
this.code = errorCode;
|
||||
this.userMessage = userMessage;
|
||||
this.userMessage = options?.userMessage;
|
||||
this.statusCode = options?.statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,16 +114,21 @@ export class AppError extends Error {
|
||||
|
||||
// Handle TRPC errors.
|
||||
if (error instanceof TRPCClientError) {
|
||||
const parsedJsonError = AppError.parseFromJSONString(error.message);
|
||||
return parsedJsonError || new AppError('UnknownError', error.message);
|
||||
const parsedJsonError = AppError.parseFromJSON(error.data?.appError);
|
||||
|
||||
const fallbackError = new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: error.message,
|
||||
});
|
||||
|
||||
return parsedJsonError || fallbackError;
|
||||
}
|
||||
|
||||
// Handle completely unknown errors.
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const { code, message, userMessage } = error as {
|
||||
const { code, message, userMessage, statusCode } = error as {
|
||||
code: unknown;
|
||||
message: unknown;
|
||||
status: unknown;
|
||||
statusCode: unknown;
|
||||
userMessage: unknown;
|
||||
};
|
||||
|
||||
@@ -102,16 +137,15 @@ export class AppError extends Error {
|
||||
const validUserMessage: string | undefined =
|
||||
typeof userMessage === 'string' ? userMessage : undefined;
|
||||
|
||||
return new AppError(validCode, validMessage, validUserMessage);
|
||||
}
|
||||
const validStatusCode = typeof statusCode === 'number' ? statusCode : undefined;
|
||||
|
||||
static parseErrorToTRPCError(error: unknown): TRPCError {
|
||||
const appError = AppError.parseError(error);
|
||||
const options: AppErrorOptions = {
|
||||
message: validMessage,
|
||||
userMessage: validUserMessage,
|
||||
statusCode: validStatusCode,
|
||||
};
|
||||
|
||||
return new TRPCError({
|
||||
code: genericErrorCodeToTrpcErrorCodeMap[appError.code] || 'BAD_REQUEST',
|
||||
message: AppError.toJSONString(appError),
|
||||
});
|
||||
return new AppError(validCode, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,12 +154,26 @@ export class AppError extends Error {
|
||||
* @param appError The AppError to convert to JSON.
|
||||
* @returns A JSON object representing the AppError.
|
||||
*/
|
||||
static toJSON({ code, message, userMessage }: AppError): TAppErrorJsonSchema {
|
||||
return {
|
||||
static toJSON({ code, message, userMessage, statusCode }: AppError): TAppErrorJsonSchema {
|
||||
const data: TAppErrorJsonSchema = {
|
||||
code,
|
||||
message,
|
||||
userMessage,
|
||||
};
|
||||
|
||||
// Explicity only set values if it exists, since TRPC will add meta for undefined
|
||||
// values which clutters up API responses.
|
||||
if (message) {
|
||||
data.message = message;
|
||||
}
|
||||
|
||||
if (userMessage) {
|
||||
data.userMessage = userMessage;
|
||||
}
|
||||
|
||||
if (statusCode) {
|
||||
data.statusCode = statusCode;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,15 +186,21 @@ export class AppError extends Error {
|
||||
return JSON.stringify(AppError.toJSON(appError));
|
||||
}
|
||||
|
||||
static parseFromJSONString(jsonString: string): AppError | null {
|
||||
static parseFromJSON(value: unknown): AppError | null {
|
||||
try {
|
||||
const parsed = ZAppErrorJsonSchema.safeParse(JSON.parse(jsonString));
|
||||
const parsed = ZAppErrorJsonSchema.safeParse(value);
|
||||
|
||||
if (!parsed.success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AppError(parsed.data.code, parsed.data.message, parsed.data.userMessage);
|
||||
const { message, userMessage, statusCode } = parsed.data;
|
||||
|
||||
return new AppError(parsed.data.code, {
|
||||
message,
|
||||
userMessage,
|
||||
statusCode,
|
||||
});
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"@documenso/email": "*",
|
||||
"@documenso/prisma": "*",
|
||||
"@documenso/signing": "*",
|
||||
"@honeybadger-io/js": "^6.10.1",
|
||||
"@lingui/core": "^4.11.3",
|
||||
"@lingui/macro": "^4.11.3",
|
||||
"@lingui/react": "^4.11.3",
|
||||
@@ -62,4 +63,4 @@
|
||||
"@types/luxon": "^3.3.1",
|
||||
"@types/pg": "^8.11.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ export const createPasskeyAuthenticationOptions = async ({
|
||||
});
|
||||
|
||||
if (!preferredPasskey) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Requested passkey not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Requested passkey not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ export const createPasskey = async ({
|
||||
});
|
||||
|
||||
if (!verificationToken) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Challenge token not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Challenge token not found',
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.verificationToken.deleteMany({
|
||||
@@ -61,7 +63,9 @@ export const createPasskey = async ({
|
||||
});
|
||||
|
||||
if (verificationToken.expires < new Date()) {
|
||||
throw new AppError(AppErrorCode.EXPIRED_CODE, 'Challenge token expired');
|
||||
throw new AppError(AppErrorCode.EXPIRED_CODE, {
|
||||
message: 'Challenge token expired',
|
||||
});
|
||||
}
|
||||
|
||||
const { rpId: expectedRPID, origin: expectedOrigin } = getAuthenticatorOptions();
|
||||
@@ -74,7 +78,9 @@ export const createPasskey = async ({
|
||||
});
|
||||
|
||||
if (!verification.verified || !verification.registrationInfo) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Verification failed');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Verification failed',
|
||||
});
|
||||
}
|
||||
|
||||
const { credentialPublicKey, credentialID, counter, credentialDeviceType, credentialBackedUp } =
|
||||
|
||||
@@ -47,7 +47,9 @@ export const createDocument = async ({
|
||||
teamId !== undefined &&
|
||||
!user.teamMembers.some((teamMember) => teamMember.teamId === teamId)
|
||||
) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Team not found',
|
||||
});
|
||||
}
|
||||
|
||||
let team: (Team & { teamGlobalSettings: TeamGlobalSettings | null }) | null = null;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { prisma } from '@documenso/prisma';
|
||||
import type { Prisma } from '@documenso/prisma/client';
|
||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { DocumentVisibility } from '../../types/document-visibility';
|
||||
import { getTeamById } from '../team/get-team';
|
||||
|
||||
@@ -20,7 +21,7 @@ export const getDocumentById = async ({ id, userId, teamId }: GetDocumentByIdOpt
|
||||
teamId,
|
||||
});
|
||||
|
||||
return await prisma.document.findFirstOrThrow({
|
||||
const document = await prisma.document.findFirst({
|
||||
where: documentWhereInput,
|
||||
include: {
|
||||
documentData: true,
|
||||
@@ -45,6 +46,14 @@ export const getDocumentById = async ({ id, userId, teamId }: GetDocumentByIdOpt
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!document) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Document could not be found',
|
||||
});
|
||||
}
|
||||
|
||||
return document;
|
||||
};
|
||||
|
||||
export type GetDocumentWhereInputOptions = {
|
||||
|
||||
@@ -107,7 +107,9 @@ export const getDocumentAndSenderByToken = async ({
|
||||
}
|
||||
|
||||
if (!documentAccessValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid access values');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Invalid access values',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -167,7 +169,9 @@ export const getDocumentAndRecipientByToken = async ({
|
||||
}
|
||||
|
||||
if (!documentAccessValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid access values');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Invalid access values',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -106,7 +106,9 @@ export const isRecipientAuthorized = async ({
|
||||
|
||||
// Should not be possible.
|
||||
if (!user) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'User not found',
|
||||
});
|
||||
}
|
||||
|
||||
return await verifyTwoFactorAuthenticationToken({
|
||||
@@ -164,7 +166,9 @@ const verifyPasskey = async ({
|
||||
});
|
||||
|
||||
if (!passkey) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Passkey not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Passkey not found',
|
||||
});
|
||||
}
|
||||
|
||||
const verificationToken = await prisma.verificationToken
|
||||
@@ -177,11 +181,15 @@ const verifyPasskey = async ({
|
||||
.catch(() => null);
|
||||
|
||||
if (!verificationToken) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Token not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Token not found',
|
||||
});
|
||||
}
|
||||
|
||||
if (verificationToken.expires < new Date()) {
|
||||
throw new AppError(AppErrorCode.EXPIRED_CODE, 'Token expired');
|
||||
throw new AppError(AppErrorCode.EXPIRED_CODE, {
|
||||
message: 'Token expired',
|
||||
});
|
||||
}
|
||||
|
||||
const { rpId, origin } = getAuthenticatorOptions();
|
||||
@@ -199,7 +207,9 @@ const verifyPasskey = async ({
|
||||
}).catch(() => null); // May want to log this for insights.
|
||||
|
||||
if (verification?.verified !== true) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'User is not authorized');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'User is not authorized',
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.passkey.update({
|
||||
|
||||
@@ -37,7 +37,9 @@ export const updateDocumentSettings = async ({
|
||||
requestMetadata,
|
||||
}: UpdateDocumentSettingsOptions) => {
|
||||
if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Missing data to update',
|
||||
});
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
@@ -96,10 +98,9 @@ export const updateDocumentSettings = async ({
|
||||
!allowedVisibilities.includes(document.visibility) ||
|
||||
(data.visibility && !allowedVisibilities.includes(data.visibility))
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to update the document visibility',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to update the document visibility',
|
||||
});
|
||||
}
|
||||
})
|
||||
.with(TeamMemberRole.MEMBER, () => {
|
||||
@@ -107,17 +108,15 @@ export const updateDocumentSettings = async ({
|
||||
document.visibility !== DocumentVisibility.EVERYONE ||
|
||||
(data.visibility && data.visibility !== DocumentVisibility.EVERYONE)
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to update the document visibility',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to update the document visibility',
|
||||
});
|
||||
}
|
||||
})
|
||||
.otherwise(() => {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to update the document',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to update the document',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -142,10 +141,9 @@ export const updateDocumentSettings = async ({
|
||||
});
|
||||
|
||||
if (!isDocumentEnterprise) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to set the action auth',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to set the action auth',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,10 +159,9 @@ export const updateDocumentSettings = async ({
|
||||
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
||||
|
||||
if (!isTitleSame && document.status !== DocumentStatus.DRAFT) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_BODY,
|
||||
'You cannot update the title if the document has been sent',
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'You cannot update the title if the document has been sent',
|
||||
});
|
||||
}
|
||||
|
||||
if (!isTitleSame) {
|
||||
|
||||
@@ -45,7 +45,9 @@ export const validateFieldAuth = async ({
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Invalid authentication values',
|
||||
});
|
||||
}
|
||||
|
||||
return derivedRecipientActionAuth;
|
||||
|
||||
@@ -104,7 +104,9 @@ export const setFieldsForDocument = async ({
|
||||
|
||||
// Each field MUST have a recipient associated with it.
|
||||
if (!recipient) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, `Recipient not found for field ${field.id}`);
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: `Recipient not found for field ${field.id}`,
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether the existing field can be modified.
|
||||
@@ -113,10 +115,10 @@ export const setFieldsForDocument = async ({
|
||||
hasFieldBeenChanged(existing, field) &&
|
||||
!canRecipientFieldsBeModified(recipient, existingFields)
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_REQUEST,
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message:
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -115,7 +115,9 @@ export const getPublicProfileByUrl = async ({
|
||||
// Log as critical error.
|
||||
if (user?.profile && team?.profile) {
|
||||
console.error('Profile URL is ambiguous', { profileUrl, userId: user.id, teamId: team.id });
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Profile URL is ambiguous');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Profile URL is ambiguous',
|
||||
});
|
||||
}
|
||||
|
||||
if (user?.profile?.enabled) {
|
||||
@@ -177,5 +179,7 @@ export const getPublicProfileByUrl = async ({
|
||||
};
|
||||
}
|
||||
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Profile not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Profile not found',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -18,10 +18,9 @@ export const getTeamTokens = async ({ userId, teamId }: GetUserTokensOptions) =>
|
||||
});
|
||||
|
||||
if (teamMember?.role !== TeamMemberRole.ADMIN) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have the required permissions to view this page.',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have the required permissions to view this page.',
|
||||
});
|
||||
}
|
||||
|
||||
return await prisma.apiToken.findMany({
|
||||
|
||||
@@ -105,10 +105,9 @@ export const setRecipientsForDocument = async ({
|
||||
});
|
||||
|
||||
if (!isDocumentEnterprise) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to set the action auth',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to set the action auth',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +141,9 @@ export const setRecipientsForDocument = async ({
|
||||
hasRecipientBeenChanged(existing, recipient) &&
|
||||
!canRecipientBeModified(existing, document.Field)
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_REQUEST,
|
||||
'Cannot modify a recipient who has already interacted with the document',
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Cannot modify a recipient who has already interacted with the document',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -72,10 +72,9 @@ export const setRecipientsForTemplate = async ({
|
||||
});
|
||||
|
||||
if (!isDocumentEnterprise) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to set the action auth',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to set the action auth',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,14 +118,15 @@ export const setRecipientsForTemplate = async ({
|
||||
);
|
||||
|
||||
if (updatedDirectRecipient?.role === RecipientRole.CC) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Cannot set direct recipient as CC');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Cannot set direct recipient as CC',
|
||||
});
|
||||
}
|
||||
|
||||
if (deletedDirectRecipient) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_BODY,
|
||||
'Cannot delete direct recipient while direct template exists',
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Cannot delete direct recipient while direct template exists',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,10 +96,9 @@ export const updateRecipient = async ({
|
||||
});
|
||||
|
||||
if (!isDocumentEnterprise) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to set the action auth',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to set the action auth',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ export const createTeamPendingCheckoutSession = async ({
|
||||
console.error(e);
|
||||
|
||||
// Absorb all the errors incase Stripe throws something sensitive.
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, 'Something went wrong.');
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Something went wrong.',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,10 +55,9 @@ export const createTeamEmailVerification = async ({
|
||||
});
|
||||
|
||||
if (team.teamEmail || team.emailVerification) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_REQUEST,
|
||||
'Team already has an email or existing email verification.',
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Team already has an email or existing email verification.',
|
||||
});
|
||||
}
|
||||
|
||||
const existingTeamEmail = await tx.teamEmail.findFirst({
|
||||
@@ -68,7 +67,9 @@ export const createTeamEmailVerification = async ({
|
||||
});
|
||||
|
||||
if (existingTeamEmail) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Email already taken by another team.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Email already taken by another team.',
|
||||
});
|
||||
}
|
||||
|
||||
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
||||
@@ -97,7 +98,9 @@ export const createTeamEmailVerification = async ({
|
||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||
|
||||
if (err.code === 'P2002' && target.success && target.data.includes('email')) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Email already taken by another team.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Email already taken by another team.',
|
||||
});
|
||||
}
|
||||
|
||||
throw err;
|
||||
|
||||
@@ -69,7 +69,9 @@ export const createTeamMemberInvites = async ({
|
||||
const currentTeamMember = team.members.find((member) => member.user.id === userId);
|
||||
|
||||
if (!currentTeamMember) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'User not part of team.');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'User not part of team.',
|
||||
});
|
||||
}
|
||||
|
||||
const usersToInvite = invitations.filter((invitation) => {
|
||||
@@ -91,10 +93,9 @@ export const createTeamMemberInvites = async ({
|
||||
);
|
||||
|
||||
if (unauthorizedRoleAccess) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'User does not have permission to set high level roles',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'User does not have permission to set high level roles',
|
||||
});
|
||||
}
|
||||
|
||||
const teamMemberInvites = usersToInvite.map(({ email, role }) => ({
|
||||
@@ -127,11 +128,10 @@ export const createTeamMemberInvites = async ({
|
||||
if (sendEmailResultErrorList.length > 0) {
|
||||
console.error(JSON.stringify(sendEmailResultErrorList));
|
||||
|
||||
throw new AppError(
|
||||
'EmailDeliveryFailed',
|
||||
'Failed to send invite emails to one or more users.',
|
||||
`Failed to send invites to ${sendEmailResultErrorList.length}/${teamMemberInvites.length} users.`,
|
||||
);
|
||||
throw new AppError('EmailDeliveryFailed', {
|
||||
message: 'Failed to send invite emails to one or more users.',
|
||||
userMessage: `Failed to send invites to ${sendEmailResultErrorList.length}/${teamMemberInvites.length} users.`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -87,7 +87,9 @@ export const createTeam = async ({
|
||||
});
|
||||
|
||||
if (existingUserProfileWithUrl) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'URL already taken.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'URL already taken.',
|
||||
});
|
||||
}
|
||||
|
||||
await tx.team.create({
|
||||
@@ -131,15 +133,21 @@ export const createTeam = async ({
|
||||
});
|
||||
|
||||
if (existingUserProfileWithUrl) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'URL already taken.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'URL already taken.',
|
||||
});
|
||||
}
|
||||
|
||||
if (existingTeamWithUrl) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Team URL already exists.',
|
||||
});
|
||||
}
|
||||
|
||||
if (!customerId) {
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, 'Missing customer ID for pending teams.');
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Missing customer ID for pending teams.',
|
||||
});
|
||||
}
|
||||
|
||||
return await tx.teamPending.create({
|
||||
@@ -166,7 +174,9 @@ export const createTeam = async ({
|
||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||
|
||||
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Team URL already exists.',
|
||||
});
|
||||
}
|
||||
|
||||
throw err;
|
||||
|
||||
@@ -60,11 +60,13 @@ export const deleteTeamMembers = async ({
|
||||
);
|
||||
|
||||
if (!currentTeamMember) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team member record does not exist');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Team member record does not exist',
|
||||
});
|
||||
}
|
||||
|
||||
if (teamMembersToRemove.find((member) => member.userId === team.ownerUserId)) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot remove the team owner');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'Cannot remove the team owner' });
|
||||
}
|
||||
|
||||
const isMemberToRemoveHigherRole = teamMembersToRemove.some(
|
||||
@@ -72,7 +74,9 @@ export const deleteTeamMembers = async ({
|
||||
);
|
||||
|
||||
if (isMemberToRemoveHigherRole) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot remove a member with a higher role');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Cannot remove a member with a higher role',
|
||||
});
|
||||
}
|
||||
|
||||
// Remove the team members.
|
||||
|
||||
@@ -24,7 +24,9 @@ export const findTeamInvoices = async ({ userId, teamId }: FindTeamInvoicesOptio
|
||||
});
|
||||
|
||||
if (!team.customerId) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team has no customer ID.');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Team has no customer ID.',
|
||||
});
|
||||
}
|
||||
|
||||
const results = await getInvoices({ customerId: team.customerId });
|
||||
|
||||
@@ -33,7 +33,9 @@ export const getTeamPublicProfile = async ({
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Team not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Create and return the public profile.
|
||||
@@ -47,7 +49,9 @@ export const getTeamPublicProfile = async ({
|
||||
});
|
||||
|
||||
if (!profile) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Failed to create public profile');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Failed to create public profile',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -38,16 +38,17 @@ export const resendTeamEmailVerification = async ({
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new AppError('TeamNotFound', 'User is not a member of the team.');
|
||||
throw new AppError('TeamNotFound', {
|
||||
message: 'User is not a member of the team.',
|
||||
});
|
||||
}
|
||||
|
||||
const { emailVerification } = team;
|
||||
|
||||
if (!emailVerification) {
|
||||
throw new AppError(
|
||||
'VerificationNotFound',
|
||||
'No team email verification exists for this team.',
|
||||
);
|
||||
throw new AppError('VerificationNotFound', {
|
||||
message: 'No team email verification exists for this team.',
|
||||
});
|
||||
}
|
||||
|
||||
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
||||
|
||||
@@ -55,7 +55,7 @@ export const resendTeamMemberInvitation = async ({
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new AppError('TeamNotFound', 'User is not a valid member of the team.');
|
||||
throw new AppError('TeamNotFound', { message: 'User is not a valid member of the team.' });
|
||||
}
|
||||
|
||||
const teamMemberInvite = await tx.teamMemberInvite.findUniqueOrThrow({
|
||||
@@ -66,7 +66,7 @@ export const resendTeamMemberInvitation = async ({
|
||||
});
|
||||
|
||||
if (!teamMemberInvite) {
|
||||
throw new AppError('InviteNotFound', 'No invite exists for this user.');
|
||||
throw new AppError('InviteNotFound', { message: 'No invite exists for this user.' });
|
||||
}
|
||||
|
||||
await sendTeamMemberInviteEmail({
|
||||
|
||||
@@ -48,11 +48,11 @@ export const updateTeamMember = async ({
|
||||
const teamMemberToUpdate = team.members.find((member) => member.id === teamMemberId);
|
||||
|
||||
if (!teamMemberToUpdate || !currentTeamMember) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team member does not exist');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Team member does not exist' });
|
||||
}
|
||||
|
||||
if (teamMemberToUpdate.userId === team.ownerUserId) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot update the owner');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'Cannot update the owner' });
|
||||
}
|
||||
|
||||
const isMemberToUpdateHigherRole = !isTeamRoleWithinUserHierarchy(
|
||||
@@ -61,7 +61,9 @@ export const updateTeamMember = async ({
|
||||
);
|
||||
|
||||
if (isMemberToUpdateHigherRole) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot update a member with a higher role');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Cannot update a member with a higher role',
|
||||
});
|
||||
}
|
||||
|
||||
const isNewMemberRoleHigherThanCurrentRole = !isTeamRoleWithinUserHierarchy(
|
||||
@@ -70,10 +72,9 @@ export const updateTeamMember = async ({
|
||||
);
|
||||
|
||||
if (isNewMemberRoleHigherThanCurrentRole) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'Cannot give a member a role higher than the user initating the update',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Cannot give a member a role higher than the user initating the update',
|
||||
});
|
||||
}
|
||||
|
||||
return await tx.teamMember.update({
|
||||
|
||||
@@ -24,7 +24,9 @@ export const updateTeam = async ({ userId, teamId, data }: UpdateTeamOptions) =>
|
||||
});
|
||||
|
||||
if (foundPendingTeamWithUrl) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Team URL already exists.',
|
||||
});
|
||||
}
|
||||
|
||||
const team = await tx.team.update({
|
||||
@@ -57,7 +59,9 @@ export const updateTeam = async ({ userId, teamId, data }: UpdateTeamOptions) =>
|
||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||
|
||||
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
||||
message: 'Team URL already exists.',
|
||||
});
|
||||
}
|
||||
|
||||
throw err;
|
||||
|
||||
@@ -101,7 +101,7 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
});
|
||||
|
||||
if (!template?.directLink?.enabled) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Invalid or missing template');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, { message: 'Invalid or missing template' });
|
||||
}
|
||||
|
||||
const { Recipient: recipients, directLink, User: templateOwner } = template;
|
||||
@@ -111,15 +111,19 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
);
|
||||
|
||||
if (!directTemplateRecipient || directTemplateRecipient.role === RecipientRole.CC) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Invalid or missing direct recipient');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Invalid or missing direct recipient',
|
||||
});
|
||||
}
|
||||
|
||||
if (template.updatedAt.getTime() !== templateUpdatedAt.getTime()) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Template no longer matches');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, { message: 'Template no longer matches' });
|
||||
}
|
||||
|
||||
if (user && user.email !== directRecipientEmail) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Email must match if you are logged in');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Email must match if you are logged in',
|
||||
});
|
||||
}
|
||||
|
||||
const { derivedRecipientAccessAuth, documentAuthOption: templateAuthOptions } =
|
||||
@@ -136,7 +140,7 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
.exhaustive();
|
||||
|
||||
if (!isAccessAuthValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'You must be logged in');
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'You must be logged in' });
|
||||
}
|
||||
|
||||
const directTemplateRecipientAuthOptions = ZRecipientAuthOptionsSchema.parse(
|
||||
@@ -163,7 +167,9 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
);
|
||||
|
||||
if (!signedFieldValue) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Invalid, missing or changed fields');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Invalid, missing or changed fields',
|
||||
});
|
||||
}
|
||||
|
||||
if (templateField.type === FieldType.NAME && directRecipientName === undefined) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { SupportedLanguageCodes } from '../../constants/i18n';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||
import { ZRecipientAuthOptionsSchema } from '../../types/document-auth';
|
||||
import type { TDocumentEmailSettings } from '../../types/document-email';
|
||||
import { ZFieldMetaSchema } from '../../types/field-meta';
|
||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||
@@ -65,6 +66,7 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
language?: SupportedLanguageCodes;
|
||||
distributionMethod?: DocumentDistributionMethod;
|
||||
typedSignatureEnabled?: boolean;
|
||||
emailSettings?: TDocumentEmailSettings;
|
||||
};
|
||||
requestMetadata?: RequestMetadata;
|
||||
};
|
||||
@@ -120,7 +122,9 @@ export const createDocumentFromTemplate = async ({
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Check that all the passed in recipient IDs can be associated with a template recipient.
|
||||
@@ -130,10 +134,9 @@ export const createDocumentFromTemplate = async ({
|
||||
);
|
||||
|
||||
if (!foundRecipient) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_BODY,
|
||||
`Recipient with ID ${recipient.id} not found in the template.`,
|
||||
);
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: `Recipient with ID ${recipient.id} not found in the template.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -188,7 +191,9 @@ export const createDocumentFromTemplate = async ({
|
||||
redirectUrl: override?.redirectUrl || template.templateMeta?.redirectUrl,
|
||||
distributionMethod:
|
||||
override?.distributionMethod || template.templateMeta?.distributionMethod,
|
||||
emailSettings: template.templateMeta?.emailSettings || undefined,
|
||||
// last `undefined` is due to JsonValue's
|
||||
emailSettings:
|
||||
override?.emailSettings || template.templateMeta?.emailSettings || undefined,
|
||||
signingOrder:
|
||||
override?.signingOrder ||
|
||||
template.templateMeta?.signingOrder ||
|
||||
|
||||
@@ -47,18 +47,18 @@ export const createTemplateDirectLink = async ({
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Template not found' });
|
||||
}
|
||||
|
||||
if (template.directLink) {
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Direct template already exists');
|
||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, { message: 'Direct template already exists' });
|
||||
}
|
||||
|
||||
if (
|
||||
directRecipientId &&
|
||||
!template.Recipient.find((recipient) => recipient.id === directRecipientId)
|
||||
) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Recipient not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Recipient not found' });
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -67,7 +67,9 @@ export const createTemplateDirectLink = async ({
|
||||
(recipient) => recipient.email.toLowerCase() === DIRECT_TEMPLATE_RECIPIENT_EMAIL,
|
||||
)
|
||||
) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Cannot generate placeholder direct recipient');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Cannot generate placeholder direct recipient',
|
||||
});
|
||||
}
|
||||
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
|
||||
@@ -39,7 +39,9 @@ export const deleteTemplateDirectLink = async ({
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
const { directLink } = template;
|
||||
|
||||
@@ -53,7 +53,9 @@ export const getTemplateById = async ({ id, userId, teamId }: GetTemplateByIdOpt
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
return template;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { TemplateWithDetails } from '@documenso/prisma/types/template';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
|
||||
export type GetTemplateWithDetailsByIdOptions = {
|
||||
id: number;
|
||||
userId: number;
|
||||
@@ -10,7 +12,7 @@ export const getTemplateWithDetailsById = async ({
|
||||
id,
|
||||
userId,
|
||||
}: GetTemplateWithDetailsByIdOptions): Promise<TemplateWithDetails> => {
|
||||
return await prisma.template.findFirstOrThrow({
|
||||
const template = await prisma.template.findFirst({
|
||||
where: {
|
||||
id,
|
||||
OR: [
|
||||
@@ -36,4 +38,12 @@ export const getTemplateWithDetailsById = async ({
|
||||
Field: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
return template;
|
||||
};
|
||||
|
||||
@@ -40,13 +40,17 @@ export const toggleTemplateDirectLink = async ({
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
const { directLink } = template;
|
||||
|
||||
if (!directLink) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Direct template link not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Direct template link not found',
|
||||
});
|
||||
}
|
||||
|
||||
return await prisma.templateDirectLink.update({
|
||||
|
||||
@@ -34,7 +34,9 @@ export const updateTemplateSettings = async ({
|
||||
data,
|
||||
}: UpdateTemplateSettingsOptions) => {
|
||||
if (Object.values(data).length === 0 && Object.keys(meta ?? {}).length === 0) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Missing data to update',
|
||||
});
|
||||
}
|
||||
|
||||
const template = await prisma.template.findFirstOrThrow({
|
||||
@@ -82,10 +84,9 @@ export const updateTemplateSettings = async ({
|
||||
});
|
||||
|
||||
if (!isDocumentEnterprise) {
|
||||
throw new AppError(
|
||||
AppErrorCode.UNAUTHORIZED,
|
||||
'You do not have permission to set the action auth',
|
||||
);
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to set the action auth',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,11 +38,10 @@ export const createUser = async ({ name, email, password, signature, url }: Crea
|
||||
});
|
||||
|
||||
if (urlExists) {
|
||||
throw new AppError(
|
||||
AppErrorCode.PROFILE_URL_TAKEN,
|
||||
'Profile username is taken',
|
||||
'The profile username is already taken',
|
||||
);
|
||||
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, {
|
||||
message: 'Profile username is taken',
|
||||
userMessage: 'The profile username is already taken',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export const getUserPublicProfile = async ({
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'User not found' });
|
||||
}
|
||||
|
||||
// Create and return the public profile.
|
||||
@@ -39,7 +39,7 @@ export const getUserPublicProfile = async ({
|
||||
});
|
||||
|
||||
if (!profile) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Failed to create public profile');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Failed to create public profile' });
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -13,7 +13,7 @@ export type UpdatePublicProfileOptions = {
|
||||
|
||||
export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileOptions) => {
|
||||
if (Object.values(data).length === 0) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, { message: 'Missing data to update' });
|
||||
}
|
||||
|
||||
const { url, bio, enabled } = data;
|
||||
@@ -25,13 +25,15 @@ export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileO
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'User not found' });
|
||||
}
|
||||
|
||||
const finalUrl = url ?? user.url;
|
||||
|
||||
if (!finalUrl && enabled) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Cannot enable a profile without a URL');
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Cannot enable a profile without a URL',
|
||||
});
|
||||
}
|
||||
|
||||
if (url) {
|
||||
@@ -57,7 +59,9 @@ export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileO
|
||||
});
|
||||
|
||||
if (isUrlTakenByAnotherUser || isUrlTakenByAnotherTeam) {
|
||||
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, 'The profile username is already taken');
|
||||
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, {
|
||||
message: 'The profile username is already taken',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ msgstr "Ein Empfänger wurde entfernt"
|
||||
msgid "A recipient was updated"
|
||||
msgstr "Ein Empfänger wurde aktualisiert"
|
||||
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||
msgstr "Eine Anfrage zur Verwendung Ihrer E-Mail wurde von {0} auf Documenso initiiert"
|
||||
|
||||
@@ -711,7 +711,7 @@ msgid "Document created"
|
||||
msgstr "Dokument erstellt"
|
||||
|
||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
||||
msgid "Document created from direct template"
|
||||
msgstr "Dokument erstellt aus direkter Vorlage"
|
||||
|
||||
@@ -1774,7 +1774,7 @@ msgstr "Du wurdest eingeladen, {0} auf Documenso beizutreten"
|
||||
msgid "You have been invited to join the following team"
|
||||
msgstr "Du wurdest eingeladen, dem folgenden Team beizutreten"
|
||||
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
||||
msgid "You have been removed from a document"
|
||||
msgstr "Du wurdest von einem Dokument entfernt"
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ msgstr ""
|
||||
"X-Crowdin-File: web.po\n"
|
||||
"X-Crowdin-File-ID: 8\n"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:231
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
msgid "\"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{0}\" hat Sie eingeladen, \"Beispieldokument\" zu unterschreiben."
|
||||
|
||||
@@ -42,7 +42,7 @@ msgstr "\"{documentTitle}\" wurde erfolgreich gelöscht"
|
||||
#~ "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example\n"
|
||||
#~ "document\"."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
msgid "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{placeholderEmail}\" im Namen von \"{0}\" hat Sie eingeladen, \"Beispieldokument\" zu unterzeichnen."
|
||||
|
||||
@@ -50,15 +50,15 @@ msgstr "\"{placeholderEmail}\" im Namen von \"{0}\" hat Sie eingeladen, \"Beispi
|
||||
#~ msgid "\"{teamUrl}\" has invited you to sign \"example document\"."
|
||||
#~ msgstr "\"{teamUrl}\" hat Sie eingeladen, \"Beispieldokument\" zu unterschreiben."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:83
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu genehmigen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu unterzeichnen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu betrachten"
|
||||
|
||||
@@ -71,7 +71,7 @@ msgstr "{0, plural, one {(1 Zeichen über dem Limit)} other {(# Zeichen über de
|
||||
msgid "{0, plural, one {# character over the limit} other {# characters over the limit}}"
|
||||
msgstr "{0, plural, one {# Zeichen über dem Limit} other {# Zeichen über dem Limit}}"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:82
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:84
|
||||
msgid "{0, plural, one {# recipient} other {# recipients}}"
|
||||
msgstr "{0, plural, one {# Empfänger} other {# Empfänger}}"
|
||||
|
||||
@@ -88,11 +88,11 @@ msgstr "{0, plural, one {<0>Du hast <1>1</1> ausstehende Team-Einladung</0>} oth
|
||||
msgid "{0, plural, one {1 matching field} other {# matching fields}}"
|
||||
msgstr "{0, plural, one {1 passendes Feld} other {# passende Felder}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:132
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Empfänger} other {# Empfänger}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:235
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:238
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {Warte auf 1 Empfänger} other {Warte auf # Empfänger}}"
|
||||
|
||||
@@ -116,7 +116,7 @@ msgstr "{0} direkte Signaturvorlagen"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} von {1} Dokumenten verbleibend in diesem Monat."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:170
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Empfänger(in)"
|
||||
|
||||
@@ -157,6 +157,18 @@ msgstr "<0>\"{0}\"</0> steht nicht mehr zur Unterschrift zur Verfügung"
|
||||
msgid "<0>Sender:</0> All"
|
||||
msgstr "<0>Absender:</0> Alle"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:104
|
||||
msgid "<0>You are about to complete approving <1>\"{documentTitle}\"</1>.</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "<0>You are about to complete signing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:76
|
||||
msgid "<0>You are about to complete viewing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/token/contants.ts:5
|
||||
msgid "1 month"
|
||||
msgstr "1 Monat"
|
||||
@@ -665,7 +677,7 @@ msgstr "App-Version"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||
msgid "Approve"
|
||||
msgstr "Genehmigen"
|
||||
|
||||
@@ -835,7 +847,7 @@ msgstr "Durch die Verwendung der elektronischen Unterschriftsfunktion stimmen Si
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:328
|
||||
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:153
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:130
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:305
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:335
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -947,22 +959,22 @@ msgstr "Klicken Sie, um das Feld einzufügen"
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:446
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:325
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
msgid "Complete"
|
||||
msgstr "Vollständig"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
msgid "Complete Approval"
|
||||
msgstr "Genehmigung abschließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
msgid "Complete Signing"
|
||||
msgstr "Unterzeichnung abschließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Betrachten abschließen"
|
||||
|
||||
@@ -1048,23 +1060,23 @@ msgstr "Fortfahren"
|
||||
msgid "Continue to login"
|
||||
msgstr "Weiter zum Login"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:188
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:185
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
msgstr "Steuert die Standardsprache eines hochgeladenen Dokuments. Diese wird als Sprache in der E-Mail-Kommunikation mit den Empfängern verwendet."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:154
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:153
|
||||
msgid "Controls the default visibility of an uploaded document."
|
||||
msgstr "Steuert die Standard-sichtbarkeit eines hochgeladenen Dokuments."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:237
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:232
|
||||
msgid "Controls the formatting of the message that will be sent when inviting a recipient to sign a document. If a custom message has been provided while configuring the document, it will be used instead."
|
||||
msgstr "Steuert das Format der Nachricht, die gesendet wird, wenn ein Empfänger eingeladen wird, ein Dokument zu unterschreiben. Wenn eine benutzerdefinierte Nachricht beim Konfigurieren des Dokuments bereitgestellt wurde, wird diese stattdessen verwendet."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:270
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:263
|
||||
msgid "Controls whether the recipients can sign the documents using a typed signature. Enable or disable the typed signature globally."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:301
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:293
|
||||
msgid "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately."
|
||||
msgstr ""
|
||||
|
||||
@@ -1185,7 +1197,7 @@ msgstr "Webhook erstellen"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Webhook erstellen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:213
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit dem modernen Dokumentensignieren."
|
||||
|
||||
@@ -1258,11 +1270,11 @@ msgstr "Ablehnen"
|
||||
msgid "Declined team invitation"
|
||||
msgstr "Team-Einladung abgelehnt"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:168
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:165
|
||||
msgid "Default Document Language"
|
||||
msgstr "Standardsprache des Dokuments"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:130
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:129
|
||||
msgid "Default Document Visibility"
|
||||
msgstr "Standard Sichtbarkeit des Dokuments"
|
||||
|
||||
@@ -1461,7 +1473,7 @@ msgstr "Dokument"
|
||||
msgid "Document All"
|
||||
msgstr "Dokument Alle"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
msgid "Document Approved"
|
||||
msgstr "Dokument genehmigt"
|
||||
|
||||
@@ -1490,7 +1502,7 @@ msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Dokument erstellt mit einem <0>direkten Link</0>"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:178
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:181
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:61
|
||||
msgid "Document deleted"
|
||||
msgstr "Dokument gelöscht"
|
||||
@@ -1503,7 +1515,7 @@ msgstr "Dokument-Entwurf"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Dokument dupliziert"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:189
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:192
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Dokumentverlauf"
|
||||
@@ -1529,7 +1541,7 @@ msgstr "Dokumentmetrik"
|
||||
msgid "Document moved"
|
||||
msgstr "Dokument verschoben"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:158
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:156
|
||||
msgid "Document no longer available to sign"
|
||||
msgstr "Dokument steht nicht mehr zur Unterschrift zur Verfügung"
|
||||
|
||||
@@ -1561,7 +1573,7 @@ msgstr "Dokument gesendet"
|
||||
#~ msgid "Document Settings"
|
||||
#~ msgstr "Document Settings"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:130
|
||||
msgid "Document Signed"
|
||||
msgstr "Dokument signiert"
|
||||
|
||||
@@ -1585,7 +1597,7 @@ msgstr "Dokumenten-Upload deaktiviert aufgrund unbezahlter Rechnungen"
|
||||
msgid "Document uploaded"
|
||||
msgstr "Dokument hochgeladen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:133
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:131
|
||||
msgid "Document Viewed"
|
||||
msgstr "Dokument angesehen"
|
||||
|
||||
@@ -1609,7 +1621,7 @@ msgstr "Dokument wird dauerhaft gelöscht"
|
||||
msgid "Documents"
|
||||
msgstr "Dokumente"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:194
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:197
|
||||
msgid "Documents created from template"
|
||||
msgstr "Dokumente erstellt aus Vorlage"
|
||||
|
||||
@@ -1690,7 +1702,7 @@ msgstr "Duplizieren"
|
||||
msgid "Edit"
|
||||
msgstr "Bearbeiten"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:114
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:117
|
||||
msgid "Edit Template"
|
||||
msgstr "Vorlage bearbeiten"
|
||||
|
||||
@@ -1778,7 +1790,7 @@ msgstr "Direktlinksignierung aktivieren"
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Direktlinksignierung aktivieren"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:255
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:248
|
||||
msgid "Enable Typed Signature"
|
||||
msgstr ""
|
||||
|
||||
@@ -1866,15 +1878,15 @@ msgstr "Fehler"
|
||||
#~ msgid "Error updating global team settings"
|
||||
#~ msgstr "Error updating global team settings"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:141
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:140
|
||||
msgid "Everyone can access and view the document"
|
||||
msgstr "Jeder kann auf das Dokument zugreifen und es anzeigen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:142
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:140
|
||||
msgid "Everyone has signed"
|
||||
msgstr "Alle haben unterschrieben"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:166
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:164
|
||||
msgid "Everyone has signed! You will receive an Email copy of the signed document."
|
||||
msgstr "Alle haben unterschrieben! Sie werden eine E-Mail-Kopie des unterzeichneten Dokuments erhalten."
|
||||
|
||||
@@ -1963,7 +1975,7 @@ msgstr "Zurück"
|
||||
msgid "Go back home"
|
||||
msgstr "Zurück nach Hause"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Zurück nach Hause"
|
||||
@@ -2047,7 +2059,7 @@ msgstr "Posteingang Dokumente"
|
||||
#~ msgid "Include Sender Details"
|
||||
#~ msgstr "Include Sender Details"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:286
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:278
|
||||
msgid "Include the Signing Certificate in the Document"
|
||||
msgstr ""
|
||||
|
||||
@@ -2267,7 +2279,7 @@ msgstr "Verwalten Sie das Profil von {0}"
|
||||
msgid "Manage all teams you are currently associated with."
|
||||
msgstr "Verwalten Sie alle Teams, mit denen Sie derzeit verbunden sind."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:158
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:161
|
||||
msgid "Manage and view template"
|
||||
msgstr "Vorlage verwalten und anzeigen"
|
||||
|
||||
@@ -2331,7 +2343,7 @@ msgstr "Verwalten Sie Ihre Passkeys."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Verwalten Sie hier Ihre Seiteneinstellungen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:140
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Als angesehen markieren"
|
||||
|
||||
@@ -2413,7 +2425,7 @@ msgstr "Meine Vorlagen"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:209
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "Müssen Dokumente signieren?"
|
||||
|
||||
@@ -2440,7 +2452,7 @@ msgstr "Neue Vorlage"
|
||||
msgid "Next"
|
||||
msgstr "Nächster"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
msgid "Next field"
|
||||
msgstr "Nächstes Feld"
|
||||
|
||||
@@ -2542,11 +2554,11 @@ msgstr "Sobald dies bestätigt ist, wird Folgendes geschehen:"
|
||||
msgid "Once you have scanned the QR code or entered the code manually, enter the code provided by your authenticator app below."
|
||||
msgstr "Sobald Sie den QR-Code gescannt oder den Code manuell eingegeben haben, geben Sie den von Ihrer Authentifizierungs-App bereitgestellten Code unten ein."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:147
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:146
|
||||
msgid "Only admins can access and view the document"
|
||||
msgstr "Nur Administratoren können auf das Dokument zugreifen und es anzeigen"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:144
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:143
|
||||
msgid "Only managers and above can access and view the document"
|
||||
msgstr "Nur Manager und darüber können auf das Dokument zugreifen und es anzeigen"
|
||||
|
||||
@@ -2792,7 +2804,7 @@ msgstr "Bitte geben Sie <0>{0}</0> ein, um zu bestätigen."
|
||||
msgid "Preferences"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:216
|
||||
msgid "Preview"
|
||||
msgstr "Vorschau"
|
||||
|
||||
@@ -3078,7 +3090,7 @@ msgstr "Rollen"
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:337
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:344
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/branding-preferences.tsx:312
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:313
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:305
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
@@ -3153,7 +3165,7 @@ msgstr "Bestätigungs-E-Mail senden"
|
||||
msgid "Send document"
|
||||
msgstr "Dokument senden"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:205
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:200
|
||||
msgid "Send on Behalf of Team"
|
||||
msgstr "Im Namen des Teams senden"
|
||||
|
||||
@@ -3226,7 +3238,7 @@ msgstr "Vorlagen in Ihrem Team-Öffentliches Profil anzeigen, damit Ihre Zielgru
|
||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:141
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:313
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -3317,7 +3329,7 @@ msgstr "Signatur-ID"
|
||||
msgid "Signatures Collected"
|
||||
msgstr "Gesammelte Unterschriften"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:200
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:198
|
||||
msgid "Signatures will appear once the document has been completed"
|
||||
msgstr "Unterschriften erscheinen, sobald das Dokument abgeschlossen ist"
|
||||
|
||||
@@ -3649,7 +3661,7 @@ msgstr "Teams beschränkt"
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:145
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
|
||||
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
|
||||
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
|
||||
msgid "Template"
|
||||
@@ -3883,7 +3895,7 @@ msgstr "Dieses Dokument konnte derzeit nicht dupliziert werden. Bitte versuche e
|
||||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Dieses Dokument konnte zu diesem Zeitpunkt nicht erneut gesendet werden. Bitte versuchen Sie es erneut."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:180
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:178
|
||||
msgid "This document has been cancelled by the owner and is no longer available for others to sign."
|
||||
msgstr "Dieses Dokument wurde vom Eigentümer storniert und steht anderen nicht mehr zur Unterzeichnung zur Verfügung."
|
||||
|
||||
@@ -3891,11 +3903,11 @@ msgstr "Dieses Dokument wurde vom Eigentümer storniert und steht anderen nicht
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "Dieses Dokument wurde vom Eigentümer storniert."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:224
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "Dieses Dokument wurde von allen Empfängern unterschrieben"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "Dieses Dokument ist momentan ein Entwurf und wurde nicht gesendet"
|
||||
|
||||
@@ -4346,7 +4358,7 @@ msgstr "Die hochgeladene Datei ist zu klein"
|
||||
msgid "Uploaded file not an allowed file type"
|
||||
msgstr "Die hochgeladene Datei ist kein zulässiger Dateityp"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:169
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:172
|
||||
msgid "Use"
|
||||
msgstr "Verwenden"
|
||||
|
||||
@@ -4488,7 +4500,7 @@ msgstr "Angesehen"
|
||||
msgid "Waiting"
|
||||
msgstr "Warten"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:148
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "Warten auf andere, um zu unterschreiben"
|
||||
|
||||
@@ -4806,16 +4818,16 @@ msgid "You"
|
||||
msgstr "Sie"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, die Genehmigung für \"{truncatedTitle}\" abzuschließen.<0/> Sind Sie sicher?"
|
||||
#~ msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Sie stehen kurz davor, die Genehmigung für \"{truncatedTitle}\" abzuschließen.<0/> Sind Sie sicher?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" zu unterzeichnen.<0/> Sind Sie sicher?"
|
||||
#~ msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" zu unterzeichnen.<0/> Sind Sie sicher?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" anzusehen.<0/> Sind Sie sicher?"
|
||||
#~ msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" anzusehen.<0/> Sind Sie sicher?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:105
|
||||
msgid "You are about to delete <0>\"{documentTitle}\"</0>"
|
||||
@@ -5015,7 +5027,7 @@ msgstr "Sie werden benachrichtigt und können Ihr Documenso öffentliches Profil
|
||||
msgid "You will now be required to enter a code from your authenticator app when signing in."
|
||||
msgstr "Sie müssen bei der Anmeldung jetzt einen Code von Ihrer Authenticator-App eingeben."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:173
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:171
|
||||
msgid "You will receive an Email copy of the signed document once everyone has signed."
|
||||
msgstr "Sie erhalten eine E-Mail-Kopie des unterzeichneten Dokuments, sobald alle unterschrieben haben."
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ msgstr "A recipient was removed"
|
||||
msgid "A recipient was updated"
|
||||
msgstr "A recipient was updated"
|
||||
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||
msgstr "A request to use your email has been initiated by {0} on Documenso"
|
||||
|
||||
@@ -706,7 +706,7 @@ msgid "Document created"
|
||||
msgstr "Document created"
|
||||
|
||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
||||
msgid "Document created from direct template"
|
||||
msgstr "Document created from direct template"
|
||||
|
||||
@@ -1769,7 +1769,7 @@ msgstr "You have been invited to join {0} on Documenso"
|
||||
msgid "You have been invited to join the following team"
|
||||
msgstr "You have been invited to join the following team"
|
||||
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
||||
msgid "You have been removed from a document"
|
||||
msgstr "You have been removed from a document"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:231
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
msgid "\"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{0}\" has invited you to sign \"example document\"."
|
||||
|
||||
@@ -37,7 +37,7 @@ msgstr "\"{documentTitle}\" has been successfully deleted"
|
||||
#~ "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example\n"
|
||||
#~ "document\"."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
msgid "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example document\"."
|
||||
|
||||
@@ -45,15 +45,15 @@ msgstr "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"ex
|
||||
#~ msgid "\"{teamUrl}\" has invited you to sign \"example document\"."
|
||||
#~ msgstr "\"{teamUrl}\" has invited you to sign \"example document\"."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:83
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) has invited you to approve this document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) has invited you to sign this document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) has invited you to view this document"
|
||||
|
||||
@@ -66,7 +66,7 @@ msgstr "{0, plural, one {(1 character over)} other {(# characters over)}}"
|
||||
msgid "{0, plural, one {# character over the limit} other {# characters over the limit}}"
|
||||
msgstr "{0, plural, one {# character over the limit} other {# characters over the limit}}"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:82
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:84
|
||||
msgid "{0, plural, one {# recipient} other {# recipients}}"
|
||||
msgstr "{0, plural, one {# recipient} other {# recipients}}"
|
||||
|
||||
@@ -83,11 +83,11 @@ msgstr "{0, plural, one {<0>You have <1>1</1> pending team invitation</0>} other
|
||||
msgid "{0, plural, one {1 matching field} other {# matching fields}}"
|
||||
msgstr "{0, plural, one {1 matching field} other {# matching fields}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:132
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:235
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:238
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
|
||||
@@ -111,7 +111,7 @@ msgstr "{0} direct signing templates"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} of {1} documents remaining this month."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:170
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Recipient(s)"
|
||||
|
||||
@@ -152,6 +152,18 @@ msgstr "<0>\"{0}\"</0>is no longer available to sign"
|
||||
msgid "<0>Sender:</0> All"
|
||||
msgstr "<0>Sender:</0> All"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:104
|
||||
msgid "<0>You are about to complete approving <1>\"{documentTitle}\"</1>.</0><2/> Are you sure?"
|
||||
msgstr "<0>You are about to complete approving <1>\"{documentTitle}\"</1>.</0><2/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "<0>You are about to complete signing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr "<0>You are about to complete signing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:76
|
||||
msgid "<0>You are about to complete viewing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr "<0>You are about to complete viewing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/token/contants.ts:5
|
||||
msgid "1 month"
|
||||
msgstr "1 month"
|
||||
@@ -660,7 +672,7 @@ msgstr "App Version"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||
msgid "Approve"
|
||||
msgstr "Approve"
|
||||
|
||||
@@ -830,7 +842,7 @@ msgstr "By using the electronic signature feature, you are consenting to conduct
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:328
|
||||
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:153
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:130
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:305
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:335
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -942,22 +954,22 @@ msgstr "Click to insert field"
|
||||
msgid "Close"
|
||||
msgstr "Close"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:446
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:325
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
msgid "Complete"
|
||||
msgstr "Complete"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
msgid "Complete Approval"
|
||||
msgstr "Complete Approval"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
msgid "Complete Signing"
|
||||
msgstr "Complete Signing"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Complete Viewing"
|
||||
|
||||
@@ -1043,23 +1055,23 @@ msgstr "Continue"
|
||||
msgid "Continue to login"
|
||||
msgstr "Continue to login"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:188
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:185
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
msgstr "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:154
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:153
|
||||
msgid "Controls the default visibility of an uploaded document."
|
||||
msgstr "Controls the default visibility of an uploaded document."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:237
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:232
|
||||
msgid "Controls the formatting of the message that will be sent when inviting a recipient to sign a document. If a custom message has been provided while configuring the document, it will be used instead."
|
||||
msgstr "Controls the formatting of the message that will be sent when inviting a recipient to sign a document. If a custom message has been provided while configuring the document, it will be used instead."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:270
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:263
|
||||
msgid "Controls whether the recipients can sign the documents using a typed signature. Enable or disable the typed signature globally."
|
||||
msgstr "Controls whether the recipients can sign the documents using a typed signature. Enable or disable the typed signature globally."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:301
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:293
|
||||
msgid "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately."
|
||||
msgstr "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately."
|
||||
|
||||
@@ -1180,7 +1192,7 @@ msgstr "Create webhook"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Create Webhook"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:213
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Create your account and start using state-of-the-art document signing."
|
||||
|
||||
@@ -1253,11 +1265,11 @@ msgstr "Decline"
|
||||
msgid "Declined team invitation"
|
||||
msgstr "Declined team invitation"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:168
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:165
|
||||
msgid "Default Document Language"
|
||||
msgstr "Default Document Language"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:130
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:129
|
||||
msgid "Default Document Visibility"
|
||||
msgstr "Default Document Visibility"
|
||||
|
||||
@@ -1456,7 +1468,7 @@ msgstr "Document"
|
||||
msgid "Document All"
|
||||
msgstr "Document All"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
msgid "Document Approved"
|
||||
msgstr "Document Approved"
|
||||
|
||||
@@ -1485,7 +1497,7 @@ msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Document created using a <0>direct link</0>"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:178
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:181
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:61
|
||||
msgid "Document deleted"
|
||||
msgstr "Document deleted"
|
||||
@@ -1498,7 +1510,7 @@ msgstr "Document draft"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Document Duplicated"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:189
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:192
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Document history"
|
||||
@@ -1524,7 +1536,7 @@ msgstr "Document metrics"
|
||||
msgid "Document moved"
|
||||
msgstr "Document moved"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:158
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:156
|
||||
msgid "Document no longer available to sign"
|
||||
msgstr "Document no longer available to sign"
|
||||
|
||||
@@ -1556,7 +1568,7 @@ msgstr "Document sent"
|
||||
#~ msgid "Document Settings"
|
||||
#~ msgstr "Document Settings"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:130
|
||||
msgid "Document Signed"
|
||||
msgstr "Document Signed"
|
||||
|
||||
@@ -1580,7 +1592,7 @@ msgstr "Document upload disabled due to unpaid invoices"
|
||||
msgid "Document uploaded"
|
||||
msgstr "Document uploaded"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:133
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:131
|
||||
msgid "Document Viewed"
|
||||
msgstr "Document Viewed"
|
||||
|
||||
@@ -1604,7 +1616,7 @@ msgstr "Document will be permanently deleted"
|
||||
msgid "Documents"
|
||||
msgstr "Documents"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:194
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:197
|
||||
msgid "Documents created from template"
|
||||
msgstr "Documents created from template"
|
||||
|
||||
@@ -1685,7 +1697,7 @@ msgstr "Duplicate"
|
||||
msgid "Edit"
|
||||
msgstr "Edit"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:114
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:117
|
||||
msgid "Edit Template"
|
||||
msgstr "Edit Template"
|
||||
|
||||
@@ -1773,7 +1785,7 @@ msgstr "Enable direct link signing"
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Enable Direct Link Signing"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:255
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:248
|
||||
msgid "Enable Typed Signature"
|
||||
msgstr "Enable Typed Signature"
|
||||
|
||||
@@ -1861,15 +1873,15 @@ msgstr "Error"
|
||||
#~ msgid "Error updating global team settings"
|
||||
#~ msgstr "Error updating global team settings"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:141
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:140
|
||||
msgid "Everyone can access and view the document"
|
||||
msgstr "Everyone can access and view the document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:142
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:140
|
||||
msgid "Everyone has signed"
|
||||
msgstr "Everyone has signed"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:166
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:164
|
||||
msgid "Everyone has signed! You will receive an Email copy of the signed document."
|
||||
msgstr "Everyone has signed! You will receive an Email copy of the signed document."
|
||||
|
||||
@@ -1958,7 +1970,7 @@ msgstr "Go Back"
|
||||
msgid "Go back home"
|
||||
msgstr "Go back home"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Go Back Home"
|
||||
@@ -2042,7 +2054,7 @@ msgstr "Inbox documents"
|
||||
#~ msgid "Include Sender Details"
|
||||
#~ msgstr "Include Sender Details"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:286
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:278
|
||||
msgid "Include the Signing Certificate in the Document"
|
||||
msgstr "Include the Signing Certificate in the Document"
|
||||
|
||||
@@ -2262,7 +2274,7 @@ msgstr "Manage {0}'s profile"
|
||||
msgid "Manage all teams you are currently associated with."
|
||||
msgstr "Manage all teams you are currently associated with."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:158
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:161
|
||||
msgid "Manage and view template"
|
||||
msgstr "Manage and view template"
|
||||
|
||||
@@ -2326,7 +2338,7 @@ msgstr "Manage your passkeys."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Manage your site settings here"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:140
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Mark as Viewed"
|
||||
|
||||
@@ -2408,7 +2420,7 @@ msgstr "My templates"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:209
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "Need to sign documents?"
|
||||
|
||||
@@ -2435,7 +2447,7 @@ msgstr "New Template"
|
||||
msgid "Next"
|
||||
msgstr "Next"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
msgid "Next field"
|
||||
msgstr "Next field"
|
||||
|
||||
@@ -2537,11 +2549,11 @@ msgstr "Once confirmed, the following will occur:"
|
||||
msgid "Once you have scanned the QR code or entered the code manually, enter the code provided by your authenticator app below."
|
||||
msgstr "Once you have scanned the QR code or entered the code manually, enter the code provided by your authenticator app below."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:147
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:146
|
||||
msgid "Only admins can access and view the document"
|
||||
msgstr "Only admins can access and view the document"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:144
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:143
|
||||
msgid "Only managers and above can access and view the document"
|
||||
msgstr "Only managers and above can access and view the document"
|
||||
|
||||
@@ -2787,7 +2799,7 @@ msgstr "Please type <0>{0}</0> to confirm."
|
||||
msgid "Preferences"
|
||||
msgstr "Preferences"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:216
|
||||
msgid "Preview"
|
||||
msgstr "Preview"
|
||||
|
||||
@@ -3073,7 +3085,7 @@ msgstr "Roles"
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:337
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:344
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/branding-preferences.tsx:312
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:313
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:305
|
||||
msgid "Save"
|
||||
msgstr "Save"
|
||||
|
||||
@@ -3148,7 +3160,7 @@ msgstr "Send confirmation email"
|
||||
msgid "Send document"
|
||||
msgstr "Send document"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:205
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:200
|
||||
msgid "Send on Behalf of Team"
|
||||
msgstr "Send on Behalf of Team"
|
||||
|
||||
@@ -3221,7 +3233,7 @@ msgstr "Show templates in your team public profile for your audience to sign and
|
||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:141
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:313
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -3312,7 +3324,7 @@ msgstr "Signature ID"
|
||||
msgid "Signatures Collected"
|
||||
msgstr "Signatures Collected"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:200
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:198
|
||||
msgid "Signatures will appear once the document has been completed"
|
||||
msgstr "Signatures will appear once the document has been completed"
|
||||
|
||||
@@ -3644,7 +3656,7 @@ msgstr "Teams restricted"
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:145
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
|
||||
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
|
||||
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
|
||||
msgid "Template"
|
||||
@@ -3878,7 +3890,7 @@ msgstr "This document could not be duplicated at this time. Please try again."
|
||||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "This document could not be re-sent at this time. Please try again."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:180
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:178
|
||||
msgid "This document has been cancelled by the owner and is no longer available for others to sign."
|
||||
msgstr "This document has been cancelled by the owner and is no longer available for others to sign."
|
||||
|
||||
@@ -3886,11 +3898,11 @@ msgstr "This document has been cancelled by the owner and is no longer available
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "This document has been cancelled by the owner."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:224
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "This document has been signed by all recipients"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "This document is currently a draft and has not been sent"
|
||||
|
||||
@@ -4341,7 +4353,7 @@ msgstr "Uploaded file is too small"
|
||||
msgid "Uploaded file not an allowed file type"
|
||||
msgstr "Uploaded file not an allowed file type"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:169
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:172
|
||||
msgid "Use"
|
||||
msgstr "Use"
|
||||
|
||||
@@ -4483,7 +4495,7 @@ msgstr "Viewed"
|
||||
msgid "Waiting"
|
||||
msgstr "Waiting"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:148
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "Waiting for others to sign"
|
||||
|
||||
@@ -4801,16 +4813,16 @@ msgid "You"
|
||||
msgstr "You"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:105
|
||||
msgid "You are about to delete <0>\"{documentTitle}\"</0>"
|
||||
@@ -5010,7 +5022,7 @@ msgstr "You will get notified & be able to set up your documenso public profile
|
||||
msgid "You will now be required to enter a code from your authenticator app when signing in."
|
||||
msgstr "You will now be required to enter a code from your authenticator app when signing in."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:173
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:171
|
||||
msgid "You will receive an Email copy of the signed document once everyone has signed."
|
||||
msgstr "You will receive an Email copy of the signed document once everyone has signed."
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ msgstr "Se eliminó un destinatario"
|
||||
msgid "A recipient was updated"
|
||||
msgstr "Se actualizó un destinatario"
|
||||
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||
msgstr "Se ha iniciado una solicitud para usar tu correo electrónico por {0} en Documenso"
|
||||
|
||||
@@ -711,7 +711,7 @@ msgid "Document created"
|
||||
msgstr "Documento creado"
|
||||
|
||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
||||
msgid "Document created from direct template"
|
||||
msgstr "Documento creado a partir de plantilla directa"
|
||||
|
||||
@@ -1774,7 +1774,7 @@ msgstr "Te han invitado a unirte a {0} en Documenso"
|
||||
msgid "You have been invited to join the following team"
|
||||
msgstr "Te han invitado a unirte al siguiente equipo"
|
||||
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
||||
msgid "You have been removed from a document"
|
||||
msgstr "Te han eliminado de un documento"
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ msgstr ""
|
||||
"X-Crowdin-File: web.po\n"
|
||||
"X-Crowdin-File-ID: 8\n"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:231
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
msgid "\"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{0}\" te ha invitado a firmar \"ejemplo de documento\"."
|
||||
|
||||
@@ -42,7 +42,7 @@ msgstr "\"{documentTitle}\" ha sido eliminado con éxito"
|
||||
#~ "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example\n"
|
||||
#~ "document\"."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
msgid "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{placeholderEmail}\" en nombre de \"{0}\" te ha invitado a firmar \"documento de ejemplo\"."
|
||||
|
||||
@@ -50,15 +50,15 @@ msgstr "\"{placeholderEmail}\" en nombre de \"{0}\" te ha invitado a firmar \"do
|
||||
#~ msgid "\"{teamUrl}\" has invited you to sign \"example document\"."
|
||||
#~ msgstr "\"{teamUrl}\" te ha invitado a firmar \"ejemplo de documento\"."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:83
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) te ha invitado a aprobar este documento"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) te ha invitado a firmar este documento"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) te ha invitado a ver este documento"
|
||||
|
||||
@@ -71,7 +71,7 @@ msgstr "{0, plural, one {(1 carácter excedido)} other {(# caracteres excedidos)
|
||||
msgid "{0, plural, one {# character over the limit} other {# characters over the limit}}"
|
||||
msgstr "{0, plural, one {# carácter sobre el límite} other {# caracteres sobre el límite}}"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:82
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:84
|
||||
msgid "{0, plural, one {# recipient} other {# recipients}}"
|
||||
msgstr "{0, plural, one {# destinatario} other {# destinatarios}}"
|
||||
|
||||
@@ -88,11 +88,11 @@ msgstr "{0, plural, one {<0>Tienes <1>1</1> invitación de equipo pendiente</0>}
|
||||
msgid "{0, plural, one {1 matching field} other {# matching fields}}"
|
||||
msgstr "{0, plural, one {1 campo que coincide} other {# campos que coinciden}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:132
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Destinatario} other {# Destinatarios}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:235
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:238
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {Esperando 1 destinatario} other {Esperando # destinatarios}}"
|
||||
|
||||
@@ -116,7 +116,7 @@ msgstr "{0} plantillas de firma directa"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} de {1} documentos restantes este mes."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:170
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Destinatario(s)"
|
||||
|
||||
@@ -157,6 +157,18 @@ msgstr "<0>\"{0}\"</0> ya no está disponible para firmar"
|
||||
msgid "<0>Sender:</0> All"
|
||||
msgstr "<0>Remitente:</0> Todos"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:104
|
||||
msgid "<0>You are about to complete approving <1>\"{documentTitle}\"</1>.</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "<0>You are about to complete signing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:76
|
||||
msgid "<0>You are about to complete viewing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/token/contants.ts:5
|
||||
msgid "1 month"
|
||||
msgstr "1 mes"
|
||||
@@ -665,7 +677,7 @@ msgstr "Versión de la Aplicación"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||
msgid "Approve"
|
||||
msgstr "Aprobar"
|
||||
|
||||
@@ -835,7 +847,7 @@ msgstr "Al utilizar la función de firma electrónica, usted está consintiendo
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:328
|
||||
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:153
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:130
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:305
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:335
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -947,22 +959,22 @@ msgstr "Haga clic para insertar campo"
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:446
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:325
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
msgid "Complete"
|
||||
msgstr "Completo"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
msgid "Complete Approval"
|
||||
msgstr "Completar Aprobación"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
msgid "Complete Signing"
|
||||
msgstr "Completar Firmado"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Completar Visualización"
|
||||
|
||||
@@ -1048,23 +1060,23 @@ msgstr "Continuar"
|
||||
msgid "Continue to login"
|
||||
msgstr "Continuar con el inicio de sesión"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:188
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:185
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
msgstr "Controla el idioma predeterminado de un documento cargado. Este se utilizará como el idioma en las comunicaciones por correo electrónico con los destinatarios."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:154
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:153
|
||||
msgid "Controls the default visibility of an uploaded document."
|
||||
msgstr "Controla la visibilidad predeterminada de un documento cargado."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:237
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:232
|
||||
msgid "Controls the formatting of the message that will be sent when inviting a recipient to sign a document. If a custom message has been provided while configuring the document, it will be used instead."
|
||||
msgstr "Controla el formato del mensaje que se enviará al invitar a un destinatario a firmar un documento. Si se ha proporcionado un mensaje personalizado al configurar el documento, se usará en su lugar."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:270
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:263
|
||||
msgid "Controls whether the recipients can sign the documents using a typed signature. Enable or disable the typed signature globally."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:301
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:293
|
||||
msgid "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately."
|
||||
msgstr ""
|
||||
|
||||
@@ -1185,7 +1197,7 @@ msgstr "Crear webhook"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Crear Webhook"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:213
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Crea tu cuenta y comienza a utilizar la firma de documentos de última generación."
|
||||
|
||||
@@ -1258,11 +1270,11 @@ msgstr "Rechazar"
|
||||
msgid "Declined team invitation"
|
||||
msgstr "Invitación de equipo rechazada"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:168
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:165
|
||||
msgid "Default Document Language"
|
||||
msgstr "Idioma predeterminado del documento"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:130
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:129
|
||||
msgid "Default Document Visibility"
|
||||
msgstr "Visibilidad predeterminada del documento"
|
||||
|
||||
@@ -1461,7 +1473,7 @@ msgstr "Documento"
|
||||
msgid "Document All"
|
||||
msgstr "Documentar Todo"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
msgid "Document Approved"
|
||||
msgstr "Documento Aprobado"
|
||||
|
||||
@@ -1490,7 +1502,7 @@ msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Documento creado usando un <0>enlace directo</0>"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:178
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:181
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:61
|
||||
msgid "Document deleted"
|
||||
msgstr "Documento eliminado"
|
||||
@@ -1503,7 +1515,7 @@ msgstr "Borrador de documento"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Documento duplicado"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:189
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:192
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Historial de documentos"
|
||||
@@ -1529,7 +1541,7 @@ msgstr "Métricas de documento"
|
||||
msgid "Document moved"
|
||||
msgstr "Documento movido"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:158
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:156
|
||||
msgid "Document no longer available to sign"
|
||||
msgstr "El documento ya no está disponible para firmar"
|
||||
|
||||
@@ -1561,7 +1573,7 @@ msgstr "Documento enviado"
|
||||
#~ msgid "Document Settings"
|
||||
#~ msgstr "Document Settings"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:130
|
||||
msgid "Document Signed"
|
||||
msgstr "Documento firmado"
|
||||
|
||||
@@ -1585,7 +1597,7 @@ msgstr "La carga de documentos está deshabilitada debido a facturas impagadas"
|
||||
msgid "Document uploaded"
|
||||
msgstr "Documento subido"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:133
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:131
|
||||
msgid "Document Viewed"
|
||||
msgstr "Documento visto"
|
||||
|
||||
@@ -1609,7 +1621,7 @@ msgstr "El documento será eliminado permanentemente"
|
||||
msgid "Documents"
|
||||
msgstr "Documentos"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:194
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:197
|
||||
msgid "Documents created from template"
|
||||
msgstr "Documentos creados a partir de la plantilla"
|
||||
|
||||
@@ -1690,7 +1702,7 @@ msgstr "Duplicar"
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:114
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:117
|
||||
msgid "Edit Template"
|
||||
msgstr "Editar plantilla"
|
||||
|
||||
@@ -1778,7 +1790,7 @@ msgstr "Habilitar firma de enlace directo"
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Habilitar firma de enlace directo"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:255
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:248
|
||||
msgid "Enable Typed Signature"
|
||||
msgstr ""
|
||||
|
||||
@@ -1866,15 +1878,15 @@ msgstr "Error"
|
||||
#~ msgid "Error updating global team settings"
|
||||
#~ msgstr "Error updating global team settings"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:141
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:140
|
||||
msgid "Everyone can access and view the document"
|
||||
msgstr "Todos pueden acceder y ver el documento"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:142
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:140
|
||||
msgid "Everyone has signed"
|
||||
msgstr "Todos han firmado"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:166
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:164
|
||||
msgid "Everyone has signed! You will receive an Email copy of the signed document."
|
||||
msgstr "¡Todos han firmado! Recibirás una copia por correo electrónico del documento firmado."
|
||||
|
||||
@@ -1963,7 +1975,7 @@ msgstr "Regresar"
|
||||
msgid "Go back home"
|
||||
msgstr "Regresar a casa"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Regresar a casa"
|
||||
@@ -2047,7 +2059,7 @@ msgstr "Documentos en bandeja de entrada"
|
||||
#~ msgid "Include Sender Details"
|
||||
#~ msgstr "Include Sender Details"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:286
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:278
|
||||
msgid "Include the Signing Certificate in the Document"
|
||||
msgstr ""
|
||||
|
||||
@@ -2267,7 +2279,7 @@ msgstr "Gestionar el perfil de {0}"
|
||||
msgid "Manage all teams you are currently associated with."
|
||||
msgstr "Gestionar todos los equipos con los que estás asociado actualmente."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:158
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:161
|
||||
msgid "Manage and view template"
|
||||
msgstr "Gestionar y ver plantilla"
|
||||
|
||||
@@ -2331,7 +2343,7 @@ msgstr "Gestionar tus claves de acceso."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Gestionar la configuración de tu sitio aquí"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:140
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Marcar como visto"
|
||||
|
||||
@@ -2413,7 +2425,7 @@ msgstr "Mis plantillas"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:209
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "¿Necesitas firmar documentos?"
|
||||
|
||||
@@ -2440,7 +2452,7 @@ msgstr "Nueva plantilla"
|
||||
msgid "Next"
|
||||
msgstr "Siguiente"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
msgid "Next field"
|
||||
msgstr "Siguiente campo"
|
||||
|
||||
@@ -2542,11 +2554,11 @@ msgstr "Una vez confirmado, ocurrirá lo siguiente:"
|
||||
msgid "Once you have scanned the QR code or entered the code manually, enter the code provided by your authenticator app below."
|
||||
msgstr "Una vez que hayas escaneado el código QR o ingresado el código manualmente, ingresa el código proporcionado por tu aplicación de autenticación a continuación."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:147
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:146
|
||||
msgid "Only admins can access and view the document"
|
||||
msgstr "Solo los administradores pueden acceder y ver el documento"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:144
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:143
|
||||
msgid "Only managers and above can access and view the document"
|
||||
msgstr "Solo los gerentes y superiores pueden acceder y ver el documento"
|
||||
|
||||
@@ -2792,7 +2804,7 @@ msgstr "Por favor, escribe <0>{0}</0> para confirmar."
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:216
|
||||
msgid "Preview"
|
||||
msgstr "Vista previa"
|
||||
|
||||
@@ -3078,7 +3090,7 @@ msgstr "Roles"
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:337
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:344
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/branding-preferences.tsx:312
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:313
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:305
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
@@ -3153,7 +3165,7 @@ msgstr "Enviar correo de confirmación"
|
||||
msgid "Send document"
|
||||
msgstr "Enviar documento"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:205
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:200
|
||||
msgid "Send on Behalf of Team"
|
||||
msgstr "Enviar en nombre del equipo"
|
||||
|
||||
@@ -3226,7 +3238,7 @@ msgstr "Mostrar plantillas en el perfil público de tu equipo para que tu audien
|
||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:141
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:313
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -3317,7 +3329,7 @@ msgstr "ID de Firma"
|
||||
msgid "Signatures Collected"
|
||||
msgstr "Firmas recolectadas"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:200
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:198
|
||||
msgid "Signatures will appear once the document has been completed"
|
||||
msgstr "Las firmas aparecerán una vez que el documento se haya completado"
|
||||
|
||||
@@ -3649,7 +3661,7 @@ msgstr "Equipos restringidos"
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:145
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
|
||||
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
|
||||
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
|
||||
msgid "Template"
|
||||
@@ -3883,7 +3895,7 @@ msgstr "Este documento no se pudo duplicar en este momento. Por favor, inténtal
|
||||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Este documento no se pudo reenviar en este momento. Por favor, inténtalo de nuevo."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:180
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:178
|
||||
msgid "This document has been cancelled by the owner and is no longer available for others to sign."
|
||||
msgstr "Este documento ha sido cancelado por el propietario y ya no está disponible para que otros lo firmen."
|
||||
|
||||
@@ -3891,11 +3903,11 @@ msgstr "Este documento ha sido cancelado por el propietario y ya no está dispon
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "Este documento ha sido cancelado por el propietario."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:224
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "Este documento ha sido firmado por todos los destinatarios"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "Este documento es actualmente un borrador y no ha sido enviado"
|
||||
|
||||
@@ -4346,7 +4358,7 @@ msgstr "El archivo subido es demasiado pequeño"
|
||||
msgid "Uploaded file not an allowed file type"
|
||||
msgstr "El archivo subido no es un tipo de archivo permitido"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:169
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:172
|
||||
msgid "Use"
|
||||
msgstr "Usar"
|
||||
|
||||
@@ -4488,7 +4500,7 @@ msgstr "Visto"
|
||||
msgid "Waiting"
|
||||
msgstr "Esperando"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:148
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "Esperando a que otros firmen"
|
||||
|
||||
@@ -4806,16 +4818,16 @@ msgid "You"
|
||||
msgstr "Tú"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Estás a punto de completar la aprobación de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
#~ msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Estás a punto de completar la aprobación de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Estás a punto de completar la firma de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
#~ msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Estás a punto de completar la firma de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Estás a punto de completar la visualización de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
#~ msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Estás a punto de completar la visualización de \"{truncatedTitle}\".<0/> ¿Estás seguro?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:105
|
||||
msgid "You are about to delete <0>\"{documentTitle}\"</0>"
|
||||
@@ -5015,7 +5027,7 @@ msgstr "Recibirás una notificación y podrás configurar tu perfil público de
|
||||
msgid "You will now be required to enter a code from your authenticator app when signing in."
|
||||
msgstr "Ahora se te pedirá que ingreses un código de tu aplicación de autenticador al iniciar sesión."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:173
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:171
|
||||
msgid "You will receive an Email copy of the signed document once everyone has signed."
|
||||
msgstr "Recibirás una copia por correo electrónico del documento firmado una vez que todos hayan firmado."
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ msgstr "Un destinataire a été supprimé"
|
||||
msgid "A recipient was updated"
|
||||
msgstr "Un destinataire a été mis à jour"
|
||||
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||
msgstr "Une demande d'utilisation de votre e-mail a été initiée par {0} sur Documenso"
|
||||
|
||||
@@ -711,7 +711,7 @@ msgid "Document created"
|
||||
msgstr "Document créé"
|
||||
|
||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
||||
msgid "Document created from direct template"
|
||||
msgstr "Document créé à partir d'un modèle direct"
|
||||
|
||||
@@ -1774,7 +1774,7 @@ msgstr "Vous avez été invité à rejoindre {0} sur Documenso"
|
||||
msgid "You have been invited to join the following team"
|
||||
msgstr "Vous avez été invité à rejoindre l'équipe suivante"
|
||||
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
||||
msgid "You have been removed from a document"
|
||||
msgstr "Vous avez été supprimé d'un document"
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ msgstr ""
|
||||
"X-Crowdin-File: web.po\n"
|
||||
"X-Crowdin-File-ID: 8\n"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:231
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
msgid "\"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{0}\" vous a invité à signer \"example document\"."
|
||||
|
||||
@@ -42,7 +42,7 @@ msgstr "\"{documentTitle}\" a été supprimé avec succès"
|
||||
#~ "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example\n"
|
||||
#~ "document\"."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:226
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
msgid "\"{placeholderEmail}\" on behalf of \"{0}\" has invited you to sign \"example document\"."
|
||||
msgstr "\"{placeholderEmail}\" au nom de \"{0}\" vous a invité à signer \"exemple de document\"."
|
||||
|
||||
@@ -50,15 +50,15 @@ msgstr "\"{placeholderEmail}\" au nom de \"{0}\" vous a invité à signer \"exem
|
||||
#~ msgid "\"{teamUrl}\" has invited you to sign \"example document\"."
|
||||
#~ msgstr "\"{teamUrl}\" vous a invité à signer \"example document\"."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:83
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) vous a invité à approuver ce document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) vous a invité à signer ce document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) vous a invité à consulter ce document"
|
||||
|
||||
@@ -71,7 +71,7 @@ msgstr "{0, plural, one {(1 caractère de trop)} other {(# caractères de trop)}
|
||||
msgid "{0, plural, one {# character over the limit} other {# characters over the limit}}"
|
||||
msgstr "{0, plural, one {# caractère au-dessus de la limite} other {# caractères au-dessus de la limite}}"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:82
|
||||
#: apps/web/src/app/(recipient)/d/[token]/page.tsx:84
|
||||
msgid "{0, plural, one {# recipient} other {# recipients}}"
|
||||
msgstr "{0, plural, one {# destinataire} other {# destinataires}}"
|
||||
|
||||
@@ -88,11 +88,11 @@ msgstr "{0, plural, one {<0>Vous avez <1>1</1> invitation d'équipe en attente</
|
||||
msgid "{0, plural, one {1 matching field} other {# matching fields}}"
|
||||
msgstr "{0, plural, one {1 champ correspondant} other {# champs correspondants}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:132
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Destinataire} other {# Destinataires}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:235
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:238
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {En attente d'1 destinataire} other {En attente de # destinataires}}"
|
||||
|
||||
@@ -116,7 +116,7 @@ msgstr "{0} modèles de signature directe"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} des {1} documents restants ce mois-ci."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:170
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Destinataire(s)"
|
||||
|
||||
@@ -157,6 +157,18 @@ msgstr "<0>\"{0}\"</0> n'est plus disponible pour signer"
|
||||
msgid "<0>Sender:</0> All"
|
||||
msgstr "<0>Expéditeur :</0> Tous"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:104
|
||||
msgid "<0>You are about to complete approving <1>\"{documentTitle}\"</1>.</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "<0>You are about to complete signing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:76
|
||||
msgid "<0>You are about to complete viewing \"<1>{documentTitle}</1>\".</0><2/> Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/token/contants.ts:5
|
||||
msgid "1 month"
|
||||
msgstr "1 mois"
|
||||
@@ -665,7 +677,7 @@ msgstr "Version de l'application"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||
msgid "Approve"
|
||||
msgstr "Approuver"
|
||||
|
||||
@@ -835,7 +847,7 @@ msgstr "En utilisant la fonctionnalité de signature électronique, vous consent
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:328
|
||||
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:153
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:130
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:305
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:335
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -947,22 +959,22 @@ msgstr "Cliquez pour insérer le champ"
|
||||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:446
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:325
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
msgid "Complete"
|
||||
msgstr "Compléter"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
msgid "Complete Approval"
|
||||
msgstr "Compléter l'approbation"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
msgid "Complete Signing"
|
||||
msgstr "Compléter la signature"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Compléter la visualisation"
|
||||
|
||||
@@ -1048,23 +1060,23 @@ msgstr "Continuer"
|
||||
msgid "Continue to login"
|
||||
msgstr "Continuer vers la connexion"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:188
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:185
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
msgstr "Contrôle la langue par défaut d'un document téléchargé. Cela sera utilisé comme langue dans les communications par e-mail avec les destinataires."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:154
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:153
|
||||
msgid "Controls the default visibility of an uploaded document."
|
||||
msgstr "Contrôle la visibilité par défaut d'un document téléchargé."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:237
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:232
|
||||
msgid "Controls the formatting of the message that will be sent when inviting a recipient to sign a document. If a custom message has been provided while configuring the document, it will be used instead."
|
||||
msgstr "Contrôle le formatage du message qui sera envoyé lors de l'invitation d'un destinataire à signer un document. Si un message personnalisé a été fourni lors de la configuration du document, il sera utilisé à la place."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:270
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:263
|
||||
msgid "Controls whether the recipients can sign the documents using a typed signature. Enable or disable the typed signature globally."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:301
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:293
|
||||
msgid "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately."
|
||||
msgstr ""
|
||||
|
||||
@@ -1185,7 +1197,7 @@ msgstr "Créer un webhook"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Créer un Webhook"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:213
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Créez votre compte et commencez à utiliser la signature de documents à la pointe de la technologie."
|
||||
|
||||
@@ -1258,11 +1270,11 @@ msgstr "Décliner"
|
||||
msgid "Declined team invitation"
|
||||
msgstr "Invitation d'équipe refusée"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:168
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:165
|
||||
msgid "Default Document Language"
|
||||
msgstr "Langue par défaut du document"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:130
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:129
|
||||
msgid "Default Document Visibility"
|
||||
msgstr "Visibilité par défaut du document"
|
||||
|
||||
@@ -1461,7 +1473,7 @@ msgstr "Document"
|
||||
msgid "Document All"
|
||||
msgstr "Document Tout"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
msgid "Document Approved"
|
||||
msgstr "Document Approuvé"
|
||||
|
||||
@@ -1490,7 +1502,7 @@ msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Document créé en utilisant un <0>lien direct</0>"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:178
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:181
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:61
|
||||
msgid "Document deleted"
|
||||
msgstr "Document supprimé"
|
||||
@@ -1503,7 +1515,7 @@ msgstr "Brouillon de document"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Document dupliqué"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:189
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:192
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Historique du document"
|
||||
@@ -1529,7 +1541,7 @@ msgstr "Métriques du document"
|
||||
msgid "Document moved"
|
||||
msgstr "Document déplacé"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:158
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:156
|
||||
msgid "Document no longer available to sign"
|
||||
msgstr "Document non disponible pour signature"
|
||||
|
||||
@@ -1561,7 +1573,7 @@ msgstr "Document envoyé"
|
||||
#~ msgid "Document Settings"
|
||||
#~ msgstr "Document Settings"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:132
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:130
|
||||
msgid "Document Signed"
|
||||
msgstr "Document signé"
|
||||
|
||||
@@ -1585,7 +1597,7 @@ msgstr "Téléchargement du document désactivé en raison de factures impayées
|
||||
msgid "Document uploaded"
|
||||
msgstr "Document téléchargé"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:133
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:131
|
||||
msgid "Document Viewed"
|
||||
msgstr "Document consulté"
|
||||
|
||||
@@ -1609,7 +1621,7 @@ msgstr "Le document sera supprimé de manière permanente"
|
||||
msgid "Documents"
|
||||
msgstr "Documents"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:194
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:197
|
||||
msgid "Documents created from template"
|
||||
msgstr "Documents créés à partir du modèle"
|
||||
|
||||
@@ -1690,7 +1702,7 @@ msgstr "Dupliquer"
|
||||
msgid "Edit"
|
||||
msgstr "Modifier"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:114
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:117
|
||||
msgid "Edit Template"
|
||||
msgstr "Modifier le modèle"
|
||||
|
||||
@@ -1778,7 +1790,7 @@ msgstr "Activer la signature par lien direct"
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Activer la signature par lien direct"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:255
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:248
|
||||
msgid "Enable Typed Signature"
|
||||
msgstr ""
|
||||
|
||||
@@ -1866,15 +1878,15 @@ msgstr "Erreur"
|
||||
#~ msgid "Error updating global team settings"
|
||||
#~ msgstr "Error updating global team settings"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:141
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:140
|
||||
msgid "Everyone can access and view the document"
|
||||
msgstr "Tout le monde peut accéder et voir le document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:142
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:140
|
||||
msgid "Everyone has signed"
|
||||
msgstr "Tout le monde a signé"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:166
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:164
|
||||
msgid "Everyone has signed! You will receive an Email copy of the signed document."
|
||||
msgstr "Tout le monde a signé ! Vous recevrez une copie par email du document signé."
|
||||
|
||||
@@ -1963,7 +1975,7 @@ msgstr "Retourner"
|
||||
msgid "Go back home"
|
||||
msgstr "Retourner à la maison"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Retourner à la maison"
|
||||
@@ -2047,7 +2059,7 @@ msgstr "Documents de la boîte de réception"
|
||||
#~ msgid "Include Sender Details"
|
||||
#~ msgstr "Include Sender Details"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:286
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:278
|
||||
msgid "Include the Signing Certificate in the Document"
|
||||
msgstr ""
|
||||
|
||||
@@ -2267,7 +2279,7 @@ msgstr "Gérer le profil de {0}"
|
||||
msgid "Manage all teams you are currently associated with."
|
||||
msgstr "Gérer toutes les équipes avec lesquelles vous êtes actuellement associé."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:158
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:161
|
||||
msgid "Manage and view template"
|
||||
msgstr "Gérer et afficher le modèle"
|
||||
|
||||
@@ -2331,7 +2343,7 @@ msgstr "Gérer vos clés d'accès."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Gérer les paramètres de votre site ici"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:140
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Marquer comme vu"
|
||||
|
||||
@@ -2413,7 +2425,7 @@ msgstr "Mes modèles"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:209
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "Besoin de signer des documents ?"
|
||||
|
||||
@@ -2440,7 +2452,7 @@ msgstr "Nouveau modèle"
|
||||
msgid "Next"
|
||||
msgstr "Suivant"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:60
|
||||
msgid "Next field"
|
||||
msgstr "Champ suivant"
|
||||
|
||||
@@ -2542,11 +2554,11 @@ msgstr "Une fois confirmé, les éléments suivants se produiront :"
|
||||
msgid "Once you have scanned the QR code or entered the code manually, enter the code provided by your authenticator app below."
|
||||
msgstr "Une fois que vous avez scanné le code QR ou saisi le code manuellement, entrez le code fourni par votre application d'authentification ci-dessous."
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:147
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:146
|
||||
msgid "Only admins can access and view the document"
|
||||
msgstr "Seules les administrateurs peuvent accéder et voir le document"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:144
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:143
|
||||
msgid "Only managers and above can access and view the document"
|
||||
msgstr "Seuls les responsables et au-dessus peuvent accéder et voir le document"
|
||||
|
||||
@@ -2792,7 +2804,7 @@ msgstr "Veuillez taper <0>{0}</0> pour confirmer."
|
||||
msgid "Preferences"
|
||||
msgstr "Préférences"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:221
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:216
|
||||
msgid "Preview"
|
||||
msgstr "Aperçu"
|
||||
|
||||
@@ -3078,7 +3090,7 @@ msgstr "Rôles"
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:337
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:344
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/branding-preferences.tsx:312
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:313
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:305
|
||||
msgid "Save"
|
||||
msgstr "Sauvegarder"
|
||||
|
||||
@@ -3153,7 +3165,7 @@ msgstr "Envoyer l'e-mail de confirmation"
|
||||
msgid "Send document"
|
||||
msgstr "Envoyer le document"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:205
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:200
|
||||
msgid "Send on Behalf of Team"
|
||||
msgstr "Envoyer au nom de l'équipe"
|
||||
|
||||
@@ -3226,7 +3238,7 @@ msgstr "Afficher des modèles dans le profil public de votre équipe pour que vo
|
||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:141
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:313
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -3317,7 +3329,7 @@ msgstr "ID de signature"
|
||||
msgid "Signatures Collected"
|
||||
msgstr "Signatures collectées"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:200
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:198
|
||||
msgid "Signatures will appear once the document has been completed"
|
||||
msgstr "Les signatures apparaîtront une fois le document complété"
|
||||
|
||||
@@ -3649,7 +3661,7 @@ msgstr "Équipes restreintes"
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:145
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
|
||||
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
|
||||
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
|
||||
msgid "Template"
|
||||
@@ -3883,7 +3895,7 @@ msgstr "Ce document n'a pas pu être dupliqué pour le moment. Veuillez réessay
|
||||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Ce document n'a pas pu être renvoyé pour le moment. Veuillez réessayer."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:180
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:178
|
||||
msgid "This document has been cancelled by the owner and is no longer available for others to sign."
|
||||
msgstr "Ce document a été annulé par le propriétaire et n'est plus disponible pour d'autres à signer."
|
||||
|
||||
@@ -3891,11 +3903,11 @@ msgstr "Ce document a été annulé par le propriétaire et n'est plus disponibl
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "Ce document a été annulé par le propriétaire."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:224
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "Ce document a été signé par tous les destinataires"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:227
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "Ce document est actuellement un brouillon et n'a pas été envoyé"
|
||||
|
||||
@@ -4346,7 +4358,7 @@ msgstr "Le fichier téléchargé est trop petit"
|
||||
msgid "Uploaded file not an allowed file type"
|
||||
msgstr "Le fichier téléchargé n'est pas un type de fichier autorisé"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:169
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:172
|
||||
msgid "Use"
|
||||
msgstr "Utiliser"
|
||||
|
||||
@@ -4488,7 +4500,7 @@ msgstr "Vu"
|
||||
msgid "Waiting"
|
||||
msgstr "En attente"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:148
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "En attente que d'autres signent"
|
||||
|
||||
@@ -4806,16 +4818,16 @@ msgid "You"
|
||||
msgstr "Vous"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Vous êtes sur le point de terminer l'approbation de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
#~ msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Vous êtes sur le point de terminer l'approbation de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Vous êtes sur le point de terminer la signature de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
#~ msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Vous êtes sur le point de terminer la signature de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Vous êtes sur le point de terminer la visualisation de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
#~ msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
#~ msgstr "Vous êtes sur le point de terminer la visualisation de \"{truncatedTitle}\".<0/> Êtes-vous sûr?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:105
|
||||
msgid "You are about to delete <0>\"{documentTitle}\"</0>"
|
||||
@@ -5015,7 +5027,7 @@ msgstr "Vous serez notifié et pourrez configurer votre profil public Documenso
|
||||
msgid "You will now be required to enter a code from your authenticator app when signing in."
|
||||
msgstr "Vous devrez maintenant entrer un code de votre application d'authentification lors de la connexion."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:173
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:171
|
||||
msgid "You will receive an Email copy of the signed document once everyone has signed."
|
||||
msgstr "Vous recevrez une copie par e-mail du document signé une fois que tout le monde aura signé."
|
||||
|
||||
|
||||
108
packages/lib/utils/logger.ts
Normal file
108
packages/lib/utils/logger.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import Honeybadger from '@honeybadger-io/js';
|
||||
|
||||
export const buildLogger = () => {
|
||||
if (process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY) {
|
||||
return new HoneybadgerLogger();
|
||||
}
|
||||
|
||||
return new DefaultLogger();
|
||||
};
|
||||
|
||||
interface LoggerDescriptionOptions {
|
||||
method?: string;
|
||||
path?: string;
|
||||
context?: Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* The type of log to be captured.
|
||||
*
|
||||
* Defaults to `info`.
|
||||
*/
|
||||
level?: 'info' | 'error' | 'critical';
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic logger implementation intended to be used in the server side for capturing
|
||||
* explicit errors and other logs.
|
||||
*
|
||||
* Not intended to capture the request and responses.
|
||||
*/
|
||||
interface Logger {
|
||||
log(message: string, options?: LoggerDescriptionOptions): void;
|
||||
|
||||
error(error: Error, options?: LoggerDescriptionOptions): void;
|
||||
}
|
||||
|
||||
class DefaultLogger implements Logger {
|
||||
log(_message: string, _options?: LoggerDescriptionOptions) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
error(_error: Error, _options?: LoggerDescriptionOptions): void {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
class HoneybadgerLogger implements Logger {
|
||||
constructor() {
|
||||
if (!process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY) {
|
||||
throw new Error('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY is not set');
|
||||
}
|
||||
|
||||
Honeybadger.configure({
|
||||
apiKey: process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Honeybadger doesn't really have a non-error logging system.
|
||||
*/
|
||||
log(message: string, options?: LoggerDescriptionOptions) {
|
||||
const { context = {}, level = 'info' } = options || {};
|
||||
|
||||
try {
|
||||
Honeybadger.event({
|
||||
message,
|
||||
context: {
|
||||
level,
|
||||
...context,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
error(error: Error, options?: LoggerDescriptionOptions): void {
|
||||
const { context = {}, level = 'error', method, path } = options || {};
|
||||
|
||||
const tags = [`level:${level}`];
|
||||
let errorMessage = error.message;
|
||||
|
||||
if (method) {
|
||||
tags.push(`method:${method}`);
|
||||
|
||||
errorMessage = `[${method}]: ${error.message}`;
|
||||
}
|
||||
|
||||
if (path) {
|
||||
tags.push(`path:${path}`);
|
||||
}
|
||||
|
||||
try {
|
||||
Honeybadger.notify(errorMessage, {
|
||||
context: {
|
||||
level,
|
||||
...context,
|
||||
},
|
||||
tags,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,9 @@ export const authRouter = router({
|
||||
const { name, email, password, signature, url } = input;
|
||||
|
||||
if (IS_BILLING_ENABLED() && url && url.length < 6) {
|
||||
throw new AppError(
|
||||
AppErrorCode.PREMIUM_PROFILE_URL,
|
||||
'Only subscribers can have a username shorter than 6 characters',
|
||||
);
|
||||
throw new AppError(AppErrorCode.PREMIUM_PROFILE_URL, {
|
||||
message: 'Only subscribers can have a username shorter than 6 characters',
|
||||
});
|
||||
}
|
||||
|
||||
const user = await createUser({ name, email, password, signature, url });
|
||||
@@ -66,7 +65,7 @@ export const authRouter = router({
|
||||
const error = AppError.parseError(err);
|
||||
|
||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
let message =
|
||||
@@ -118,7 +117,7 @@ export const authRouter = router({
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
throw err;
|
||||
}
|
||||
}),
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { AppError } from '@documenso/lib/errors/app-error';
|
||||
import { getFieldById } from '@documenso/lib/server-only/field/get-field-by-id';
|
||||
import { removeSignedFieldWithToken } from '@documenso/lib/server-only/field/remove-signed-field-with-token';
|
||||
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
||||
@@ -96,7 +95,7 @@ export const fieldRouter = router({
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
throw err;
|
||||
}
|
||||
}),
|
||||
|
||||
|
||||
@@ -100,10 +100,9 @@ export const profileRouter = router({
|
||||
);
|
||||
|
||||
if (subscriptions.length === 0) {
|
||||
throw new AppError(
|
||||
AppErrorCode.PREMIUM_PROFILE_URL,
|
||||
'Only subscribers can have a username shorter than 6 characters',
|
||||
);
|
||||
throw new AppError(AppErrorCode.PREMIUM_PROFILE_URL, {
|
||||
message: 'Only subscribers can have a username shorter than 6 characters',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ export const profileRouter = router({
|
||||
const error = AppError.parseError(err);
|
||||
|
||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new TRPCError({
|
||||
|
||||
@@ -76,412 +76,238 @@ export const teamRouter = router({
|
||||
acceptTeamInvitation: authenticatedProcedure
|
||||
.input(ZAcceptTeamInvitationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await acceptTeamInvitation({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await acceptTeamInvitation({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
}),
|
||||
|
||||
declineTeamInvitation: authenticatedProcedure
|
||||
.input(ZDeclineTeamInvitationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await declineTeamInvitation({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await declineTeamInvitation({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
}),
|
||||
|
||||
createBillingPortal: authenticatedProcedure
|
||||
.input(ZCreateTeamBillingPortalMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTeamBillingPortal({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createTeamBillingPortal({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
createTeam: authenticatedProcedure
|
||||
.input(ZCreateTeamMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
createTeamEmailVerification: authenticatedProcedure
|
||||
.input(ZCreateTeamEmailVerificationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTeamEmailVerification({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
data: {
|
||||
email: input.email,
|
||||
name: input.name,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createTeamEmailVerification({
|
||||
teamId: input.teamId,
|
||||
userId: ctx.user.id,
|
||||
data: {
|
||||
email: input.email,
|
||||
name: input.name,
|
||||
},
|
||||
});
|
||||
}),
|
||||
|
||||
createTeamMemberInvites: authenticatedProcedure
|
||||
.input(ZCreateTeamMemberInvitesMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTeamMemberInvites({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createTeamMemberInvites({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
createTeamPendingCheckout: authenticatedProcedure
|
||||
.input(ZCreateTeamPendingCheckoutMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await createTeamPendingCheckoutSession({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createTeamPendingCheckoutSession({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeam: authenticatedProcedure
|
||||
.input(ZDeleteTeamMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamEmail: authenticatedProcedure
|
||||
.input(ZDeleteTeamEmailMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamEmail({
|
||||
userId: ctx.user.id,
|
||||
userEmail: ctx.user.email,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamEmail({
|
||||
userId: ctx.user.id,
|
||||
userEmail: ctx.user.email,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamEmailVerification: authenticatedProcedure
|
||||
.input(ZDeleteTeamEmailVerificationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamEmailVerification({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamEmailVerification({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamMemberInvitations: authenticatedProcedure
|
||||
.input(ZDeleteTeamMemberInvitationsMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamMemberInvitations({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamMemberInvitations({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamMembers: authenticatedProcedure
|
||||
.input(ZDeleteTeamMembersMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamMembers({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamMembers({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamPending: authenticatedProcedure
|
||||
.input(ZDeleteTeamPendingMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamPending({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamPending({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTeamTransferRequest: authenticatedProcedure
|
||||
.input(ZDeleteTeamTransferRequestMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await deleteTeamTransferRequest({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await deleteTeamTransferRequest({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
findTeamInvoices: authenticatedProcedure
|
||||
.input(ZFindTeamInvoicesQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTeamInvoices({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await findTeamInvoices({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
findTeamMemberInvites: authenticatedProcedure
|
||||
.input(ZFindTeamMemberInvitesQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTeamMemberInvites({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await findTeamMemberInvites({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
findTeamMembers: authenticatedProcedure
|
||||
.input(ZFindTeamMembersQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTeamMembers({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
}),
|
||||
|
||||
findTeams: authenticatedProcedure.input(ZFindTeamsQuerySchema).query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTeams({
|
||||
return await findTeamMembers({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}),
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
findTeams: authenticatedProcedure.input(ZFindTeamsQuerySchema).query(async ({ input, ctx }) => {
|
||||
return await findTeams({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
findTeamsPending: authenticatedProcedure
|
||||
.input(ZFindTeamsPendingQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTeamsPending({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await findTeamsPending({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
getTeam: authenticatedProcedure.input(ZGetTeamQuerySchema).query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await getTeamById({ teamId: input.teamId, userId: ctx.user.id });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeamById({ teamId: input.teamId, userId: ctx.user.id });
|
||||
}),
|
||||
|
||||
getTeamEmailByEmail: authenticatedProcedure.query(async ({ ctx }) => {
|
||||
try {
|
||||
return await getTeamEmailByEmail({ email: ctx.user.email });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeamEmailByEmail({ email: ctx.user.email });
|
||||
}),
|
||||
|
||||
getTeamInvitations: authenticatedProcedure.query(async ({ ctx }) => {
|
||||
try {
|
||||
return await getTeamInvitations({ email: ctx.user.email });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeamInvitations({ email: ctx.user.email });
|
||||
}),
|
||||
|
||||
getTeamMembers: authenticatedProcedure
|
||||
.input(ZGetTeamMembersQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await getTeamMembers({ teamId: input.teamId, userId: ctx.user.id });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeamMembers({ teamId: input.teamId, userId: ctx.user.id });
|
||||
}),
|
||||
|
||||
getTeamPrices: authenticatedProcedure.query(async () => {
|
||||
try {
|
||||
return await getTeamPrices();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeamPrices();
|
||||
}),
|
||||
|
||||
getTeams: authenticatedProcedure.query(async ({ ctx }) => {
|
||||
try {
|
||||
return await getTeams({ userId: ctx.user.id });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await getTeams({ userId: ctx.user.id });
|
||||
}),
|
||||
|
||||
leaveTeam: authenticatedProcedure
|
||||
.input(ZLeaveTeamMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await leaveTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await leaveTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeam: authenticatedProcedure
|
||||
.input(ZUpdateTeamMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await updateTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await updateTeam({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeamEmail: authenticatedProcedure
|
||||
.input(ZUpdateTeamEmailMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await updateTeamEmail({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await updateTeamEmail({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeamMember: authenticatedProcedure
|
||||
.input(ZUpdateTeamMemberMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await updateTeamMember({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await updateTeamMember({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeamPublicProfile: authenticatedProcedure
|
||||
@@ -506,7 +332,7 @@ export const teamRouter = router({
|
||||
const error = AppError.parseError(err);
|
||||
|
||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new TRPCError({
|
||||
@@ -520,48 +346,30 @@ export const teamRouter = router({
|
||||
requestTeamOwnershipTransfer: authenticatedProcedure
|
||||
.input(ZRequestTeamOwnerhsipTransferMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await requestTeamOwnershipTransfer({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await requestTeamOwnershipTransfer({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
resendTeamEmailVerification: authenticatedProcedure
|
||||
.input(ZResendTeamEmailVerificationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
await resendTeamEmailVerification({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
await resendTeamEmailVerification({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
resendTeamMemberInvitation: authenticatedProcedure
|
||||
.input(ZResendTeamMemberInvitationMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
await resendTeamMemberInvitation({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
await resendTeamMemberInvitation({
|
||||
userId: ctx.user.id,
|
||||
userName: ctx.user.name ?? '',
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeamBrandingSettings: authenticatedProcedure
|
||||
@@ -569,17 +377,11 @@ export const teamRouter = router({
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const { teamId, settings } = input;
|
||||
|
||||
try {
|
||||
return await updateTeamBrandingSettings({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
settings,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await updateTeamBrandingSettings({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
settings,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTeamDocumentSettings: authenticatedProcedure
|
||||
@@ -587,16 +389,10 @@ export const teamRouter = router({
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const { teamId, settings } = input;
|
||||
|
||||
try {
|
||||
return await updateTeamDocumentSettings({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
settings,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await updateTeamDocumentSettings({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
settings,
|
||||
});
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -42,323 +42,214 @@ export const templateRouter = router({
|
||||
createTemplate: authenticatedProcedure
|
||||
.input(ZCreateTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { teamId, title, templateDocumentDataId } = input;
|
||||
const { teamId, title, templateDocumentDataId } = input;
|
||||
|
||||
return await createTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
title,
|
||||
templateDocumentDataId,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to create this template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await createTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
title,
|
||||
templateDocumentDataId,
|
||||
});
|
||||
}),
|
||||
|
||||
createDocumentFromDirectTemplate: maybeAuthenticatedProcedure
|
||||
.input(ZCreateDocumentFromDirectTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const {
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
} = input;
|
||||
const {
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
} = input;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await createDocumentFromDirectTemplate({
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
user: ctx.user
|
||||
? {
|
||||
id: ctx.user.id,
|
||||
name: ctx.user.name || undefined,
|
||||
email: ctx.user.email,
|
||||
}
|
||||
: undefined,
|
||||
requestMetadata,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await createDocumentFromDirectTemplate({
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
user: ctx.user
|
||||
? {
|
||||
id: ctx.user.id,
|
||||
name: ctx.user.name || undefined,
|
||||
email: ctx.user.email,
|
||||
}
|
||||
: undefined,
|
||||
requestMetadata,
|
||||
});
|
||||
}),
|
||||
|
||||
createDocumentFromTemplate: authenticatedProcedure
|
||||
.input(ZCreateDocumentFromTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, teamId, recipients } = input;
|
||||
const { templateId, teamId, recipients } = input;
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId });
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId });
|
||||
|
||||
if (limits.remaining.documents === 0) {
|
||||
throw new Error('You have reached your document limit.');
|
||||
}
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
let document: Document = await createDocumentFromTemplate({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
recipients,
|
||||
requestMetadata,
|
||||
});
|
||||
|
||||
if (input.distributeDocument) {
|
||||
document = await sendDocument({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
requestMetadata,
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
|
||||
throw new AppError('DOCUMENT_SEND_FAILED');
|
||||
});
|
||||
}
|
||||
|
||||
return document;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
if (limits.remaining.documents === 0) {
|
||||
throw new Error('You have reached your document limit.');
|
||||
}
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
let document: Document = await createDocumentFromTemplate({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
recipients,
|
||||
requestMetadata,
|
||||
});
|
||||
|
||||
if (input.distributeDocument) {
|
||||
document = await sendDocument({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
requestMetadata,
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
|
||||
throw new AppError('DOCUMENT_SEND_FAILED');
|
||||
});
|
||||
}
|
||||
|
||||
return document;
|
||||
}),
|
||||
|
||||
duplicateTemplate: authenticatedProcedure
|
||||
.input(ZDuplicateTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { teamId, templateId } = input;
|
||||
const { teamId, templateId } = input;
|
||||
|
||||
return await duplicateTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
templateId,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to duplicate the template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await duplicateTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
templateId,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteTemplate: authenticatedProcedure
|
||||
.input(ZDeleteTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { id, teamId } = input;
|
||||
const { id, teamId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await deleteTemplate({ userId, id, teamId });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to delete this template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await deleteTemplate({ userId, id, teamId });
|
||||
}),
|
||||
|
||||
getTemplateWithDetailsById: authenticatedProcedure
|
||||
.input(ZGetTemplateWithDetailsByIdQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await getTemplateWithDetailsById({
|
||||
id: input.id,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to find this template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await getTemplateWithDetailsById({
|
||||
id: input.id,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
}),
|
||||
|
||||
// Todo: Add API
|
||||
updateTemplateSettings: authenticatedProcedure
|
||||
.input(ZUpdateTemplateSettingsMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, teamId, data, meta } = input;
|
||||
const { templateId, teamId, data, meta } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await updateTemplateSettings({
|
||||
userId,
|
||||
teamId,
|
||||
templateId,
|
||||
data,
|
||||
meta: {
|
||||
...meta,
|
||||
language: isValidLanguageCode(meta?.language) ? meta?.language : undefined,
|
||||
},
|
||||
requestMetadata,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message:
|
||||
'We were unable to update the settings for this template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await updateTemplateSettings({
|
||||
userId,
|
||||
teamId,
|
||||
templateId,
|
||||
data,
|
||||
meta: {
|
||||
...meta,
|
||||
language: isValidLanguageCode(meta?.language) ? meta?.language : undefined,
|
||||
},
|
||||
requestMetadata,
|
||||
});
|
||||
}),
|
||||
|
||||
setSigningOrderForTemplate: authenticatedProcedure
|
||||
.input(ZSetSigningOrderForTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, teamId, signingOrder } = input;
|
||||
const { templateId, teamId, signingOrder } = input;
|
||||
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
data: {},
|
||||
meta: { signingOrder },
|
||||
userId: ctx.user.id,
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message:
|
||||
'We were unable to update the settings for this document. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
data: {},
|
||||
meta: { signingOrder },
|
||||
userId: ctx.user.id,
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
}),
|
||||
|
||||
findTemplates: authenticatedProcedure
|
||||
.input(ZFindTemplatesQuerySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
try {
|
||||
return await findTemplates({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
}
|
||||
return await findTemplates({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
|
||||
createTemplateDirectLink: authenticatedProcedure
|
||||
.input(ZCreateTemplateDirectLinkMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, teamId, directRecipientId } = input;
|
||||
const { templateId, teamId, directRecipientId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
||||
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId: template.teamId });
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId: template.teamId });
|
||||
|
||||
if (limits.remaining.directTemplates === 0) {
|
||||
throw new AppError(
|
||||
AppErrorCode.LIMIT_EXCEEDED,
|
||||
'You have reached your direct templates limit.',
|
||||
);
|
||||
}
|
||||
|
||||
return await createTemplateDirectLink({ userId, templateId, directRecipientId });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
const error = AppError.parseError(err);
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
if (limits.remaining.directTemplates === 0) {
|
||||
throw new AppError(AppErrorCode.LIMIT_EXCEEDED, {
|
||||
message: 'You have reached your direct templates limit.',
|
||||
});
|
||||
}
|
||||
|
||||
return await createTemplateDirectLink({ userId, templateId, directRecipientId });
|
||||
}),
|
||||
|
||||
deleteTemplateDirectLink: authenticatedProcedure
|
||||
.input(ZDeleteTemplateDirectLinkMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId } = input;
|
||||
const { templateId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await deleteTemplateDirectLink({ userId, templateId });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
const error = AppError.parseError(err);
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
}
|
||||
return await deleteTemplateDirectLink({ userId, templateId });
|
||||
}),
|
||||
|
||||
toggleTemplateDirectLink: authenticatedProcedure
|
||||
.input(ZToggleTemplateDirectLinkMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, enabled } = input;
|
||||
const { templateId, enabled } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await toggleTemplateDirectLink({ userId, templateId, enabled });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
const error = AppError.parseError(err);
|
||||
throw AppError.parseErrorToTRPCError(error);
|
||||
}
|
||||
return await toggleTemplateDirectLink({ userId, templateId, enabled });
|
||||
}),
|
||||
|
||||
moveTemplateToTeam: authenticatedProcedure
|
||||
.input(ZMoveTemplatesToTeamSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { templateId, teamId } = input;
|
||||
const userId = ctx.user.id;
|
||||
const { templateId, teamId } = input;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await moveTemplateToTeam({
|
||||
templateId,
|
||||
teamId,
|
||||
userId,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
if (err instanceof TRPCError) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to move this template. Please try again later.',
|
||||
});
|
||||
}
|
||||
return await moveTemplateToTeam({
|
||||
templateId,
|
||||
teamId,
|
||||
userId,
|
||||
});
|
||||
}),
|
||||
|
||||
updateTemplateTypedSignatureSettings: authenticatedProcedure
|
||||
|
||||
@@ -1,12 +1,37 @@
|
||||
import { TRPCError, initTRPC } from '@trpc/server';
|
||||
import SuperJSON from 'superjson';
|
||||
|
||||
import { AppError, genericErrorCodeToTrpcErrorCodeMap } from '@documenso/lib/errors/app-error';
|
||||
import { isAdmin } from '@documenso/lib/next-auth/guards/is-admin';
|
||||
|
||||
import type { TrpcContext } from './context';
|
||||
|
||||
const t = initTRPC.context<TrpcContext>().create({
|
||||
transformer: SuperJSON,
|
||||
errorFormatter(opts) {
|
||||
const { shape, error } = opts;
|
||||
|
||||
const originalError = error.cause;
|
||||
|
||||
let data: Record<string, unknown> = shape.data;
|
||||
|
||||
if (originalError instanceof AppError) {
|
||||
data = {
|
||||
...data,
|
||||
appError: AppError.toJSON(originalError),
|
||||
code: originalError.code,
|
||||
httpStatus:
|
||||
originalError.statusCode ??
|
||||
genericErrorCodeToTrpcErrorCodeMap[originalError.code]?.status ??
|
||||
500,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...shape,
|
||||
data,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -98,7 +98,7 @@ export const twoFactorAuthenticationRouter = router({
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
throw AppError.parseErrorToTRPCError(err);
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
2
packages/tsconfig/process-env.d.ts
vendored
2
packages/tsconfig/process-env.d.ts
vendored
@@ -88,6 +88,8 @@ declare namespace NodeJS {
|
||||
NEXT_PRIVATE_INNGEST_APP_ID?: string;
|
||||
NEXT_PRIVATE_INNGEST_EVENT_KEY?: string;
|
||||
|
||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY?: string;
|
||||
|
||||
/**
|
||||
* Vercel environment variables
|
||||
*/
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"NEXT_PRIVATE_TRIGGER_API_KEY",
|
||||
"NEXT_PRIVATE_TRIGGER_API_URL",
|
||||
"NEXT_PRIVATE_INNGEST_APP_ID",
|
||||
"NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY",
|
||||
"INNGEST_EVENT_KEY",
|
||||
"NEXT_PRIVATE_INNGEST_EVENT_KEY",
|
||||
"CI",
|
||||
|
||||
Reference in New Issue
Block a user