Files
calendar/packages/features/ee/workflows/lib/getAllWorkflows.ts
T
Joe Au-YeungandGitHub 8c9eb18463 chore: Add spam checking for workflow bodies (#18822)
* Add akismet package to tasker

* Create scanWorkflowBody task

* Schedule workflow body scan

* Add AKISMET_API_KEY .env

* Auto lock user if spam is detected

* Uncommit key

* Add safe param to workflow step

* Migration for safe field

* Do not process workflow steps is `safe` is false

* Update migration to set previous records to true

* Address comments

* Refactor `scheduleWorkflowNotifications` to accept an object

* If new steps or editing old ones send to tasker

* Call `scheduleWorkflowNotifications` in task

* Fix `IS_SELF_HOSTED`

* Remove unused function

* Make `safe` optional in schema

* Type fix

* Revert "Make `safe` optional in schema"

This reverts commit d0964702affa87c35562300301473d25635c565b.

* Revert "Type fix"

This reverts commit d9a031303269a2994ae46f576ab2a3d31e4d977b.

* Type fixes

* Type fixes

* Address comments

* Fix tests

* Add tests

* Update tests

* Typo fix

* Update `safe` to `verifiedAt`

* feat: Compare workflow reminder bodies to default template (#19060)

* Add `getTemplateForAction` function

* Use `getTemplateForAction` when creating a new step

* Use `getTemplateForAction` when action changes

* Have `emailReminderTemplate` accept an object as a param

* Rename `getTemplateForAction` to  `getTemplateBodyForAction`

* Simplify changing body when changing templates

* Create `compareReminderBodyToTemplate`

* In task, compare if reminderBody is a template

* Linting

* Add tests

* refactor: `emailReminderTemplate` to accept object as param (#19288)

* Add `getTemplateForAction` function

* Use `getTemplateForAction` when creating a new step

* Use `getTemplateForAction` when action changes

* Have `emailReminderTemplate` accept an object as a param

* Rename `getTemplateForAction` to  `getTemplateBodyForAction`

* Simplify changing body when changing templates

* Create `compareReminderBodyToTemplate`

* In task, compare if reminderBody is a template

* Linting

* Add tests

* Refactor `scheduleEmailReminders`

* Refactor `create.handler` for new workflows

* Refactor `emailReminderManager`

* Refactor `getEmailTemplateText`

* Fix typo

* Type fix - whatsapp plain text template imports

* Type fix - no template found

* Type fix - add `isBrandingDisabled` to `emailReminderTemplate`

* Add workflow and user to prisma mock

* Fix imports for akismet dependencies

* Record user lock reason

* Undo linting changes

* Fix tests

* New workflow, at verify created step

* Handle if `SCANNING_WORKFLOW_STEPS` is toggled

* Move `verifiedAt` checks to specific schedule functions
- `scheduleWhatsappReminder`
- `scheduleEmailReminder`
- `scheduleSMSReminder`

* Update logic

* Do not fallback verifiedAt

* Add comment to next.config.js
2025-04-02 08:16:26 -07:00

122 lines
2.8 KiB
TypeScript

import prisma from "@calcom/prisma";
import type { Workflow } from "./types";
export const workflowSelect = {
id: true,
trigger: true,
time: true,
timeUnit: true,
userId: true,
teamId: true,
name: true,
steps: {
select: {
id: true,
action: true,
sendTo: true,
reminderBody: true,
emailSubject: true,
template: true,
numberVerificationPending: true,
sender: true,
includeCalendarEvent: true,
numberRequired: true,
verifiedAt: true,
},
},
};
export const getAllWorkflows = async (
eventTypeWorkflows: Workflow[],
userId?: number | null,
teamId?: number | null,
orgId?: number | null,
workflowsLockedForUser = true
) => {
const allWorkflows = eventTypeWorkflows;
if (orgId) {
if (teamId) {
const orgTeamWorkflowsRel = await prisma.workflowsOnTeams.findMany({
where: {
teamId: teamId,
},
select: {
workflow: {
select: workflowSelect,
},
},
});
const orgTeamWorkflows = orgTeamWorkflowsRel?.map((workflowRel) => workflowRel.workflow) ?? [];
allWorkflows.push(...orgTeamWorkflows);
} else if (userId) {
const orgUserWorkflowsRel = await prisma.workflowsOnTeams.findMany({
where: {
team: {
members: {
some: {
userId: userId,
accepted: true,
},
},
},
},
select: {
workflow: {
select: workflowSelect,
},
team: true,
},
});
const orgUserWorkflows = orgUserWorkflowsRel.map((workflowRel) => workflowRel.workflow) ?? [];
allWorkflows.push(...orgUserWorkflows);
}
// get workflows that are active on all
const activeOnAllOrgWorkflows = await prisma.workflow.findMany({
where: {
teamId: orgId,
isActiveOnAll: true,
},
select: workflowSelect,
});
allWorkflows.push(...activeOnAllOrgWorkflows);
}
if (teamId) {
const activeOnAllTeamWorkflows = await prisma.workflow.findMany({
where: {
teamId,
isActiveOnAll: true,
},
select: workflowSelect,
});
allWorkflows.push(...activeOnAllTeamWorkflows);
}
if ((!teamId || !workflowsLockedForUser) && userId) {
const activeOnAllUserWorkflows = await prisma.workflow.findMany({
where: {
userId,
teamId: null,
isActiveOnAll: true,
},
select: workflowSelect,
});
allWorkflows.push(...activeOnAllUserWorkflows);
}
// remove all the duplicate workflows from allWorkflows
const seen = new Set();
const workflows = allWorkflows.filter((workflow) => {
const duplicate = seen.has(workflow.id);
seen.add(workflow.id);
return !duplicate;
});
return workflows;
};