const axios = require('axios'); const jwt = require('jsonwebtoken'); const { KEYCLOAK_TOKEN_URL, CLIENT_ID, CLIENT_SECRET, JWT_SECRET, } = require('../../../config/keycloak.js'); const HttpException = require('../../utils/HttpException.js'); const prisma = require('../../prisma/PrismaClient.js'); const { loginLog, logoutLog } = require('../../utils/LogActivity.js'); exports.loginService = async ({ username, password }, req) => { const params = new URLSearchParams(); params.append('grant_type', 'password'); params.append('client_id', CLIENT_ID); params.append('client_secret', CLIENT_SECRET); params.append('username', username); params.append('password', password); try { const { data } = await axios.post(KEYCLOAK_TOKEN_URL, params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); const decoded = jwt.decode(data.access_token); const user = { id: decoded.sub, username: decoded.preferred_username, email: decoded.email, firstname: decoded.given_name, lastname: decoded.family_name, roles: decoded.realm_access?.roles || [] }; await loginLog(req, user); user.token = jwt.sign(user, JWT_SECRET, { expiresIn: '1d' }); return user; } catch (error) { throw new HttpException('Invalid username or password', 401); } }; exports.getUserService = async (req) => { const user = req.user; if (!user) { throw new HttpException('Invalid or missing token', 401); } const { id, username, email, firstname, lastname, roles } = user; return { id, username, email, firstname, lastname, roles }; }; // exports.registerService = async (req) => { // const { username, email, firstname, lastname, password, phonenumber, alamathehe } = validateRegisterRequest(req.body); // // Ambil admin token via client_credentials // const tokenParams = qs.stringify({ // grant_type: 'client_credentials', // client_id: CLIENT_ID, // client_secret: CLIENT_SECRET // }); // let adminToken; // try { // const tokenResponse = await axios.post( // KEYCLOAK_TOKEN_URL, // tokenParams, // { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } // ); // adminToken = tokenResponse.data.access_token; // } catch (err) { // console.error('Token Error:', err.response?.data || err.message); // throw new HttpException('Failed to get admin token', 400); // } // // Panggil endpoint pendaftaran user // try { // const response = await axios.post( // `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`, // { // username, // email, // enabled: true, // firstName: firstname, // lastName: lastname, // credentials: [ // { // type: 'password', // value: password, // temporary: false // } // ], // attributes: [ // { // phoneNumber: phonenumber, // }, // { // alamatHehe: alamathehe // } // ] // }, // { // headers: { // Authorization: `Bearer ${adminToken}`, // 'Content-Type': 'application/json' // } // } // ); // if (response.status !== 201) { // throw new HttpException('Failed to register user in Keycloak', 400); // } // } catch (err) { // // console.error('Register Error:', err.response?.data || err.message); // // throw new HttpException('Keycloak registration error: ' + (err.response?.data?.errorMessage || err.message), 400); // throw new HttpException((err.response?.data?.errorMessage || err.message), 400); // } // }; exports.logoutService = async (req) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { throw new HttpException('No JWT token provided', 401); } const token = authHeader.split(' ')[1]; let decoded; try { decoded = jwt.verify(token, JWT_SECRET); } catch (error) { throw new HttpException('Invalid JWT token', 400); } // Simpan ke tabel revoked_tokens await prisma.revokedToken.create({ data: { token, }, }); await logoutLog(req, decoded) };