diff --git a/spec/verifyUserEmails.spec.js b/spec/verifyUserEmails.spec.js new file mode 100644 index 0000000000..9524649d7b --- /dev/null +++ b/spec/verifyUserEmails.spec.js @@ -0,0 +1,66 @@ +'use strict'; + +const { getAuthForSessionToken } = require('../lib/Auth'); +const Config = require('../lib/Config'); + +describe('verifyUserEmails with Auth Context', () => { + let user; + let config; + + beforeEach(async (done) => { + await reconfigureServer({ + verifyUserEmails: jasmine.createSpy('verifyUserEmails'), + }); + + user = new Parse.User(); + await user.signUp({ + username: 'testuser', + password: 'securepassword', + email: 'test@example.com', + }); + + config = Config.get('test'); + done(); + }); + + it('should call verifyUserEmails with correct auth context on signup', async (done) => { + const sessionToken = user.getSessionToken(); + expect(sessionToken).toBeDefined(); + + await getAuthForSessionToken({ + sessionToken, + config, + }); + + expect(config.verifyUserEmails).toHaveBeenCalledWith({ + action: 'signup', + authProvider: 'password', + }); + done(); + }); + + it('should call verifyUserEmails with correct auth context on login', async (done) => { + await Parse.User.logIn('testuser', 'securepassword'); + + expect(config.verifyUserEmails).toHaveBeenCalledWith({ + action: 'login', + authProvider: 'password', + }); + done(); + }); + + it('should call verifyUserEmails with correct provider for social login', async (done) => { + const socialAuthData = { + id: '1234567890', + access_token: 'mockAccessToken', + }; + + await Parse.User.logInWith('facebook', { authData: socialAuthData }); + + expect(config.verifyUserEmails).toHaveBeenCalledWith({ + action: 'login', + authProvider: 'facebook', + }); + done(); + }); +}); diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 296b7f6868..c1a62657c2 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -11,8 +11,9 @@ var RestQuery = require('../RestQuery'); var Auth = require('../Auth'); export class UserController extends AdaptableController { - constructor(adapter, appId, options = {}) { + constructor(adapter, appId, options = {}, authContext = {}) { super(adapter, appId, options); + this.authContext = authContext; } get config() { @@ -38,8 +39,13 @@ export class UserController extends AdaptableController { async setEmailVerifyToken(user, req, storage = {}) { const shouldSendEmail = this.shouldVerifyEmails === true || - (typeof this.shouldVerifyEmails === 'function' && - (await Promise.resolve(this.shouldVerifyEmails(req))) === true); + (typeof this.shouldVerifyEmails === "function" && + (await Promise.resolve( + this.shouldVerifyEmails({ + user: Parse.Object.fromJSON({ className: "_User", ...user }), + authContext: this.authContext + }) + )) === true); if (!shouldSendEmail) { return false; } diff --git a/src/Controllers/index.js b/src/Controllers/index.js index abf0950640..52dcbe6a0e 100644 --- a/src/Controllers/index.js +++ b/src/Controllers/index.js @@ -98,14 +98,15 @@ export function getFilesController(options: ParseServerOptions): FilesController }); } -export function getUserController(options: ParseServerOptions): UserController { +export function getUserController(options: ParseServerOptions, authContext = {}): UserController { const { appId, emailAdapter, verifyUserEmails } = options; const emailControllerAdapter = loadAdapter(emailAdapter); return new UserController(emailControllerAdapter, appId, { verifyUserEmails, - }); + }, authContext); } + export function getCacheController(options: ParseServerOptions): CacheController { const { appId, cacheAdapter, cacheTTL, cacheMaxSize } = options; const cacheControllerAdapter = loadAdapter(cacheAdapter, InMemoryCacheAdapter, {