"use strict"; const _ = require("lodash"); const moment = require("moment"); const httpStatus = require("http-status"); const controllerHelper = require("../../helpers/controller.helper"); const crypto = require("crypto"); const securityHelper = require("../../helpers/security.helper"); const authService = require("./auth.service"); const userService = require("./user.service"); const marketing = require("../../helpers/hubspot.helper"); const marketingService = require("../events/marketing_list.service"); const eventInscriptionService = require("../events/events_inscriptions.service"); const { RequestContactImportNewList } = require("sib-api-v3-sdk"); moment.locale("es"); //////////////////////////////////////////////////////////////////////////////// // CONSTANTS //////////////////////////////////////////////////////////////////////////////// // Module Name const MODULE_NAME = "[auth.controller]"; //////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////// async function login(req, res, next) { try { const data = { id: req.user.id, email: req.user.email, phone: req.user.phoneNumber, fbuid: req.user.uid, }; const tokens = securityHelper.generateToken(data); const response = { token: tokens.token, refreshToken: tokens.refreshToken, user: req.user, }; return controllerHelper.handleResultResponse(response, null, req.params, res, httpStatus.OK); } catch (error) { return controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res); } } async function loginWithPhone(req, res, next) { try { const appVersion = req && req.headers && req.headers["accept-version"] ? req.headers["accept-version"] : null; console.log("loginWithPhone - appVersion: ", appVersion); console.log(req.user); const findOptions = { phone: req.user.phoneNumber, fbuid: req.user.uid, }; //Comprobamos si el usuario ya existe en nuestro sistema let _user = await authService.extraMethods.findUserByPhone(req.user.phoneNumber); if (_user) { _user = _user.toJSON(); if (appVersion) { if (_user.app_version != appVersion) { userService._updateLastLoginAndVersionUser(_user.id, appVersion); _user.app_version = appVersion; } } const tokenData = { id: _user.id, email: _user.email, phone: _user.phone, fbuid: _user.fbuid, }; const tokens = securityHelper.generateToken(tokenData); _user.token = tokens.token; //Recuperamos el número de tickets para los proximos eventos try { const result = await eventInscriptionService._getInscriptionsOfNextEventsUser(_user.id); console.log("Entradas del usuario", result); _user.nextTicketsCount = result; } catch (error) { console.error(error); return controllerHelper.handleErrorResponse(MODULE_NAME, "getInscriptionsOfNextEventsCount", error, res); } return controllerHelper.handleResultResponse(_user, null, req.params, res, httpStatus.OK); } else { return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.NOT_FOUND); } } catch (error) { console.error(error); return controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res); } } async function register(req, res, next) { function cleanAdminData(user) { let cUser = user; delete cUser.lastLogin; delete cUser.state; delete cUser.createdAt; delete cUser.updatedAt; return cUser; } const values = { phone: req.body.phone, fbuid: req.body.fbuid, }; const appVersion = req && req.headers && req.headers["accept-version"] ? req.headers["accept-version"] : null; console.log("register - appVersion: ", appVersion); //Comprobamos si el usuario ya existe en nuestro sistema console.log("COMPROBAMOS SI EXISTE EN NUESTRO SISTEMA", values.phone); let newUser = await authService.extraMethods.findUserByPhone(values.phone); const data = { //refresh_token: tokens.refreshToken, phone: req.body.phone, fbuid: req.body.fbuid, email: req.body.email, name: req.body.name, surname: req.body.surname, entityId: req.body.entityid, accessibility: req.body.accessibility, profile: req.body.profile, country: req.body.country ? req.body.country : "ES", app_version: appVersion, lastlogin: moment().utc(), }; if (!newUser) { console.log("NO EXISTE"); try { newUser = await authService.extraMethods.createUser(data); console.log("CREAMOS EL USUARIO EN NUESTRO SISTEMA", newUser); } catch (error) { console.error(error); return controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res); } } else { console.log("EXISTE"); try { const oldUserData = newUser; newUser = await authService.extraMethods.updateUser(newUser.id, data); try { const userDTO = marketingService.userToMarketingDTO(newUser); if (await marketing.getMemberByEmail(newUser.email)) { marketing.updateMemberByEmail(oldUserData.email, userDTO); } else { // No mandar a Sendinblue hasta que no se inscriba en un congreso. } } catch (err) { console.error(err); } console.log("MODIFICAMOS EL USUARIO EN NUESTRO SISTEMA", newUser); } catch (error) { console.error(error); return controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res); } } if (newUser) { newUser = newUser.toJSON(); newUser = cleanAdminData(newUser); if (appVersion) { if (newUser.app_version != appVersion) { const result = await userService._updateLastLoginAndVersionUser(newUser.id, appVersion); newUser.app_version = appVersion; } } const tokenData = { phone: values.phone, fbuid: values.fbuid, id: newUser.id, email: newUser.email, }; const tokens = securityHelper.generateToken(tokenData); newUser.token = tokens.token; console.log("COMO YA EXISTE CREAMOS EL TOKEN Y LO ASIGNAMOS", newUser); } return controllerHelper.handleResultResponse(newUser, null, req.params, res, httpStatus.OK); } async function regenerateToken(req, res, next) { const refreshToken = req.body.token; const phone = req.body.phone; const email = req.body.email; const user = await authService.extraMethods.findUserByRefreshToken(refreshToken); console.debug(user, req.body); if (user && user.phone === phone && user.email === email) { const tokenData = { phone: user.phone, fbuid: user.fbuid, id: user.id, email: user.email, }; try { const tokens = securityHelper.generateToken(tokenData); await authService.extraMethods.updateUserRefreshToken(user.id, tokens.refreshToken); const result = { token: tokens.token }; return controllerHelper.handleResultResponse(result, null, req.params, res, httpStatus.OK); } catch (error) { return controllerHelper.handleErrorResponse(MODULE_NAME, regenerateToken.name, error, res); } } else { return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.UNAUTHORIZED); } } async function rejectToken(req, res, next) { const refreshToken = req.body.refreshToken; const user = await authService.extraMethods.findUserByRefreshToken(refreshToken); if (user && user.token === refreshToken) { try { await authService.extraMethods.deleteRefreshToken(refreshToken); return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.OK); } catch (error) { return controllerHelper.handleErrorResponse(MODULE_NAME, rejectToken.name, error, res); } } else { return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.NOT_FOUND); } } // Registro por email y por password async function singup(req, res, next) { var newUser = undefined; try { const data = { email: req.body.email, name: req.body.name, surname: req.body.surname, level: 8, password: crypto.createHash("sha512").update(req.body.password).digest("hex"), }; newUser = await authService.extraMethods.createUser(data); } catch (error) { console.error(error); return controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res); } if (newUser) { newUser = newUser.toJSON(); const tokenData = { phone: undefined, fbuid: undefined, id: newUser.id, email: newUser.email, }; const tokens = securityHelper.generateToken(tokenData); newUser.token = tokens.token; } return controllerHelper.handleResultResponse(newUser, null, req.params, res, httpStatus.OK); } function adminVerify(req, res, next) { return controllerHelper.handleResultResponse("OK", null, req.params, res, httpStatus.OK); } function verify(req, res, next) { const params = controllerHelper.extractParamsFromRequest(req, res, {}); const phone = params.query.phone; const email = params.query.email; const fbuid = params.query.fbuid; const user = req.user; if (user && user.phone === phone && user.email === email && user.fbuid === fbuid) { return controllerHelper.handleResultResponse(user, null, req.params, res, httpStatus.OK); } else { return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.UNAUTHORIZED); } } async function getOrCreateUser(req, res, next) { const params = controllerHelper.extractParamsFromRequest(req, res, {}); let dataInscription = res.locals.dataInscription; console.log('getOrCreateUser>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', dataInscription); if (!dataInscription) return controllerHelper.handleResultResponse( "Error getOrCreateUser, prepareDataInscription, recuperateReservationByCode requerida", null, params, res, httpStatus.NOT_FOUND ); //Iniciamos el usuario relacionadas con la inscripción. let dataUser; dataUser = { id: req.user ? req.user.id : null, phone: req.user ? req.user.phone : null, //((req.body.phone != '+34') ? req.body.phone : null), lo quitamos de momento por la de movistar name: req.user ? req.user.name : req.body.name, surname: req.user ? req.user.surname : req.body.surname, email: req.user ? req.user.email : req.body.email, entityId: null, entityName: null, entityLevel: null, userResult: req.user ? req.user : null, }; //Asignamos a los datos del usuario a crear, el id de la entidad a la que pertenece, este caso solo es necesario cuando viene la inscripción por web ya que hay que crear un usuario nuevo if (dataInscription.reservation) { dataUser.entityId = dataInscription.reservation.entityId; } //creamos o recuperamos el usuario teniendo en cuenta que pude venir por APP o WEB //si viene por web se tendra en cuenta el email y si viene por APP el phone para buscar try { if (req.user) { //MAPEO SALIDA API4 //Caso API V4 user {} if (_.isEmpty(req.user)){ dataUser = {}; dataUser.userResult = await userService._getOrCreateUserWEBV4(dataUser, req); } //Si viene user relleno viene por APP else dataUser.userResult = await userService._getOrCreateUser(dataUser); } //Caso Formulario web página actual //CHAPUZA SE PERMITE DAR DE ALTA USUARIOS CON EL MISMO CORREO ELECTRONICO, PERO DISTINTO NOMBRE Y APELLIDO. else dataUser.userResult = await userService._getOrCreateUserWEB(dataUser); console.log('CHAPUZAAAAAAAAAA2>>>', dataUser.userResult); if (!dataUser.userResult) { // No se ha encontrado return controllerHelper.handleResultResponse( "No se ha podido crear o encontrar el usuario dado", null, params, res, httpStatus.NOT_FOUND ); } } catch (error) { console.log("error>>>>",error); return controllerHelper.handleErrorResponse(MODULE_NAME, "getOrCreateUser", error, res); } //console.log(">>>>>>>>>>>>>>>>>>>> getOrCreateUser", dataUser.userResult.user.Entity); //Refrescamos datos que nos interesan dataUser.id = dataUser.userResult.user.id; //caso API V4 no recuperamos Entidad, asignamos entityId del parametro dado dataUser.entityId = dataUser.userResult.user.Entity ? dataUser.userResult.user.Entity.id : (dataUser.userResult.user.entityId? dataUser.userResult.user.entityId : null); dataUser.entityName = dataUser.userResult.user.Entity ? dataUser.userResult.user.Entity.name : "DEFAULT"; dataUser.entityLevel = dataUser.userResult.user.Entity ? dataUser.userResult.user.Entity.level : null; dataUser.email = dataUser.userResult.user ? dataUser.userResult.user.email : null; dataUser.phone = dataUser.userResult.user ? dataUser.userResult.user.phone : null; //((req.body.phone != '+34') ? req.body.phone : null), lo quitamos de momento por la de movistar dataUser.name = dataUser.userResult.user ? dataUser.userResult.user.name : null; dataUser.surname = dataUser.userResult.user ? dataUser.userResult.user.surname : null; //Reasignamos a variable de entorno res.locals.dataUser = dataUser; next(); } async function deleteUser(req, res, next) { const params = controllerHelper.extractParamsFromRequest(req, res, {}); let dataUser = { id: req.body ? req.body.id : null, phone: req.body ? req.body.phone : null, //((req.body.phone != '+34') ? req.body.phone : null), lo quitamos de momento por la de movistar email: req.body ? req.body.email : null, }; const resultCount = await authService.extraMethods.deleteUser(dataUser.id, dataUser.email, dataUser.phone); if (resultCount < 1) { // No se ha encontrado return controllerHelper.handleResultResponse( "No se ha podido encontrar el usuario", null, params, res, httpStatus.NOT_FOUND ); } // Delete in Sendinblue try { const userDTO = marketingService.userToMarketingDTO(dataUser); marketing.deleteMemberByEmail(userDTO.email); } catch (error) { console.log(error); //return controllerHelper.handleErrorResponse(MODULE_NAME, "deleteUser", error, res); } return controllerHelper.handleResultResponse(resultCount, resultCount, params, res, httpStatus.OK); } module.exports = { login, loginWithPhone, register, regenerateToken, rejectToken, singup, adminVerify, verify, getOrCreateUser, deleteUser, MODULE_NAME, };