All files / src/controllers social-login.controller.ts

71.83% Statements 51/71
56.25% Branches 9/16
62.5% Functions 5/8
71.01% Lines 49/69

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 1161x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 1x   5x 5x 5x 5x 5x 5x             1x 3x 3x 3x 3x 2x 2x     2x 2x     1x         1x           1x 2x 2x 2x 1x 1x                             1x     1x               3x 3x       1x 1x 1x 1x                               1x          
import {inject} from '@loopback/core';
import {repository} from '@loopback/repository';
import {post, Request, requestBody, Response, RestBindings} from '@loopback/rest';
import axios from 'axios';
import * as _ from 'lodash';
import {isObject, isString} from 'lodash';
import {ControllerKey, TokenServiceBindings, UserServiceBindings} from '../keys';
import {UserRepository} from '../repositories';
import {JWTService} from '../services/jwt-service';
import {MyUserService} from '../services/user-service';
import errorMessages from '../utils/errorMessages';
import {log} from '../utils/logMethod';
import {AuthController} from "./auth.controller";
import {failureHandler, successHandler, validatePayload} from './components';
import {baseResponse, linkedInReq, socialLoginReq} from "./requestSpecs";
import {socialLoginType} from "./types";
let {requiredFieldIsMissing} = errorMessages
export class SocialLoginController {
  constructor(
    @inject(RestBindings.Http.RESPONSE) protected res: Response,
    @inject(RestBindings.Http.REQUEST) protected req: Request,
    @inject(ControllerKey.AUTH_CONTROLLER) public authController: AuthController,
    @repository(UserRepository) public userRepository: UserRepository,
    @inject(UserServiceBindings.USER_SERVICE) public userService: MyUserService,
    @inject(TokenServiceBindings.TOKEN_SERVICE) public jwtService: JWTService,
 
  ) {
 
  }
  @post('/socialLogin', baseResponse)
  @log()
  async socialLogin(@requestBody(socialLoginReq) body: socialLoginType): Promise<Response> {
    try {
      validatePayload(body, socialLoginReq)
      let isUserExist = await this.userRepository.findOne({where: {email: body.email}})
      if (isUserExist) {
        let userResponse = await this.authController.getUserWithRole({email: body.email}, body.isUser)
        Iif (isString(userResponse)) {
          return this.failureHandler(this.res, 422, userResponse)
        } else {
          let {token}: any = await this.authController.registerUser(body)
          return successHandler(this.res, 200, token)
        }
      } else {
        let {token}: any = await this.authController.registerUser(body)
        return successHandler(this.res, 200, token)
      }
 
    } catch (error) {
      return this.failureHandler(this.res, 403, error);
    }
  }
 
  @post('/linkedInLogin')
  @log()
  async sendQuestion(@requestBody(linkedInReq) body: {code: string, isUser: boolean | undefined}): Promise<Response> {
    try {
      validatePayload(body, linkedInReq)
      if (body.code) {
        let response: {email: string, name: string, image: string} = await getLinkedInProfile(body.code)
        Iif (isObject(response) && response.email) {
          let isUserExist = await this.userRepository.findOne({where: {email: response.email}})
          if (isUserExist) {
            let userResponse = await this.authController.getUserWithRole({email: response.email}, body.isUser)
            if (isString(userResponse)) {
              return this.failureHandler(this.res, 422, userResponse)
            } else {
              let {token}: any = await this.authController.registerUser(response)
              return successHandler(this.res, 200, token)
            }
          } else {
            let {token}: any = await this.authController.registerUser(response)
            return successHandler(this.res, 200, token)
          }
        } else {
          return this.failureHandler(this.res, 422, response)
        }
      } else {
        return this.failureHandler(this.res, 422, requiredFieldIsMissing)
      }
 
    } catch (error) {
      return this.failureHandler(this.res, 422, error)
    }
  }
  private failureHandler(res: Response, code: number, error: any): Promise<Response> {
    let className = error.className || SocialLoginController.name
    return failureHandler(res, code, error, className)
  }
}
 
const getLinkedInProfile = async (code: string) => {
  let url = `https://www.linkedin.com/oauth/v2/accessToken?grant_type=authorization_code&code=${code}&redirect_uri=${process.env.APP_URL}&client_id=${process.env.LINKEDIN_CLIENT_ID}&client_secret=${process.env.LINKEDIN_CLIENT_SECRET}`
  try {
    let token = await axios.get(url)
      .then(res => {return res.data.access_token})
    var headers = {'Authorization': "Bearer " + token};
    let profile = await axios.get('https://api.linkedin.com/v2/me?projection=(id,localizedFirstName,localizedLastName,profilePicture(displayImage~digitalmediaAsset:playableStreams))', {headers})
      .then(res => {return res.data})
 
    let emailAddress = await axios.get("https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))", {headers})
      .then(res => {return res.data})
 
    let obj = {
      name: _.get(profile, 'localizedFirstName', '') + " " + _.get(profile, 'localizedLastName', ''),
      image: _.get(_.last(_.get(profile, 'profilePicture.displayImage~.elements', '')), 'identifiers[0].identifier', ''),
      email: _.get(emailAddress, 'elements[0].handle~.emailAddress', ''),
    }
    return obj
  } catch (error: any) {
    return error.response.data.error_description
  }
 
}