Skip to content

Commit

Permalink
Merge remote-tracking branch 'pritam/fix_zoho' into fix/CAL-3578
Browse files Browse the repository at this point in the history
  • Loading branch information
vachmara committed May 2, 2024
2 parents 97b2816 + d7b06fc commit 96a2fa0
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 18 deletions.
15 changes: 15 additions & 0 deletions packages/app-store/_utils/updateAppServerLocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import prisma from "@calcom/prisma";

import { appKeysSchema as zohoKeysSchema } from "../zohocalendar/zod";

async function updateAppServerLocation(slug: string, serverUrl: string) {
const app = await prisma.app.findUnique({ where: { slug } });
const { client_id, client_secret } = zohoKeysSchema.parse(app?.keys) || {};
const updatedKeys = { client_id, client_secret, server_location: serverUrl };
await prisma.app.update({
where: { slug },
data: { keys: updatedKeys },
});
}

export default updateAppServerLocation;
24 changes: 18 additions & 6 deletions packages/app-store/zohocalendar/api/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ import { Prisma } from "@calcom/prisma/client";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
import updateAppServerLocation from "../../_utils/updateAppServerLocation";
import config from "../config.json";
import type { ZohoAuthCredentials } from "../types/ZohoCalendar";
import { appKeysSchema as zohoKeysSchema } from "../zod";

const log = logger.getSubLogger({ prefix: [`[[zohocalendar/api/callback]`] });

const OAUTH_BASE_URL = "https://accounts.zoho.com/oauth/v2";
function getOAuthBaseUrl(domain: string): string {
return `https://accounts.zoho.${domain}/oauth/v2`;
}

async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const { code } = req.query;
const { code, location } = req.query;

const state = decodeOAuthState(req);

if (code && typeof code !== "string") {
Expand All @@ -33,8 +37,12 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
return res.status(401).json({ message: "You must be logged in to do this" });
}

if (location && typeof location === "string") {
updateAppServerLocation(config.slug, location);
}

const appKeys = await getAppKeysFromSlug(config.slug);
const { client_id, client_secret } = zohoKeysSchema.parse(appKeys);
const { client_id, client_secret, server_location } = zohoKeysSchema.parse(appKeys);

const params = {
client_id,
Expand All @@ -46,14 +54,14 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {

const query = stringify(params);

const response = await fetch(`${OAUTH_BASE_URL}/token?${query}`, {
const response = await fetch(`${getOAuthBaseUrl(server_location || "com")}/token?${query}`, {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
},
});

const responseBody = await response.json();
const responseBody = await JSON.parse(await response.text());

if (!response.ok || responseBody.error) {
log.error("get access_token failed", responseBody);
Expand All @@ -66,7 +74,11 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
expires_in: Math.round(+new Date() / 1000 + responseBody.expires_in),
};

const calendarResponse = await fetch("https://calendar.zoho.com/api/v1/calendars", {
function getCalenderUri(domain: string): string {
return `https://calendar.zoho.${domain}/api/v1/calendars`;
}

const calendarResponse = await fetch(getCalenderUri(server_location || "com"), {
method: "GET",
headers: {
Authorization: `Bearer ${key.access_token}`,
Expand Down
21 changes: 9 additions & 12 deletions packages/app-store/zohocalendar/lib/CalendarService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { stringify } from "querystring";
import { z } from "zod";

import dayjs from "@calcom/dayjs";
import { getLocation, getRichDescription } from "@calcom/lib/CalEventParser";
Expand All @@ -16,11 +15,7 @@ import type { CredentialPayload } from "@calcom/types/Credential";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import type { ZohoAuthCredentials, FreeBusy, ZohoCalendarListResp } from "../types/ZohoCalendar";

const zohoKeysSchema = z.object({
client_id: z.string(),
client_secret: z.string(),
});
import { appKeysSchema as zohoKeysSchema } from "../zod";

export default class ZohoCalendarService implements Calendar {
private integrationName = "";
Expand All @@ -41,7 +36,7 @@ export default class ZohoCalendarService implements Calendar {
const refreshAccessToken = async () => {
try {
const appKeys = await getAppKeysFromSlug("zohocalendar");
const { client_id, client_secret } = zohoKeysSchema.parse(appKeys);
const { client_id, client_secret, server_location } = zohoKeysSchema.parse(appKeys);

const params = {
client_id,
Expand All @@ -52,7 +47,7 @@ export default class ZohoCalendarService implements Calendar {

const query = stringify(params);

const res = await fetch(`https://accounts.zoho.com/oauth/v2/token?${query}`, {
const res = await fetch(`https://accounts.zoho.${server_location}/oauth/v2/token?${query}`, {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
Expand Down Expand Up @@ -87,8 +82,9 @@ export default class ZohoCalendarService implements Calendar {

private fetcher = async (endpoint: string, init?: RequestInit | undefined) => {
const credentials = await this.auth.getToken();

return fetch(`https://calendar.zoho.com/api/v1${endpoint}`, {
const appKeys = await getAppKeysFromSlug("zohocalendar");
const { server_location } = zohoKeysSchema.parse(appKeys);
return fetch(`https://calendar.zoho.${server_location}/api/v1${endpoint}`, {
method: "GET",
...init,
headers: {
Expand All @@ -101,8 +97,9 @@ export default class ZohoCalendarService implements Calendar {

private getUserInfo = async () => {
const credentials = await this.auth.getToken();

const response = await fetch(`https://accounts.zoho.com/oauth/user/info`, {
const appKeys = await getAppKeysFromSlug("zohocalendar");
const { server_location } = zohoKeysSchema.parse(appKeys);
const response = await fetch(`https://accounts.zoho.${server_location}/oauth/user/info`, {
method: "GET",
headers: {
Authorization: `Bearer ${credentials.access_token}`,
Expand Down
1 change: 1 addition & 0 deletions packages/app-store/zohocalendar/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export const appDataSchema = z.object({});
export const appKeysSchema = z.object({
client_id: z.string().min(1),
client_secret: z.string().min(1),
server_location: z.string().optional(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type SaveKeysOptions = {
};

export const saveKeysHandler = async ({ ctx, input }: SaveKeysOptions) => {
console.log(ctx);
const keysSchema = appKeysSchemas[input.dirName as keyof typeof appKeysSchemas];
const keys = keysSchema.parse(input.keys);

Expand Down

0 comments on commit 96a2fa0

Please sign in to comment.