userlogin.service.js

PHOTO EMBED

Tue Feb 27 2024 04:43:34 GMT+0000 (Coordinated Universal Time)

Saved by @minhgiau998

import config from 'config';
import fetch from 'node-fetch';
// import jwt from 'jsonwebtoken';
import moment from 'moment';
import bcrypt from 'bcrypt';
import ejwt from '../../../helper/encrypted-jwt';
import logger from '../../../helper/logger';
import db from '../../../server/database';
import * as util from '../../../helper/util';
import { modifyStatus } from '../../model/user/userinfo.model';
import * as UserLogin from '../../model/user/userlogin.model';
import * as userInfoService from '../../service/user/userinfo.service';
import * as codeInfoService from '../../service/code/codeinfo.service';
import * as userGroupService from '../../service/user/usergroup.service';
import * as companyService from '../../service/user/company.service';
import CustomError from '../../../helper/error';
import sendMail from './email.service';

const cacheOptions = {
  name: 'logininfo',
  time: 3600,
  force: false,
};

/**
 * get getRefreshJWT
 *
 * @param   {String} id
 * @param   {Boolean} rememberme
 * @returns {String}
 */
export const getRefreshJWT = (row, expirationTime) => {
  // cookie : milliseconds, jwt : seconds
  const defaultTime = parseInt(config.get('jwt.expiration'), 10) * 1000;
  const expirationTime1 = parseInt((expirationTime || defaultTime) / 1000, 10);
  // "Bearer "+
  const token = ejwt.sign(
    config.get('jwt.secretkey'),
    {
      userId: row.userId,
      email: row.email,
      srcloc: row.srcloc,
      userType: row.userType,
      rememberMe: row.rememberMe || false,
    },
    config.get('jwt.encryption'),
    { expiresIn: expirationTime1 },
  );
  // console.log('token', token);
  return token;
};

/**
 * set RefreshToken
 *
 * @param   {object} userInfo
 * @param   {object} req
 * @param   {object} res
 * @returns {String}
 */
const setRefreshToken = async (userInfo, req, res) => {
  // check remember me
  const rememberMe = userInfo.rememberMe || false;

  // calculate expire time
  let expirationTimeRefreshToken = parseInt(config.get('jwt.expiration1'), 10) * 1000;

  let expiresRefreshToken = new Date();
  expiresRefreshToken = new Date(Date.now() + expirationTimeRefreshToken);
  // set up for expire
  if (rememberMe) {
    expirationTimeRefreshToken = parseInt(config.get('jwt.expiration2'), 10) * 1000;
    expiresRefreshToken = new Date(Date.now() + expirationTimeRefreshToken);
  }
  // console.log('expiresRefreshToken', expiresRefreshToken);

  // get token
  const refreshToken = getRefreshJWT(userInfo, expirationTimeRefreshToken);

  const params = [];
  // update user login info
  params[0] = util.replaceUndefined(refreshToken);
  params[1] = util.replaceUndefined(expiresRefreshToken.toGMTString());
  params[2] = util.replaceUndefined(userInfo.userId);
  params[3] = util.replaceUndefined(userInfo.srcloc);
  await db.execute(UserLogin.refresh(), params, cacheOptions);

  // console.log('refreshToken', refreshToken);
  util.addCookie(req, res, 'auth.remember-me', refreshToken, '', expirationTimeRefreshToken);
  return { refreshToken, expires: expiresRefreshToken };
};

/**
 * login user
 *
 * @param   {Object} userInfo
 * @param   {Object} req
 * @param   {Object} res
 * @returns {Object}
 */
