fix: add team installation support for HitPay payment integration (#24738)
- Add teamId support to HitPay add.ts installation handler - Update callback.ts to fetch credentials by teamId for team bookings - Update webhook.ts to fetch credentials by teamId for team bookings - Update setup page to accept and handle teamId from query params - Add permission checks using throwIfNotHaveAdminAccessToTeam - Ensure credentials are created with teamId for team installs, userId for user installs Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin AI
parent
ad4b5957fc
commit
a3fc17bc75
@@ -1,5 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { throwIfNotHaveAdminAccessToTeam } from "@calcom/app-store/_utils/throwIfNotHaveAdminAccessToTeam";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import config from "../config.json";
|
||||
@@ -8,12 +9,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
if (!req.session?.user?.id) {
|
||||
return res.status(401).json({ message: "You must be logged in to do this" });
|
||||
}
|
||||
|
||||
const { teamId } = req.query;
|
||||
const teamIdNumber = teamId ? Number(teamId) : null;
|
||||
|
||||
await throwIfNotHaveAdminAccessToTeam({ teamId: teamIdNumber, userId: req.session.user.id });
|
||||
const installForObject = teamIdNumber ? { teamId: teamIdNumber } : { userId: req.session.user.id };
|
||||
|
||||
const appType = config.type;
|
||||
try {
|
||||
const alreadyInstalled = await prisma.credential.findFirst({
|
||||
where: {
|
||||
type: appType,
|
||||
userId: req.session.user.id,
|
||||
...installForObject,
|
||||
},
|
||||
});
|
||||
if (alreadyInstalled) {
|
||||
@@ -23,13 +31,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
data: {
|
||||
type: appType,
|
||||
key: {},
|
||||
userId: req.session.user.id,
|
||||
appId: "hitpay",
|
||||
...(teamIdNumber ? { teamId: teamIdNumber } : { userId: req.session.user.id }),
|
||||
},
|
||||
});
|
||||
|
||||
if (!installation) {
|
||||
throw new Error("Unable to create user credential for Alby");
|
||||
throw new Error("Unable to create user credential for HitPay");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
const message =
|
||||
@@ -38,5 +46,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
return res.status(500).json({ message });
|
||||
}
|
||||
|
||||
return res.status(200).json({ url: "/apps/hitpay/setup" });
|
||||
return res.status(200).json({ url: `/apps/hitpay/setup${teamIdNumber ? `?teamId=${teamIdNumber}` : ""}` });
|
||||
}
|
||||
|
||||
@@ -30,21 +30,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
booking: {
|
||||
select: {
|
||||
uid: true,
|
||||
userId: true,
|
||||
user: {
|
||||
select: {
|
||||
email: true,
|
||||
username: true,
|
||||
credentials: {
|
||||
where: {
|
||||
type: "hitpay_payment",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: true,
|
||||
eventType: {
|
||||
select: {
|
||||
slug: true,
|
||||
teamId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -55,7 +52,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
if (!payment) {
|
||||
throw new HttpCode({ statusCode: 204, message: "Payment not found" });
|
||||
}
|
||||
const key = payment.booking?.user?.credentials?.[0].key;
|
||||
|
||||
const credential = await prisma.credential.findFirst({
|
||||
where: {
|
||||
type: "hitpay_payment",
|
||||
...(payment.booking?.eventType?.teamId
|
||||
? { teamId: payment.booking.eventType.teamId }
|
||||
: { userId: payment.booking?.userId }),
|
||||
},
|
||||
});
|
||||
|
||||
const key = credential?.key;
|
||||
if (!key) {
|
||||
throw new HttpCode({ statusCode: 204, message: "Credential not found" });
|
||||
}
|
||||
|
||||
@@ -62,13 +62,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
bookingId: true,
|
||||
booking: {
|
||||
select: {
|
||||
user: {
|
||||
userId: true,
|
||||
eventType: {
|
||||
select: {
|
||||
credentials: {
|
||||
where: {
|
||||
type: "hitpay_payment",
|
||||
},
|
||||
},
|
||||
teamId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -79,7 +76,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
if (!payment) {
|
||||
throw new HttpCode({ statusCode: 204, message: "Payment not found" });
|
||||
}
|
||||
const key = payment.booking?.user?.credentials?.[0].key;
|
||||
|
||||
const credential = await prisma.credential.findFirst({
|
||||
where: {
|
||||
type: "hitpay_payment",
|
||||
...(payment.booking?.eventType?.teamId
|
||||
? { teamId: payment.booking.eventType.teamId }
|
||||
: { userId: payment.booking?.userId }),
|
||||
},
|
||||
});
|
||||
|
||||
const key = credential?.key;
|
||||
if (!key) {
|
||||
throw new HttpCode({ statusCode: 204, message: "Credentials not found" });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import { z } from "zod";
|
||||
|
||||
import { throwIfNotHaveAdminAccessToTeam } from "@calcom/app-store/_utils/throwIfNotHaveAdminAccessToTeam";
|
||||
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
@@ -13,7 +14,7 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
|
||||
if (typeof ctx.params?.slug !== "string") return notFound;
|
||||
|
||||
const { req } = ctx;
|
||||
const { req, query } = ctx;
|
||||
const session = await getServerSession({ req });
|
||||
|
||||
if (!session?.user?.id) {
|
||||
@@ -22,10 +23,15 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
return redirect;
|
||||
}
|
||||
|
||||
const teamId = query.teamId ? Number(query.teamId) : null;
|
||||
|
||||
await throwIfNotHaveAdminAccessToTeam({ teamId, userId: session.user.id });
|
||||
const installForObject = teamId ? { teamId } : { userId: session.user.id };
|
||||
|
||||
const credentials = await prisma.credential.findFirst({
|
||||
where: {
|
||||
type: "hitpay_payment",
|
||||
userId: session?.user.id,
|
||||
...installForObject,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user