fix: Update credentialId when null for a given selectedCalendar (#13735)

* fix: Update credentialId when null for a given selectedCalendar

* Add returnTo return path

* chore

* chore: undo return

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
This commit is contained in:
Alex van Andel
2024-02-22 12:05:46 +00:00
committed by GitHub
co-authored by Udit Takkar Udit Takkar
parent b38807cb0f
commit 3d1ac4523f
4 changed files with 87 additions and 13 deletions
@@ -2,6 +2,7 @@ import type { Auth } from "googleapis";
import { google } from "googleapis";
import type { NextApiRequest, NextApiResponse } from "next";
import { renewSelectedCalendarCredentialId } from "@calcom/lib/connectedCalendar";
import { WEBAPP_URL_FOR_OAUTH, WEBAPP_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { HttpError } from "@calcom/lib/http-error";
@@ -105,23 +106,38 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
appId: "google-calendar",
},
});
const selectedCalendarWhereUnique = {
userId: req.session.user.id,
externalId: primaryCal.id,
integration: "google_calendar",
};
// Wrapping in a try/catch to reduce chance of race conditions-
// also this improves performance for most of the happy-paths.
try {
await prisma.selectedCalendar.create({
data: {
userId: req.session.user.id,
externalId: primaryCal.id,
credentialId: credential.id,
integration: "google_calendar",
...selectedCalendarWhereUnique,
},
});
} catch (error) {
await prisma.credential.delete({ where: { id: credential.id } });
let errorMessage = "something_went_wrong";
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
// it is possible a selectedCalendar was orphaned, in this situation-
// we want to recover by connecting the existing selectedCalendar to the new Credential.
if (await renewSelectedCalendarCredentialId(selectedCalendarWhereUnique, credential.id)) {
res.redirect(
getSafeRedirectUrl(state?.returnTo) ??
getInstalledAppPath({ variant: "calendar", slug: "google-calendar" })
);
return;
}
// else
errorMessage = "account_already_linked";
}
await prisma.credential.delete({ where: { id: credential.id } });
res.redirect(
`${
getSafeRedirectUrl(state?.onErrorReturnTo) ??
@@ -1,6 +1,7 @@
import type { Calendar as OfficeCalendar } from "@microsoft/microsoft-graph-types-beta";
import type { NextApiRequest, NextApiResponse } from "next";
import { renewSelectedCalendarCredentialId } from "@calcom/lib/connectedCalendar";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { handleErrorsJson } from "@calcom/lib/errors";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
@@ -119,23 +120,36 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
appId: "office365-calendar",
},
});
const selectedCalendarWhereUnique = {
userId: req.session?.user.id,
integration: "office365_calendar",
externalId: defaultCalendar.id,
};
// Wrapping in a try/catch to reduce chance of race conditions-
// also this improves performance for most of the happy-paths.
try {
await prisma.selectedCalendar.create({
data: {
userId: req.session?.user.id,
integration: "office365_calendar",
externalId: defaultCalendar.id,
...selectedCalendarWhereUnique,
credentialId: credential.id,
},
});
} catch (error) {
await prisma.credential.delete({ where: { id: credential.id } });
let errorMessage = "something_went_wrong";
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
// it is possible a selectedCalendar was orphaned, in this situation-
// we want to recover by connecting the existing selectedCalendar to the new Credential.
if (await renewSelectedCalendarCredentialId(selectedCalendarWhereUnique, credential.id)) {
res.redirect(
getSafeRedirectUrl(state?.returnTo) ??
getInstalledAppPath({ variant: "calendar", slug: "office365-calendar" })
);
return;
}
// else
errorMessage = "account_already_linked";
}
await prisma.credential.delete({ where: { id: credential.id } });
res.redirect(
`${
getSafeRedirectUrl(state?.onErrorReturnTo) ??
@@ -146,8 +160,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
}
return res.redirect(
res.redirect(
getSafeRedirectUrl(state?.returnTo) ??
getInstalledAppPath({ variant: "calendar", slug: "office365-calendar" })
);
return;
}
@@ -1,6 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { stringify } from "querystring";
import { renewSelectedCalendarCredentialId } from "@calcom/lib/connectedCalendar";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import logger from "@calcom/lib/logger";
@@ -86,23 +87,36 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
appId: config.slug,
},
});
const selectedCalendarWhereUnique = {
userId: req.session?.user.id,
integration: config.type,
externalId: primaryCalendar.uid,
};
// Wrapping in a try/catch to reduce chance of race conditions-
// also this improves performance for most of the happy-paths.
try {
await prisma.selectedCalendar.create({
data: {
userId: req.session.user.id,
integration: config.type,
externalId: primaryCalendar.uid,
...selectedCalendarWhereUnique,
credentialId: credential.id,
},
});
} catch (error) {
await prisma.credential.delete({ where: { id: credential.id } });
let errorMessage = "something_went_wrong";
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
// it is possible a selectedCalendar was orphaned, in this situation-
// we want to recover by connecting the existing selectedCalendar to the new Credential.
if (await renewSelectedCalendarCredentialId(selectedCalendarWhereUnique, credential.id)) {
res.redirect(
getSafeRedirectUrl(state?.returnTo) ??
getInstalledAppPath({ variant: "calendar", slug: config.slug })
);
return;
}
// else
errorMessage = "account_already_linked";
}
await prisma.credential.delete({ where: { id: credential.id } });
res.redirect(
`${
getSafeRedirectUrl(state?.onErrorReturnTo) ??
+29
View File
@@ -0,0 +1,29 @@
import prisma from "@calcom/prisma";
export async function renewSelectedCalendarCredentialId(
selectedCalendarWhereUnique: {
userId: number;
integration: string;
externalId: string;
},
credentialId: number
): Promise<boolean> /* True if renewed, false if not */ {
const selectedCalendar = await prisma.selectedCalendar.findFirst({
where: {
...selectedCalendarWhereUnique,
credentialId: null,
},
});
if (selectedCalendar) {
await prisma.selectedCalendar.update({
where: {
userId_integration_externalId: selectedCalendarWhereUnique,
},
data: {
credentialId: credentialId,
},
});
return true;
}
return false;
}