148 lines
4.6 KiB
TypeScript
148 lines
4.6 KiB
TypeScript
/* 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<FirebaseTokenResult> {
|
|
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<FirebaseTokenResult> {
|
|
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<FirebaseTokenResult> {
|
|
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<FirebaseTokenResult> {
|
|
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<SuccessResponse> {
|
|
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<SuccessResponse> {
|
|
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;
|
|
}
|
|
}
|