export const loginUser = async (userInfo, req, res) => {
  logger.debug(`userlogin.loginUser : ${userInfo.email}`);
  // createLog(req, ['loginUser', userInfo.srcloc, '', '', userInfo.userId]);

  const params = [];
  params[0] = util.replaceUndefined(userInfo.email);
  params[1] = util.replaceUndefined(userInfo.srcloc);

  const rowUser = await db.findOne(UserLogin.loginUser(), params, cacheOptions);
  if (util.isEmpty(rowUser)) {
    logger.error(`loginUser not found : ${userInfo.email}`);
    if (userInfo.srcloc === 'A') {
      throw new CustomError('not-found', 24);
    } else {
      throw new CustomError('login-error', 10924);
    }
    // throw new CustomError('not-found', userInfo.srcloc === 'A' ? 24 : 10910);
  }
  // is locked user ?
  if (parseInt(rowUser.userStatus, 10) === 17003) {
    logger.error(`loginUser locked : ${userInfo.email}, ${rowUser.userStatus}`);
    const rowFail = await db.findOne(UserLogin.getFailed(), [rowUser.userId], cacheOptions);
    if (!util.isEmpty(rowFail)) {
      const tdiff = parseInt(rowFail.tdiff, 10);
      if (tdiff === 0) {
        // vulerabliity No.9 rollback
        // if (userInfo.srcloc === 'A') {
        //   throw new CustomError('locked-account', 11);
        // } else {
        //   throw new CustomError('login-error', 10924);
        // }
        throw new CustomError('locked-account', userInfo.srcloc === 'A' ? 11 : 10921);
      } else {
        await util.to(db.execute(modifyStatus(), [17001, rowUser.userId], cacheOptions));
        rowUser.userStatus = 17001;
      }
    }
  }
  // compare password
  const pass = bcrypt.compareSync(userInfo.pwd, rowUser.pwd);
  // invalid password
  if (!pass) {
    // check previous failed history
    const rowFail = await db.findOne(UserLogin.getFailed(), [rowUser.userId], cacheOptions);
    if (util.isEmpty(rowFail)) {
      await db.execute(UserLogin.createFailed(), [rowUser.userId], cacheOptions);
    } else {
      const failCount = parseInt(rowFail.failed_count, 10);

      logger.error(`loginUser invalid password : ${userInfo.email}, ${failCount}`);
      // too many failed user
      if (failCount >= 5) {
        const [, vResult] = await util.to(db.execute(modifyStatus(), [17003, rowUser.userId], cacheOptions));
        if (vResult.affectedRows === 1 || vResult.changedRows === 1) {
          let locale = rowUser.basicLanguage || 'en';
          if ('en,ja,zh,it'.indexOf(locale) < 0) {
            locale = 'en';
          }
          // send email
          const templateId = 14;
          const row = {};
          row.userId = rowUser.userId;
          row.receiver_email = rowUser.email;
          row.receiver_name = rowUser.nickname;
          row.basicLanguage = locale;
          row.locale = locale;
          const [, returnValue] = await util.to(sendMail(req, row, templateId));
          if (returnValue.code !== 0) {
            logger.error(`modify ${rowUser.email} : failed to send email`);
            vResult.info = 'locked but failed to send email';
          }
        }
         //set field count = 0
         await db.execute(UserLogin.updateFailCount(),[rowUser.userId], cacheOptions);
        if (userInfo.srcloc === 'A') {
          throw new CustomError('not-found', 24);
        } else {
          throw new CustomError('locked-account', 10921);
        }
        // throw new CustomError('invalid-password', userInfo.srcloc === 'A' ? 13 : 10924);

      } else {
        await db.execute(UserLogin.updateFailed(), [rowUser.userId], cacheOptions);
      }
    }
    if (userInfo.srcloc === 'A') {
      throw new CustomError('not-found', 24);
    } else {
      throw new CustomError('login-error', 10924);
    }
    // throw new CustomError('invalid-password', userInfo.srcloc === 'A' ? 13 : 10924);
  }
  // is not active ?
  if (parseInt(rowUser.userStatus, 10) !== 17001) {
    logger.error(`loginUser not active : ${userInfo.email}, ${rowUser.userStatus}`);
    if (userInfo.srcloc === 'A') {
      throw new CustomError('not-found', 24);
    } else {
      throw new CustomError('login-error', 10924);
    }
    // throw new CustomError('not-active', userInfo.srcloc === 'A' ? 12 : 10916);
  }

  // is not plan ?
  // if (rowUser.srcloc === 'A' && (rowUser.validPlan === 'N' || parseInt(rowUser.planId, 10) > 30001)) {
  // After the Expire Date, I will not be able to log in from APEX.
  if (config.get('serverConfig.mode') !== 'staging') {
    if (rowUser.srcloc === 'A' && parseInt(rowUser.planId, 10) > 30001) {
      logger.error(`loginUser not plan : ${userInfo.email}, ${rowUser.planId}, ${rowUser.validPlan}`);
      if (userInfo.srcloc === 'A') {
        throw new CustomError('not-found', 24);
      } else {
        throw new CustomError('login-error', 10924);
      }
      // throw new CustomError('invalid-plan', userInfo.srcloc === 'A' ? 14 : 10927);
    }
  }
  req.session.save();
  const isForce = userInfo.force || false;
  // if (config.get('serverConfig.mode') === 'production') {
  // compare cookie expire date
  // user may be not logout or do not access during long time.
  // if expires date is later than current, user is already login except user is super admin.
  const sessUser = await db.findOne(UserLogin.selectSession(), [userInfo.userId, userInfo.srcloc, rowUser.userType], cacheOptions);
  if (!util.isEmpty(sessUser)) {
    // console.log('moment().unix()', moment().unix(), sessUser.expires);
    // console.log('moment().unix()', sessUser.session_id, req.sessionID);
    if (sessUser.session_id !== req.sessionID) {
    //   throw new CustomError('multiple-logins (same session)', 10);
    // }
      if (moment().unix() < sessUser.expires) {
        // user is not super admin and user's token is not empty
        if ((sessUser.session_id !== req.sessionID)) { // parseInt(rowUser.userType, 10) !== 15000 &&
          logger.info(`loginUser already : ${userInfo.email}`);
          if (isForce) {
            await db.execute(UserLogin.deleteSessionByUserId(), [userInfo.userId, userInfo.srcloc, rowUser.userType], cacheOptions);
            req.session.save();
          } else {
            res.status(500).send({
              status: false,
              name: 'login',
              code: userInfo.srcloc === 'A' ? 10 : 10410,
              message: 'multiple-logins',
              // stack: err.stack,
            });
            return;
            // throw new CustomError('multiple-logins', userInfo.srcloc === 'A' ? 10 : 10410);
          }
        }
      }
    }
  }
  // }

  // clear failed history
  await db.execute(UserLogin.deleteFailed(), [rowUser.userId], cacheOptions);

  const params2 = [];
  // update user login info
  params2[0] = util.replaceUndefined(rowUser.userId);
  params2[1] = util.replaceUndefined(rowUser.srcloc);
  await db.execute(UserLogin.login(), params2, cacheOptions);

  // get latest user login info
  const returnUser = await db.findOne(UserLogin.loginUser(), [rowUser.userId, rowUser.srcloc], cacheOptions);
  returnUser.pwd = undefined;
  if (config.get('serverConfig.mode') !== 'test') {
    returnUser.accessToken = undefined;
    returnUser.expires = undefined;
    returnUser.refreshToken = undefined;
  }

  returnUser.rememberMe = userInfo.rememberMe || false;
  req.session.isAdmin = userInfo.isAdmin || 'N';
  req.session.user = returnUser;
  // set remember-me to cookie
  const [, refresh] = await util.to(setRefreshToken(returnUser, req, res));

  if (config.get('serverConfig.mode') === 'test') {
    returnUser.refreshToken = refresh.refreshToken;
  }
  // update email of user_session
  req.session.save();
  await db.execute(UserLogin.modifySession(), [rowUser.userId, rowUser.srcloc, rowUser.userType, req.sessionID], cacheOptions);

  if (rowUser.srcloc === 'A') {
    returnUser.userType = parseInt((parseInt(returnUser.userType, 10) - 15000) / 10, 10);
    returnUser.userRole = parseInt(returnUser.userRole, 10) - 16000;
    returnUser.userStatus = parseInt(returnUser.userStatus, 10) - 17000;
  }
  // eslint-disable-next-line consistent-return
  return returnUser;
};

