Skip to content

Commit

Permalink
Merge pull request #1128 from CruGlobal/recaptcha-enterprise
Browse files Browse the repository at this point in the history
Update to Recaptcha Enterprise
  • Loading branch information
wrandall22 authored Jan 14, 2025
2 parents a693205 + 2dc3a44 commit 603c396
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 360 deletions.
7 changes: 6 additions & 1 deletion src/app/branded/branded-checkout.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import thankYouSummary from 'app/thankYou/summary/thankYouSummary.component'

import sessionService from 'common/services/session/session.service'
import orderService from 'common/services/api/order.service'
import checkoutService from 'common/services/checkoutHelpers/checkout.service'
import brandedAnalyticsFactory from './analytics/branded-analytics.factory'

import 'common/lib/fakeLocalStorage'
Expand All @@ -23,7 +24,7 @@ const componentName = 'brandedCheckout'

class BrandedCheckoutController {
/* @ngInject */
constructor ($element, $window, analyticsFactory, brandedAnalyticsFactory, tsysService, sessionService, envService, orderService, $translate) {
constructor ($element, $window, analyticsFactory, brandedAnalyticsFactory, tsysService, sessionService, envService, orderService, checkoutService, $translate) {
this.$element = $element[0] // extract the DOM element from the jqLite wrapper
this.$window = $window
this.analyticsFactory = analyticsFactory
Expand All @@ -33,6 +34,7 @@ class BrandedCheckoutController {
this.envService = envService
this.orderService = orderService
this.$translate = $translate
this.checkoutService = checkoutService

this.orderService.clearCoverFees()
}
Expand All @@ -57,6 +59,8 @@ class BrandedCheckoutController {
console.error(err)
})
this.$translate.use(this.language || 'en')

this.checkoutService.initializeRecaptcha()
}

formatDonorDetails () {
Expand Down Expand Up @@ -152,6 +156,7 @@ export default angular
thankYouSummary.name,
sessionService.name,
orderService.name,
checkoutService.name,
brandedAnalyticsFactory.name,
uibModal,
'environment',
Expand Down
11 changes: 10 additions & 1 deletion src/app/branded/branded-checkout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ describe('branded checkout', () => {
onOrderCompleted: jest.fn(),
onOrderFailed: jest.fn(),
},
);
)
}))

describe('$onInit', () => {
beforeEach(() => {
jest.spyOn($ctrl.checkoutService, 'initializeRecaptcha').mockImplementation(() => {})
})

it('should set API Url if custom one is set', () => {
$ctrl.apiUrl = 'https://custom-api.cru.org'
$ctrl.$onInit()
Expand All @@ -74,6 +78,11 @@ describe('branded checkout', () => {
expect($ctrl.formatDonorDetails).toHaveBeenCalled()
expect($ctrl.$window.sessionStorage.removeItem).toHaveBeenCalledWith('initialLoadComplete')
})

it('should initialize recaptcha', () => {
$ctrl.$onInit()
expect($ctrl.checkoutService.initializeRecaptcha).toHaveBeenCalled()
})
})

describe('formatDonorDetails', () => {
Expand Down
5 changes: 0 additions & 5 deletions src/app/checkout/cart-summary/cart-summary.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import template from './cart-summary.tpl.html'

const componentName = 'checkoutCartSummary'

export const recaptchaFailedEvent = 'recaptchaFailedEvent'
export const submitOrderEvent = 'submitOrderEvent'

class CartSummaryController {
Expand All @@ -22,10 +21,6 @@ class CartSummaryController {
return this.cartService.buildCartUrl()
}

handleRecaptchaFailure (componentInstance) {
componentInstance.$rootScope.$emit(recaptchaFailedEvent)
}

onSubmit (componentInstance) {
componentInstance.$rootScope.$emit(submitOrderEvent)
}
Expand Down
8 changes: 0 additions & 8 deletions src/app/checkout/cart-summary/cart-summary.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,5 @@ describe('checkout', function () {
expect(componentInstance.$rootScope.$emit).toHaveBeenCalledWith(submitOrderEvent)
})
})

describe('handleRecaptchaFailure', () => {
it('should emit an event', () => {
jest.spyOn(componentInstance.$rootScope, '$emit').mockImplementation(() => {})
self.controller.handleRecaptchaFailure(componentInstance)
expect(componentInstance.$rootScope.$emit).toHaveBeenCalledWith(recaptchaFailedEvent)
})
})
})
})
3 changes: 1 addition & 2 deletions src/app/checkout/cart-summary/cart-summary.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ <h3 id="cart-summary-header" class="panel-name" translate>Cart Summary</h3>
<a id="editCartButton" ng-href="{{$ctrl.buildCartUrl()}}" class="btn btn-subtle mt" translate>Edit Cart</a>
<recaptcha-wrapper
ng-if="$ctrl.showSubmitBtn"
action="'submit_gift'"
action="'checkout'"
on-success="$ctrl.onSubmit"
on-failure="$ctrl.handleRecaptchaFailure"
component-instance="$ctrl.componentReference"
button-id="'submitGiftButton'"
button-type="'submit'"
Expand Down
7 changes: 6 additions & 1 deletion src/app/checkout/checkout.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import showErrors from 'common/filters/showErrors.filter'
import cartService from 'common/services/api/cart.service'
import orderService from 'common/services/api/order.service'
import designationsService from 'common/services/api/designations.service'
import checkoutService from 'common/services/checkoutHelpers/checkout.service'

