UNPKG

@lomray/microservice-users

Version:

Users microservice based on NodeJS & inverted json.

231 lines (227 loc) 8.49 kB
'use strict'; var tslib = require('tslib'); var microserviceHelpers = require('@lomray/microservice-helpers'); var microserviceNodejsLib = require('@lomray/microservice-nodejs-lib'); var firebaseSdk = require('../external/firebase-sdk.js'); var abstract = require('./abstract.js'); /** * Firebase identity provider */ class Firebase extends abstract { /** * Return user by identity token */ getUserByToken() { return tslib.__awaiter(this, void 0, void 0, function* () { // Get firebase user const [firebaseUser] = yield this.getFirebaseUser(); // Get related user from db const user = yield this.userRepository.findUserByIdentifier(this.provider, firebaseUser.uid); if (!user) { throw new microserviceNodejsLib.BaseException({ status: 404, message: 'User was not found.', }); } return user; }); } /** * @inheritDoc */ signIn({ isDenyRegister, isDenyAuthViaRegister, isShouldAttachUserPhoto = true, isShouldApproveProvider = false, } = {}) { return tslib.__awaiter(this, void 0, void 0, function* () { const [firebaseUser, providerType] = yield this.getFirebaseUser(); const user = yield this.userRepository.findUserByIdentifier(this.provider, firebaseUser.uid); /** * Verify if the user was deleted and can he restore the account */ yield this.userRepository.verifyDeleteAt(user); this.isShouldAttachUserPhoto = isShouldAttachUserPhoto; this.isShouldApproveProvider = isShouldApproveProvider; if (!user) { if (isDenyRegister) { throw new microserviceNodejsLib.BaseException({ status: 500, message: 'User not found.', }); } const userResult = yield this.register(firebaseUser, providerType); return { user: userResult, isNew: true }; } if (isDenyAuthViaRegister) { /** * If user registered - error */ throw new microserviceNodejsLib.BaseException({ status: 500, message: 'User already exists.', }); } return { user, isNew: false }; }); } /** * @inheritDoc */ attachProvider(userId) { return tslib.__awaiter(this, void 0, void 0, function* () { const [firebaseUser, providerType] = yield this.getFirebaseUser(); const user = yield this.userRepository.findOne({ id: userId }, { relations: ['profile'] }); if (!user) { throw new microserviceNodejsLib.BaseException({ status: 404, message: 'User not found.', }); } const { profile, email, phone } = user; // @ts-ignore this need for success pass validation delete user.profile; if (!email && firebaseUser.email) { user.email = firebaseUser.email; } if (!phone && firebaseUser.phoneNumber) { user.phone = firebaseUser.phoneNumber; } const identityProvider = this.getIdentityProvider(firebaseUser, providerType); return this.assign(identityProvider, user, this.getProfile(firebaseUser, profile)); }); } /** * Sign up user * NOTE: type - (google or facebook) * @protected */ register(firebaseUser, type) { var _a, _b; const [firstName, lastName, middleName] = (_b = (_a = firebaseUser.displayName) === null || _a === void 0 ? void 0 : _a.split(' ')) !== null && _b !== void 0 ? _b : []; const user = this.userRepository.create({ firstName, lastName, middleName, email: firebaseUser.email, phone: firebaseUser.phoneNumber, }); const profile = this.getProfile(firebaseUser); const identityProvider = this.getIdentityProvider(firebaseUser, type); /** * Approve non-trusted identity provider */ void this.approveFirebaseUserProvider(firebaseUser); return this.createUser(user, identityProvider, profile); } /** * Approve firebase user identity * NOTE: Set emailVerified to true for preventing override * non-trusted providers */ approveFirebaseUserProvider(firebaseUser) { return tslib.__awaiter(this, void 0, void 0, function* () { const firebase = yield firebaseSdk(); /** * If email verified by default true for trusted provider */ if (firebaseUser.emailVerified || !this.isShouldApproveProvider) { return; } yield firebase.auth().updateUser(firebaseUser.uid, { emailVerified: true, }); }); } /** * Returns user photo if it should be attached * NOTE: Uses while user on split sign up want to upload own photo, * in this case we don't need to set photo from user provider result */ getUserPhoto(firebaseUser) { var _a; if (!this.isShouldAttachUserPhoto) { return null; } return (_a = Firebase.getUserPhoto(firebaseUser)) !== null && _a !== void 0 ? _a : null; } /** * Make or update user profile * @protected */ getProfile(firebaseUser, profile) { const updatedProfile = profile !== null && profile !== void 0 ? profile : this.profileRepository.create({ params: {} }); if (!updatedProfile.photo) { updatedProfile.photo = this.getUserPhoto(firebaseUser); } updatedProfile.params.isEmailVerified = firebaseUser.emailVerified; updatedProfile.params.isPhoneVerified = Boolean(firebaseUser.phoneNumber); return updatedProfile; } /** * Get current identity provider * @protected */ getIdentityProvider(firebaseUser, type) { return this.providerRepository.create({ provider: this.provider, identifier: firebaseUser.uid, type, params: { uid: Firebase.getTypeUid(firebaseUser, type), }, }); } /** * Get provider uid for facebook, google, etc... * @protected */ static getTypeUid(firebaseUser, type) { for (const { providerId, uid } of firebaseUser.providerData) { if (providerId === type) { return uid; } } return undefined; } /** * Get firebase user photo with large size * @protected */ static getUserPhoto(firebaseUser) { for (const { providerId, photoURL } of firebaseUser.providerData) { if (providerId.includes('google')) { return photoURL === null || photoURL === void 0 ? void 0 : photoURL.replace('s96-c', 's400-c'); } else if (providerId.includes('facebook')) { return `${photoURL}?type=large`; } } return firebaseUser.photoURL; } /** * Get firebase user by token * @protected */ getFirebaseUser() { return tslib.__awaiter(this, void 0, void 0, function* () { const firebase = yield firebaseSdk(); try { const validToken = yield firebase.auth().verifyIdToken(this.token); const identifier = validToken.sub; const firebaseUser = yield firebase.auth().getUser(identifier); if (firebaseUser.disabled) { throw new Error('User disabled.'); } return [firebaseUser, validToken.firebase.sign_in_provider]; } catch (e) { microserviceHelpers.Log.error('Failed verify firebase token', e); throw new microserviceNodejsLib.BaseException({ status: 422, message: 'Bad firebase token.', payload: { original: e.message, }, }); } }); } } module.exports = Firebase;