Files
multiverse/jumpa-iam/app/api/auth/register/route.ts
T

84 lines
2.5 KiB
TypeScript

import { NextResponse } from 'next/server';
import { db, writerDb } from "@/drizzle/db";
import { users, tenants } from "@/drizzle/schema";
import { eq } from 'drizzle-orm';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';
export async function POST(req: Request) {
try {
const { email, password } = await req.json();
if (!email || !password || password.length < 6) {
return NextResponse.json({ error: 'Email and password (min 6 chars) are required' }, { status: 400 });
}
// Check if email already exists
const existingUser = await db.select().from(users).where(eq(users.email, email)).limit(1);
if (existingUser.length > 0) {
return NextResponse.json({ error: 'Email sudah terdaftar.' }, { status: 409 });
}
// Create a new Tenant for the user
const tenantName = `Personal Workspace - ${email.split('@')[0]}`;
const newTenantResult = await writerDb.insert(tenants).values({
name: tenantName,
isActive: true
}).returning({ id: tenants.id, name: tenants.name });
const newTenant = newTenantResult[0];
// Create the user with bcrypt-hashed password (Kelas Militer)
const hashedPassword = await bcrypt.hash(password, 12);
const newUserResult = await writerDb.insert(users).values({
email: email,
passwordHash: hashedPassword,
tenantId: newTenant.id,
role: 'admin' // The creator of the personal tenant is an admin
}).returning({ id: users.id, email: users.email, role: users.role });
const user = newUserResult[0];
// Generate JWT Token
const token = jwt.sign(
{
userId: user.id,
email: user.email,
role: user.role,
tenantId: newTenant.id,
tenantName: newTenant.name,
licenses: {}
},
process.env.JWT_SECRET as string,
{ expiresIn: '8h' }
);
const response = NextResponse.json({
message: 'Registrasi Berhasil.',
user: {
email: user.email,
role: user.role,
tenantName: newTenant.name
}
}, { status: 201 });
// Set HttpOnly Cookie for SSO
response.cookies.set({
name: 'jumpa_token',
value: token,
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
domain: process.env.NEXT_PUBLIC_COOKIE_DOMAIN || undefined,
maxAge: 8 * 60 * 60
});
return response;
} catch (error) {
console.error('[API REGISTER ERROR]', error);
return NextResponse.json({ error: 'Kesalahan Sistem Internal PostgreSQL' }, { status: 500 });
}
}