chore: merge main, resolve biome formatting conflicts

Merge origin/main into feat/external-2fa-codes. Resolve formatting
conflicts caused by biome rollout; preserve both feature streams:
PR's external 2FA token + signing-session 2FA proof additions plus
main's RateLimit/RecipientExpired/signingReminders/date-auto-insert.

In complete-document-with-token.ts, drop the duplicate early
field-fetching block introduced when main moved that logic later
with date auto-insert support; keep the EXTERNAL_TWO_FACTOR_AUTH
check using derivedRecipientActionAuth.
This commit is contained in:
ephraimduncan
2026-05-12 11:46:11 +00:00
parent 9194884fbe
commit 138d663c25
1959 changed files with 93488 additions and 47038 deletions
@@ -1,32 +1,23 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { Trans } from '@lingui/react/macro';
import type { TeamGlobalSettings } from '@prisma/client';
import { DocumentVisibility, OrganisationType, type RecipientRole } from '@prisma/client';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { useSession } from '@documenso/lib/client-only/providers/session';
import { DATE_FORMATS } from '@documenso/lib/constants/date-formats';
import { DOCUMENT_SIGNATURE_TYPES, DocumentSignatureType } from '@documenso/lib/constants/document';
import {
SUPPORTED_LANGUAGES,
SUPPORTED_LANGUAGE_CODES,
isValidLanguageCode,
} from '@documenso/lib/constants/i18n';
type TEnvelopeExpirationPeriod,
ZEnvelopeExpirationPeriod,
} from '@documenso/lib/constants/envelope-expiration';
import { type TEnvelopeReminderSettings, ZEnvelopeReminderSettings } from '@documenso/lib/constants/envelope-reminder';
import { isValidLanguageCode, SUPPORTED_LANGUAGE_CODES, SUPPORTED_LANGUAGES } from '@documenso/lib/constants/i18n';
import { TIME_ZONES } from '@documenso/lib/constants/time-zones';
import type { TDefaultRecipients } from '@documenso/lib/types/default-recipients';
import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';
import {
type TDocumentMetaDateFormat,
ZDocumentMetaTimezoneSchema,
} from '@documenso/lib/types/document-meta';
import { type TDocumentMetaDateFormat, ZDocumentMetaTimezoneSchema } from '@documenso/lib/types/document-meta';
import { isPersonalLayout } from '@documenso/lib/utils/organisations';
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
import { extractTeamSignatureSettings } from '@documenso/lib/utils/teams';
import { DocumentSignatureSettingsTooltip } from '@documenso/ui/components/document/document-signature-settings-tooltip';
import { ExpirationPeriodPicker } from '@documenso/ui/components/document/expiration-period-picker';
import { ReminderSettingsPicker } from '@documenso/ui/components/document/reminder-settings-picker';
import { RecipientRoleSelect } from '@documenso/ui/components/recipient/recipient-role-select';
import { Alert } from '@documenso/ui/primitives/alert';
import { AvatarWithText } from '@documenso/ui/primitives/avatar';
@@ -42,13 +33,15 @@ import {
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { MultiSelectCombobox } from '@documenso/ui/primitives/multi-select-combobox';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { zodResolver } from '@hookform/resolvers/zod';
import { msg, t } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import type { TeamGlobalSettings } from '@prisma/client';
import { DocumentVisibility, OrganisationType, type RecipientRole } from '@prisma/client';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { useOptionalCurrentTeam } from '~/providers/team';
@@ -70,6 +63,8 @@ export type TDocumentPreferencesFormSchema = {
defaultRecipients: TDefaultRecipients | null;
delegateDocumentOwnership: boolean | null;
aiFeaturesEnabled: boolean | null;
envelopeExpirationPeriod: TEnvelopeExpirationPeriod | null;
reminderSettings: TEnvelopeReminderSettings | null;
};
type SettingsSubset = Pick<
@@ -87,6 +82,8 @@ type SettingsSubset = Pick<
| 'defaultRecipients'
| 'delegateDocumentOwnership'
| 'aiFeaturesEnabled'
| 'envelopeExpirationPeriod'
| 'reminderSettings'
>;
export type DocumentPreferencesFormProps = {
@@ -102,7 +99,7 @@ export const DocumentPreferencesForm = ({
canInherit,
isAiFeaturesConfigured = false,
}: DocumentPreferencesFormProps) => {
const { t } = useLingui();
const { _ } = useLingui();
const { user, organisations } = useSession();
const currentOrganisation = useCurrentOrganisation();
const optionalTeam = useOptionalCurrentTeam();
@@ -126,14 +123,14 @@ export const DocumentPreferencesForm = ({
defaultRecipients: ZDefaultRecipientsSchema.nullable(),
delegateDocumentOwnership: z.boolean().nullable(),
aiFeaturesEnabled: z.boolean().nullable(),
envelopeExpirationPeriod: ZEnvelopeExpirationPeriod.nullable(),
reminderSettings: ZEnvelopeReminderSettings.nullable(),
});
const form = useForm<TDocumentPreferencesFormSchema>({
defaultValues: {
documentVisibility: settings.documentVisibility,
documentLanguage: isValidLanguageCode(settings.documentLanguage)
? settings.documentLanguage
: null,
documentLanguage: isValidLanguageCode(settings.documentLanguage) ? settings.documentLanguage : null,
documentTimezone: settings.documentTimezone,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
documentDateFormat: settings.documentDateFormat as TDocumentMetaDateFormat | null,
@@ -141,11 +138,11 @@ export const DocumentPreferencesForm = ({
includeSigningCertificate: settings.includeSigningCertificate,
includeAuditLog: settings.includeAuditLog,
signatureTypes: extractTeamSignatureSettings({ ...settings }),
defaultRecipients: settings.defaultRecipients
? ZDefaultRecipientsSchema.parse(settings.defaultRecipients)
: null,
defaultRecipients: settings.defaultRecipients ? ZDefaultRecipientsSchema.parse(settings.defaultRecipients) : null,
delegateDocumentOwnership: settings.delegateDocumentOwnership,
aiFeaturesEnabled: settings.aiFeaturesEnabled,
envelopeExpirationPeriod: settings.envelopeExpirationPeriod ?? null,
reminderSettings: settings.reminderSettings ?? null,
},
resolver: zodResolver(ZDocumentPreferencesFormSchema),
});
@@ -153,10 +150,7 @@ export const DocumentPreferencesForm = ({
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onFormSubmit)}>
<fieldset
className="flex h-full max-w-2xl flex-col gap-y-6"
disabled={form.formState.isSubmitting}
>
<fieldset className="flex h-full max-w-2xl flex-col gap-y-6" disabled={form.formState.isSubmitting}>
{!isPersonalLayoutMode && (
<FormField
control={form.control}
@@ -233,7 +227,7 @@ export const DocumentPreferencesForm = ({
<SelectContent>
{Object.entries(SUPPORTED_LANGUAGES).map(([code, language]) => (
<SelectItem key={code} value={code}>
{language.full}
{_(language.full)}
</SelectItem>
))}
@@ -246,8 +240,8 @@ export const DocumentPreferencesForm = ({
<FormDescription>
<Trans>
Controls the default language of an uploaded document. This will be used as the
language in email communications with the recipients.
Controls the default language of an uploaded document. This will be used as the language in email
communications with the recipients.
</Trans>
</FormDescription>
</FormItem>
@@ -304,9 +298,7 @@ export const DocumentPreferencesForm = ({
<FormControl>
<Combobox
triggerPlaceholder={
canInherit ? t`Inherit from organisation` : t`Local timezone`
}
triggerPlaceholder={canInherit ? t`Inherit from organisation` : t`Local timezone`}
placeholder={t`Select a time zone`}
options={TIME_ZONES}
value={field.value}
@@ -333,16 +325,14 @@ export const DocumentPreferencesForm = ({
<FormControl>
<MultiSelectCombobox
options={Object.values(DOCUMENT_SIGNATURE_TYPES).map((option) => ({
label: t(option.label),
label: _(option.label),
value: option.value,
}))}
selectedValues={field.value}
onChange={field.onChange}
className="w-full bg-background"
enableSearch={false}
emptySelectionPlaceholder={
canInherit ? t`Inherit from organisation` : t`Select signature types`
}
emptySelectionPlaceholder={canInherit ? t`Inherit from organisation` : t`Select signature types`}
testId="signature-types-trigger"
/>
</FormControl>
@@ -351,9 +341,7 @@ export const DocumentPreferencesForm = ({
<FormMessage />
) : (
<FormDescription>
<Trans>
Controls which signatures are allowed to be used when signing a document.
</Trans>
<Trans>Controls which signatures are allowed to be used when signing a document.</Trans>
</FormDescription>
)}
</FormItem>
@@ -404,15 +392,14 @@ export const DocumentPreferencesForm = ({
</FormControl>
<div className="pt-2">
<div className="text-xs font-medium text-muted-foreground">
<div className="font-medium text-muted-foreground text-xs">
<Trans>Preview</Trans>
</div>
<Alert variant="neutral" className="mt-1 px-2.5 py-1.5 text-sm">
{field.value ? (
<Trans>
"{placeholderEmail}" on behalf of "Team Name" has invited you to sign
"example document".
"{placeholderEmail}" on behalf of "Team Name" has invited you to sign "example document".
</Trans>
) : (
<Trans>"Team Name" has invited you to sign "example document".</Trans>
@@ -422,9 +409,9 @@ export const DocumentPreferencesForm = ({
<FormDescription>
<Trans>
Controls the formatting of the message that will be sent when inviting a
recipient to sign a document. If a custom message has been provided while
configuring the document, it will be used instead.
Controls the formatting of the message that will be sent when inviting a recipient to sign a
document. If a custom message has been provided while configuring the document, it will be used
instead.
</Trans>
</FormDescription>
</FormItem>
@@ -476,9 +463,8 @@ export const DocumentPreferencesForm = ({
<FormDescription>
<Trans>
Controls whether the signing certificate will be included in the document when
it is downloaded. The signing certificate can still be downloaded from the logs
page separately.
Controls whether the signing certificate will be included in the document when it is downloaded. The
signing certificate can still be downloaded from the logs page separately.
</Trans>
</FormDescription>
</FormItem>
@@ -526,9 +512,8 @@ export const DocumentPreferencesForm = ({
<FormDescription>
<Trans>
Controls whether the audit logs will be included in the document when it is
downloaded. The audit logs can still be downloaded from the logs page
separately.
Controls whether the audit logs will be included in the document when it is downloaded. The audit
logs can still be downloaded from the logs page separately.
</Trans>
</FormDescription>
</FormItem>
@@ -584,15 +569,11 @@ export const DocumentPreferencesForm = ({
<AvatarWithText
avatarFallback={recipientAbbreviation(recipient)}
primaryText={
<span className="text-sm font-medium">
{recipient.name || recipient.email}
</span>
<span className="font-medium text-sm">{recipient.name || recipient.email}</span>
}
secondaryText={
recipient.name ? (
<span className="text-xs text-muted-foreground">
{recipient.email}
</span>
<span className="text-muted-foreground text-xs">{recipient.email}</span>
) : undefined
}
className="flex-1"
@@ -635,9 +616,7 @@ export const DocumentPreferencesForm = ({
<Select
{...field}
value={field.value === null ? '-1' : field.value.toString()}
onValueChange={(value) =>
field.onChange(value === 'true' ? true : value === 'false' ? false : null)
}
onValueChange={(value) => field.onChange(value === 'true' ? true : value === 'false' ? false : null)}
>
<SelectTrigger className="bg-background text-muted-foreground">
<SelectValue />
@@ -660,11 +639,67 @@ export const DocumentPreferencesForm = ({
</SelectContent>
</Select>
<FormDescription>
<Trans>Enable team API tokens to delegate document ownership to another team member.</Trans>
</FormDescription>
</FormItem>
)}
/>
<FormField
control={form.control}
name="envelopeExpirationPeriod"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>
<Trans>Default Envelope Expiration</Trans>
</FormLabel>
<FormControl>
<ExpirationPeriodPicker
value={field.value}
onChange={field.onChange}
inheritLabel={canInherit ? t`Inherit from organisation` : undefined}
/>
</FormControl>
<FormDescription>
<Trans>
Enable team API tokens to delegate document ownership to another team member.
Controls how long recipients have to complete signing before the document expires. After expiration,
recipients can no longer sign the document.
</Trans>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="reminderSettings"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>
<Trans>Default Signing Reminders</Trans>
</FormLabel>
<FormControl>
<ReminderSettingsPicker
value={field.value}
onChange={field.onChange}
inheritLabel={canInherit ? t`Inherit from organisation` : undefined}
/>
</FormControl>
<FormDescription>
<Trans>
Controls when and how often reminder emails are sent to recipients who have not yet completed
signing.
</Trans>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
@@ -711,10 +746,9 @@ export const DocumentPreferencesForm = ({
<FormDescription>
<Trans>
Enable AI-powered features such as automatic recipient detection. When
enabled, document content will be sent to AI providers. We only use providers
that do not retain data for training and prefer European regions where
available.
Enable AI-powered features such as automatic recipient detection. When enabled, document content
will be sent to AI providers. We only use providers that do not retain data for training and
prefer European regions where available.
</Trans>
</FormDescription>
</FormItem>