diff --git a/graph/connectors.js b/graph/connectors.js index 3ad3024ea..f1e2612af 100644 --- a/graph/connectors.js +++ b/graph/connectors.js @@ -54,6 +54,7 @@ const Subscriptions = require('../services/subscriptions'); const Tags = require('../services/tags'); const Tokens = require('../services/tokens'); const Users = require('../services/users'); +const Utils = require('../services/utils'); const Wordlist = require('../services/wordlist'); // Connectors. @@ -95,6 +96,7 @@ const defaultConnectors = { Tags, Tokens, Users, + Utils, Wordlist, }, graph: { diff --git a/graph/context.js b/graph/context.js index ea694f6cf..815f7761a 100644 --- a/graph/context.js +++ b/graph/context.js @@ -104,6 +104,17 @@ class Context { this.parent = ctx; } + /** + * Gets the root parent object. + */ + get rootParent() { + let ctx = this; + while (ctx.parent) { + ctx = ctx.parent; + } + return ctx; + } + /** * graphql will execute a graph request for the current context. * diff --git a/plugins/talk-plugin-local-auth/server/mutators.js b/plugins/talk-plugin-local-auth/server/mutators.js index 044371688..76eb227fc 100644 --- a/plugins/talk-plugin-local-auth/server/mutators.js +++ b/plugins/talk-plugin-local-auth/server/mutators.js @@ -20,7 +20,12 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) { loaders: { Settings }, connectors: { models: { User }, - services: { Mailer, I18n, Users }, + services: { + Mailer, + I18n, + Users, + Utils: { getRedirectUri }, + }, }, } = ctx; @@ -77,9 +82,12 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) { subject: I18n.t('email.email_change_original.subject'), }); + // Try to get the root parent, and their redirect uri. + const redirectUri = getRedirectUri(ctx.rootParent); + // Send off the email to the new email address that we need to verify the new // address. - await Users.sendEmailConfirmation(user, email); + await Users.sendEmailConfirmation(user, email, redirectUri); } // attachUserLocalAuth will attach a new local profile to an existing user. @@ -88,7 +96,10 @@ async function attachUserLocalAuth(ctx, email, password) { user, connectors: { models: { User }, - services: { Users }, + services: { + Users, + Utils: { getRedirectUri }, + }, }, } = ctx; @@ -141,9 +152,12 @@ async function attachUserLocalAuth(ctx, email, password) { throw new Error('local auth attachment failed due to unexpected reason'); } + // Try to get the root parent, and their redirect uri. + const redirectUri = getRedirectUri(ctx.rootParent); + // Send off the email to the new email address that we need to verify the // new address. - await Users.sendEmailConfirmation(updatedUser, email); + await Users.sendEmailConfirmation(updatedUser, email, redirectUri); } catch (err) { if (err.code === 11000) { throw new ErrEmailTaken(); diff --git a/routes/api/v1/users.js b/routes/api/v1/users.js index 481e5650c..77cefa66e 100644 --- a/routes/api/v1/users.js +++ b/routes/api/v1/users.js @@ -1,6 +1,7 @@ const express = require('express'); const router = express.Router(); const UsersService = require('../../../services/users'); +const { getRedirectUri } = require('../../../services/utils'); const { ErrMissingEmail, ErrNotFound } = require('../../../errors'); const authorization = require('../../../middleware/authorization'); const Limit = require('../../../services/limit'); @@ -8,7 +9,7 @@ const Limit = require('../../../services/limit'); // create a local user. router.post('/', async (req, res, next) => { const { email, password, username } = req.body; - const redirectUri = req.header('X-Pym-Url') || req.header('Referer'); + const redirectUri = getRedirectUri(req); try { // Adjusted the user creation endpoint. diff --git a/services/utils.js b/services/utils.js index 1eafe86b5..c8b1ac82b 100644 --- a/services/utils.js +++ b/services/utils.js @@ -24,6 +24,13 @@ function dotize(object) { return result; } +function getRedirectUri(req) { + if (typeof req.header === 'function') { + return req.header('X-Pym-Url') || req.header('Referer'); + } +} + module.exports = { dotize, + getRedirectUri, }; diff --git a/test/server/graph/context.js b/test/server/graph/context.js index b3319d5c4..dde601580 100644 --- a/test/server/graph/context.js +++ b/test/server/graph/context.js @@ -31,6 +31,18 @@ describe('graph.Context', () => { }); }); + describe('#rootParent', () => { + it('can access the root context parent', () => { + const ctx = new Context({ test: 1 }); + const ctx2 = new Context(ctx); + const ctx3 = new Context(ctx2); + + const parent = ctx3.rootParent; + + expect(parent).to.have.property('test', 1); + }); + }); + describe('#constructor: without a user', () => { let c;