mirror of
https://bitbucket.org/tagfer_team/tagfer-server.git
synced 2025-12-25 03:37:38 +00:00
Signup + Route Changes + Error Handling
This commit is contained in:
parent
cbeb15936e
commit
cfeb388943
@ -6,7 +6,10 @@
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017,
|
||||
"sourceType": "module"
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
@ -24,6 +27,7 @@
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
],
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
@ -65,6 +65,8 @@
|
||||
"verificationTTL": 300000,
|
||||
"verificationTTLClear": 1800000
|
||||
},
|
||||
"defaultProfileName": "Business Profile",
|
||||
"baseURL": "https://tagfer.com",
|
||||
"referralTokens": 50,
|
||||
"defaultProfileName": "Public Profile",
|
||||
"suggestedUsersCount": 20
|
||||
}
|
||||
@ -19,6 +19,7 @@ module.exports = {
|
||||
APP_NETWORK_TIMEOUT: 'app/network-timeout',
|
||||
APP_UNABLE_TO_PARSE_RESPONSE: 'app/unable-to-parse-response',
|
||||
APP_FIREBASE_DATABASE_ERROR: 'app/firebase-database-error',
|
||||
APP_FIREBASE_STORAGE_ERROR: 'app/firebase-storage-error',
|
||||
//Request Errors
|
||||
MISSING_BODY_ATTRIBUTES: 'request/missing-body-attributes',
|
||||
//Profile Errors
|
||||
|
||||
@ -22,9 +22,8 @@ function router(app) {
|
||||
app.put('/auth/signup', AuthHandlers.signup);
|
||||
|
||||
// Profile Endpoints
|
||||
app.post('/profiles/me/:profileNumber', ProfileHandlers.updateUserProfile);
|
||||
app.get('/profiles/me/:profileNumber', ProfileHandlers.getUserProfile);
|
||||
app.put('/profiles/uploadImage/:profileNumber', ProfileHandlers.updateUserProfileImage);
|
||||
app.post('/profiles/me/:profileN', ProfileHandlers.updateUserProfile);
|
||||
app.get('/profiles/me/:profileN', ProfileHandlers.getUserProfile);
|
||||
app.get('/profiles/suggest', ProfileHandlers.suggestNProfiles);
|
||||
|
||||
// Notes Endpoints
|
||||
|
||||
@ -5,26 +5,30 @@ const appConfig = require('./app.json');
|
||||
const authToken = appConfig.keys.twilio.authToken;
|
||||
const accountSid = appConfig.keys.twilio.accountSid;
|
||||
const tagferPhone = appConfig.keys.twilio.phoneNumber;
|
||||
const client = new Twilio(accountSid, authToken);
|
||||
var client;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function sendSMSTo(clientPhone, message, callback) {
|
||||
function sendSMSTo(clientPhone, message, callback = () => {}) {
|
||||
const sms = {
|
||||
from: tagferPhone,
|
||||
body: message,
|
||||
to: clientPhone
|
||||
};
|
||||
|
||||
client.messages.create(sms).then(() => {
|
||||
getClient().messages.create(sms).then(() => {
|
||||
callback({result: true});
|
||||
}).catch(error => {
|
||||
//TODO: add twilio error handler
|
||||
callback({error: error.message});
|
||||
}).done();
|
||||
}
|
||||
|
||||
function getClient() {
|
||||
if (!client) {
|
||||
client = new Twilio(accountSid, authToken);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sendSMSTo
|
||||
};
|
||||
@ -1,11 +1,12 @@
|
||||
const firebase = require('firebase');
|
||||
const admin = require('firebase-admin');
|
||||
const uuid = require('uuid/v4');
|
||||
const _ = require('lodash');
|
||||
|
||||
const utils = require('../utils/utils');
|
||||
const errors = require('../../config/errors');
|
||||
const loki = require('../../config/loki');
|
||||
const twilio = require('../../config/twilio');
|
||||
const appConfig = require('../../config/app.json');
|
||||
|
||||
/**
|
||||
* Checks if the email exists in our auth system
|
||||
@ -30,6 +31,7 @@ function doesPhoneExist(phoneNumber) {
|
||||
|
||||
/**
|
||||
* Sign in user using firebase client api
|
||||
*
|
||||
* @param {String} email
|
||||
* @param {String} password
|
||||
*/
|
||||
@ -39,6 +41,7 @@ function signinWithEmail(email, password) {
|
||||
|
||||
/**
|
||||
* Sign in with tagferId using the admin sdk to get email and then the firebase client to sign in
|
||||
*
|
||||
* @param {String} tagferId
|
||||
* @param {String} password
|
||||
*/
|
||||
@ -48,6 +51,7 @@ function signinWithTagferId(tagferId, password) {
|
||||
|
||||
/**
|
||||
* Creates a new user in firebase auth
|
||||
*
|
||||
* @param {Object} user
|
||||
* @param {Function} callback
|
||||
*/
|
||||
@ -56,9 +60,25 @@ function createNewUser(user) {
|
||||
uid: user.tagferId.toLowerCase(),
|
||||
email: user.email,
|
||||
password: user.password,
|
||||
phoneNumber: user.phoneNumber,
|
||||
displayName: _.startCase(user.fullName)
|
||||
});
|
||||
phoneNumber: user.phoneNumber
|
||||
}).catch(error => { throw error.code; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the user signup data to firebase database
|
||||
*/
|
||||
function signup(tagferId, phoneNumber, profile, requests = []) {
|
||||
const ref = admin.database().ref();
|
||||
const updates = {};
|
||||
updates[`profiles/${tagferId}/profile1`] = profile;
|
||||
updates[`mapper/phoneNumbers/${phoneNumber}`] = tagferId;
|
||||
|
||||
for (let i = 0; i < requests.length; i++) {
|
||||
updates[`requests/${tagferId}/sent/${requests[i]}`] = 1;
|
||||
updates[`requests/${requests[i]}/received/${tagferId}`] = 1;
|
||||
}
|
||||
|
||||
return ref.update(updates).catch(utils.dbErrorHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,6 +86,7 @@ function createNewUser(user) {
|
||||
* 1. Contacts that are in the tagfer network.
|
||||
* 2. Contacts that are out of the network.
|
||||
* 3. Contacts that failed to be processed.
|
||||
*
|
||||
* @param {Array} phoneNumbers
|
||||
* @returns {Object} groups of inNetwork, outNetwork, failed
|
||||
*/
|
||||
@ -117,6 +138,28 @@ function sendVerificationCode(phoneNumber, callback) {
|
||||
twilio.sendSMSTo(phoneNumber, message, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a mass text invite for all phone numbers supplied. Calls are subject to be throttled, since Twillio has a limit
|
||||
* of 1 MPS, with a queue of max size of 1MPS * 14,400.
|
||||
*
|
||||
* @param {Array} phoneNumbers
|
||||
* @param {String} fullName
|
||||
* @param {String} tagferId
|
||||
*/
|
||||
async function sendMassTextInvites(phoneNumbers = [], fullName, tagferId) {
|
||||
const promises = [];
|
||||
const referralMessage = `${fullName} gave you ${appConfig.referralTokens} Tagfer Tokens! To claim use his referral link: ${appConfig.baseURL}/${tagferId}`;
|
||||
for (let i = 0; i < phoneNumbers.length; i++) {
|
||||
promises[i] = twilio.sendSMSTo(phoneNumbers[i], referralMessage);
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new session for security of users and to maintain states of the requests.
|
||||
* @returns Session identifier to manage state of the user
|
||||
@ -215,8 +258,10 @@ module.exports = {
|
||||
doesEmailExist,
|
||||
doesTagferIdExist,
|
||||
doesPhoneExist,
|
||||
sendMassTextInvites,
|
||||
sendVerificationCode,
|
||||
isVerificationCodeCorrect,
|
||||
signup,
|
||||
signinWithTagferId,
|
||||
signinWithEmail,
|
||||
createNewUser,
|
||||
|
||||
@ -4,8 +4,6 @@ const authDao = require('./dao');
|
||||
const profileDao = require('./../profiles/dao');
|
||||
const utils = require('../utils/utils');
|
||||
const errors = require('../../config/errors');
|
||||
const appConfig = require('../../config/app.json');
|
||||
const http = require('../../config/http');
|
||||
const twitter = require('../socials/twitter');
|
||||
|
||||
// Handlers
|
||||
@ -87,6 +85,7 @@ function verifyPhoneCode(req, res) {
|
||||
/**
|
||||
* Endpoint: auth/signin
|
||||
* Signs the user in using firebase auth
|
||||
*
|
||||
* @param {Object} req {email: String, password: String} | {tagferId: String, password: String}
|
||||
* @param {Object} res {sessionId: String} | {error: String}
|
||||
*/
|
||||
@ -107,9 +106,9 @@ function signin(req, res) {
|
||||
|
||||
promise.then( ({ user })=> {
|
||||
const sessionId = authDao.createNewSessionId(user.uid);
|
||||
res.json({sessionId});
|
||||
res.json({ sessionId });
|
||||
}).catch(error => {
|
||||
res.json( {error: error.code} );
|
||||
res.json({ error: error.code });
|
||||
});
|
||||
}
|
||||
|
||||
@ -133,28 +132,35 @@ function signout(req, res) {
|
||||
/**
|
||||
* Endpoint: auth/signup
|
||||
* Signs up the user by creating a new user in firebase admin.
|
||||
*
|
||||
* @param {Object} req { tagferId: String, email: String, password: String, phoneNumber: String, fullName: String }
|
||||
* @param {Object} res { sessionId: String } | { error: String }
|
||||
*/
|
||||
async function signup(req, res) {
|
||||
const {user, profile} = req.body;
|
||||
const userVerifier = () => user.tagferId && user.email && user.password && user.phoneNumber && user.fullName;
|
||||
const profileVerifier = () => profile.company && profile.company.profession && profile.company.name && profile.company.address && profile.company.number;
|
||||
|
||||
if (!utils.isAppSecretValid(req,res) || !utils.isBodyValid(userVerifier, res) || !utils.isBodyValid(profileVerifier, res)) {
|
||||
const { user, profile, invites } = req.body;
|
||||
if (!utils.isAppSecretValid(req,res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
profile.name = appConfig.defaultProfileName;
|
||||
profile.email = user.email;
|
||||
|
||||
try {
|
||||
await authDao.createNewUser(user);
|
||||
await profileDao.createInitialProfiles(profile, user.tagferId);
|
||||
const sessionId = authDao.createNewSessionId(user.tagferId);
|
||||
res.status(http.CREATED).json({sessionId});
|
||||
// ADD USER TO FIREBASE AUTH
|
||||
const tagferId = (await authDao.createNewUser(user)).uid;
|
||||
|
||||
// CREATE PROFILE OBJECT
|
||||
const profileObject = await profileDao.createInitialProfileObject(profile, tagferId);
|
||||
|
||||
// ADD PROFILE, MAPPER, REQUESTS TO DB
|
||||
await authDao.signup(tagferId, user.phoneNumber, profileObject, invites.requests);
|
||||
|
||||
// CREATE NEW SESSION ID
|
||||
const sessionId = authDao.createNewSessionId(tagferId);
|
||||
res.json({ sessionId });
|
||||
|
||||
// INVITES SENT IN THE BACKGROUND
|
||||
authDao.sendMassTextInvites(invites.phoneNumbers, profile.fullName, tagferId);
|
||||
} catch (error) {
|
||||
res.status(http.BAD_REQUEST).json({error:error.code});
|
||||
console.log(error);
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,56 +2,32 @@ const database = require('firebase-admin').database();
|
||||
const utils = require('../utils/utils');
|
||||
const appConfig = require('../../config/app.json');
|
||||
|
||||
/**
|
||||
* Blind initializing function for a new user's default profile
|
||||
* @param {object} profileObj
|
||||
* @param {string} tagferId
|
||||
*/
|
||||
function createInitialProfiles(profileObj, tagferId) {
|
||||
//persist profile data to firebase
|
||||
return database.ref(`/profiles/${tagferId}/profile1`).set(profileObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user profile
|
||||
*
|
||||
* @param {object} profileObj JSON object containing all data for a profile captured from the frontend
|
||||
* @param {number} profileNumber Number used to identify which profile a user wants to update/add to if the profile slot is empty
|
||||
* @param {string} tagferId tagferId obtained by extracting from authorization header
|
||||
* @returns {Boolean} Boolean result of whether the
|
||||
*/
|
||||
function updateProfile(profileObj, profileNumber, tagferId) {
|
||||
//persist profile data to firebase
|
||||
return database.ref(`/profiles/${tagferId}/profile${profileNumber}`).set(profileObj);
|
||||
async function updateProfile(profileObj, profileN, tagferId) {
|
||||
if (profileObj.photoBytes) {
|
||||
profileObj.photoURL = await _uploadProfileImageToBucket(profileObj.photoBytes, profileN, tagferId).catch(utils.storageErrorHandler);
|
||||
profileObj.photoBytes = null;
|
||||
}
|
||||
|
||||
return database.ref(`/profiles/${tagferId}/profile${profileN}`).update(profileObj).catch(utils.dbErrorHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user profile
|
||||
*
|
||||
* @param {Number} profileNumber profile number that identifies which profile information to get for a user
|
||||
* @param {string} tagferId SessionId obtained by extracting from authorization header
|
||||
* @returns {Object} Profile object containg information for a specific user's profile
|
||||
*/
|
||||
function getProfile(profileNumber, tagferId) {
|
||||
return database.ref(`/profiles/${tagferId}/profile${profileNumber}`).once('value').then(function (snapshot) {
|
||||
return (snapshot.exists() ? snapshot.val() : {});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user's profile image
|
||||
* @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}
|
||||
*/
|
||||
|
||||
async function updateProfileImage(profileImageData, profileNumber, tagferId) {
|
||||
//persist profile image data to firebase storage
|
||||
try {
|
||||
const downloadURL = await utils.uploadImage(profileImageData, `${tagferId}-profile${profileNumber}`, appConfig.buckets.profile);
|
||||
return { promise: database.ref(`/profiles/${tagferId}/profile${profileNumber}/photoURL`).set(downloadURL), imageURL: downloadURL };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
function getProfile(profileN, tagferId) {
|
||||
return database.ref(`/profiles/${tagferId}/profile${profileN}`).once('value')
|
||||
.then(snapshot => (snapshot.exists() ? snapshot.val() : {}))
|
||||
.catch(utils.dbErrorHandler);
|
||||
}
|
||||
|
||||
var lastRetrievedProfile = undefined;
|
||||
@ -63,42 +39,70 @@ var lastRetrievedProfile = undefined;
|
||||
*
|
||||
* @param {Number} N number of profiles to retrieve
|
||||
*/
|
||||
function suggestNProfiles(N) {
|
||||
let promise = null;
|
||||
async function suggestNProfiles(N) {
|
||||
let data = null;
|
||||
|
||||
if (lastRetrievedProfile) {
|
||||
promise = database.ref('profiles').orderByKey().startAt(lastRetrievedProfile).limitToFirst(N).once('value');
|
||||
data = await database.ref('profiles').orderByKey().startAt(lastRetrievedProfile).limitToFirst(N).once('value').catch(utils.dbErrorHandler);
|
||||
} else {
|
||||
promise = database.ref('profiles').limitToFirst(N).once('value');
|
||||
data = await database.ref('profiles').limitToFirst(N).once('value').catch(utils.dbErrorHandler);
|
||||
}
|
||||
|
||||
return promise.then(data => {
|
||||
const list = new Array(data.numChildren());
|
||||
let index = 0;
|
||||
|
||||
data.forEach(profile => { list[index++] = _toLiteProfile(profile.val().profile1, profile.key); });
|
||||
if (index > 0) {
|
||||
lastRetrievedProfile = list[index-1].tagferId;
|
||||
}
|
||||
const list = new Array(data.numChildren());
|
||||
let index = 0;
|
||||
|
||||
if (data.hasChildren && N !== data.numChildren()) {
|
||||
lastRetrievedProfile = undefined;
|
||||
return suggestNProfiles(N - index).then(list2 => list2.concat(list));
|
||||
data.forEach(profile => { list[index++] = _toLiteProfile(profile.val().profile1, profile.key); });
|
||||
if (index > 0) {
|
||||
lastRetrievedProfile = list[index-1].tagferId;
|
||||
}
|
||||
|
||||
if (data.hasChildren && N !== data.numChildren()) {
|
||||
lastRetrievedProfile = undefined;
|
||||
return suggestNProfiles(N - index).then(list2 => list2.concat(list));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the initial profile object by formatting the object received from the app and adding the photoURL
|
||||
*
|
||||
* @param {Realm Profile} profile
|
||||
* @param {String} tagferId
|
||||
*/
|
||||
async function createInitialProfileObject(profile, tagferId) {
|
||||
const { fullName, jobTitle, companyName, companyEmail, companyPhoneNumber, photoBytes } = profile;
|
||||
const photoURL = profile.photoBytes ? await _uploadProfileImageToBucket(photoBytes, 1, tagferId) : null;
|
||||
|
||||
return {
|
||||
profileName: appConfig.defaultProfileName,
|
||||
fullName,
|
||||
photoURL,
|
||||
experience: {
|
||||
jobTitle,
|
||||
companyName
|
||||
},
|
||||
emails: {
|
||||
company: companyEmail
|
||||
},
|
||||
phoneNumbers: {
|
||||
company: companyPhoneNumber
|
||||
}
|
||||
|
||||
return list;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function _toLiteProfile(profile, tagferId) {
|
||||
const { fullName, jobTitle, companyName, photoURL } = profile;
|
||||
const { fullName, experience, photoURL } = profile;
|
||||
const { jobTitle, companyName } = experience;
|
||||
return { tagferId, fullName, jobTitle, companyName, photoURL };
|
||||
}
|
||||
|
||||
function _uploadProfileImageToBucket(image, profileN, tagferId) {
|
||||
return utils.uploadImage(image, `${tagferId}-profile${profileN}.jpeg`, appConfig.buckets.profile);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createInitialProfileObject,
|
||||
updateProfile,
|
||||
createInitialProfiles,
|
||||
updateProfileImage,
|
||||
getProfile,
|
||||
suggestNProfiles
|
||||
};
|
||||
|
||||
@ -1,76 +1,40 @@
|
||||
const profileDao = require('./dao');
|
||||
const authDao = require('../auth/dao');
|
||||
const utils = require('../utils/utils');
|
||||
const errors = require('../../config/errors');
|
||||
const http = require('../../config/http');
|
||||
const appConfig = require('../../config/app.json');
|
||||
|
||||
// Handlers
|
||||
/**
|
||||
* Endpoints: POST profiles/
|
||||
* Updates a profile for a user based on session stored tagferId
|
||||
*
|
||||
* @param {Object} req
|
||||
* @param {Object} res {result: Boolean} | {error: String}
|
||||
*/
|
||||
async function updateUserProfile(req, res) {
|
||||
const profileObj = req.body;
|
||||
const profileNumber = req.params.profileNumber;
|
||||
|
||||
if (!utils.isProfileNumberValid(profileNumber, res)) {
|
||||
return;
|
||||
}
|
||||
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
|
||||
try {
|
||||
const tagferId = authDao.getSession(sessionId).tagferId;
|
||||
profileDao.updateProfile(profileObj, profileNumber, tagferId).then(() => {
|
||||
res.status(http.CREATED).json({});
|
||||
}).catch(() => {
|
||||
res.status(http.INTERNAL_SERVER_ERROR).json({ error: errors.APP_FIREBASE_DATABASE_ERROR });
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(http.UNAUTHORIZED).json({ error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoints: PUT profiles/uploadImage/:profileNumber
|
||||
* Updates user's profile with a profile image based on profile number given.
|
||||
* This endpoint is called seperately in order to add an image to a profile.
|
||||
* @param {Object} req {profileNumber}
|
||||
* @param {Object} res
|
||||
*/
|
||||
async function updateUserProfileImage(req, res) {
|
||||
const profileImageObj = req.body;
|
||||
const profileNumber = req.params.profileN;
|
||||
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
|
||||
|
||||
try {
|
||||
const tagferId = authDao.getSession(sessionId).tagferId;
|
||||
const result = await profileDao.updateProfileImage(profileImageObj, req.params.profileNumber, tagferId);
|
||||
result.promise.then(() => {
|
||||
res.status(http.OK).json({ imageURL: result.imageURL });
|
||||
}).catch((error) => {
|
||||
res.status(http.INTERNAL_SERVER_ERROR).json({ error });
|
||||
});
|
||||
await profileDao.updateProfile(profileObj, profileNumber, tagferId);
|
||||
res.json({});
|
||||
} catch (error) {
|
||||
res.status(http.BAD_REQUEST).json({ error });
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserProfile(req, res) {
|
||||
const profileNumber = req.params.profileNumber;
|
||||
if (!utils.isProfileNumberValid(profileNumber)) {
|
||||
return;
|
||||
}
|
||||
const profileNumber = req.params.profileN;
|
||||
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
|
||||
|
||||
try {
|
||||
const tagferId = authDao.getSession(sessionId).tagferId;
|
||||
profileDao.getProfile(profileNumber, tagferId).then((profile) => {
|
||||
res.status(http.OK).json({ profile });
|
||||
}).catch(error => {
|
||||
res.status(http.INTERNAL_SERVER_ERROR).json({ error: error.code });
|
||||
});
|
||||
const profile = await profileDao.getProfile(profileNumber, tagferId);
|
||||
res.json({ ...profile });
|
||||
} catch (error) {
|
||||
res.status(http.UNAUTHORIZED).json({ error });
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,19 +45,21 @@ async function getUserProfile(req, res) {
|
||||
*
|
||||
* LiteProfileObject = { tagferId, fullName, photoURL, jobTitle, companyName }
|
||||
*/
|
||||
function suggestNProfiles(req, res) {
|
||||
async function suggestNProfiles(req, res) {
|
||||
if (!utils.isAppSecretValid(req,res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
profileDao.suggestNProfiles(appConfig.suggestedUsersCount)
|
||||
.then(profiles => res.json({ profiles }))
|
||||
.catch(() => res.json({ error: errors.APP_FIREBASE_DATABASE_ERROR }));
|
||||
try {
|
||||
const profiles = await profileDao.suggestNProfiles(appConfig.suggestedUsersCount);
|
||||
res.json({ profiles });
|
||||
} catch(error) {
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
updateUserProfile,
|
||||
updateUserProfileImage,
|
||||
getUserProfile,
|
||||
suggestNProfiles
|
||||
};
|
||||
@ -1,9 +1,10 @@
|
||||
const OAuth = require('oauth-1.0a');
|
||||
const OAuth = require('oauth-1.0a');
|
||||
const admin = require('firebase-admin');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const appConfig = require('../../config/app.json');
|
||||
const http = require('../../config/http');
|
||||
const errors = require('../../config/errors');
|
||||
const firebase = require('firebase-admin');
|
||||
|
||||
/**
|
||||
* Verifies if the request is valid by checking if the request has the right app secret.
|
||||
@ -55,8 +56,8 @@ function isProfileNumberValid(profileNumber, response) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: move this so other files in the socials dir can use it
|
||||
* Creates the OAuth header to be passed into a request.
|
||||
*
|
||||
* @param {Object} request { method: String, url: String, data: Object }
|
||||
* @param {Object} app { consumer: Object, token: Object }, each object is of the following { key: String, secret: String }
|
||||
* @returns { Authorization: String }
|
||||
@ -71,37 +72,38 @@ 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 {*} bucketName bucketName
|
||||
*
|
||||
* @returns {*} imageURL
|
||||
*/
|
||||
async function uploadImage(imageData, path, bucketName) {
|
||||
try {
|
||||
const bucket = firebase.storage().bucket(`gs://${bucketName}`);
|
||||
const bucket = admin.storage().bucket(`gs://${bucketName}`);
|
||||
|
||||
const file = bucket.file(`${path}.${appConfig.imageFormat[imageData.metaData.contentType]}`);
|
||||
const imageBuffer = Buffer.from(imageData.base64Data, 'base64');
|
||||
|
||||
await file.save(imageBuffer);
|
||||
const file = bucket.file(`${path}`);
|
||||
await file.save(Buffer.from(imageData, 'base64'));
|
||||
|
||||
const fileMetaData = await file.getMetadata();
|
||||
|
||||
return fileMetaData[0].mediaLink;
|
||||
|
||||
} catch (error) {
|
||||
throw error;
|
||||
console.log(error);
|
||||
throw errors.APP_FIREBASE_STORAGE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
function dbErrorHandler(error) {
|
||||
console.log(error);
|
||||
throw errors.APP_FIREBASE_DATABASE_ERROR;
|
||||
}
|
||||
|
||||
function storageErrorHandler(error) {
|
||||
console.log(error);
|
||||
throw errors.APP_FIREBASE_STORAGE_ERROR;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isAppSecretValid,
|
||||
isBodyValid,
|
||||
getSessionIdFromAuthHeader,
|
||||
isProfileNumberValid,
|
||||
createOAuthHeader,
|
||||
uploadImage
|
||||
uploadImage,
|
||||
dbErrorHandler,
|
||||
storageErrorHandler
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user