49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { randomBytes } from "node:crypto";
|
|
import { cookies } from "next/headers";
|
|
import { requireAdmin } from "@/lib/auth";
|
|
|
|
const TIKTOK_OAUTH_STATE_COOKIE = "tiktok-oauth-state";
|
|
|
|
/**
|
|
* GET /api/auth/tiktok
|
|
* Redirects to TikTok OAuth authorization page.
|
|
* Visit this URL once to start the OAuth flow and get your refresh token.
|
|
*/
|
|
export async function GET() {
|
|
await requireAdmin();
|
|
|
|
const clientKey = process.env.TIKTOK_CLIENT_KEY;
|
|
const redirectUri = `${process.env.BASE_URL}/api/auth/tiktok/callback`;
|
|
|
|
if (!clientKey) {
|
|
return NextResponse.json(
|
|
{ error: "TIKTOK_CLIENT_KEY not set in environment" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
const csrfState = randomBytes(32).toString("hex");
|
|
|
|
const params = new URLSearchParams({
|
|
client_key: clientKey,
|
|
scope: "user.info.basic,user.info.profile,user.info.stats,video.list,video.publish",
|
|
response_type: "code",
|
|
redirect_uri: redirectUri,
|
|
state: csrfState,
|
|
});
|
|
|
|
const authUrl = `https://www.tiktok.com/v2/auth/authorize/?${params.toString()}`;
|
|
|
|
const response = NextResponse.redirect(authUrl);
|
|
const cookieStore = await cookies();
|
|
cookieStore.set(TIKTOK_OAUTH_STATE_COOKIE, csrfState, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === "production",
|
|
sameSite: "lax",
|
|
maxAge: 600,
|
|
path: "/api/auth/tiktok",
|
|
});
|
|
return response;
|
|
}
|