/**
* login user infor by Auth0
 *
 * @param   {Object} userInfo
 * @param   {Object} req
 * @param   {Object} res
 * @returns {Object}
 */
export const loginUserApex = async (userInfo, req, res) => {
  logger.debug(`userlogin.loginUser : ${userInfo.email}`);
  const body = new URLSearchParams();
  body.append("client_id", config.get('auth0Apex.AUTH0_CLIENT_ID'));
  body.append("client_secret", config.get('auth0Apex.AUTH0_CLIENT_SECRET'));
  body.append("audience", `${config.get('auth0Apex.AUTH0_DOMAIN')}/api/v2/`);
  body.append("grant_type", config.get('auth0Apex.GRANT_TYPE'));
  body.append("realm", config.get('auth0Apex.REALM'));
  body.append("scope", config.get('auth0Apex.SCOPE'));
  body.append("username", userInfo.email);
  body.append("password", userInfo.pwd);
  let responseAuth0 = false;
  let userInfoAuth0 = {};
  try {
    const response = await fetch(`${config.get('auth0.AUTH0_DOMAIN')}/oauth/token`, {
      method: "POST",
      body,
      headers: {
        "Cache-Control": "no-cache",
        "Content-Type": "application/x-www-form-urlencoded",
      },
    });
    responseAuth0 = response.status === 200;
    const data = await response.json();
    if (!responseAuth0) {
      throw new CustomError("not-found", 24);
    } else {
      // data user in Auth0
      const { id_token } = data;
      userInfoAuth0 = JSON.parse(
        Buffer.from(id_token.split(".")[1], "base64").toString()
      );
    }
  } catch (err) {
    throw new CustomError("not-found", 24);
  }
  let rowUser = await db.findOne(
    UserLogin.loginUserAuth0(),
    [userInfoAuth0.sub, userInfo.srcloc],
    cacheOptions
  );
  if (util.isEmpty(rowUser)) {
    logger.error(`loginUser not found : ${userInfo.email}`);
    if (userInfo.srcloc === "A") {
      throw new CustomError("not-found", 24);
    } else {
      throw new CustomError("login-error", 10924);
    }
  }
  rowUser = {
    ...rowUser,
    email: userInfoAuth0.email,
    userName: userInfoAuth0.family_name.concat(' ', userInfoAuth0.given_name),
    basicLanguage: userInfoAuth0.lang.code || 'en',
    srcloc: userInfo.srcloc,
  };
  // is not active ?
  if (parseInt(rowUser.userStatus, 10) !== 17001) {
    logger.error(
      `loginUser not active : ${userInfo.email}, ${rowUser.userStatus}`
    );
    if (userInfo.srcloc === "A") {
      throw new CustomError("not-found", 24);
    } else {
      throw new CustomError("login-error", 10924);
    }
    // throw new CustomError('not-active', userInfo.srcloc === 'A' ? 12 : 10916);
  }
  // is not plan ?
  // if (rowUser.srcloc === 'A' && (rowUser.validPlan === 'N' || parseInt(rowUser.planId, 10) > 30001)) {
  // After the Expire Date, I will not be able to log in from APEX.
  if (rowUser.srcloc === "A" && parseInt(rowUser.planId, 10) > 30001) {
    logger.error(
      `loginUser not plan : ${userInfo.email}, ${rowUser.planId}, ${rowUser.validPlan}`
    );
    if (userInfo.srcloc === "A") {
      throw new CustomError("not-found", 24);
    } else {
      throw new CustomError("login-error", 10924);
    }
    // throw new CustomError('invalid-plan', userInfo.srcloc === 'A' ? 14 : 10927);
  }
  req.session.save();
  const isForce = userInfo.force || false;

  const sessUser = await db.findOne(
    UserLogin.selectSession(),
    [rowUser.userId, rowUser.srcloc, rowUser.userType],
    cacheOptions
  );
  if (!util.isEmpty(sessUser)) {
    if (sessUser.session_id !== req.sessionID) {
      if (moment().unix() < sessUser.expires) {
        // user is not super admin and user's token is not empty
        if (sessUser.session_id !== req.sessionID) {
          logger.info(`loginUser already : ${userInfo.email}`);
          if (isForce) {
            await db.execute(
              UserLogin.deleteSessionByUserId(),
              [rowUser.userId, userInfo.srcloc, rowUser.userType],
              cacheOptions
            );
            req.session.save();
          } else {
            res.status(500).send({
              status: false,
              name: "login",
              code: userInfo.srcloc === "A" ? 10 : 10410,
              message: "multiple-logins",
              // stack: err.stack,
            });
            return;
          }
        }
      }
    }
  }

  const params2 = [];
  // update user login info
  params2[0] = util.replaceUndefined(rowUser.userId);
  params2[1] = util.replaceUndefined(rowUser.srcloc);
  await db.execute(UserLogin.login(), params2, cacheOptions);

  if (config.get("serverConfig.mode") !== "test") {
    rowUser.accessToken = undefined;
    rowUser.expires = undefined;
    rowUser.refreshToken = undefined;
  }
  rowUser.rememberMe = userInfo.rememberMe || false;
  req.session.isAdmin = userInfo.isAdmin || "N";
  req.session.user = rowUser;
  // set remember-me to cookie
  const [, refresh] = await util.to(setRefreshToken(rowUser, req, res));
  if (config.get("serverConfig.mode") === "test") {
    rowUser.refreshToken = refresh.refreshToken;
  }
  // update email of user_session
  req.session.save();
  await db.execute(
    UserLogin.modifySession(),
    [rowUser.userId, rowUser.srcloc, rowUser.userType, req.sessionID],
    cacheOptions
  );
  if (rowUser.srcloc === "A") {
    rowUser.userType = parseInt(
      (parseInt(rowUser.userType, 10) - 15000) / 10,
      10
    );
    rowUser.userRole = parseInt(rowUser.userRole, 10) - 16000;
    rowUser.userStatus = parseInt(rowUser.userStatus, 10) - 17000;
  }
  // eslint-disable-next-line consistent-return
  return rowUser;
};

