Pengaturan Hak Akses Fleksibel & Anti-Kecurangan
Mengatur hak buka, tambah, ubah, dan hapus untuk tiap jabatan secara leluasa lewat tabel centang, dilengkapi pengaman agar staf biasa tidak bisa menaikkan wewenangnya sendiri.
Mengatur hak buka, tambah, ubah, dan hapus untuk tiap jabatan secara leluasa lewat tabel centang, dilengkapi pengaman agar staf biasa tidak bisa menaikkan wewenangnya sendiri.
Tantangan & Kebutuhan Pengguna
Pada aplikasi skala enterprise, pembagian wewenang tidak cukup hanya mengandalkan pengecekan peran statis di kode seperti `user.role === 'ADMIN'`. Organisasi membutuhkan fleksibilitas untuk menambah peran baru dan mengatur izin spesifik per modul (`read`, `add`, `edit`, `delete`) langsung dari antarmuka dashboard tanpa perlu melakukan deployment ulang. Namun, kebebasan mengubah matriks izin membuka celah berbahaya: pengguna dengan akses manajemen peran dapat melakukan privilege escalation dengan memberikan izin yang lebih tinggi dari yang ia miliki sendiri.
Seorang pengguna tidak boleh bisa menghadiahkan wewenang yang dirinya sendiri tidak memilikinya, dan izin di UI hanyalah kosmetik sampai diverifikasi ulang di lapisan server.
Solusi & Cara Kerja
Sistem memisahkan definisi fitur di `common/constants/rbac.constant.ts` dan menyinkronkannya ke tabel `features` serta `role_permissions` melalui CLI `npm run db:sync`. Saat request masuk, fungsi `getPermissionMap` yang dibungkus React `cache()` memuat matriks izin satu kali per siklus request. Penegakan dilakukan di tiga titik: `requirePageAccess` untuk memblokir navigasi halaman secara SSR, `requirePermission` pada baris pertama setiap Server Action dan API Route, serta `PermissionContext` (`can()`) untuk menyembunyikan elemen tombol di sisi klien. Di lapisan mutasi matriks, transaksi Prisma memvalidasi bahwa non-Super Admin tidak dapat mengubah peran Super Admin, tidak dapat memodifikasi perannya sendiri, dan tidak dapat memberikan aksi di luar hak akses miliknya.
Berikut adalah implementasi proteksi anti-eskalasi hak akses di `modules/dashboard/role-permission/role-permission.service.ts` dan gate otorisasi di `common/lib/auth.ts`:
Detail & Hal yang Diperhatikan
- Eliminasi N+1 Query Izin: Fungsi `getPermissionMap(roleUuid)` dibungkus dengan `React.cache()`, sehingga pemanggilan berulang di layout, halaman, dan komponen server hanya mengeksekusi 1 query database per request.
- Sinkronisasi Fitur Baru Otomatis: Skrip `scripts/sync-features.ts` memastikan setiap fitur baru yang ditambahkan developer langsung terdaftar di database dan otomatis memberikan izin penuh ke Super Admin tanpa menyentuh izin role eksisting.
- Proteksi Role Bawaan Sistem: Role `Super Admin` dan `User` dikunci melalui konstanta `PROTECTED_ROLE_NAMES` agar tidak dapat dihapus atau diganti namanya secara tidak sengaja.