import { Injectable } from '@nestjs/common' ; import { Repository } from 'typeorm' ; import { InjectRepository } from '@nestjs/typeorm' ; import FB from 'fb' ; import { environment } from '../../../../../environments/environment' ; import { SocialUser } from '../../../../../client/app/shared/auth/social-module/classes/social-user.class' ; import { User } from '../../user.entity' ; import { FacebookProvider } from './facebook-provider.entity' ; import { SecurityService } from '../../../common/security/security.service' ; import { UserSessionAndCSRFToken } from '../../interfaces/user-session-and-csrfToken.interface' ; @ Injectable ( ) export class FacebookService { constructor ( @ InjectRepository ( User ) private readonly userRepository , @ InjectRepository ( FacebookProvider ) private readonly facebookProviderRepository , private readonly securityService ) { } async verifyAccessToken ( accessToken ) { try { const verifiedAccessToken = await FB . api ( 'me' , { access_token : accessToken , fields : 'id,email' , } ) ; return verifiedAccessToken ; } catch ( e ) { return false ; } } async findFacebookProviderBySocialUid ( socialUid ) { return await this . facebookProviderRepository . findOne ( { where : { socialUid } , } ) ; } async findUserAccountByFacebookProviderId ( id ) { return await this . userRepository . findOne ( { where : { facebookProviderId : id } , relations : [ 'facebookProvider' ] , } ) ; } async findFacebookProviderById ( providerId ) { return await this . facebookProviderRepository . findOne ( { where : { id : providerId } , cache : true , } ) ; } async createFacebookUserSessionAndCSRF ( socialUser ) { try { const user = await this . addFacebookUserToDatabase ( socialUser ) ; const sessionToken = await this . securityService . createSessionToken ( { roles : user . roles , id : user . id , loginProvider : socialUser . provider , } ) ; const csrfToken = await this . securityService . createCsrfToken ( ) ; const result = { user , sessionToken , csrfToken } ; return result ; } catch ( err ) { return err ; } } private async addFacebookUserToDatabase ( socialUser ) { const facebookProvider = new FacebookProvider ( ) ; facebookProvider . accessToken = socialUser . accessToken ; facebookProvider . email = socialUser . email ; facebookProvider . name = socialUser . name ; facebookProvider . photoUrl = socialUser . photoUrl ; facebookProvider . socialUid = socialUser . socialUid ; const user = new User ( ) ; user . isAnonymous = false ; user . roles = [ 'user' ] ; user . facebookProvider = facebookProvider ; return await this . userRepository . save ( user ) ; } async loginFacebookUserSessionAndCSRF ( facebookProvider ) { const user = await this . findUserAccountByFacebookProviderId ( facebookProvider . id ) ; const sessionToken = await this . securityService . createSessionToken ( { roles : user . roles , id : user . id , loginProvider : 'facebook' , } ) ; const csrfToken = await this . securityService . createCsrfToken ( ) ; const result = { user , sessionToken , csrfToken } ; return result ; } async linkProviderToExistingAccount ( user , socialUser , refreshToken ) { const updatedUser = user ; const facebookProvider = new FacebookProvider ( ) ; facebookProvider . accessToken = socialUser . accessToken ; facebookProvider . email = socialUser . email ; facebookProvider . name = socialUser . name ; facebookProvider . photoUrl = socialUser . photoUrl ; facebookProvider . socialUid = socialUser . socialUid ; updatedUser . facebookProvider = facebookProvider ; await this . userRepository . save ( updatedUser ) ; const sessionToken = await this . securityService . createSessionToken ( { roles : updatedUser . roles , id : updatedUser . id , loginProvider : 'facebook' , refreshToken , } ) ; const csrfToken = await this . securityService . createCsrfToken ( ) ; const result = { user : updatedUser , sessionToken , csrfToken } ; return result ; } async removeFacebookProvider ( provider ) { await this . facebookProviderRepository . remove ( provider ) ; } async revokeAccessToken ( accessToken ) { return await FB . api ( 'me/permissions' , 'delete' , { access_token : accessToken , } ) ; } }