export const getUserByCodeAuth0 = async (code, req, res) => {
  const body = new URLSearchParams();
  body.append("client_id", config.get('auth0.AUTH0_CLIENT_ID'));
  body.append("client_secret", config.get('auth0.AUTH0_CLIENT_SECRET'));
  body.append("audience", config.get('auth0.AUDIENCE'));
  body.append("grant_type", config.get('auth0.GRANT_TYPE'));
  body.append("redirect_uri", `https://${req.headers.host}/api/v1/login/auth0`);
  body.append("scope", config.get('auth0.SCOPE'));
  body.append("code", code);
  let userAuth0 = {};
  try {
    const response = await fetch(`${config.get('auth0.AUTH0_DOMAIN')}/oauth/token`, {
      method: "POST",
      body,
      headers: {
        "Cache-Control": "no-cache",
        "Content-Type": "application/x-www-form-urlencoded",
      },
    });
    const responseAuth0 = response.status === 200;
    const data = await response.json();
    if (!responseAuth0) {
      throw new CustomError("not-found", 24);
    } else {
      // data user in Auth0
      const { id_token } = data;
      userAuth0 = JSON.parse(
        Buffer.from(id_token.split(".")[1], "base64").toString()
      );
    }
    return userAuth0
  } catch (err) {
    throw new CustomError("not-found", 24);
  }
};

