diff --git a/package.json b/package.json index a573ea49d8..57e9369fd4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "files": [ "bin/", "lib/", - "public_html/", + "public/", "views/", "LICENSE", "NOTICE", diff --git a/spec/PagesRouter.spec.js b/spec/PagesRouter.spec.js index 009254dfcc..fc32e61e13 100644 --- a/spec/PagesRouter.spec.js +++ b/spec/PagesRouter.spec.js @@ -1181,6 +1181,61 @@ describe('Pages Router', () => { }); }); + describe('async publicServerURL', () => { + it('resolves async publicServerURL for password reset page', async () => { + const emailAdapter = { + sendVerificationEmail: () => Promise.resolve(), + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + await reconfigureServer({ + appId: 'test', + appName: 'exampleAppname', + verifyUserEmails: true, + emailAdapter, + publicServerURL: () => 'http://localhost:8378/1', + pages: { enableRouter: true }, + }); + + const user = new Parse.User(); + user.setUsername('asyncUrlUser'); + user.setPassword('examplePassword'); + user.set('email', 'async-url@example.com'); + await user.signUp(); + await Parse.User.requestPasswordReset('async-url@example.com'); + + const response = await request({ + url: 'http://localhost:8378/1/apps/test/request_password_reset?token=invalidToken', + followRedirects: false, + }).catch(e => e); + expect(response.status).toBe(200); + expect(response.text).toContain('Invalid password reset link!'); + }); + + it('resolves async publicServerURL for email verification page', async () => { + const emailAdapter = { + sendVerificationEmail: () => Promise.resolve(), + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + await reconfigureServer({ + appId: 'test', + appName: 'exampleAppname', + verifyUserEmails: true, + emailAdapter, + publicServerURL: () => 'http://localhost:8378/1', + pages: { enableRouter: true }, + }); + + const response = await request({ + url: 'http://localhost:8378/1/apps/test/verify_email?token=invalidToken', + followRedirects: false, + }).catch(e => e); + expect(response.status).toBe(200); + expect(response.text).toContain('Invalid verification link!'); + }); + }); + describe('XSS Protection', () => { beforeEach(async () => { await reconfigureServer({ diff --git a/src/Routers/PagesRouter.js b/src/Routers/PagesRouter.js index 74beec770c..a4f7c6f89b 100644 --- a/src/Routers/PagesRouter.js +++ b/src/Routers/PagesRouter.js @@ -624,12 +624,14 @@ export class PagesRouter extends PromiseRouter { * @param {Boolean} failGracefully Is true if failing to set the config should * not result in an invalid request response. Default is `false`. */ - setConfig(req, failGracefully = false) { + async setConfig(req, failGracefully = false) { req.config = Config.get(req.params.appId || req.query.appId); if (!req.config && !failGracefully) { this.invalidRequest(); } - return Promise.resolve(); + if (req.config) { + await req.config.loadKeys(); + } } mountPagesRoutes() { @@ -637,7 +639,7 @@ export class PagesRouter extends PromiseRouter { 'GET', `/${this.pagesEndpoint}/:appId/verify_email`, req => { - this.setConfig(req); + return this.setConfig(req); }, req => { return this.verifyEmail(req); @@ -648,7 +650,7 @@ export class PagesRouter extends PromiseRouter { 'POST', `/${this.pagesEndpoint}/:appId/resend_verification_email`, req => { - this.setConfig(req); + return this.setConfig(req); }, req => { return this.resendVerificationEmail(req); @@ -659,7 +661,7 @@ export class PagesRouter extends PromiseRouter { 'GET', `/${this.pagesEndpoint}/choose_password`, req => { - this.setConfig(req); + return this.setConfig(req); }, req => { return this.passwordReset(req); @@ -670,7 +672,7 @@ export class PagesRouter extends PromiseRouter { 'POST', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { - this.setConfig(req); + return this.setConfig(req); }, req => { return this.resetPassword(req); @@ -681,7 +683,7 @@ export class PagesRouter extends PromiseRouter { 'GET', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { - this.setConfig(req); + return this.setConfig(req); }, req => { return this.requestResetPassword(req); @@ -695,7 +697,7 @@ export class PagesRouter extends PromiseRouter { route.method, `/${this.pagesEndpoint}/:appId/${route.path}`, req => { - this.setConfig(req); + return this.setConfig(req); }, async req => { const { file, query = {} } = (await route.handler(req)) || {}; @@ -718,7 +720,7 @@ export class PagesRouter extends PromiseRouter { 'GET', `/${this.pagesEndpoint}/*resource`, req => { - this.setConfig(req, true); + return this.setConfig(req, true); }, req => { return this.staticRoute(req);