Spaces:
Sleeping
Sleeping
File size: 2,834 Bytes
89ccd89 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import crypto from "crypto";
// GET — list user's API keys
export async function GET() {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const { data: profile } = await supabase.from("profiles").select("plan, team_id").eq("id", user.id).single();
if (profile?.plan === "free") return NextResponse.json({ error: "API access requires Pro or Team plan" }, { status: 403 });
const { data: keys } = await supabase.from("api_keys")
.select("id, name, key_prefix, calls_this_month, calls_limit, is_active, last_used_at, created_at")
.eq("user_id", user.id)
.order("created_at", { ascending: false });
return NextResponse.json({ keys: keys || [] });
}
// POST — create new API key
export async function POST(req: NextRequest) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const { data: profile } = await supabase.from("profiles").select("plan, team_id").eq("id", user.id).single();
if (profile?.plan === "free") return NextResponse.json({ error: "API access requires Pro or Team plan" }, { status: 403 });
const { name } = await req.json();
// Generate key: cg_live_ + 32 random hex chars
const rawKey = "cg_live_" + crypto.randomBytes(24).toString("hex");
const keyHash = crypto.createHash("sha256").update(rawKey).digest("hex");
const keyPrefix = rawKey.substring(0, 16) + "...";
const callsLimit = profile?.plan === "team" ? 10000 : 1000;
const { error } = await supabase.from("api_keys").insert({
user_id: user.id,
team_id: profile?.team_id || null,
name: name || "Default",
key_hash: keyHash,
key_prefix: keyPrefix,
calls_limit: callsLimit,
});
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
// Return the full key ONCE — it's never shown again
return NextResponse.json({ key: rawKey, prefix: keyPrefix, name, calls_limit: callsLimit });
}
// DELETE — revoke an API key
export async function DELETE(req: NextRequest) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const { keyId } = await req.json();
const { error } = await supabase.from("api_keys")
.update({ is_active: false })
.eq("id", keyId)
.eq("user_id", user.id);
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
return NextResponse.json({ success: true });
}
|