export const loginUserAuth0 = async (userInfo, req, res) => {
  logger.debug(`userlogin.loginUserAuth0 : ${userInfo.email}`);

  const rowUser = userInfo;
  req.session.save();

  // check user exist
  let user = await db.findOne(UserLogin.checkUserExist(), [userInfo.sub], cacheOptions);
  if (util.isEmpty(user)) {
    // register Account
    const guest = {}
    guest.firstName = userInfo.family_name
    guest.lastName = userInfo.given_name
    guest.userStatus = 17001
    guest.basicLanguage = userInfo.lang.code
    if (userInfo.user_type.code === 'Shima') {
      guest.userType = 15040
      guest.userRole = 16040
    } else {
      guest.userType = 15030
      guest.userRole = 16030
    }

    guest.auth0Id = userInfo.sub
    const [err, vResult] = await util.to(userInfoService.create(guest));
    if (err) {
      throw new CustomError('Register Guest is error', 24);
    }
    const [, groupId] = await util.to(codeInfoService.getSeqId('COMPANY'));
    await util.to(userGroupService.create({
      groupId, email: null, userType: guest.userType, userRole: guest.userRole, mailId: '', userId: vResult.insertId
    }));
    if (userInfo.user_type.code === 'Shima') {
      const company = {}
      company.companyName = userInfo.company_en
      company.companyId = groupId
      const [err1] = await util.to(companyService.create(company));
      if (err1) {
        error.message = err1.message;
        logger.error(error);
        return Response.error(res, error, 500);
      }
      await util.to(companyService.createPlan(req, { companyId: groupId, planId: 30001 }));
    }
    user = await db.findOne(UserLogin.checkUserExist(), [userInfo.sub], cacheOptions);
  }

  const sessUser = await db.findOne(UserLogin.selectSession(), [user.userId, userInfo.srcloc, user.userType], cacheOptions);
  if (!util.isEmpty(sessUser)) {
    if (sessUser.session_id !== req.sessionID) {
      if (moment().unix() < sessUser.expires) {
        // user is not super admin and user's token is not empty
        if ((sessUser.session_id !== req.sessionID)) { // parseInt(rowUser.userType, 10) !== 15000 &&
          logger.info(`loginUser already : ${userInfo.email}`);
          await db.execute(UserLogin.deleteSessionByUserId(), [user.userId, userInfo.srcloc, user.userType], cacheOptions);
          req.session.save();
        }
      }
    }
  }

  let returnUser = {}
  // check company
  const company = await db.findOne(UserLogin.checkCompanyExist(), [user.userId], cacheOptions);
  if (util.isEmpty(company)) {
    returnUser = await db.findOne(UserLogin.loginUserAuth0WithoutCompany(), [userInfo.sub, userInfo.srcloc], cacheOptions);
  } else {
    returnUser = await db.findOne(UserLogin.loginUserAuth0(), [userInfo.sub, userInfo.srcloc], cacheOptions);
  }

  // modify information
  returnUser.userName = rowUser.family_name.concat(' ', rowUser.given_name)
  returnUser.basicLanguage = rowUser.lang.code || 'en'
  returnUser.email = rowUser.email
  returnUser.srcloc = userInfo.srcloc
  returnUser.address1 = rowUser.direction
  returnUser.tel = rowUser.tel

  if (returnUser.userType === 15030) {
    returnUser.countryCode = rowUser.country.code
  }

  if (config.get('serverConfig.mode') !== 'test') {
    returnUser.accessToken = undefined;
    returnUser.expires = undefined;
    returnUser.refreshToken = undefined;
  }

  returnUser.rememberMe = userInfo.rememberMe || false;
  req.session.isAdmin = userInfo.isAdmin || 'N';
  req.session.user = returnUser;

  // set remember-me to cookie
  const [, refresh] = await util.to(setRefreshToken(returnUser, req, res));

  if (config.get('serverConfig.mode') === 'test') {
    returnUser.refreshToken = refresh.refreshToken;
  }
  // update information of user_session
  req.session.save();
  await db.execute(UserLogin.modifySession(), [returnUser.userId, userInfo.srcloc, returnUser.userType, req.sessionID], cacheOptions);
  return returnUser;
};

