From 06c7152f4b2c2a60579a5a3c60e837e82ed1099c Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Fri, 10 Jul 2020 12:07:11 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20Stripe=20webhooks=20for?= =?UTF-8?q?=20subdirectory=20setups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no-issue - Added breaking test for webhook url including subdirectory - Previously the webhook handler URL was generated incorrectly when running Ghost on a subdirectory, appending the path to the root of the host, this fix ensures that the subdirectory is included before the path. --- core/server/services/members/config.js | 2 +- test/unit/services/members/config_spec.js | 45 ++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/core/server/services/members/config.js b/core/server/services/members/config.js index 32b19e72e3..0797f14d7b 100644 --- a/core/server/services/members/config.js +++ b/core/server/services/members/config.js @@ -133,7 +133,7 @@ class MembersConfigProvider { getStripeUrlConfig() { const siteUrl = this._urlUtils.getSiteUrl(); - const webhookHandlerUrl = new URL('/members/webhooks/stripe', siteUrl); + const webhookHandlerUrl = new URL('members/webhooks/stripe/', siteUrl); const checkoutSuccessUrl = new URL(siteUrl); checkoutSuccessUrl.searchParams.set('stripe', 'success'); diff --git a/test/unit/services/members/config_spec.js b/test/unit/services/members/config_spec.js index 2465628741..10400aa320 100644 --- a/test/unit/services/members/config_spec.js +++ b/test/unit/services/members/config_spec.js @@ -1,6 +1,6 @@ const should = require('should'); +const UrlUtils = require('@tryghost/url-utils'); const MembersConfigProvider = require('../../../../core/server/services/members/config'); -const urlUtils = require('../../../../core/shared/url-utils'); const sinon = require('sinon'); /** @@ -19,7 +19,6 @@ function createConfigMock({stripeDirectValue}) { * @param {boolean} options.setDirect - Whether the "direct" keys should be set * @param {boolean} options.setConnect - Whether the connect_integration keys should be set */ - function createSettingsMock({setDirect, setConnect}) { const getStub = sinon.stub(); @@ -51,10 +50,29 @@ function createSettingsMock({setDirect, setConnect}) { }; } +function createUrlUtilsMock({url = 'http://domain.tld/subdir', adminUrl = 'http://sub.domain.tld'} = {}) { + return new UrlUtils({ + url, + adminUrl, + apiVersions: { + all: ['v3'], + v3: { + admin: 'v3/admin', + content: 'v3/content' + } + }, + defaultApiVersion: 'v3', + slugs: ['ghost', 'rss', 'amp'], + redirectCacheMaxAge: 31536000, + baseApiPath: '/ghost/api' + }); +} + describe('Members - config', function () { it('Uses direct keys when stripeDirect is true, regardles of which keys exist', function () { const config = createConfigMock({stripeDirectValue: true}); const settingsCache = createSettingsMock({setDirect: true, setConnect: Math.random() < 0.5}); + const urlUtils = createUrlUtilsMock(); const membersConfig = new MembersConfigProvider({ config, @@ -73,6 +91,7 @@ describe('Members - config', function () { it('Does not use connect keys if stripeDirect is true, and the direct keys do not exist', function () { const config = createConfigMock({stripeDirectValue: true}); const settingsCache = createSettingsMock({setDirect: false, setConnect: true}); + const urlUtils = createUrlUtilsMock(); const membersConfig = new MembersConfigProvider({ config, @@ -90,6 +109,7 @@ describe('Members - config', function () { it('Uses connect keys when stripeDirect is false, and the connect keys exist', function () { const config = createConfigMock({stripeDirectValue: false}); const settingsCache = createSettingsMock({setDirect: true, setConnect: true}); + const urlUtils = createUrlUtilsMock(); const membersConfig = new MembersConfigProvider({ config, @@ -108,6 +128,7 @@ describe('Members - config', function () { it('Uses direct keys when stripeDirect is false, but the connect keys do not exist', function () { const config = createConfigMock({stripeDirectValue: false}); const settingsCache = createSettingsMock({setDirect: true, setConnect: false}); + const urlUtils = createUrlUtilsMock(); const membersConfig = new MembersConfigProvider({ config, @@ -122,4 +143,24 @@ describe('Members - config', function () { should.equal(paymentConfig.publicKey, 'direct_publishable'); should.equal(paymentConfig.secretKey, 'direct_secret'); }); + + it('Includes the subdirectory in the webhookHandlerUrl', function () { + const config = createConfigMock({stripeDirectValue: false}); + const settingsCache = createSettingsMock({setDirect: true, setConnect: false}); + const urlUtils = createUrlUtilsMock({ + url: 'http://site.com/subdir' + }); + + const membersConfig = new MembersConfigProvider({ + config, + settingsCache, + urlUtils, + ghostVersion: {original: 'v7357'}, + logging: console + }); + + const paymentConfig = membersConfig.getStripePaymentConfig(); + + should.equal(paymentConfig.webhookHandlerUrl, 'http://site.com/subdir/members/webhooks/stripe/'); + }); });