From c43c5a060486afbd0b57fe35e39b70dc47ca85d8 Mon Sep 17 00:00:00 2001 From: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Date: Wed, 9 Apr 2025 17:30:00 -0400 Subject: [PATCH] chore: Admin unlocking user, also verify workflow steps (#20613) --- .../ee/users/components/UsersTable.tsx | 12 ++++++++ .../server/routers/viewer/admin/_router.ts | 8 +++++ .../viewer/admin/verifyWorkflows.handler.ts | 29 +++++++++++++++++++ .../viewer/admin/verifyWorkflows.schema.ts | 7 +++++ 4 files changed, 56 insertions(+) create mode 100644 packages/trpc/server/routers/viewer/admin/verifyWorkflows.handler.ts create mode 100644 packages/trpc/server/routers/viewer/admin/verifyWorkflows.schema.ts diff --git a/packages/features/ee/users/components/UsersTable.tsx b/packages/features/ee/users/components/UsersTable.tsx index 630f957e3e..26fd9920de 100644 --- a/packages/features/ee/users/components/UsersTable.tsx +++ b/packages/features/ee/users/components/UsersTable.tsx @@ -119,6 +119,12 @@ function UsersTableBare() { }, }); + const verifyWorkflows = trpc.viewer.admin.verifyWorkflows.useMutation({ + onSuccess: () => { + showToast("Workflows verified", "success"); + }, + }); + const handleImpersonateUser = async (username: string | null) => { await signIn("impersonation-auth", { username: username, callbackUrl: `${WEBAPP_URL}/event-types` }); }; @@ -236,6 +242,12 @@ function UsersTableBare() { onClick: () => lockUserAccount.mutate({ userId: user.id, locked: !user.locked }), icon: "lock", }, + { + id: "verify-workflows", + label: "Verify workflows", + onClick: () => verifyWorkflows.mutate({ userId: user.id }), + icon: "check", + }, { id: "impersonation", label: "Impersonate", diff --git a/packages/trpc/server/routers/viewer/admin/_router.ts b/packages/trpc/server/routers/viewer/admin/_router.ts index 19113a00be..3fb02f960c 100644 --- a/packages/trpc/server/routers/viewer/admin/_router.ts +++ b/packages/trpc/server/routers/viewer/admin/_router.ts @@ -7,6 +7,7 @@ import { ZAdminRemoveTwoFactor } from "./removeTwoFactor.schema"; import { ZAdminPasswordResetSchema } from "./sendPasswordReset.schema"; import { ZSetSMSLockState } from "./setSMSLockState.schema"; import { toggleFeatureFlag } from "./toggleFeatureFlag.procedure"; +import { ZAdminVerifyWorkflowsSchema } from "./verifyWorkflows.schema"; import { workspacePlatformCreateSchema, workspacePlatformUpdateSchema, @@ -68,6 +69,13 @@ export const adminRouter = router({ ); return handler(opts); }), + verifyWorkflows: authedAdminProcedure.input(ZAdminVerifyWorkflowsSchema).mutation(async (opts) => { + const handler = await importHandler( + namespaced("verifyWorkflows"), + () => import("./verifyWorkflows.handler") + ); + return handler(opts); + }), workspacePlatform: router({ list: authedAdminProcedure.query(async () => { const handler = await importHandler( diff --git a/packages/trpc/server/routers/viewer/admin/verifyWorkflows.handler.ts b/packages/trpc/server/routers/viewer/admin/verifyWorkflows.handler.ts new file mode 100644 index 0000000000..54ad7c7970 --- /dev/null +++ b/packages/trpc/server/routers/viewer/admin/verifyWorkflows.handler.ts @@ -0,0 +1,29 @@ +import { prisma } from "@calcom/prisma"; + +import type { TrpcSessionUser } from "../../../types"; +import type { TAdminVerifyWorkflowsSchema } from "./verifyWorkflows.schema"; + +type GetOptions = { + ctx: { + user: NonNullable; + }; + input: TAdminVerifyWorkflowsSchema; +}; + +export const verifyWorkflows = async ({ input }: GetOptions) => { + const { userId } = input; + + await prisma.workflowStep.updateMany({ + where: { + workflow: { + userId, + }, + verifiedAt: null, + }, + data: { + verifiedAt: new Date(), + }, + }); +}; + +export default verifyWorkflows; diff --git a/packages/trpc/server/routers/viewer/admin/verifyWorkflows.schema.ts b/packages/trpc/server/routers/viewer/admin/verifyWorkflows.schema.ts new file mode 100644 index 0000000000..5556374ac1 --- /dev/null +++ b/packages/trpc/server/routers/viewer/admin/verifyWorkflows.schema.ts @@ -0,0 +1,7 @@ +import { z } from "zod"; + +export const ZAdminVerifyWorkflowsSchema = z.object({ + userId: z.number(), +}); + +export type TAdminVerifyWorkflowsSchema = z.infer;