mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
feat: add signature configurations (#1710)
Add ability to enable or disable allowed signature types: - Drawn - Typed - Uploaded **Tabbed style signature dialog**  **Document settings**  **Team preferences**  - Add multiselect to select allowed signatures in document and templates settings tab - Add multiselect to select allowed signatures in teams preferences - Removed "Enable typed signatures" from document/template edit page - Refactored signature pad to use tabs instead of an all in one signature pad Added E2E tests to check settings are applied correctly for documents and templates
This commit is contained in:
@ -27,6 +27,8 @@ export type CreateDocumentMetaOptions = {
|
||||
allowDictateNextSigner?: boolean;
|
||||
distributionMethod?: DocumentDistributionMethod;
|
||||
typedSignatureEnabled?: boolean;
|
||||
uploadSignatureEnabled?: boolean;
|
||||
drawSignatureEnabled?: boolean;
|
||||
language?: SupportedLanguageCodes;
|
||||
requestMetadata: ApiRequestMetadata;
|
||||
};
|
||||
@ -46,6 +48,8 @@ export const upsertDocumentMeta = async ({
|
||||
emailSettings,
|
||||
distributionMethod,
|
||||
typedSignatureEnabled,
|
||||
uploadSignatureEnabled,
|
||||
drawSignatureEnabled,
|
||||
language,
|
||||
requestMetadata,
|
||||
}: CreateDocumentMetaOptions) => {
|
||||
@ -99,6 +103,8 @@ export const upsertDocumentMeta = async ({
|
||||
emailSettings,
|
||||
distributionMethod,
|
||||
typedSignatureEnabled,
|
||||
uploadSignatureEnabled,
|
||||
drawSignatureEnabled,
|
||||
language,
|
||||
},
|
||||
update: {
|
||||
@ -113,6 +119,8 @@ export const upsertDocumentMeta = async ({
|
||||
emailSettings,
|
||||
distributionMethod,
|
||||
typedSignatureEnabled,
|
||||
uploadSignatureEnabled,
|
||||
drawSignatureEnabled,
|
||||
language,
|
||||
},
|
||||
});
|
||||
|
||||
@ -158,6 +158,10 @@ export const createDocumentV2 = async ({
|
||||
language: meta?.language || team?.teamGlobalSettings?.documentLanguage,
|
||||
typedSignatureEnabled:
|
||||
meta?.typedSignatureEnabled ?? team?.teamGlobalSettings?.typedSignatureEnabled,
|
||||
uploadSignatureEnabled:
|
||||
meta?.uploadSignatureEnabled ?? team?.teamGlobalSettings?.uploadSignatureEnabled,
|
||||
drawSignatureEnabled:
|
||||
meta?.drawSignatureEnabled ?? team?.teamGlobalSettings?.drawSignatureEnabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -128,8 +128,10 @@ export const createDocument = async ({
|
||||
documentMeta: {
|
||||
create: {
|
||||
language: team?.teamGlobalSettings?.documentLanguage,
|
||||
typedSignatureEnabled: team?.teamGlobalSettings?.typedSignatureEnabled,
|
||||
timezone: timezone,
|
||||
typedSignatureEnabled: team?.teamGlobalSettings?.typedSignatureEnabled ?? true,
|
||||
uploadSignatureEnabled: team?.teamGlobalSettings?.uploadSignatureEnabled ?? true,
|
||||
drawSignatureEnabled: team?.teamGlobalSettings?.drawSignatureEnabled ?? true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -201,7 +201,7 @@ export const signFieldWithToken = async ({
|
||||
throw new Error('Signature field must have a signature');
|
||||
}
|
||||
|
||||
if (isSignatureField && !documentMeta?.typedSignatureEnabled && typedSignature) {
|
||||
if (isSignatureField && documentMeta?.typedSignatureEnabled === false && typedSignature) {
|
||||
throw new Error('Typed signatures are not allowed. Please draw your signature');
|
||||
}
|
||||
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
import type { DocumentVisibility } from '@prisma/client';
|
||||
import { TeamMemberRole } from '@prisma/client';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { TeamGlobalSettingsSchema } from '@documenso/prisma/generated/zod/modelSchema/TeamGlobalSettingsSchema';
|
||||
|
||||
import type { SupportedLanguageCodes } from '../../constants/i18n';
|
||||
|
||||
export type UpdateTeamDocumentSettingsOptions = {
|
||||
userId: number;
|
||||
teamId: number;
|
||||
|
||||
settings: {
|
||||
documentVisibility: DocumentVisibility;
|
||||
documentLanguage: SupportedLanguageCodes;
|
||||
includeSenderDetails: boolean;
|
||||
typedSignatureEnabled: boolean;
|
||||
includeSigningCertificate: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export const ZUpdateTeamDocumentSettingsResponseSchema = TeamGlobalSettingsSchema;
|
||||
|
||||
export type TUpdateTeamDocumentSettingsResponse = z.infer<
|
||||
typeof ZUpdateTeamDocumentSettingsResponseSchema
|
||||
>;
|
||||
|
||||
export const updateTeamDocumentSettings = async ({
|
||||
userId,
|
||||
teamId,
|
||||
settings,
|
||||
}: UpdateTeamDocumentSettingsOptions): Promise<TUpdateTeamDocumentSettingsResponse> => {
|
||||
const {
|
||||
documentVisibility,
|
||||
documentLanguage,
|
||||
includeSenderDetails,
|
||||
includeSigningCertificate,
|
||||
typedSignatureEnabled,
|
||||
} = settings;
|
||||
|
||||
const member = await prisma.teamMember.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
teamId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!member || member.role !== TeamMemberRole.ADMIN) {
|
||||
throw new Error('You do not have permission to update this team.');
|
||||
}
|
||||
|
||||
return await prisma.teamGlobalSettings.upsert({
|
||||
where: {
|
||||
teamId,
|
||||
},
|
||||
create: {
|
||||
teamId,
|
||||
documentVisibility,
|
||||
documentLanguage,
|
||||
includeSenderDetails,
|
||||
typedSignatureEnabled,
|
||||
includeSigningCertificate,
|
||||
},
|
||||
update: {
|
||||
documentVisibility,
|
||||
documentLanguage,
|
||||
includeSenderDetails,
|
||||
typedSignatureEnabled,
|
||||
includeSigningCertificate,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -324,6 +324,9 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
language: metaLanguage,
|
||||
signingOrder: metaSigningOrder,
|
||||
distributionMethod: template.templateMeta?.distributionMethod,
|
||||
typedSignatureEnabled: template.templateMeta?.typedSignatureEnabled,
|
||||
uploadSignatureEnabled: template.templateMeta?.uploadSignatureEnabled,
|
||||
drawSignatureEnabled: template.templateMeta?.drawSignatureEnabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -96,6 +96,9 @@ export const createDocumentFromTemplateLegacy = async ({
|
||||
signingOrder: template.templateMeta?.signingOrder ?? undefined,
|
||||
language:
|
||||
template.templateMeta?.language || template.team?.teamGlobalSettings?.documentLanguage,
|
||||
typedSignatureEnabled: template.templateMeta?.typedSignatureEnabled,
|
||||
uploadSignatureEnabled: template.templateMeta?.uploadSignatureEnabled,
|
||||
drawSignatureEnabled: template.templateMeta?.drawSignatureEnabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -82,9 +82,11 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
signingOrder?: DocumentSigningOrder;
|
||||
language?: SupportedLanguageCodes;
|
||||
distributionMethod?: DocumentDistributionMethod;
|
||||
typedSignatureEnabled?: boolean;
|
||||
allowDictateNextSigner?: boolean;
|
||||
emailSettings?: TDocumentEmailSettings;
|
||||
typedSignatureEnabled?: boolean;
|
||||
uploadSignatureEnabled?: boolean;
|
||||
drawSignatureEnabled?: boolean;
|
||||
};
|
||||
requestMetadata: ApiRequestMetadata;
|
||||
};
|
||||
@ -405,6 +407,10 @@ export const createDocumentFromTemplate = async ({
|
||||
template.team?.teamGlobalSettings?.documentLanguage,
|
||||
typedSignatureEnabled:
|
||||
override?.typedSignatureEnabled ?? template.templateMeta?.typedSignatureEnabled,
|
||||
uploadSignatureEnabled:
|
||||
override?.uploadSignatureEnabled ?? template.templateMeta?.uploadSignatureEnabled,
|
||||
drawSignatureEnabled:
|
||||
override?.drawSignatureEnabled ?? template.templateMeta?.drawSignatureEnabled,
|
||||
allowDictateNextSigner:
|
||||
override?.allowDictateNextSigner ??
|
||||
template.templateMeta?.allowDictateNextSigner ??
|
||||
|
||||
@ -4,6 +4,8 @@ import { prisma } from '@documenso/prisma';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod/modelSchema//TemplateSchema';
|
||||
import type { TCreateTemplateMutationSchema } from '@documenso/trpc/server/template-router/schema';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
|
||||
export type CreateTemplateOptions = TCreateTemplateMutationSchema & {
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
@ -19,8 +21,10 @@ export const createTemplate = async ({
|
||||
teamId,
|
||||
templateDocumentDataId,
|
||||
}: CreateTemplateOptions) => {
|
||||
let team = null;
|
||||
|
||||
if (teamId) {
|
||||
await prisma.team.findFirstOrThrow({
|
||||
team = await prisma.team.findFirst({
|
||||
where: {
|
||||
id: teamId,
|
||||
members: {
|
||||
@ -29,7 +33,14 @@ export const createTemplate = async ({
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
teamGlobalSettings: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
return await prisma.template.create({
|
||||
@ -38,6 +49,14 @@ export const createTemplate = async ({
|
||||
userId,
|
||||
templateDocumentDataId,
|
||||
teamId,
|
||||
templateMeta: {
|
||||
create: {
|
||||
language: team?.teamGlobalSettings?.documentLanguage,
|
||||
typedSignatureEnabled: team?.teamGlobalSettings?.typedSignatureEnabled ?? true,
|
||||
uploadSignatureEnabled: team?.teamGlobalSettings?.uploadSignatureEnabled ?? true,
|
||||
drawSignatureEnabled: team?.teamGlobalSettings?.drawSignatureEnabled ?? true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user