From 316fe3f7a4e84c09b8992e90b6a3b253c6e608a3 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 12:01:40 +0200 Subject: [PATCH 01/12] set up project --- package-lock.json | 34 +++++++++++++++++----------------- package.json | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3fb12fd..fe39c38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "morgan": "^1.10.0", "nodemon": "^3.0.1" }, @@ -1410,12 +1410,12 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -1423,7 +1423,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1730,9 +1730,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -2032,16 +2032,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -4013,9 +4013,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", diff --git a/package.json b/package.json index ec6510a..d8aab1f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "homepage": "https://github.com/boolean-uk/api-address-book#readme", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "morgan": "^1.10.0", "nodemon": "^3.0.1" }, From befcd3b47a274729ac54221e423a7f18f9cd5387 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 12:22:47 +0200 Subject: [PATCH 02/12] add sequence diagram --- sequence diagram.png | Bin 0 -> 56437 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sequence diagram.png diff --git a/sequence diagram.png b/sequence diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c997bb390320061f329fbc73998ed685b00e13 GIT binary patch literal 56437 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 R==Xp>x@Qf}^2 literal 0 HcmV?d00001 From c42518d264e933fa70d4dbb9c9e328e0e28c7e02 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 12:50:46 +0200 Subject: [PATCH 03/12] add basic get and post functionality --- src/server.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index 30f0ce3..204d7da 100644 --- a/src/server.js +++ b/src/server.js @@ -7,7 +7,27 @@ app.use(morgan("dev")) app.use(cors()) app.use(express.json()) -// write your app code here +const contacts = require("../data/contacts") +let idCounter = 3 + +app.get('/contacts', (req, res) => { + res.status(200).json({ + contacts + }) +}) + +app.post('/contacts', (req, res) => { + const contact = req.body + + if (contact) { + contact.id = idCounter + contacts.push(contact) + + idCounter++ + + res.status(201).json({contact}) + } +}) module.exports = app From e27a79fb2e12b1b4f1b3a8250c3d3ba5d41a6ed8 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 12:56:38 +0200 Subject: [PATCH 04/12] add get contact by id functionality --- src/server.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/server.js b/src/server.js index 204d7da..32745a4 100644 --- a/src/server.js +++ b/src/server.js @@ -30,4 +30,13 @@ app.post('/contacts', (req, res) => { } }) +app.get('/contacts/:id', (req, res) => { + const contactID = Number(req.params.id) + console.log(contactID) + + const foundContact = contacts.find((contact) => contact.id === contactID) + + res.status(200).json({contact: foundContact}) +}) + module.exports = app From a36ed4262ca6ae6bbe40be22110a835c7f60ba18 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:00:57 +0200 Subject: [PATCH 05/12] add delete contact by id functionality --- src/server.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/server.js b/src/server.js index 32745a4..33b7fdf 100644 --- a/src/server.js +++ b/src/server.js @@ -7,7 +7,7 @@ app.use(morgan("dev")) app.use(cors()) app.use(express.json()) -const contacts = require("../data/contacts") +let contacts = require("../data/contacts") let idCounter = 3 @@ -32,10 +32,17 @@ app.post('/contacts', (req, res) => { app.get('/contacts/:id', (req, res) => { const contactID = Number(req.params.id) - console.log(contactID) + const foundContact = contacts.find((contact) => contact.id === contactID) + + res.status(200).json({contact: foundContact}) +}) +app.delete('/contacts/:id', (req, res) => { + const contactID = Number(req.params.id) const foundContact = contacts.find((contact) => contact.id === contactID) + contacts = contacts.filter((contact) => contact.id !== contactID) + res.status(200).json({contact: foundContact}) }) From 3914c305392352b09b358fba7194162a83993034 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:08:43 +0200 Subject: [PATCH 06/12] add update contact by id functionality --- src/server.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/server.js b/src/server.js index 33b7fdf..5c4fd28 100644 --- a/src/server.js +++ b/src/server.js @@ -46,4 +46,17 @@ app.delete('/contacts/:id', (req, res) => { res.status(200).json({contact: foundContact}) }) +app.put('/contacts/:id', (req, res) => { + const newContactInfo = req.body + const contactID = Number(req.params.id) + const foundContact = contacts.find((contact) => contact.id === contactID) + const foundContactIndex = contacts.indexOf(foundContact) + + newContactInfo.id = contactID + + contacts.splice(foundContactIndex, 1, newContactInfo) + + res.status(200).json({contact: newContactInfo}) +}) + module.exports = app From 05d8837c30a39d81bd7dad8f6ccabace096c2d5d Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:14:11 +0200 Subject: [PATCH 07/12] add functionilty to get all meetings --- src/server.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/server.js b/src/server.js index 5c4fd28..663cf66 100644 --- a/src/server.js +++ b/src/server.js @@ -7,12 +7,13 @@ app.use(morgan("dev")) app.use(cors()) app.use(express.json()) -let contacts = require("../data/contacts") +let contacts = require("../data/contacts.js") +let meetings = require("../data/meetings.js") let idCounter = 3 app.get('/contacts', (req, res) => { - res.status(200).json({ + res.json({ contacts }) }) @@ -20,21 +21,19 @@ app.get('/contacts', (req, res) => { app.post('/contacts', (req, res) => { const contact = req.body - if (contact) { - contact.id = idCounter - contacts.push(contact) + contact.id = idCounter + contacts.push(contact) - idCounter++ + idCounter++ - res.status(201).json({contact}) - } + res.status(201).json({contact}) }) app.get('/contacts/:id', (req, res) => { const contactID = Number(req.params.id) const foundContact = contacts.find((contact) => contact.id === contactID) - res.status(200).json({contact: foundContact}) + res.json({contact: foundContact}) }) app.delete('/contacts/:id', (req, res) => { @@ -43,7 +42,7 @@ app.delete('/contacts/:id', (req, res) => { contacts = contacts.filter((contact) => contact.id !== contactID) - res.status(200).json({contact: foundContact}) + res.json({contact: foundContact}) }) app.put('/contacts/:id', (req, res) => { @@ -56,7 +55,11 @@ app.put('/contacts/:id', (req, res) => { contacts.splice(foundContactIndex, 1, newContactInfo) - res.status(200).json({contact: newContactInfo}) + res.json({contact: newContactInfo}) +}) + +app.get('/meetings', (req, res) => { + res.json({meetings}) }) module.exports = app From 0832b524abca14300970ff5314508f630a2248c8 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:23:52 +0200 Subject: [PATCH 08/12] add functionality to delete meetings by id or contact --- src/server.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/server.js b/src/server.js index 663cf66..3d6f718 100644 --- a/src/server.js +++ b/src/server.js @@ -42,6 +42,8 @@ app.delete('/contacts/:id', (req, res) => { contacts = contacts.filter((contact) => contact.id !== contactID) + meetings = meetings.filter((meeting) => meeting.contactId !== contactID) + res.json({contact: foundContact}) }) @@ -62,4 +64,20 @@ app.get('/meetings', (req, res) => { res.json({meetings}) }) +app.get('/meetings/:id', (req, res) => { + const meetingID = Number(req.params.id) + const foundMeeting = meetings.find((meeting) => meeting.id === meetingID) + + res.json({meeting: foundMeeting}) +}) + +app.delete('/meetings/:id', (req, res) => { + const meetingID = Number(req.params.id) + const foundMeeting = meetings.find((meeting) => meeting.id === meetingID) + + meetings = meetings.filter((meeting) => meeting.id !== meetingID) + + res.json({meeting: foundMeeting}) +}) + module.exports = app From 23ac5e6654b31731c40a8eb5766ed0a2472a4f20 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:34:20 +0200 Subject: [PATCH 09/12] add functionality to update meeting by contact id --- src/server.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/server.js b/src/server.js index 3d6f718..1081d8e 100644 --- a/src/server.js +++ b/src/server.js @@ -80,4 +80,19 @@ app.delete('/meetings/:id', (req, res) => { res.json({meeting: foundMeeting}) }) +app.put('/meetings/:id', (req, res) => { + const newMeetingInfo = req.body + const contactID = Number(req.params.id) + + const foundMeeting = meetings.find((meeting) => meeting.contactId === contactID) + const foundMeetingIndex = meetings.indexOf(foundMeeting) + + newMeetingInfo.id = foundMeeting.id + newMeetingInfo.contactId = contactID + + meetings.splice(foundMeetingIndex, 1, newMeetingInfo) + + res.json({meeting: newMeetingInfo}) +}) + module.exports = app From 034213a7bf0e01b85b633f694a74988d6046fa91 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:38:47 +0200 Subject: [PATCH 10/12] add functionality to get contact meetings by contact id --- src/server.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/server.js b/src/server.js index 1081d8e..97335a0 100644 --- a/src/server.js +++ b/src/server.js @@ -95,4 +95,13 @@ app.put('/meetings/:id', (req, res) => { res.json({meeting: newMeetingInfo}) }) +app.get('/contacts/:id/meetings', (req, res) => { + const contactID = Number(req.params.id) + console.log(contactID) + + const filteredMeetings = meetings.filter((meeting) => meeting.contactId === contactID) + + res.json({meetings: filteredMeetings}) +}) + module.exports = app From dd249f0526d68d1655a333e8d2ca44c3a6db7266 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 13:48:51 +0200 Subject: [PATCH 11/12] add functionality to add new meeting for contact id --- src/server.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index 97335a0..3cf06f1 100644 --- a/src/server.js +++ b/src/server.js @@ -11,6 +11,7 @@ let contacts = require("../data/contacts.js") let meetings = require("../data/meetings.js") let idCounter = 3 +let meetingIdCounter = 4 app.get('/contacts', (req, res) => { res.json({ @@ -97,11 +98,24 @@ app.put('/meetings/:id', (req, res) => { app.get('/contacts/:id/meetings', (req, res) => { const contactID = Number(req.params.id) - console.log(contactID) const filteredMeetings = meetings.filter((meeting) => meeting.contactId === contactID) res.json({meetings: filteredMeetings}) }) +app.post('/contacts/:id/meetings', (req, res) => { + const contactID = Number(req.params.id) + const meetingInfo = req.body + + meetingInfo.contactId = contactID + meetingInfo.id = meetingIdCounter + + meetings.push(meetingInfo) + + meetingIdCounter++ + + res.status(201).json({meeting: meetingInfo}) +}) + module.exports = app From 991f3021dfdd50dc55885b138e1fa4a802ba9a7d Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Mon, 17 Jun 2024 17:34:39 +0200 Subject: [PATCH 12/12] add property validation --- src/server.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/server.js b/src/server.js index 3cf06f1..2722a1b 100644 --- a/src/server.js +++ b/src/server.js @@ -22,6 +22,10 @@ app.get('/contacts', (req, res) => { app.post('/contacts', (req, res) => { const contact = req.body + if(!verifyContactProperties(contact)) { + return res.status(400).json({message: 'invalid body'}) + } + contact.id = idCounter contacts.push(contact) @@ -51,6 +55,11 @@ app.delete('/contacts/:id', (req, res) => { app.put('/contacts/:id', (req, res) => { const newContactInfo = req.body const contactID = Number(req.params.id) + + if(!verifyContactProperties(newContactInfo)) { + return res.status(400).json({message: 'invalid body'}) + } + const foundContact = contacts.find((contact) => contact.id === contactID) const foundContactIndex = contacts.indexOf(foundContact) @@ -85,6 +94,10 @@ app.put('/meetings/:id', (req, res) => { const newMeetingInfo = req.body const contactID = Number(req.params.id) + if(!verifyMeetingProperties(newMeetingInfo)) { + return res.status(400).json({message: 'invalid body'}) + } + const foundMeeting = meetings.find((meeting) => meeting.contactId === contactID) const foundMeetingIndex = meetings.indexOf(foundMeeting) @@ -108,6 +121,10 @@ app.post('/contacts/:id/meetings', (req, res) => { const contactID = Number(req.params.id) const meetingInfo = req.body + if(!verifyMeetingProperties(meetingInfo)) { + return res.status(400).json({message: 'invalid body'}) + } + meetingInfo.contactId = contactID meetingInfo.id = meetingIdCounter @@ -118,4 +135,26 @@ app.post('/contacts/:id/meetings', (req, res) => { res.status(201).json({meeting: meetingInfo}) }) +function verifyContactProperties(object) { + const neededProperties = ['firstName', 'lastName', 'street', 'city', 'type', 'email', 'linkedin', 'twitter'] + + for (const item of neededProperties) { + if (object[item] === undefined) { + return false + } + } + + return true +} + +function verifyMeetingProperties(object) { + const neededProperties = 'name' + + if (object[neededProperties] === undefined) { + return false + } + + return true +} + module.exports = app