/**
 * logout user
 *
 * @param   {Object} userInfo
 * @returns {Object}
 */
export const logoutUser = async (userInfo) => {
  logger.debug(`userlogin.logoutUser : ${userInfo.userId}`);
  // createLog(req, ['logoutUser', userInfo.srcloc, '', '', userInfo.userId]);
  await db.execute(UserLogin.deleteSessionByUserId(), [userInfo.userId, userInfo.srcloc, userInfo.userType], cacheOptions);

  const params2 = [];
  params2[0] = util.replaceUndefined(userInfo.userId);
  params2[1] = util.replaceUndefined(userInfo.srcloc);

  const rows = await db.execute(UserLogin.logout(), params2, cacheOptions);
  return rows;
};

/**
 * logout user
 *
 * @param   {Object} userInfo
 * @returns {Object}
 */
export const logoutUserDeleteMe = async (userInfo) => {
  logger.debug(`userlogin.logoutUserDeleteMe : ${userInfo.userId}`);
  // createLog(req, ['logoutUser', userInfo.srcloc, '', '', userInfo.userId]);
  await db.execute(UserLogin.deleteSessionByUserId(), [userInfo.userId, userInfo.srcloc, userInfo.userType], cacheOptions);

  const params2 = [];
  params2[0] = util.replaceUndefined(userInfo.userId);
  params2[1] = util.replaceUndefined(userInfo.srcloc);

  const rows = await db.execute(UserLogin.logoutOnly(), params2, cacheOptions);
  return rows;
};

