@govuk-pay/pay-js-commons 3.8.4 → 3.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <code_scheme name="Project" version="173">
3
+ <ScalaCodeStyleSettings>
4
+ <option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
5
+ </ScalaCodeStyleSettings>
6
+ </code_scheme>
7
+ </component>
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
+ </state>
5
+ </component>
package/.idea/misc.xml ADDED
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MavenImportPreferences">
4
+ <option name="generalSettings">
5
+ <MavenGeneralSettings>
6
+ <option name="mavenHome" value="$APPLICATION_HOME_DIR$/plugins/maven/lib/maven3" />
7
+ </MavenGeneralSettings>
8
+ </option>
9
+ </component>
10
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
11
+ <output url="file://$PROJECT_DIR$/out" />
12
+ </component>
13
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/pay-js-commons.iml" filepath="$PROJECT_DIR$/.idea/pay-js-commons.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="JAVA_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="inheritedJdk" />
7
+ <orderEntry type="sourceFolder" forTests="false" />
8
+ </component>
9
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -1,23 +1,31 @@
1
1
  "use strict";
2
2
 
3
3
  var fs = require('fs');
4
+
4
5
  var Cookies = require('js-cookie');
6
+
5
7
  var path = require('path');
8
+
6
9
  var template = fs.readFileSync(path.join(__dirname, 'banner.html'), 'utf-8');
7
10
  var GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME = 'govuk_pay_cookie_policy';
8
11
  var ANALYTICS_CONSENT_BANNER_ID = 'pay-cookie-banner';
12
+
9
13
  function hasAnalyticsConsent() {
10
14
  var cookie = Cookies.get(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME);
11
15
  var parsed = cookie && JSON.parse(cookie);
12
16
  return Boolean(parsed) && parsed.analytics === true;
13
17
  }
18
+
14
19
  function getCookieDomain() {
15
20
  var PROD_HOSTNAME = 'payments.service.gov.uk';
21
+
16
22
  if (window.location.hostname.includes(PROD_HOSTNAME)) {
17
23
  return PROD_HOSTNAME;
18
24
  }
25
+
19
26
  return undefined;
20
27
  }
