Jelajahi Sumber

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

[web] block web sales to restricted countries

GitOrigin-RevId: 21029cf016eaa0c63ce6939ab8681979118a9dc4
Brian Gough 2 tahun lalu
induk
melakukan
2e00894270

+ 14 - 1
services/web/app/src/Features/Subscription/SubscriptionController.js

@@ -227,7 +227,7 @@ async function paymentPage(req, res) {
       }
 
       // 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', {
           title: 'restricted',
         })
@@ -510,6 +510,19 @@ async function createSubscription(req, res) {
     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 = {}
   await Modules.promises.hooks.fire(
     'createSubscription',

+ 1 - 0
services/web/config/settings.defaults.js

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

+ 27 - 3
services/web/test/unit/src/Subscription/SubscriptionControllerTests.js

@@ -85,6 +85,7 @@ describe('SubscriptionController', function () {
         .returns({ plans: [], planCodesChangingAtTermEnd: [] }),
     }
     this.settings = {
+      restrictedCountries: ['KP'],
       coupon_codes: {
         upgradeToAnnualPromo: {
           student: 'STUDENTCODEHERE',
@@ -116,9 +117,12 @@ describe('SubscriptionController', function () {
     }
     this.GeoIpLookup = {
       isValidCurrencyParam: sinon.stub().returns(true),
-      getCurrencyCode: sinon.stub(),
+      getCurrencyCode: sinon.stub().yields('USD', 'US'),
       promises: {
-        getCurrencyCode: sinon.stub(),
+        getCurrencyCode: sinon.stub().resolves({
+          countryCode: 'US',
+          currencyCode: 'USD',
+        }),
       },
     }
     this.UserGetter = {
@@ -161,7 +165,10 @@ describe('SubscriptionController', function () {
         './GroupPlansData': (this.GroupPlansData = {}),
         './V1SubscriptionManager': (this.V1SubscriptionManager = {}),
         '../Errors/HttpErrorHandler': (this.HttpErrorHandler = {
-          unprocessableEntity: sinon.stub(),
+          unprocessableEntity: sinon.stub().callsFake((req, res, message) => {
+            res.status(422)
+            res.json({ message })
+          }),
         }),
         './Errors': SubscriptionErrors,
         '../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) {
       this.LimitationsManager.promises.userHasV1OrV2Subscription.resolves(false)
       this.SubscriptionHandler.promises.createSubscription.rejects(