From 8adcbee11283d3e95179ca2047e2615f52c18806 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Sat, 6 Jan 2024 16:41:13 +0100 Subject: [PATCH] feat: Add `installationId`, `ip`, `resendRequest` to arguments passed to `verifyUserEmails` on verification email request (#8873) BREAKING CHANGE: The `Parse.User` passed as argument if `verifyUserEmails` is set to a function is renamed from `user` to `object` for consistency with invocations of `verifyUserEmails` on signup or login; the user object is not a plain JavaScript object anymore but an instance of `Parse.User` --- spec/EmailVerificationToken.spec.js | 36 +++++++++++++++++++++++++++++ src/Controllers/UserController.js | 12 +++++++--- src/Routers/UsersRouter.js | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/spec/EmailVerificationToken.spec.js b/spec/EmailVerificationToken.spec.js index 3963b2aa..f4976207 100644 --- a/spec/EmailVerificationToken.spec.js +++ b/spec/EmailVerificationToken.spec.js @@ -3,6 +3,7 @@ const Auth = require('../lib/Auth'); const Config = require('../lib/Config'); const request = require('../lib/request'); +const MockEmailAdapterWithOptions = require('./support/MockEmailAdapterWithOptions'); describe('Email Verification Token Expiration: ', () => { it('show the invalid verification link page, if the user clicks on the verify email link after the email verify token expires', done => { @@ -794,6 +795,41 @@ describe('Email Verification Token Expiration: ', () => { }); }); + it('provides function arguments in verifyUserEmails on verificationEmailRequest', async () => { + const user = new Parse.User(); + user.setUsername('user'); + user.setPassword('pass'); + user.set('email', 'test@example.com'); + await user.signUp(); + + const verifyUserEmails = { + method: async (params) => { + expect(params.object).toBeInstanceOf(Parse.User); + expect(params.ip).toBeDefined(); + expect(params.master).toBeDefined(); + expect(params.installationId).toBeDefined(); + expect(params.resendRequest).toBeTrue(); + return true; + }, + }; + const verifyUserEmailsSpy = spyOn(verifyUserEmails, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'test', + publicServerURL: 'http://localhost:1337/1', + verifyUserEmails: verifyUserEmails.method, + preventLoginWithUnverifiedEmail: verifyUserEmails.method, + preventSignupWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + await expectAsync(Parse.User.requestEmailVerification('test@example.com')).toBeResolved(); + expect(verifyUserEmailsSpy).toHaveBeenCalledTimes(1); + }); + it('should throw with invalid emailVerifyTokenReuseIfValid', async done => { const sendEmailOptions = []; const emailAdapter = { diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 69839aa8..0f174022 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -197,7 +197,7 @@ export class UserController extends AdaptableController { * @param user * @returns {*} */ - async regenerateEmailVerifyToken(user, master) { + async regenerateEmailVerifyToken(user, master, installationId, ip) { const { _email_verify_token } = user; let { _email_verify_token_expires_at } = user; if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') { @@ -211,7 +211,13 @@ export class UserController extends AdaptableController { ) { return Promise.resolve(); } - const shouldSend = await this.setEmailVerifyToken(user, { user, master }); + const shouldSend = await this.setEmailVerifyToken(user, { + object: Parse.User.fromJSON(Object.assign({ className: '_User' }, user)), + master, + installationId, + ip, + resendRequest: true + }); if (!shouldSend) { return; } @@ -223,7 +229,7 @@ export class UserController extends AdaptableController { if (!aUser || aUser.emailVerified) { throw undefined; } - const generate = await this.regenerateEmailVerifyToken(aUser, req.auth?.isMaster); + const generate = await this.regenerateEmailVerifyToken(aUser, req.auth?.isMaster, req.auth?.installationId, req.ip); if (generate) { this.sendVerificationEmail(aUser, req); } diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 5de6077d..e3effd96 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -490,7 +490,7 @@ export class UsersRouter extends ClassesRouter { } const userController = req.config.userController; - const send = await userController.regenerateEmailVerifyToken(user, req.auth.isMaster); + const send = await userController.regenerateEmailVerifyToken(user, req.auth.isMaster, req.auth.installationId, req.ip); if (send) { userController.sendVerificationEmail(user, req); }