import sessionEnforcerService, { EnforcerCallbacks } from 'common/services/session/sessionEnforcer.service'
import { Roles, SignOutEvent } from 'common/services/session/session.service'
Expand All @@ -27,7 +28,7 @@ const componentName = 'checkout'

class CheckoutController {
/* @ngInject */
constructor ($window, $location, $rootScope, $log, cartService, envService, orderService, designationsService, sessionEnforcerService, analyticsFactory) {
constructor ($window, $location, $rootScope, $log, cartService, envService, orderService, designationsService, sessionEnforcerService, checkoutService, analyticsFactory) {
this.$log = $log
this.$window = $window
this.$location = $location
Expand All @@ -40,6 +41,7 @@ class CheckoutController {
this.loadingCartData = true
this.analyticsFactory = analyticsFactory
this.selfReference = this
this.checkoutService = checkoutService
}

$onInit () {
Expand All @@ -56,6 +58,8 @@ class CheckoutController {
this.initStepParam(true)
this.listenForLocationChange()
this.analyticsFactory.pageLoaded(true)

this.checkoutService.initializeRecaptcha()
}

$onDestroy () {
Expand Down Expand Up @@ -146,6 +150,7 @@ export default angular
orderService.name,
designationsService.name,
sessionEnforcerService.name,
checkoutService.name,
showErrors.name,
analyticsFactory.name
])
Expand Down
2 changes: 2 additions & 0 deletions src/app/checkout/checkout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('checkout', function () {
jest.spyOn(self.controller, 'sessionEnforcerService').mockImplementation(() => {})
jest.spyOn(self.controller.$rootScope, '$on').mockImplementation(() => {})
jest.spyOn(self.controller, 'signedOut').mockImplementation(() => {})
jest.spyOn(self.controller.checkoutService, 'initializeRecaptcha').mockImplementation(() => {})
self.controller.$onInit()
})

Expand All @@ -53,6 +54,7 @@ describe('checkout', function () {
self.controller.$rootScope.$on.mock.calls[0][1]()

expect(self.controller.signedOut).toHaveBeenCalled()
expect(self.controller.checkoutService.initializeRecaptcha).toHaveBeenCalled()
})

describe('sessionEnforcerService success', () => {
Expand Down
17 changes: 1 addition & 16 deletions src/app/checkout/step-3/step-3.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { datadogRum } from '@datadog/browser-rum'
import template from './step-3.tpl.html'

import analyticsFactory from 'app/analytics/analytics.factory'
import { recaptchaFailedEvent, submitOrderEvent } from 'app/checkout/cart-summary/cart-summary.component'
import { submitOrderEvent } from 'app/checkout/cart-summary/cart-summary.component'

const componentName = 'checkoutStep3'

Expand All @@ -46,9 +46,6 @@ class Step3Controller {
this.$onInit()
})

this.$rootScope.$on(recaptchaFailedEvent, () => {
this.handleRecaptchaFailure(this)
})
this.$rootScope.$on(submitOrderEvent, () => {
this.submitOrder()
})
Expand Down Expand Up @@ -183,18 +180,6 @@ class Step3Controller {
componentInstance.$window.scrollTo(0, 0)
})
}

handleRecaptchaFailure (componentInstance) {
componentInstance.analyticsFactory.checkoutFieldError('submitOrder', 'failed')
componentInstance.submittingOrder = false
componentInstance.onSubmittingOrder({ value: false })

componentInstance.loadCart()

componentInstance.onSubmitted()
componentInstance.submissionError = 'generic error'
componentInstance.$window.scrollTo(0, 0)
}
}

export default angular
Expand Down
22 changes: 0 additions & 22 deletions src/app/checkout/step-3/step-3.component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,34 +448,12 @@ describe('checkout', () => {
})
})

