backend/lib/seed/services/auth/FirebaseAuthService.ts
2025-05-14 21:45:16 +02:00

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;
}
}