chore: merge main

This commit is contained in:
Catalin Documenso
2025-06-24 10:49:08 +03:00
787 changed files with 55308 additions and 42985 deletions

View File

@ -124,8 +124,8 @@ export const ZDocumentAuditLogFieldDiffSchema = z.union([
]);
export const ZGenericFromToSchema = z.object({
from: z.string().nullable(),
to: z.string().nullable(),
from: z.union([z.string(), z.array(z.string())]).nullable(),
to: z.union([z.string(), z.array(z.string())]).nullable(),
});
export const ZRecipientDiffActionAuthSchema = ZGenericFromToSchema.extend({
@ -297,7 +297,7 @@ export const ZDocumentAuditLogEventDocumentFieldInsertedSchema = z.object({
},
z
.object({
type: ZRecipientActionAuthTypesSchema,
type: ZRecipientActionAuthTypesSchema.optional(),
})
.optional(),
),
@ -385,7 +385,7 @@ export const ZDocumentAuditLogEventDocumentFieldPrefilledSchema = z.object({
},
z
.object({
type: ZRecipientActionAuthTypesSchema,
type: ZRecipientActionAuthTypesSchema.optional(),
})
.optional(),
),
@ -429,7 +429,13 @@ export const ZDocumentAuditLogEventDocumentMetaUpdatedSchema = z.object({
export const ZDocumentAuditLogEventDocumentOpenedSchema = z.object({
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED),
data: ZBaseRecipientDataSchema.extend({
accessAuth: z.string().optional(),
accessAuth: z.preprocess((unknownValue) => {
if (!unknownValue) {
return [];
}
return Array.isArray(unknownValue) ? unknownValue : [unknownValue];
}, z.array(ZRecipientAccessAuthTypesSchema)),
}),
});
@ -439,7 +445,13 @@ export const ZDocumentAuditLogEventDocumentOpenedSchema = z.object({
export const ZDocumentAuditLogEventDocumentRecipientCompleteSchema = z.object({
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED),
data: ZBaseRecipientDataSchema.extend({
actionAuth: z.string().optional(),
actionAuth: z.preprocess((unknownValue) => {
if (!unknownValue) {
return [];
}
return Array.isArray(unknownValue) ? unknownValue : [unknownValue];
}, z.array(ZRecipientActionAuthTypesSchema)),
}),
});
@ -517,8 +529,20 @@ export const ZDocumentAuditLogEventFieldUpdatedSchema = z.object({
export const ZDocumentAuditLogEventRecipientAddedSchema = z.object({
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED),
data: ZBaseRecipientDataSchema.extend({
accessAuth: ZRecipientAccessAuthTypesSchema.optional(),
actionAuth: ZRecipientActionAuthTypesSchema.optional(),
accessAuth: z.preprocess((unknownValue) => {
if (!unknownValue) {
return [];
}
return Array.isArray(unknownValue) ? unknownValue : [unknownValue];
}, z.array(ZRecipientAccessAuthTypesSchema)),
actionAuth: z.preprocess((unknownValue) => {
if (!unknownValue) {
return [];
}
return Array.isArray(unknownValue) ? unknownValue : [unknownValue];
}, z.array(ZRecipientActionAuthTypesSchema)),
}),
});

View File

@ -9,8 +9,10 @@ export const ZDocumentAuthTypesSchema = z.enum([
'ACCOUNT',
'PASSKEY',
'TWO_FACTOR_AUTH',
'PASSWORD',
'EXPLICIT_NONE',
]);
export const DocumentAuth = ZDocumentAuthTypesSchema.Enum;
const ZDocumentAuthAccountSchema = z.object({
@ -27,6 +29,11 @@ const ZDocumentAuthPasskeySchema = z.object({
tokenReference: z.string().min(1),
});
const ZDocumentAuthPasswordSchema = z.object({
type: z.literal(DocumentAuth.PASSWORD),
password: z.string().min(1),
});
const ZDocumentAuth2FASchema = z.object({
type: z.literal(DocumentAuth.TWO_FACTOR_AUTH),
token: z.string().min(4).max(10),
@ -40,6 +47,7 @@ export const ZDocumentAuthMethodsSchema = z.discriminatedUnion('type', [
ZDocumentAuthExplicitNoneSchema,
ZDocumentAuthPasskeySchema,
ZDocumentAuth2FASchema,
ZDocumentAuthPasswordSchema,
]);
/**
@ -61,9 +69,15 @@ export const ZDocumentActionAuthSchema = z.discriminatedUnion('type', [
ZDocumentAuthAccountSchema,
ZDocumentAuthPasskeySchema,
ZDocumentAuth2FASchema,
ZDocumentAuthPasswordSchema,
]);
export const ZDocumentActionAuthTypesSchema = z
.enum([DocumentAuth.ACCOUNT, DocumentAuth.PASSKEY, DocumentAuth.TWO_FACTOR_AUTH])
.enum([
DocumentAuth.ACCOUNT,
DocumentAuth.PASSKEY,
DocumentAuth.TWO_FACTOR_AUTH,
DocumentAuth.PASSWORD,
])
.describe(
'The type of authentication required for the recipient to sign the document. This field is restricted to Enterprise plan users only.',
);
@ -89,6 +103,7 @@ export const ZRecipientActionAuthSchema = z.discriminatedUnion('type', [
ZDocumentAuthAccountSchema,
ZDocumentAuthPasskeySchema,
ZDocumentAuth2FASchema,
ZDocumentAuthPasswordSchema,
ZDocumentAuthExplicitNoneSchema,
]);
export const ZRecipientActionAuthTypesSchema = z
@ -96,6 +111,7 @@ export const ZRecipientActionAuthTypesSchema = z
DocumentAuth.ACCOUNT,
DocumentAuth.PASSKEY,
DocumentAuth.TWO_FACTOR_AUTH,
DocumentAuth.PASSWORD,
DocumentAuth.EXPLICIT_NONE,
])
.describe('The type of authentication required for the recipient to sign the document.');
@ -110,18 +126,26 @@ export const RecipientActionAuth = ZRecipientActionAuthTypesSchema.Enum;
*/
export const ZDocumentAuthOptionsSchema = z.preprocess(
(unknownValue) => {
if (unknownValue) {
return unknownValue;
if (!unknownValue || typeof unknownValue !== 'object') {
return {
globalAccessAuth: [],
globalActionAuth: [],
};
}
const globalAccessAuth =
'globalAccessAuth' in unknownValue ? processAuthValue(unknownValue.globalAccessAuth) : [];
const globalActionAuth =
'globalActionAuth' in unknownValue ? processAuthValue(unknownValue.globalActionAuth) : [];
return {
globalAccessAuth: null,
globalActionAuth: null,
globalAccessAuth,
globalActionAuth,
};
},
z.object({
globalAccessAuth: ZDocumentAccessAuthTypesSchema.nullable(),
globalActionAuth: ZDocumentActionAuthTypesSchema.nullable(),
globalAccessAuth: z.array(ZDocumentAccessAuthTypesSchema),
globalActionAuth: z.array(ZDocumentActionAuthTypesSchema),
}),
);
@ -130,21 +154,46 @@ export const ZDocumentAuthOptionsSchema = z.preprocess(
*/
export const ZRecipientAuthOptionsSchema = z.preprocess(
(unknownValue) => {
if (unknownValue) {
return unknownValue;
if (!unknownValue || typeof unknownValue !== 'object') {
return {
accessAuth: [],
actionAuth: [],
};
}
const accessAuth =
'accessAuth' in unknownValue ? processAuthValue(unknownValue.accessAuth) : [];
const actionAuth =
'actionAuth' in unknownValue ? processAuthValue(unknownValue.actionAuth) : [];
return {
accessAuth: null,
actionAuth: null,
accessAuth,
actionAuth,
};
},
z.object({
accessAuth: ZRecipientAccessAuthTypesSchema.nullable(),
actionAuth: ZRecipientActionAuthTypesSchema.nullable(),
accessAuth: z.array(ZRecipientAccessAuthTypesSchema),
actionAuth: z.array(ZRecipientActionAuthTypesSchema),
}),
);
/**
* Utility function to process the auth value.
*
* Converts the old singular auth value to an array of auth values.
*/
const processAuthValue = (value: unknown) => {
if (value === null || value === undefined) {
return [];
}
if (Array.isArray(value)) {
return value;
}
return [value];
};
export type TDocumentAuth = z.infer<typeof ZDocumentAuthTypesSchema>;
export type TDocumentAuthMethods = z.infer<typeof ZDocumentAuthMethodsSchema>;
export type TDocumentAuthOptions = z.infer<typeof ZDocumentAuthOptionsSchema>;

View File

@ -155,6 +155,10 @@ export const ZFieldMetaPrefillFieldsSchema = z
label: z.string().optional(),
value: z.string().optional(),
}),
z.object({
type: z.literal('date'),
value: z.string().optional(),
}),
]),
);

View File

@ -0,0 +1,45 @@
import type { z } from 'zod';
import OrganisationClaimSchema from '@documenso/prisma/generated/zod/modelSchema/OrganisationClaimSchema';
import { OrganisationSchema } from '@documenso/prisma/generated/zod/modelSchema/OrganisationSchema';
export const ZOrganisationSchema = OrganisationSchema.pick({
id: true,
createdAt: true,
updatedAt: true,
type: true,
name: true,
url: true,
avatarImageId: true,
customerId: true,
ownerUserId: true,
}).extend({
organisationClaim: OrganisationClaimSchema.pick({
id: true,
createdAt: true,
updatedAt: true,
originalSubscriptionClaimId: true,
teamCount: true,
memberCount: true,
flags: true,
}),
});
export type TOrganisation = z.infer<typeof ZOrganisationSchema>;
export const ZOrganisationLiteSchema = OrganisationSchema.pick({
id: true,
createdAt: true,
updatedAt: true,
type: true,
name: true,
url: true,
avatarImageId: true,
customerId: true,
ownerUserId: true,
});
/**
* A version of the organisation response schema when returning multiple organisations at once from a single API endpoint.
*/
export const ZOrganisationManySchema = ZOrganisationLiteSchema;

View File

@ -0,0 +1,177 @@
import type { SubscriptionClaim } from '@prisma/client';
import { z } from 'zod';
import { ZOrganisationNameSchema } from '@documenso/trpc/server/organisation-router/create-organisation.types';
/**
* README:
* - If you update this you MUST update the `backport-subscription-claims` schema as well.
*/
export const ZClaimFlagsSchema = z.object({
/**
* Allows disabling of Documenso branding for:
* - Certificates
* - Emails
* - Other?
*/
allowCustomBranding: z.boolean().optional(),
hidePoweredBy: z.boolean().optional(),
unlimitedDocuments: z.boolean().optional(),
embedAuthoring: z.boolean().optional(),
embedAuthoringWhiteLabel: z.boolean().optional(),
embedSigning: z.boolean().optional(),
embedSigningWhiteLabel: z.boolean().optional(),
cfr21: z.boolean().optional(),
});
export type TClaimFlags = z.infer<typeof ZClaimFlagsSchema>;
// When adding keys, update internal documentation with this.
export const SUBSCRIPTION_CLAIM_FEATURE_FLAGS: Record<
keyof TClaimFlags,
{
label: string;
key: keyof TClaimFlags;
}
> = {
unlimitedDocuments: {
key: 'unlimitedDocuments',
label: 'Unlimited documents',
},
allowCustomBranding: {
key: 'allowCustomBranding',
label: 'Branding',
},
hidePoweredBy: {
key: 'hidePoweredBy',
label: 'Hide Documenso branding by',
},
embedAuthoring: {
key: 'embedAuthoring',
label: 'Embed authoring',
},
embedSigning: {
key: 'embedSigning',
label: 'Embed signing',
},
embedAuthoringWhiteLabel: {
key: 'embedAuthoringWhiteLabel',
label: 'White label for embed authoring',
},
embedSigningWhiteLabel: {
key: 'embedSigningWhiteLabel',
label: 'White label for embed signing',
},
cfr21: {
key: 'cfr21',
label: '21 CFR',
},
};
export enum INTERNAL_CLAIM_ID {
FREE = 'free',
INDIVIDUAL = 'individual',
TEAM = 'team',
EARLY_ADOPTER = 'earlyAdopter',
PLATFORM = 'platform',
ENTERPRISE = 'enterprise',
}
export type InternalClaim = Omit<SubscriptionClaim, 'createdAt' | 'updatedAt'>;
export type InternalClaims = {
[key in INTERNAL_CLAIM_ID]: InternalClaim;
};
export const internalClaims: InternalClaims = {
[INTERNAL_CLAIM_ID.FREE]: {
id: INTERNAL_CLAIM_ID.FREE,
name: 'Free',
teamCount: 1,
memberCount: 1,
locked: true,
flags: {},
},
[INTERNAL_CLAIM_ID.INDIVIDUAL]: {
id: INTERNAL_CLAIM_ID.INDIVIDUAL,
name: 'Individual',
teamCount: 1,
memberCount: 1,
locked: true,
flags: {
unlimitedDocuments: true,
},
},
[INTERNAL_CLAIM_ID.TEAM]: {
id: INTERNAL_CLAIM_ID.TEAM,
name: 'Teams',
teamCount: 1,
memberCount: 5,
locked: true,
flags: {
unlimitedDocuments: true,
allowCustomBranding: true,
embedSigning: true,
},
},
[INTERNAL_CLAIM_ID.PLATFORM]: {
id: INTERNAL_CLAIM_ID.PLATFORM,
name: 'Platform',
teamCount: 1,
memberCount: 0,
locked: true,
flags: {
unlimitedDocuments: true,
allowCustomBranding: true,
hidePoweredBy: true,
embedAuthoring: false,
embedAuthoringWhiteLabel: true,
embedSigning: false,
embedSigningWhiteLabel: true,
},
},
[INTERNAL_CLAIM_ID.ENTERPRISE]: {
id: INTERNAL_CLAIM_ID.ENTERPRISE,
name: 'Enterprise',
teamCount: 0,
memberCount: 0,
locked: true,
flags: {
unlimitedDocuments: true,
allowCustomBranding: true,
hidePoweredBy: true,
embedAuthoring: true,
embedAuthoringWhiteLabel: true,
embedSigning: true,
embedSigningWhiteLabel: true,
cfr21: true,
},
},
[INTERNAL_CLAIM_ID.EARLY_ADOPTER]: {
id: INTERNAL_CLAIM_ID.EARLY_ADOPTER,
name: 'Early Adopter',
teamCount: 0,
memberCount: 0,
locked: true,
flags: {
unlimitedDocuments: true,
allowCustomBranding: true,
hidePoweredBy: true,
embedSigning: true,
embedSigningWhiteLabel: true,
},
},
} as const;
export const ZStripeOrganisationCreateMetadataSchema = z.object({
organisationName: ZOrganisationNameSchema,
userId: z.number(),
});
export type StripeOrganisationCreateMetadata = z.infer<
typeof ZStripeOrganisationCreateMetadataSchema
>;