AuthService.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. const axios = require('axios');
  2. const jwt = require('jsonwebtoken');
  3. const {
  4. KEYCLOAK_TOKEN_URL,
  5. CLIENT_ID,
  6. CLIENT_SECRET,
  7. JWT_SECRET,
  8. } = require('../../../config/keycloak.js');
  9. const HttpException = require('../../utils/HttpException.js');
  10. const prisma = require('../../prisma/PrismaClient.js');
  11. const { loginLog, logoutLog } = require('../../utils/LogActivity.js');
  12. exports.loginService = async ({ username, password }, req) => {
  13. const params = new URLSearchParams();
  14. params.append('grant_type', 'password');
  15. params.append('client_id', CLIENT_ID);
  16. params.append('client_secret', CLIENT_SECRET);
  17. params.append('username', username);
  18. params.append('password', password);
  19. try {
  20. const { data } = await axios.post(KEYCLOAK_TOKEN_URL, params, {
  21. headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
  22. });
  23. const decoded = jwt.decode(data.access_token);
  24. const user = {
  25. id: decoded.sub,
  26. username: decoded.preferred_username,
  27. email: decoded.email,
  28. firstname: decoded.given_name,
  29. lastname: decoded.family_name,
  30. roles: decoded.realm_access?.roles || []
  31. };
  32. await loginLog(req, user);
  33. user.token = jwt.sign(user, JWT_SECRET, { expiresIn: '1d' });
  34. return user;
  35. } catch (error) {
  36. throw new HttpException('Invalid username or password', 401);
  37. }
  38. };
  39. exports.getUserService = async (req) => {
  40. const user = req.user;
  41. if (!user) {
  42. throw new HttpException('Invalid or missing token', 401);
  43. }
  44. const { id, username, email, firstname, lastname, roles } = user;
  45. return { id, username, email, firstname, lastname, roles };
  46. };
  47. // exports.registerService = async (req) => {
  48. // const { username, email, firstname, lastname, password, phonenumber, alamathehe } = validateRegisterRequest(req.body);
  49. // // Ambil admin token via client_credentials
  50. // const tokenParams = qs.stringify({
  51. // grant_type: 'client_credentials',
  52. // client_id: CLIENT_ID,
  53. // client_secret: CLIENT_SECRET
  54. // });
  55. // let adminToken;
  56. // try {
  57. // const tokenResponse = await axios.post(
  58. // KEYCLOAK_TOKEN_URL,
  59. // tokenParams,
  60. // { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
  61. // );
  62. // adminToken = tokenResponse.data.access_token;
  63. // } catch (err) {
  64. // console.error('Token Error:', err.response?.data || err.message);
  65. // throw new HttpException('Failed to get admin token', 400);
  66. // }
  67. // // Panggil endpoint pendaftaran user
  68. // try {
  69. // const response = await axios.post(
  70. // `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`,
  71. // {
  72. // username,
  73. // email,
  74. // enabled: true,
  75. // firstName: firstname,
  76. // lastName: lastname,
  77. // credentials: [
  78. // {
  79. // type: 'password',
  80. // value: password,
  81. // temporary: false
  82. // }
  83. // ],
  84. // attributes: [
  85. // {
  86. // phoneNumber: phonenumber,
  87. // },
  88. // {
  89. // alamatHehe: alamathehe
  90. // }
  91. // ]
  92. // },
  93. // {
  94. // headers: {
  95. // Authorization: `Bearer ${adminToken}`,
  96. // 'Content-Type': 'application/json'
  97. // }
  98. // }
  99. // );
  100. // if (response.status !== 201) {
  101. // throw new HttpException('Failed to register user in Keycloak', 400);
  102. // }
  103. // } catch (err) {
  104. // // console.error('Register Error:', err.response?.data || err.message);
  105. // // throw new HttpException('Keycloak registration error: ' + (err.response?.data?.errorMessage || err.message), 400);
  106. // throw new HttpException((err.response?.data?.errorMessage || err.message), 400);
  107. // }
  108. // };
  109. exports.logoutService = async (req) => {
  110. const authHeader = req.headers.authorization;
  111. if (!authHeader || !authHeader.startsWith('Bearer ')) {
  112. throw new HttpException('No JWT token provided', 401);
  113. }
  114. const token = authHeader.split(' ')[1];
  115. let decoded;
  116. try {
  117. decoded = jwt.verify(token, JWT_SECRET);
  118. } catch (error) {
  119. throw new HttpException('Invalid JWT token', 400);
  120. }
  121. // Simpan ke tabel revoked_tokens
  122. await prisma.revokedToken.create({
  123. data: {
  124. token,
  125. },
  126. });
  127. await logoutLog(req, decoded)
  128. };