Files
calendar/example-apps/credential-sync/pages/api/setTokenInCalCom.ts
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7c373ddad6 feat: Introduce biome (#25664)
* Configure biome

* Fix companion build

* fix: remove generated files from formatter ignore list to enable proper formatting

Co-Authored-By: Volnei Munhoz <[email protected]>

* fix: add explicit stripe dependency to @calcom/features to fix type resolution

Co-Authored-By: Volnei Munhoz <[email protected]>

* fix: rename const require to nodeRequire in generate-swagger.ts to avoid TypeScript reserved identifier conflict

Co-Authored-By: Volnei Munhoz <[email protected]>

* fix: add guard for document in makeBodyVisible to prevent test environment teardown errors

Co-Authored-By: Volnei Munhoz <[email protected]>

* fix: replace ESLint with Biome CLI in embed-code-generator.e2e.ts

Co-Authored-By: Volnei Munhoz <[email protected]>

* fix: address cubic review comments

- Fix invalid --reporter-path Biome CLI option by using shell redirection
- Fix packages/lib lint report filename (app-store.json -> lib.json)
- Add typescript-eslint and eslint back to companion for lint:react-compiler
- Add missing restricted import rules to biome.json:
  - packages/lib: add ../trpc/** and @trpc/server restrictions
  - packages/trpc: add ../apps/web/** restriction

Co-Authored-By: Volnei Munhoz <[email protected]>

* chore: regenerate companion bun.lock after adding eslint dependencies

Co-Authored-By: Volnei Munhoz <[email protected]>

* Remove remaining eslint things

* add tailwind directives

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 19:41:41 -03:00

68 lines
2.1 KiB
TypeScript

import type { NextApiRequest } from "next";
import { symmetricEncrypt } from "@calcom/lib/crypto";
import {
CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY,
CALCOM_CREDENTIAL_SYNC_SECRET,
CALCOM_CREDENTIAL_SYNC_HEADER_NAME,
CALCOM_ADMIN_API_KEY,
} from "../../constants";
import { generateGoogleCalendarAccessToken, generateZoomAccessToken } from "../../lib/integrations";
export default async function handler(req: NextApiRequest, res) {
const isInvalid = req.query.invalid === "1";
const userId = parseInt(req.query.userId as string, 10);
const appSlug = req.query.appSlug;
try {
let accessToken;
if (appSlug === "google-calendar") {
accessToken = await generateGoogleCalendarAccessToken();
} else if (appSlug === "zoom") {
accessToken = await generateZoomAccessToken();
} else {
throw new Error(`Unhandled appSlug: ${appSlug}`);
}
if (!accessToken) {
return res.status(500).json({ error: "Could not get access token" });
}
const result = await fetch(
`http://localhost:3002/api/v1/credential-sync?apiKey=${CALCOM_ADMIN_API_KEY}&userId=${userId}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
[CALCOM_CREDENTIAL_SYNC_HEADER_NAME]: CALCOM_CREDENTIAL_SYNC_SECRET,
},
body: JSON.stringify({
appSlug,
encryptedKey: symmetricEncrypt(
JSON.stringify({
access_token: isInvalid ? "1233231231231" : accessToken,
}),
CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY
),
}),
}
);
const clonedResult = result.clone();
try {
if (result.ok) {
const json = await result.json();
return res.status(200).json(json);
} else {
return res.status(400).json({ error: await clonedResult.text() });
}
} catch (e) {
return res.status(400).json({ error: await clonedResult.text() });
}
} catch (error) {
console.error(error);
return res.status(400).json({ message: "Internal Server Error", error: error.message });
}
}