mirror of
https://github.com/hanzoai/sign.git
synced 2026-10-21 01:21:51 +00:00
Emails, the signing page's title, the sealed PDF's reason, the sign-in refusal and the dialogs still said Hanzo Sign. The catalogs change with the strings, message for message, so every translation keeps its id.
155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
import { createElement } from 'react';
|
|
|
|
import { msg } from '@lingui/core/macro';
|
|
import { OrganisationGroupType, type Team } from '@prisma/client';
|
|
import { uniqueBy } from 'remeda';
|
|
|
|
import { mailer } from '@hanzo/esign-email/mailer';
|
|
import { TeamDeleteEmailTemplate } from '@hanzo/esign-email/templates/team-delete';
|
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@hanzo/esign-lib/constants/app';
|
|
import { AppError, AppErrorCode } from '@hanzo/esign-lib/errors/app-error';
|
|
import { prisma } from '@hanzo/esign-prisma';
|
|
|
|
import { getI18nInstance } from '../../client-only/providers/i18n-server';
|
|
import { TEAM_MEMBER_ROLE_PERMISSIONS_MAP } from '../../constants/teams';
|
|
import { jobs } from '../../jobs/client';
|
|
import { renderEmailWithI18N } from '../../utils/render-email-with-i18n';
|
|
import { buildTeamWhereQuery } from '../../utils/teams';
|
|
import { getEmailContext } from '../email/get-email-context';
|
|
|
|
export type DeleteTeamOptions = {
|
|
userId: number;
|
|
teamId: number;
|
|
};
|
|
|
|
export const deleteTeam = async ({ userId, teamId }: DeleteTeamOptions) => {
|
|
const team = await prisma.team.findFirst({
|
|
where: buildTeamWhereQuery({
|
|
teamId,
|
|
userId,
|
|
roles: TEAM_MEMBER_ROLE_PERMISSIONS_MAP['DELETE_TEAM'],
|
|
}),
|
|
include: {
|
|
organisation: {
|
|
select: {
|
|
organisationGlobalSettings: true,
|
|
},
|
|
},
|
|
teamGroups: {
|
|
include: {
|
|
organisationGroup: {
|
|
include: {
|
|
organisationGroupMembers: {
|
|
include: {
|
|
organisationMember: {
|
|
include: {
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!team) {
|
|
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
|
message: 'You are not authorized to delete this team',
|
|
});
|
|
}
|
|
|
|
const membersToNotify = uniqueBy(
|
|
team.teamGroups.flatMap((group) =>
|
|
group.organisationGroup.organisationGroupMembers.map((member) => ({
|
|
id: member.organisationMember.user.id,
|
|
name: member.organisationMember.user.name || '',
|
|
email: member.organisationMember.user.email,
|
|
})),
|
|
),
|
|
(member) => member.id,
|
|
);
|
|
|
|
await prisma.$transaction(
|
|
async (tx) => {
|
|
await tx.team.delete({
|
|
where: {
|
|
id: teamId,
|
|
},
|
|
});
|
|
|
|
// Purge all internal organisation groups that have no teams.
|
|
await tx.organisationGroup.deleteMany({
|
|
where: {
|
|
type: OrganisationGroupType.INTERNAL_TEAM,
|
|
teamGroups: {
|
|
none: {},
|
|
},
|
|
},
|
|
});
|
|
},
|
|
{ timeout: 30_000 },
|
|
);
|
|
|
|
await jobs.triggerJob({
|
|
name: 'send.team-deleted.email',
|
|
payload: {
|
|
team: {
|
|
name: team.name,
|
|
url: team.url,
|
|
},
|
|
members: membersToNotify,
|
|
organisationId: team.organisationId,
|
|
},
|
|
});
|
|
};
|
|
|
|
type SendTeamDeleteEmailOptions = {
|
|
email: string;
|
|
team: Pick<Team, 'url' | 'name'>;
|
|
organisationId: string;
|
|
};
|
|
|
|
export const sendTeamDeleteEmail = async ({
|
|
email,
|
|
team,
|
|
organisationId,
|
|
}: SendTeamDeleteEmailOptions) => {
|
|
const template = createElement(TeamDeleteEmailTemplate, {
|
|
assetBaseUrl: NEXT_PUBLIC_WEBAPP_URL(),
|
|
baseUrl: NEXT_PUBLIC_WEBAPP_URL(),
|
|
teamUrl: team.url,
|
|
});
|
|
|
|
const { branding, emailLanguage, senderEmail } = await getEmailContext({
|
|
emailType: 'INTERNAL',
|
|
source: {
|
|
type: 'organisation',
|
|
organisationId,
|
|
},
|
|
});
|
|
|
|
const [html, text] = await Promise.all([
|
|
renderEmailWithI18N(template, { lang: emailLanguage, branding }),
|
|
renderEmailWithI18N(template, { lang: emailLanguage, branding, plainText: true }),
|
|
]);
|
|
|
|
const i18n = await getI18nInstance(emailLanguage);
|
|
|
|
await mailer.sendMail({
|
|
to: email,
|
|
from: senderEmail,
|
|
subject: i18n._(msg`Team "${team.name}" has been deleted on Hanzo eSign`),
|
|
html,
|
|
text,
|
|
});
|
|
};
|