feat: add envelope editor

This commit is contained in:
David Nguyen
2025-10-12 23:35:54 +11:00
parent bf89bc781b
commit 0da8e7dbc6
307 changed files with 24657 additions and 3681 deletions

View File

@ -1,20 +1,6 @@
import { EnvelopeType } from '@prisma/client';
import type { Context } from 'hono';
import { getSession } from '@documenso/auth/server/lib/utils/get-session';
import {
mapDocumentIdToSecondaryId,
mapTemplateIdToSecondaryId,
} from '@documenso/lib/utils/envelope';
import { buildTeamWhereQuery } from '@documenso/lib/utils/teams';
import { prisma } from '@documenso/prisma';
function extractIdFromPath(path: string, prefix: string): string | null {
const regex = new RegExp(`^${prefix}/([^/]+)`);
const match = path.match(regex);
return match ? match[1] : null;
}
// eslint-disable-next-line @typescript-eslint/require-await
export const handleRedirects = async (c: Context): Promise<string | null> => {
const { req } = c;
const path = req.path;
@ -29,154 +15,5 @@ export const handleRedirects = async (c: Context): Promise<string | null> => {
return '/';
}
// Document folder routes.
if (path.startsWith('/documents/f/')) {
const folderId = extractIdFromPath(path, '/documents/f');
if (!folderId) {
return '/';
}
const teamUrl = await hasAccessToFolder(c, folderId);
if (folderId && teamUrl) {
return `/t/${teamUrl}/documents/f/${folderId}`;
}
}
// Document routes.
if (path.startsWith('/documents/')) {
const rawDocumentId = extractIdFromPath(path, '/documents');
const documentId = Number(rawDocumentId);
if (!documentId || isNaN(documentId)) {
return '/';
}
const teamUrl = await hasAccessToDocument(c, documentId);
if (!teamUrl) {
return '/';
}
const queryString = req.url.split('?')[1];
const redirectPath = `/t/${teamUrl}${path}${queryString ? `?${queryString}` : ''}`;
return redirectPath;
}
// Template folder routes.
if (path.startsWith('/templates/f/')) {
const folderId = extractIdFromPath(path, '/templates/f');
if (!folderId) {
return '/';
}
const teamUrl = await hasAccessToFolder(c, folderId);
if (folderId && teamUrl) {
return `/t/${teamUrl}/templates/f/${folderId}`;
}
}
if (path.startsWith('/templates/')) {
const rawTemplateId = extractIdFromPath(path, '/templates');
const templateId = Number(rawTemplateId);
if (!templateId || isNaN(templateId)) {
return '/';
}
const teamUrl = await hasAccessToTemplate(c, templateId);
if (!teamUrl) {
return '/';
}
const queryString = req.url.split('?')[1];
const redirectPath = `/t/${teamUrl}${path}${queryString ? `?${queryString}` : ''}`;
return redirectPath;
}
return null;
};
async function hasAccessToDocument(c: Context, documentId: number): Promise<string | null> {
const session = await getSession(c);
const userId = session.user.id;
const envelope = await prisma.envelope.findUnique({
where: {
type: EnvelopeType.DOCUMENT,
secondaryId: mapDocumentIdToSecondaryId(documentId),
team: buildTeamWhereQuery({
userId,
teamId: undefined,
}),
},
select: {
team: {
select: {
url: true,
},
},
},
});
return envelope ? envelope.team.url : null;
}
async function hasAccessToFolder(c: Context, folderId: string): Promise<string | null> {
const session = await getSession(c);
const userId = session.user.id;
const folder = await prisma.folder.findUnique({
where: {
id: folderId,
team: buildTeamWhereQuery({
userId,
teamId: undefined,
}),
},
select: {
team: {
select: {
url: true,
},
},
},
});
return folder ? folder.team.url : null;
}
async function hasAccessToTemplate(c: Context, templateId: number): Promise<string | null> {
const session = await getSession(c);
const userId = session.user.id;
const envelope = await prisma.envelope.findUnique({
where: {
type: EnvelopeType.TEMPLATE,
secondaryId: mapTemplateIdToSecondaryId(templateId),
team: buildTeamWhereQuery({
userId,
teamId: undefined,
}),
},
select: {
team: {
select: {
url: true,
},
},
},
});
return envelope ? envelope.team.url : null;
}