diff --git a/utils/connectApp.js b/utils/connectApp.js index 492aee54..bafdf978 100644 --- a/utils/connectApp.js +++ b/utils/connectApp.js @@ -1,5 +1,5 @@ const { getResponseJSON, setHeadersDomainRestricted, getUserProfile } = require('./shared'); -const { recruitSubmit, submitSocial, getUserSurveys, getUserCollections } = require('./submission'); +const { submit, submitSocial, getUserSurveys, getUserCollections } = require('./submission'); const { retrieveNotifications, sendEmailLink } = require('./notifications'); const { validateToken, generateToken, updateParticipantFirebaseAuthentication, validateUsersEmailPhone } = require('./validation'); @@ -37,9 +37,23 @@ const connectApp = async (req, res) => { console.log(`PWA API: ${api}, called from uid: ${uid}`); try { - if (api === 'submit') return await recruitSubmit(req, res, uid); + if (api === 'submit') { - if (api === 'submitSocial') return submitSocial(req, res, uid); + if (req.method !== 'POST') { + return res.status(405).json(getResponseJSON('Only POST requests are accepted!', 405)); + } + + const body = req.body; + + if (!body || Object.keys(body).length === 0) { + return res.status(400).json(getResponseJSON('Bad request!', 400)); + } + + // all 'submit' paths return res.status(code).json({ message, code }); + return await submit(res, body, uid); + } + + else if (api === 'submitSocial') return submitSocial(req, res, uid); else if (api === 'getUserProfile') return getUserProfile(req, res, uid); diff --git a/utils/firestore.js b/utils/firestore.js index 0cebeb45..92a373fc 100644 --- a/utils/firestore.js +++ b/utils/firestore.js @@ -101,16 +101,17 @@ const updateResponse = async (data, uid) => { try{ const snapshot = await db.collection('participants').where('state.uid', '==', uid).get(); printDocsCount(snapshot, "updateResponse"); - if(snapshot.size === 1) { - for(let doc of snapshot.docs){ - await db.collection('participants').doc(doc.id).update(data); - return true; - } + + if (snapshot.size !== 1) { + throw new Error(`updateResponse expected 1 document, found ${snapshot.size}. uid: ${uid}`); } + + await snapshot.docs[0].ref.update(data); + return true; } catch(error){ - console.error(error); - return new Error(error) + console.error(`Error in updateResponse: ${error}`); + return new Error(`Error in updateResponse: ${error}`); } } diff --git a/utils/shared.js b/utils/shared.js index b978ce07..dd895e5f 100644 --- a/utils/shared.js +++ b/utils/shared.js @@ -784,7 +784,7 @@ const cleanSurveyData = (data) => { const admin = require('firebase-admin'); Object.keys(data).forEach(key => { - if(data[key] === null) { + if (data[key] === null || data[key] === undefined) { data[key] = admin.firestore.FieldValue.delete(); } }); diff --git a/utils/submission.js b/utils/submission.js index 326fc271..c07cc65a 100644 --- a/utils/submission.js +++ b/utils/submission.js @@ -1,96 +1,90 @@ -const { getResponseJSON, setHeaders, logIPAddress } = require('./shared'); +const { cleanSurveyData, getResponseJSON, lockedAttributes, setHeaders, logIPAddress, moduleConceptsToCollections, moduleStatusConcepts } = require('./shared'); +const { updateResponse } = require('./firestore'); const fieldMapping = require('./fieldToConceptIdMapping'); const submit = async (res, data, uid) => { - // Remove locked attributes. - const { lockedAttributes } = require('./shared'); lockedAttributes.forEach(atr => delete data[atr]); - // generate Connect_ID if Consent form submitted - if(data[919254129] !== undefined && data[919254129] === 353358909) { - const { generateConnectID } = require('./shared'); - const { sanityCheckConnectID } = require('./firestore'); - let boo = false; - let Connect_ID; - while(boo === false){ - const ID = generateConnectID(); - const response = await sanityCheckConnectID(ID); - if(response === true) { - Connect_ID = ID; - boo = true; + try { + // generate Connect_ID if Consent form submitted + if(data[919254129] !== undefined && data[919254129] === 353358909) { + const { generateConnectID } = require('./shared'); + const { sanityCheckConnectID } = require('./firestore'); + let boo = false; + let Connect_ID; + while(boo === false){ + const ID = generateConnectID(); + const response = await sanityCheckConnectID(ID); + if(response === true) { + Connect_ID = ID; + boo = true; + } } + data = {...data, Connect_ID} } - data = {...data, Connect_ID} - } - - let keys = Object.keys(data); - // check if submitting survey - if (keys.length === 1) { + let keys = Object.keys(data); - const { moduleConceptsToCollections } = require('./shared'); + // check if submitting survey + if (keys.length === 1) { + let key = keys[0]; + let collection = moduleConceptsToCollections[key]; - let key = keys[0]; - let collection = moduleConceptsToCollections[key]; - - if(collection) { - let moduleData = data[key]; - return await submitSurvey(res, moduleData, collection, uid) + if(collection) { + let moduleData = data[key]; + return await submitSurvey(res, moduleData, collection, uid) + } } - } - - const { cleanSurveyData } = require('./shared'); - data = cleanSurveyData(data); - - const { updateResponse } = require('./firestore'); - const response = await updateResponse(data, uid); - if (response) { - let moduleComplete = false; - let calculateScores = false; + data = cleanSurveyData(data); - keys.forEach(key => { - const { moduleStatusConcepts } = require('./shared'); + // response is either true or an Error object + const response = await updateResponse(data, uid); + if (response) { + let moduleComplete = false; + let calculateScores = false; - if (moduleStatusConcepts[key] && data[key] === 231311385) { - moduleComplete = true; + keys.forEach(key => { + if (moduleStatusConcepts[key] && data[key] === 231311385) { + moduleComplete = true; - if (key === '320303124') { - calculateScores = true; + if (key === '320303124') { + calculateScores = true; + } } - } - }) - - if(moduleComplete) { + }) - const { checkDerivedVariables } = require('./validation'); - const { getTokenForParticipant, retrieveUserProfile } = require('./firestore'); + if (moduleComplete) { + const { checkDerivedVariables } = require('./validation'); + const { getTokenForParticipant, retrieveUserProfile } = require('./firestore'); - const participant = await retrieveUserProfile(uid); - const siteCode = participant['827220437']; - const token = await getTokenForParticipant(uid); + const participant = await retrieveUserProfile(uid); + const siteCode = participant['827220437']; + const token = await getTokenForParticipant(uid); - await checkDerivedVariables(token, siteCode); + await checkDerivedVariables(token, siteCode); - if (calculateScores) { + if (calculateScores) { - //remove condition once implemented in dev tier - if (process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-stg-5519' || process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-prod-6d04') { - const { processPromisResults } = require('./promis'); - processPromisResults(uid); + //remove condition once implemented in dev tier + if (process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-stg-5519' || process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-prod-6d04') { + const { processPromisResults } = require('./promis'); + processPromisResults(uid); + } } } } + + if (response instanceof Error) { + return res.status(500).json(getResponseJSON(response.message, 500)); + } + return res.status(200).json(getResponseJSON('Data stored successfully!', 200)); + + } catch (error) { + console.error('Error in submit:', error); + return res.status(500).json(getResponseJSON(error.message, 500)); } - - if(response instanceof Error){ - return res.status(500).json(getResponseJSON(response.message, 500)); - } - if(!response) { - return res.status(500).json(getResponseJSON("Can't add/update data!", 500)); - } - return res.status(200).json(getResponseJSON('Data stored successfully!', 200)); }; const submitSurvey = async (res, data, collection, uid) => { @@ -129,18 +123,6 @@ const submitSurvey = async (res, data, collection, uid) => { return res.status(200).json(getResponseJSON('Survey data stored successfully!', 200)); } -const recruitSubmit = async (req, res, uid) => { - if(req.method !== 'POST') { - return res.status(405).json(getResponseJSON('Only POST requests are accepted!', 405)); - } - - const data = req.body; - if(Object.keys(data).length <= 0){ - return res.status(400).json(getResponseJSON('Bad request!', 400)); - } - return await submit(res, data, uid); -} - const submitSocial = async (req, res, uid) => { if (req.method !== 'POST') { @@ -744,7 +726,6 @@ const getTextAndVersionNumberFromGitHubCommit = async (sha, path, token) => { module.exports = { submit, - recruitSubmit, submitSocial, getFilteredParticipants, getParticipants,