From 72a09dab3a05b95ddf305540398d684250c7355c Mon Sep 17 00:00:00 2001 From: lukew3 Date: Sat, 22 May 2021 09:56:51 -0400 Subject: [PATCH] Added config save --- backend/models/user.js | 1 + backend/mongo-todo.md | 14 ++++--- backend/server.js | 90 +++++++++++++++++++++++++++++++++++++++-- functions/index.js | 91 ------------------------------------------ src/js/db.js | 2 +- 5 files changed, 96 insertions(+), 102 deletions(-) diff --git a/backend/models/user.js b/backend/models/user.js index 0363e12ea..b065cefe5 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -78,6 +78,7 @@ const userSchema = new Schema( email: { type: String, required: true }, password: { type: String, required: true }, refreshTokens: [{ type: String, required: true }], + config: { type: Schema.Types.Mixed, default: {} }, }, { timestamps: true, diff --git a/backend/mongo-todo.md b/backend/mongo-todo.md index a8782fff1..539e94f32 100644 --- a/backend/mongo-todo.md +++ b/backend/mongo-todo.md @@ -9,14 +9,16 @@ - should be objects that are set on new pb - Move user data to localstorage instead of cookies - Result is duplicated in analytics + - Does entire result need to be stored in analytics + - Should result be stored in seperate collection and then referenced in user doc and analytics? +- Loader should hide after tag is added, deleted, or edited +- Fix localhost, production, development server detection - - Should results be moved to a seperate collection + - Should be a setting in the .env - - Does the entire test need to be in the analytics collection? - - - make sure refresh token won't expire - - make refresh token expire after session if don't remeber me is set? - - Keep jwt and refresh in cookies? +- make sure refresh token won't expire + - make refresh token expire after session if don't remeber me is set? +- Keep jwt and refresh in cookies? - Get somebody else to check over security due to my lack of expertise diff --git a/backend/server.js b/backend/server.js index 35cb7829a..b04b65bb5 100644 --- a/backend/server.js +++ b/backend/server.js @@ -834,10 +834,92 @@ app.get("/api/userResults", authenticateToken, (req, res) => { res.sendStatus(200); }); -app.post("/api/saveConfig", (req, res) => { - const config = req.body.config; - //parse config object to prevent errors - //save passed config object to database +function isConfigKeyValid(name) { + if (name === null || name === undefined || name === "") return false; + if (name.length > 30) return false; + return /^[0-9a-zA-Z_.\-#+]+$/.test(name); +} + +app.post("/api/saveConfig", authenticateToken, (req, res) => { + try { + if (req.name === undefined || req.body.obj === undefined) { + console.error(`error saving config for ${req.name} - missing input`); + return { + resultCode: -1, + message: "Missing input", + }; + } + + let obj = req.body.obj; + let errorMessage = ""; + let err = false; + Object.keys(obj).forEach((key) => { + if (err) return; + if (!isConfigKeyValid(key)) { + err = true; + console.error(`${key} failed regex check`); + errorMessage = `${key} failed regex check`; + } + if (err) return; + if (key === "resultFilters") return; + if (key === "customBackground") return; + let val = obj[key]; + if (Array.isArray(val)) { + val.forEach((valarr) => { + if (!isConfigKeyValid(valarr)) { + err = true; + console.error(`${key}: ${valarr} failed regex check`); + errorMessage = `${key}: ${valarr} failed regex check`; + } + }); + } else { + if (!isConfigKeyValid(val)) { + err = true; + console.error(`${key}: ${val} failed regex check`); + errorMessage = `${key}: ${val} failed regex check`; + } + } + }); + if (err) { + console.error( + `error saving config for ${request.uid} - bad input - ${JSON.stringify( + request.obj + )}` + ); + return { + resultCode: -1, + message: "Bad input. " + errorMessage, + }; + } + + User.findOne({ name: req.name }, (err, user) => { + if (err) res.status(500).send({ error: err }); + user.config = obj; + //what does {merge: true} do in firebase + user.save(); + }) + .then(() => { + return { + resultCode: 1, + message: "Saved", + }; + }) + .catch((e) => { + console.error( + `error saving config to DB for ${req.name} - ${e.message}` + ); + return { + resultCode: -1, + message: e.message, + }; + }); + } catch (e) { + console.error(`error saving config for ${req.name} - ${e}`); + return { + resultCode: -999, + message: e, + }; + } }); /* diff --git a/functions/index.js b/functions/index.js index 1fe5571af..1e142fc20 100644 --- a/functions/index.js +++ b/functions/index.js @@ -796,97 +796,6 @@ exports.updateResultTags = functions.https.onCall((request, response) => { } }); -function isConfigKeyValid(name) { - if (name === null || name === undefined || name === "") return false; - if (name.length > 30) return false; - return /^[0-9a-zA-Z_.\-#+]+$/.test(name); -} - -exports.saveConfig = functions.https.onCall((request, response) => { - try { - if (request.uid === undefined || request.obj === undefined) { - console.error(`error saving config for ${request.uid} - missing input`); - return { - resultCode: -1, - message: "Missing input", - }; - } - - let obj = request.obj; - let errorMessage = ""; - let err = false; - Object.keys(obj).forEach((key) => { - if (err) return; - if (!isConfigKeyValid(key)) { - err = true; - console.error(`${key} failed regex check`); - errorMessage = `${key} failed regex check`; - } - if (err) return; - if (key === "resultFilters") return; - if (key === "customBackground") return; - let val = obj[key]; - if (Array.isArray(val)) { - val.forEach((valarr) => { - if (!isConfigKeyValid(valarr)) { - err = true; - console.error(`${key}: ${valarr} failed regex check`); - errorMessage = `${key}: ${valarr} failed regex check`; - } - }); - } else { - if (!isConfigKeyValid(val)) { - err = true; - console.error(`${key}: ${val} failed regex check`); - errorMessage = `${key}: ${val} failed regex check`; - } - } - }); - if (err) { - console.error( - `error saving config for ${request.uid} - bad input - ${JSON.stringify( - request.obj - )}` - ); - return { - resultCode: -1, - message: "Bad input. " + errorMessage, - }; - } - - return db - .collection(`users`) - .doc(request.uid) - .set( - { - config: obj, - }, - { merge: true } - ) - .then((e) => { - return { - resultCode: 1, - message: "Saved", - }; - }) - .catch((e) => { - console.error( - `error saving config to DB for ${request.uid} - ${e.message}` - ); - return { - resultCode: -1, - message: e.message, - }; - }); - } catch (e) { - console.error(`error saving config for ${request.uid} - ${e}`); - return { - resultCode: -999, - message: e, - }; - } -}); - exports.addPreset = functions.https.onCall(async (request, response) => { try { if (!isTagPresetNameValid(request.obj.name)) { diff --git a/src/js/db.js b/src/js/db.js index 03ffb815e..f95a8c66a 100644 --- a/src/js/db.js +++ b/src/js/db.js @@ -441,7 +441,7 @@ export async function saveConfig(config) { AccountButton.loading(true); axiosInstance .post("/api/saveConfig", { - uid: currentUser().uid, + obj: config, }) .then((response) => { AccountButton.loading(false);