Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import type { NextApiRequest, NextApiResponse } from "next";
|
|
|
|
import { WEBAPP_URL } from "@calcom/lib/constants";
|
|
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
|
|
import { HttpError } from "@calcom/lib/http-error";
|
|
|
|
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
|
|
import getParsedAppKeysFromSlug from "../../_utils/getParsedAppKeysFromSlug";
|
|
import createOAuthAppCredential from "../../_utils/oauth/createOAuthAppCredential";
|
|
import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState";
|
|
import { dubAppKeysSchema } from "../lib/utils";
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
const { code } = req.query;
|
|
|
|
const state = decodeOAuthState(req);
|
|
|
|
if (typeof code !== "string") {
|
|
if (state?.onErrorReturnTo || state?.returnTo) {
|
|
res.redirect(
|
|
getSafeRedirectUrl(state.onErrorReturnTo) ??
|
|
getSafeRedirectUrl(state?.returnTo) ??
|
|
`${WEBAPP_URL}/apps/installed`
|
|
);
|
|
return;
|
|
}
|
|
throw new HttpError({ statusCode: 400, message: "`code` must be a string" });
|
|
}
|
|
|
|
if (!req.session?.user?.id) {
|
|
throw new HttpError({ statusCode: 401, message: "You must be logged in to do this" });
|
|
}
|
|
|
|
const { client_id, redirect_uris, client_secret } = await getParsedAppKeysFromSlug("dub", dubAppKeysSchema);
|
|
|
|
const codeExchangeUrl = `https://api.dub.co/oauth/token`;
|
|
|
|
const result = await fetch(codeExchangeUrl, {
|
|
method: "POST",
|
|
body: new URLSearchParams({
|
|
code,
|
|
client_id,
|
|
redirect_uri: redirect_uris,
|
|
client_secret,
|
|
grant_type: "authorization_code",
|
|
}).toString(),
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
});
|
|
|
|
if (result.status !== 200) {
|
|
let errorMessage = "Something wrong with Dub Api";
|
|
try {
|
|
const responseBody = await result.json();
|
|
if (typeof responseBody?.error?.message === "string") {
|
|
errorMessage = responseBody.error.message;
|
|
}
|
|
} catch (err) {
|
|
return;
|
|
}
|
|
|
|
return res.status(400).json({ message: errorMessage });
|
|
}
|
|
|
|
const responseBody = await result.json();
|
|
|
|
responseBody.expiry_date = Math.round(Date.now() + responseBody.expires_in * 1000);
|
|
delete responseBody.expires_in;
|
|
|
|
await createOAuthAppCredential({ appId: "dub", type: "dub" }, responseBody, req);
|
|
|
|
res.redirect(
|
|
getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath({ variant: "analytics", slug: "dub" })
|
|
);
|
|
}
|