diff --git a/.agents/plans/warm-purple-flower-custom-email-domain-sync-and-recovery.md b/.agents/plans/warm-purple-flower-custom-email-domain-sync-and-recovery.md new file mode 100644 index 000000000..c0a566169 --- /dev/null +++ b/.agents/plans/warm-purple-flower-custom-email-domain-sync-and-recovery.md @@ -0,0 +1,263 @@ +--- +date: 2026-02-24 +title: Custom Email Domain Sync And Recovery +--- + +## Problem Statement + +Custom email domains configured via AWS SES can get stuck in a `PENDING` state or fail validation silently. Currently, there is **no automated verification** -- users must manually click "Sync" in the UI to check domain status. If a domain fails to validate, the only option is to delete it and recreate it, which generates new DKIM keys and requires the user to update their DNS records. + +### Current Pain Points + +1. **No background sync** -- Domain verification status is never checked automatically; users must manually click "Sync" +2. **Stuck domains** -- Domains can remain in `PENDING` state indefinitely with no alerting or auto-recovery +3. **Failed recovery requires DNS changes** -- Deleting and recreating a domain generates new keys, forcing the user to update DNS records +4. **No visibility into failure duration** -- There's no tracking of how long a domain has been pending + +## Proposed Solution + +### 1. Hourly Background Sync Job + +Create a new cron job (`internal.sync-email-domains`) that runs every hour to automatically verify all `PENDING` email domains. + +**Job Definition:** `packages/lib/jobs/definitions/internal/sync-email-domains.ts` +**Job Handler:** `packages/lib/jobs/definitions/internal/sync-email-domains.handler.ts` + +**Pattern:** Follow the existing `cleanup-rate-limits` cron job pattern: + +- `cron: '0 * * * *'` (every hour, on the hour) +- Empty `z.object({})` schema (no payload needed) +- Register in `packages/lib/jobs/client.ts` + +**Handler Logic:** + +1. Query all `EmailDomain` records with `status: 'PENDING'` +2. For each domain, call `verifyEmailDomain(emailDomainId)` which: + - Calls AWS SES `GetEmailIdentityCommand` to check current verification status + - Updates DB status to `ACTIVE` if verified, keeps `PENDING` otherwise +3. Log results via `io.logger` (how many checked, how many transitioned to ACTIVE) +4. Process domains in batches to avoid overwhelming SES API rate limits +5. Add error handling per-domain so one failure doesn't stop the entire sweep + +### 2. Schema Changes -- Track Pending Duration + +Add a `lastVerifiedAt` column to the `EmailDomain` model to track when verification was last attempted, enabling "stale domain" detection. + +**File:** `packages/prisma/schema.prisma` + +```prisma +model EmailDomain { + // ... existing fields ... + lastVerifiedAt DateTime? // Last time verification was checked against SES +} +``` + +**Migration:** Create a new Prisma migration for this column addition. + +**Updates needed:** + +- `verify-email-domain.ts` -- Update `lastVerifiedAt` when verification is checked +- The sync job handler -- Use `lastVerifiedAt` to avoid re-checking domains that were just verified + +### 3. Domain Re-registration (Recovery) -- Delete & Recreate in SES Without Changing Keys + +Add a new "Re-register" action that deletes the SES identity and recreates it using the **same** DKIM key pair stored in the database, so the user's DNS records remain valid. + +#### 3a. New Service Function + +**File:** `packages/ee/server-only/lib/reregister-email-domain.ts` + +```typescript +export const reregisterEmailDomain = async (options: { emailDomainId: string }) => { + // 1. Fetch the EmailDomain record (including encrypted privateKey) + // 2. Decrypt the private key using DOCUMENSO_ENCRYPTION_KEY + // 3. Call DeleteEmailIdentityCommand on SES (ignore NotFoundException) + // 4. Call CreateEmailIdentityCommand with BYODKIM using the SAME selector + private key + // 5. Update EmailDomain status back to PENDING, update lastVerifiedAt + // 6. Return the updated domain +}; +``` + +Key points: + +- Uses the existing encrypted `privateKey` from the DB -- no new key generation +- Uses the existing `selector` -- DNS records stay the same +- Deletes first, then recreates -- handles cases where SES state is corrupted +- Resets status to `PENDING` since verification will need to re-occur +- Uses `verifyDomainWithDKIM()` from `create-email-domain.ts` (may need to extract/export this helper) + +#### 3b. Admin TRPC Routes (Find, Get, Re-register) + +All email domain admin routes use `adminProcedure` -- requires system-level `Role.ADMIN`. + +**Find (list) route:** +**File:** `packages/trpc/server/admin-router/find-email-domains.ts` +**Types:** `packages/trpc/server/admin-router/find-email-domains.types.ts` + +- Query route: `admin.emailDomain.find` +- Input: `{ query?: string, page?: number, perPage?: number, status?: EmailDomainStatus }` +- Extends `ZFindSearchParamsSchema` with optional `status` filter +- Returns standard `ZFindResultResponse` with email domain data including: id, domain, status, selector, createdAt, lastVerifiedAt, organisation name, email count +- Prisma query filters by domain name (LIKE search on `query`), optional status, joins organisation for name, counts emails + +**Get (detail) route:** +**File:** `packages/trpc/server/admin-router/get-email-domain.ts` +**Types:** `packages/trpc/server/admin-router/get-email-domain.types.ts` + +- Query route: `admin.emailDomain.get` +- Input: `{ emailDomainId: string }` +- Returns full email domain detail: all fields (except privateKey), organisation info, list of associated emails, DNS records (generated from publicKey + selector) +- Omits `privateKey` from response + +**Re-register (mutation) route:** +**File:** `packages/trpc/server/admin-router/reregister-email-domain.ts` +**Types:** `packages/trpc/server/admin-router/reregister-email-domain.types.ts` + +- Mutation route: `admin.emailDomain.reregister` +- Input: `{ emailDomainId: string }` +- Calls `reregisterEmailDomain()` +- Rationale: Re-registration is a recovery/operational action that deletes and recreates an SES identity. This is a privileged operation that should only be performed by platform operators, not self-service by org admins. + +#### 3c. Register in Admin Router + +**File:** `packages/trpc/server/admin-router/router.ts` + +Add a new `emailDomain` namespace to the admin router: + +```typescript +emailDomain: { + find: findEmailDomainsRoute, + get: getEmailDomainRoute, + reregister: reregisterEmailDomainRoute, +}, +``` + +#### 3d. Admin Panel UI -- Email Domains Section + +**List page:** `apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx` + +- New admin panel page at `/admin/email-domains` +- Follow the existing admin documents list pattern (client-side TRPC data fetching) +- Search input (debounced) filtering by domain name +- Status filter dropdown (All / Pending / Active) +- DataTable with columns: Domain, Organisation, Status (badge), Email Count, Created, Last Verified, Actions +- Actions dropdown per row: View details, Re-register +- Pagination via `DataTablePagination` + +**Detail page:** `apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx` + +- Shows full domain details: domain, selector, status, organisation, created date, last verified date +- Shows DNS records (DKIM + SPF) with copy buttons (reuse `organisation-email-domain-records-dialog` pattern) +- Table of associated organisation emails +- "Re-register" button with confirmation dialog explaining the action (SES identity will be deleted and recreated with the same keys) +- "Verify Now" button to manually trigger a verification check +- Shows how long the domain has been pending (using `lastVerifiedAt` or `createdAt`) + +**Navigation:** Add menu item to admin sidebar in `_layout.tsx`: + +```tsx + +``` + +**Table component:** `apps/remix/app/components/tables/admin-email-domains-table.tsx` (optional -- can be inline in the route file like the documents page) + +#### 3e. Automatic Re-registration in Sync Job (Optional Enhancement) + +In the hourly sync job, after checking verification status, if a domain has been `PENDING` for more than 48 hours: + +- Automatically call `reregisterEmailDomain()` to attempt recovery +- Log the auto-recovery attempt +- This provides a self-healing mechanism without user intervention + +## Implementation Plan + +### Phase 1: Background Sync Job (Core) + +1. Create `sync-email-domains.ts` job definition with hourly cron +2. Create `sync-email-domains.handler.ts` with batch verification logic +3. Register job in `packages/lib/jobs/client.ts` +4. Add error handling and logging + +### Phase 2: Schema Enhancement + +5. Add `lastVerifiedAt` column to `EmailDomain` model +6. Create Prisma migration +7. Update `verifyEmailDomain()` to set `lastVerifiedAt` on each check +8. Update sync job to use `lastVerifiedAt` for intelligent scheduling + +### Phase 3: Admin Email Domains Panel + +9. Create `find-email-domains` admin TRPC route + types (list/search with pagination and status filter) +10. Create `get-email-domain` admin TRPC route + types (detail view with org info, emails, DNS records) +11. Register find + get routes in admin router under `emailDomain` namespace +12. Create admin list page (`admin+/email-domains._index.tsx`) with search, status filter, DataTable +13. Create admin detail page (`admin+/email-domains.$id.tsx`) with domain info, emails table, DNS records +14. Add "Email Domains" menu item to admin sidebar (`_layout.tsx`) + +### Phase 4: Re-registration Feature + +15. Extract `verifyDomainWithDKIM()` as a shared helper (if not already exported) +16. Create `reregisterEmailDomain()` service function +17. Create `reregister-email-domain` admin TRPC mutation route + types +18. Register reregister route in admin router under `emailDomain.reregister` +19. Add "Re-register" button + confirmation dialog on admin detail page + +### Phase 5: Auto-Recovery (Optional) + +20. Add 48-hour stale detection logic to sync job +21. Auto-trigger re-registration for stale domains +22. Add logging/notifications for auto-recovery events + +## Files to Create/Modify + +### New Files + +- `packages/lib/jobs/definitions/internal/sync-email-domains.ts` +- `packages/lib/jobs/definitions/internal/sync-email-domains.handler.ts` +- `packages/ee/server-only/lib/reregister-email-domain.ts` +- `packages/trpc/server/admin-router/find-email-domains.ts` +- `packages/trpc/server/admin-router/find-email-domains.types.ts` +- `packages/trpc/server/admin-router/get-email-domain.ts` +- `packages/trpc/server/admin-router/get-email-domain.types.ts` +- `packages/trpc/server/admin-router/reregister-email-domain.ts` +- `packages/trpc/server/admin-router/reregister-email-domain.types.ts` +- `apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx` +- `apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx` + +### Modified Files + +- `packages/prisma/schema.prisma` -- Add `lastVerifiedAt` field +- `packages/lib/jobs/client.ts` -- Register new sync job +- `packages/ee/server-only/lib/verify-email-domain.ts` -- Update `lastVerifiedAt` +- `packages/ee/server-only/lib/create-email-domain.ts` -- Export `verifyDomainWithDKIM` helper +- `packages/trpc/server/admin-router/router.ts` -- Add `emailDomain.{find, get, reregister}` routes +- `apps/remix/app/routes/_authenticated+/admin+/_layout.tsx` -- Add "Email Domains" nav item to sidebar +- New Prisma migration file + +## Technical Considerations + +1. **SES API Rate Limits** -- AWS SES has rate limits on `GetEmailIdentityCommand`. The sync job should process domains in batches with small delays between calls (e.g., 5-10 per batch with 1s delay). + +2. **Concurrency** -- The local job provider has deterministic deduplication via SHA-256 IDs, so multiple app instances won't run the same cron tick twice. + +3. **Error Isolation** -- Each domain verification in the sync job should be wrapped in try/catch so one failing domain doesn't prevent others from being checked. + +4. **Re-registration Safety** -- The re-register function should be idempotent. Deleting a non-existent SES identity should be handled gracefully (already done in `deleteEmailDomain`). + +5. **Private Key Security** -- The private key is encrypted at rest and should only be decrypted transiently during re-registration. It should never be logged or exposed in API responses. + +6. **Feature Gating** -- The sync job should only process domains belonging to organisations with active `emailDomains` claim flags. This prevents processing domains for orgs that have downgraded. + +7. **Observability** -- Add structured logging to the sync job so operations teams can monitor domain verification health across all tenants. diff --git a/apps/remix/app/routes/_authenticated+/admin+/_layout.tsx b/apps/remix/app/routes/_authenticated+/admin+/_layout.tsx index 8757372b1..43fe8feda 100644 --- a/apps/remix/app/routes/_authenticated+/admin+/_layout.tsx +++ b/apps/remix/app/routes/_authenticated+/admin+/_layout.tsx @@ -3,6 +3,7 @@ import { BarChart3, Building2Icon, FileStack, + MailIcon, Settings, Trophy, Users, @@ -122,6 +123,20 @@ export default function AdminLayout({ loaderData }: Route.ComponentProps) { + + + + + + + + Re-register Email Domain + + + + + This will delete the existing SES identity for{' '} + {emailDomain.domain} and recreate it using the same DKIM keys. + The user will not need to update their DNS records. The domain status will be + reset to Pending. + + + + + + + Cancel + + + reregisterDomain({ emailDomainId: emailDomain.id })} + > + Re-register + + + + + + +
+ +

+ DNS Records +

+ +
+ {dnsRecords.map((record, index) => ( +
+
+
+ {record.type} Record +
+ + +
+ +
+
+ + Name:{' '} + + {record.name} +
+
+ + Value:{' '} + + {record.value} +
+
+
+ ))} +
+ +
+ +

+ Emails ({emailDomain.emails.length}) +

