mirror of
https://github.com/documenso/documenso.git
synced 2026-06-22 04:12:06 +10:00
fix: add email disable flag (#2931)
This commit is contained in:
@@ -3,10 +3,10 @@ import {
|
||||
createOrganisationClaimUpsertData,
|
||||
} from '@documenso/lib/server-only/organisation/create-organisation';
|
||||
import type { Stripe } from '@documenso/lib/server-only/stripe';
|
||||
import type { InternalClaim, StripeOrganisationCreateMetadata } from '@documenso/lib/types/subscription';
|
||||
import type { StripeOrganisationCreateMetadata } from '@documenso/lib/types/subscription';
|
||||
import { INTERNAL_CLAIM_ID, ZStripeOrganisationCreateMetadataSchema } from '@documenso/lib/types/subscription';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { OrganisationType, SubscriptionStatus } from '@prisma/client';
|
||||
import { OrganisationType, type SubscriptionClaim, SubscriptionStatus } from '@prisma/client';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { extractStripeClaim } from './on-subscription-updated';
|
||||
@@ -108,7 +108,7 @@ export const onSubscriptionCreated = async ({ subscription }: OnSubscriptionCrea
|
||||
|
||||
type HandleOrganisationCreateOptions = {
|
||||
customerId: string;
|
||||
claim: InternalClaim;
|
||||
claim: Omit<SubscriptionClaim, 'createdAt' | 'updatedAt'>;
|
||||
unknownCreateData: string;
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ const handleOrganisationCreate = async ({ customerId, claim, unknownCreateData }
|
||||
|
||||
type HandleOrganisationUpdateOptions = {
|
||||
customerId: string;
|
||||
claim: InternalClaim;
|
||||
claim: Omit<SubscriptionClaim, 'createdAt' | 'updatedAt'>;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ export const run = async ({ payload, io }: { payload: TSendDocumentCancelledEmai
|
||||
},
|
||||
});
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, isOrganisationOwnerDisabled, organisationId, claims } =
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims, emailsDisabled } =
|
||||
await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
@@ -60,8 +60,8 @@ export const run = async ({ payload, io }: { payload: TSendDocumentCancelledEmai
|
||||
|
||||
const { documentMeta, user: documentOwner } = envelope;
|
||||
|
||||
// Don't send cancellation emails on behalf of a disabled (e.g. banned) account.
|
||||
if (isOrganisationOwnerDisabled || documentOwner.disabled) {
|
||||
// Don't send cancellation emails if the organisation has email sending disabled or the owner is disabled (e.g. banned).
|
||||
if (emailsDisabled || documentOwner.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ export const run = async ({ payload, io }: { payload: TSendDocumentCompletedEmai
|
||||
throw new Error('Document has no recipients');
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, isOrganisationOwnerDisabled, organisationId, claims } =
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims, emailsDisabled } =
|
||||
await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
@@ -77,8 +77,8 @@ export const run = async ({ payload, io }: { payload: TSendDocumentCompletedEmai
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't send completion emails on behalf of a disabled (e.g. banned) account.
|
||||
if (envelope.user.disabled || isOrganisationOwnerDisabled) {
|
||||
// Don't send completion emails if the organisation has email sending disabled or the owner is disabled (e.g. banned).
|
||||
if (envelope.user.disabled || emailsDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export const run = async ({ payload, io }: { payload: TSendOwnerRecipientExpired
|
||||
return;
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail } = await getEmailContext({
|
||||
const { branding, emailLanguage, senderEmail, emailsDisabled } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
@@ -71,6 +71,11 @@ export const run = async ({ payload, io }: { payload: TSendOwnerRecipientExpired
|
||||
meta: documentMeta,
|
||||
});
|
||||
|
||||
// Don't send any emails if the organisation has email sending disabled.
|
||||
if (emailsDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const i18n = await getI18nInstance(emailLanguage);
|
||||
|
||||
const documentLink = `${NEXT_PUBLIC_WEBAPP_URL()}${formatDocumentsPath(envelope.team.url)}/${envelope.id}`;
|
||||
|
||||
@@ -64,7 +64,7 @@ export const run = async ({ payload, io }: { payload: TSendSigningRejectionEmail
|
||||
return;
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail } = await getEmailContext({
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, emailsDisabled } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
@@ -75,8 +75,10 @@ export const run = async ({ payload, io }: { payload: TSendSigningRejectionEmail
|
||||
|
||||
const i18n = await getI18nInstance(emailLanguage);
|
||||
|
||||
// Send confirmation email to the recipient who rejected
|
||||
if (isRecipientEmailValidForSending(recipient)) {
|
||||
// Send confirmation email to the recipient who rejected.
|
||||
// Skipped when the organisation has email sending disabled, since this is sent on its behalf.
|
||||
// The owner notification below intentionally uses the internal Documenso email, so it still sends.
|
||||
if (!emailsDisabled && isRecipientEmailValidForSending(recipient)) {
|
||||
await io.runTask('send-rejection-confirmation-email', async () => {
|
||||
const recipientTemplate = createElement(DocumentRejectionConfirmedEmail, {
|
||||
recipientName: recipient.name,
|
||||
|
||||
@@ -99,7 +99,7 @@ export const run = async ({ payload, io }: { payload: TSendSigningEmailJobDefini
|
||||
replyToEmail,
|
||||
organisationId,
|
||||
claims,
|
||||
isOrganisationOwnerDisabled,
|
||||
emailsDisabled,
|
||||
} = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
@@ -109,8 +109,8 @@ export const run = async ({ payload, io }: { payload: TSendSigningEmailJobDefini
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't send signing invitations on behalf of a disabled (e.g. banned) account.
|
||||
if (envelope.user.disabled || isOrganisationOwnerDisabled) {
|
||||
// Don't send signing invitations if the organisation has email sending disabled or the owner is disabled (e.g. banned).
|
||||
if (envelope.user.disabled || emailsDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const BACKPORT_SUBSCRIPTION_CLAIM_JOB_DEFINITION_SCHEMA = z.object({
|
||||
cfr21: z.literal(true).optional(),
|
||||
hipaa: z.literal(true).optional(),
|
||||
signingReminders: z.literal(true).optional(),
|
||||
disableEmails: z.literal(true).optional(),
|
||||
// Todo: Envelopes - Do we need to check?
|
||||
// authenticationPortal & emailDomains missing here.
|
||||
}),
|
||||
|
||||
@@ -108,9 +108,9 @@ export const run = async ({ payload, io }: { payload: TProcessSigningReminderJob
|
||||
organisationType,
|
||||
senderEmail,
|
||||
replyToEmail,
|
||||
isOrganisationOwnerDisabled,
|
||||
organisationId,
|
||||
claims,
|
||||
emailsDisabled,
|
||||
} = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
@@ -120,9 +120,10 @@ export const run = async ({ payload, io }: { payload: TProcessSigningReminderJob
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't send reminders on behalf of a disabled (e.g. banned) account.
|
||||
if (envelope.user.disabled || isOrganisationOwnerDisabled) {
|
||||
io.logger.info(`Envelope ${envelope.id} owner is disabled, skipping reminder`);
|
||||
// Don't send reminders if the owner is disabled (e.g. banned) or the organisation
|
||||
// has email sending disabled.
|
||||
if (envelope.user.disabled || emailsDisabled) {
|
||||
io.logger.info(`Envelope ${envelope.id} skipping reminder: owner disabled or organisation emails disabled`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ const handleDocumentOwnerDelete = async ({ envelope, user, requestMetadata }: Ha
|
||||
return;
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail } = await getEmailContext({
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, emailsDisabled } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
@@ -187,7 +187,9 @@ const handleDocumentOwnerDelete = async ({ envelope, user, requestMetadata }: Ha
|
||||
|
||||
const isEnvelopeDeleteEmailEnabled = extractDerivedDocumentEmailSettings(envelope.documentMeta).documentDeleted;
|
||||
|
||||
if (!isEnvelopeDeleteEmailEnabled) {
|
||||
// Skip sending if the email is disabled for this document or the organisation
|
||||
// has email sending disabled entirely.
|
||||
if (!isEnvelopeDeleteEmailEnabled || emailsDisabled) {
|
||||
return deletedEnvelope;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,15 +151,28 @@ export const resendDocument = async ({ id, userId, recipients, teamId, requestMe
|
||||
return envelope;
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, organisationType, senderEmail, replyToEmail, organisationId, claims } =
|
||||
await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId: envelope.teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
const {
|
||||
branding,
|
||||
emailLanguage,
|
||||
organisationType,
|
||||
senderEmail,
|
||||
replyToEmail,
|
||||
organisationId,
|
||||
claims,
|
||||
emailsDisabled,
|
||||
} = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId: envelope.teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't resend any emails if the organisation has email sending disabled.
|
||||
if (user.disabled || emailsDisabled) {
|
||||
return envelope;
|
||||
}
|
||||
|
||||
// Assert that there is enough quota to send the emails.
|
||||
await assertOrganisationRatesAndLimits({
|
||||
|
||||
@@ -47,7 +47,7 @@ export const sendPendingEmail = async ({ id, recipientId }: SendPendingEmailOpti
|
||||
throw new Error('Document has no recipients');
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail } = await getEmailContext({
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, emailsDisabled } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
@@ -56,6 +56,11 @@ export const sendPendingEmail = async ({ id, recipientId }: SendPendingEmailOpti
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't send any emails if the organisation has email sending disabled.
|
||||
if (emailsDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isDocumentPendingEmailEnabled = extractDerivedDocumentEmailSettings(envelope.documentMeta).documentPending;
|
||||
|
||||
if (!isDocumentPendingEmailEnabled) {
|
||||
|
||||
@@ -66,6 +66,12 @@ export type EmailContextResponse = {
|
||||
branding: BrandingSettings;
|
||||
settings: Omit<OrganisationGlobalSettings, 'id'>;
|
||||
claims: OrganisationClaim;
|
||||
/**
|
||||
* Whether the organisation is prevented from sending emails.
|
||||
*
|
||||
* When true, ALL emails sent on behalf of this organisation must be skipped.
|
||||
*/
|
||||
emailsDisabled: boolean;
|
||||
organisationId: string;
|
||||
organisationType: OrganisationType;
|
||||
senderEmail: {
|
||||
@@ -74,7 +80,6 @@ export type EmailContextResponse = {
|
||||
};
|
||||
replyToEmail: string | undefined;
|
||||
emailLanguage: string;
|
||||
isOrganisationOwnerDisabled: boolean;
|
||||
};
|
||||
|
||||
export const getEmailContext = async (options: GetEmailContextOptions): Promise<EmailContextResponse> => {
|
||||
@@ -171,9 +176,9 @@ const handleOrganisationEmailContext = async (organisationId: string) => {
|
||||
),
|
||||
settings: organisation.organisationGlobalSettings,
|
||||
claims,
|
||||
emailsDisabled: organisation.owner.disabled || claims.flags.disableEmails === true,
|
||||
organisationId: organisation.id,
|
||||
organisationType: organisation.type,
|
||||
isOrganisationOwnerDisabled: organisation.owner.disabled,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -223,9 +228,9 @@ const handleTeamEmailContext = async (teamId: number) => {
|
||||
branding: teamGlobalSettingsToBranding(teamSettings, teamId, claims.flags.hidePoweredBy ?? false),
|
||||
settings: teamSettings,
|
||||
claims,
|
||||
emailsDisabled: organisation.owner.disabled || claims.flags.disableEmails === true,
|
||||
organisationId: organisation.id,
|
||||
organisationType: organisation.type,
|
||||
isOrganisationOwnerDisabled: organisation.owner.disabled,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ export const sendOrganisationMemberInviteEmail = async ({
|
||||
organisationName: organisation.name,
|
||||
});
|
||||
|
||||
const { branding, emailLanguage, senderEmail } = await getEmailContext({
|
||||
const { branding, emailLanguage, senderEmail, emailsDisabled } = await getEmailContext({
|
||||
emailType: 'INTERNAL',
|
||||
source: {
|
||||
type: 'organisation',
|
||||
@@ -195,6 +195,12 @@ export const sendOrganisationMemberInviteEmail = async ({
|
||||
},
|
||||
});
|
||||
|
||||
// Member invites can be sent to anyone, so block them when the organisation has email
|
||||
// sending disabled.
|
||||
if (emailsDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [html, text] = await Promise.all([
|
||||
renderEmailWithI18N(template, {
|
||||
lang: emailLanguage,
|
||||
|
||||
@@ -6,7 +6,6 @@ import { OrganisationMemberRole, OrganisationType, Prisma, type SubscriptionClai
|
||||
import { IS_BILLING_ENABLED } from '../../constants/app';
|
||||
import { ORGANISATION_INTERNAL_GROUPS } from '../../constants/organisations';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { InternalClaim } from '../../types/subscription';
|
||||
import { INTERNAL_CLAIM_ID } from '../../types/subscription';
|
||||
import { generateDatabaseId, prefixedId } from '../../universal/id';
|
||||
import { generateDefaultOrganisationSettings } from '../../utils/organisations';
|
||||
@@ -18,7 +17,7 @@ type CreateOrganisationOptions = {
|
||||
type: OrganisationType;
|
||||
url?: string;
|
||||
customerId?: string;
|
||||
claim: InternalClaim;
|
||||
claim: Omit<SubscriptionClaim, 'createdAt' | 'updatedAt'>;
|
||||
};
|
||||
|
||||
export const createOrganisation = async ({ name, url, type, userId, customerId, claim }: CreateOrganisationOptions) => {
|
||||
|
||||
@@ -152,14 +152,20 @@ export const deleteEnvelopeRecipient = async ({
|
||||
assetBaseUrl,
|
||||
});
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId: envelope.teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims, emailsDisabled } =
|
||||
await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId: envelope.teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
// Don't send the removal email if the organisation has email sending disabled.
|
||||
if (emailsDisabled) {
|
||||
return deletedRecipient;
|
||||
}
|
||||
|
||||
// Meter the removal email against the organisation email quota/stats.
|
||||
// Add/remove churn can be used to blast unsolicited removal emails
|
||||
|
||||
@@ -85,14 +85,15 @@ export const setDocumentRecipients = async ({
|
||||
throw new Error('Document already complete');
|
||||
}
|
||||
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims } = await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
const { branding, emailLanguage, senderEmail, replyToEmail, organisationId, claims, emailsDisabled } =
|
||||
await getEmailContext({
|
||||
emailType: 'RECIPIENT',
|
||||
source: {
|
||||
type: 'team',
|
||||
teamId,
|
||||
},
|
||||
meta: envelope.documentMeta,
|
||||
});
|
||||
|
||||
const recipientsHaveActionAuth = recipients.some(
|
||||
(recipient) => recipient.actionAuth && recipient.actionAuth.length > 0,
|
||||
@@ -281,6 +282,7 @@ export const setDocumentRecipients = async ({
|
||||
await Promise.all(
|
||||
removedRecipients.map(async (recipient) => {
|
||||
if (
|
||||
emailsDisabled ||
|
||||
recipient.sendStatus !== SendStatus.SENT ||
|
||||
recipient.role === RecipientRole.CC ||
|
||||
!isRecipientRemovedEmailEnabled ||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { INTERNAL_CLAIM_ID, internalClaims } from '@documenso/lib/types/subscription';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { SubscriptionClaim } from '@prisma/client';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
@@ -12,12 +10,6 @@ export const getSubscriptionClaim = async (
|
||||
});
|
||||
|
||||
if (!subscriptionClaim) {
|
||||
// Temporary fallback for free claim so we don't break self-hosters who somehow removed it
|
||||
// from the database.
|
||||
if (claimId === INTERNAL_CLAIM_ID.FREE) {
|
||||
return internalClaims[INTERNAL_CLAIM_ID.FREE];
|
||||
}
|
||||
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: `Subscription claim ${claimId} not found`,
|
||||
});
|
||||
|
||||
@@ -51,6 +51,13 @@ export const ZClaimFlagsSchema = z.object({
|
||||
allowLegacyEnvelopes: z.boolean().optional(),
|
||||
|
||||
signingReminders: z.boolean().optional(),
|
||||
|
||||
/**
|
||||
* Controls whether an organisation is prevented from sending emails.
|
||||
*
|
||||
* When this is enabled, ALL emails for the organisation are blocked.
|
||||
*/
|
||||
disableEmails: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type TClaimFlags = z.infer<typeof ZClaimFlagsSchema>;
|
||||
@@ -122,6 +129,10 @@ export const SUBSCRIPTION_CLAIM_FEATURE_FLAGS: Record<
|
||||
key: 'signingReminders',
|
||||
label: 'Signing reminders',
|
||||
},
|
||||
disableEmails: {
|
||||
key: 'disableEmails',
|
||||
label: 'Disable emails',
|
||||
},
|
||||
};
|
||||
|
||||
export enum INTERNAL_CLAIM_ID {
|
||||
@@ -133,20 +144,12 @@ export enum INTERNAL_CLAIM_ID {
|
||||
ENTERPRISE = 'enterprise',
|
||||
}
|
||||
|
||||
export type InternalClaim = Omit<SubscriptionClaim, 'createdAt' | 'updatedAt'>;
|
||||
export type InternalClaim = Pick<SubscriptionClaim, 'id' | 'name'>;
|
||||
|
||||
export type InternalClaims = {
|
||||
[key in INTERNAL_CLAIM_ID]: InternalClaim;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: THIS NEEDS A REWORK
|
||||
*
|
||||
* Only the values within "free" claim (flags, etc) are directly used, the rest are taken
|
||||
* from the actual SubscriptionClaim in the database.
|
||||
*
|
||||
* We need to remove all the content besides id/name and fetch free from the database.
|
||||
*/
|
||||
export const internalClaims: InternalClaims = {
|
||||
/**
|
||||
* Free plan has no rates and quotas since this may break self-hosters.
|
||||
@@ -154,135 +157,26 @@ export const internalClaims: InternalClaims = {
|
||||
[INTERNAL_CLAIM_ID.FREE]: {
|
||||
id: INTERNAL_CLAIM_ID.FREE,
|
||||
name: 'Free',
|
||||
teamCount: 1,
|
||||
memberCount: 1,
|
||||
envelopeItemCount: 5,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
[INTERNAL_CLAIM_ID.INDIVIDUAL]: {
|
||||
id: INTERNAL_CLAIM_ID.INDIVIDUAL,
|
||||
name: 'Individual',
|
||||
teamCount: 1,
|
||||
memberCount: 1,
|
||||
envelopeItemCount: 5,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {
|
||||
unlimitedDocuments: true,
|
||||
signingReminders: true,
|
||||
},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
[INTERNAL_CLAIM_ID.TEAM]: {
|
||||
id: INTERNAL_CLAIM_ID.TEAM,
|
||||
name: 'Teams',
|
||||
teamCount: 1,
|
||||
memberCount: 5,
|
||||
envelopeItemCount: 5,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {
|
||||
unlimitedDocuments: true,
|
||||
allowCustomBranding: true,
|
||||
embedSigning: true,
|
||||
signingReminders: true,
|
||||
},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
[INTERNAL_CLAIM_ID.PLATFORM]: {
|
||||
id: INTERNAL_CLAIM_ID.PLATFORM,
|
||||
name: 'Platform',
|
||||
teamCount: 1,
|
||||
memberCount: 0,
|
||||
envelopeItemCount: 10,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {
|
||||
unlimitedDocuments: true,
|
||||
allowCustomBranding: true,
|
||||
hidePoweredBy: true,
|
||||
emailDomains: false,
|
||||
embedAuthoring: false,
|
||||
embedAuthoringWhiteLabel: true,
|
||||
embedSigning: false,
|
||||
embedSigningWhiteLabel: true,
|
||||
signingReminders: true,
|
||||
},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
[INTERNAL_CLAIM_ID.ENTERPRISE]: {
|
||||
id: INTERNAL_CLAIM_ID.ENTERPRISE,
|
||||
name: 'Enterprise',
|
||||
teamCount: 0,
|
||||
memberCount: 0,
|
||||
envelopeItemCount: 10,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {
|
||||
unlimitedDocuments: true,
|
||||
allowCustomBranding: true,
|
||||
hidePoweredBy: true,
|
||||
emailDomains: true,
|
||||
embedAuthoring: true,
|
||||
embedAuthoringWhiteLabel: true,
|
||||
embedSigning: true,
|
||||
embedSigningWhiteLabel: true,
|
||||
cfr21: true,
|
||||
authenticationPortal: true,
|
||||
signingReminders: true,
|
||||
},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
[INTERNAL_CLAIM_ID.EARLY_ADOPTER]: {
|
||||
id: INTERNAL_CLAIM_ID.EARLY_ADOPTER,
|
||||
name: 'Early Adopter',
|
||||
teamCount: 0,
|
||||
memberCount: 0,
|
||||
envelopeItemCount: 5,
|
||||
recipientCount: 0,
|
||||
locked: true,
|
||||
flags: {
|
||||
unlimitedDocuments: true,
|
||||
allowCustomBranding: true,
|
||||
hidePoweredBy: true,
|
||||
embedSigning: true,
|
||||
embedSigningWhiteLabel: true,
|
||||
signingReminders: true,
|
||||
},
|
||||
documentRateLimits: [],
|
||||
documentQuota: null,
|
||||
emailRateLimits: [],
|
||||
emailQuota: null,
|
||||
apiRateLimits: [],
|
||||
apiQuota: null,
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user