Dashboard-Automatizase/app/api/google-calendar/manage-credential/route.ts
Luis Erlacher 0152a2fda0 feat: add n8n API testing script for Google OAuth2 schema and existing credentials
- Implemented a bash script to test n8n API and retrieve credential schemas.
- Added types for API responses, Google Calendar, and WhatsApp instances.
- Configured Vitest for testing with React and added setup for testing-library.
2025-10-10 14:29:02 -03:00

171 lines
4.5 KiB
TypeScript

import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
import { type NextRequest, NextResponse } from "next/server";
import { upsertGoogleCredential } from "@/lib/n8n-api";
/**
* GET /api/google-calendar/manage-credential
*
* Retorna o ID da credencial "refugio" configurada
*
* @returns {credentialId: string}
*/
export async function GET(_request: NextRequest) {
try {
const cookieStore = await cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
for (const { name, value, options } of cookiesToSet) {
cookieStore.set(name, value, options);
}
},
},
},
);
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const credentialId = process.env.N8N_GOOGLE_CREDENTIAL_ID;
console.log("[manage-credential] GET - Credential ID:", credentialId);
return NextResponse.json({
success: true,
credentialId: credentialId || null,
});
} catch (error) {
console.error("[manage-credential] GET error:", error);
return NextResponse.json(
{ success: false, error: "Failed to get credential ID" },
{ status: 500 },
);
}
}
/**
* POST /api/google-calendar/manage-credential
*
* Story 3.4: Cria ou atualiza credencial "refugio" no n8n com tokens do Google
*
* @body {accessToken, refreshToken, expiresIn}
* @returns {success: boolean, credentialId: string}
*/
export async function POST(request: NextRequest) {
try {
const cookieStore = await cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
for (const { name, value, options } of cookiesToSet) {
cookieStore.set(name, value, options);
}
},
},
},
);
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await request.json();
const { accessToken, refreshToken, expiresIn } = body;
if (!accessToken || !refreshToken) {
return NextResponse.json(
{ success: false, error: "Missing required tokens" },
{ status: 400 },
);
}
console.log("[manage-credential] POST - User:", user.id);
const clientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID;
const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
if (!clientId || !clientSecret) {
throw new Error("Google OAuth credentials not configured");
}
// Upsert credencial "refugio" no n8n
const result = await upsertGoogleCredential(
"refugio",
clientId,
clientSecret,
"https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/calendar.events",
accessToken,
refreshToken,
expiresIn || 3599,
);
const credentialId = result.id;
console.log(
"[manage-credential] Credential upserted in n8n:",
credentialId,
);
// Salvar credentialId no Supabase (schema portal)
const { error: upsertError } = await supabase
.schema("portal")
.from("integrations")
.upsert(
{
user_id: user.id,
provider: "google_calendar",
status: "connected",
n8n_credential_id: credentialId,
updated_at: new Date().toISOString(),
},
{
onConflict: "user_id,provider",
},
);
if (upsertError) {
console.error("[manage-credential] Supabase upsert error:", upsertError);
throw upsertError;
}
console.log("[manage-credential] Integration status saved to Supabase");
return NextResponse.json({
success: true,
credentialId,
});
} catch (error) {
console.error("[manage-credential] POST error:", error);
return NextResponse.json(
{
success: false,
error:
error instanceof Error
? error.message
: "Failed to manage credential",
},
{ status: 500 },
);
}
}