Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Add crm type to app credentials #14147

Merged
merged 38 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bad017a
fix timezone display on booking page to reflect event availability ti…
Mar 18, 2024
e4f9679
migrate fetching event owner's schedule to server side
Mar 19, 2024
2dc2272
migrate fetching event owner's schedule to server side
Mar 19, 2024
12f228f
fix e2e test errors
Mar 19, 2024
df6672e
Merge branch 'calcom:main' into main
Shaik-Sirajuddin Mar 19, 2024
5f274fc
Merge branch 'main' of https://github.com/Shaik-Sirajuddin/cal.com
Mar 19, 2024
4cd9236
Merge branch 'main' into main
joeauyeung Mar 19, 2024
dc45e8c
Merge branch 'calcom:main' into main
Shaik-Sirajuddin Mar 19, 2024
046a3a0
Add WEBAPP_URL_FOR_OAUTH to salesforce auth
joeauyeung Mar 19, 2024
2f19c18
In event manager constructor include "_crm" credentials as calendar c…
joeauyeung Mar 19, 2024
58eb841
Change crm apps to type to end with `_crm`
joeauyeung Mar 19, 2024
4ce8a85
Move sendgrid out of CRM
joeauyeung Mar 19, 2024
288915e
Add zoho bigin to CRM apps
joeauyeung Mar 20, 2024
1777a3a
When getting apps, use slug
joeauyeung Mar 20, 2024
a9bb57f
Add `crm` variants
joeauyeung Mar 20, 2024
698d41e
Hubspot Oauth use `WEBAPP_URL_FOR_OAUTH`
joeauyeung Mar 20, 2024
d40835e
Refactor creating credentials
joeauyeung Mar 20, 2024
bbc068f
Fix empty CRM page
joeauyeung Mar 20, 2024
747c71a
Use credentials with `_crm`
joeauyeung Mar 20, 2024
be2f2b1
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 20, 2024
11b6c7f
Merge branch 'add-crm-app-type' of https://github.com/calcom/cal.com …
joeauyeung Mar 20, 2024
7f5fdb4
Abstract getAppCategoryTitle
joeauyeung Mar 20, 2024
9cff361
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 20, 2024
1db94c8
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 20, 2024
9986bb4
Merge branch 'add-crm-app-type' of https://github.com/calcom/cal.com …
joeauyeung Mar 20, 2024
db8f38e
Add integration.handler changes
joeauyeung Mar 20, 2024
f568c3e
Merge branch 'main' into add-crm-app-type
sean-brydon Mar 25, 2024
b07473d
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 26, 2024
f068be4
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 29, 2024
8f19358
Merge branch 'main' into add-crm-app-type
joeauyeung Mar 29, 2024
666dcb3
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 4, 2024
db36cbf
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 4, 2024
8b1b206
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 5, 2024
9c2cb92
Fix tests
joeauyeung Apr 5, 2024
de1c55d
Type fix
joeauyeung Apr 5, 2024
d9368a6
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 5, 2024
7680e9f
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 8, 2024
58a0cb7
Merge branch 'main' into add-crm-app-type
joeauyeung Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/web/pages/apps/installed/[category].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { useReducer } from "react";

