From f5222edd99beec6088ab825fd0683b2c8f2367da Mon Sep 17 00:00:00 2001 From: obafemi oderanti Date: Wed, 10 Jun 2020 10:38:58 +0100 Subject: [PATCH 1/8] update getplaces endpoint --- fasta-backend/routes/location-transporter.js | 18 ++++++++++++++++-- fasta-backend/routes/tripInfo.js | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fasta-backend/routes/location-transporter.js b/fasta-backend/routes/location-transporter.js index e70851d..0cbc978 100644 --- a/fasta-backend/routes/location-transporter.js +++ b/fasta-backend/routes/location-transporter.js @@ -12,7 +12,9 @@ const Transporters = require("../api/transporters-api"); const ScheduleTrip = require("../models/trip"); const authChecker = require("../middlewares/authChecker"); - +const key= "AIzaSyAm00Wsdh6jJB2QzlW5c6t_nu0gMRAZB9s"; +const distancePath = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&"; +const placesPath = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="; const router = express.Router(); // api to get nearby transporters base on users location @@ -174,5 +176,17 @@ router.get("/trips/:id", authChecker, async (req, res) => { }); }); - +router.get("/getplaces/:place", async (req, res) => { + console.log(req.params); + const { val } = req.params; + const placesUrl = `${placesPath}${val}&key=${key}`; + + try { + const place = await fetch(placesUrl); + const placeResponse = await place.json(); + return placeResponse; + } catch (e) { + console.log(e); + } +}) module.exports = router; diff --git a/fasta-backend/routes/tripInfo.js b/fasta-backend/routes/tripInfo.js index 2e299d1..3653d29 100644 --- a/fasta-backend/routes/tripInfo.js +++ b/fasta-backend/routes/tripInfo.js @@ -1,7 +1,7 @@ /* eslint-disable no-unused-vars */ /* eslint-disable consistent-return */ const express = require("express"); -const { PolyUtil } = require("node-geometry-library"); +// const { PolyUtil } = require("node-geometry-library"); const ScheduleTrip = require("../models/trip"); const Reports = require("../models/report"); From 6bcc271149cb50fc894ac518e3b4193753034777 Mon Sep 17 00:00:00 2001 From: obafemi oderanti Date: Wed, 10 Jun 2020 13:54:59 +0100 Subject: [PATCH 2/8] submission --- fasta-backend/routes/location-transporter.js | 38 ++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/fasta-backend/routes/location-transporter.js b/fasta-backend/routes/location-transporter.js index 0cbc978..b02a633 100644 --- a/fasta-backend/routes/location-transporter.js +++ b/fasta-backend/routes/location-transporter.js @@ -11,12 +11,15 @@ const TripInfo = require("../api/transporters-api"); const Transporters = require("../api/transporters-api"); const ScheduleTrip = require("../models/trip"); const authChecker = require("../middlewares/authChecker"); +const dotenv = require("dotenv"); +dotenv.config(); -const key= "AIzaSyAm00Wsdh6jJB2QzlW5c6t_nu0gMRAZB9s"; const distancePath = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&"; const placesPath = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="; const router = express.Router(); +console.log((process.env.TEST_KEY ? "keyTrue" : "keyFalse")); + // api to get nearby transporters base on users location router.post("/location-transporter", (req, res) => { const trip = new TripInfo(req.body.latitude, req.body.longitude, req.body.method); @@ -36,14 +39,16 @@ router.post("/trip-distance", async (req, res) => { `https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=${origin}&destinations=${destination}&key=${ process.env.TEST_KEY }` - ) + ) .then((response) => { - if (response.data.rows.length <= 0) { - return res.json({ error: response.data.error_message }); - } + // if (response.data.rows.length <= 0) { + // return res.json({ error: response.data.error_message }); + // } const result = response.data.rows[0].elements[0]; const { distance, duration } = result; - return res.json({ data: { distance: distance.text, duration: duration.text } }); + // return res.json({ data: { distance: distance.text, duration: duration.text } }); + console.log(response); + return res.json({ response }); // return res.json({ data: { result } }); // console.log(response); }) @@ -176,17 +181,22 @@ router.get("/trips/:id", authChecker, async (req, res) => { }); }); -router.get("/getplaces/:place", async (req, res) => { - console.log(req.params); +router.get("/getplaces/:val", async (req, res) => { const { val } = req.params; - const placesUrl = `${placesPath}${val}&key=${key}`; + console.log(req.params, val); + const placesUrl = `${placesPath}${val}&key=${process.env.TEST_KEY}`; try { - const place = await fetch(placesUrl); - const placeResponse = await place.json(); - return placeResponse; + await axios + .get(placesUrl) + .then((response) => { + console.log(response); + return res.json({response}); + }) + .catch((e) => console.log(e)); } catch (e) { - console.log(e); + res.status(500).json({ e: e.message }); } -}) +}); + module.exports = router; From 54e3a838954c97854f61c54b1b3e117985457573 Mon Sep 17 00:00:00 2001 From: obafemi oderanti Date: Tue, 16 Jun 2020 12:50:44 +0100 Subject: [PATCH 3/8] move googleapis calls to backend --- fasta-backend/api/transporters-api.js | 5 +- fasta-backend/routes/location-transporter.js | 60 ++++++++++++++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/fasta-backend/api/transporters-api.js b/fasta-backend/api/transporters-api.js index 0c6f893..2543122 100644 --- a/fasta-backend/api/transporters-api.js +++ b/fasta-backend/api/transporters-api.js @@ -8,14 +8,15 @@ const https = require("https"); const options = { hostname: "maps.googleapis.com", port: 443, - path: `/maps/api/place/textsearch/json?query=transport&location=${this.latitude},${this.longitude}&radius=10000&key=AIzaSyDg-6GC6doxzpE_etI9E-yJR2NOLyFzBYc`, + // path: `/maps/api/place/textsearch/json?query=transport&location=${this.latitude},${this.longitude}&radius=10000&key=AIzaSyDg-6GC6doxzpE_etI9E-yJR2NOLyFzBYc`, + path: `/maps/api/place/textsearch/json?query=transport&location=${this.latitude},${this.longitude}&radius=10000&key=AIzaSyAm00Wsdh6jJB2QzlW5c6t_nu0gMRAZB9s`, method: "GET" }; // Allow function to receive coordinate argument from client class GetTripInfo { constructor(latitude, longitude, method) { - this.latitude = latitude; + this.latitude = latitude; this.longitude = longitude; this.method = method; } diff --git a/fasta-backend/routes/location-transporter.js b/fasta-backend/routes/location-transporter.js index b02a633..d72822b 100644 --- a/fasta-backend/routes/location-transporter.js +++ b/fasta-backend/routes/location-transporter.js @@ -16,6 +16,9 @@ dotenv.config(); const distancePath = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&"; const placesPath = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="; +const transporterPath = `https://maps.googleapis.com/maps/api/place/textsearch/json?location`; +const locationStr = "=&radius=1000&sensor=true&query=transport&key="; + const router = express.Router(); console.log((process.env.TEST_KEY ? "keyTrue" : "keyFalse")); @@ -24,8 +27,10 @@ console.log((process.env.TEST_KEY ? "keyTrue" : "keyFalse")); router.post("/location-transporter", (req, res) => { const trip = new TripInfo(req.body.latitude, req.body.longitude, req.body.method); const locationTrnasporter = trip.getPlaces(); - +console.log(locationTrnasporter); locationTrnasporter.then((data) => { +console.log(data); + res.send({ data }); }); }); @@ -177,7 +182,7 @@ router.get("/trips/:id", authChecker, async (req, res) => { response: trip }); }).catch((e) => { - res.status(500).json({ e: e.message }); + return res.status(500).json({ e: e.message }); }); }); @@ -190,13 +195,56 @@ router.get("/getplaces/:val", async (req, res) => { await axios .get(placesUrl) .then((response) => { - console.log(response); - return res.json({response}); + // console.log(response.data); + return res.json(response.data); }) - .catch((e) => console.log(e)); + .catch((e) => { + return res.status(500).json({ e: e.message }); + }); } catch (e) { - res.status(500).json({ e: e.message }); + return res.status(500).json({ e: e.message }); } }); + +router.post("/getdistances/", async (req, res) => { + const { origin, destination } = req.body; + console.log(req.body); + const distancesUrl = `${distancePath}origins=${origin.lat},${origin.lng}&destinations=${destination.lat},${destination.lng}&key=${process.env.TEST_KEY}`; + + try { + await axios + .get(distancesUrl) + .then((response) => { + // console.log(response.data); + return res.json(response.data); + }) + .catch((e) => { + return res.status(500).json({ e: e.message }); + }); + } catch (e) { + return res.status(500).json({ e: e.message }); + } +}); + +router.post("/gettransporters", async (req, res) => { + const { origin } = req.body; + console.log(req.body); + const transportersUrl = `${transporterPath}${origin.lat},${origin.lng}${locationStr}${process.env.TEST_KEY}`; + + try { + await axios + .get(transportersUrl) + .then((response) => { + // console.log(response.data); + return res.json(response.data); + }) + .catch((e) => { + return res.status(500).json({ e: e.message }); + }); + } catch (e) { + return res.status(500).json({ e: e.message }); + } +}); + module.exports = router; From dac9e38134bfeb5474732aa8a9b696e71b888fe2 Mon Sep 17 00:00:00 2001 From: obafemi Date: Tue, 7 Jul 2020 21:33:12 +0100 Subject: [PATCH 4/8] push notification implemented --- fasta-backend/app.js | 2 +- fasta-backend/package-lock.json | 115 ++++++++++++++++++++++++++++++++ fasta-backend/package.json | 3 +- fasta-backend/routes/index.js | 15 ++++- 4 files changed, 131 insertions(+), 4 deletions(-) diff --git a/fasta-backend/app.js b/fasta-backend/app.js index 8cac3a2..c08572f 100644 --- a/fasta-backend/app.js +++ b/fasta-backend/app.js @@ -4,7 +4,7 @@ const cookieParser = require("cookie-parser"); const logger = require("morgan"); const bodyParser = require("body-parser"); const dotenv = require("dotenv"); - +const webpush = require("web-push"); dotenv.config(); diff --git a/fasta-backend/package-lock.json b/fasta-backend/package-lock.json index c3ab3c3..43863a5 100644 --- a/fasta-backend/package-lock.json +++ b/fasta-backend/package-lock.json @@ -136,6 +136,29 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==" }, + "agent-base": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", + "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "agentkeepalive": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.2.tgz", @@ -278,6 +301,17 @@ "safer-buffer": "~2.1.0" } }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -366,6 +400,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -1623,6 +1662,14 @@ "sshpk": "^1.7.0" } }, + "http_ece": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.1.0.tgz", + "integrity": "sha512-bptAfCDdPJxOs5zYSe7Y3lpr772s1G346R4Td5LgRUeCwIGpCGDUTJxRrhTNcAXbx37spge0kWEIH7QAYWNTlA==", + "requires": { + "urlsafe-base64": "~1.0.0" + } + }, "httpntlm": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", @@ -1642,6 +1689,30 @@ "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q=" }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -2184,6 +2255,11 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3632,6 +3708,11 @@ "prepend-http": "^2.0.0" } }, + "urlsafe-base64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", + "integrity": "sha1-I/iQaabGL0bPOh07ABac77kL4MY=" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -3667,6 +3748,40 @@ "extsprintf": "^1.2.0" } }, + "web-push": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.4.4.tgz", + "integrity": "sha512-tB0F+ccobsfw5jTWBinWJKyd/YdCdRbKj+CFSnsJeEgFYysOULvWFYyeCxn9KuQvG/3UF1t3cTAcJzBec5LCWA==", + "requires": { + "asn1.js": "^5.3.0", + "http_ece": "1.1.0", + "https-proxy-agent": "^5.0.0", + "jws": "^4.0.0", + "minimist": "^1.2.5", + "urlsafe-base64": "^1.0.0" + }, + "dependencies": { + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + } + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/fasta-backend/package.json b/fasta-backend/package.json index 6fd881c..05cb854 100644 --- a/fasta-backend/package.json +++ b/fasta-backend/package.json @@ -28,7 +28,8 @@ "nodemailer": "^6.4.6", "nodemailer-smtp-transport": "^2.7.4", "reverse-geocoding": "^3.0.2", - "reverse-geocoding-google": "^1.1.0" + "reverse-geocoding-google": "^1.1.0", + "web-push": "^3.4.4" }, "devDependencies": { "nodemon": "^2.0.3" diff --git a/fasta-backend/routes/index.js b/fasta-backend/routes/index.js index 459c834..15eaa49 100644 --- a/fasta-backend/routes/index.js +++ b/fasta-backend/routes/index.js @@ -1,8 +1,19 @@ - const express = require("express"); - const router = express.Router(); +const webpush = require("web-push"); + +console.log(process.env.VAPID_PUBLIC_KEY); +webpush.setVapidDetails("mailto:thevetdoctor@gmail.com", process.env.VAPID_PUBLIC_KEY, process.env.VAPID_PRIVATE_KEY); + router.get("/", (req, res) => res.status(200).json({ message: "Welcome to FASTA, taking you faster in safety & convenience!" })); +router.post("/subscribe", (req, res) => { + const subscription = req.body; + + const payload = JSON.stringify({ title: "Push test"}); + webpush.sendNotification(subscription, payload).catch(err => console.log(err)); + res.status(201).json({message: "Push sent"}); +}); + module.exports = router; From fe26dfd6aa79c05c5d99303cc2176c8c72105975 Mon Sep 17 00:00:00 2001 From: obafemi Date: Tue, 7 Jul 2020 22:21:04 +0100 Subject: [PATCH 5/8] track public dir --- fasta-backend/public/car.png | Bin 0 -> 660 bytes fasta-backend/public/index.html | 14 +++++++++ fasta-backend/public/pushClient.js | 47 +++++++++++++++++++++++++++++ fasta-backend/public/worker.js | 11 +++++++ 4 files changed, 72 insertions(+) create mode 100644 fasta-backend/public/car.png create mode 100644 fasta-backend/public/index.html create mode 100644 fasta-backend/public/pushClient.js create mode 100644 fasta-backend/public/worker.js diff --git a/fasta-backend/public/car.png b/fasta-backend/public/car.png new file mode 100644 index 0000000000000000000000000000000000000000..da5275b5e0708a1001ca3ccd863f2398ac54b767 GIT binary patch literal 660 zcmV;F0&D$=P)K~z|U?Um1K6G0rs-<$11lwie852bhzGzwk{B3LlJ_$P?h zntBMx?j@iIigzhOATt3;F6l)Op;u4d1b^Losl66bj7TXe*<`;S%tFyjvb#|P%{$HR zynXKj^W9xwrkVbCagw1@sT_A4=dA0xZkpgQ48y@-@S)jke#s2r`+kw+D*y{=%8zJY zDRs48ukY9lb7SeqI{+3)z7&y9X_`r%5|L|B6x{_-vHENq)oS%v7>0WQ=(_G=tycS* z2B2In=kodd9ssA;>n+-jLfHcP{r(LACrLg{TMhv2cKaKEX8=yPu6y0)vjT|7Isimb zw3)U%7RmV8b*pF8%^(QQ0N4evV~jbU6=0aP4d4RFb6V@&pZ7-&p@`ffNdO(+_wP*u z0N^74Mp0A-@Gubo$(zGviDYR?fTNke0N7^W^zSH5l4%{np*kXRh2%VdjTB{%NY0a7 z0kA*LI2J%eT8&2It=9UW)9Ks?aG0R{uuv#G&{`j8t=|A>WdV2s&NN)<^ilU&W3Gt*4}w!Q=MaGtZ<&z7420000 + + + + + Push Notifications for FASTA + + +

