From 17914d337b7b75395ac06d94760b16c54c770434 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Tue, 2 May 2023 14:43:22 +0200 Subject: [PATCH 1/2] Integrated Google API and out of country check --- .env | 1 + index.js | 41 ++++++++-- package-lock.json | 202 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 4 files changed, 239 insertions(+), 7 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..9e8e7cf --- /dev/null +++ b/.env @@ -0,0 +1 @@ +GOOGLE_API_KEY=AIzaSyAaVfXbFPUQSeif2FwY1gQ2iJaBp9ZPdPM \ No newline at end of file diff --git a/index.js b/index.js index f18cbd8..0972dd9 100644 --- a/index.js +++ b/index.js @@ -1,11 +1,15 @@ const { createReadStream, readFileSync } = require('fs') const { join } = require('path') +require('dotenv').config() + const express = require('express') const cors = require('cors') const morgan = require('morgan') const helmet = require("helmet"); const json = require('big-json') +const { Client } = require("@googlemaps/google-maps-services-js"); + const GeoJsonGeometriesLookup = require("geojson-geometries-lookup") const lookupTable = require('./rep-lookup') @@ -45,14 +49,37 @@ app.use('/rep', async (req, res) => { const closestCity = await (await fetch( `https://geo.api.gouv.fr/communes?lat=${lat}&lon=${lon}` )).json(); - let codeDepartement = closestCity[0]?.codeDepartement + codeDepartement = closestCity[0]?.codeDepartement + + // Usually means we're out of France + if (!codeDepartement) { + + // ...Check if in another country + const gaClient = new Client({}) + + try { + const gaRes = await gaClient.reverseGeocode({ params: { latlng: `${lat},${lon}`, key: process.env.GOOGLE_API_KEY }}) + const gaData = await gaRes.data + + if (gaData.results) { + const countryName = gaData.results.find((addr) => addr.types.find((type) => type === "country"))?.formatted_address + + // From country name, get the associated rep + } else { + // If not in a valid country, ends req + res.status(400).json({ + "message": "Les coordonnées de géolocalisation ne sont pas correctes ; vérifiez votre navigateur ou contactez l'administrateur du site si vous pensez qu'il s'agit d'une erreur." + }); + return + } + } catch (err) { + res.status(500).json({ + "message": "Une erreur est survenue à cause de l'API Google Maps. Nous vous recommandez de réessayer plus tard." + }); + return + } + - // If somehow, the gov api can't find the nearest city... - if (!codeDepartement || codeDepartement === "") { - res.status(400).json({ - "message": "Les coordonnées de géolocalisation ne sont pas correctes ; vérifiez votre navigateur ou contactez l'administrateur du site si vous pensez qu'il s'agit d'une erreur." - }); - return } // Changes dep code to format of filenames on server, ie "075" diff --git a/package-lock.json b/package-lock.json index 13b4525..102ee89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,14 +6,36 @@ "": { "license": "ISC", "dependencies": { + "@googlemaps/google-maps-services-js": "^3.3.29", "big-json": "^3.2.0", "cors": "^2.8.5", + "dotenv": "^16.0.3", "express": "^4.18.2", "geojson-geometries-lookup": "^0.5.0", "helmet": "^6.1.5", "morgan": "^1.10.0" } }, + "node_modules/@googlemaps/google-maps-services-js": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@googlemaps/google-maps-services-js/-/google-maps-services-js-3.3.29.tgz", + "integrity": "sha512-tFev5JZDo/9n5jKJi/AAhXlebLd+iup3IQybptbJfp8lgQL9pjyVNT2ci65T+GC+AeDzL+Hh189kFM8gJAHNMw==", + "dependencies": { + "@googlemaps/url-signature": "^1.0.4", + "agentkeepalive": "^4.1.0", + "axios": "^0.27.2", + "query-string": "^7.1.3", + "retry-axios": "^2.6.0" + } + }, + "node_modules/@googlemaps/url-signature": { + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@googlemaps/url-signature/-/url-signature-1.0.29.tgz", + "integrity": "sha512-EKcL5ki6gUC02Yyrru8l37YKTNvfpoE/gMHy+tHoXjw2UuRBwGcXyMoHonGDUE9HNJrR7kXeG89ex4oGyX0NGQ==", + "dependencies": { + "crypto-js": "^4.1.1" + } + }, "node_modules/@turf/bbox": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-6.5.0.tgz", @@ -107,6 +129,40 @@ "node": ">= 0.6" } }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/agentkeepalive/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agentkeepalive/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -120,6 +176,20 @@ "node": ">=0.8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -192,6 +262,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -241,6 +322,11 @@ "node": ">= 0.10" } }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -249,6 +335,22 @@ "ms": "2.0.0" } }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -266,6 +368,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -333,6 +443,14 @@ "node": ">= 0.10.0" } }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -350,6 +468,38 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -460,6 +610,14 @@ "node": ">= 0.8" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -714,6 +872,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/quickselect": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", @@ -768,6 +943,17 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/retry-axios": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-2.6.0.tgz", + "integrity": "sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==", + "engines": { + "node": ">=10.7.0" + }, + "peerDependencies": { + "axios": "*" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -852,6 +1038,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "engines": { + "node": ">=6" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -860,6 +1054,14 @@ "node": ">= 0.8" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/package.json b/package.json index f4780e8..48e6649 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,10 @@ "author": "", "license": "ISC", "dependencies": { + "@googlemaps/google-maps-services-js": "^3.3.29", "big-json": "^3.2.0", "cors": "^2.8.5", + "dotenv": "^16.0.3", "express": "^4.18.2", "geojson-geometries-lookup": "^0.5.0", "helmet": "^6.1.5", From 61b1b2d9535a56d2cb860805a044a94a098cdaea Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Tue, 2 May 2023 19:38:28 +0200 Subject: [PATCH 2/2] Added foreign rep tables response and data --- index.js | 25 ++++- rep-lookup-foreign.js | 214 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 rep-lookup-foreign.js diff --git a/index.js b/index.js index 0972dd9..1d05a2d 100644 --- a/index.js +++ b/index.js @@ -49,7 +49,7 @@ app.use('/rep', async (req, res) => { const closestCity = await (await fetch( `https://geo.api.gouv.fr/communes?lat=${lat}&lon=${lon}` )).json(); - codeDepartement = closestCity[0]?.codeDepartement + let codeDepartement = closestCity[0]?.codeDepartement // Usually means we're out of France if (!codeDepartement) { @@ -65,6 +65,26 @@ app.use('/rep', async (req, res) => { const countryName = gaData.results.find((addr) => addr.types.find((type) => type === "country"))?.formatted_address // From country name, get the associated rep + const foreignLookupTable = require('./rep-lookup-foreign') + + let circoForeign + + // foreignLookupTable.forEach((value, index) => { + // if (value.includes(countryName)) { + // circoForeign = index + // } + // }); + + for (const [key, value] of Object.entries(foreignLookupTable)) { + if (value.includes(countryName)) { + circoForeign = key + } + } + + // If a code is found, send the associated file containing the representant data + const repFile = readFileSync(join(__dirname, `public/reps/${lookupTable[circoForeign]}.json`), 'utf-8') + res.end(repFile) + return } else { // If not in a valid country, ends req res.status(400).json({ @@ -73,13 +93,12 @@ app.use('/rep', async (req, res) => { return } } catch (err) { + console.log(err) res.status(500).json({ "message": "Une erreur est survenue à cause de l'API Google Maps. Nous vous recommandez de réessayer plus tard." }); return } - - } // Changes dep code to format of filenames on server, ie "075" diff --git a/rep-lookup-foreign.js b/rep-lookup-foreign.js new file mode 100644 index 0000000..391d093 --- /dev/null +++ b/rep-lookup-foreign.js @@ -0,0 +1,214 @@ +'use strict'; + +module.exports = { + "099-01": [ + "Canada", + "United States", + ], + "099-02": [ + "Belize", + "Costa Rica", + "Guatemala", + "Honduras", + "Mexico", + "Nicaragua", + "Panama", + "Salvador", + "Bolivia", + "Colombia", + "Ecuador", + "Peru", + "Venezuela", + "Brazil", + "Guyana", + "Suriname", + "Argentina", + "Chile", + "Paraguay", + "Uruguay", + "Antigua and Barbuda", + "The Bahamas", + "Barbados", + "Cuba", + "Dominican Republic", + "Dominica", + "Grenada", + "Haiti", + "Jamaica", + "St Kitts and Nevis", + "St Lucia", + "St Vincent and the Grenadines", + "Trinidad and Tobago", + ], + "099-03": [ + "Ireland", + "United Kingdom", + "Denmark", + "Estonia", + "Finland", + "Iceland", + "Latvia", + "Lituania", + "Norway", + "Sweden", + ], + "099-04": [ + "Belgium", + "Netherlands", + "Luxembourg", + ], + "099-05": [ + "Andorra", + "Spain", + "Monaco", + "Portugal", + ], + "099-06": [ + "Liechtenstein", + "Switzerland", + ], + "099-07": [ + "Germany", + "Albania", + "Austria", + "Bosnia and Herzegovina", + "Bulgaria", + "Croatia", + "Hungary", + "North Macedonia", + "Poland", + "Romania", + "Serbia and Montenegro", + "Slovenia", + "Czechia", + "Slovakia", + ], + "099-08": [ + "Italia", + "Malta", + "San Marino", + "Holy See", + "Cyprus", + "Greece", + "Turkey", + "Israel" + ], + "099-09": [ + "Algeria", + "Morocco", + "Libya", + "Tunisia", + "Burkina Faso", + "Mali", + "Niger", + "Mauritania", + "Cabo Verde", + "The Gambia", + "Guinea", + "Guinea-Bissau", + "Senegal", + "Sierra Leone", + "Ivory Coast", + "Liberia", + ], + "099-10": [ + "Bostwana", + "Lesotho", + "Malawi", + "Mozambique", + "Namibia", + "Swaziland", + "Zambia", + "Zimbabwe", + "Comoros", + "Madagascar", + "Mauritius", + "Seychelles", + "Egypt", + "Sudan", + "Djibouti", + "Eritrea", + "Ethiopia", + "Somalia", + "Burundi", + "Kenya", + "Uganda", + "Rwanda", + "Tanzania", + "Benign", + "Ghana", + "Nigeria", + "Togo", + "Cameroon", + "Central African Republic", + "Chad", + "Gabon", + "Equatorial Guinea", + "São Tomé and Príncipe", + "Angola", + "Congolese", + "Democratic Republic of Congo", + "Iraq", + "Jordan", + "Lebanon", + "Syria", + "Saudi Arabia", + "Bahrain", + "United Arab Emirates", + "Kuwait", + "Oman", + "Qatar", + "Yemen", + ], + "099-11": [ + "Armenia", + "Azerbaijan", + "Belarus", + "Georgia", + "Kazakhstan", + "Kyrgyzstan", + "Moldova", + "Uzbekistan", + "Russia", + "Tajikistan", + "Turkmenistan", + "Ukraine", + "Afghani", + "Bangladeshi", + "India", + "Iran", + "Maldives", + "Nepal", + "Pakistan", + "Sri Lanka", + "China", + "South Korea", + "Japan", + "Mongolia", + "Burma", + "Brunei", + "Cambodia", + "Indonesia", + "Laos", + "Malaysia", + "Palau", + "Philippines", + "Singapore", + "Thailand", + "East Timor", + "Vietnam", + "Australia", + "Fiji", + "Kiribati", + "Marshall", + "Micronesia", + "Nauru", + "New Zealand", + "Papua New Guinea", + "Solomon", + "Samoa", + "Tonga", + "Tuvalu", + "Vanuatu", + ], +}