describe('handleRecaptchaFailure', () => {
it('should show an error if recaptcha fails', () => {
const componentInstance = self.controller
jest.spyOn(componentInstance.analyticsFactory, 'checkoutFieldError').mockImplementation(() => {})
self.controller.handleRecaptchaFailure(componentInstance)

expect(componentInstance.analyticsFactory.checkoutFieldError).toHaveBeenCalledWith('submitOrder', 'failed')
expect(componentInstance.submittingOrder).toEqual(false)
expect(componentInstance.onSubmittingOrder).toHaveBeenCalledWith({ value: false })
expect(componentInstance.loadCart).toHaveBeenCalled()
expect(componentInstance.onSubmitted).toHaveBeenCalled()
expect(componentInstance.submissionError).toEqual('generic error')
expect(componentInstance.$window.scrollTo).toHaveBeenCalledWith(0, 0)
})
})

describe('event handling', () => {
it('should call submit order if the submitOrderEvent is received', () => {
jest.spyOn(self.controller, 'submitOrder').mockImplementation(() => {})
self.controller.$rootScope.$emit(submitOrderEvent)
expect(self.controller.submitOrder).toHaveBeenCalled()
})

it('should call handleRecaptchaFailure if the recaptchaFailedEvent is received', () => {
jest.spyOn(self.controller, 'handleRecaptchaFailure').mockImplementation(() => {})
self.controller.$rootScope.$emit(recaptchaFailedEvent)
expect(self.controller.handleRecaptchaFailure).toHaveBeenCalledWith(self.controller)
})
})
})
})
3 changes: 1 addition & 2 deletions src/app/checkout/step-3/step-3.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,8 @@
</div>
<div class="checkout-cta pull-right">
<recaptcha-wrapper
action="$ctrl.isBranded ? 'branded_submit' : 'submit_gift'"
action="$ctrl.isBranded ? 'branded_checkout' : 'checkout'"
on-success="$ctrl.submitOrderInternal"
on-failure="$ctrl.handleRecaptchaFailure"
component-instance="$ctrl.selfReference"
button-id="'submitOrderButton'"
button-type="'submit'"
Expand Down
12 changes: 6 additions & 6 deletions src/common/app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://stage.cru.org',
publicGive: 'https://give-stage2.cru.org',
acsUrl: 'https://cru-mkt-stage1.adobe-campaign.com/lp/LP63?_uuid=f1938f90-38ea-41a6-baad-9ac133f6d2ec&service=%404k83N_C5RZnLNvwz7waA2SwyzIuP6ATcN8vJjmT5km0iZPYKUUYk54sthkZjj-hltAuOKDYocuEi5Pxv8BSICoA4uppcvU_STKCzjv9RzLpE4hqj&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LcCMoYqAAAAABMoyLs5CyKWwE8qn_YslEaiRPRD'
},
devcloud: {
apiUrl: 'https://give-stage2.cru.org',
Expand All @@ -63,7 +63,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://stage-cloud.cru.org',
publicGive: 'https://give-dev-cloud.cru.org',
acsUrl: 'https://cru-mkt-stage1.adobe-campaign.com/lp/LP63?_uuid=f1938f90-38ea-41a6-baad-9ac133f6d2ec&service=%404k83N_C5RZnLNvwz7waA2SwyzIuP6ATcN8vJjmT5km0iZPYKUUYk54sthkZjj-hltAuOKDYocuEi5Pxv8BSICoA4uppcvU_STKCzjv9RzLpE4hqj&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LcCMoYqAAAAABMoyLs5CyKWwE8qn_YslEaiRPRD'
},
stagecloud: {
apiUrl: 'https://give-stage-cloud.cru.org',
Expand All @@ -72,7 +72,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://stage-cloud.cru.org',
publicGive: 'https://give-stage-cloud.cru.org',
acsUrl: 'https://cru-mkt-stage1.adobe-campaign.com/lp/LP63?_uuid=f1938f90-38ea-41a6-baad-9ac133f6d2ec&service=%404k83N_C5RZnLNvwz7waA2SwyzIuP6ATcN8vJjmT5km0iZPYKUUYk54sthkZjj-hltAuOKDYocuEi5Pxv8BSICoA4uppcvU_STKCzjv9RzLpE4hqj&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LcCMoYqAAAAABMoyLs5CyKWwE8qn_YslEaiRPRD'
},
prodcloud: {
apiUrl: 'https://give-prod-cloud.cru.org',
Expand All @@ -81,7 +81,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://www.cru.org',
publicGive: 'https://give-prod-cloud.cru.org',
acsUrl: 'https://cru-mkt-prod1-m.adobe-campaign.com/lp/LPEmailPrefCenter?_uuid=8831d67a-0d46-406b-8987-fd07c97c4ca7&service=%400fAlW4GPmxXExp8qlx7HDlAM6FSZUd0yYRlQg6HRsO_kglfi0gs650oHPZX6LrOvg7OHoIWWpobOeGZduxdNU_m5alc&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LduSiQqAAAAAOLA7NEU8-3-mdCmBKEUCwaFQuJF'
},
staging: {
apiUrl: 'https://give-stage2.cru.org',
Expand All @@ -90,7 +90,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://stage.cru.org',
publicGive: 'https://give-stage2.cru.org',
acsUrl: 'https://cru-mkt-stage1.adobe-campaign.com/lp/LP63?_uuid=f1938f90-38ea-41a6-baad-9ac133f6d2ec&service=%404k83N_C5RZnLNvwz7waA2SwyzIuP6ATcN8vJjmT5km0iZPYKUUYk54sthkZjj-hltAuOKDYocuEi5Pxv8BSICoA4uppcvU_STKCzjv9RzLpE4hqj&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LcCMoYqAAAAABMoyLs5CyKWwE8qn_YslEaiRPRD'
},
nonprod: {
apiUrl: 'https://give-stage2-next.cru.org',
Expand All @@ -116,7 +116,7 @@ export const appConfig = /* @ngInject */ function (envServiceProvider, $compileP
publicCru: 'https://www.cru.org',
publicGive: 'https://give.cru.org',
acsUrl: 'https://cru-mkt-prod1-m.adobe-campaign.com/lp/LPEmailPrefCenter?_uuid=8831d67a-0d46-406b-8987-fd07c97c4ca7&service=%400fAlW4GPmxXExp8qlx7HDlAM6FSZUd0yYRlQg6HRsO_kglfi0gs650oHPZX6LrOvg7OHoIWWpobOeGZduxdNU_m5alc&pkey=',
recaptchaKey: '6LdNz5UlAAAAAPSrzydROuY76yGVIquVQAup69PO'
recaptchaKey: '6LduSiQqAAAAAOLA7NEU8-3-mdCmBKEUCwaFQuJF'
},
defaults: {
isCheckout: false,
Expand Down
Loading

0 comments on commit 603c396

Please sign in to comment.