Welcome to FASTA

+ +

Push Notifications being implemented for FASTA...

Check out version 1 of the FASTA API

+ + + \ No newline at end of file diff --git a/fasta-backend/public/pushClient.js b/fasta-backend/public/pushClient.js new file mode 100644 index 0000000..616e2d2 --- /dev/null +++ b/fasta-backend/public/pushClient.js @@ -0,0 +1,47 @@ +const VAPID_PUBLIC_KEY = "BMntNKURDsrT_FV7D8Nn8nXZWn_J62wMMrjzXGuoiXBscvPqzckV8c4RKUCmJzjAKWez2LUbD11OWMhcUy6GwWA"; + +// check for service Worker +if("serviceWorker" in navigator) { + send().catch(err => console.log(err)); +} + +// Register SW, Regisster Push, Send Push +async function send() { +// Register SW + console.log("Registering service worker..."); + const register = await navigator.serviceWorker.register("/worker.js", {scope: "/"}); + console.log("Service Worker Registered"); + +// Register Push + console.log("Registering Push..."); + const subscription = await register.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) + }); + console.log("Push Registered..."); + + // Send Push Notification + console.log("Sending Push..."); + await fetch("api/v1/subscribe", { + method: "POST", + body: JSON.stringify(subscription), + headers: { + "content-type": "application/json" + } + }); +} + +function urlBase64ToUint8Array(base64String) { + const padding = "=".repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/\-/g, "+") + .replace(/_/g, "/"); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +} \ No newline at end of file diff --git a/fasta-backend/public/worker.js b/fasta-backend/public/worker.js new file mode 100644 index 0000000..81726e4 --- /dev/null +++ b/fasta-backend/public/worker.js @@ -0,0 +1,11 @@ +console.log("Service worker loaded!"); + +self.addEventListener("push", e => { + const { data } = e; + console.log(data, "Push received..."); + + self.registration.showNotification("FASTA is here... Expect MORE!!!", { + body: "Notified by FASTA.ng", + icon: "/car.png" + }); +}); \ No newline at end of file From 5d15aa19288a2baf941a298dd1871251385a9fb3 Mon Sep 17 00:00:00 2001 From: obafemi Date: Tue, 7 Jul 2020 23:12:50 +0100 Subject: [PATCH 6/8] fix report exact location --- fasta-backend/routes/report.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fasta-backend/routes/report.js b/fasta-backend/routes/report.js index 3631f5a..62ae21f 100644 --- a/fasta-backend/routes/report.js +++ b/fasta-backend/routes/report.js @@ -19,10 +19,10 @@ router.post("/report", authChecker, async (req, res) => { return res.status(403).json({ response: "please all fields are required" }); } try { - const { lat, long } = location; + const { lat, lng } = location; let address; await axios.get( - `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${process.env.TEST_KEY}` + `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.TEST_KEY}` ).then((data) => { if (data.data) { if (data.data.status === "OK") { @@ -30,6 +30,7 @@ router.post("/report", authChecker, async (req, res) => { address = data.data.results[0].formatted_address; } else { // console.log("error"); + address = "Unidentified Location"; throw new Error(); } } @@ -40,9 +41,10 @@ router.post("/report", authChecker, async (req, res) => { tripId, type, description, - location, + location, address }; + // console.log(reportDetails); const reports = await Reports.create(reportDetails); if (reports) { return res.status(200).json({ response: `${reports} Thanks for giving, your report has been saved` }); @@ -56,9 +58,9 @@ router.get("/reports", async (req, res) => { let { lat, lng } = req.query; lat = Number(lat); lng = Number(lng); - await Reports.find({ "location.lat": { $gte: lat - 1, $lte: lat + 1 }, "location.lng": { $gte: lng - 1, $lte: lng + 1 } }) + await Reports.find({ "location.lat": { $gte: lat - 0.07, $lte: lat + 0.07 }, "location.lng": { $gte: lng - 0.07, $lte: lng + 0.07 } }) // await Reports.find({ "location.lat": { lat }, "location.lng": { lng } }) - .select("_id type description location date") + .select("_id type description location address date") .exec() .then((allReports) => { if (!allReports || allReports < 1) { From 2a6b1cbcb31fdb1949f3db537a84c1ce29817917 Mon Sep 17 00:00:00 2001 From: obafemi Date: Thu, 9 Jul 2020 06:32:37 +0100 Subject: [PATCH 7/8] refactor and fix trip info route --- fasta-backend/routes/tripInfo.js | 153 ++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 56 deletions(-) diff --git a/fasta-backend/routes/tripInfo.js b/fasta-backend/routes/tripInfo.js index 3653d29..38ac8ce 100644 --- a/fasta-backend/routes/tripInfo.js +++ b/fasta-backend/routes/tripInfo.js @@ -1,69 +1,110 @@ +/* eslint-disable no-useless-return */ +/* eslint-disable array-callback-return */ +/* eslint-disable no-plusplus */ +/* eslint-disable max-len */ /* eslint-disable no-unused-vars */ /* eslint-disable consistent-return */ const express = require("express"); -// const { PolyUtil } = require("node-geometry-library"); +const axios = require("axios"); +const router = express.Router(); +const { PolyUtil } = require("node-geometry-library"); const ScheduleTrip = require("../models/trip"); const Reports = require("../models/report"); -const router = express.Router(); -router.get("/trip-info/:tripId", async (req, res) => { -// get allthe report locations - const reports = []; - let trips; - await Reports.find() - .select("-_id location") - .exec() - .then((allReports) => { - if (!allReports || allReports < 1) { - return res.status(404).json({ response: "unfortunetly, we dont have any report location schedule for you, check back" }); - } +const directionUrl = "https://maps.googleapis.com/maps/api/directions/json?"; - const valuesArray = Object.keys(allReports); - valuesArray.forEach((key) => { - const value = allReports[parseInt(key)]; - reports.push(value.location); - }); - }) - .catch((error) => { - res.status(500).json({ error }); - }); - // get schedule trip Id - await ScheduleTrip.findById({ _id: req.params.tripId }) - .select("-_id origin destination") - .exec() - .then((trip) => { - if (!trip || trip < 1) { - return res.status(404).json({ response: "unfortunetly, we dont have any report location schedule for you, check back" }); - } - trips = trip; - }) - .catch((error) => { - res.status(500).json({ error }); - }); +router.get("/trip-info/:tripId?", async (req, res) => { + + console.log("params: ", req.params); + console.log("query: ", req.query); + let { t } = req.query; + console.log("t: ", Number(t)); + const tolerance = Number(t) || PolyUtil.DEFAULT_TOLERANCE; + let reportsOnRoute; - try { - const response = await PolyUtil.containsLocation(trips, reports); - if (response) { - await Reports.find() - .select() - .exec() - .then((allReports) => { - if (!allReports || allReports < 1) { - return res.status(404).json({ response: "unfortunetly, we dont have any report location schedule for you, check back" }); + // identify trip by ID from database + const tripz = await ScheduleTrip.findById({ _id: req.params.tripId }) + .select("-_id mode originLatLng destinationLatLng") + .exec() + .then((trip) => { + if (!trip || trip < 1) { + return res.json({response: "Trip not found!"}); + } + console.log("trip: ", trip); + return trip; + }) + .catch((error) => { + return res.status(500).json({ error }); + }); + + // pull reports from database + const reportz = await Reports.find() + .select("-_id") + .exec() + .then((allReports) => { + if (!allReports || allReports < 1) { + return res.status(404).json({ response: "Reports not available at the moment, we're still checking" }); + } + // console.log("allReports: ", allReports); + return allReports; + }) + .catch((error) => { + return res.status(500).json({ error }); + }); + + // get list of points between from origin to destination + const getDirection = async (request) => { + const origin = `${request.originLatLng.lat},${request.originLatLng.lng}`; + const destination = `${request.destinationLatLng.lat},${request.destinationLatLng.lng}`; + // console.log(origin, destination); + return await axios + .get( + `${directionUrl}origin=${origin}&destination=${destination}&key=${process.env.TEST_KEY}` + ) + .then((response) => { + try { + if (response.data.length <= 0) { + return res.json({ error: response.data.error_message }); + } + // console.log("steps: ", response.data.routes[0].legs[0].steps); + // console.log("points: ", response.data.routes[0].overview_polyline.points); + return response.data.routes[0].overview_polyline.points; + } catch (err) { + console.error(err); + } + }) + .catch((error) => { + // throw new Error("Error fetching data"); + return res.json({response: "Error fetching data"}); + }); + }; + + try { + const triped = JSON.parse(JSON.stringify(tripz)); + const response = await getDirection(triped); + const path = PolyUtil.decode(response); + console.log("PolyUtil decoded points: ", path.length); + + const reportsOnPath = reportz.filter((report) => { + if (report.location !== undefined && report.location !== "unknown location") { + const reportFound = PolyUtil.isLocationOnEdge(report.location, path, tolerance); + if (reportFound) { + // console.log("PolyUtil tolerance", tolerance); + console.log(report.location,"is on path"); + return report; + } } - res.status(200).json({ response: allReports }); - }) - .catch((error) => { - res.status(500).json({ error }); - }); - } else { - res.send("Trip does match any incidence"); - } - } catch (err) { - // empty - } + }); + reportsOnRoute = reportsOnPath; + + } catch (err) { + console.log(err); + } + // console.log(reportsOnRoute); + + return res.json({response: reportsOnRoute}); }); -module.exports = router; +module.exports = router; \ No newline at end of file From a11a35698d9ba1db8aadba87877adfb7e90c8b48 Mon Sep 17 00:00:00 2001 From: ebuka Date: Fri, 17 Jul 2020 10:31:41 +0100 Subject: [PATCH 8/8] added a notification endpoint to the branch --- fasta-backend/app.js | 6 +- fasta-backend/public/pushClient.js | 67 ++++++++++--------- fasta-backend/public/worker.js | 29 ++++++-- fasta-backend/routes/index.js | 22 +++--- .../{helpers => routes}/notification.js | 31 +++------ fasta-backend/routes/users.js | 5 +- 6 files changed, 88 insertions(+), 72 deletions(-) rename fasta-backend/{helpers => routes}/notification.js (51%) diff --git a/fasta-backend/app.js b/fasta-backend/app.js index 5a10de6..e4fe329 100644 --- a/fasta-backend/app.js +++ b/fasta-backend/app.js @@ -4,10 +4,9 @@ const cookieParser = require("cookie-parser"); const logger = require("morgan"); const bodyParser = require("body-parser"); const dotenv = require("dotenv"); -// const webpush = require("web-push"); dotenv.config(); - + const CORS = require("cors"); const userRouter = require("./routes/users"); const indexRouter = require("./routes/index"); @@ -17,6 +16,7 @@ const reportRouter = require("./routes/report"); const tripInfoRouter = require("./routes/tripInfo"); +const notififoRouter = require("./routes/notification"); require("./db/index"); @@ -43,6 +43,8 @@ app.use("/api/v1/", sendRouter); app.use("/api/v1/", getTransporter); app.use("/api/v1", reportRouter); app.use("/api/v1", tripInfoRouter); +app.use("/api/v1", notififoRouter); + app.get("/", (req, res) => res.send("

