chore: migrate oauth APIs to app router (#19824)

* migrate api/auth/oauth/me

* migrate the rest

* fix

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
Benny Joo
2025-03-10 17:56:53 +01:00
committed by GitHub
co-authored by Anik Dhabal Babu
parent 4a4bee7140
commit 3ab053bf17
6 changed files with 40 additions and 53 deletions
+18
View File
@@ -0,0 +1,18 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import isAuthorized from "@calcom/features/auth/lib/oAuthAuthorization";
async function handler(req: NextRequest) {
const requiredScopes = ["READ_PROFILE"];
const token = req.headers.get("authorization")?.split(" ")[1] || "";
const account = await isAuthorized(token, requiredScopes);
if (!account) {
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
return NextResponse.json({ username: account.name }, { status: 201 });
}
export { handler as GET, handler as POST };
@@ -1,23 +1,16 @@
import jwt from "jsonwebtoken";
import type { NextApiRequest, NextApiResponse } from "next";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import prisma from "@calcom/prisma";
import { generateSecret } from "@calcom/trpc/server/routers/viewer/oAuth/addClient.handler";
import type { OAuthTokenPayload } from "@calcom/types/oauth";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") {
res.status(405).json({ message: "Invalid method" });
return;
}
const refreshToken = req.headers.authorization?.split(" ")[1] || "";
const { client_id, client_secret, grant_type } = req.body;
export async function POST(req: NextRequest) {
const { client_id, client_secret, grant_type } = await req.json();
if (grant_type !== "refresh_token") {
res.status(400).json({ message: "grant type invalid" });
return;
return NextResponse.json({ message: "grant type invalid" }, { status: 400 });
}
const [hashedSecret] = generateSecret(client_secret);
@@ -33,8 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!client) {
res.status(401).json({ message: "Unauthorized" });
return;
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
const secretKey = process.env.CALENDSO_ENCRYPTION_KEY || "";
@@ -42,15 +34,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
let decodedRefreshToken: OAuthTokenPayload;
try {
const refreshToken = req.headers.get("authorization")?.split(" ")[1] || "";
decodedRefreshToken = jwt.verify(refreshToken, secretKey) as OAuthTokenPayload;
} catch {
res.status(401).json({ message: "Unauthorized" });
return;
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
if (!decodedRefreshToken || decodedRefreshToken.token_type !== "Refresh Token") {
res.status(401).json({ message: "Unauthorized" });
return;
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
const payload: OAuthTokenPayload = {
@@ -65,5 +56,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
expiresIn: 1800, // 30 min
});
res.status(200).json({ access_token });
return NextResponse.json({ access_token }, { status: 200 });
}
@@ -1,21 +1,16 @@
import jwt from "jsonwebtoken";
import type { NextApiRequest, NextApiResponse } from "next";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import prisma from "@calcom/prisma";
import { generateSecret } from "@calcom/trpc/server/routers/viewer/oAuth/addClient.handler";
import type { OAuthTokenPayload } from "@calcom/types/oauth";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") {
res.status(405).json({ message: "Invalid method" });
return;
}
const { code, client_id, client_secret, grant_type, redirect_uri } = req.body;
export async function POST(req: NextRequest) {
const { code, client_id, client_secret, grant_type, redirect_uri } = await req.json();
if (grant_type !== "authorization_code") {
res.status(400).json({ message: "grant_type invalid" });
return;
return NextResponse.json({ message: "grant_type invalid" }, { status: 400 });
}
const [hashedSecret] = generateSecret(client_secret);
@@ -31,8 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!client || client.redirectUri !== redirect_uri) {
res.status(401).json({ message: "Unauthorized" });
return;
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
const accessCode = await prisma.accessCode.findFirst({
@@ -45,7 +39,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
},
});
//delete all expired accessCodes + the one that is used here
// Delete all expired accessCodes + the one that is used here
await prisma.accessCode.deleteMany({
where: {
OR: [
@@ -63,8 +57,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!accessCode) {
res.status(401).json({ message: "Unauthorized" });
return;
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
const secretKey = process.env.CALENDSO_ENCRYPTION_KEY || "";
@@ -93,5 +86,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
expiresIn: 30 * 24 * 60 * 60, // 30 days
});
res.status(200).json({ access_token, refresh_token });
return NextResponse.json({ access_token, refresh_token }, { status: 200 });
}
-14
View File
@@ -1,14 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import isAuthorized from "@calcom/features/auth/lib/oAuthAuthorization";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const requiredScopes = ["READ_PROFILE"];
const account = await isAuthorized(req, requiredScopes);
if (!account) {
return res.status(401).json({ message: "Unauthorized" });
}
return res.status(201).json({ username: account.name });
}
@@ -8,7 +8,8 @@ export async function validateAccountOrApiKey(req: NextApiRequest, requiredScope
const apiKey = req.query.apiKey as string;
if (!apiKey) {
const authorizedAccount = await isAuthorized(req, requiredScopes);
const token = req.headers.authorization?.split(" ")[1] || "";
const authorizedAccount = await isAuthorized(token, requiredScopes);
if (!authorizedAccount) throw new HttpError({ statusCode: 401, message: "Unauthorized" });
return { account: authorizedAccount, appApiKey: undefined };
}
@@ -1,11 +1,9 @@
import jwt from "jsonwebtoken";
import type { NextApiRequest } from "next";
import prisma from "@calcom/prisma";
import type { OAuthTokenPayload } from "@calcom/types/oauth";
export default async function isAuthorized(req: NextApiRequest, requiredScopes: string[] = []) {
const token = req.headers.authorization?.split(" ")[1] || "";
export default async function isAuthorized(token: string, requiredScopes: string[] = []) {
let decodedToken: OAuthTokenPayload;
try {
decodedToken = jwt.verify(token, process.env.CALENDSO_ENCRYPTION_KEY || "") as OAuthTokenPayload;