import getAppCategoryTitle from "@calcom/app-store/_utils/getAppCategoryTitle";
import DisconnectIntegrationModal from "@calcom/features/apps/components/DisconnectIntegrationModal";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
Expand Down Expand Up @@ -57,11 +58,13 @@ const IntegrationsContainer = ({
customLoader={<SkeletonLoader />}
success={({ data }) => {
if (!data.items.length) {
const emptyHeaderCategory = getAppCategoryTitle(variant || "other", true);

return (
<EmptyScreen
Icon={emptyIcon[variant || "other"]}
headline={t("no_category_apps", {
category: (variant && t(variant).toLowerCase()) || t("other").toLowerCase(),
category: emptyHeaderCategory,
})}
description={t(`no_category_apps_description_${variant || "other"}`)}
buttonRaw={
Expand Down
9 changes: 9 additions & 0 deletions apps/web/playwright/payment-apps.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
await prisma.credential.create({
data: {
type: "alby_payment",
appId: "alby",
userId: user.id,
key: {
account_id: "random",
Expand Down Expand Up @@ -57,6 +58,7 @@
await prisma.credential.create({
data: {
type: "stripe_payment",
appId: "stripe",
userId: user.id,
key: {
scope: "read_write",
Expand Down Expand Up @@ -101,6 +103,7 @@
await prisma.credential.create({
data: {
type: "paypal_payment",
appId: "paypal",
userId: user.id,
key: {
client_id: "randomString",
Expand Down Expand Up @@ -147,6 +150,7 @@
await prisma.credential.create({
data: {
type: "alby_payment",
appId: "alby",
userId: user.id,
key: {},
},
Expand All @@ -173,6 +177,7 @@
await prisma.credential.create({
data: {
type: "paypal_payment",
appId: "paypal",
userId: user.id,
key: {},
},
Expand Down Expand Up @@ -227,13 +232,14 @@
const user = await users.create();
await user.apiLogin();
const paymentEvent = user.eventTypes.find((item) => item.slug === "paid");
if (!paymentEvent) {
throw new Error("No payment event found");
}

Check warning on line 237 in apps/web/playwright/payment-apps.e2e.ts

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

apps/web/playwright/payment-apps.e2e.ts#L235-L237

[playwright/no-conditional-in-test] Avoid having conditionals in tests
await prisma.credential.createMany({
data: [
{
type: "paypal_payment",
appId: "paypal",
userId: user.id,
key: {
client_id: "randomString",
Expand All @@ -243,6 +249,7 @@
},
{
type: "stripe_payment",
appId: "stripe",
userId: user.id,
key: {
scope: "read_write",
Expand Down Expand Up @@ -271,14 +278,15 @@
const user = await users.create();
await user.apiLogin();
const paymentEvent = user.eventTypes.find((item) => item.slug === "paid");
if (!paymentEvent) {
throw new Error("No payment event found");
}

Check warning on line 283 in apps/web/playwright/payment-apps.e2e.ts

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

apps/web/playwright/payment-apps.e2e.ts#L281-L283

[playwright/no-conditional-in-test] Avoid having conditionals in tests

await prisma.credential.createMany({
data: [
{
type: "paypal_payment",
appId: "paypal",
userId: user.id,
key: {
client_id: "randomString",
Expand All @@ -288,6 +296,7 @@
},
{
type: "stripe_payment",
appId: "stripe",
userId: user.id,
key: {
scope: "read_write",
Expand Down
22 changes: 22 additions & 0 deletions packages/app-store/_utils/getAppCategoryTitle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { AppCategories } from "@calcom/prisma/enums";

/**
* Handles if the app category should be full capitalized ex. CRM
*
* @param {App["variant"]} variant - The variant of the app.
* @param {boolean} [returnLowerCase] - Optional flag to return the title in lowercase.
*/
const getAppCategoryTitle = (variant: AppCategories, returnLowerCase?: boolean) => {
let title: string;

if (variant === "crm") {
title = "CRM";
return title;
} else {
title = variant;
}

return returnLowerCase ? title.toLowerCase() : title;
};

export default getAppCategoryTitle;
5 changes: 5 additions & 0 deletions packages/app-store/_utils/getCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export const getCalendar = async (credential: CredentialPayload | null): Promise
if (calendarType?.endsWith("_other_calendar")) {
calendarType = calendarType.split("_other_calendar")[0];
}
// Backwards compatibility until CRM manager is created
if (calendarType?.endsWith("_crm")) {
calendarType = calendarType.split("_crm")[0];
}

const calendarAppImportFn = appStore[calendarType.split("_").join("") as keyof typeof appStore];

if (!calendarAppImportFn) {
Expand Down
5 changes: 3 additions & 2 deletions packages/app-store/closecom/api/_postAdd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import prisma from "@calcom/prisma";

import checkSession from "../../_utils/auth";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import appConfig from "../config.json";

export async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const session = checkSession(req);
Expand All @@ -18,10 +19,10 @@ export async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const encrypted = symmetricEncrypt(JSON.stringify({ api_key }), process.env.CALENDSO_ENCRYPTION_KEY || "");

const data = {
type: "closecom_other_calendar",
type: appConfig.type,
key: { encrypted },
userId: session.user?.id,
appId: "closecom",
appId: appConfig.slug,
};

try {
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/closecom/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"name": "Close.com",
"title": "Close.com",
"slug": "closecom",
"type": "closecom_other_calendar",
"type": "closecom_crm",
"logo": "icon.svg",
"url": "https://cal.com/",
"variant": "other",
"variant": "crm",
"categories": ["crm"],
"publisher": "Cal.com, Inc.",
"email": "help@cal.com",
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/hubspot/_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const metadata = {
name: "HubSpot CRM",
installed: !!process.env.HUBSPOT_CLIENT_ID,
description: _package.description,
type: "hubspot_other_calendar",
variant: "other_calendar",
type: "hubspot_crm",
variant: "crm",
logo: "icon.svg",
publisher: "Cal.com",
url: "https://hubspot.com/",
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/hubspot/api/add.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as hubspot from "@hubspot/api-client";
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import { encodeOAuthState } from "../../_utils/oauth/encodeOAuthState";
Expand All @@ -18,7 +18,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (typeof appKeys.client_id === "string") client_id = appKeys.client_id;
if (!client_id) return res.status(400).json({ message: "HubSpot client id missing." });

const redirectUri = `${WEBAPP_URL}/api/integrations/hubspot/callback`;
const redirectUri = `${WEBAPP_URL_FOR_OAUTH}/api/integrations/hubspot/callback`;
const url = hubspotClient.oauth.getAuthorizationUrl(
client_id,
redirectUri,
Expand Down
7 changes: 4 additions & 3 deletions packages/app-store/hubspot/api/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import * as hubspot from "@hubspot/api-client";
import type { TokenResponseIF } from "@hubspot/api-client/lib/codegen/oauth/models/TokenResponseIF";
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import createOAuthAppCredential from "../../_utils/oauth/createOAuthAppCredential";
import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
import metadata from "../_metadata";

let client_id = "";
let client_secret = "";
Expand Down Expand Up @@ -39,15 +40,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const hubspotToken: HubspotToken = await hubspotClient.oauth.tokensApi.createToken(
"authorization_code",
code,
`${WEBAPP_URL}/api/integrations/hubspot/callback`,
`${WEBAPP_URL_FOR_OAUTH}/api/integrations/hubspot/callback`,
client_id,
client_secret
);

// set expiry date as offset from current time.
hubspotToken.expiryDate = Math.round(Date.now() + hubspotToken.expiresIn * 1000);

await createOAuthAppCredential({ appId: "hubspot", type: "hubspot_other_calendar" }, hubspotToken, req);
await createOAuthAppCredential({ appId: metadata.slug, type: metadata.type }, hubspotToken, req);

const state = decodeOAuthState(req);
res.redirect(
Expand Down
2 changes: 1 addition & 1 deletion packages/app-store/pipedrive-crm/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"/*": "Don't modify slug - If required, do it using cli edit command",
"name": "Pipedrive CRM",
"slug": "pipedrive-crm",
"type": "pipedrive-crm_other_calendar",
"type": "pipedrive-crm_crm",
"logo": "icon.svg",
"url": "https://revert.dev",
"variant": "crm",
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/salesforce/api/add.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import jsforce from "jsforce";
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import { encodeOAuthState } from "../../_utils/oauth/encodeOAuthState";
Expand All @@ -17,7 +17,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)

const salesforceClient = new jsforce.Connection({
clientId: consumer_key,
redirectUri: `${WEBAPP_URL}/api/integrations/salesforce/callback`,
redirectUri: `${WEBAPP_URL_FOR_OAUTH}/api/integrations/salesforce/callback`,
});

const url = salesforceClient.oauth2.getAuthorizationUrl({
Expand Down
11 changes: 4 additions & 7 deletions packages/app-store/salesforce/api/callback.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import jsforce from "jsforce";
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";

import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import createOAuthAppCredential from "../../_utils/oauth/createOAuthAppCredential";
import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
import appConfig from "../config.json";

let consumer_key = "";
let consumer_secret = "";
Expand All @@ -33,16 +34,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const conn = new jsforce.Connection({
clientId: consumer_key,
clientSecret: consumer_secret,
redirectUri: `${WEBAPP_URL}/api/integrations/salesforce/callback`,
redirectUri: `${WEBAPP_URL_FOR_OAUTH}/api/integrations/salesforce/callback`,
});

const salesforceTokenInfo = await conn.oauth2.requestToken(code as string);

await createOAuthAppCredential(
{ appId: "salesforce", type: "salesforce_other_calendar" },
salesforceTokenInfo,
req
);
await createOAuthAppCredential({ appId: appConfig.slug, type: appConfig.type }, salesforceTokenInfo, req);

const state = decodeOAuthState(req);
res.redirect(
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/salesforce/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"/*": "Don't modify slug - If required, do it using cli edit command",
"name": "Salesforce",
"slug": "salesforce",
"type": "salesforce_other_calendar",
"type": "salesforce_crm",
"logo": "icon.png",
"url": "https://cal.com/",
"variant": "other_calendar",
"variant": "crm",
"categories": ["crm"],
"publisher": "Cal.com, Inc.",
"email": "help@cal.com",
Expand Down
2 changes: 1 addition & 1 deletion packages/app-store/sendgrid/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"logo": "logo.png",
"url": "https://cal.com/",
"variant": "other_calendar",
"categories": ["crm"],
"categories": ["other"],
"publisher": "Cal.com, Inc.",
"email": "help@cal.com",
"description": "SendGrid delivers your transactional and marketing emails through the world's largest cloud-based email delivery platform.",
Expand Down
2 changes: 1 addition & 1 deletion packages/app-store/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const ALL_APPS = Object.values(ALL_APPS_MAP);
*/
function getApps(credentials: CredentialDataWithTeamName[], filterOnCredentials?: boolean) {
const apps = ALL_APPS.reduce((reducedArray, appMeta) => {
const appCredentials = credentials.filter((credential) => credential.type === appMeta.type);
const appCredentials = credentials.filter((credential) => credential.appId === appMeta.slug);

if (filterOnCredentials && !appCredentials.length && !appMeta.isGlobal) return reducedArray;

Expand Down
6 changes: 3 additions & 3 deletions packages/app-store/zoho-bigin/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"/*": "Don't modify slug - If required, do it using cli edit command",
"name": "Zoho Bigin",
"slug": "zoho-bigin",
"type": "zoho-bigin_other_calendar",
"type": "zoho-bigin_crm",
"logo": "zohobigin.svg",
"url": "https://github.com/ShaneMaglangit",
"variant": "other",
"categories": ["other"],
"variant": "crm",
"categories": ["crm"],
"publisher": "Shane Maglangit",
"email": "help@cal.com",
"description": "Bigin easily transforms your day-to-day customer processes into actionable pipelines. From qualifying leads to closing deals to managing important after-sales operations—Bigin connects your different teams to work together so that you can offer the best possible experience to your customers. Say goodbye to missing follow-ups, manual data entry, lack of team communication, and information silos.",
Expand Down
7 changes: 2 additions & 5 deletions packages/app-store/zohocrm/api/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import createOAuthAppCredential from "../../_utils/oauth/createOAuthAppCredential";
import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
import appConfig from "../config.json";

let client_id = "";
let client_secret = "";
Expand Down Expand Up @@ -51,11 +52,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
zohoCrmTokenInfo.data.expiryDate = Math.round(Date.now() + 60 * 60);
zohoCrmTokenInfo.data.accountServer = req.query["accounts-server"];

await createOAuthAppCredential(
{ appId: "zohocrm", type: "zohocrm_other_calendar" },
zohoCrmTokenInfo.data,
req
);
await createOAuthAppCredential({ appId: appConfig.slug, type: appConfig.type }, zohoCrmTokenInfo.data, req);

const state = decodeOAuthState(req);
res.redirect(
Expand Down
4 changes: 2 additions & 2 deletions packages/app-store/zohocrm/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"/*": "Don't modify slug - If required, do it using cli edit command",
"name": "ZohoCRM",
"slug": "zohocrm",
"type": "zohocrm_other_calendar",
"type": "zohocrm_crm",
"logo": "icon.svg",
"url": "https://github.com/jatinsandilya",
"variant": "other",
"variant": "crm",
"categories": ["crm"],
"publisher": "Jatin Sandilya",
"email": "help@cal.com",
Expand Down