From 8e035a4b33b5f4ee8f8cfc5b5441d3eefb0ecb49 Mon Sep 17 00:00:00 2001 From: Okechi Onyeje Date: Fri, 4 Jan 2019 19:14:49 -0500 Subject: [PATCH] T-954157790482076: Move image upload functionality to its own generic util function --- src/ups/profiles/dao.js | 32 ++++++---------------------- src/ups/profiles/handlers.js | 6 +++--- src/ups/utils/utils.js | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/ups/profiles/dao.js b/src/ups/profiles/dao.js index 6f40adc..063b4d6 100644 --- a/src/ups/profiles/dao.js +++ b/src/ups/profiles/dao.js @@ -1,5 +1,5 @@ const database = require('firebase-admin').database(); -const storage = require('firebase-admin').storage(); +const utils = require('../utils/utils'); /** * Blind initializing function for a new user's default profile @@ -37,41 +37,21 @@ function getProfile(profileNumber, tagferId) { /** * Updates a user's profile image - * @param {object} profileObj JSON object containing all image data for a profile captured from the frontend + * @param {object} profileImageData JSON object containing all image data for a profile captured from the frontend * @param {number} profileNumber Number used to identify which profile a user wants to update/add image to * @param {string} tagferId tagferId obtained by extracting from authorization header * @returns {object} Object containing a Promise that contains the result of uploading profile image, and the image url | {promise, imageURL} */ -function updateProfileImage(profileImageObj, profileNumber, tagferId) { +async function updateProfileImage(profileImageData, profileNumber, tagferId, res) { //persist profile image data to firebase storage - var profileImageRef = storage.ref(`images/profiles/${tagferId}/profile${profileNumber}/${profileImageObj.name}`); - - var uploadTask = profileImageRef.put(profileImageObj.file, profileImageObj.metaData); - - return uploadTask.on('state_changed',(snapshot) => { - var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; - console.log('Upload is ' + progress + '% done'); - switch (snapshot.state) { - case 'paused': // or 'paused' - console.log('Upload is paused'); - break; - case 'running': // or 'running' - console.log('Upload is running'); - break; - } - }, (error) => {throw error} - , () => { - return uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => { - //save image url to user's selected profile - return {promise: database.ref(`/profiles/${tagferId}/profile${profileNumber}/imageURL`).set(downloadURL), imageURL: downloadURL}; - }).catch( (error) => {throw error}); - }) + var downloadURL = await utils.uploadImage(profileImageData, `images/${tagferId}/profile${profileNumber}/${profileImageData.metaData.name}`, 'tagfer-inc_profile-images', res) + return {promise: database.ref(`/profiles/${tagferId}/profile${profileNumber}/imageURL`).set(downloadURL), imageURL: downloadURL}; } module.exports = { updateProfile, createInitialProfiles, - updateProfileImage + updateProfileImage, getProfile }; diff --git a/src/ups/profiles/handlers.js b/src/ups/profiles/handlers.js index 145eafb..04eb27e 100644 --- a/src/ups/profiles/handlers.js +++ b/src/ups/profiles/handlers.js @@ -39,13 +39,13 @@ async function updateUserProfile(req, res) { * @param {Object} req {profileNumber} * @param {Object} res */ -async function updateUserProfileImage() { +async function updateUserProfileImage(req, res) { const profileImageObj = req.body; const sessionId = utils.getSessionIdFromAuthHeader(req, res); try { const tagferId = authDao.getSession(sessionId).tagferId; - const result = profileDao.updateProfileImage(profileImageObj, req.params.profileNumber, tagferId) + const result = await profileDao.updateProfileImage(profileImageObj, req.params.profileNumber, tagferId, res) result.promise.then( () => { res.status(http.OK).json({imageURL: result.imageURL}); }).catch( (error) => { @@ -76,6 +76,6 @@ async function getUserProfile(req, res) { module.exports = { updateUserProfile, - updateUserProfileImage + updateUserProfileImage, getUserProfile } \ No newline at end of file diff --git a/src/ups/utils/utils.js b/src/ups/utils/utils.js index 9c2a3f5..2d32f7d 100644 --- a/src/ups/utils/utils.js +++ b/src/ups/utils/utils.js @@ -4,6 +4,8 @@ const crypto = require('crypto'); const appConfig = require('../../config/app.json'); const http = require('../../config/http'); const errors = require('../../config/errors'); +const UUID = require("uuid/v4"); +const firebase = require('firebase-admin'); /** * Verifies if the request is valid by checking if the request has the right app secret. @@ -71,10 +73,49 @@ function createOAuthHeader(request, app) { return oauth.toHeader(oauth.authorize(request, app.token)); } +/** + * + * @param {*} image as raw bytes + * @param {*} path to saving image in firebase + * @param {*} bucket + * + * @returns {*} imageURL + */ +async function uploadImage(imageData, path, bucketName, res) { + try { + var bucket = await firebase.storage().bucket(`gs://${bucketName}`); + + var file = bucket.file(path); + const uuid = UUID() + var imageBuffer = new Buffer(imageData.base64Data, 'base64'); + + var result = await file.save(imageBuffer, { + metaData: { + contentType: imageData.metaData.contentType, + metadata: { + firebaseStorageDownloadTokens: uuid + } + }, + public: true, + validation: 'md5', + }); + + const fileMetaData = await file.getMetadata(); + //const signedURL = await file.getSignedUrl(); + + return fileMetaData[0].mediaLink; + + } catch (error) { + res.status(http.INTERNAL_SERVER_ERROR).json({error}); + return null; + } +} + module.exports = { isAppSecretValid, isBodyValid, getSessionIdFromAuthHeader, isProfileNumberValid, createOAuthHeader + uploadImage }; \ No newline at end of file