/* eslint-disable @typescript-eslint/camelcase */ import { apiCall } from '@seed/helpers/FetchHelper'; import { FirebaseTokenResult } from '@seed/interfaces/components'; import { ApolloError } from 'apollo-server-lambda'; import Firebase from './FirebaseService'; import { LoginInput, LinkEmailInput, SMSVerif, CodeConfirmInput } from '@services/module-accounts/account.components'; import { v4 as uuid } from 'uuid'; import { newError } from '@seed/helpers/Error'; const firebaseAuthUrl = 'https://identitytoolkit.googleapis.com/v1'; import { google, identitytoolkit_v3 } from 'googleapis'; import { SuccessResponse } from '@seed/interfaces/response'; export default class FirebaseAuth { private static instance: FirebaseAuth; private apiKey: string; private identityToolkit: identitytoolkit_v3.Identitytoolkit; private constructor() { this.apiKey = process.env.FIREBASE_apiKey || ''; this.identityToolkit = google.identitytoolkit({ auth: this.apiKey || '', version: 'v3', }); } public static getInstance(): FirebaseAuth { if (!FirebaseAuth.instance) { FirebaseAuth.instance = new FirebaseAuth(); } return FirebaseAuth.instance; } /* * Login functions */ public async loginWithEmailPassword({ email, password }: LoginInput): Promise { try { const requestUrl = `${firebaseAuthUrl}/accounts:signInWithPassword?key=${this.apiKey}`; const res = await apiCall(requestUrl, 'POST', null, { email, password, returnSecureToken: true, }); return res; } catch (err) { throw newError(2010, err); } } public async loginWithRefreshToken(refreshToken: string): Promise { try { const requestUrl = `${firebaseAuthUrl}/token?key=${this.apiKey}`; const res = await apiCall(requestUrl, 'POST', null, { grant_type: 'refresh_token', refresh_token: refreshToken, }); return { localId: res.user_id, idToken: res.id_token, refreshToken: res.refresh_token, expiresIn: res.expires_in, }; } catch (err) { // throw newError('auth.error.' + err.error.error.message, err.error.error.code, err); throw newError(2010, err); } } public async loginAnonymous(): Promise { try { const requestUrl = `${firebaseAuthUrl}/accounts:signUp?key=${this.apiKey}`; const res = await apiCall(requestUrl, 'POST', null, { returnSecureToken: true, }); return res; } catch (err) { // throw newError('auth.error.' + err.error.error.message, err.error.error.code, err); throw newError(2010, err); } } public async linkWithEmailPassword({ idToken, email, password }: LinkEmailInput): Promise { try { const requestUrl = `${firebaseAuthUrl}/accounts:update?key=${this.apiKey}`; const res = await apiCall(requestUrl, 'POST', null, { idToken, email, password, returnSecureToken: true, }); return res; } catch (err) { throw newError(2015, err); } } /* * MFA SMS functions */ public async sendSMSVerification({ phoneNumber, recaptchaToken }: SMSVerif): Promise { const response = new SuccessResponse(); const gRes = await this.identityToolkit.relyingparty.sendVerificationCode({ requestBody: { phoneNumber, recaptchaToken, }, }); // save sessionInfo into db. You will need this to verify the SMS code const sessionInfo = gRes.data.sessionInfo; console.log(sessionInfo); response.success = true; return response; } public async checkSMSVerification({ email, code }: CodeConfirmInput): Promise { const response = new SuccessResponse(); const sessionInfo = ''; const log = await this.identityToolkit.relyingparty.verifyPhoneNumber({ requestBody: { code: code.toString(), phoneNumber: '', sessionInfo, }, }); response.success = true; console.log(log); return response; } }