77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { exchangeCodeForTokens } from "@/lib/tiktok";
|
|
import { prisma } from "@/lib/prisma";
|
|
|
|
const baseUrl = process.env.NEXTAUTH_URL || "https://marouette.fun";
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const { searchParams } = new URL(request.url);
|
|
const code = searchParams.get("code");
|
|
const state = searchParams.get("state");
|
|
const error = searchParams.get("error");
|
|
|
|
if (error || !code || !state) {
|
|
return NextResponse.redirect(`${baseUrl}/tiktok?error=access_denied`);
|
|
}
|
|
|
|
try {
|
|
const pkceRecord = await prisma.tikTokPKCE.findUnique({ where: { state } });
|
|
if (!pkceRecord) {
|
|
return NextResponse.redirect(`${baseUrl}/tiktok?error=missing_verifier`);
|
|
}
|
|
|
|
await prisma.tikTokPKCE.delete({ where: { state } });
|
|
|
|
const { userId, codeVerifier } = pkceRecord;
|
|
|
|
console.log("[TikTok callback] codeVerifier from DB:", codeVerifier);
|
|
console.log("[TikTok callback] code from TikTok:", code);
|
|
|
|
const tokens = await exchangeCodeForTokens(code, codeVerifier);
|
|
const expiresAt = new Date(Date.now() + tokens.expires_in * 1000);
|
|
|
|
// Upsert sur userId — plusieurs users peuvent partager le même compte TikTok
|
|
await prisma.tikTokToken.upsert({
|
|
where: { userId },
|
|
update: {
|
|
openId: tokens.open_id,
|
|
accessToken: tokens.access_token,
|
|
refreshToken: tokens.refresh_token,
|
|
expiresAt,
|
|
},
|
|
create: {
|
|
userId,
|
|
openId: tokens.open_id,
|
|
accessToken: tokens.access_token,
|
|
refreshToken: tokens.refresh_token,
|
|
expiresAt,
|
|
},
|
|
});
|
|
|
|
// TrackedAccount : update si existe, sinon create
|
|
const existing = await prisma.trackedAccount.findFirst({
|
|
where: { userId, platform: "tiktok" },
|
|
});
|
|
|
|
if (existing) {
|
|
await prisma.trackedAccount.update({
|
|
where: { id: existing.id },
|
|
data: { username: tokens.open_id, accountId: tokens.open_id },
|
|
});
|
|
} else {
|
|
await prisma.trackedAccount.create({
|
|
data: {
|
|
userId,
|
|
platform: "tiktok",
|
|
username: tokens.open_id,
|
|
accountId: tokens.open_id,
|
|
},
|
|
});
|
|
}
|
|
|
|
return NextResponse.redirect(`${baseUrl}/tiktok?connected=1`);
|
|
} catch (err) {
|
|
console.error("[TikTok callback error]", err);
|
|
return NextResponse.redirect(`${baseUrl}/tiktok?error=token_exchange`);
|
|
}
|
|
} |