import FuseUtils from '@fuse/utils/FuseUtils'; import _ from '@lodash'; import * as firebaseAuth from 'firebase/auth'; import * as firebaseDb from 'firebase/database'; export default class AuthService extends FuseUtils.EventEmitter { #auth; #db; init(authInstance, dbInstance) { this.#auth = authInstance; this.#db = dbInstance; } createUser = ({ displayName, email, password }) => { return new Promise((resolve, reject) => { firebaseAuth .createUserWithEmailAndPassword(this.#auth, email, password) .then((userCredential) => firebaseAuth.updateProfile(userCredential.user, { displayName })) .then(() => { const userRef = firebaseDb.ref(this.#db, `users/${this.#auth.currentUser.uid}`); const value = { role: 'user', data: { displayName, email }, favorites: [] }; return firebaseDb.set(userRef, value); }) .then(() => { resolve(); }) .catch((error) => { reject(error); }); }); }; signInWithEmailAndPassword = ({ email, password, remember }) => { const persistence = remember ? firebaseAuth.browserLocalPersistence : firebaseAuth.browserSessionPersistence; return new Promise((resolve, reject) => { firebaseAuth .setPersistence(this.#auth, persistence) .then(() => firebaseAuth.signInWithEmailAndPassword(this.#auth, email, password)) .then((userCredential) => { resolve(userCredential.user); const { user } = userCredential; this.emit('onLogin', { role: 'user', data: { displayName: user.displayName, photoURL: user.photoURL, email: user.email }, }); }) .catch((error) => { reject(error); }); }); }; updateUserData = (user) => { return new Promise((resolve, reject) => { if (_.isEmpty(user)) { reject(Error('User data is empty')); } const userRef = firebaseDb.ref(this.#db, `users/${this.#auth.currentUser.uid}`); firebaseDb .set(userRef, user) .then(() => { if (user.data.email !== this.#auth.currentUser.email) { return firebaseAuth.updateEmail(this.#auth, user.data.email); } return null; }) .then(() => { resolve(); }) .catch((error) => { reject(error); }); }); }; logout = () => { this.#auth .signOut() .then(() => { this.emit('onLogout', 'Logged out'); }) .catch((error) => { console.warn('Logout error: ', error); }); }; getUserData = (userId) => { return new Promise((resolve, reject) => { const userRef = firebaseDb.ref(this.#db, `users/${userId}`); firebaseDb.onValue( userRef, (snapshot) => { const user = snapshot.val(); resolve(user); }, (error) => { reject(error); } ); }); }; sendPasswordResetEmail = (email) => { return new Promise((resolve, reject) => { if (!email) { reject(Error('Email is empty')); } firebaseAuth .sendPasswordResetEmail(this.#auth, email) .then(() => { resolve(); }) .catch((error) => { reject(error); }); }); }; onAuthStateChanged = (callback) => { if (!this.#auth) { return; } this.#auth.onAuthStateChanged(callback); }; }