+ +
+ {emailDomain.emails.length > 0 ? ( + {}} + /> + ) : ( +

+ No emails configured for this domain. +

+ )} +
+ + ); +} diff --git a/apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx b/apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx new file mode 100644 index 000000000..669747e6d --- /dev/null +++ b/apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx @@ -0,0 +1,207 @@ +import { useMemo, useState } from 'react'; + +import { msg } from '@lingui/core/macro'; +import { useLingui } from '@lingui/react'; +import { Trans } from '@lingui/react/macro'; +import { EmailDomainStatus } from '@prisma/client'; +import { CheckCircle2Icon, ClockIcon, Loader } from 'lucide-react'; +import { Link, useSearchParams } from 'react-router'; +import { match } from 'ts-pattern'; + +import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounced-value'; +import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; +import { trpc } from '@documenso/trpc/react'; +import { Badge } from '@documenso/ui/primitives/badge'; +import { Button } from '@documenso/ui/primitives/button'; +import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table'; +import { DataTable } from '@documenso/ui/primitives/data-table'; +import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination'; +import { Input } from '@documenso/ui/primitives/input'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@documenso/ui/primitives/select'; + +export default function AdminEmailDomainsPage() { + const { _, i18n } = useLingui(); + + const [searchParams] = useSearchParams(); + const updateSearchParams = useUpdateSearchParams(); + + const [term, setTerm] = useState(() => searchParams?.get?.('term') ?? ''); + const debouncedTerm = useDebouncedValue(term, 500); + + const page = searchParams?.get?.('page') ? Number(searchParams.get('page')) : undefined; + const perPage = searchParams?.get?.('perPage') ? Number(searchParams.get('perPage')) : undefined; + const statusParam = searchParams?.get?.('status') ?? 'ALL'; + + const statusFilter = + statusParam === 'PENDING' || statusParam === 'ACTIVE' ? statusParam : undefined; + + const { data: findEmailDomainsData, isPending: isFindEmailDomainsLoading } = + trpc.admin.emailDomain.find.useQuery( + { + query: debouncedTerm, + page: page || 1, + perPage: perPage || 20, + status: statusFilter, + }, + { + placeholderData: (previousData) => previousData, + }, + ); + + const results = findEmailDomainsData ?? { + data: [], + perPage: 20, + currentPage: 1, + totalPages: 1, + }; + + const columns = useMemo(() => { + return [ + { + header: _(msg`Domain`), + accessorKey: 'domain', + cell: ({ row }) => ( + + {row.original.domain} + + ), + }, + { + header: _(msg`Organisation`), + accessorKey: 'organisation', + cell: ({ row }) => ( + + {row.original.organisation.name} + + ), + }, + { + header: _(msg`Status`), + accessorKey: 'status', + cell: ({ row }) => + match(row.original.status) + .with(EmailDomainStatus.ACTIVE, () => ( + + + Active + + )) + .with(EmailDomainStatus.PENDING, () => ( + + + Pending + + )) + .exhaustive(), + }, + { + header: _(msg`Emails`), + accessorKey: '_count', + cell: ({ row }) => row.original._count.emails, + }, + { + header: _(msg`Created`), + accessorKey: 'createdAt', + cell: ({ row }) => i18n.date(row.original.createdAt), + }, + { + header: _(msg`Last Verified`), + accessorKey: 'lastVerifiedAt', + cell: ({ row }) => + row.original.lastVerifiedAt ? i18n.date(row.original.lastVerifiedAt) : '-', + }, + { + header: _(msg`Actions`), + cell: ({ row }) => ( + + ), + }, + ] satisfies DataTableColumnDef<(typeof results)['data'][number]>[]; + }, []); + + const onPaginationChange = (newPage: number, newPerPage: number) => { + updateSearchParams({ + page: newPage, + perPage: newPerPage, + }); + }; + + const onStatusChange = (value: string) => { + updateSearchParams({ + status: value === 'ALL' ? undefined : value, + page: 1, + }); + }; + + return ( +
+

+ Email Domains +

+ +
+
+ setTerm(e.target.value)} + /> + + +
+ +
+ + {(table) => } + + + {isFindEmailDomainsLoading && ( +
+ +
+ )} +
+
+
+ ); +} diff --git a/package-lock.json b/package-lock.json index c9038d9ee..74de229a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@libpdf/core": "^0.2.9", "@lingui/conf": "^5.6.0", "@lingui/core": "^5.6.0", + "@prisma/extension-read-replicas": "^0.4.1", "ai": "^5.0.104", "cron-parser": "^5.5.0", "luxon": "^3.7.2", @@ -12193,6 +12194,15 @@ "integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==", "license": "Apache-2.0" }, + "node_modules/@prisma/extension-read-replicas": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@prisma/extension-read-replicas/-/extension-read-replicas-0.4.1.tgz", + "integrity": "sha512-mCMDloqUKUwx2o5uedTs1FHX3Nxdt1GdRMoeyp1JggjiwOALmIYWhxfIN08M2BZ0w8SKwvJqicJZMjkQYkkijw==", + "license": "Apache-2.0", + "peerDependencies": { + "@prisma/client": "^6.5.0" + } + }, "node_modules/@prisma/fetch-engine": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz", diff --git a/package.json b/package.json index 69c41b221..92af48da1 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "@libpdf/core": "^0.2.9", "@lingui/conf": "^5.6.0", "@lingui/core": "^5.6.0", + "@prisma/extension-read-replicas": "^0.4.1", "ai": "^5.0.104", "cron-parser": "^5.5.0", "luxon": "^3.7.2", diff --git a/packages/app-tests/e2e/webhooks/webhooks-crud.spec.ts b/packages/app-tests/e2e/webhooks/webhooks-crud.spec.ts index 9db66b988..def95e7cc 100644 --- a/packages/app-tests/e2e/webhooks/webhooks-crud.spec.ts +++ b/packages/app-tests/e2e/webhooks/webhooks-crud.spec.ts @@ -2,6 +2,7 @@ import { expect, test } from '@playwright/test'; import { WebhookCallStatus, WebhookTriggerEvents } from '@prisma/client'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; +import { alphaid } from '@documenso/lib/universal/id'; import { prisma } from '@documenso/prisma'; import { seedBlankDocument } from '@documenso/prisma/seed/documents'; import { seedUser } from '@documenso/prisma/seed/users'; @@ -279,8 +280,8 @@ test('[WEBHOOKS]: cannot see unrelated webhooks', async ({ page }) => { const user1Data = await seedUser(); const user2Data = await seedUser(); - const webhookUrl1 = `https://example.com/webhook-team1-${Date.now()}`; - const webhookUrl2 = `https://example.com/webhook-team2-${Date.now()}`; + const webhookUrl1 = `https://example.com/webhook-team1-${alphaid(12)}`; + const webhookUrl2 = `https://example.com/webhook-team2-${alphaid(12)}`; // Create webhooks for both teams with DOCUMENT_CREATED event const webhook1 = await seedWebhook({ diff --git a/packages/ee/server-only/lib/create-email-domain.ts b/packages/ee/server-only/lib/create-email-domain.ts index b50a55965..061a71cc1 100644 --- a/packages/ee/server-only/lib/create-email-domain.ts +++ b/packages/ee/server-only/lib/create-email-domain.ts @@ -142,6 +142,7 @@ export const createEmailDomain = async ({ domain, organisationId }: CreateEmailD publicKey: true, createdAt: true, updatedAt: true, + lastVerifiedAt: true, emails: true, }, }); diff --git a/packages/ee/server-only/lib/reregister-email-domain.ts b/packages/ee/server-only/lib/reregister-email-domain.ts new file mode 100644 index 000000000..1b9960c6b --- /dev/null +++ b/packages/ee/server-only/lib/reregister-email-domain.ts @@ -0,0 +1,93 @@ +import { DeleteEmailIdentityCommand } from '@aws-sdk/client-sesv2'; +import { EmailDomainStatus } from '@prisma/client'; + +import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto'; +import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; +import { symmetricDecrypt } from '@documenso/lib/universal/crypto'; +import { prisma } from '@documenso/prisma'; + +import { getSesClient, verifyDomainWithDKIM } from './create-email-domain'; + +type ReregisterEmailDomainOptions = { + emailDomainId: string; +}; + +/** + * Re-register an email domain in SES using the same DKIM key pair. + * + * This deletes the existing SES identity and recreates it with the same + * selector and private key, so the user does not need to update their DNS records. + * + * Permission is assumed to be checked in the caller. + */ +export const reregisterEmailDomain = async ({ emailDomainId }: ReregisterEmailDomainOptions) => { + const encryptionKey = DOCUMENSO_ENCRYPTION_KEY; + + if (!encryptionKey) { + throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY'); + } + + const emailDomain = await prisma.emailDomain.findUnique({ + where: { + id: emailDomainId, + }, + }); + + if (!emailDomain) { + throw new AppError(AppErrorCode.NOT_FOUND, { + message: 'Email domain not found', + }); + } + + const sesClient = getSesClient(); + + // Delete the existing SES identity, ignoring if it no longer exists. + await sesClient + .send( + new DeleteEmailIdentityCommand({ + EmailIdentity: emailDomain.domain, + }), + ) + .catch((err) => { + if (err.name === 'NotFoundException') { + return; + } + + throw err; + }); + + // Decrypt the stored private key. + const decryptedPrivateKeyBytes = symmetricDecrypt({ + key: encryptionKey, + data: emailDomain.privateKey, + }); + + const decryptedPrivateKey = new TextDecoder().decode(decryptedPrivateKeyBytes); + + // The selector field in the DB is the full record name (e.g. "documenso-orgid._domainkey.example.com"). + // We need to extract just the selector part (before "._domainkey."). + const selectorParts = emailDomain.selector.split('._domainkey.'); + const selector = selectorParts[0]; + + if (!selector) { + throw new AppError(AppErrorCode.UNKNOWN_ERROR, { + message: 'Could not extract selector from email domain record', + }); + } + + // Recreate the SES identity with the same DKIM key pair. + await verifyDomainWithDKIM(emailDomain.domain, selector, decryptedPrivateKey); + + // Reset status to PENDING and update lastVerifiedAt. + const updatedEmailDomain = await prisma.emailDomain.update({ + where: { + id: emailDomainId, + }, + data: { + status: EmailDomainStatus.PENDING, + lastVerifiedAt: new Date(), + }, + }); + + return updatedEmailDomain; +}; diff --git a/packages/ee/server-only/lib/verify-email-domain.ts b/packages/ee/server-only/lib/verify-email-domain.ts index 0c898016e..bf82a78da 100644 --- a/packages/ee/server-only/lib/verify-email-domain.ts +++ b/packages/ee/server-only/lib/verify-email-domain.ts @@ -35,6 +35,7 @@ export const verifyEmailDomain = async (emailDomainId: string) => { }, data: { status: isVerified ? EmailDomainStatus.ACTIVE : EmailDomainStatus.PENDING, + lastVerifiedAt: new Date(), }, }); diff --git a/packages/lib/jobs/client.ts b/packages/lib/jobs/client.ts index 0471e2018..af6241320 100644 --- a/packages/lib/jobs/client.ts +++ b/packages/lib/jobs/client.ts @@ -16,6 +16,7 @@ import { EXECUTE_WEBHOOK_JOB_DEFINITION } from './definitions/internal/execute-w import { EXPIRE_RECIPIENTS_SWEEP_JOB_DEFINITION } from './definitions/internal/expire-recipients-sweep'; import { PROCESS_RECIPIENT_EXPIRED_JOB_DEFINITION } from './definitions/internal/process-recipient-expired'; import { SEAL_DOCUMENT_JOB_DEFINITION } from './definitions/internal/seal-document'; +import { SYNC_EMAIL_DOMAINS_JOB_DEFINITION } from './definitions/internal/sync-email-domains'; /** * The `as const` assertion is load bearing as it provides the correct level of type inference for @@ -39,6 +40,7 @@ export const jobsClient = new JobClient([ EXPIRE_RECIPIENTS_SWEEP_JOB_DEFINITION, PROCESS_RECIPIENT_EXPIRED_JOB_DEFINITION, CLEANUP_RATE_LIMITS_JOB_DEFINITION, + SYNC_EMAIL_DOMAINS_JOB_DEFINITION, ] as const); export const jobs = jobsClient; diff --git a/packages/lib/jobs/client/inngest.ts b/packages/lib/jobs/client/inngest.ts index 8b565342b..702fc1de7 100644 --- a/packages/lib/jobs/client/inngest.ts +++ b/packages/lib/jobs/client/inngest.ts @@ -26,6 +26,7 @@ export class InngestJobProvider extends BaseJobProvider { const client = new InngestClient({ id: env('NEXT_PRIVATE_INNGEST_APP_ID') || 'documenso-app', eventKey: env('INNGEST_EVENT_KEY') || env('NEXT_PRIVATE_INNGEST_EVENT_KEY'), + logger: console, }); this._instance = new InngestJobProvider({ client }); @@ -90,7 +91,10 @@ export class InngestJobProvider extends BaseJobProvider { return { wait: step.sleep, logger: { - ...ctx.logger, + info: ctx.logger.info, + debug: ctx.logger.debug, + error: ctx.logger.error, + warn: ctx.logger.warn, log: ctx.logger.info, }, runTask: async (cacheKey, callback) => { diff --git a/packages/lib/jobs/definitions/internal/sync-email-domains.handler.ts b/packages/lib/jobs/definitions/internal/sync-email-domains.handler.ts new file mode 100644 index 000000000..8d580a010 --- /dev/null +++ b/packages/lib/jobs/definitions/internal/sync-email-domains.handler.ts @@ -0,0 +1,86 @@ +import { DateTime } from 'luxon'; + +import { reregisterEmailDomain } from '@documenso/ee/server-only/lib/reregister-email-domain'; +import { verifyEmailDomain } from '@documenso/ee/server-only/lib/verify-email-domain'; +import { prisma } from '@documenso/prisma'; + +import type { JobRunIO } from '../../client/_internal/job'; +import type { TSyncEmailDomainsJobDefinition } from './sync-email-domains'; + +const BATCH_SIZE = 10; +const AUTO_REREGISTER_AFTER_HOURS = 48; + +export const run = async ({ io }: { payload: TSyncEmailDomainsJobDefinition; io: JobRunIO }) => { + const pendingDomains = await prisma.emailDomain.findMany({ + where: { + status: 'PENDING', + }, + select: { + id: true, + domain: true, + createdAt: true, + lastVerifiedAt: true, + }, + orderBy: { + lastVerifiedAt: { sort: 'asc', nulls: 'first' }, + }, + }); + + if (pendingDomains.length === 0) { + io.logger.info('No pending email domains to sync'); + return; + } + + io.logger.info(`Found ${pendingDomains.length} pending email domains to sync`); + + let verifiedCount = 0; + let reregisteredCount = 0; + let errorCount = 0; + + const reregisterCutoff = DateTime.now().minus({ hours: AUTO_REREGISTER_AFTER_HOURS }).toJSDate(); + + for (let i = 0; i < pendingDomains.length; i += BATCH_SIZE) { + const batch = pendingDomains.slice(i, i + BATCH_SIZE); + + const results = await Promise.allSettled( + batch.map(async (domain) => { + const shouldReregister = domain.createdAt < reregisterCutoff; + + if (shouldReregister) { + io.logger.info( + `Domain "${domain.domain}" has been pending since ${domain.createdAt.toISOString()}, attempting re-registration`, + ); + + await reregisterEmailDomain({ emailDomainId: domain.id }); + return 'reregistered' as const; + } + + const { isVerified } = await verifyEmailDomain(domain.id); + + return isVerified ? ('verified' as const) : ('pending' as const); + }), + ); + + for (const result of results) { + if (result.status === 'rejected') { + errorCount++; + io.logger.error(`Failed to process email domain: ${String(result.reason)}`); + } else if (result.value === 'verified') { + verifiedCount++; + } else if (result.value === 'reregistered') { + reregisteredCount++; + } + } + + // Small delay between batches to respect SES API rate limits. + if (i + BATCH_SIZE < pendingDomains.length) { + await new Promise((resolve) => { + setTimeout(resolve, 1000); + }); + } + } + + io.logger.info( + `Sync complete: ${verifiedCount} verified, ${reregisteredCount} re-registered, ${errorCount} errors out of ${pendingDomains.length} pending domains`, + ); +}; diff --git a/packages/lib/jobs/definitions/internal/sync-email-domains.ts b/packages/lib/jobs/definitions/internal/sync-email-domains.ts new file mode 100644 index 000000000..f20f3b18d --- /dev/null +++ b/packages/lib/jobs/definitions/internal/sync-email-domains.ts @@ -0,0 +1,30 @@ +import { z } from 'zod'; + +import { type JobDefinition } from '../../client/_internal/job'; + +const SYNC_EMAIL_DOMAINS_JOB_DEFINITION_ID = 'internal.sync-email-domains'; + +const SYNC_EMAIL_DOMAINS_JOB_DEFINITION_SCHEMA = z.object({}); + +export type TSyncEmailDomainsJobDefinition = z.infer< + typeof SYNC_EMAIL_DOMAINS_JOB_DEFINITION_SCHEMA +>; + +export const SYNC_EMAIL_DOMAINS_JOB_DEFINITION = { + id: SYNC_EMAIL_DOMAINS_JOB_DEFINITION_ID, + name: 'Sync Email Domains', + version: '1.0.0', + trigger: { + name: SYNC_EMAIL_DOMAINS_JOB_DEFINITION_ID, + schema: SYNC_EMAIL_DOMAINS_JOB_DEFINITION_SCHEMA, + cron: '0 * * * *', // Every hour, on the hour. + }, + handler: async ({ payload, io }) => { + const handler = await import('./sync-email-domains.handler'); + + await handler.run({ payload, io }); + }, +} as const satisfies JobDefinition< + typeof SYNC_EMAIL_DOMAINS_JOB_DEFINITION_ID, + TSyncEmailDomainsJobDefinition +>; diff --git a/packages/lib/translations/de/web.po b/packages/lib/translations/de/web.po index 5ff0955fb..21569537a 100644 --- a/packages/lib/translations/de/web.po +++ b/packages/lib/translations/de/web.po @@ -2764,6 +2764,10 @@ msgstr "Fahre fort, indem du das Dokument ansiehst." msgid "Continue to login" msgstr "Weiter zum Login" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Kontrolliert die Standard-E-Mail-Einstellungen, wenn neue Dokumente oder Vorlagen erstellt werden." @@ -3123,6 +3127,10 @@ msgstr "Derzeit können E-Mail-Domains nur für Plattform- und höhere Pläne ko msgid "Custom {0} MB file" msgstr "Benutzerdefinierte {0} MB-Datei" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Benutzerdefinierte Organisationsgruppen" @@ -3165,6 +3173,10 @@ msgstr "Datumseinstellungen" msgid "David is the Employee, Lucas is the Manager" msgstr "David ist der Mitarbeiter, Lucas ist der Manager" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "Standard-E-Mail" msgid "Default Email Settings" msgstr "Standard-E-Mail-Einstellungen" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Standarddatei" @@ -3943,6 +3959,7 @@ msgstr "Dokumentation" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "Alle haben unterschrieben! Sie erhalten eine Kopie des unterschriebenen msgid "Exceeded timeout" msgstr "Zeitüberschreitung überschritten" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Abgelaufen" @@ -4744,6 +4766,11 @@ msgstr "Abgelaufen" msgid "Expires" msgstr "Läuft ab" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Startseite (kein Ordner)" msgid "Horizontal" msgstr "Horizontal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Ich bin einverstanden, mein Konto mit dieser Organisation zu verknüpfen." @@ -5385,6 +5416,10 @@ msgstr "Audit-Logs im Dokument einbeziehen" msgid "Include the Signing Certificate in the Document" msgstr "Signaturzertifikat in das Dokument einfügen" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Authentifizierungsmethode erben" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Ungültige Domains" msgid "Invalid email" msgstr "Ungültige E-Mail" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Ungültiger Lizenzschlüssel" @@ -5814,6 +5854,8 @@ msgstr "Lade Vorschläge ..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Wird geladen..." @@ -6120,6 +6162,10 @@ msgstr "Monatlich aktive Benutzer: Benutzer, die mindestens ein Dokument erstell msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Monatlich aktive Benutzer: Benutzer, die mindestens eines ihrer Dokumente abgeschlossen haben" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Niemals" msgid "Never expire" msgstr "Nie ablaufen" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Neues Passwort" @@ -6442,6 +6492,10 @@ msgstr "Keine (überschreibt globale Einstellungen)" msgid "Not found" msgstr "Nicht gefunden" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Nicht unterstützt" @@ -6852,6 +6906,7 @@ msgstr "Zahlung überfällig" msgid "PDF Document" msgstr "PDF-Dokument" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Bitte prüfen Sie die CSV-Datei und stellen Sie sicher, dass sie unserem Format entspricht" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Bitte überprüfen Sie bei der übergeordneten Anwendung weitere Informationen." @@ -7406,6 +7462,10 @@ msgstr "Der Empfänger hat das Dokument in CC gesetzt" msgid "Recipient completed their task" msgstr "Der Empfänger hat seine Aufgabe abgeschlossen" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Dem Empfänger ist es nicht gelungen, ein 2FA-Token für das Dokument zu verifizieren" @@ -7434,6 +7494,11 @@ msgstr "Der Empfänger hat das Dokument unterschrieben" msgid "Recipient signing request email" msgstr "E-Mail zur Unterzeichnungsanfrage des Empfängers" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Empfänger aktualisiert" @@ -7789,6 +7854,7 @@ msgstr "Wiederholen" msgid "Return" msgstr "Zurück" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Dokumente sofort an Empfänger senden" msgid "Send on Behalf of Team" msgstr "Im Namen des Teams senden" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Unterzeichnungszertifikat bereitgestellt von" msgid "Signing Complete!" msgstr "Unterzeichnung abgeschlossen!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Unterzeichne für" @@ -8540,6 +8614,26 @@ msgstr "Unterzeichnungslinks wurden für dieses Dokument erstellt." msgid "Signing order is enabled." msgstr "Unterzeichnungsreihenfolge ist aktiviert." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Registrierungen sind deaktiviert." @@ -9489,6 +9583,10 @@ msgstr "Die E-Mail des Unterzeichners" msgid "The signer's name" msgstr "Der Name des Unterzeichners" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "Der Name des Unterzeichners" msgid "The signing link has been copied to your clipboard." msgstr "Der Signierlink wurde in die Zwischenablage kopiert." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "Das Seitenbanner ist eine Nachricht, die oben auf der Seite angezeigt wird. Es kann verwendet werden, um Ihren Nutzern wichtige Informationen anzuzeigen." @@ -9861,6 +9967,10 @@ msgstr "Dies wird an alle Empfänger gesendet, sobald das Dokument vollständig msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Dies wird an den Dokumenteneigentümer gesendet, sobald das Dokument vollständig abgeschlossen wurde." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Dadurch werden der Status aller E-Mail-Domains dieser Organisation überprüft und synchronisiert." @@ -10792,6 +10902,7 @@ msgstr "Dokument anzeigen" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "Webhook-URL" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Willkommen" @@ -11404,6 +11519,10 @@ msgstr "Schreiben Sie eine Beschreibung, die in Ihrem öffentlichen Profil angez msgid "Yearly" msgstr "Jährlich" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Ihr Wiederherstellungscode wurde in die Zwischenablage kopiert." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Ihre Wiederherstellungscodes sind unten aufgeführt. Bitte bewahren Sie sie an einem sicheren Ort auf." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Ihre Support-Anfrage wurde eingereicht. Wir werden uns bald bei Ihnen melden!" @@ -12446,4 +12569,3 @@ msgstr "Ihr Verifizierungscode:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/en/web.po b/packages/lib/translations/en/web.po index 5fe7130bb..092118758 100644 --- a/packages/lib/translations/en/web.po +++ b/packages/lib/translations/en/web.po @@ -2759,6 +2759,10 @@ msgstr "Continue by viewing the document." msgid "Continue to login" msgstr "Continue to login" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Controls the default email settings when new documents or templates are created" @@ -3118,6 +3122,10 @@ msgstr "Currently email domains can only be configured for Platform and above pl msgid "Custom {0} MB file" msgstr "Custom {0} MB file" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "Custom duration" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Custom Organisation Groups" @@ -3160,6 +3168,10 @@ msgstr "Date Settings" msgid "David is the Employee, Lucas is the Manager" msgstr "David is the Employee, Lucas is the Manager" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "Days" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3186,6 +3198,10 @@ msgstr "Default Email" msgid "Default Email Settings" msgstr "Default Email Settings" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "Default Envelope Expiration" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Default file" @@ -3938,6 +3954,7 @@ msgstr "Documentation" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4298,6 +4315,22 @@ msgstr "Email Preferences" msgid "Email preferences updated" msgstr "Email preferences updated" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when a pending document is deleted" +msgstr "Email recipients when a pending document is deleted" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when the document is completed" +msgstr "Email recipients when the document is completed" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when they're removed from a pending document" +msgstr "Email recipients when they're removed from a pending document" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients with a signing request" +msgstr "Email recipients with a signing request" + #: packages/lib/utils/document-audit-logs.ts msgctxt "Audit log format" msgid "Email resent" @@ -4323,6 +4356,18 @@ msgstr "Email sent!" msgid "Email Settings" msgstr "Email Settings" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the owner when a recipient signs" +msgstr "Email the owner when a recipient signs" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the owner when the document is completed" +msgstr "Email the owner when the document is completed" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the signer if the document is still pending" +msgstr "Email the signer if the document is still pending" + #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Email verification" msgstr "Email verification" @@ -4698,6 +4743,11 @@ msgstr "Everyone has signed! You will receive an email copy of the signed docume msgid "Exceeded timeout" msgstr "Exceeded timeout" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "Expiration" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Expired" @@ -4711,6 +4761,11 @@ msgstr "Expired" msgid "Expires" msgstr "Expires" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "Expires {0}" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5250,6 +5305,10 @@ msgstr "Home (No Folder)" msgid "Horizontal" msgstr "Horizontal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "I agree to link my account with this organization" @@ -5352,6 +5411,10 @@ msgstr "Include the Audit Logs in the Document" msgid "Include the Signing Certificate in the Document" msgstr "Include the Signing Certificate in the Document" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "Includes:" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5373,6 +5436,7 @@ msgstr "Inherit authentication method" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5428,6 +5492,10 @@ msgstr "Invalid domains" msgid "Invalid email" msgstr "Invalid email" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "Invalid embedding presign token provided" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Invalid License Key" @@ -5781,6 +5849,8 @@ msgstr "Loading suggestions..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Loading..." @@ -6087,6 +6157,10 @@ msgstr "Monthly Active Users: Users that created at least one Document" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Monthly Active Users: Users that had at least one of their documents completed" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "Months" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6208,6 +6282,10 @@ msgstr "Never" msgid "Never expire" msgstr "Never expire" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "Never expires" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "New Password" @@ -6409,6 +6487,10 @@ msgstr "None (Overrides global settings)" msgid "Not found" msgstr "Not found" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "Not Found" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Not supported" @@ -6819,6 +6901,7 @@ msgstr "Payment overdue" msgid "PDF Document" msgstr "PDF Document" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6934,6 +7017,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Please check the CSV file and make sure it is according to our format" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Please check with the parent application for more information." @@ -7373,6 +7457,10 @@ msgstr "Recipient CC'd the document" msgid "Recipient completed their task" msgstr "Recipient completed their task" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "Recipient expired email" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Recipient failed to validate a 2FA token for the document" @@ -7401,6 +7489,11 @@ msgstr "Recipient signed the document" msgid "Recipient signing request email" msgstr "Recipient signing request email" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "Recipient signing window expired" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Recipient updated" @@ -7756,6 +7849,7 @@ msgstr "Retry" msgid "Return" msgstr "Return" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8164,22 +8258,6 @@ msgstr "Send document" msgid "Send Document" msgstr "Send Document" -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document completed email" -msgstr "Send document completed email" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document completed email to the owner" -msgstr "Send document completed email to the owner" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document deleted email" -msgstr "Send document deleted email" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document pending email" -msgstr "Send document pending email" - #: packages/email/templates/confirm-team-email.tsx msgid "Send documents on behalf of the team using the email address" msgstr "Send documents on behalf of the team using the email address" @@ -8193,16 +8271,8 @@ msgid "Send on Behalf of Team" msgstr "Send on Behalf of Team" #: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient removed email" -msgstr "Send recipient removed email" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient signed email" -msgstr "Send recipient signed email" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient signing request email" -msgstr "Send recipient signing request email" +msgid "Send recipient expired email to the owner" +msgstr "Send recipient expired email to the owner" #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx @@ -8511,6 +8581,10 @@ msgstr "Signing certificate provided by" msgid "Signing Complete!" msgstr "Signing Complete!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "Signing Deadline Expired" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Signing for" @@ -8535,6 +8609,26 @@ msgstr "Signing links have been generated for this document." msgid "Signing order is enabled." msgstr "Signing order is enabled." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "Signing Window Expired" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "Signing window expired for \"{0}\" on \"{1}\"" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "Signing window expired for \"{displayName}\" on \"{documentName}\"" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "Signing window expired for {0}" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Signups are disabled." @@ -9484,6 +9578,10 @@ msgstr "The signer's email" msgid "The signer's name" msgstr "The signer's name" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9491,6 +9589,14 @@ msgstr "The signer's name" msgid "The signing link has been copied to your clipboard." msgstr "The signing link has been copied to your clipboard." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." @@ -9856,6 +9962,10 @@ msgstr "This will be sent to all recipients once the document has been fully com msgid "This will be sent to the document owner once the document has been fully completed." msgstr "This will be sent to the document owner once the document has been fully completed." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "This will be sent to the document owner when a recipient's signing window has expired." + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "This will check and sync the status of all email domains for this organisation" @@ -10787,6 +10897,7 @@ msgstr "View document" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11314,6 +11425,10 @@ msgstr "Webhook URL" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "Weeks" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Welcome" @@ -11399,6 +11514,10 @@ msgstr "Write a description to display on your public profile" msgid "Yearly" msgstr "Yearly" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "Years" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12373,6 +12492,10 @@ msgstr "Your recovery code has been copied to your clipboard." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Your recovery codes are listed below. Please store them in a safe place." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "Your signing window for this document has expired. Please contact the sender for a new invitation." + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Your support request has been submitted. We'll get back to you soon!" diff --git a/packages/lib/translations/es/web.po b/packages/lib/translations/es/web.po index 4d5204d29..d2dc9238e 100644 --- a/packages/lib/translations/es/web.po +++ b/packages/lib/translations/es/web.po @@ -2764,6 +2764,10 @@ msgstr "Continúa viendo el documento." msgid "Continue to login" msgstr "Continuar con el inicio de sesión" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Controla la configuración de correo electrónico predeterminada cuando se crean nuevos documentos o plantillas" @@ -3123,6 +3127,10 @@ msgstr "Actualmente los dominios de correo electrónico solo se pueden configura msgid "Custom {0} MB file" msgstr "Archivo personalizado de {0} MB" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Grupos de Organización Personalizados" @@ -3165,6 +3173,10 @@ msgstr "Configuración de Fecha" msgid "David is the Employee, Lucas is the Manager" msgstr "David es el empleado, Lucas es el gerente" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "Correo predeterminado" msgid "Default Email Settings" msgstr "Configuración de correo predeterminada" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Archivo por defecto" @@ -3943,6 +3959,7 @@ msgstr "Documentación" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "¡Todos han firmado! Recibirás una copia del documento firmado por corr msgid "Exceeded timeout" msgstr "Tiempo de espera excedido" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Expirado" @@ -4744,6 +4766,11 @@ msgstr "Vencida" msgid "Expires" msgstr "Vence" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Inicio (Sin Carpeta)" msgid "Horizontal" msgstr "Horizontal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Acepto vincular mi cuenta con esta organización" @@ -5385,6 +5416,10 @@ msgstr "Incluir los registros de auditoría en el documento" msgid "Include the Signing Certificate in the Document" msgstr "Incluir el certificado de firma en el documento" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Heredar método de autenticación" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Dominios no válidos" msgid "Invalid email" msgstr "Email inválido" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Clave de licencia no válida" @@ -5814,6 +5854,8 @@ msgstr "Cargando sugerencias..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Cargando..." @@ -6120,6 +6162,10 @@ msgstr "Usuarios activos mensuales: Usuarios que crearon al menos un documento" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Usuarios activos mensuales: Usuarios que completaron al menos uno de sus documentos" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Nunca" msgid "Never expire" msgstr "Nunca expira" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nueva Contraseña" @@ -6442,6 +6492,10 @@ msgstr "Ninguno (anula la configuración global)" msgid "Not found" msgstr "No Encontrado" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "No soportado" @@ -6852,6 +6906,7 @@ msgstr "Pago atrasado" msgid "PDF Document" msgstr "Documento PDF" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Por favor, revisa el archivo CSV y asegúrate de que esté de acuerdo con nuestro formato" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Por favor consulta con la aplicación principal para obtener más información." @@ -7406,6 +7462,10 @@ msgstr "El destinatario envió una copia del documento" msgid "Recipient completed their task" msgstr "El destinatario completó su tarea" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "El destinatario no pudo validar un token 2FA para el documento" @@ -7434,6 +7494,11 @@ msgstr "El destinatario firmó el documento" msgid "Recipient signing request email" msgstr "Correo electrónico de solicitud de firma de destinatario" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Destinatario actualizado" @@ -7789,6 +7854,7 @@ msgstr "Reintentar" msgid "Return" msgstr "Regresar" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Enviar documentos a los destinatarios inmediatamente" msgid "Send on Behalf of Team" msgstr "Enviar en nombre del equipo" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Certificado de firma proporcionado por" msgid "Signing Complete!" msgstr "¡Firma completa!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Firmando para" @@ -8540,6 +8614,26 @@ msgstr "Se han generado enlaces de firma para este documento." msgid "Signing order is enabled." msgstr "El orden de firma está habilitado." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Las inscripciones están deshabilitadas." @@ -9489,6 +9583,10 @@ msgstr "El correo electrónico del firmante" msgid "The signer's name" msgstr "El nombre del firmante" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "El nombre del firmante" msgid "The signing link has been copied to your clipboard." msgstr "El enlace de firma ha sido copiado a tu portapapeles." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "El banner del sitio es un mensaje que se muestra en la parte superior del sitio. Se puede usar para mostrar información importante a tus usuarios." @@ -9861,6 +9967,10 @@ msgstr "Esto se enviará a todos los destinatarios una vez que el documento est msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Esto se enviará al propietario del documento una vez que el documento se haya completado por completo." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Esto verificará y sincronizará el estado de todos los dominios de correo electrónico para esta organización." @@ -10792,6 +10902,7 @@ msgstr "Ver documento" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "URL del Webhook" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Bienvenido" @@ -11404,6 +11519,10 @@ msgstr "Escribe una descripción para mostrar en tu perfil público" msgid "Yearly" msgstr "Anual" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Tu código de recuperación ha sido copiado en tu portapapeles." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Tus códigos de recuperación se enumeran a continuación. Por favor, guárdalos en un lugar seguro." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Su solicitud de soporte ha sido enviada. ¡Nos pondremos en contacto contigo pronto!" @@ -12446,4 +12569,3 @@ msgstr "Su código de verificación:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "su-dominio.com otro-dominio.com" - diff --git a/packages/lib/translations/fr/web.po b/packages/lib/translations/fr/web.po index e50169b1c..f31d82699 100644 --- a/packages/lib/translations/fr/web.po +++ b/packages/lib/translations/fr/web.po @@ -2764,6 +2764,10 @@ msgstr "Continuer en consultant le document." msgid "Continue to login" msgstr "Continuer vers la connexion" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Contrôler les paramètres de messagerie par défaut lors de la création de nouveaux documents ou modèles" @@ -3123,6 +3127,10 @@ msgstr "Actuellement, les domaines de messagerie ne peuvent être configurés qu msgid "Custom {0} MB file" msgstr "Fichier personnalisé de {0} Mo" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Groupes d'organisation personnalisés" @@ -3165,6 +3173,10 @@ msgstr "Paramètres de la date" msgid "David is the Employee, Lucas is the Manager" msgstr "David est l'employé, Lucas est le manager" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "E-mail par défaut" msgid "Default Email Settings" msgstr "Paramètres d'e-mail par défaut" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Fichier par défaut" @@ -3943,6 +3959,7 @@ msgstr "Documentation" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "Tout le monde a signé ! Vous recevrez une copie du document signé par msgid "Exceeded timeout" msgstr "Délai dépassé" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Expiré" @@ -4744,6 +4766,11 @@ msgstr "Expiré" msgid "Expires" msgstr "Expire le" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Accueil (Pas de Dossier)" msgid "Horizontal" msgstr "Horizontal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "J'accepte de lier mon compte avec cette organisation" @@ -5385,6 +5416,10 @@ msgstr "Inclure les journaux d'audit dans le document" msgid "Include the Signing Certificate in the Document" msgstr "Includez le certificat de signature dans le document" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Hériter de la méthode d'authentification" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Domaines invalides" msgid "Invalid email" msgstr "Email invalide" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Clé de licence invalide" @@ -5814,6 +5854,8 @@ msgstr "Chargement des suggestions..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Chargement..." @@ -6120,6 +6162,10 @@ msgstr "Utilisateurs actifs mensuels : utilisateurs ayant créé au moins un doc msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Utilisateurs actifs mensuels : utilisateurs ayant terminé au moins un de leurs documents" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Jamais" msgid "Never expire" msgstr "Ne jamais expirer" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nouveau Mot de Passe" @@ -6442,6 +6492,10 @@ msgstr "Aucun (remplace les paramètres globaux)" msgid "Not found" msgstr "Non trouvé" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Non pris en charge" @@ -6852,6 +6906,7 @@ msgstr "Paiement en retard" msgid "PDF Document" msgstr "Document PDF" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Veuillez vérifier le fichier CSV et vous assurer qu'il est conforme à notre format" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Veuillez vérifier auprès de l'application parent pour plus d'informations." @@ -7406,6 +7462,10 @@ msgstr "Le destinataire a mis le document en copie" msgid "Recipient completed their task" msgstr "Le destinataire a terminé sa tâche" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Le destinataire n'a pas réussi à valider un jeton 2FA pour le document" @@ -7434,6 +7494,11 @@ msgstr "Le destinataire a signé le document" msgid "Recipient signing request email" msgstr "E-mail de demande de signature de destinataire" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Destinataire mis à jour" @@ -7789,6 +7854,7 @@ msgstr "Réessayer" msgid "Return" msgstr "Retour" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Envoyer les documents aux destinataires immédiatement" msgid "Send on Behalf of Team" msgstr "Envoyer au nom de l'équipe" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Certificat de signature fourni par" msgid "Signing Complete!" msgstr "Signature Complète !" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Signé pour" @@ -8540,6 +8614,26 @@ msgstr "Des liens de signature ont été générés pour ce document." msgid "Signing order is enabled." msgstr "L'ordre de signature est activé." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Les inscriptions sont désactivées." @@ -9489,6 +9583,10 @@ msgstr "L'email du signataire" msgid "The signer's name" msgstr "Le nom du signataire" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "Le nom du signataire" msgid "The signing link has been copied to your clipboard." msgstr "Le lien de signature a été copié dans votre presse-papiers." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "La bannière du site est un message affiché en haut du site. Elle peut être utilisée pour afficher des informations importantes à vos utilisateurs." @@ -9861,6 +9967,10 @@ msgstr "Cela sera envoyé à tous les destinataires une fois que le document aur msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Cela sera envoyé au propriétaire du document une fois que le document aura été entièrement complété." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Cela vérifiera et synchronisera l'état de tous les domaines de messagerie de cette organisation" @@ -10792,6 +10902,7 @@ msgstr "Voir le document" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "URL du webhook" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Bienvenue" @@ -11404,6 +11519,10 @@ msgstr "Écrivez une description à afficher sur votre profil public" msgid "Yearly" msgstr "Annuel" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Votre code de récupération a été copié dans votre presse-papiers." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Vos codes de récupération sont listés ci-dessous. Veuillez les conserver dans un endroit sûr." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Votre demande de support a été soumise. Nous vous recontacterons bientôt !" @@ -12446,4 +12569,3 @@ msgstr "Votre code de vérification :" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/it/web.po b/packages/lib/translations/it/web.po index ff5878a7b..2fb764ae3 100644 --- a/packages/lib/translations/it/web.po +++ b/packages/lib/translations/it/web.po @@ -2764,6 +2764,10 @@ msgstr "Continua visualizzando il documento." msgid "Continue to login" msgstr "Continua per accedere" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Controlla le impostazioni email predefinite quando vengono creati nuovi documenti o modelli" @@ -3123,6 +3127,10 @@ msgstr "Attualmente i domini email possono essere configurati solo per i piani P msgid "Custom {0} MB file" msgstr "File personalizzato da {0} MB" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Gruppi di Organizzazione Personalizzati" @@ -3165,6 +3173,10 @@ msgstr "Impostazioni della data" msgid "David is the Employee, Lucas is the Manager" msgstr "David è il dipendente, Lucas è il manager" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "Email Predefinita" msgid "Default Email Settings" msgstr "Impostazioni Email Predefinite" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "File predefinito" @@ -3943,6 +3959,7 @@ msgstr "Documentazione" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "Tutti hanno firmato! Riceverai una copia del documento firmato via email msgid "Exceeded timeout" msgstr "Tempo scaduto" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Scaduto" @@ -4744,6 +4766,11 @@ msgstr "Scaduto" msgid "Expires" msgstr "Scade" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Home (Nessuna Cartella)" msgid "Horizontal" msgstr "Orizzontale" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Accetto di collegare il mio account con questa organizzazione" @@ -5385,6 +5416,10 @@ msgstr "Includi i Registri di Audit nel Documento" msgid "Include the Signing Certificate in the Document" msgstr "Includi il certificato di firma nel documento" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Ereditare metodo di autenticazione" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Domini non validi" msgid "Invalid email" msgstr "Email non valida" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Chiave di licenza non valida" @@ -5814,6 +5854,8 @@ msgstr "Caricamento suggerimenti..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Caricamento in corso..." @@ -6120,6 +6162,10 @@ msgstr "Utenti attivi mensili: Utenti che hanno creato almeno un documento" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Utenti attivi mensili: Utenti con almeno uno dei loro documenti completati" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Mai" msgid "Never expire" msgstr "Mai scadere" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nuova Password" @@ -6442,6 +6492,10 @@ msgstr "Nessuno (sovrascrive le impostazioni globali)" msgid "Not found" msgstr "Non trovato" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Non supportato" @@ -6852,6 +6906,7 @@ msgstr "Pagamento scaduto" msgid "PDF Document" msgstr "Documento PDF" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Si prega di controllare il file CSV e assicurarsi che sia conforme al nostro formato" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Controlla con l'applicazione principale per ulteriori informazioni." @@ -7406,6 +7462,10 @@ msgstr "Il destinatario ha messo in CC il documento" msgid "Recipient completed their task" msgstr "Il destinatario ha completato la propria attività" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Il destinatario non è riuscito a convalidare un token 2FA per il documento" @@ -7434,6 +7494,11 @@ msgstr "Il destinatario ha firmato il documento" msgid "Recipient signing request email" msgstr "Email richiesta firma destinatario" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Destinatario aggiornato" @@ -7789,6 +7854,7 @@ msgstr "Riprova" msgid "Return" msgstr "Ritorna" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Invia documenti ai destinatari immediatamente" msgid "Send on Behalf of Team" msgstr "Invia per conto del team" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Certificato di firma fornito da" msgid "Signing Complete!" msgstr "Firma completata!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Firma per" @@ -8540,6 +8614,26 @@ msgstr "I link di firma sono stati generati per questo documento." msgid "Signing order is enabled." msgstr "L'ordine di firma è abilitato." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Le iscrizioni sono disabilitate." @@ -9489,6 +9583,10 @@ msgstr "L'email del firmatario" msgid "The signer's name" msgstr "Il nome del firmatario" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "Il nome del firmatario" msgid "The signing link has been copied to your clipboard." msgstr "Il link di firma è stato copiato negli appunti." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "Il banner del sito è un messaggio che viene mostrato in cima al sito. Può essere utilizzato per visualizzare informazioni importanti ai tuoi utenti." @@ -9861,6 +9967,10 @@ msgstr "Questo sarà inviato a tutti i destinatari una volta che il documento è msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Questo sarà inviato al proprietario del documento una volta che il documento è stato completamente completato." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Questo controllerà e sincronizzerà lo stato di tutti i domini email per questa organizzazione" @@ -10792,6 +10902,7 @@ msgstr "Visualizza documento" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "URL del webhook" msgid "Webhooks" msgstr "Webhook" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Benvenuto" @@ -11404,6 +11519,10 @@ msgstr "Scrivi una descrizione da mostrare sul tuo profilo pubblico" msgid "Yearly" msgstr "Annuale" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Il tuo codice di recupero è stato copiato negli appunti." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "I tuoi codici di recupero sono elencati di seguito. Si prega di conservarli in un luogo sicuro." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "La tua richiesta di supporto è stata inviata. Ti contatteremo presto!" @@ -12446,4 +12569,3 @@ msgstr "Il tuo codice di verifica:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "tuo-dominio.com altro-dominio.com" - diff --git a/packages/lib/translations/ja/web.po b/packages/lib/translations/ja/web.po index c0f1f71f4..e21daaafb 100644 --- a/packages/lib/translations/ja/web.po +++ b/packages/lib/translations/ja/web.po @@ -2764,6 +2764,10 @@ msgstr "ドキュメントを表示して続行してください。" msgid "Continue to login" msgstr "ログインを続ける" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "新しいドキュメントやテンプレートを作成する際の既定のメール設定を制御します" @@ -3123,6 +3127,10 @@ msgstr "現在、メールドメインは Platform プラン以上のみ設定 msgid "Custom {0} MB file" msgstr "カスタム {0} MB ファイル" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "カスタム組織グループ" @@ -3165,6 +3173,10 @@ msgstr "日付設定" msgid "David is the Employee, Lucas is the Manager" msgstr "David は従業員で、Lucas はマネージャーです" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "既定のメール" msgid "Default Email Settings" msgstr "既定のメール設定" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "デフォルトのファイル" @@ -3943,6 +3959,7 @@ msgstr "ドキュメント" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "全員が署名しました。署名済みドキュメントのコピー msgid "Exceeded timeout" msgstr "タイムアウトを超えました" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "有効期限切れ" @@ -4744,6 +4766,11 @@ msgstr "有効期限切れ" msgid "Expires" msgstr "有効期限" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "ホーム(フォルダなし)" msgid "Horizontal" msgstr "横" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "この組織と自分のアカウントをリンクすることに同意します" @@ -5385,6 +5416,10 @@ msgstr "監査ログをドキュメントに含める" msgid "Include the Signing Certificate in the Document" msgstr "署名証明書をドキュメントに含める" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "認証方法を継承" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "無効なドメイン" msgid "Invalid email" msgstr "無効なメールアドレスです" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "無効なライセンスキー" @@ -5814,6 +5854,8 @@ msgstr "候補を読み込み中..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "読み込み中..." @@ -6120,6 +6162,10 @@ msgstr "月間アクティブユーザー:1 つ以上の文書を作成した msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "月間アクティブユーザー:1 つ以上の文書が完了したユーザー" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "なし" msgid "Never expire" msgstr "有効期限なし" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "新しいパスワード" @@ -6442,6 +6492,10 @@ msgstr "なし(グローバル設定を上書き)" msgid "Not found" msgstr "見つかりません" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "サポートされていません" @@ -6852,6 +6906,7 @@ msgstr "支払い期限超過" msgid "PDF Document" msgstr "PDF文書" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "CSV ファイルが当社のフォーマットに従っているか確認してください" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "詳細については、親アプリケーションを確認してください。" @@ -7406,6 +7462,10 @@ msgstr "受信者が文書のCCに追加されました" msgid "Recipient completed their task" msgstr "受信者が自分のタスクを完了しました" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "受信者は文書用の2要素認証トークンを検証できませんでした" @@ -7434,6 +7494,11 @@ msgstr "受信者が文書に署名しました" msgid "Recipient signing request email" msgstr "受信者署名依頼メール" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "受信者を更新しました" @@ -7789,6 +7854,7 @@ msgstr "再試行" msgid "Return" msgstr "戻る" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "ドキュメントをすぐに受信者へ送信する" msgid "Send on Behalf of Team" msgstr "チームを代表して送信" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "署名証明書の提供元" msgid "Signing Complete!" msgstr "署名が完了しました" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "署名対象" @@ -8540,6 +8614,26 @@ msgstr "この文書の署名リンクが生成されています。" msgid "Signing order is enabled." msgstr "署名順序が有効になっています。" +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "サインアップは無効になっています。" @@ -9489,6 +9583,10 @@ msgstr "署名者のメールアドレス" msgid "The signer's name" msgstr "署名者の名前" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "署名者の名前" msgid "The signing link has been copied to your clipboard." msgstr "署名用リンクをクリップボードにコピーしました。" +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "サイトバナーはサイト上部に表示されるメッセージです。ユーザーに重要なお知らせを表示するために利用できます。" @@ -9861,6 +9967,10 @@ msgstr "ドキュメントが完全に完了した後、これはすべての受 msgid "This will be sent to the document owner once the document has been fully completed." msgstr "ドキュメントが完全に完了した後、これはドキュメント所有者に送信されます。" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "この操作により、この組織のすべてのメールドメインのステータスをチェックして同期します。" @@ -10792,6 +10902,7 @@ msgstr "ドキュメントを表示" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "Webhook URL" msgid "Webhooks" msgstr "Webhook" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "ようこそ" @@ -11404,6 +11519,10 @@ msgstr "公開プロフィールに表示する説明文を入力してくださ msgid "Yearly" msgstr "年額" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "リカバリーコードをクリップボードにコピーしました msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "リカバリーコードは以下のとおりです。安全な場所に保管してください。" +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "サポートリクエストを送信しました。追ってご連絡いたします。" @@ -12446,4 +12569,3 @@ msgstr "認証コード:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/ko/web.po b/packages/lib/translations/ko/web.po index a88d84d15..6e6953450 100644 --- a/packages/lib/translations/ko/web.po +++ b/packages/lib/translations/ko/web.po @@ -2764,6 +2764,10 @@ msgstr "문서를 열람하여 계속 진행하세요." msgid "Continue to login" msgstr "로그인으로 이동" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "새 문서 또는 템플릿을 생성할 때 사용할 기본 이메일 설정을 제어합니다." @@ -3123,6 +3127,10 @@ msgstr "현재 이메일 도메인은 Platform 요금제 이상에서만 구성 msgid "Custom {0} MB file" msgstr "사용자 정의 {0} MB 파일" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "사용자 지정 조직 그룹" @@ -3165,6 +3173,10 @@ msgstr "날짜 설정" msgid "David is the Employee, Lucas is the Manager" msgstr "David는 직원이고, Lucas는 관리자입니다." +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "기본 이메일" msgid "Default Email Settings" msgstr "기본 이메일 설정" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "기본 파일" @@ -3943,6 +3959,7 @@ msgstr "문서" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "모두 서명했습니다! 서명된 문서의 사본이 이메일로 msgid "Exceeded timeout" msgstr "시간 초과됨" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "만료됨" @@ -4744,6 +4766,11 @@ msgstr "만료됨" msgid "Expires" msgstr "만료일" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "홈(폴더 없음)" msgid "Horizontal" msgstr "가로" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "이 조직과 계정을 연결하는 데 동의합니다" @@ -5385,6 +5416,10 @@ msgstr "문서에 감사 로그 포함" msgid "Include the Signing Certificate in the Document" msgstr "문서에 서명 인증서 포함" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "인증 방식 상속" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "잘못된 도메인" msgid "Invalid email" msgstr "유효한 이메일이 아닙니다." +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "잘못된 라이선스 키" @@ -5814,6 +5854,8 @@ msgstr "제안 불러오는 중..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "로딩 중..." @@ -6120,6 +6162,10 @@ msgstr "월간 활성 사용자: 문서를 하나 이상 생성한 사용자" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "월간 활성 사용자: 문서가 하나 이상 완료된 사용자" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "없음" msgid "Never expire" msgstr "만료되지 않음" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "새 비밀번호" @@ -6442,6 +6492,10 @@ msgstr "없음(전역 설정 무시)" msgid "Not found" msgstr "찾을 수 없음" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "지원되지 않습니다" @@ -6852,6 +6906,7 @@ msgstr "결제 지연" msgid "PDF Document" msgstr "PDF 문서" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "CSV 파일 형식을 확인하고, 안내된 형식과 일치하는지 확인해 주세요" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "자세한 정보는 상위 애플리케이션에서 확인해 주세요." @@ -7406,6 +7462,10 @@ msgstr "수신자가 문서의 참조(CC) 수신자가 되었습니다" msgid "Recipient completed their task" msgstr "수신자가 자신의 작업을 완료했습니다" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "수신자가 문서에 대한 2FA 토큰 검증에 실패했습니다" @@ -7434,6 +7494,11 @@ msgstr "수신자가 문서에 서명했습니다" msgid "Recipient signing request email" msgstr "수신자 서명 요청 이메일" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "수신자가 업데이트되었습니다" @@ -7789,6 +7854,7 @@ msgstr "재시도" msgid "Return" msgstr "돌아가기" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "생성된 문서를 즉시 수신자에게 전송" msgid "Send on Behalf of Team" msgstr "팀을 대신해 발송" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "서명 인증서 제공자" msgid "Signing Complete!" msgstr "서명이 완료되었습니다!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "대리 서명 대상" @@ -8540,6 +8614,26 @@ msgstr "이 문서에 대한 서명 링크가 생성되었습니다." msgid "Signing order is enabled." msgstr "서명 순서가 활성화되어 있습니다." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "회원 가입이 비활성화되어 있습니다." @@ -9489,6 +9583,10 @@ msgstr "서명자의 이메일" msgid "The signer's name" msgstr "서명자의 이름" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "서명자의 이름" msgid "The signing link has been copied to your clipboard." msgstr "서명 링크가 클립보드에 복사되었습니다." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "사이트 배너는 사이트 상단에 표시되는 메시지입니다. 사용자에게 중요한 정보를 표시하는 데 사용할 수 있습니다." @@ -9861,6 +9967,10 @@ msgstr "문서가 완전히 완료되면 모든 수신자에게 이 메일이 msgid "This will be sent to the document owner once the document has been fully completed." msgstr "문서가 완전히 완료되면 문서 소유자에게 이 메일이 전송됩니다." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "이 작업은 이 조직의 모든 이메일 도메인 상태를 확인하고 동기화합니다." @@ -10792,6 +10902,7 @@ msgstr "문서 보기" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "웹훅 URL" msgid "Webhooks" msgstr "웹훅" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "환영합니다" @@ -11404,6 +11519,10 @@ msgstr "공개 프로필에 표시될 설명을 작성하세요." msgid "Yearly" msgstr "연간" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "복구 코드가 클립보드에 복사되었습니다." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "아래에 복구 코드가 표시됩니다. 안전한 곳에 보관해 주세요." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "지원 요청이 제출되었습니다. 곧 다시 연락드리겠습니다!" @@ -12446,4 +12569,3 @@ msgstr "인증 코드:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/nl/web.po b/packages/lib/translations/nl/web.po index 9eb0d4230..fa6bbcb09 100644 --- a/packages/lib/translations/nl/web.po +++ b/packages/lib/translations/nl/web.po @@ -2764,6 +2764,10 @@ msgstr "Ga verder door het document te bekijken." msgid "Continue to login" msgstr "Doorgaan naar inloggen" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Bepaalt de standaard e-mailinstellingen wanneer nieuwe documenten of sjablonen worden aangemaakt" @@ -3123,6 +3127,10 @@ msgstr "E-maildomeinen kunnen momenteel alleen worden geconfigureerd voor Platfo msgid "Custom {0} MB file" msgstr "Aangepast {0} MB-bestand" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Aangepaste organisatiegroepen" @@ -3165,6 +3173,10 @@ msgstr "Datuminstellingen" msgid "David is the Employee, Lucas is the Manager" msgstr "David is de werknemer, Lucas is de manager" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "Standaard e-mailadres" msgid "Default Email Settings" msgstr "Standaarde-mailinstellingen" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Standaardbestand" @@ -3943,6 +3959,7 @@ msgstr "Documentatie" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "Iedereen heeft ondertekend! U ontvangt een kopie van het ondertekende do msgid "Exceeded timeout" msgstr "Time‑out overschreden" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Verlopen" @@ -4744,6 +4766,11 @@ msgstr "Verlopen" msgid "Expires" msgstr "Verloopt" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Home (geen map)" msgid "Horizontal" msgstr "Horizontaal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Ik ga akkoord met het koppelen van mijn account aan deze organisatie" @@ -5385,6 +5416,10 @@ msgstr "Auditlogs opnemen in het document" msgid "Include the Signing Certificate in the Document" msgstr "Het ondertekeningscertificaat opnemen in het document" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Authenticatiemethode overnemen" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Ongeldige domeinen" msgid "Invalid email" msgstr "Ongeldig e-mailadres" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Ongeldige licentiesleutel" @@ -5814,6 +5854,8 @@ msgstr "Suggesties laden..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Laden..." @@ -6120,6 +6162,10 @@ msgstr "Maandelijks actieve gebruikers: gebruikers die ten minste één document msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Maandelijks actieve gebruikers: gebruikers van wie ten minste één document is voltooid" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Nooit" msgid "Never expire" msgstr "Nooit verlopen" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nieuw wachtwoord" @@ -6442,6 +6492,10 @@ msgstr "Geen (Overschrijft globale instellingen)" msgid "Not found" msgstr "Niet gevonden" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Niet ondersteund" @@ -6852,6 +6906,7 @@ msgstr "Betaling achterstallig" msgid "PDF Document" msgstr "PDF-document" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Controleer het CSV‑bestand en zorg dat het overeenkomt met ons formaat" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Raadpleeg de hoofdapplicatie voor meer informatie." @@ -7406,6 +7462,10 @@ msgstr "Ontvanger heeft het document in CC gekregen" msgid "Recipient completed their task" msgstr "Ontvanger heeft zijn taak voltooid" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Ontvanger kon een 2FA-token voor het document niet valideren" @@ -7434,6 +7494,11 @@ msgstr "Ontvanger heeft het document ondertekend" msgid "Recipient signing request email" msgstr "E-mail voor ondertekeningsverzoek aan ontvanger" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Ontvanger bijgewerkt" @@ -7789,6 +7854,7 @@ msgstr "Opnieuw proberen" msgid "Return" msgstr "Terugkeren" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Documenten direct naar ontvangers verzenden" msgid "Send on Behalf of Team" msgstr "Verzenden namens team" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Ondertekeningscertificaat verstrekt door" msgid "Signing Complete!" msgstr "Ondertekening voltooid!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Ondertekenen voor" @@ -8540,6 +8614,26 @@ msgstr "Voor dit document zijn ondertekeningslinks gegenereerd." msgid "Signing order is enabled." msgstr "Ondertekeningsvolgorde is ingeschakeld." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Aanmeldingen zijn uitgeschakeld." @@ -9489,6 +9583,10 @@ msgstr "Het e-mailadres van de ondertekenaar" msgid "The signer's name" msgstr "De naam van de ondertekenaar" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "De naam van de ondertekenaar" msgid "The signing link has been copied to your clipboard." msgstr "De ondertekeningslink is naar je klembord gekopieerd." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "De sitebanner is een bericht dat bovenaan de site wordt weergegeven. Je kunt hiermee belangrijke informatie aan je gebruikers tonen." @@ -9861,6 +9967,10 @@ msgstr "Dit wordt verzonden naar alle ontvangers zodra het document volledig is msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Dit wordt verzonden naar de documenteigenaar zodra het document volledig is voltooid." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Hiermee wordt de status van alle e-maildomeinen voor deze organisatie gecontroleerd en gesynchroniseerd" @@ -10792,6 +10902,7 @@ msgstr "Document bekijken" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "Webhook‑URL" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Welkom" @@ -11404,6 +11519,10 @@ msgstr "Schrijf een beschrijving die op je openbare profiel wordt weergegeven" msgid "Yearly" msgstr "Jaarlijks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Je herstelcode is naar je klembord gekopieerd." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Je herstelcodes staan hieronder. Bewaar ze op een veilige plek." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Uw supportverzoek is ingediend. We nemen snel contact met u op!" @@ -12446,4 +12569,3 @@ msgstr "Uw verificatiecode:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/pl/web.po b/packages/lib/translations/pl/web.po index e19f6d7b8..68a9782e7 100644 --- a/packages/lib/translations/pl/web.po +++ b/packages/lib/translations/pl/web.po @@ -2764,6 +2764,10 @@ msgstr "Wyświetl dokument." msgid "Continue to login" msgstr "Przejdź do logowania" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Wybierz domyślne ustawienia wiadomości podczas tworzenia nowych dokumentów i szablonów" @@ -3123,6 +3127,10 @@ msgstr "Domeny możesz skonfigurować tylko w planie Platform lub wyższym." msgid "Custom {0} MB file" msgstr "Niestandardowy plik {0} MB" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Niestandardowe grupy w organizacji" @@ -3165,6 +3173,10 @@ msgstr "Ustawienia daty" msgid "David is the Employee, Lucas is the Manager" msgstr "David jest pracownikiem. Lucas jest managerem." +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "Domyślny adres e-mail" msgid "Default Email Settings" msgstr "Domyślne ustawienia adresu e-mail" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Domyślny plik" @@ -3943,6 +3959,7 @@ msgstr "Dokumentacja" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "Wszyscy podpisali! Otrzymasz wiadomość z podpisanym dokumentem." msgid "Exceeded timeout" msgstr "Przekroczono limit czasu" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Wygasł" @@ -4744,6 +4766,11 @@ msgstr "Wygasła" msgid "Expires" msgstr "Wygasa" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "Strona główna (brak folderu)" msgid "Horizontal" msgstr "Poziomo" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Zgadzam się połączyć moje konto z organizacją" @@ -5385,6 +5416,10 @@ msgstr "Dołącz dziennik logów do dokumentu" msgid "Include the Signing Certificate in the Document" msgstr "Dołącz certyfikat podpisu do dokumentu" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "Odziedzicz metodę uwierzytelniania" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "Domeny są nieprawidłowe" msgid "Invalid email" msgstr "Adres e-mail jest nieprawidłowy" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "Klucz licencyjny jest nieprawidłowy" @@ -5814,6 +5854,8 @@ msgstr "Ładowanie sugestii..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Ładowanie..." @@ -6120,6 +6162,10 @@ msgstr "Miesięczna liczba aktywnych użytkowników: Użytkownicy, którzy utwor msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Miesięczna liczba aktywnych użytkowników: Użytkownicy, którzy zakończyli co najmniej jeden dokument" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "Nigdy" msgid "Never expire" msgstr "Nigdy nie wygasa" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nowe hasło" @@ -6442,6 +6492,10 @@ msgstr "Brak (odziedzicz metodę uwierzytelniania)" msgid "Not found" msgstr "Strona nie została znaleziona" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Nieobsługiwane" @@ -6852,6 +6906,7 @@ msgstr "Zaległa płatność" msgid "PDF Document" msgstr "Dokument PDF" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Sprawdź plik CSV i upewnij się, że jest zgodny z wymaganym formatem" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Sprawdź instrukcje na stronie." @@ -7406,6 +7462,10 @@ msgstr "Odbiorca odebrał kopię dokumentu" msgid "Recipient completed their task" msgstr "Odbiorca zakończył swoje zadanie" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "Odbiorca nie zweryfikował kodu weryfikacyjnego dla dokumentu" @@ -7434,6 +7494,11 @@ msgstr "Odbiorca podpisał dokument" msgid "Recipient signing request email" msgstr "Wiadomość z prośbą o podpisanie" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Odbiorca został zaktualizowany" @@ -7789,6 +7854,7 @@ msgstr "Spróbuj ponownie" msgid "Return" msgstr "Wróć" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "Wyślij dokumenty do odbiorców natychmiast" msgid "Send on Behalf of Team" msgstr "Wyślij w imieniu zespołu" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "Certyfikat podpisu został dostarczony przez" msgid "Signing Complete!" msgstr "Podpisywanie zostało zakończone!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Podpisywanie w imieniu" @@ -8540,6 +8614,26 @@ msgstr "Linki do podpisywania zostały wygenerowane dla tego dokumentu." msgid "Signing order is enabled." msgstr "Kolejność podpisywania jest włączona." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Rejestracje są wyłączone." @@ -9489,6 +9583,10 @@ msgstr "Adres e-mail podpisującego" msgid "The signer's name" msgstr "Nazwa podpisującego" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "Nazwa podpisującego" msgid "The signing link has been copied to your clipboard." msgstr "Link do podpisywania został skopiowany do schowka." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "Baner strony internetowej to zawartość wyświetlana na górze strony. Może być używana do wyświetlania ważnych informacji użytkownikom." @@ -9861,6 +9967,10 @@ msgstr "Zostanie wysłana do wszystkich odbiorców po zakończeniu dokumentu." msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Zostanie wysłana do właściciela po zakończeniu dokumentu." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Spowoduje to synchronizowanie statusu wszystkich domen organizacji" @@ -10792,6 +10902,7 @@ msgstr "Wyświetl dokument" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "Adres URL webhooka" msgid "Webhooks" msgstr "Webhooki" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Witaj" @@ -11404,6 +11519,10 @@ msgstr "Wpisz opis, który będzie wyświetlany w profilu publicznym" msgid "Yearly" msgstr "Rocznie" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "Kod odzyskiwania został skopiowany do schowka." msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "To są Twoje kody odzyskiwania. Przechowuj je w bezpiecznym miejscu." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Zgłoszenie zostało wysłane. Skontaktujemy się z Tobą wkrótce!" @@ -12446,4 +12569,3 @@ msgstr "Twój kod weryfikacyjny:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/translations/pt-BR/web.po b/packages/lib/translations/pt-BR/web.po index d8889cc3e..b2db7d103 100644 --- a/packages/lib/translations/pt-BR/web.po +++ b/packages/lib/translations/pt-BR/web.po @@ -2759,6 +2759,10 @@ msgstr "Continue visualizando o documento." msgid "Continue to login" msgstr "Continuar para o login" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "Controla as configurações padrão de e-mail quando novos documentos ou modelos são criados" @@ -3118,6 +3122,10 @@ msgstr "Atualmente, domínios de e-mail só podem ser configurados para planos P msgid "Custom {0} MB file" msgstr "Arquivo personalizado de {0} MB" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "Grupos de Organização Personalizados" @@ -3160,6 +3168,10 @@ msgstr "Configurações de Data" msgid "David is the Employee, Lucas is the Manager" msgstr "David é o Funcionário, Lucas é o Gerente" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3186,6 +3198,10 @@ msgstr "E-mail Padrão" msgid "Default Email Settings" msgstr "Configurações de E-mail Padrão" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "Arquivo padrão" @@ -3938,6 +3954,7 @@ msgstr "Documentação" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4298,6 +4315,22 @@ msgstr "Preferências de E-mail" msgid "Email preferences updated" msgstr "Preferências de e-mail atualizadas" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when a pending document is deleted" +msgstr "" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when the document is completed" +msgstr "" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients when they're removed from a pending document" +msgstr "" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email recipients with a signing request" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgctxt "Audit log format" msgid "Email resent" @@ -4323,6 +4356,18 @@ msgstr "E-mail enviado!" msgid "Email Settings" msgstr "Configurações de E-mail" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the owner when a recipient signs" +msgstr "" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the owner when the document is completed" +msgstr "" + +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Email the signer if the document is still pending" +msgstr "" + #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Email verification" msgstr "Verificação de e-mail" @@ -4698,6 +4743,11 @@ msgstr "Todos assinaram! Você receberá uma cópia do documento assinado por e- msgid "Exceeded timeout" msgstr "Tempo limite excedido" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "Expirado" @@ -4711,6 +4761,11 @@ msgstr "" msgid "Expires" msgstr "" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5250,6 +5305,10 @@ msgstr "Início (Sem Pasta)" msgid "Horizontal" msgstr "Horizontal" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "Concordo em vincular minha conta a esta organização" @@ -5352,6 +5411,10 @@ msgstr "Incluir os Logs de Auditoria no Documento" msgid "Include the Signing Certificate in the Document" msgstr "Incluir o Certificado de Assinatura no Documento" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5373,6 +5436,7 @@ msgstr "Herdar método de autenticação" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5428,6 +5492,10 @@ msgstr "Domínios inválidos" msgid "Invalid email" msgstr "E-mail inválido" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "" @@ -5781,6 +5849,8 @@ msgstr "Carregando sugestões..." #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "Carregando..." @@ -6087,6 +6157,10 @@ msgstr "Usuários Ativos Mensais: Usuários que criaram pelo menos um Documento" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Usuários Ativos Mensais: Usuários que tiveram pelo menos um de seus documentos concluídos" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6208,6 +6282,10 @@ msgstr "Nunca" msgid "Never expire" msgstr "Nunca expirar" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "Nova Senha" @@ -6409,6 +6487,10 @@ msgstr "" msgid "Not found" msgstr "Não encontrado" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "Não suportado" @@ -6819,6 +6901,7 @@ msgstr "Pagamento em atraso" msgid "PDF Document" msgstr "Documento PDF" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6934,6 +7017,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "Por favor, verifique o arquivo CSV e certifique-se de que está de acordo com nosso formato" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "Por favor, verifique com o aplicativo principal para mais informações." @@ -7373,6 +7457,10 @@ msgstr "" msgid "Recipient completed their task" msgstr "" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "" @@ -7401,6 +7489,11 @@ msgstr "" msgid "Recipient signing request email" msgstr "E-mail de solicitação de assinatura do destinatário" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "Destinatário atualizado" @@ -7756,6 +7849,7 @@ msgstr "Tentar novamente" msgid "Return" msgstr "Retornar" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8164,22 +8258,6 @@ msgstr "Enviar documento" msgid "Send Document" msgstr "Enviar Documento" -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document completed email" -msgstr "Enviar e-mail de documento concluído" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document completed email to the owner" -msgstr "Enviar e-mail de documento concluído para o proprietário" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document deleted email" -msgstr "Enviar e-mail de documento excluído" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send document pending email" -msgstr "Enviar e-mail de documento pendente" - #: packages/email/templates/confirm-team-email.tsx msgid "Send documents on behalf of the team using the email address" msgstr "Enviar documentos em nome da equipe usando o endereço de e-mail" @@ -8193,16 +8271,8 @@ msgid "Send on Behalf of Team" msgstr "Enviar em Nome da Equipe" #: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient removed email" -msgstr "Enviar e-mail de destinatário removido" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient signed email" -msgstr "Enviar e-mail de destinatário assinado" - -#: packages/ui/components/document/document-email-checkboxes.tsx -msgid "Send recipient signing request email" -msgstr "Enviar e-mail de solicitação de assinatura do destinatário" +msgid "Send recipient expired email to the owner" +msgstr "" #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx @@ -8511,6 +8581,10 @@ msgstr "Certificado de assinatura fornecido por" msgid "Signing Complete!" msgstr "Assinatura Concluída!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "Assinando para" @@ -8535,6 +8609,26 @@ msgstr "Links de assinatura foram gerados para este documento." msgid "Signing order is enabled." msgstr "A ordem de assinatura está habilitada." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "Inscrições estão desativadas." @@ -9484,6 +9578,10 @@ msgstr "O e-mail do signatário" msgid "The signer's name" msgstr "O nome do signatário" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9491,6 +9589,14 @@ msgstr "O nome do signatário" msgid "The signing link has been copied to your clipboard." msgstr "O link de assinatura foi copiado para sua área de transferência." +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "O banner do site é uma mensagem exibida no topo do site. Pode ser usado para exibir informações importantes aos seus usuários." @@ -9856,6 +9962,10 @@ msgstr "Isso será enviado a todos os destinatários assim que o documento for t msgid "This will be sent to the document owner once the document has been fully completed." msgstr "Isso será enviado ao proprietário do documento assim que o documento for totalmente concluído." +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "Isso verificará e sincronizará o status de todos os domínios de e-mail para esta organização" @@ -10787,6 +10897,7 @@ msgstr "Visualizar documento" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11314,6 +11425,10 @@ msgstr "URL do Webhook" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "Bem-vindo" @@ -11399,6 +11514,10 @@ msgstr "Escreva uma descrição para exibir em seu perfil público" msgid "Yearly" msgstr "Anual" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12373,6 +12492,10 @@ msgstr "Seu código de recuperação foi copiado para sua área de transferênci msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "Seus códigos de recuperação estão listados abaixo. Por favor, guarde-os em um local seguro." +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "Sua solicitação de suporte foi enviada. Entraremos em contato em breve!" diff --git a/packages/lib/translations/zh/web.po b/packages/lib/translations/zh/web.po index fb07f7ddf..078ee463e 100644 --- a/packages/lib/translations/zh/web.po +++ b/packages/lib/translations/zh/web.po @@ -2764,6 +2764,10 @@ msgstr "继续查看文档。" msgid "Continue to login" msgstr "继续登录" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document." +msgstr "" + #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Controls the default email settings when new documents or templates are created" msgstr "控制新建文档或模板时的默认邮件设置" @@ -3123,6 +3127,10 @@ msgstr "目前仅 Platform 及以上套餐可以配置邮箱域名。" msgid "Custom {0} MB file" msgstr "自定义 {0} MB 文件" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Custom duration" +msgstr "" + #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx msgid "Custom Organisation Groups" msgstr "自定义组织组" @@ -3165,6 +3173,10 @@ msgstr "日期设置" msgid "David is the Employee, Lucas is the Manager" msgstr "David 是员工,Lucas 是经理" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Days" +msgstr "" + #: apps/remix/app/components/general/organisations/organisation-invitations.tsx #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx #: packages/email/templates/organisation-invite.tsx @@ -3191,6 +3203,10 @@ msgstr "默认邮箱" msgid "Default Email Settings" msgstr "默认邮件设置" +#: apps/remix/app/components/forms/document-preferences-form.tsx +msgid "Default Envelope Expiration" +msgstr "" + #: apps/remix/app/components/dialogs/template-use-dialog.tsx msgid "Default file" msgstr "默认文件" @@ -3943,6 +3959,7 @@ msgstr "文档" #: apps/remix/app/components/general/app-nav-mobile.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-upload-page.tsx #: apps/remix/app/components/general/skeletons/document-edit-skeleton.tsx +#: apps/remix/app/components/general/user-profile-skeleton.tsx #: apps/remix/app/components/general/user-profile-timur.tsx #: apps/remix/app/components/tables/admin-dashboard-users-table.tsx #: apps/remix/app/components/tables/organisation-insights-table.tsx @@ -4731,6 +4748,11 @@ msgstr "所有人都已签署!您将收到一份已签署文档的电子邮件 msgid "Exceeded timeout" msgstr "超时" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "Expiration" +msgstr "" + +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx msgid "Expired" msgstr "已过期" @@ -4744,6 +4766,11 @@ msgstr "已过期" msgid "Expires" msgstr "到期时间" +#. placeholder {0}: recipient.expiresAt ? i18n.date(recipient.expiresAt, DateTime.DATETIME_MED) : 'N/A' +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx +msgid "Expires {0}" +msgstr "" + #. placeholder {0}: DateTime.fromMillis(Math.max(millisecondsRemaining, 0)).toFormat( 'mm:ss', ) #: apps/remix/app/components/general/document-signing/access-auth-2fa-form.tsx msgid "Expires in {0}" @@ -5283,6 +5310,10 @@ msgstr "首页(无文件夹)" msgid "Horizontal" msgstr "水平" +#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx +msgid "How long recipients have to complete this document after it is sent. Uses the team default when set to inherit." +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/organisation.sso.confirmation.$token.tsx msgid "I agree to link my account with this organization" msgstr "我同意将我的账户与此组织关联" @@ -5385,6 +5416,10 @@ msgstr "在文档中包含审计日志" msgid "Include the Signing Certificate in the Document" msgstr "在文档中包含签署证书" +#: apps/remix/app/components/general/billing-plans.tsx +msgid "Includes:" +msgstr "" + #: apps/remix/app/components/general/document/document-page-view-information.tsx #: apps/remix/app/components/general/template/template-page-view-information.tsx msgid "Information" @@ -5406,6 +5441,7 @@ msgstr "继承认证方式" #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx +#: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx #: apps/remix/app/components/forms/email-preferences-form.tsx msgid "Inherit from organisation" @@ -5461,6 +5497,10 @@ msgstr "无效的域名" msgid "Invalid email" msgstr "邮箱无效" +#: apps/remix/app/routes/embed+/v1+/authoring+/_layout.tsx +msgid "Invalid embedding presign token provided" +msgstr "" + #: apps/remix/app/components/general/admin-license-card.tsx msgid "Invalid License Key" msgstr "许可证密钥无效" @@ -5814,6 +5854,8 @@ msgstr "正在加载建议…" #: apps/remix/app/components/embed/embed-client-loading.tsx #: apps/remix/app/components/general/default-recipients-multiselect-combobox.tsx #: apps/remix/app/components/general/document/document-page-view-recent-activity.tsx +#: packages/ui/components/pdf-viewer/pdf-viewer-konva-lazy.tsx +#: packages/ui/primitives/pdf-viewer/lazy.tsx msgid "Loading..." msgstr "正在加载..." @@ -6120,6 +6162,10 @@ msgstr "月活跃用户:至少创建过一份文档的用户" msgid "Monthly Active Users: Users that had at least one of their documents completed" msgstr "月活跃用户:至少有一份文档被完成的用户" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Months" +msgstr "" + #: apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx #: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx #: apps/remix/app/components/dialogs/folder-move-dialog.tsx @@ -6241,6 +6287,10 @@ msgstr "从不" msgid "Never expire" msgstr "永不过期" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Never expires" +msgstr "" + #: apps/remix/app/components/forms/password.tsx msgid "New Password" msgstr "新密码" @@ -6442,6 +6492,10 @@ msgstr "无(覆盖全局设置)" msgid "Not found" msgstr "未找到" +#: apps/remix/app/routes/embed+/_v0+/_layout.tsx +msgid "Not Found" +msgstr "" + #: apps/remix/app/components/forms/signin.tsx msgid "Not supported" msgstr "不支持" @@ -6852,6 +6906,7 @@ msgstr "付款逾期" msgid "PDF Document" msgstr "PDF 文档" +#: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-status.tsx #: apps/remix/app/components/general/envelope-editor/envelope-editor-header.tsx @@ -6967,6 +7022,7 @@ msgid "Please check the CSV file and make sure it is according to our format" msgstr "请检查 CSV 文件并确保其符合我们的格式要求" #: apps/remix/app/components/embed/embed-document-waiting-for-turn.tsx +#: apps/remix/app/components/embed/embed-recipient-expired.tsx msgid "Please check with the parent application for more information." msgstr "更多信息请查看父应用程序。" @@ -7406,6 +7462,10 @@ msgstr "收件人已将此文档加入抄送" msgid "Recipient completed their task" msgstr "收件人已完成其任务" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Recipient expired email" +msgstr "" + #: packages/lib/utils/document-audit-logs.ts msgid "Recipient failed to validate a 2FA token for the document" msgstr "收件人未能验证此文档的双重验证 (2FA) 令牌" @@ -7434,6 +7494,11 @@ msgstr "收件人已签署此文档" msgid "Recipient signing request email" msgstr "收件人签署请求邮件" +#: packages/lib/utils/document-audit-logs.ts +msgctxt "Audit log format" +msgid "Recipient signing window expired" +msgstr "" + #: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx msgid "Recipient updated" msgstr "收件人已更新" @@ -7789,6 +7854,7 @@ msgstr "重试" msgid "Return" msgstr "返回" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx #: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx msgid "Return Home" @@ -8209,6 +8275,10 @@ msgstr "立即将文档发送给收件人" msgid "Send on Behalf of Team" msgstr "以团队名义发送" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "Send recipient expired email to the owner" +msgstr "" + #: apps/remix/app/components/dialogs/document-resend-dialog.tsx #: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx msgid "Send reminder" @@ -8516,6 +8586,10 @@ msgstr "签署证书由以下机构提供" msgid "Signing Complete!" msgstr "签署完成!" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "Signing Deadline Expired" +msgstr "" + #: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx msgid "Signing for" msgstr "代签对象" @@ -8540,6 +8614,26 @@ msgstr "已为此文档生成签署链接。" msgid "Signing order is enabled." msgstr "签署顺序已启用。" +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Signing Window Expired" +msgstr "" + +#. placeholder {0}: recipient.name || recipient.email +#. placeholder {1}: envelope.title +#: packages/lib/jobs/definitions/emails/send-owner-recipient-expired-email.handler.ts +msgid "Signing window expired for \"{0}\" on \"{1}\"" +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "Signing window expired for \"{displayName}\" on \"{documentName}\"" +msgstr "" + +#. placeholder {0}: data.recipientName || data.recipientEmail +#: packages/lib/utils/document-audit-logs.ts +#: packages/lib/utils/document-audit-logs.ts +msgid "Signing window expired for {0}" +msgstr "" + #: apps/remix/app/components/forms/signup.tsx msgid "Signups are disabled." msgstr "注册已被禁用。" @@ -9489,6 +9583,10 @@ msgstr "签署人的邮箱" msgid "The signer's name" msgstr "签署人的姓名" +#: apps/remix/app/routes/_recipient+/sign.$token+/expired.tsx +msgid "The signing deadline for this document has passed. Please contact the document owner if you need a new copy to sign." +msgstr "" + #: apps/remix/app/components/general/avatar-with-recipient.tsx #: apps/remix/app/components/general/document/document-page-view-recipients.tsx #: apps/remix/app/components/general/document/document-recipient-link-copy-dialog.tsx @@ -9496,6 +9594,14 @@ msgstr "签署人的姓名" msgid "The signing link has been copied to your clipboard." msgstr "签署链接已复制到剪贴板。" +#: packages/email/templates/recipient-expired.tsx +msgid "The signing window for \"{recipientName}\" on document \"{documentName}\" has expired." +msgstr "" + +#: packages/email/template-components/template-recipient-expired.tsx +msgid "The signing window for {displayName} on document \"{documentName}\" has expired. You can resend the document to extend their deadline or cancel the document." +msgstr "" + #: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx msgid "The site banner is a message that is shown at the top of the site. It can be used to display important information to your users." msgstr "站点横幅是在站点顶部显示的一条消息。你可以利用它向用户展示重要信息。" @@ -9861,6 +9967,10 @@ msgstr "当文档完全完成后,将向所有收件人发送此邮件。" msgid "This will be sent to the document owner once the document has been fully completed." msgstr "当文档完全完成后,将向文档所有者发送此邮件。" +#: packages/ui/components/document/document-email-checkboxes.tsx +msgid "This will be sent to the document owner when a recipient's signing window has expired." +msgstr "" + #: apps/remix/app/components/tables/organisation-email-domains-table.tsx msgid "This will check and sync the status of all email domains for this organisation" msgstr "这将检查并同步此组织所有邮箱域名的状态" @@ -10792,6 +10902,7 @@ msgstr "查看文档" #: apps/remix/app/components/general/document-signing/document-signing-page-view-v2.tsx #: packages/email/template-components/template-document-invite.tsx #: packages/email/template-components/template-document-rejected.tsx +#: packages/email/template-components/template-recipient-expired.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx #: packages/ui/primitives/document-flow/add-subject.tsx @@ -11319,6 +11430,10 @@ msgstr "Webhook URL" msgid "Webhooks" msgstr "Webhooks" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Weeks" +msgstr "" + #: apps/remix/app/routes/_unauthenticated+/articles.signature-disclosure.tsx msgid "Welcome" msgstr "欢迎" @@ -11404,6 +11519,10 @@ msgstr "撰写将在您的公共主页上展示的简介" msgid "Yearly" msgstr "按年" +#: packages/ui/components/document/expiration-period-picker.tsx +msgid "Years" +msgstr "" + #: apps/remix/app/components/forms/branding-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx #: apps/remix/app/components/forms/document-preferences-form.tsx @@ -12378,6 +12497,10 @@ msgstr "你的恢复代码已复制到剪贴板。" msgid "Your recovery codes are listed below. Please store them in a safe place." msgstr "你的恢复代码列在下方。请妥善保存。" +#: apps/remix/app/components/embed/embed-recipient-expired.tsx +msgid "Your signing window for this document has expired. Please contact the sender for a new invitation." +msgstr "" + #: apps/remix/app/components/forms/support-ticket-form.tsx msgid "Your support request has been submitted. We'll get back to you soon!" msgstr "您的支持请求已提交。我们会尽快回复您!" @@ -12446,4 +12569,3 @@ msgstr "您的验证码:" #: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx msgid "your-domain.com another-domain.com" msgstr "your-domain.com another-domain.com" - diff --git a/packages/lib/types/email-domain.ts b/packages/lib/types/email-domain.ts index 2dbf79b2a..df5944bfc 100644 --- a/packages/lib/types/email-domain.ts +++ b/packages/lib/types/email-domain.ts @@ -18,6 +18,7 @@ export const ZEmailDomainSchema = EmailDomainSchema.pick({ publicKey: true, createdAt: true, updatedAt: true, + lastVerifiedAt: true, }).extend({ emails: ZOrganisationEmailLiteSchema.array(), }); @@ -35,6 +36,7 @@ export const ZEmailDomainManySchema = EmailDomainSchema.pick({ selector: true, createdAt: true, updatedAt: true, + lastVerifiedAt: true, }); export type TEmailDomainMany = z.infer; diff --git a/packages/prisma/index.ts b/packages/prisma/index.ts index cffa7a451..1e0b6c079 100644 --- a/packages/prisma/index.ts +++ b/packages/prisma/index.ts @@ -1,5 +1,6 @@ /// import { PrismaClient } from '@prisma/client'; +import { readReplicas } from '@prisma/extension-read-replicas'; import { Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler } from 'kysely'; import kyselyExtension from 'prisma-extension-kysely'; @@ -7,7 +8,7 @@ import type { DB } from './generated/types'; import { getDatabaseUrl } from './helper'; import { remember } from './utils/remember'; -export const prisma = remember( +const prisma = remember( 'prisma', () => new PrismaClient({ @@ -65,4 +66,25 @@ export const prismaWithLogging = remember('prismaWithLogging', () => { return client; }); +export const prismaWithReplicas = remember('prismaWithReplicas', () => { + if (!process.env.NEXT_PRIVATE_DATABASE_REPLICA_URLS) { + return prisma; + } + + const replicaUrls = process.env.NEXT_PRIVATE_DATABASE_REPLICA_URLS.split(',').map((url) => + url.trim(), + ); + + // !: Nasty hack, means we can't do any fancy $primary/$replica queries + // !: but it is acceptable since not all setups will have replicas anyway. + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + return prisma.$extends( + readReplicas({ + url: replicaUrls, + }), + ) as unknown as typeof prisma; +}); + +export { prismaWithReplicas as prisma }; + export { sql } from 'kysely'; diff --git a/packages/prisma/migrations/20260224000000_add_email_domain_last_verified_at/migration.sql b/packages/prisma/migrations/20260224000000_add_email_domain_last_verified_at/migration.sql new file mode 100644 index 000000000..6d2dc6073 --- /dev/null +++ b/packages/prisma/migrations/20260224000000_add_email_domain_last_verified_at/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "EmailDomain" ADD COLUMN "lastVerifiedAt" TIMESTAMP(3); diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 8fa202e77..fe1786417 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1039,10 +1039,11 @@ model EmailDomain { status EmailDomainStatus @default(PENDING) - selector String @unique - domain String @unique - publicKey String - privateKey String + selector String @unique + domain String @unique + publicKey String + privateKey String + lastVerifiedAt DateTime? organisationId String organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade) diff --git a/packages/trpc/server/admin-router/find-email-domains.ts b/packages/trpc/server/admin-router/find-email-domains.ts new file mode 100644 index 000000000..5caa8d58e --- /dev/null +++ b/packages/trpc/server/admin-router/find-email-domains.ts @@ -0,0 +1,101 @@ +import { Prisma } from '@prisma/client'; + +import type { FindResultResponse } from '@documenso/lib/types/search-params'; +import { prisma } from '@documenso/prisma'; + +import { adminProcedure } from '../trpc'; +import { + ZFindEmailDomainsRequestSchema, + ZFindEmailDomainsResponseSchema, +} from './find-email-domains.types'; + +export const findEmailDomainsRoute = adminProcedure + .input(ZFindEmailDomainsRequestSchema) + .output(ZFindEmailDomainsResponseSchema) + .query(async ({ input }) => { + const { query, page, perPage, status } = input; + + return await findEmailDomains({ query, page, perPage, status }); + }); + +type FindEmailDomainsOptions = { + query?: string; + page?: number; + perPage?: number; + status?: 'PENDING' | 'ACTIVE'; +}; + +const findEmailDomains = async ({ + query, + page = 1, + perPage = 20, + status, +}: FindEmailDomainsOptions) => { + const whereClause: Prisma.EmailDomainWhereInput = {}; + + if (query) { + whereClause.OR = [ + { + domain: { + contains: query, + mode: Prisma.QueryMode.insensitive, + }, + }, + { + organisation: { + name: { + contains: query, + mode: Prisma.QueryMode.insensitive, + }, + }, + }, + ]; + } + + if (status) { + whereClause.status = status; + } + + const [data, count] = await Promise.all([ + prisma.emailDomain.findMany({ + where: whereClause, + skip: Math.max(page - 1, 0) * perPage, + take: perPage, + orderBy: { + createdAt: 'desc', + }, + select: { + id: true, + domain: true, + status: true, + selector: true, + createdAt: true, + updatedAt: true, + lastVerifiedAt: true, + organisation: { + select: { + id: true, + name: true, + url: true, + }, + }, + _count: { + select: { + emails: true, + }, + }, + }, + }), + prisma.emailDomain.count({ + where: whereClause, + }), + ]); + + return { + data, + count, + currentPage: Math.max(page, 1), + perPage, + totalPages: Math.ceil(count / perPage), + } satisfies FindResultResponse; +}; diff --git a/packages/trpc/server/admin-router/find-email-domains.types.ts b/packages/trpc/server/admin-router/find-email-domains.types.ts new file mode 100644 index 000000000..c4118436e --- /dev/null +++ b/packages/trpc/server/admin-router/find-email-domains.types.ts @@ -0,0 +1,36 @@ +import { z } from 'zod'; + +import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params'; +import EmailDomainStatusSchema from '@documenso/prisma/generated/zod/inputTypeSchemas/EmailDomainStatusSchema'; +import EmailDomainSchema from '@documenso/prisma/generated/zod/modelSchema/EmailDomainSchema'; +import OrganisationSchema from '@documenso/prisma/generated/zod/modelSchema/OrganisationSchema'; + +export const ZFindEmailDomainsRequestSchema = ZFindSearchParamsSchema.extend({ + status: EmailDomainStatusSchema.optional(), +}); + +export const ZFindEmailDomainsResponseSchema = ZFindResultResponse.extend({ + data: EmailDomainSchema.pick({ + id: true, + domain: true, + status: true, + selector: true, + createdAt: true, + updatedAt: true, + lastVerifiedAt: true, + }) + .extend({ + organisation: OrganisationSchema.pick({ + id: true, + name: true, + url: true, + }), + _count: z.object({ + emails: z.number(), + }), + }) + .array(), +}); + +export type TFindEmailDomainsRequest = z.infer; +export type TFindEmailDomainsResponse = z.infer; diff --git a/packages/trpc/server/admin-router/get-email-domain.ts b/packages/trpc/server/admin-router/get-email-domain.ts new file mode 100644 index 000000000..b4acf4f69 --- /dev/null +++ b/packages/trpc/server/admin-router/get-email-domain.ts @@ -0,0 +1,42 @@ +import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; +import { prisma } from '@documenso/prisma'; + +import { adminProcedure } from '../trpc'; +import { + ZGetEmailDomainRequestSchema, + ZGetEmailDomainResponseSchema, +} from './get-email-domain.types'; + +export const getEmailDomainRoute = adminProcedure + .input(ZGetEmailDomainRequestSchema) + .output(ZGetEmailDomainResponseSchema) + .query(async ({ input }) => { + const { emailDomainId } = input; + + const emailDomain = await prisma.emailDomain.findUnique({ + where: { + id: emailDomainId, + }, + omit: { + privateKey: true, + }, + include: { + organisation: { + select: { + id: true, + name: true, + url: true, + }, + }, + emails: true, + }, + }); + + if (!emailDomain) { + throw new AppError(AppErrorCode.NOT_FOUND, { + message: 'Email domain not found', + }); + } + + return emailDomain; + }); diff --git a/packages/trpc/server/admin-router/get-email-domain.types.ts b/packages/trpc/server/admin-router/get-email-domain.types.ts new file mode 100644 index 000000000..fdfc00810 --- /dev/null +++ b/packages/trpc/server/admin-router/get-email-domain.types.ts @@ -0,0 +1,30 @@ +import { z } from 'zod'; + +import { ZOrganisationEmailLiteSchema } from '@documenso/lib/types/organisation-email'; +import EmailDomainSchema from '@documenso/prisma/generated/zod/modelSchema/EmailDomainSchema'; +import OrganisationSchema from '@documenso/prisma/generated/zod/modelSchema/OrganisationSchema'; + +export const ZGetEmailDomainRequestSchema = z.object({ + emailDomainId: z.string(), +}); + +export const ZGetEmailDomainResponseSchema = EmailDomainSchema.pick({ + id: true, + domain: true, + status: true, + selector: true, + publicKey: true, + createdAt: true, + updatedAt: true, + lastVerifiedAt: true, +}).extend({ + organisation: OrganisationSchema.pick({ + id: true, + name: true, + url: true, + }), + emails: ZOrganisationEmailLiteSchema.array(), +}); + +export type TGetEmailDomainRequest = z.infer; +export type TGetEmailDomainResponse = z.infer; diff --git a/packages/trpc/server/admin-router/reregister-email-domain.ts b/packages/trpc/server/admin-router/reregister-email-domain.ts new file mode 100644 index 000000000..d334c66e3 --- /dev/null +++ b/packages/trpc/server/admin-router/reregister-email-domain.ts @@ -0,0 +1,22 @@ +import { reregisterEmailDomain } from '@documenso/ee/server-only/lib/reregister-email-domain'; + +import { adminProcedure } from '../trpc'; +import { + ZReregisterEmailDomainRequestSchema, + ZReregisterEmailDomainResponseSchema, +} from './reregister-email-domain.types'; + +export const reregisterEmailDomainRoute = adminProcedure + .input(ZReregisterEmailDomainRequestSchema) + .output(ZReregisterEmailDomainResponseSchema) + .mutation(async ({ input, ctx }) => { + const { emailDomainId } = input; + + ctx.logger.info({ + input: { + emailDomainId, + }, + }); + + await reregisterEmailDomain({ emailDomainId }); + }); diff --git a/packages/trpc/server/admin-router/reregister-email-domain.types.ts b/packages/trpc/server/admin-router/reregister-email-domain.types.ts new file mode 100644 index 000000000..de7d222f4 --- /dev/null +++ b/packages/trpc/server/admin-router/reregister-email-domain.types.ts @@ -0,0 +1,10 @@ +import { z } from 'zod'; + +export const ZReregisterEmailDomainRequestSchema = z.object({ + emailDomainId: z.string(), +}); + +export const ZReregisterEmailDomainResponseSchema = z.void(); + +export type TReregisterEmailDomainRequest = z.infer; +export type TReregisterEmailDomainResponse = z.infer; diff --git a/packages/trpc/server/admin-router/router.ts b/packages/trpc/server/admin-router/router.ts index 17783072d..dd472705f 100644 --- a/packages/trpc/server/admin-router/router.ts +++ b/packages/trpc/server/admin-router/router.ts @@ -11,11 +11,14 @@ import { findAdminOrganisationsRoute } from './find-admin-organisations'; import { findDocumentAuditLogsRoute } from './find-document-audit-logs'; import { findDocumentJobsRoute } from './find-document-jobs'; import { findDocumentsRoute } from './find-documents'; +import { findEmailDomainsRoute } from './find-email-domains'; import { findSubscriptionClaimsRoute } from './find-subscription-claims'; import { findUserTeamsRoute } from './find-user-teams'; import { getAdminOrganisationRoute } from './get-admin-organisation'; +import { getEmailDomainRoute } from './get-email-domain'; import { getUserRoute } from './get-user'; import { promoteMemberToOwnerRoute } from './promote-member-to-owner'; +import { reregisterEmailDomainRoute } from './reregister-email-domain'; import { resealDocumentRoute } from './reseal-document'; import { resetTwoFactorRoute } from './reset-two-factor-authentication'; import { resyncLicenseRoute } from './resync-license'; @@ -68,5 +71,10 @@ export const adminRouter = router({ recipient: { update: updateRecipientRoute, }, + emailDomain: { + find: findEmailDomainsRoute, + get: getEmailDomainRoute, + reregister: reregisterEmailDomainRoute, + }, updateSiteSetting: updateSiteSettingRoute, }); diff --git a/packages/trpc/server/enterprise-router/find-organisation-email-domain.ts b/packages/trpc/server/enterprise-router/find-organisation-email-domain.ts index 6901efb76..e8694fc38 100644 --- a/packages/trpc/server/enterprise-router/find-organisation-email-domain.ts +++ b/packages/trpc/server/enterprise-router/find-organisation-email-domain.ts @@ -95,6 +95,7 @@ export const findOrganisationEmailDomains = async ({ selector: true, createdAt: true, updatedAt: true, + lastVerifiedAt: true, _count: { select: { emails: true, diff --git a/turbo.json b/turbo.json index 2a4f650e1..011cf518c 100644 --- a/turbo.json +++ b/turbo.json @@ -52,6 +52,7 @@ "NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT", "NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY", "NEXT_PRIVATE_DATABASE_URL", + "NEXT_PRIVATE_DATABASE_REPLICA_URLS", "NEXT_PRIVATE_DIRECT_DATABASE_URL", "NEXT_PRIVATE_LOGGER_FILE_PATH", "NEXT_PRIVATE_SIGNING_TRANSPORT",