Merge pull request #14861 from overleaf/jpa-web-restrict-new-subscription

[web] block web sales to restricted countries

GitOrigin-RevId: 21029cf016eaa0c63ce6939ab8681979118a9dc4
This commit is contained in:
Brian Gough 2023-09-20 15:09:57 +01:00 committed by Copybot
parent 1ef6c70258
commit 2e00894270
3 changed files with 42 additions and 4 deletions

View file

@ -227,7 +227,7 @@ async function paymentPage(req, res) {
} }
// Block web sales to restricted countries // Block web sales to restricted countries
if (['CU', 'IR', 'KP', 'RU', 'SY', 'VE'].includes(countryCode)) { if (Settings.restrictedCountries.includes(countryCode)) {
return res.render('subscriptions/restricted-country', { return res.render('subscriptions/restricted-country', {
title: 'restricted', title: 'restricted',
}) })
@ -510,6 +510,19 @@ async function createSubscription(req, res) {
return res.sendStatus(409) // conflict return res.sendStatus(409) // conflict
} }
const { countryCode } = await _getRecommendedCurrency(req, res)
// Block web sales to restricted countries
if (Settings.restrictedCountries.includes(countryCode)) {
return HttpErrorHandler.unprocessableEntity(
req,
res,
req.i18n.translate('sorry_detected_sales_restricted_region', {
link: '/contact',
})
)
}
const result = {} const result = {}
await Modules.promises.hooks.fire( await Modules.promises.hooks.fire(
'createSubscription', 'createSubscription',

View file

@ -347,6 +347,7 @@ module.exports = {
], ],
enableSubscriptions: false, enableSubscriptions: false,
restrictedCountries: [],
enabledLinkedFileTypes: (process.env.ENABLED_LINKED_FILE_TYPES || '').split( enabledLinkedFileTypes: (process.env.ENABLED_LINKED_FILE_TYPES || '').split(
',' ','

View file

@ -85,6 +85,7 @@ describe('SubscriptionController', function () {
.returns({ plans: [], planCodesChangingAtTermEnd: [] }), .returns({ plans: [], planCodesChangingAtTermEnd: [] }),
} }
this.settings = { this.settings = {
restrictedCountries: ['KP'],
coupon_codes: { coupon_codes: {
upgradeToAnnualPromo: { upgradeToAnnualPromo: {
student: 'STUDENTCODEHERE', student: 'STUDENTCODEHERE',
@ -116,9 +117,12 @@ describe('SubscriptionController', function () {
} }
this.GeoIpLookup = { this.GeoIpLookup = {
isValidCurrencyParam: sinon.stub().returns(true), isValidCurrencyParam: sinon.stub().returns(true),
getCurrencyCode: sinon.stub(), getCurrencyCode: sinon.stub().yields('USD', 'US'),
promises: { promises: {
getCurrencyCode: sinon.stub(), getCurrencyCode: sinon.stub().resolves({
countryCode: 'US',
currencyCode: 'USD',
}),
}, },
} }
this.UserGetter = { this.UserGetter = {
@ -161,7 +165,10 @@ describe('SubscriptionController', function () {
'./GroupPlansData': (this.GroupPlansData = {}), './GroupPlansData': (this.GroupPlansData = {}),
'./V1SubscriptionManager': (this.V1SubscriptionManager = {}), './V1SubscriptionManager': (this.V1SubscriptionManager = {}),
'../Errors/HttpErrorHandler': (this.HttpErrorHandler = { '../Errors/HttpErrorHandler': (this.HttpErrorHandler = {
unprocessableEntity: sinon.stub(), unprocessableEntity: sinon.stub().callsFake((req, res, message) => {
res.status(422)
res.json({ message })
}),
}), }),
'./Errors': SubscriptionErrors, './Errors': SubscriptionErrors,
'../Analytics/AnalyticsManager': (this.AnalyticsManager = { '../Analytics/AnalyticsManager': (this.AnalyticsManager = {
@ -599,6 +606,23 @@ describe('SubscriptionController', function () {
}) })
}) })
it('should handle restricted country', function (done) {
this.GeoIpLookup.promises.getCurrencyCode.resolves({
countryCode: 'KP',
})
this.res.callback = () => {
expect(this.res.statusCode).to.equal(422)
expect(this.res.body).to.include(
'sorry_detected_sales_restricted_region'
)
this.SubscriptionHandler.promises.createSubscription.called.should.equal(
false
)
done()
}
this.SubscriptionController.createSubscription(this.req, this.res)
})
it('should handle 3DSecure errors/recurly transaction errors', function (done) { it('should handle 3DSecure errors/recurly transaction errors', function (done) {
this.LimitationsManager.promises.userHasV1OrV2Subscription.resolves(false) this.LimitationsManager.promises.userHasV1OrV2Subscription.resolves(false)
this.SubscriptionHandler.promises.createSubscription.rejects( this.SubscriptionHandler.promises.createSubscription.rejects(