mirror of
https://github.com/documenso/documenso.git
synced 2025-11-17 10:11:35 +10:00
feat: add organisations (#1820)
This commit is contained in:
@ -2,11 +2,8 @@ import { data } from 'react-router';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||
import { isCommunityPlan as isUserCommunityPlan } from '@documenso/ee/server-only/util/is-community-plan';
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
|
||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
|
||||
import { getOrganisationClaimByTeamId } from '@documenso/lib/server-only/organisation/get-organisation-claims';
|
||||
import { getTemplateByDirectLinkToken } from '@documenso/lib/server-only/template/get-template-by-direct-link-token';
|
||||
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
|
||||
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
||||
@ -36,10 +33,15 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
throw new Response('Not found', { status: 404 });
|
||||
}
|
||||
|
||||
const organisationClaim = await getOrganisationClaimByTeamId({ teamId: template.teamId });
|
||||
|
||||
const allowEmbedSigningWhitelabel = organisationClaim.flags.embedSigningWhiteLabel;
|
||||
const hidePoweredBy = organisationClaim.flags.hidePoweredBy;
|
||||
|
||||
// TODO: Make this more robust, we need to ensure the owner is either
|
||||
// TODO: the member of a team that has an active subscription, is an early
|
||||
// TODO: adopter or is an enterprise user.
|
||||
if (IS_BILLING_ENABLED() && !template.teamId) {
|
||||
if (IS_BILLING_ENABLED() && !organisationClaim.flags.embedSigning) {
|
||||
throw data(
|
||||
{
|
||||
type: 'embed-paywall',
|
||||
@ -56,18 +58,6 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
documentAuth: template.authOptions,
|
||||
});
|
||||
|
||||
const [isPlatformDocument, isEnterpriseDocument, isCommunityPlan] = await Promise.all([
|
||||
isDocumentPlatform(template),
|
||||
isUserEnterprise({
|
||||
userId: template.userId,
|
||||
teamId: template.teamId ?? undefined,
|
||||
}),
|
||||
isUserCommunityPlan({
|
||||
userId: template.userId,
|
||||
teamId: template.teamId ?? undefined,
|
||||
}),
|
||||
]);
|
||||
|
||||
const isAccessAuthValid = match(derivedRecipientAccessAuth.at(0))
|
||||
.with(DocumentAccessAuth.ACCOUNT, () => !!user)
|
||||
.with(undefined, () => true)
|
||||
@ -98,12 +88,6 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
|
||||
const fields = template.fields.filter((field) => field.recipientId === directTemplateRecipientId);
|
||||
|
||||
const team = template.teamId
|
||||
? await getTeamById({ teamId: template.teamId, userId: template.userId }).catch(() => null)
|
||||
: null;
|
||||
|
||||
const hidePoweredBy = team?.teamGlobalSettings?.brandingHidePoweredBy ?? false;
|
||||
|
||||
return superLoaderJson({
|
||||
token,
|
||||
user,
|
||||
@ -111,24 +95,13 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
recipient,
|
||||
fields,
|
||||
hidePoweredBy,
|
||||
isPlatformDocument,
|
||||
isEnterpriseDocument,
|
||||
isCommunityPlan,
|
||||
allowEmbedSigningWhitelabel,
|
||||
});
|
||||
}
|
||||
|
||||
export default function EmbedDirectTemplatePage() {
|
||||
const {
|
||||
token,
|
||||
user,
|
||||
template,
|
||||
recipient,
|
||||
fields,
|
||||
hidePoweredBy,
|
||||
isPlatformDocument,
|
||||
isEnterpriseDocument,
|
||||
isCommunityPlan,
|
||||
} = useSuperLoaderData<typeof loader>();
|
||||
const { token, user, template, recipient, fields, hidePoweredBy, allowEmbedSigningWhitelabel } =
|
||||
useSuperLoaderData<typeof loader>();
|
||||
|
||||
return (
|
||||
<DocumentSigningProvider
|
||||
@ -152,10 +125,8 @@ export default function EmbedDirectTemplatePage() {
|
||||
recipient={recipient}
|
||||
fields={fields}
|
||||
metadata={template.templateMeta}
|
||||
hidePoweredBy={
|
||||
isCommunityPlan || isPlatformDocument || isEnterpriseDocument || hidePoweredBy
|
||||
}
|
||||
allowWhiteLabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
||||
hidePoweredBy={hidePoweredBy}
|
||||
allowWhiteLabelling={allowEmbedSigningWhitelabel}
|
||||
/>
|
||||
</DocumentSigningRecipientProvider>
|
||||
</DocumentSigningAuthProvider>
|
||||
|
||||
@ -3,17 +3,14 @@ import { data } from 'react-router';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||
import { isCommunityPlan as isUserCommunityPlan } from '@documenso/ee/server-only/util/is-community-plan';
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
|
||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||
import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||
import { getCompletedFieldsForToken } from '@documenso/lib/server-only/field/get-completed-fields-for-token';
|
||||
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
|
||||
import { getOrganisationClaimByTeamId } from '@documenso/lib/server-only/organisation/get-organisation-claims';
|
||||
import { getIsRecipientsTurnToSign } from '@documenso/lib/server-only/recipient/get-is-recipient-turn';
|
||||
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
||||
import { getRecipientsForAssistant } from '@documenso/lib/server-only/recipient/get-recipients-for-assistant';
|
||||
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
|
||||
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
|
||||
import { isDocumentCompleted } from '@documenso/lib/utils/document';
|
||||
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
||||
@ -51,10 +48,15 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
throw new Response('Not found', { status: 404 });
|
||||
}
|
||||
|
||||
const organisationClaim = await getOrganisationClaimByTeamId({ teamId: document.teamId });
|
||||
|
||||
const allowEmbedSigningWhitelabel = organisationClaim.flags.embedSigningWhiteLabel;
|
||||
const hidePoweredBy = organisationClaim.flags.hidePoweredBy;
|
||||
|
||||
// TODO: Make this more robust, we need to ensure the owner is either
|
||||
// TODO: the member of a team that has an active subscription, is an early
|
||||
// TODO: adopter or is an enterprise user.
|
||||
if (IS_BILLING_ENABLED() && !document.teamId) {
|
||||
if (IS_BILLING_ENABLED() && !organisationClaim.flags.embedSigning) {
|
||||
throw data(
|
||||
{
|
||||
type: 'embed-paywall',
|
||||
@ -65,18 +67,6 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
);
|
||||
}
|
||||
|
||||
const [isPlatformDocument, isEnterpriseDocument, isCommunityPlan] = await Promise.all([
|
||||
isDocumentPlatform(document),
|
||||
isUserEnterprise({
|
||||
userId: document.userId,
|
||||
teamId: document.teamId ?? undefined,
|
||||
}),
|
||||
isUserCommunityPlan({
|
||||
userId: document.userId,
|
||||
teamId: document.teamId ?? undefined,
|
||||
}),
|
||||
]);
|
||||
|
||||
const { derivedRecipientAccessAuth } = extractDocumentAuthMethods({
|
||||
documentAuth: document.authOptions,
|
||||
});
|
||||
@ -119,12 +109,6 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
})
|
||||
: [];
|
||||
|
||||
const team = document.teamId
|
||||
? await getTeamById({ teamId: document.teamId, userId: document.userId }).catch(() => null)
|
||||
: null;
|
||||
|
||||
const hidePoweredBy = team?.teamGlobalSettings?.brandingHidePoweredBy ?? false;
|
||||
|
||||
return superLoaderJson({
|
||||
token,
|
||||
user,
|
||||
@ -134,9 +118,7 @@ export async function loader({ params, request }: Route.LoaderArgs) {
|
||||
fields,
|
||||
completedFields,
|
||||
hidePoweredBy,
|
||||
isPlatformDocument,
|
||||
isEnterpriseDocument,
|
||||
isCommunityPlan,
|
||||
allowEmbedSigningWhitelabel,
|
||||
});
|
||||
}
|
||||
|
||||
@ -150,9 +132,7 @@ export default function EmbedSignDocumentPage() {
|
||||
fields,
|
||||
completedFields,
|
||||
hidePoweredBy,
|
||||
isPlatformDocument,
|
||||
isEnterpriseDocument,
|
||||
isCommunityPlan,
|
||||
allowEmbedSigningWhitelabel,
|
||||
} = useSuperLoaderData<typeof loader>();
|
||||
|
||||
return (
|
||||
@ -178,10 +158,8 @@ export default function EmbedSignDocumentPage() {
|
||||
completedFields={completedFields}
|
||||
metadata={document.documentMeta}
|
||||
isCompleted={isDocumentCompleted(document.status)}
|
||||
hidePoweredBy={
|
||||
isCommunityPlan || isPlatformDocument || isEnterpriseDocument || hidePoweredBy
|
||||
}
|
||||
allowWhitelabelling={isCommunityPlan || isPlatformDocument || isEnterpriseDocument}
|
||||
hidePoweredBy={hidePoweredBy}
|
||||
allowWhitelabelling={allowEmbedSigningWhitelabel}
|
||||
allRecipients={allRecipients}
|
||||
/>
|
||||
</DocumentSigningAuthProvider>
|
||||
|
||||
@ -2,10 +2,8 @@ import { useLayoutEffect } from 'react';
|
||||
|
||||
import { Outlet, useLoaderData } from 'react-router';
|
||||
|
||||
import { isCommunityPlan } from '@documenso/ee/server-only/util/is-community-plan';
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
|
||||
import { verifyEmbeddingPresignToken } from '@documenso/lib/server-only/embedding-presign/verify-embedding-presign-token';
|
||||
import { getOrganisationClaimByTeamId } from '@documenso/lib/server-only/organisation/get-organisation-claims';
|
||||
import { TrpcProvider } from '@documenso/trpc/react';
|
||||
|
||||
import { ZBaseEmbedAuthoringSchema } from '~/types/embed-authoring-base-schema';
|
||||
@ -27,39 +25,25 @@ export const loader = async ({ request }: Route.LoaderArgs) => {
|
||||
|
||||
const result = await verifyEmbeddingPresignToken({ token }).catch(() => null);
|
||||
|
||||
let hasPlatformPlan = false;
|
||||
let hasEnterprisePlan = false;
|
||||
let hasCommunityPlan = false;
|
||||
let allowEmbedAuthoringWhiteLabel = false;
|
||||
|
||||
if (result) {
|
||||
[hasCommunityPlan, hasPlatformPlan, hasEnterprisePlan] = await Promise.all([
|
||||
isCommunityPlan({
|
||||
userId: result.userId,
|
||||
teamId: result.teamId ?? undefined,
|
||||
}),
|
||||
isDocumentPlatform({
|
||||
userId: result.userId,
|
||||
teamId: result.teamId,
|
||||
}),
|
||||
isUserEnterprise({
|
||||
userId: result.userId,
|
||||
teamId: result.teamId ?? undefined,
|
||||
}),
|
||||
]);
|
||||
const organisationClaim = await getOrganisationClaimByTeamId({
|
||||
teamId: result.teamId,
|
||||
});
|
||||
|
||||
allowEmbedAuthoringWhiteLabel = organisationClaim.flags.embedAuthoringWhiteLabel ?? false;
|
||||
}
|
||||
|
||||
return {
|
||||
hasValidToken: !!result,
|
||||
token,
|
||||
hasCommunityPlan,
|
||||
hasPlatformPlan,
|
||||
hasEnterprisePlan,
|
||||
allowEmbedAuthoringWhiteLabel,
|
||||
};
|
||||
};
|
||||
|
||||
export default function AuthoringLayout() {
|
||||
const { hasValidToken, token, hasCommunityPlan, hasPlatformPlan, hasEnterprisePlan } =
|
||||
useLoaderData<typeof loader>();
|
||||
const { hasValidToken, token, allowEmbedAuthoringWhiteLabel } = useLoaderData<typeof loader>();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
try {
|
||||
@ -79,7 +63,7 @@ export default function AuthoringLayout() {
|
||||
document.documentElement.classList.add('dark-mode-disabled');
|
||||
}
|
||||
|
||||
if (hasCommunityPlan || hasPlatformPlan || hasEnterprisePlan) {
|
||||
if (allowEmbedAuthoringWhiteLabel) {
|
||||
injectCss({
|
||||
css,
|
||||
cssVars,
|
||||
|
||||
@ -4,12 +4,9 @@ import { SigningStatus } from '@prisma/client';
|
||||
import { useRevalidator } from 'react-router';
|
||||
|
||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||
import { isCommunityPlan as isUserCommunityPlan } from '@documenso/ee/server-only/util/is-community-plan';
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
|
||||
import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||
import { getOrganisationClaimByTeamId } from '@documenso/lib/server-only/organisation/get-organisation-claims';
|
||||
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
||||
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
|
||||
|
||||
import { BrandingLogo } from '~/components/general/branding-logo';
|
||||
import { DocumentSigningAuthProvider } from '~/components/general/document-signing/document-signing-auth-provider';
|
||||
@ -54,26 +51,10 @@ export async function loader({ request }: Route.LoaderArgs) {
|
||||
});
|
||||
}
|
||||
|
||||
const team = firstDocument.teamId
|
||||
? await getTeamById({ teamId: firstDocument.teamId, userId: firstDocument.userId }).catch(
|
||||
() => null,
|
||||
)
|
||||
: null;
|
||||
const organisationClaim = await getOrganisationClaimByTeamId({ teamId: firstDocument.teamId });
|
||||
|
||||
const [isPlatformDocument, isEnterpriseDocument, isCommunityPlan] = await Promise.all([
|
||||
isDocumentPlatform(firstDocument),
|
||||
isUserEnterprise({
|
||||
userId: firstDocument.userId,
|
||||
teamId: firstDocument.teamId ?? undefined,
|
||||
}),
|
||||
isUserCommunityPlan({
|
||||
userId: firstDocument.userId,
|
||||
teamId: firstDocument.teamId ?? undefined,
|
||||
}),
|
||||
]);
|
||||
|
||||
const hidePoweredBy = team?.teamGlobalSettings?.brandingHidePoweredBy ?? false;
|
||||
const allowWhitelabelling = isCommunityPlan || isPlatformDocument || isEnterpriseDocument;
|
||||
const allowWhitelabelling = organisationClaim.flags.embedSigningWhiteLabel;
|
||||
const hidePoweredBy = organisationClaim.flags.hidePoweredBy;
|
||||
|
||||
return superLoaderJson({
|
||||
envelopes,
|
||||
|
||||
Reference in New Issue
Block a user