Welcome to FASTA

Check out version 1 of the FASTA API

")); diff --git a/fasta-backend/public/pushClient.js b/fasta-backend/public/pushClient.js index 616e2d2..d3a5885 100644 --- a/fasta-backend/public/pushClient.js +++ b/fasta-backend/public/pushClient.js @@ -1,47 +1,52 @@ -const VAPID_PUBLIC_KEY = "BMntNKURDsrT_FV7D8Nn8nXZWn_J62wMMrjzXGuoiXBscvPqzckV8c4RKUCmJzjAKWez2LUbD11OWMhcUy6GwWA"; +const VAPID_PUBLIC_KEY = "BJOK8gh8hHPlZbr5Ci4LmJMWNlDsTdmQ2bGfE7TA6c9UhGmEuHTvjS179aqzobeQfQgWE94ELR26qbozfOfAVpc"; // check for service Worker -if("serviceWorker" in navigator) { - send().catch(err => console.log(err)); +if ("serviceWorker" in navigator) { + // eslint-disable-next-line no-use-before-define + send().catch((err) => console.log(err)); } // Register SW, Regisster Push, Send Push async function send() { // Register SW - console.log("Registering service worker..."); - const register = await navigator.serviceWorker.register("/worker.js", {scope: "/"}); - console.log("Service Worker Registered"); + console.log("Registering service worker..."); + const register = await navigator.serviceWorker.register("/worker.js", { scope: "/" }); + console.log("Service Worker Registered"); -// Register Push - console.log("Registering Push..."); - const subscription = await register.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) - }); - console.log("Push Registered..."); + // Register Push + console.log("Registering Push..."); + const subscription = await register.pushManager.subscribe({ + userVisibleOnly: true, + // eslint-disable-next-line no-use-before-define + applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) + }); + console.log("Push Registered..."); - // Send Push Notification - console.log("Sending Push..."); - await fetch("api/v1/subscribe", { - method: "POST", - body: JSON.stringify(subscription), - headers: { - "content-type": "application/json" - } - }); + // Send Push Notification + console.log("Sending Push..."); + await fetch("api/v1/subscribe", { + method: "POST", + body: JSON.stringify(subscription), + headers: { + "content-type": "application/json" + } + }); } function urlBase64ToUint8Array(base64String) { - const padding = "=".repeat((4 - base64String.length % 4) % 4); - const base64 = (base64String + padding) + // eslint-disable-next-line no-mixed-operators + const padding = "=".repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + // eslint-disable-next-line no-useless-escape .replace(/\-/g, "+") .replace(/_/g, "/"); - const rawData = window.atob(base64); - const outputArray = new Uint8Array(rawData.length); + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); - for (let i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); - } - return outputArray; -} \ No newline at end of file + // eslint-disable-next-line no-plusplus + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +} diff --git a/fasta-backend/public/worker.js b/fasta-backend/public/worker.js index 81726e4..cc0cfd5 100644 --- a/fasta-backend/public/worker.js +++ b/fasta-backend/public/worker.js @@ -1,11 +1,26 @@ console.log("Service worker loaded!"); -self.addEventListener("push", e => { - const { data } = e; - console.log(data, "Push received..."); - self.registration.showNotification("FASTA is here... Expect MORE!!!", { - body: "Notified by FASTA.ng", - icon: "/car.png" +// eslint-disable-next-line no-restricted-globals +self.addEventListener("push", (e) => { + const { data } = e; + console.log(data, "Push received..."); + + + fetch("/api/v1/notification").then((ed) => ed.json()).then((d) => { + const { options } = d; + // eslint-disable-next-line no-restricted-globals + self.registration.showNotification(`${options.subject}`, { + body: `${options.text} + ${options.output}`, + icon: "/car.png" }); -}); \ No newline at end of file + }) + .catch((ee) => console.log(ee)); + + // eslint-disable-next-line no-restricted-globals + // self.registration.showNotification("FASTA is here... Expect MORE!!!", { + // body: "Notified by FASTA.ng", + // icon: "/car.png" + // }); +}); diff --git a/fasta-backend/routes/index.js b/fasta-backend/routes/index.js index a79814a..37e5912 100644 --- a/fasta-backend/routes/index.js +++ b/fasta-backend/routes/index.js @@ -1,19 +1,25 @@ const express = require("express"); + const router = express.Router(); const webpush = require("web-push"); - -// console.log(process.env.VAPID_PUBLIC_KEY); -webpush.setVapidDetails("mailto:thevetdoctor@gmail.com", process.env.VAPID_PUBLIC_KEY, process.env.VAPID_PRIVATE_KEY); + +const vpidkeys = webpush.generateVAPIDKeys(); +// console.log(vpidkeys.privateKey); + + +// eslint-disable-next-line max-len +// webpush.setVapidDetails("mailto:thevetdoctor@gmail.com", process.env.VAPID_PUBLIC_KEY, process.env.VAPID_PRIVATE_KEY); +webpush.setVapidDetails("mailto:thevetdoctor@gmail.com", vpidkeys.publicKey, vpidkeys.privateKey); router.get("/", (req, res) => res.status(200).json({ message: "Welcome to FASTA, taking you faster in safety & convenience!" })); router.post("/subscribe", (req, res) => { - const subscription = req.body; + const subscription = req.body; - const payload = JSON.stringify({ title: "Push test"}); - webpush.sendNotification(subscription, payload).catch(err => console.log(err)); - res.status(201).json({message: "Push sent"}); + const payload = JSON.stringify({ title: "Push test" }); + webpush.sendNotification(subscription, payload).catch((err) => console.log(err)); + res.status(201).json({ message: "Push sent" }); }); - + module.exports = router; diff --git a/fasta-backend/helpers/notification.js b/fasta-backend/routes/notification.js similarity index 51% rename from fasta-backend/helpers/notification.js rename to fasta-backend/routes/notification.js index bc48e74..05fa7e3 100644 --- a/fasta-backend/helpers/notification.js +++ b/fasta-backend/routes/notification.js @@ -1,14 +1,10 @@ -/* eslint-disable consistent-return */ -/* eslint-disable func-names */ -/* eslint-disable no-undefined */ -const cron = require("node-cron"); +const router = require("express").Router(); const ScheduleTrip = require("../models/trip"); const Reports = require("../models/report"); -const mailer = require("./mailer"); const User = require("../models/index"); -const notification = async () => { +router.get("/notification", async (req, res) => { const reports = await Reports.find() .select("description location date") .exec(); @@ -19,19 +15,17 @@ const notification = async () => { reports.forEach((r) => { schedules.forEach((s) => { - if (r.location === s.destination && r.date < s.tripTime) { - const ids = User.findById(s.userId) - .select("email fullname") - .exec(); - ids + // if (r.location === s.destination && r.date < s.tripTime) { + if (r.location === s.destination) { + User.findById(s.userId) .then((id) => { const options = { - receiver: id.email, subject: "This is happening in your desiation!", text: `Hello ${id.fullname}`, - output: `${r.description}\n\n` + output: `${r.description}` }; - mailer(options); + + return res.send({ options }); }) .catch(() => { // console.log(e); @@ -39,12 +33,7 @@ const notification = async () => { } }); }); -}; +}); -const pushNotification = () => { - cron.schedule("* 08 * * *", () => { - notification(); - }); -}; -module.exports = pushNotification; +module.exports = router; diff --git a/fasta-backend/routes/users.js b/fasta-backend/routes/users.js index 8d8db1f..faea3d4 100644 --- a/fasta-backend/routes/users.js +++ b/fasta-backend/routes/users.js @@ -11,7 +11,6 @@ const User = require("../models/index.js"); const bcrypt = require("../helpers/auth"); const authChecker = require("../middlewares/authChecker"); const mailer = require("../helpers/mailer"); -const notification = require("../helpers/notification"); // CREATE A NEW USER AND ADD TO DATABASE @@ -75,7 +74,7 @@ router.post("/login", async (req, res) => { const passwordcheck = bcrypt.comparePassword(password, user.password); if (passwordcheck) { const token = bcrypt.generateToken(user); - notification(); + return res.status(200).json({ response: "Login successful", token, @@ -109,7 +108,7 @@ router.get("/:id", authChecker, (req, res) => { _id: id }).then( (thisUser) => { - // console.log("Getting specific user by ID!"); + // console.log("Getting specific user by ID!"); res.status(200).json(thisUser); } ).catch(