28
+
21
29
  function setAnalyticsCookie() {
22
30
  var userConsentedToAnalytics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
23
31
  var cookieValue = JSON.stringify({
@@ -30,15 +38,19 @@ function setAnalyticsCookie() {
30
38
  };
31
39
  Cookies.set(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME, cookieValue, cookieAttributes);
32
40
  }
41
+
33
42
  function hideBannerIfExists(event) {
34
43
  var banner = document.querySelector("#".concat(ANALYTICS_CONSENT_BANNER_ID));
44
+
35
45
  if (banner) {
36
46
  banner.style.display = 'none';
37
47
  }
48
+
38
49
  if (event.target) {
39
50
  event.preventDefault();
40
51
  }
41
52
  }
53
+
42
54
  function showConfirmationMessage(analyticsConsent) {
43
55
  var messagePrefix = analyticsConsent ? 'You’ve accepted analytics cookies.' : 'You told us not to use analytics cookies.';
44
56
  var $cookieBannerMainContent = document.querySelector('.pay-cookie-banner__wrapper');
@@ -48,14 +60,17 @@ function showConfirmationMessage(analyticsConsent) {
48
60
  var $cookieBannerConfirmationWrapper = document.querySelector('.pay-cookie-banner__confirmation');
49
61
  $cookieBannerConfirmationWrapper.style.display = 'block';
50
62
  }
63
+
51
64
  function acceptAnalyticsCookies() {
52
65
  setAnalyticsCookie(true);
53
66
  showConfirmationMessage(true);
54
67
  }
68
+
55
69
  function rejectAnalyticsCookies() {
56
70
  setAnalyticsCookie(false);
57
71
  showConfirmationMessage(false);
58
72
  }
73
+
59
74
  function createBannerHTMLElement() {
60
75
  var consentProvidedCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
61
76
  var banner = document.createElement('div');
@@ -63,31 +78,39 @@ function createBannerHTMLElement() {
63
78
  banner.innerHTML = template.trim();
64
79
  var acceptButton = banner.querySelector('button[data-accept-cookies=true]');
65
80
  var rejectButton = banner.querySelector('button[data-accept-cookies=false]');
81
+
66
82
  if (acceptButton && rejectButton) {
67
83
  acceptButton.addEventListener('click', acceptAnalyticsCookies);
68
84
  acceptButton.addEventListener('click', consentProvidedCallback);
69
85
  rejectButton.addEventListener('click', rejectAnalyticsCookies);
70
86
  }
87
+
71
88
  var hideCookieBannerLink = banner.querySelector('button[data-hide-cookie-banner]');
89
+
72
90
  if (hideCookieBannerLink) {
73
91
  hideCookieBannerLink.addEventListener('click', hideBannerIfExists);
74
92
  }
93
+
75
94
  return banner;
76
95
  }
77
-
78
96
  /**
79
97
  * ConsentProvidedCallback: function - generic callback that will be called
80
98
  * if and only if the user provides consent
81
99
  */
100
+
101
+
82
102
  function showBannerIfConsentNotSet() {
83
103
  var consentProvidedCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
84
104
  var consentCookieNotSet = !Cookies.get(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME);
85
105
  var banner = document.querySelector("#".concat(ANALYTICS_CONSENT_BANNER_ID));
106
+
86
107
  if (consentCookieNotSet && !banner) {
87
108
  var _banner = createBannerHTMLElement(consentProvidedCallback);
109
+
88
110
  document.body.prepend(_banner);
89
111
  }
90
112
  }
113
+
91
114
  module.exports = {
92
115
  hasAnalyticsConsent: hasAnalyticsConsent,
93
116
  showBannerIfConsentNotSet: showBannerIfConsentNotSet
@@ -870,22 +870,29 @@ process.umask = function() { return 0; };
870
870
  "use strict";
871
871
 
872
872
  var Cookies = require('js-cookie');
873
+
873
874
  var path = require('path');
875
+
874
876
  var template = "<style>\n\t/* component should only be shown if JS is available, by the cookieMessage JS, so hide by default */\n\t.pay-cookie-banner {\n\t\tdisplay: block;\n\t}\n\n\t.pay-cookie-banner__wrapper {\n\t\tpadding-top: 15px;\n \tpadding-bottom: 15px;\n\t}\n\n\t.pay-cookie-banner__buttons {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap;\n\t}\n\n\t@media (min-width: 40.0625em){\n\t\t.pay-cookie-banner__buttons {\n\t\t\tflex-wrap: nowrap;\n\t\t}\n\t}\n\n\n\t.pay-cookie-banner__button,\n\t.pay-cookie-banner__link {\n\t\tvertical-align: baseline;\n\t}\n\n\t.pay-cookie-banner__button {\n\t\tdisplay: inline-block;\n\t\tflex: 1 0;\n\t\tpadding-left: 60px;\n\t\tpadding-right: 60px;\n\t\tmargin-bottom: 10px;\n\t\tmargin-right: 20px;\n\t}\n\n\t@media (min-width: 40.0625em){\n\t\t.pay-cookie-banner__button {\n\t\t\tflex: 0 0 150px;\n\t\t\tpadding-left: 10px;\n\t\t\tpadding-right: 10px;\n\t\t\tmargin-bottom: 5px;\n\t\t}\n\t}\n\t\n\t.pay-cookie-banner__link {\n\t\tfont-family: \"GDS Transport\", Arial, sans-serif;\n\t\tfont-weight: 400;\n\t\tfont-size: 16px;\n\t\tfont-size: 1rem;\n\t\tline-height: 1.25;\n\t\tline-height: 1;\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t padding: 9px 0px 6px;\n\t}\n\t\n\t@media (min-width: 40.0625em){\n\t\t.pay-cookie-banner__link {\n\t\t\tdisplay: inline;\n\t\t\twidth: auto;\n\t\t\tmargin-left: 30px;\n\t\t}\n\t}\n\n\n\t.pay-cookie-banner__confirmation {\n\t\tdisplay: none;\n\t\tposition: relative;\n\t\tpadding: 20px 0;\n\n\t\t\n\t}\n\n\t/* This element is focused using JavaScript so that it's being read out by screen readers\n\tor this reason we don't want to show the default outline or emphasise it visually using `govuk-focused-text`*/\n\t.pay-cookie-banner__confirmation:focus {\n\t outline: none;\n\t}\n\n\n\t.pay-cookie-banner__confirmation-message,\n\t.pay-cookie-banner__hide-button {\n\t\tdisplay: block;\n\t}\n\n\n\t@media (min-width: 48.0625em){\n\t\t.pay-cookie-banner__confirmation-message, \n\t\t.pay-cookie-banner__hide-button {\n\t\t display: inline-block;\n\t\t}\n\t}\n\n\t.pay-cookie-banner__confirmation-message {\n\t\tmargin-right: 20px;\n\t}\n\n\t@media (min-width: 48.0625em){\n\t\t.pay-cookie-banner__confirmation-message {\n\t\t\tmax-width: 90%;\n\t\t}\n\t}\n\n\t.pay-cookie-banner__hide-button {\n\t\tfont-family: \"GDS Transport\", Arial, sans-serif;\n\t\tfont-weight: 400;\n\t\tfont-size: 16px;\n\t\tfont-size: 1rem;\n\t\tline-height: 1.25;\n\t\tcolor: #1d70b8;\n\t\toutline: 0;\n\t\tborder: 0;\n\t\tbackground: none;\n\t\ttext-decoration: underline;\n\t\tpadding: 0;\n\t\tmargin-top: 10px;\n\t\tright: 15px;\n\t\tcursor: pointer;\n\t}\n\n\t@media (min-width: 40.0625em){\n\t\t.pay-cookie-banner__hide-button {\n\t\t\tfont-size: 19px;\n\t\t\tfont-size: 1.1875rem;\n\t\t\tline-height: 1.3157894737;\n\t\t}\n\t}\n</style>\n<div id=\"pay-cookie-banner\" class=\"pay-cookie-banner govuk-width-container\" data-module=\"pay-cookie-banner\" role=\"region\" aria-label=\"cookie banner\">\n\t<div class=\"pay-cookie-banner__wrapper\">\n\t\t<h2 class=\"pay-cookie-banner__heading govuk-heading-m\" id=\"pay-cookie-banner__heading\">\n\t\t\tCan we store analytics cookies on your device?\n\t\t</h2>\n\t\t<p class=\"govuk-body\">\n\t\t\tAnalytics cookies help us understand how our website is being used.\n\t\t</p>\n\t\t<div class=\"pay-cookie-banner__buttons\">\n\t\t\t<button class=\"govuk-button pay-cookie-banner__button pay-cookie-banner__button--accept\" type=\"submit\" data-accept-cookies=\"true\" aria-describedby=\"pay-cookie-banner__heading\">\n\t\t\t\tYes<span class=\"govuk-visually-hidden\">, GOV.UK Pay can store analytics cookies on your device</span>\n\t\t\t</button>\n\t\t\t<button class=\"govuk-button pay-cookie-banner__button pay-cookie-banner__button--reject\" type=\"submit\" data-accept-cookies=\"false\" aria-describedby=\"pay-cookie-banner__heading\">\n\t\t\t\tNo<span class=\"govuk-visually-hidden\">, GOV.UK Pay cannot store analytics cookies on your device</span>\n\t\t\t</button>\n\t\t\t<a class=\"govuk-link pay-cookie-banner__link\" href=\"https://www.payments.service.gov.uk/cookies\">How GOV.UK Pay uses cookies</a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"pay-cookie-banner__confirmation\" tabindex=\"-1\">\n\t\t<p class=\"pay-cookie-banner__confirmation-message govuk-body\">\n\t\t\tYou can <a class=\"govuk-link\" href=\"https://www.payments.service.gov.uk/cookies/\">change your cookie settings</a> at any time.\n\t\t</p>\n\t\t<button class=\"pay-cookie-banner__hide-button govuk-link\" data-hide-cookie-banner=\"true\" role=\"link\">Hide</button>\n\t</div>\n</div>\n";
875
877
  var GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME = 'govuk_pay_cookie_policy';
876
878
  var ANALYTICS_CONSENT_BANNER_ID = 'pay-cookie-banner';
879
+
877
880
  function hasAnalyticsConsent() {
878
881
  var cookie = Cookies.get(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME);
879
882
  var parsed = cookie && JSON.parse(cookie);
880
883
  return Boolean(parsed) && parsed.analytics === true;
881
884
  }
885
+
882
886
  function getCookieDomain() {
883
887
  var PROD_HOSTNAME = 'payments.service.gov.uk';
888
+
884
889
  if (window.location.hostname.includes(PROD_HOSTNAME)) {
885
890
  return PROD_HOSTNAME;
886
891
  }
892
+
887
893
  return undefined;
888
894
  }
895
+
889
896
  function setAnalyticsCookie() {
890
897
  var userConsentedToAnalytics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
891
898
  var cookieValue = JSON.stringify({
@@ -898,15 +905,19 @@ function setAnalyticsCookie() {
898
905
  };
899
906
  Cookies.set(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME, cookieValue, cookieAttributes);
900
907
  }
908
+
901
909
  function hideBannerIfExists(event) {
902
910
  var banner = document.querySelector("#".concat(ANALYTICS_CONSENT_BANNER_ID));
911
+
903
912
  if (banner) {
904
913
  banner.style.display = 'none';
905
914
  }
915
+
906
916
  if (event.target) {
907
917
  event.preventDefault();
908
918
  }
909
919
  }
920
+
910
921
  function showConfirmationMessage(analyticsConsent) {
911
922
  var messagePrefix = analyticsConsent ? 'You’ve accepted analytics cookies.' : 'You told us not to use analytics cookies.';
912
923
  var $cookieBannerMainContent = document.querySelector('.pay-cookie-banner__wrapper');
@@ -916,14 +927,17 @@ function showConfirmationMessage(analyticsConsent) {
916
927
  var $cookieBannerConfirmationWrapper = document.querySelector('.pay-cookie-banner__confirmation');
917
928
  $cookieBannerConfirmationWrapper.style.display = 'block';
918
929
  }
930
+
919
931
  function acceptAnalyticsCookies() {
920
932
  setAnalyticsCookie(true);
921
933
  showConfirmationMessage(true);
922
934
  }
935
+
923
936
  function rejectAnalyticsCookies() {
924
937
  setAnalyticsCookie(false);
925
938
  showConfirmationMessage(false);
926
939
  }
940
+
927
941
  function createBannerHTMLElement() {
928
942
  var consentProvidedCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
929
943
  var banner = document.createElement('div');
@@ -931,31 +945,39 @@ function createBannerHTMLElement() {
931
945
  banner.innerHTML = template.trim();
932
946
  var acceptButton = banner.querySelector('button[data-accept-cookies=true]');
933
947
  var rejectButton = banner.querySelector('button[data-accept-cookies=false]');
948
+
934
949
  if (acceptButton && rejectButton) {
935
950
  acceptButton.addEventListener('click', acceptAnalyticsCookies);
936
951
  acceptButton.addEventListener('click', consentProvidedCallback);
937
952
  rejectButton.addEventListener('click', rejectAnalyticsCookies);
938
953
  }
954
+
939
955
  var hideCookieBannerLink = banner.querySelector('button[data-hide-cookie-banner]');
956
+
940
957
  if (hideCookieBannerLink) {
941
958
  hideCookieBannerLink.addEventListener('click', hideBannerIfExists);
942
959
  }
960
+
943
961
  return banner;
944
962
  }
945
-
946
963
  /**
947
964
  * ConsentProvidedCallback: function - generic callback that will be called
948
965
  * if and only if the user provides consent
949
966
  */
967
+
968
+
950
969
  function showBannerIfConsentNotSet() {
951
970
  var consentProvidedCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
952
971
  var consentCookieNotSet = !Cookies.get(GOVUK_PAY_ANALYTICS_CONSENT_COOKIE_NAME);
953
972
  var banner = document.querySelector("#".concat(ANALYTICS_CONSENT_BANNER_ID));
973
+
954
974
  if (consentCookieNotSet && !banner) {
955
975
  var _banner = createBannerHTMLElement(consentProvidedCallback);
976
+
956
977
  document.body.prepend(_banner);
957
978
  }
958
979
  }
980
+
959
981
  module.exports = {
960
982
  hasAnalyticsConsent: hasAnalyticsConsent,
961
983
  showBannerIfConsentNotSet: showBannerIfConsentNotSet
@@ -965,6 +987,7 @@ module.exports = {
965
987
  "use strict";
966
988
 
967
989
  var cookies = require('./cookies/validate');
990
+
968
991
  window.GovUkPay = {
969
992
  cookies: cookies
970
993
  };
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var cookies = require('./cookies/validate');
4
+
4
5
  window.GovUkPay = {
5
6
  cookies: cookies
6
7
  };
@@ -1,10 +1,10 @@
1
- 'use strict';
1
+ 'use strict'; // NPM Dependencies
2
+
3
+ var every = require('lodash/every'); // Local Dependencies
2
4
 
3
- // NPM Dependencies
4
- var every = require('lodash/every');
5
5
 
6
- // Local Dependencies
7
6
  var checks = require('../../utils/field-validation-checks');
7
+
8
8
  exports.enableFieldValidation = function () {
9
9
  var allForms = Array.prototype.slice.call(document.getElementsByTagName('form'));
10
10
  allForms.filter(function (form) {
@@ -13,6 +13,7 @@ exports.enableFieldValidation = function () {
13
13
  return form.addEventListener('submit', initValidation, false);
14
14
  });
15
15
  };
16
+
16
17
  function initValidation(e) {
17
18
  var form = e.target;
18
19
  e.preventDefault();
@@ -20,12 +21,14 @@ function initValidation(e) {
20
21
  var validatedFields = findFields(form).map(function (field) {
21
22
  return validateField(form, field);
22
23
  });
24
+
23
25
  if (every(validatedFields)) {
24
26
  form.submit();
25
27
  } else {
26
28
  populateErrorSummary(form);
27
29
  }
28
30
  }
31
+
29
32
  function clearPreviousErrors() {
30
33
  var previousErrorsMessages = Array.prototype.slice.call(document.querySelectorAll('.error-message, .error-summary'));
31
34
  var previousErrorsFields = Array.prototype.slice.call(document.querySelectorAll('.form-group.error'));
@@ -36,12 +39,14 @@ function clearPreviousErrors() {
36
39
  return errorField.classList.remove('error');
37
40
  });
38
41
  }
42
+
39
43
  function findFields(form) {
40
44
  var formFields = Array.prototype.slice.call(form.querySelectorAll('input, textarea, select'));
41
45
  return formFields.filter(function (field) {
42
46
  return field.hasAttribute('data-validate');
43
47
  });
44
48
  }
49
+
45
50
  function validateField(form, field) {
46
51
  var result;
47
52
  var validationTypes = field.getAttribute('data-validate').split(' ');
@@ -50,47 +55,60 @@ function validateField(form, field) {
50
55
  case 'required':
51
56
  result = checks.isEmpty(field.value);
52
57
  break;
58
+
53
59
  case 'currency':
54
60
  result = checks.isCurrency(field.value);
55
61
  break;
62
+
56
63
  case 'email':
57
64
  result = checks.isValidEmail(field.value);
58
65
  break;
66
+
59
67
  case 'phone':
60
68
  result = checks.isPhoneNumber(field.value);
61
69
  break;
70
+
62
71
  case 'https':
63
72
  result = checks.isHttps(field.value);
64
73
  break;
74
+
65
75
  case 'belowMaxAmount':
66
76
  result = checks.isAboveMaxAmount(field.value);
67
77
  break;
78
+
68
79
  case 'passwordLessThanTenChars':
69
80
  result = checks.isPasswordLessThanTenChars(field.value);
70
81
  break;
82
+
71
83
  case 'isFieldGreaterThanMaxLengthChars':
72
84
  result = checks.isFieldGreaterThanMaxLengthChars(field.value, field.getAttribute('data-validate-max-length'));
73
85
  break;
86
+
74
87
  case 'isNaxsiSafe':
75
88
  result = checks.isNaxsiSafe(field.value);
76
89
  break;
90
+
77
91
  default:
78
92
  result = false;
79
93
  break;
80
94
  }
95
+
81
96
  if (result) {
82
97
  applyErrorMessaging(form, field, result);
83
98
  }
84
99
  });
85
100
  return !field.closest('.form-group').classList.contains('error');
86
101
  }
102
+
87
103
  function applyErrorMessaging(form, field, result) {
88
104
  var formGroup = field.closest('.form-group');
105
+
89
106
  if (!formGroup.classList.contains('error')) {
90
107
  formGroup.classList.add('error');
91
108
  document.querySelector('label[for="' + field.id + '"]').insertAdjacentHTML('beforeend', '<span class="error-message">' + result + '</span>');
92
109
  }
93
110
  }
111
+
94
112
  function populateErrorSummary(form) {
95
113
  var erroringFields = Array.prototype.slice.call(form.querySelectorAll('.form-group.error label'));
96
114
  var errorMessages = erroringFields.map(function (field) {
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
-
3
2
  /*
4
3
  Metadata Column constants match up those defined:
5
4
  https://github.com/alphagov/pay-java-commons/blob/master/model/src/main/java/uk/gov/pay/commons/model/charge/ExternalMetadata.java
6
5
  */
6
+
7
7
  module.exports = {
8
8
  externalMetadata: {
9
9
  MAX_KEY_VALUE_PAIRS: 10,
package/lib/index.js CHANGED
@@ -1,18 +1,23 @@
1
1
  'use strict';
2
2
 
3
3
  var browsered = require('./browsered');
4
+
4
5
  var utils = require('./utils');
6
+
5
7
  var nunjucksFilters = require('./nunjucks-filters');
8
+
6
9
  var logging = require('./logging');
7
- var constants = require('./constants');
8
10
 
9
- // Add to window.GOVUKPAY if in browser context
11
+ var constants = require('./constants'); // Add to window.GOVUKPAY if in browser context
12
+
13
+
10
14
  if (typeof window !== 'undefined') {
11
15
  window.GOVUKPAY = window.GOVUKPAY || {};
12
16
  window.GOVUKPAY = {
13
17
  browsered: browsered
14
18
  };
15
19
  }
20
+
16
21
  module.exports = {
17
22
  browsered: browsered,
18
23
  utils: utils,
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var _require = require('winston'),
4
- format = _require.format;
4
+ format = _require.format;
5
+
5
6
  var govUkPayLoggingFormat = format(function (info, opts) {
6
7
  info['@timestamp'] = new Date().toISOString();
7
8
  info['@version'] = 1;
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var keys = require('./keys');
4
+
4
5
  var _require = require('./format'),
5
- govUkPayLoggingFormat = _require.govUkPayLoggingFormat;
6
+ govUkPayLoggingFormat = _require.govUkPayLoggingFormat;
7
+
6
8
  var requestLogFormat = require('./request-log-format');
9
+
7
10
  module.exports = {
8
11
  govUkPayLoggingFormat: govUkPayLoggingFormat,
9
12
  keys: keys,
@@ -1,108 +1,75 @@
1
- 'use strict';
2
-
3
- // This file needs to be kept in sync with its Java consociate
1
+ 'use strict'; // This file needs to be kept in sync with its Java consociate
4
2
  // https://github.com/alphagov/pay-java-commons/blob/master/logging/src/main/java/uk/gov/pay/logging/LoggingKeys.java
5
-
6
3
  // "card", "Direct Debit"
7
- exports.PAYMENT_TYPE = 'payment_type';
8
4
 
9
- // "payment", "mandate", "refund"
10
- exports.RESOURCE_TYPE = 'resource_type';
5
+ exports.PAYMENT_TYPE = 'payment_type'; // "payment", "mandate", "refund"
11
6
 
12
- // "sandbox", "Worldpay", "Smartpay", "ePDQ", "Stripe", "GoCardless"
13
- exports.PROVIDER = 'provider';
7
+ exports.RESOURCE_TYPE = 'resource_type'; // "sandbox", "Worldpay", "Smartpay", "ePDQ", "Stripe", "GoCardless"
14
8
 
15
- // The digital wallet used for a payment
9
+ exports.PROVIDER = 'provider'; // The digital wallet used for a payment
16
10
  // Value must be a value of the WalletType enum
17
11
  // https://github.com/alphagov/pay-connector/blob/master/src/main/java/uk/gov/pay/connector/wallets/WalletType.java
18
- exports.WALLET = 'wallet';
19
12
 
20
- // The type of a gateway account
13
+ exports.WALLET = 'wallet'; // The type of a gateway account
21
14
  // Value must be a value of the GatewayAccountEntity.Type enum
22
15
  // https://github.com/alphagov/pay-connector/blob/master/src/main/java/uk/gov/pay/connector/gatewayaccount/model/GatewayAccountEntity.java
23
- exports.GATEWAY_ACCOUNT_TYPE = 'gateway_account_type';
24
16
 
25
- // The type of operation being performed with a gateway for a card payment
17
+ exports.GATEWAY_ACCOUNT_TYPE = 'gateway_account_type'; // The type of operation being performed with a gateway for a card payment
26
18
  // Value must be a value of the OperationType enum
27
19
  // https://github.com/alphagov/pay-connector/blob/master/src/main/java/uk/gov/pay/connector/paymentprocessor/model/OperationType.java
28
- exports.GATEWAY_CARD_OPERATION = 'gateway_card_operation';
29
20
 
30
- // The amount of a payment in pence
31
- exports.AMOUNT = 'amount';
21
+ exports.GATEWAY_CARD_OPERATION = 'gateway_card_operation'; // The amount of a payment in pence
32
22
 
33
- // Mandate external id
34
- exports.MANDATE_EXTERNAL_ID = 'mandate_external_id';
23
+ exports.AMOUNT = 'amount'; // Mandate external id
35
24
 
36
- // The PSP's identifier for a payment
37
- exports.PROVIDER_PAYMENT_ID = 'provider_payment_id';
25
+ exports.MANDATE_EXTERNAL_ID = 'mandate_external_id'; // The PSP's identifier for a payment
38
26
 
39
- // The ID a provider gives to an event (e.g. one in a notification)
40
- exports.PROVIDER_EVENT_ID = 'provider_event_id';
27
+ exports.PROVIDER_PAYMENT_ID = 'provider_payment_id'; // The ID a provider gives to an event (e.g. one in a notification)
41
28
 
42
- // The reference a partner service assigns to a payment, mandate etc.
43
- exports.SERVICE_PAYMENT_REFERENCE = 'service_reference';
29
+ exports.PROVIDER_EVENT_ID = 'provider_event_id'; // The reference a partner service assigns to a payment, mandate etc.
44
30
 
45
- // The ID GOV.UK Pay gives to a gateway account
46
- exports.GATEWAY_ACCOUNT_ID = 'gateway_account_id';
31
+ exports.SERVICE_PAYMENT_REFERENCE = 'service_reference'; // The ID GOV.UK Pay gives to a gateway account
47
32
 
48
- // The ID of an event emitted to ledger
49
- exports.LEDGER_EVENT_ID = 'ledger_event_id';
33
+ exports.GATEWAY_ACCOUNT_ID = 'gateway_account_id'; // The ID of an event emitted to ledger
50
34
 
51
- // The type of an event emitted to ledger
52
- exports.LEDGER_EVENT_TYPE = 'ledger_event_type';
35
+ exports.LEDGER_EVENT_ID = 'ledger_event_id'; // The type of an event emitted to ledger
53
36
 
54
- // The type of an internal event recorded by Direct Debit
37
+ exports.LEDGER_EVENT_TYPE = 'ledger_event_type'; // The type of an internal event recorded by Direct Debit
55
38
  // Value must be a value from the GovUkPayEventType enum
56
39
  // https://github.com/alphagov/pay-direct-debit-connector/blob/master/src/main/java/uk/gov/pay/directdebit/events/model/GovUkPayEventType.java
57
- exports.DIRECT_DEBIT_INTERNAL_EVENT_TYPE = 'direct_debit_internal_event_type';
58
40
 
59
- // The current (or new if transitioning) internal state of a payment, mandate etc.
60
- exports.CURRENT_INTERNAL_STATE = 'current_internal_state';
41
+ exports.DIRECT_DEBIT_INTERNAL_EVENT_TYPE = 'direct_debit_internal_event_type'; // The current (or new if transitioning) internal state of a payment, mandate etc.
42
+
43
+ exports.CURRENT_INTERNAL_STATE = 'current_internal_state'; // The previous internal state of a payment, mandate etc. when transitioning
61
44
 
62
- // The previous internal state of a payment, mandate etc. when transitioning
63
- exports.PREVIOUS_INTERNAL_STATUS = 'previous_internal_status';
45
+ exports.PREVIOUS_INTERNAL_STATUS = 'previous_internal_status'; // The last event (status) that Worldpay recorded for a payment, refund etc.
64
46
 
65
- // The last event (status) that Worldpay recorded for a payment, refund etc.
66
- exports.WORLDPAY_LAST_EVENT = 'worldpay_last_event';
47
+ exports.WORLDPAY_LAST_EVENT = 'worldpay_last_event'; // The result code (status) that Smartpay recorded for a payment, refund etc.
67
48
 
68
- // The result code (status) that Smartpay recorded for a payment, refund etc.
69
- exports.SMARTPAY_RESULT_CODE = 'smartpay_result_code';
49
+ exports.SMARTPAY_RESULT_CODE = 'smartpay_result_code'; // The status code that ePDQ recorded for a payment, refund etc.
70
50
 
71
- // The status code that ePDQ recorded for a payment, refund etc.
72
- exports.EPDQ_STATUS = 'epdq_status';
51
+ exports.EPDQ_STATUS = 'epdq_status'; // The status that Stripe recorded for a payment, refund etc.
73
52
 
74
- // The status that Stripe recorded for a payment, refund etc.
75
- exports.STRIPE_STATUS = 'stripe_status';
53
+ exports.STRIPE_STATUS = 'stripe_status'; // The action that GoCardless recorded for a payment, mandate etc.
76
54
 
77
- // The action that GoCardless recorded for a payment, mandate etc.
78
- exports.GOCARDLESS_PAYMENT_ACTION = 'gocardless_action';
55
+ exports.GOCARDLESS_PAYMENT_ACTION = 'gocardless_action'; // The HTTP status we sent to a client
79
56
 
80
- // The HTTP status we sent to a client
81
- exports.HTTP_STATUS = 'http_status';
57
+ exports.HTTP_STATUS = 'http_status'; // The HTTP status code we received from a remote server (e.g. a payment provider)
82
58
 
83
- // The HTTP status code we received from a remote server (e.g. a payment provider)
84
- exports.REMOTE_HTTP_STATUS = 'remote_http_status';
59
+ exports.REMOTE_HTTP_STATUS = 'remote_http_status'; // AWS error code
85
60
 
86
- // AWS error code
87
- exports.AWS_ERROR_CODE = 'aws_error_code';
61
+ exports.AWS_ERROR_CODE = 'aws_error_code'; // The correlation id for the request
88
62
 
89
- // The correlation id for the request
90
- exports.CORRELATION_ID = 'x_request_id';
63
+ exports.CORRELATION_ID = 'x_request_id'; // Payment External Id
91
64
 
92
- // Payment External Id
93
- exports.PAYMENT_EXTERNAL_ID = 'payment_external_id';
65
+ exports.PAYMENT_EXTERNAL_ID = 'payment_external_id'; // Refund External Id
94
66
 
95
- // Refund External Id
96
- exports.REFUND_EXTERNAL_ID = 'refund_external_id';
67
+ exports.REFUND_EXTERNAL_ID = 'refund_external_id'; // Secure Token
97
68
 
98
- // Secure Token
99
- exports.SECURE_TOKEN = 'secure_token';
69
+ exports.SECURE_TOKEN = 'secure_token'; // User external id
100
70
 
101
- // User external id
102
- exports.USER_EXTERNAL_ID = 'user_external_id';
71
+ exports.USER_EXTERNAL_ID = 'user_external_id'; // A service's external id
103
72
 
104
- // A service's external id
105
- exports.SERVICE_EXTERNAL_ID = 'service_external_id';
73
+ exports.SERVICE_EXTERNAL_ID = 'service_external_id'; // product external id
106
74
 
107
- // product external id
108
75
  exports.PRODUCT_EXTERNAL_ID = 'product_external_id';
@@ -2,6 +2,7 @@
2
2
 
3
3
  module.exports = function () {
4
4
  var correlationIdHeader = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'x-request-id';
5
+
5
6
  var format = function format(tokens, req, res) {
6
7
  return JSON.stringify({
7
8
  /* eslint-disable camelcase */
@@ -17,6 +18,7 @@ module.exports = function () {
17
18
  response_time: "".concat(tokens['response-time'](req, res), " ms"),
18
19
  x_request_id: tokens.req(req, res, correlationIdHeader)
19
20
  /* eslint-enable camelcase */
21
+
20
22
  });
21
23
  };
22
24
 
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var _require = require('../utils/countries'),
4
- translateAlpha2 = _require.translateAlpha2;
4
+ translateAlpha2 = _require.translateAlpha2;
5
+
5
6
  module.exports = function (iso) {
6
7
  return translateAlpha2(iso);
7
8
  };
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
 
3
3
  var moment = require('moment-timezone');
4
+
4
5
  module.exports = function (isoTimeString, format) {
5
6
  var formatString = 'D MMMM YYYY h:mm:ssa z';
7
+
6
8
  if (format === 'date') {
7
9
  formatString = 'DD/MM/YYYY';
8
10
  } else if (format === 'datelong') {
@@ -10,5 +12,6 @@ module.exports = function (isoTimeString, format) {
10
12
  } else if (format === 'time') {
11
13
  formatString = 'HH:mm:ss';
12
14
  }
15
+
13
16
  return moment(isoTimeString).tz('Europe/London').format(formatString);
14
17
  };
@@ -2,7 +2,6 @@
2
2
 
3
3
  // Removes indefinite articles (a/an)
4
4
  // Removes definite articles (the)
5
-
6
5
  module.exports = function (string) {
7
6
  return string.replace(/\ba\s|\ban\s|\bthe\s/gi, '');
8
7
  };
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var slugify = require('slugify');
4
+
4
5
  module.exports = function (string) {
5
6
  slugify.extend({
6
7
  ŵ: 'w',
@@ -1,17 +1,18 @@
1
- 'use strict';
1
+ 'use strict'; // NPM Dependencies
2
+
3
+ var lodash = require('lodash'); // Local Dependencies
2
4
 
3
- // NPM Dependencies
4
- var lodash = require('lodash');
5
5
 
6
- // Local Dependencies
7
6
  var countries = require('../data/countries.json');
8
- var extensions = require('../data/country-record-extension.json');
9
7
 
10
- // Merge the additional data into the register data
8
+ var extensions = require('../data/country-record-extension.json'); // Merge the additional data into the register data
9
+
10
+
11
11
  countries.forEach(function (country) {
12
12
  var extension = extensions.find(function (item) {
13
13
  return item.country === country;
14
14
  });
15
+
15
16
  if (extension) {
16
17
  country.entry.aliases = extension.aliases;
17
18
  country.entry.weighting = extension.weighting;
@@ -20,9 +21,8 @@ countries.forEach(function (country) {
20
21
  countries = lodash.compact(countries);
21
22
  countries = lodash.sortBy(countries, function (country) {
22
23
  return country.entry.name.toLowerCase();
23
- });
24
+ }); // Exports
24
25
 
25
- // Exports
26
26
  exports.retrieveCountries = function (selectedCountry) {
27
27
  var countriesList = lodash.clone(countries);
28
28
  countriesList.forEach(function (country) {
@@ -30,6 +30,7 @@ exports.retrieveCountries = function (selectedCountry) {
30
30
  });
31
31
  return countriesList;
32
32
  };
33
+
33
34
  exports.govukFrontendFormatted = function (selectedCountry) {
34
35
  var countriesList = lodash.clone(countries);
35
36
  countriesList.forEach(function (country) {
@@ -39,6 +40,7 @@ exports.govukFrontendFormatted = function (selectedCountry) {
39
40
  });
40
41
  return countriesList;
41
42
  };
43
+
42
44
  exports.translateAlpha2 = function (alpha2Code) {
43
45
  return countries.find(function (country) {
44
46
  return country.entry.country === alpha2Code;
@@ -1,36 +1,44 @@
1
- 'use strict';
1
+ 'use strict'; // Local contants
2
2
 
3
- // Local contants
4
3
  var AMOUNT_FORMAT = /^(\d+)(?:\.(\d{1,2}))?$/;
4
+
5
5
  var penceToPounds = function penceToPounds(amount) {
6
6
  return (amount / 100).toFixed(2);
7
7
  };
8
+
8
9
  var poundsToPence = function poundsToPence(amount) {
9
10
  return (amount * 100).toFixed(0);
10
11
  };
12
+
11
13
  var penceToPoundsWithCurrency = function penceToPoundsWithCurrency(amount) {
12
14
  return new Intl.NumberFormat('en-gb', {
13
15
  style: 'currency',
14
16
  currency: 'GBP'
15
17
  }).format(penceToPounds(amount));
16
18
  };
19
+
17
20
  var sanitisePoundsAndPenceInput = function sanitisePoundsAndPenceInput(amount) {
18
21
  if (amount) {
19
22
  var cleanedCurrencyString = amount.replace(/[^0-9.-]+/g, '');
20
23
  var result = AMOUNT_FORMAT.exec(cleanedCurrencyString);
24
+
21
25
  if (result) {
22
26
  var pounds = result[1];
23
27
  var pence = result[2];
28
+
24
29
  if (pence === undefined) {
25
30
  pence = '00';
26
31
  } else if (pence.length === 1) {
27
32
  pence += '0';
28
33
  }
34
+
29
35
  return parseInt(pounds + pence, 10);
30
36
  }
37
+
31
38
  return null;
32
39
  }
33
40
  };
41
+
34
42
  module.exports = {
35
43
  penceToPounds: penceToPounds,
36
44
  poundsToPence: poundsToPence,
@@ -1,12 +1,11 @@
1
- 'use strict';
1
+ 'use strict'; // NPM dependencies
2
2
 
3
- // NPM dependencies
4
- var parseInt = require('lodash/parseInt');
3
+ var parseInt = require('lodash/parseInt'); // Local dependencies
4
+
5
+
6
+ var emailValidator = require('./is-valid-email'); // Constants
5
7
 
6
- // Local dependencies
7
- var emailValidator = require('./is-valid-email');
8
8
 
9
- // Constants
10
9
  var NUMBERS_ONLY = /^\d+$/;
11
10
  var MAX_AMOUNT = 100000;
12
11
  var validationErrors = {
@@ -20,53 +19,70 @@ var validationErrors = {
20
19
  isGreaterThanMaxLengthChars: 'The text is too long',
21
20
  invalidCharacters: 'You cannot use any of the following characters < > ; : ` ( ) " \' = | , ~ [ ]'
22
21
  };
22
+
23
23
  exports.isEmpty = function (value) {
24
24
  if (value === '') {
25
25
  return validationErrors.required;
26
26
  }
27
+
27
28
  return false;
28
29
  };
30
+
29
31
  exports.isCurrency = function (value) {
30
32
  if (!/^(\d+)(?:\.(\d{1,2}))?$/.test(value)) {
31
33
  return validationErrors.currency;
32
34
  }
35
+
33
36
  return false;
34
37
  };
38
+
35
39
  exports.isValidEmail = function (value) {
36
40
  if (!emailValidator(value)) {
37
41
  return validationErrors.validEmail;
38
42
  }
43
+
39
44
  return false;
40
45
  };
46
+
41
47
  exports.isPhoneNumber = function (value) {
42
48
  var trimmedTelephoneNumber = value.replace(/\s/g, '');
49
+
43
50
  if (trimmedTelephoneNumber.length < 11 || !NUMBERS_ONLY.test(trimmedTelephoneNumber)) {
44
51
  return validationErrors.phoneNumber;
45
52
  }
53
+
46
54
  return false;
47
55
  };
56
+
48
57
  exports.isHttps = function (value) {
49
58
  if (value.substr(0, 8) !== 'https://') {
50
59
  return validationErrors.isHttps;
51
60
  }
61
+
52
62
  return false;
53
63
  };
64
+
54
65
  exports.isAboveMaxAmount = function (value) {
55
66
  if (!exports.isCurrency(value) && parseFloat(value) > MAX_AMOUNT) {
56
67
  return validationErrors.isAboveMaxAmount;
57
68
  }
69
+
58
70
  return false;
59
71
  };
72
+
60
73
  exports.isFieldGreaterThanMaxLengthChars = function (value, maxLength) {
61
74
  var parsedMaxLength = parseInt(maxLength);
62
75
  return parsedMaxLength && value.length > parsedMaxLength ? validationErrors.isGreaterThanMaxLengthChars : false;
63
76
  };
77
+
64
78
  exports.isPasswordLessThanTenChars = function (value) {
65
79
  return !value || value.length < 10 ? validationErrors.isPasswordLessThanTenChars : false;
66
80
  };
81
+
67
82
  exports.isNaxsiSafe = function (value) {
68
83
  if (/[<>;:`()"'=|,~[\]]+/g.test(value)) {
69
84
  return validationErrors.invalidCharacters;
70
85
  }
86
+
71
87
  return false;
72
88
  };
@@ -1,11 +1,12 @@
1
- 'use strict';
1
+ 'use strict'; // NPM dependencies
2
2
 
3
- // NPM dependencies
4
3
  var rfc822Validator = require('rfc822-validate');
4
+
5
5
  module.exports = function (email) {
6
6
  if (rfc822Validator(email)) {
7
7
  var domain = email.split('@')[1];
8
8
  return !(domain && domain.indexOf('.') === -1);
9
9
  }
10
+
10
11
  return false;
11
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@govuk-pay/pay-js-commons",
3
- "version": "3.8.4",
3
+ "version": "3.8.5",
4
4
  "description": "Reusable js scripts for GOV.UK Pay Node.js projects",
5
5
  "engines": {
6
6
  "node": "^16.14.0"
@@ -0,0 +1,56 @@
1
+ $govuk-font-family: -apple-system,BlinkMacSystemFont,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif; // Override font as so not to use New Transport
2
+ @import "application";
3
+
4
+ // CUSTOM BRANDING
5
+ // Use the variables below to control the style
6
+ // Make sure banner colours meet minimum colour contrast levels
7
+
8
+ $custom-banner-colour: #008489;
9
+ $custom-banner-border-colour: #ffffff;
10
+ $custom-text-colour: #ffffff;
11
+ $logo-image-height: 2em;
12
+
13
+ .custom-branding {
14
+ @if $logo-image-height != null {
15
+ .custom-branding-image {
16
+ height: $logo-image-height;
17
+ width: 100%;
18
+
19
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
20
+ width: 100%;
21
+ }
22
+ }
23
+ }
24
+
25
+ .govuk-header {
26
+ background-color: $custom-banner-colour;
27
+ }
28
+
29
+ .govuk-header__link {
30
+ &:link,
31
+ &:visited {
32
+ color: $custom-text-colour;
33
+ }
34
+ }
35
+
36
+ .govuk-header__link--service-name {
37
+ display: none;
38
+ }
39
+
40
+ .govuk-header__container {
41
+ border-bottom-color: $custom-banner-border-colour;
42
+ }
43
+
44
+ @include govuk-media-query($from: tablet) {
45
+ .govuk-header__content {
46
+ width: 66%;
47
+ vertical-align: bottom;
48
+ margin-bottom: 7px;
49
+ }
50
+ }
51
+
52
+ .govuk-button {
53
+ padding: 7px 15px 6px;
54
+ padding: .368421053em .842105263em .315789474em;
55
+ }
56
+ }