diff --git a/.envdev b/.envdev index 64c7d09..425e90e 100644 --- a/.envdev +++ b/.envdev @@ -29,4 +29,7 @@ DB_LOGGING= SECRET_ACCESS=access # Make sure this value is kept secret -SECRET_REFRESH=refresh \ No newline at end of file +SECRET_REFRESH=refresh + +# Post-signup hook JSON array (MUST include http:// or https://) +HOOK_POST_VALIDATION_ARRAY= \ No newline at end of file diff --git a/README.md b/README.md index 7cd81de..2c661d4 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,10 @@ 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} +//DOCS: If the environment variable HOOK_POST_VALIDATION_ARRAY is set to a JSON array of valid URLs, then the server will send a GET message to each URL with the newly created account's index +//DOCS: The GET requests will have a JWT authorization header +HOOK_POST_VALIDATION_ARRAY=["http://example.com", "http://example2.com"] +GET {HOOK_POST_VALIDATION_ARRAY[i]}?accountIndex={index} ### diff --git a/server/auth/validation.js b/server/auth/validation.js index d38def5..8bd0f29 100644 --- a/server/auth/validation.js +++ b/server/auth/validation.js @@ -1,5 +1,6 @@ const { pendingSignups, accounts } = require('../database/models'); const fetch = require('node-fetch'); +const jwt = require('jsonwebtoken'); //auth/validation const route = async (req, res) => { @@ -38,14 +39,42 @@ const route = async (req, res) => { 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 (process.env.HOOK_POST_VALIDATION_ARRAY) { + try { + hooks = JSON.parse(process.env.HOOK_POST_VALIDATION_ARRAY); - if (!probe.ok) { - console.error('Could not probe the post validation hook'); + if (!Array.isArray(hooks)) { + throw 'isArray() check failed'; + } + + //authenticate the hooks + const bearer = jwt.sign({ type: 'hook authentication' }, process.env.SECRET_ACCESS, { expiresIn: '5m', issuer: 'auth' }); + + //promise for each given hook + const promises = hooks.map(async hook => { + if (typeof hook != 'string') { + throw 'hook is not a string'; + } + + const probe = await fetch(`${hook}?accountIndex=${account.index}`, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${bearer}` + } + }); + + if (!probe.ok) { + throw `Could not probe the post validation hook: ${hook}`; + } + + //discard the result + }); + + Promise.all(promises); + } + catch(e) { + console.error('HOOK_POST_VALIDATION_ARRAY is not a valid array of strings in JSON format: ' + e); } - - //discard the result } };