feat: implement role-based access control (RBAC) management system with Keycloak integration and dynamic page permission configuration
This commit is contained in:
No files matched your search
@@ -0,0 +1,23 @@
|
||||
// server/api/hak-akses/check.ts
|
||||
export default defineEventHandler(async (event) => {
|
||||
// This is a mock endpoint to simulate backend checking permission.
|
||||
// In production, the backend will validate the user's token directly.
|
||||
const method = event.method;
|
||||
if (method === 'POST') {
|
||||
const body = await readBody(event);
|
||||
const { menuKey, action } = body;
|
||||
|
||||
// Simulating some random failure or checking logic
|
||||
if (!menuKey || !action) {
|
||||
return createError({ statusCode: 400, statusMessage: 'Bad Request: menuKey and action required' });
|
||||
}
|
||||
|
||||
// Just simulating success for now.
|
||||
return {
|
||||
success: true,
|
||||
message: `Mock check: User has ${action} permission for ${menuKey}`,
|
||||
allowed: true
|
||||
}
|
||||
}
|
||||
return createError({ statusCode: 405, statusMessage: 'Method Not Allowed' });
|
||||
});
|
||||
@@ -1,12 +1,12 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import type { HakAkses } from '~/types/setting';
|
||||
import { randomUUID } from 'node:crypto'; // Use standard node crypto
|
||||
import { hakAksesPayloadSchema, type HakAksesPayload } from '~/server/utils/schemas/permissionSchema';
|
||||
|
||||
const filePath = path.resolve('data/mock/hakAkses.json');
|
||||
|
||||
// Helper to read JSON file
|
||||
const readData = (): HakAkses[] => {
|
||||
const readData = (): HakAksesPayload[] => {
|
||||
try {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
// Ensure directory exists
|
||||
@@ -26,7 +26,7 @@ const readData = (): HakAkses[] => {
|
||||
};
|
||||
|
||||
// Helper to write JSON file
|
||||
const writeData = (data: HakAkses[]): boolean => {
|
||||
const writeData = (data: HakAksesPayload[]): boolean => {
|
||||
try {
|
||||
fs.writeFileSync(filePath, JSON.stringify(data, null, 4), 'utf-8');
|
||||
return true;
|
||||
@@ -51,7 +51,20 @@ export default defineEventHandler(async (event) => {
|
||||
// POST - Create or Update hak akses
|
||||
if (method === 'POST') {
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const rawBody = await readBody(event);
|
||||
|
||||
// Validate payload with Zod Schema (Contract testing)
|
||||
const validationResult = hakAksesPayloadSchema.safeParse(rawBody);
|
||||
|
||||
if (!validationResult.success) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Payload invalid: Gagal menyimpan hak akses',
|
||||
error: validationResult.error.format()
|
||||
};
|
||||
}
|
||||
|
||||
const body = validationResult.data;
|
||||
const data = readData();
|
||||
|
||||
if (body.id) {
|
||||
@@ -63,18 +76,21 @@ export default defineEventHandler(async (event) => {
|
||||
...body
|
||||
};
|
||||
} else {
|
||||
data.push(body);
|
||||
data.push(body as HakAksesPayload);
|
||||
}
|
||||
} else {
|
||||
// Create new
|
||||
const newId = randomUUID();
|
||||
const newHakAkses: HakAkses = {
|
||||
id: newId,
|
||||
namaHakAkses: body.namaHakAkses,
|
||||
status: body.status || 'aktif',
|
||||
pages: body.pages || []
|
||||
};
|
||||
data.push(newHakAkses);
|
||||
body.id = randomUUID();
|
||||
|
||||
// For backward compatibility with HakAkses.vue UI that expects 'namaHakAkses'
|
||||
if (!body.namaHakAkses) {
|
||||
body.namaHakAkses = body.role || body.group || body.namaTipeUser || "Unknown";
|
||||
}
|
||||
if (!body.status) {
|
||||
body.status = 'aktif';
|
||||
}
|
||||
|
||||
data.push(body as HakAksesPayload);
|
||||
}
|
||||
|
||||
const success = writeData(data);
|
||||
@@ -91,7 +107,7 @@ export default defineEventHandler(async (event) => {
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Gagal menyimpan hak akses',
|
||||
message: 'Gagal memproses request',
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user