Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Commit

Permalink
fix: better errors for googlecalendar integration (calcom#12403)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThyMinimalDev authored Nov 21, 2023
1 parent 85237c4 commit 556b382
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 30 deletions.
52 changes: 28 additions & 24 deletions packages/app-store/googlecalendar/api/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { google } from "googleapis";
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";
import { HttpError } from "@calcom/lib/http-error";
import { defaultHandler, defaultResponder } from "@calcom/lib/server";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import { encodeOAuthState } from "../../_utils/oauth/encodeOAuthState";
Expand All @@ -14,28 +16,30 @@ const scopes = [
let client_id = "";
let client_secret = "";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "GET") {
// Get token from Google Calendar API
const appKeys = await getAppKeysFromSlug("google-calendar");
if (typeof appKeys.client_id === "string") client_id = appKeys.client_id;
if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret;
if (!client_id) return res.status(400).json({ message: "Google client_id missing." });
if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." });
const redirect_uri = `${WEBAPP_URL_FOR_OAUTH}/api/integrations/googlecalendar/callback`;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);

const authUrl = oAuth2Client.generateAuthUrl({
access_type: "offline",
scope: scopes,
// A refresh token is only returned the first time the user
// consents to providing access. For illustration purposes,
// setting the prompt to 'consent' will force this consent
// every time, forcing a refresh_token to be returned.
prompt: "consent",
state: encodeOAuthState(req),
});

res.status(200).json({ url: authUrl });
}
async function getHandler(req: NextApiRequest, res: NextApiResponse) {
// Get token from Google Calendar API
const appKeys = await getAppKeysFromSlug("google-calendar");
if (typeof appKeys.client_id === "string") client_id = appKeys.client_id;
if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret;
if (!client_id) throw new HttpError({ statusCode: 400, message: "Google client_id missing." });
if (!client_secret) throw new HttpError({ statusCode: 400, message: "Google client_secret missing." });
const redirect_uri = `${WEBAPP_URL_FOR_OAUTH}/api/integrations/googlecalendar/callback`;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);

const authUrl = oAuth2Client.generateAuthUrl({
access_type: "offline",
scope: scopes,
// A refresh token is only returned the first time the user
// consents to providing access. For illustration purposes,
// setting the prompt to 'consent' will force this consent
// every time, forcing a refresh_token to be returned.
prompt: "consent",
state: encodeOAuthState(req),
});

res.status(200).json({ url: authUrl });
}

export default defaultHandler({
GET: Promise.resolve({ default: defaultResponder(getHandler) }),
});
17 changes: 11 additions & 6 deletions packages/app-store/googlecalendar/api/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL_FOR_OAUTH, CAL_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { HttpError } from "@calcom/lib/http-error";
import { defaultHandler, defaultResponder } from "@calcom/lib/server";
import prisma from "@calcom/prisma";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
Expand All @@ -12,24 +14,23 @@ import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
let client_id = "";
let client_secret = "";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const { code } = req.query;
const state = decodeOAuthState(req);

if (typeof code !== "string") {
res.status(400).json({ message: "`code` must be a string" });
return;
throw new HttpError({ statusCode: 400, message: "`code` must be a string" });
}

if (!req.session?.user?.id) {
return res.status(401).json({ message: "You must be logged in to do this" });
throw new HttpError({ statusCode: 401, message: "You must be logged in to do this" });
}

const appKeys = await getAppKeysFromSlug("google-calendar");
if (typeof appKeys.client_id === "string") client_id = appKeys.client_id;
if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret;
if (!client_id) return res.status(400).json({ message: "Google client_id missing." });
if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." });
if (!client_id) throw new HttpError({ statusCode: 400, message: "Google client_id missing." });
if (!client_secret) throw new HttpError({ statusCode: 400, message: "Google client_secret missing." });

const redirect_uri = `${WEBAPP_URL_FOR_OAUTH}/api/integrations/googlecalendar/callback`;

Expand Down Expand Up @@ -107,3 +108,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
getInstalledAppPath({ variant: "calendar", slug: "google-calendar" })
);
}

export default defaultHandler({
GET: Promise.resolve({ default: defaultResponder(getHandler) }),
});

0 comments on commit 556b382

Please sign in to comment.