Merge branch 'main' into feat/add-pdf-image-renderer

This commit is contained in:
David Nguyen
2026-02-25 19:26:47 +11:00
committed by GitHub
38 changed files with 2700 additions and 69 deletions
@@ -0,0 +1,101 @@
import { Prisma } from '@prisma/client';
import type { FindResultResponse } from '@documenso/lib/types/search-params';
import { prisma } from '@documenso/prisma';
import { adminProcedure } from '../trpc';
import {
ZFindEmailDomainsRequestSchema,
ZFindEmailDomainsResponseSchema,
} from './find-email-domains.types';
export const findEmailDomainsRoute = adminProcedure
.input(ZFindEmailDomainsRequestSchema)
.output(ZFindEmailDomainsResponseSchema)
.query(async ({ input }) => {
const { query, page, perPage, status } = input;
return await findEmailDomains({ query, page, perPage, status });
});
type FindEmailDomainsOptions = {
query?: string;
page?: number;
perPage?: number;
status?: 'PENDING' | 'ACTIVE';
};
const findEmailDomains = async ({
query,
page = 1,
perPage = 20,
status,
}: FindEmailDomainsOptions) => {
const whereClause: Prisma.EmailDomainWhereInput = {};
if (query) {
whereClause.OR = [
{
domain: {
contains: query,
mode: Prisma.QueryMode.insensitive,
},
},
{
organisation: {
name: {
contains: query,
mode: Prisma.QueryMode.insensitive,
},
},
},
];
}
if (status) {
whereClause.status = status;
}
const [data, count] = await Promise.all([
prisma.emailDomain.findMany({
where: whereClause,
skip: Math.max(page - 1, 0) * perPage,
take: perPage,
orderBy: {
createdAt: 'desc',
},
select: {
id: true,
domain: true,
status: true,
selector: true,
createdAt: true,
updatedAt: true,
lastVerifiedAt: true,
organisation: {
select: {
id: true,
name: true,
url: true,
},
},
_count: {
select: {
emails: true,
},
},
},
}),
prisma.emailDomain.count({
where: whereClause,
}),
]);
return {
data,
count,
currentPage: Math.max(page, 1),
perPage,
totalPages: Math.ceil(count / perPage),
} satisfies FindResultResponse<typeof data>;
};
@@ -0,0 +1,36 @@
import { z } from 'zod';
import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params';
import EmailDomainStatusSchema from '@documenso/prisma/generated/zod/inputTypeSchemas/EmailDomainStatusSchema';
import EmailDomainSchema from '@documenso/prisma/generated/zod/modelSchema/EmailDomainSchema';
import OrganisationSchema from '@documenso/prisma/generated/zod/modelSchema/OrganisationSchema';
export const ZFindEmailDomainsRequestSchema = ZFindSearchParamsSchema.extend({
status: EmailDomainStatusSchema.optional(),
});
export const ZFindEmailDomainsResponseSchema = ZFindResultResponse.extend({
data: EmailDomainSchema.pick({
id: true,
domain: true,
status: true,
selector: true,
createdAt: true,
updatedAt: true,
lastVerifiedAt: true,
})
.extend({
organisation: OrganisationSchema.pick({
id: true,
name: true,
url: true,
}),
_count: z.object({
emails: z.number(),
}),
})
.array(),
});
export type TFindEmailDomainsRequest = z.infer<typeof ZFindEmailDomainsRequestSchema>;
export type TFindEmailDomainsResponse = z.infer<typeof ZFindEmailDomainsResponseSchema>;
@@ -0,0 +1,42 @@
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { prisma } from '@documenso/prisma';
import { adminProcedure } from '../trpc';
import {
ZGetEmailDomainRequestSchema,
ZGetEmailDomainResponseSchema,
} from './get-email-domain.types';
export const getEmailDomainRoute = adminProcedure
.input(ZGetEmailDomainRequestSchema)
.output(ZGetEmailDomainResponseSchema)
.query(async ({ input }) => {
const { emailDomainId } = input;
const emailDomain = await prisma.emailDomain.findUnique({
where: {
id: emailDomainId,
},
omit: {
privateKey: true,
},
include: {
organisation: {
select: {
id: true,
name: true,
url: true,
},
},
emails: true,
},
});
if (!emailDomain) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Email domain not found',
});
}
return emailDomain;
});
@@ -0,0 +1,30 @@
import { z } from 'zod';
import { ZOrganisationEmailLiteSchema } from '@documenso/lib/types/organisation-email';
import EmailDomainSchema from '@documenso/prisma/generated/zod/modelSchema/EmailDomainSchema';
import OrganisationSchema from '@documenso/prisma/generated/zod/modelSchema/OrganisationSchema';
export const ZGetEmailDomainRequestSchema = z.object({
emailDomainId: z.string(),
});
export const ZGetEmailDomainResponseSchema = EmailDomainSchema.pick({
id: true,
domain: true,
status: true,
selector: true,
publicKey: true,
createdAt: true,
updatedAt: true,
lastVerifiedAt: true,
}).extend({
organisation: OrganisationSchema.pick({
id: true,
name: true,
url: true,
}),
emails: ZOrganisationEmailLiteSchema.array(),
});
export type TGetEmailDomainRequest = z.infer<typeof ZGetEmailDomainRequestSchema>;
export type TGetEmailDomainResponse = z.infer<typeof ZGetEmailDomainResponseSchema>;
@@ -0,0 +1,22 @@
import { reregisterEmailDomain } from '@documenso/ee/server-only/lib/reregister-email-domain';
import { adminProcedure } from '../trpc';
import {
ZReregisterEmailDomainRequestSchema,
ZReregisterEmailDomainResponseSchema,
} from './reregister-email-domain.types';
export const reregisterEmailDomainRoute = adminProcedure
.input(ZReregisterEmailDomainRequestSchema)
.output(ZReregisterEmailDomainResponseSchema)
.mutation(async ({ input, ctx }) => {
const { emailDomainId } = input;
ctx.logger.info({
input: {
emailDomainId,
},
});
await reregisterEmailDomain({ emailDomainId });
});
@@ -0,0 +1,10 @@
import { z } from 'zod';
export const ZReregisterEmailDomainRequestSchema = z.object({
emailDomainId: z.string(),
});
export const ZReregisterEmailDomainResponseSchema = z.void();
export type TReregisterEmailDomainRequest = z.infer<typeof ZReregisterEmailDomainRequestSchema>;
export type TReregisterEmailDomainResponse = z.infer<typeof ZReregisterEmailDomainResponseSchema>;
@@ -11,11 +11,14 @@ import { findAdminOrganisationsRoute } from './find-admin-organisations';
import { findDocumentAuditLogsRoute } from './find-document-audit-logs';
import { findDocumentJobsRoute } from './find-document-jobs';
import { findDocumentsRoute } from './find-documents';
import { findEmailDomainsRoute } from './find-email-domains';
import { findSubscriptionClaimsRoute } from './find-subscription-claims';
import { findUserTeamsRoute } from './find-user-teams';
import { getAdminOrganisationRoute } from './get-admin-organisation';
import { getEmailDomainRoute } from './get-email-domain';
import { getUserRoute } from './get-user';
import { promoteMemberToOwnerRoute } from './promote-member-to-owner';
import { reregisterEmailDomainRoute } from './reregister-email-domain';
import { resealDocumentRoute } from './reseal-document';
import { resetTwoFactorRoute } from './reset-two-factor-authentication';
import { resyncLicenseRoute } from './resync-license';
@@ -68,5 +71,10 @@ export const adminRouter = router({
recipient: {
update: updateRecipientRoute,
},
emailDomain: {
find: findEmailDomainsRoute,
get: getEmailDomainRoute,
reregister: reregisterEmailDomainRoute,
},
updateSiteSetting: updateSiteSettingRoute,
});
@@ -95,6 +95,7 @@ export const findOrganisationEmailDomains = async ({
selector: true,
createdAt: true,
updatedAt: true,
lastVerifiedAt: true,
_count: {
select: {
emails: true,