123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- const axios = require('axios');
- const qs = require('qs');
- const {
- KEYCLOAK_REALM,
- KEYCLOAK_ADMIN_URL,
- CLIENT_ID,
- CLIENT_SECRET
- } = require('../../../config/keycloak.js');
- const HttpException = require('../../utils/HttpException.js');
- const bcrypt = require('bcrypt');
- const prisma = require('../../prisma/PrismaClient.js');
- const getAdminToken = async () => {
- const tokenParams = qs.stringify({
- grant_type: 'client_credentials',
- client_id: CLIENT_ID,
- client_secret: CLIENT_SECRET
- });
- const { data } = await axios.post(
- `${KEYCLOAK_ADMIN_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`,
- tokenParams,
- {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- }
- }
- );
- return data.access_token;
- };
- const KeycloakRepository = {
- createUser: async (userData) => {
- const token = await getAdminToken();
- // Cek apakah username sudah terpakai
- const { data: usersByUsername } = await axios.get(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?username=${encodeURIComponent(userData.username)}`,
- { headers: { Authorization: `Bearer ${token}` } }
- );
- if (usersByUsername.length > 0) {
- throw new HttpException('Username already exists in Keycloak', 409);
- }
- // Cek apakah email sudah terpakai
- const { data: usersByEmail } = await axios.get(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?email=${encodeURIComponent(userData.email)}`,
- { headers: { Authorization: `Bearer ${token}` } }
- );
- if (usersByEmail.length > 0) {
- throw new HttpException('Email already exists in Keycloak', 409);
- }
- const response = await axios.post(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`,
- {
- username: userData.username,
- email: userData.email,
- firstName: userData.firstname,
- lastName: userData.lastname,
- enabled: true,
- credentials: [{
- type: "password",
- value: userData.password,
- temporary: false
- }]
- },
- { headers: { Authorization: `Bearer ${token}` } }
- );
- return response.headers.location.split('/').pop();
- },
- assignAdminRole: async (userId) => {
- const token = await getAdminToken();
- // Get role sales
- const { data: roles } = await axios.get(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/roles`,
- { headers: { Authorization: `Bearer ${token}` } }
- );
- const adminRole = roles.find(role => role.name === 'admin');
- if (!adminRole) throw new HttpException('Admin role not found in Keycloak', 500);
- // Assign role to user
- await axios.post(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}/role-mappings/realm`,
- [adminRole],
- { headers: { Authorization: `Bearer ${token}` } }
- );
- },
- updateUser: async (userId, updatedData) => {
- const token = await getAdminToken();
- await axios.put(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
- {
- firstName: updatedData.firstname,
- lastName: updatedData.lastname,
- email: updatedData.email,
- credentials: updatedData.password ? [{
- type: 'password',
- value: updatedData.password,
- temporary: false
- }] : undefined
- },
- { headers: { Authorization: `Bearer ${token}` } }
- );
- },
- deleteUser: async (userId) => {
- const token = await getAdminToken();
- await axios.delete(
- `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
- { headers: { Authorization: `Bearer ${token}` } }
- );
- }
- };
- const AdminRepository = {
- createUser: async (userId, userData) => {
- const hashedPassword = await bcrypt.hash(userData.password, 10);
- return prisma.user.create({
- data: {
- id: userId,
- username: userData.username,
- email: userData.email,
- firstname: userData.firstname,
- lastname: userData.lastname,
- password: hashedPassword,
- role: 'admin'
- }
- });
- },
- findAll: async ({ skip, take, where, orderBy }) => {
- return prisma.user.findMany({
- where: {
- ...where,
- role: 'admin'
- },
- skip,
- take,
- orderBy,
- select: {
- id: true,
- username: true,
- email: true,
- firstname: true,
- lastname: true,
- role: true,
- createdAt: true,
- updatedAt: true,
- },
- });
- },
- countAll: async (where) => {
- return prisma.user.count({
- where: {
- ...where,
- role: 'admin'
- }
- });
- },
- findById: async (id) => {
- return prisma.user.findFirst({
- where: {
- id,
- deletedAt: null
- },
- select: {
- id: true,
- username: true,
- email: true,
- firstname: true,
- lastname: true,
- createdAt: true,
- updatedAt: true,
- }
- });
- },
- updateUser: async (id, updatedData) => {
- const updatePayload = {
- email: updatedData.email,
- firstname: updatedData.firstname,
- lastname: updatedData.lastname
- };
- if (updatedData.password) {
- updatePayload.password = await bcrypt.hash(updatedData.password, 10);
- }
- return prisma.user.update({
- where: { id },
- data: updatePayload
- });
- },
- deleteUser: async (id) => {
- return prisma.user.update({
- where: { id },
- data: {
- deletedAt: new Date()
- }
- });
- }
- };
- module.exports = { KeycloakRepository, AdminRepository };
|