From 9bdf3925a357c971303a556e318996e88fad9eed Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 11 Dec 2021 09:59:57 +0000 Subject: [PATCH] Implemented a post-validation hook --- README.md | 2 + configure-script.js | 2 + package-lock.json | 106 +++++++++++++++++++++++++++++++++++++- package.json | 3 +- server/auth/validation.js | 18 ++++++- 5 files changed, 127 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5f06448..ad92d3f 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ Content-Type: application/json //DOCS: Used for validating the email address specified above GET /auth/validation?username=example&token=12345678 +//DOCS: If the environment variable HOOK_POST_VALIDATION is set to a URL, then the server will send a GET message to that URL with the newly created account's index +GET https://{HOOK_POST_VALIDATION}?accountIndex={index} ### diff --git a/configure-script.js b/configure-script.js index 0265783..76529f0 100644 --- a/configure-script.js +++ b/configure-script.js @@ -30,6 +30,7 @@ const question = (prompt, def = null) => { //project configuration const appName = await question('App Name', 'auth'); const appWebAddress = await question('Web Addr', `${appName}.example.com`); + const postValidationHook = await question('Post Validation Hook', ''); const resetAddress = await question('Reset Addr', `example.com/reset`); const appPort = await question('App Port', '3200'); @@ -70,6 +71,7 @@ services: environment: - WEB_PROTOCOL=https - WEB_ADDRESS=${appWebAddress} + - HOOK_POST_VALIDATION=${postValidationHook} - WEB_RESET_ADDRESS=${resetAddress} - WEB_PORT=${appPort} - DB_HOSTNAME=database diff --git a/package-lock.json b/package-lock.json index 0ee8f53..bfbd2e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "auth-server", - "version": "1.4.5", + "version": "1.4.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "auth-server", - "version": "1.4.5", + "version": "1.4.6", "license": "ISC", "dependencies": { "bcryptjs": "^2.4.3", @@ -16,6 +16,7 @@ "jsonwebtoken": "^8.5.1", "mariadb": "^2.5.4", "node-cron": "^2.0.3", + "node-fetch": "^3.1.0", "nodemailer": "^6.6.3", "sequelize": "^6.6.5" }, @@ -452,6 +453,14 @@ "node": ">=8" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -637,6 +646,27 @@ "node": ">= 0.10.0" } }, + "node_modules/fetch-blob": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.3.tgz", + "integrity": "sha512-ax1Y5I9w+9+JiM+wdHkhBoxew+zG4AJ2SvAD1v1szpddUIiPERVGBxrMcB2ZqW0Y3PP8bOWYv2zqQq1Jp2kqUQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -666,6 +696,17 @@ "node": ">= 0.8" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1280,6 +1321,23 @@ "node": ">=6.0.0" } }, + "node_modules/node-fetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.1.0.tgz", + "integrity": "sha512-QU0WbIfMUjd5+MUzQOYhenAazakV7Irh1SGkWCsRzBwvm4fAhzEUaHMJ6QLP7gWT6WO9/oH2zhKMMGMuIrDyKw==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.2", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/nodemailer": { "version": "6.6.3", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.3.tgz", @@ -2045,6 +2103,14 @@ "node": ">= 0.8" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", + "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", @@ -2437,6 +2503,11 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2592,6 +2663,14 @@ "vary": "~1.1.2" } }, + "fetch-blob": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.3.tgz", + "integrity": "sha512-ax1Y5I9w+9+JiM+wdHkhBoxew+zG4AJ2SvAD1v1szpddUIiPERVGBxrMcB2ZqW0Y3PP8bOWYv2zqQq1Jp2kqUQ==", + "requires": { + "web-streams-polyfill": "^3.0.3" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2615,6 +2694,14 @@ "unpipe": "~1.0.0" } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3092,6 +3179,16 @@ "tz-offset": "0.0.1" } }, + "node-fetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.1.0.tgz", + "integrity": "sha512-QU0WbIfMUjd5+MUzQOYhenAazakV7Irh1SGkWCsRzBwvm4fAhzEUaHMJ6QLP7gWT6WO9/oH2zhKMMGMuIrDyKw==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.2", + "formdata-polyfill": "^4.0.10" + } + }, "nodemailer": { "version": "6.6.3", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.3.tgz", @@ -3663,6 +3760,11 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "web-streams-polyfill": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", + "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==" + }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", diff --git a/package.json b/package.json index bcf0b2d..fef48aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auth-server", - "version": "1.4.5", + "version": "1.4.6", "description": "An API centric auth server. Uses Sequelize and mariaDB by default.", "main": "server/server.js", "scripts": { @@ -26,6 +26,7 @@ "jsonwebtoken": "^8.5.1", "mariadb": "^2.5.4", "node-cron": "^2.0.3", + "node-fetch": "^3.1.0", "nodemailer": "^6.6.3", "sequelize": "^6.6.5" }, diff --git a/server/auth/validation.js b/server/auth/validation.js index b2c86f6..87f959b 100644 --- a/server/auth/validation.js +++ b/server/auth/validation.js @@ -1,4 +1,5 @@ const { pendingSignups, accounts } = require('../database/models'); +const fetch = require('node-fetch'); //auth/validation const route = async (req, res) => { @@ -19,7 +20,7 @@ const route = async (req, res) => { } //move data to the accounts table - accounts.create({ + const [account] = await accounts.upsert({ email: info.email, username: info.username, hash: info.hash, @@ -35,6 +36,21 @@ const route = async (req, res) => { //finally res.status(200).send('Validation succeeded!'); + + //post-validation hook + if (process.env.HOOK_POST_VALIDATION) { + const probe = await fetch(`https://${process.env.HOOK_POST_VALIDATION}?accountIndex=${account.index}`); + + if (!probe.ok) { + console.error('Could not probe the post validation hook'); + } else { + console.log('Validation hook probe successful'); //TODO: remove this + } + + //discard the result + } else { + console.log('No validation hook'); //TODO: remove this + } }; module.exports = route; \ No newline at end of file