* refactor: migrate workflows utilities from trpc to features layer Move workflow utility functions from packages/trpc/server/routers/viewer/workflows/util.ts to packages/features/ee/workflows/lib/workflowUtils.ts to break circular dependencies. Functions migrated: - isAuthorized - getAllWorkflowsFromEventType - scheduleWorkflowNotifications - scheduleBookingReminders Changes: - Created new workflowUtils.ts in features layer with migrated functions - Added getBookingsForWorkflowReminders to WorkflowRepository (no prisma outside repositories) - Updated all imports in features layer to use new location - Updated trpc util.ts to re-export from features for backward compatibility - Fixed pre-existing lint warning (any -> unknown) in handleMarkNoShow.ts This is part of the effort to remove circular dependencies between packages/features and packages/trpc. Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * refactor: remove re-exports from trpc util.ts, update imports to use features layer Per user request, removed the backward compatibility re-exports from packages/trpc/server/routers/viewer/workflows/util.ts and updated all imports in the trpc package to import directly from the features layer. Files updated to import from @calcom/features/ee/workflows/lib/workflowUtils: - confirm.handler.ts (getAllWorkflowsFromEventType) - delete.handler.ts (isAuthorized) - update.handler.ts (isAuthorized, scheduleWorkflowNotifications) - getAllActiveWorkflows.handler.ts (getAllWorkflowsFromEventType) - get.handler.ts (isAuthorized) - util.test.ts (isAuthorized) - delete.handler.test.ts (isAuthorized) Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * fix: update test imports to use features layer for workflow utilities Updated test files to import scheduleBookingReminders and scheduleWorkflowNotifications from @calcom/features/ee/workflows/lib/workflowUtils instead of @calcom/trpc/server/routers/viewer/workflows/util. Files updated: - packages/features/ee/workflows/lib/test/workflows.test.ts - packages/features/tasker/tasks/scanWorkflowBody.test.ts Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * refactor: split workflowUtils.ts into individual files Split the monolithic workflowUtils.ts into separate files for each function: - isAuthorized.ts - Authorization check for workflow access - getAllWorkflowsFromEventType.ts - Get workflows for an event type - scheduleWorkflowNotifications.ts - Schedule workflow notifications - scheduleBookingReminders.ts - Schedule booking reminders The workflowUtils.ts now re-exports from these individual files for backward compatibility. Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * fix import * fix more * wip * wip * remove workflowUtils * wip * refactor deleteRemindersOfActiveOnIds * fix --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
137 lines
2.9 KiB
TypeScript
137 lines
2.9 KiB
TypeScript
import { ErrorCode } from "@calcom/lib/errorCodes";
|
|
import { ErrorWithCode } from "@calcom/lib/errors";
|
|
import { prisma } from "@calcom/prisma";
|
|
|
|
export const verifyEmailSender = async (email: string, userId: number, teamId: number | null) => {
|
|
const verifiedEmail = await prisma.verifiedEmail.findFirst({
|
|
where: {
|
|
email,
|
|
OR: [{ userId }, { teamId }],
|
|
},
|
|
});
|
|
|
|
if (verifiedEmail) {
|
|
if (teamId) {
|
|
if (!verifiedEmail.teamId) {
|
|
await prisma.verifiedEmail.update({
|
|
where: {
|
|
id: verifiedEmail.id,
|
|
},
|
|
data: {
|
|
teamId,
|
|
},
|
|
});
|
|
} else if (verifiedEmail.teamId !== teamId) {
|
|
await prisma.verifiedEmail.create({
|
|
data: {
|
|
email,
|
|
userId,
|
|
teamId,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
const userEmail = await prisma.user.findFirst({
|
|
where: {
|
|
id: userId,
|
|
email,
|
|
},
|
|
});
|
|
|
|
if (userEmail) {
|
|
await prisma.verifiedEmail.create({
|
|
data: {
|
|
email,
|
|
userId,
|
|
teamId,
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Check if it's a verified secondary email of the user
|
|
const secondaryEmail = await prisma.secondaryEmail.findFirst({
|
|
where: {
|
|
userId,
|
|
email,
|
|
emailVerified: {
|
|
not: null,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (secondaryEmail) {
|
|
await prisma.verifiedEmail.create({
|
|
data: {
|
|
email,
|
|
userId,
|
|
teamId,
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (teamId) {
|
|
const team = await prisma.team.findUnique({
|
|
where: {
|
|
id: teamId,
|
|
},
|
|
select: {
|
|
members: {
|
|
include: {
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
secondaryEmails: {
|
|
select: {
|
|
email: true,
|
|
emailVerified: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!team) {
|
|
throw new ErrorWithCode(ErrorCode.NotFound, "Team not found");
|
|
}
|
|
|
|
const isTeamMember = team.members.some((member) => member.userId === userId);
|
|
|
|
if (!isTeamMember) {
|
|
throw new ErrorWithCode(ErrorCode.Forbidden, "You are not a member of this team");
|
|
}
|
|
|
|
let foundTeamMember = team.members.find((member) => member.user.email === email);
|
|
|
|
// Only check secondary emails if no match was found with primary email
|
|
if (!foundTeamMember) {
|
|
foundTeamMember = team.members.find((member) =>
|
|
member.user.secondaryEmails.some(
|
|
(secondary) => secondary.email === email && !!secondary.emailVerified
|
|
)
|
|
);
|
|
}
|
|
|
|
if (foundTeamMember) {
|
|
await prisma.verifiedEmail.create({
|
|
data: {
|
|
email,
|
|
userId,
|
|
teamId,
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
throw new ErrorWithCode(ErrorCode.NotFound, "Email not verified");
|
|
};
|