User yang sudah registrasi sudah langsung diarahkan ke layout sesuai dengan roleIdnya
Superadmin sudah bisa menambah atau mengurangkan menu pad user yang diinginkan Next------------------------------- Ada bug saat tampilan menu sudah di edit superamin berhasil namun saat user logout tampilan menunya balik ke sebelumnya
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// app/api/auth/_lib/session_create.ts
|
||||
// src/app/api/auth/_lib/sessionCreate.ts
|
||||
import { cookies } from "next/headers";
|
||||
import { encrypt } from "./encrypt";
|
||||
import prisma from "@/lib/prisma";
|
||||
@@ -9,11 +9,13 @@ export async function sessionCreate({
|
||||
exp = "30 day",
|
||||
jwtSecret,
|
||||
user,
|
||||
invalidatePrevious = true, // 🔑 kontrol apakah sesi lama di-nonaktifkan
|
||||
}: {
|
||||
sessionKey: string;
|
||||
exp?: string;
|
||||
jwtSecret: string;
|
||||
user: Record<string, unknown> & { id: string };
|
||||
invalidatePrevious?: boolean; // default true untuk login, false untuk registrasi
|
||||
}) {
|
||||
// ✅ Validasi env vars
|
||||
if (!sessionKey || sessionKey.length === 0) {
|
||||
@@ -28,18 +30,19 @@ export async function sessionCreate({
|
||||
throw new Error("Token generation failed");
|
||||
}
|
||||
|
||||
// ✅ Hitung expiresAt sesuai exp
|
||||
// ✅ Hitung expiresAt
|
||||
let expiresAt = add(new Date(), { days: 30 });
|
||||
if (exp === "7 day") expiresAt = add(new Date(), { days: 7 });
|
||||
// tambahkan opsi lain jika perlu
|
||||
|
||||
// Sebelum create session baru, nonaktifkan session aktif sebelumnya
|
||||
await prisma.userSession.updateMany({
|
||||
where: { userId: user.id, active: true },
|
||||
data: { active: false },
|
||||
});
|
||||
// 🔐 Hanya nonaktifkan sesi aktif sebelumnya jika diminta (misal: saat login ulang)
|
||||
if (invalidatePrevious) {
|
||||
await prisma.userSession.updateMany({
|
||||
where: { userId: user.id, active: true },
|
||||
data: { active: false },
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Simpan ke database
|
||||
// ✅ Simpan sesi baru
|
||||
await prisma.userSession.create({
|
||||
data: {
|
||||
token,
|
||||
@@ -55,8 +58,8 @@ export async function sessionCreate({
|
||||
sameSite: "lax",
|
||||
path: "/",
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 30 * 24 * 60 * 60, // seconds
|
||||
maxAge: 30 * 24 * 60 * 60, // 30 hari dalam detik
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -30,13 +30,7 @@ export async function verifySession() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ❌ Hanya tolak jika sessionInvalid = true
|
||||
if (dbSession.user.sessionInvalid) {
|
||||
console.log('⚠️ Session di-invalidate');
|
||||
return null;
|
||||
}
|
||||
|
||||
// ✅ Return user, meskipun isActive = false
|
||||
// Don't check isActive here, let the frontend handle it
|
||||
return dbSession.user;
|
||||
} catch (error) {
|
||||
console.warn('Session verification failed:', error);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// src/app/api/auth/finalize-registration/route.ts
|
||||
|
||||
import prisma from "@/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
import { sessionCreate } from "../_lib/session_create";
|
||||
@@ -7,7 +6,6 @@ import { sessionCreate } from "../_lib/session_create";
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const { nomor, username, kodeId } = await req.json();
|
||||
|
||||
const cleanNomor = nomor.replace(/\D/g, "");
|
||||
|
||||
if (!cleanNomor || !username || !kodeId) {
|
||||
@@ -17,13 +15,7 @@ export async function POST(req: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Di awal fungsi POST
|
||||
console.log("📦 Received payload:", { nomor, username, kodeId });
|
||||
|
||||
// Validasi OTP
|
||||
const otpRecord = await prisma.kodeOtp.findUnique({
|
||||
where: { id: kodeId },
|
||||
});
|
||||
const otpRecord = await prisma.kodeOtp.findUnique({ where: { id: kodeId } });
|
||||
if (!otpRecord?.isActive || otpRecord.nomor !== cleanNomor) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "OTP tidak valid" },
|
||||
@@ -31,7 +23,6 @@ export async function POST(req: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Cek duplikat username
|
||||
if (await prisma.user.findFirst({ where: { username } })) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Username sudah digunakan" },
|
||||
@@ -39,7 +30,6 @@ export async function POST(req: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// ✅ Gunakan username dari input user
|
||||
const defaultRole = await prisma.role.findFirst({
|
||||
where: { name: "ADMIN DESA" },
|
||||
select: { id: true },
|
||||
@@ -52,23 +42,20 @@ export async function POST(req: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// ✅ Buat user dengan username yang diinput
|
||||
const newUser = await prisma.user.create({
|
||||
data: {
|
||||
username, // ✅ Ini yang benar
|
||||
username,
|
||||
nomor,
|
||||
roleId: defaultRole.id,
|
||||
isActive: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Nonaktifkan OTP
|
||||
await prisma.kodeOtp.update({
|
||||
where: { id: kodeId },
|
||||
data: { isActive: false },
|
||||
});
|
||||
|
||||
// ✅ BUAT SESI untuk user baru (meski isActive = false)
|
||||
const token = await sessionCreate({
|
||||
sessionKey: process.env.BASE_SESSION_KEY!,
|
||||
jwtSecret: process.env.BASE_TOKEN_KEY!,
|
||||
@@ -76,24 +63,15 @@ export async function POST(req: Request) {
|
||||
user: {
|
||||
id: newUser.id,
|
||||
nomor: newUser.nomor,
|
||||
username: newUser.username, // ✅ Pastikan sesuai
|
||||
roleId: newUser.roleId,
|
||||
isActive: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Set cookie
|
||||
const response = NextResponse.json({
|
||||
success: true,
|
||||
message: "Registrasi berhasil. Menunggu persetujuan admin.",
|
||||
user: {
|
||||
id: newUser.id,
|
||||
name: newUser.username,
|
||||
username: newUser.username,
|
||||
roleId: newUser.roleId,
|
||||
isActive: false,
|
||||
},
|
||||
invalidatePrevious: false,
|
||||
});
|
||||
|
||||
// ✅ REDIRECT DARI SERVER — cookie pasti tersedia
|
||||
const response = NextResponse.redirect(new URL('/waiting-room', req.url));
|
||||
response.cookies.set(process.env.BASE_SESSION_KEY!, token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
@@ -111,4 +89,4 @@ export async function POST(req: Request) {
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/app/api/auth/refresh-session/route.ts
Normal file
55
src/app/api/auth/refresh-session/route.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { verifySession } from '../_lib/session_verify';
|
||||
import { sessionCreate } from '../_lib/session_create';
|
||||
import prisma from '@/lib/prisma';
|
||||
|
||||
export async function POST() {
|
||||
try {
|
||||
const sessionUser = await verifySession();
|
||||
if (!sessionUser) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Unauthorized" },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
// Get fresh user data
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: sessionUser.id },
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
roleId: true,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "User not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
// Create new session with updated data
|
||||
await sessionCreate({
|
||||
sessionKey: process.env.BASE_SESSION_KEY!,
|
||||
jwtSecret: process.env.BASE_TOKEN_KEY!,
|
||||
user: {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
roleId: user.roleId,
|
||||
isActive: user.isActive,
|
||||
},
|
||||
invalidatePrevious: false, // Keep existing sessions
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('Error refreshing session:', error);
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user