/**
 * refresh user
 *
 * @param   {Object} userInfo
 * @returns {Object}
 */
export const refresh = async (userInfo, req, res) => {
  logger.debug(`userlogin.refresh : ${userInfo.userId}`);

  const params = [];
  params[0] = util.replaceUndefined(userInfo.userId);
  params[1] = util.replaceUndefined(userInfo.srcloc);
  const rowUser = await db.findOne(UserLogin.loginUserById(), params, cacheOptions);
  if (util.isEmpty(rowUser)) {
    logger.error(`user not found : ${userInfo.userId}`);
    throw new CustomError('not-found', 24);
  }
  await db.execute(UserLogin.deleteSessionByUserId(), [rowUser.userId, rowUser.srcloc, rowUser.userType], cacheOptions);
  req.session.save();

  // get latest user login info
  const returnUser = await db.findOne(UserLogin.loginUser(), [rowUser.userId, rowUser.srcloc], cacheOptions);
  returnUser.pwd = undefined;
  // returnUser.refreshToken = refreshToken.refreshToken;
  if (config.get('serverConfig.mode') !== 'test') {
    returnUser.accessToken = undefined;
    returnUser.expires = undefined;
    returnUser.refreshToken = undefined;
  }

  // modify information
  returnUser.userName = userInfo.family_name.concat(' ', rowUser.given_name)
  returnUser.basicLanguage = userInfo.lang.code || 'en'
  returnUser.email = userInfo.email
  returnUser.srcloc = userInfo.srcloc

  returnUser.rememberMe = userInfo.rememberMe || false;
  req.session.user = returnUser;
  await util.to(setRefreshToken(returnUser, req, res));

  req.session.save();
  await db.execute(UserLogin.modifySession(), [rowUser.userId, rowUser.srcloc, rowUser.userType, req.sessionID], cacheOptions);

  if (rowUser.srcloc === 'A') {
    returnUser.userType = parseInt((parseInt(returnUser.userType, 10) - 15000) / 10, 10);
    returnUser.userRole = parseInt(returnUser.userRole, 10) - 16000;
    returnUser.userStatus = parseInt(returnUser.userStatus, 10) - 17000;
  }

  const params2 = [];
  // update user login info
  params2[0] = util.replaceUndefined(rowUser.userId);
  params2[1] = util.replaceUndefined(rowUser.srcloc);
  await db.execute(UserLogin.login(), params2, cacheOptions);

  return returnUser;
};

/**
 * reload user
 *
 * @param   {Object} sessionId
 * @returns {Object}
 */
export const reload = async (sessionId) => {
  // logger.debug(`userlogin.reload : ${sessionId}`);

  const returnUser = await db.findOne(UserLogin.selectSessionById(), [sessionId], cacheOptions);
  if (util.isEmpty(returnUser)) {
    return false;
  }
  return true;
};

/**
 * getSession
 *
 * @param   {Object} sessionId
 * @returns {Object}
 */
export const getSession = async (sessionId) => {
  // logger.debug(`userlogin.reload : ${sessionId}`);

  const returnUser = await db.findOne(UserLogin.selectSessionById(), [sessionId], cacheOptions);
  return returnUser;
};

/**
 * get refreshtoken
 *
 * @param   {Object} sessionId
 * @returns {Object}
 */
export const getRefreshToken = async (pInfo) => {
  // logger.debug(`userlogin.reload : ${sessionId}`);

  const returnUser = await db.findOne(UserLogin.loginUser(), [pInfo.userId, pInfo.srcloc], cacheOptions);
  return returnUser;
};
content_copyCOPY