|
|
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
|
import { getPool } from "@/lib/database";
|
|
|
|
|
import bcrypt from "bcryptjs";
|
|
|
|
|
|
|
|
|
|
export async function POST(request: NextRequest) {
|
|
|
|
|
try {
|
|
|
|
|
const { firstName, lastName, email, password } = await request.json();
|
|
|
|
|
|
|
|
|
|
// Validate input
|
|
|
|
|
if (!firstName || !lastName || !email || !password) {
|
|
|
|
|
return NextResponse.json(
|
|
|
|
|
{ error: "All fields are required" },
|
|
|
|
|
{ status: 400 }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate email format
|
|
|
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
|
|
if (!emailRegex.test(email)) {
|
|
|
|
|
return NextResponse.json(
|
|
|
|
|
{ error: "Invalid email format" },
|
|
|
|
|
{ status: 400 }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate password length
|
|
|
|
|
if (password.length < 6) {
|
|
|
|
|
return NextResponse.json(
|
|
|
|
|
{ error: "Password must be at least 6 characters" },
|
|
|
|
|
{ status: 400 }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const pool = getPool();
|
|
|
|
|
const client = await pool.connect();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Check if user already exists
|
|
|
|
|
const existingUser = await client.query(
|
|
|
|
|
"SELECT id FROM users WHERE email = $1",
|
|
|
|
|
[email]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (existingUser.rows.length > 0) {
|
|
|
|
|
return NextResponse.json(
|
|
|
|
|
{ error: "User with this email already exists" },
|
|
|
|
|
{ status: 409 }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hash the password
|
|
|
|
|
const saltRounds = 12;
|
|
|
|
|
const passwordHash = await bcrypt.hash(password, saltRounds);
|
|
|
|
|
|
|
|
|
|
// Insert new user
|
|
|
|
|
const result = await client.query(
|
|
|
|
|
`INSERT INTO users (email, password_hash, first_name, last_name, role, subscription_tier)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
|
|
|
RETURNING id, email, first_name, last_name, role, subscription_tier, created_at`,
|
|
|
|
|
[email, passwordHash, firstName, lastName, "USER", "BASIC"]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const newUser = result.rows[0];
|
|
|
|
|
|
|
|
|
|
// Don't create subscription automatically - users need to purchase a plan
|
|
|
|
|
// Subscriptions will be created when users complete payment via Stripe webhook
|
|
|
|
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "User created successfully",
|
|
|
|
|
user: {
|
|
|
|
|
id: newUser.id,
|
|
|
|
|
email: newUser.email,
|
|
|
|
|
firstName: newUser.first_name,
|
|
|
|
|
lastName: newUser.last_name,
|
|
|
|
|
role: newUser.role,
|
|
|
|
|
subscriptionTier: newUser.subscription_tier,
|
|
|
|
|
createdAt: newUser.created_at,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
client.release();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Registration error:", error);
|
|
|
|
|
return NextResponse.json(
|
|
|
|
|
{ error: "Internal server error" },
|
|
|
|
|
{ status: 500 }
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|