feat: complete document 2fa (wip)

This commit is contained in:
Ephraim Atta-Duncan
2025-04-23 08:26:52 +00:00
parent b94645a451
commit 35db8182f0
9 changed files with 171 additions and 84 deletions
@@ -1,8 +1,6 @@
import { DocumentVisibility } from '@prisma/client';
import { DocumentStatus, TeamMemberRole } from '@prisma/client';
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@prisma/client';
import { match } from 'ts-pattern';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import type { CreateDocumentAuditLogDataResponse } from '@documenso/lib/utils/document-audit-logs';
@@ -135,18 +133,18 @@ export const updateDocument = async ({
data?.globalActionAuth === undefined ? documentGlobalActionAuth : data.globalActionAuth;
// Check if user has permission to set the global action auth.
if (newGlobalActionAuth) {
const isDocumentEnterprise = await isUserEnterprise({
userId,
teamId,
});
// if (newGlobalActionAuth) {
// const isDocumentEnterprise = await isUserEnterprise({
// userId,
// teamId,
// });
if (!isDocumentEnterprise) {
throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'You do not have permission to set the action auth',
});
}
}
// if (!isDocumentEnterprise) {
// throw new AppError(AppErrorCode.UNAUTHORIZED, {
// message: 'You do not have permission to set the action auth',
// });
// }
// }
const isTitleSame = data.title === undefined || data.title === document.title;
const isExternalIdSame = data.externalId === undefined || data.externalId === document.externalId;
@@ -2,6 +2,7 @@ import { DocumentStatus, FieldType, RecipientRole, SigningStatus } from '@prisma
import { DateTime } from 'luxon';
import { match } from 'ts-pattern';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
@@ -13,7 +14,7 @@ import { prisma } from '@documenso/prisma';
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '../../constants/date-formats';
import { DEFAULT_DOCUMENT_TIME_ZONE } from '../../constants/time-zones';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
import type { TRecipientActionAuth } from '../../types/document-auth';
import type { TRecipientActionAuth, TRecipientActionAuthTypes } from '../../types/document-auth';
import {
ZCheckboxFieldMeta,
ZDropdownFieldMeta,
@@ -23,6 +24,7 @@ import {
} from '../../types/field-meta';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
import { extractDocumentAuthMethods } from '../../utils/document-auth';
import { validateFieldAuth } from '../document/validate-field-auth';
export type SignFieldWithTokenOptions = {
@@ -169,13 +171,24 @@ export const signFieldWithToken = async ({
}
}
const derivedRecipientActionAuth = await validateFieldAuth({
documentAuthOptions: document.authOptions,
recipient,
field,
userId,
authOptions,
});
const isEnterprise = userId ? await isUserEnterprise({ userId }) : false;
let requiredAuthType: TRecipientActionAuthTypes | null = null;
if (isEnterprise) {
requiredAuthType = await validateFieldAuth({
documentAuthOptions: document.authOptions,
recipient,
field,
userId,
authOptions,
});
} else {
const { derivedRecipientActionAuth } = extractDocumentAuthMethods({
documentAuth: document.authOptions,
recipientAuth: recipient.authOptions,
});
requiredAuthType = derivedRecipientActionAuth;
}
const documentMeta = await prisma.documentMeta.findFirst({
where: {
@@ -286,9 +299,9 @@ export const signFieldWithToken = async ({
}),
)
.exhaustive(),
fieldSecurity: derivedRecipientActionAuth
fieldSecurity: requiredAuthType
? {
type: derivedRecipientActionAuth,
type: requiredAuthType,
}
: undefined,
},
+14
View File
@@ -68,6 +68,16 @@ export const ZDocumentActionAuthTypesSchema = z
'The type of authentication required for the recipient to sign the document. This field is restricted to Enterprise plan users only.',
);
/**
* The non-enterprise document action auth methods.
*
* Only includes options available to non-enterprise users.
*/
export const ZNonEnterpriseDocumentActionAuthTypesSchema = z.enum([
DocumentAuth.TWO_FACTOR_AUTH,
DocumentAuth.EXPLICIT_NONE,
]);
/**
* The recipient access auth methods.
*
@@ -102,6 +112,7 @@ export const ZRecipientActionAuthTypesSchema = z
export const DocumentAccessAuth = ZDocumentAccessAuthTypesSchema.Enum;
export const DocumentActionAuth = ZDocumentActionAuthTypesSchema.Enum;
export const NonEnterpriseDocumentActionAuth = ZNonEnterpriseDocumentActionAuthTypesSchema.Enum;
export const RecipientAccessAuth = ZRecipientAccessAuthTypesSchema.Enum;
export const RecipientActionAuth = ZRecipientActionAuthTypesSchema.Enum;
@@ -152,6 +163,9 @@ export type TDocumentAccessAuth = z.infer<typeof ZDocumentAccessAuthSchema>;
export type TDocumentAccessAuthTypes = z.infer<typeof ZDocumentAccessAuthTypesSchema>;
export type TDocumentActionAuth = z.infer<typeof ZDocumentActionAuthSchema>;
export type TDocumentActionAuthTypes = z.infer<typeof ZDocumentActionAuthTypesSchema>;
export type TNonEnterpriseDocumentActionAuthTypes = z.infer<
typeof ZNonEnterpriseDocumentActionAuthTypesSchema
>;
export type TRecipientAccessAuth = z.infer<typeof ZRecipientAccessAuthSchema>;
export type TRecipientAccessAuthTypes = z.infer<typeof ZRecipientAccessAuthTypesSchema>;
export type TRecipientActionAuth = z.infer<typeof ZRecipientActionAuthSchema>;