Created
June 9, 2017 05:29
-
-
Save rockchalkwushock/55a208af39aa91cf2b89daacc4b4a491 to your computer and use it in GitHub Desktop.
Explanation of code for Rhonda
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // The createNote conroller | |
| // @see https://github.com/rockchalkwushock/note_dashboard/blob/master/api/modules/note/controller.js#L49 | |
| export const createNote = async (req, res, next) => { | |
| const filteredBody = filterBody(req.body, config.WHITELIST.notes.create) | |
| try { | |
| const note = await Note.createNote(filteredBody, req.user._id) | |
| return res.status(HTTPStatus.CREATED).json(note) | |
| } catch (e) { | |
| e.status = HTTPStatus.BAD_REQUEST | |
| /* istanbul ignore next */ | |
| return next(e) | |
| } | |
| } | |
| /* | |
| So createNote is a function expression that is going to run asynchronously meaning this is a promise. | |
| It takes in 3 params: | |
| - request - the http request submitted by the user. | |
| - response - the http response object we will modify and send back to the user. | |
| - next - a funciton that handles the finalization of the promise. | |
| @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next | |
| The first thing we do is take the data being submitted by the user in req.body & send it as a param to the | |
| filterBody() method with the keys that we have whitelisted as the second param. This method will return an | |
| object that is the data we expected from the user and nothing more (no malicious key/value pairs). | |
| We now enter the try/catch block. We are going to pause the function and await the data that will | |
| be returned from the method on our Note model because it is a promise. We store that data in | |
| a variable to send back to the user. | |
| The await keyword is just pausing the function and waiting for the promise to resolve or reject. Should the promise reject | |
| the catch block will 'catch' the error & add the status key/value pair to the error object which will be returned to the user. | |
| If the promise resloves then we return the success object to the user & the data has been created on the database. | |
| */ | |
| // Whitelist | |
| // @see https://github.com/rockchalkwushock/note_dashboard/blob/master/api/configs/configuration.js#L9 | |
| /* | |
| These are the properties we are expecting on the req.body object. | |
| And the ONLY properties we are going to let through to the server | |
| via the filterBody() method. | |
| */ | |
| const WHITELIST = { | |
| notes: { | |
| create: ['text', 'title'], | |
| } | |
| } | |
| // filterBody() | |
| // @see https://github.com/rockchalkwushock/note_dashboard/blob/master/api/utils/filterBody.js#L18 | |
| export const filterBody = (body, whitelist) => { | |
| const items = {}; | |
| /* | |
| Example: | |
| body: { | |
| text: "foo", | |
| title: "bar", | |
| malicious: "virus" | |
| } | |
| */ | |
| // take req.body & give me back an array of the keys | |
| // i.e. ["text", "title", "malicious"] | |
| // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys | |
| Object.keys(body).forEach(key => { | |
| /* | |
| Whitelist: | |
| create: ["text", "title"] | |
| */ | |
| /* | |
| Does the key from body exist in the whitelist? | |
| If yes then indexOf evaluates to >= 0 | |
| If no then indexOf evaluates to -1 and this key/value is not added to items. | |
| */ | |
| // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf?v=example | |
| if (whitelist.indexOf(key) >= 0) { | |
| /* | |
| NOTE: body.text evaluates to the value stored at that key! | |
| Iteration 1: items.text = body.text | |
| Iteration 2: items.title = body.title | |
| Iteration 3: FAIL not present in whitelist evaluates as -1 which fails the if block. | |
| */ | |
| items[key] = body[key]; | |
| } | |
| }); | |
| // Return the object of filtered key/value pairs. | |
| return items; | |
| } | |
| // Note.createNote() | |
| // @see https://github.com/rockchalkwushock/note_dashboard/blob/master/api/modules/note/model.js#L41 | |
| NoteSchema.statics = { | |
| /* | |
| take the filtered object & add the author value to it | |
| then we pass this object to the create method that is native | |
| to mongoose, creating the document in the database. | |
| @see http://mongoosejs.com/docs/api.html#model_Model.create | |
| NOTE: to create a note there must be an author because this is | |
| an auth protected route if the userId present does not match our | |
| database or their is no userId present this method will fail and | |
| not add data (possibly malicious) to our database. | |
| */ | |
| createNote(args, userId) { | |
| return this.create({ | |
| ...args, | |
| author: userId, | |
| }) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment