Skip to content

Commit

Permalink
Release braintree-web 3.91.0 source
Browse files Browse the repository at this point in the history
Co-authored-by: Nidhi Narendra <[email protected]>
  • Loading branch information
braintreeps and Nidhi Narendra committed Feb 22, 2023
1 parent f33e15d commit 05d5ac6
Show file tree
Hide file tree
Showing 19 changed files with 404 additions and 180 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# CHANGELOG

# 3.91.0
- 3D Secure
- Add `requestedExemptionType` option to `verifyCard`
- Deprecate `exemptionRequested` option in `verifyCard`
- Made `verifyCard` BIN param required
- Add error on use of v1
- Hosted Fields
- Improved accessibility for screen readers

# 3.90.0

- Paypal
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "braintree-web",
"version": "3.90.0",
"version": "3.91.0",
"license": "MIT",
"main": "src/index.js",
"private": true,
Expand Down
9 changes: 3 additions & 6 deletions src/hosted-fields/internal/components/base-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@ function constructAttributes(options) {
};

if (!attributes.type) {
if (browserDetection.isIos()) {
attributes.type = "text";
attributes.pattern = "\\d*";
} else {
attributes.type = "tel";
}
attributes.type = "text";
attributes.pattern = "\\d*";
attributes.inputmode = "numeric";
}

if (!options.shouldAutofill) {
Expand Down
2 changes: 1 addition & 1 deletion src/paypal-checkout/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* @name BraintreeError.Paypal Checkout - updatePayment Error Codes
* @description Errors that occur when using the [`updatePayment` method](./PayPalCheckout.html#updatePayment).
* @property {MERCHANT} PAYPAL_INVALID_PAYMENT_OPTION Occurs when an option contains an invalid value.
* @property {MERCHANT} PAYPAL_MISSING_REQUIRED_OPTION Occurs when a required option is missing.
* @property {MERCHANT} PAYPAL_MISSING_REQUIRED_OPTION Occurs when a required option is missing.
* @property {NETWORK} PAYPAL_FLOW_FAILED Occurs when something goes wrong when initializing the flow or communicating with the server.
*/
var BraintreeError = require("../lib/braintree-error");
Expand Down
2 changes: 2 additions & 0 deletions src/preferred-payment-methods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ var basicComponentVerification = require("../lib/basic-component-verification");
var PreferredPaymentMethods = require("./preferred-payment-methods");
var VERSION = process.env.npm_package_version;

// NEXT_MAJOR_VERSION
// Remove this integration entirely. It doesn't work, isn't documented, and otherwise isn't going to be pursued further beyond the non-operational beta it is in.
/**
* @static
* @function create
Expand Down
30 changes: 25 additions & 5 deletions src/three-d-secure/external/frameworks/songbird.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ var SONGBIRD_UI_EVENTS = [
"ui.loading.render",
];

var SCA_EXEMPTION_TYPES = ["low_value", "transaction_risk_analysis"];

function SongbirdFramework(options) {
BaseFramework.call(this, options);

Expand Down Expand Up @@ -144,11 +146,6 @@ SongbirdFramework.prototype._triggerCardinalBinProcess = function (bin) {
var self = this;
var issuerStartTime = Date.now();

if (!bin) {
// skip bin lookup because bin wasn't passed in
return Promise.resolve();
}

return window.Cardinal.trigger("bin.process", bin).then(function (
binResults
) {
Expand Down Expand Up @@ -668,6 +665,14 @@ SongbirdFramework.prototype._checkForVerifyCardError = function (
options,
privateOptions
) {
if (!options.bin) {
return new BraintreeError({
type: errors.THREEDS_MISSING_VERIFY_CARD_OPTION.type,
code: errors.THREEDS_MISSING_VERIFY_CARD_OPTION.code,
message: "verifyCard options must include a BIN.",
});
}

return BaseFramework.prototype._checkForVerifyCardError.call(
this,
options,
Expand Down Expand Up @@ -786,6 +791,21 @@ SongbirdFramework.prototype._formatLookupData = function (options) {
if (options.challengeRequested) {
data.challengeRequested = options.challengeRequested;
}
if (options.requestedExemptionType) {
if (!SCA_EXEMPTION_TYPES.includes(options.requestedExemptionType)) {
throw new BraintreeError({
code: errors.THREEDS_REQUESTED_EXEMPTION_TYPE_INVALID.code,
type: errors.THREEDS_REQUESTED_EXEMPTION_TYPE_INVALID.type,
message:
"requestedExemptionType `" +
options.requestedExemptionType +
"` is not a valid exemption. The accepted values are: `" +
SCA_EXEMPTION_TYPES.join("`, `") +
"`",
});
}
data.requestedExemptionType = options.requestedExemptionType;
}
if (options.dataOnlyRequested) {
data.dataOnlyRequested = options.dataOnlyRequested;
}
Expand Down
7 changes: 4 additions & 3 deletions src/three-d-secure/external/three-d-secure.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ function ThreeDSecure(options) {
}

EventEmitter.createChild(ThreeDSecure);

// NEXT_MAJOR_VERSION remove exemptionRequested entirely in favor of `requestedExemptionType`
/**
* Launch the 3D Secure login flow, returning a nonce payload.
*
Expand All @@ -401,8 +401,9 @@ EventEmitter.createChild(ThreeDSecure);
* @param {boolean} [options.cardAddChallengeRequested] If set to `true`, a card-add challenge will be requested from the issuer. If set to `false`, a card-add challenge will not be requested. If the param is missing, a card-add challenge will only be requested for $0 amount. An authentication created using this flag should only be used for vaulting operations (creation of customers' credit cards or payment methods) and not for creating transactions.
* @param {boolean} [options.cardAdd] *Deprecated:* Use `cardAddChallengeRequested` instead.
* @param {boolean} [options.challengeRequested] If set to true, an authentication challenge will be forced if possible.
* @param {boolean} [options.exemptionRequested] If set to true, an exemption to the authentication challenge will be requested.
* @param {boolean} [options.dataOnlyRequested] Indicates whether to use the data only flow. In this flow, frictionless 3DS is ensured for Mastercard cardholders as the card scheme provides a risk score for the issuer to determine whether to approve. If data only is not supported by the processor, a validation error will be raised. Non-Mastercard cardholders will fallback to a normal 3DS flow.
* @param {boolean} [options.exemptionRequested] *Deprecated:* Use `requestedExemptionType` instead.
* @param {string} [options.requestedExemptionType] If an exemption is requested and the exemption's conditions are satisfied, then it will be applied. The following supported exemptions are defined as per PSD2 regulation: `low_value`, `transaction_risk_analysis`
* @param {function} [options.onLookupComplete] *Deprecated:* Use {@link ThreeDSecure#event:lookup-complete|`threeDSecureInstance.on('lookup-complete')`} instead. Function to execute when lookup completes. The first argument, `data`, is a {@link ThreeDSecure~verificationData|verificationData} object, and the second argument, `next`, is a callback. `next` must be called to continue.
* @param {string} [options.email] The email used for verification. (maximum length 255)
* @param {string} [options.mobilePhoneNumber] The mobile phone number used for verification. Only numbers; remove dashes, parenthesis and other characters. (maximum length 25)
Expand Down Expand Up @@ -655,7 +656,7 @@ ThreeDSecure.prototype.initializeChallengeWithLookupResponse = function (
* @public
* @param {object} options Options for 3D Secure lookup.
* @param {string} options.nonce The nonce representing the card from a tokenization payload. For example, this can be a {@link HostedFields~tokenizePayload|tokenizePayload} returned by Hosted Fields under `payload.nonce`.
* @param {string} [options.bin] The numeric Bank Identification Number (bin) of the card from a tokenization payload. For example, this can be a {@link HostedFields~tokenizePayload|tokenizePayload} returned by Hosted Fields under `payload.details.bin`. Though not required to start the verification, it is required to receive a 3DS 2.0 lookup response.
* @param {string} options.bin The numeric Bank Identification Number (bin) of the card from a tokenization payload. For example, this can be a {@link HostedFields~tokenizePayload|tokenizePayload} returned by Hosted Fields under `payload.details.bin`.
* @param {callback} [callback] The second argument, <code>data</code>, is a {@link ThreeDSecure~prepareLookupPayload|prepareLookupPayload}. If no callback is provided, it will return a promise that resolves {@link ThreeDSecure~prepareLookupPayload|prepareLookupPayload}.
* @returns {(Promise|void)} Returns a promise if no callback is provided.
Expand Down
8 changes: 6 additions & 2 deletions src/three-d-secure/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ var wrapPromise = require("@braintree/wrap-promise");
*/
function create(options) {
var name = "3D Secure";
var framework = getFramework(options);

return basicComponentVerification
.verify({
Expand All @@ -125,7 +126,6 @@ function create(options) {
})
.then(function () {
var assetsUrl = createAssetsUrl.create(options.authorization);
var framework = getFramework(options);
var createPromise = createDeferredClient
.create({
authorization: options.authorization,
Expand Down Expand Up @@ -200,7 +200,11 @@ function getFramework(options) {
var version = String(options.version || "");

if (!version || version === "1") {
return "legacy";
throw new BraintreeError({
code: errors.THREEDS_UNSUPPORTED_VERSION.code,
type: errors.THREEDS_UNSUPPORTED_VERSION.type,
message: errors.THREEDS_UNSUPPORTED_VERSION.message,
});
}

switch (version) {
Expand Down
13 changes: 13 additions & 0 deletions src/three-d-secure/shared/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* @property {MERCHANT} THREEDS_CARDINAL_SDK_BAD_JWT Occurs when a malformed config causes a either a missing response JWT or a malformed Cardinal response.
* @property {UNKNOWN} THREEDS_CARDINAL_SDK_ERROR Occurs when a "general error" or a Cardinal hosted fields error happens. Description contains more details.
* @property {CUSTOMER} THREEDS_CARDINAL_SDK_CANCELED Occurs when customer cancels the transaction mid-flow, usually with alt-pays that have their own cancel buttons.
* @property {MERCHANT} THREEDS_UNSUPPORTED_VERSION Occurs when 3D Secure component is created with version 1 (or default version) parameter.
*/

/**
Expand All @@ -29,6 +30,7 @@
* @property {UNKNOWN} THREEDS_LOOKUP_ERROR An unknown error occurred while attempting the 3D Secure lookup.
* @property {MERCHANT} THREEDS_VERIFY_CARD_CANCELED_BY_MERCHANT Occurs when the 3D Secure flow is canceled by the merchant using `cancelVerifyCard` (3D Secure v2 flows only).
* @property {UNKNOWN} THREEDS_INLINE_IFRAME_DETAILS_INCORRECT An unknown error occurred while attempting to use the inline iframe framework.
* @property {MERCHANT} THREEDS_REQUESTED_EXEMPTION_TYPE_INVALID Occurs when unrecognized exemption enum value is passed into verifyCard.
*/

/**
Expand Down Expand Up @@ -174,4 +176,15 @@ module.exports = {
code: "THREEDS_FRAMEWORK_METHOD_NOT_IMPLEMENTED",
message: "Method not implemented for this framework.",
},
THREEDS_REQUESTED_EXEMPTION_TYPE_INVALID: {
type: BraintreeError.types.MERCHANT,
code: "THREEDS_REQUESTED_EXEMPTION_TYPE_INVALID",
message: "Requested Exemption Type is invalid.",
},
THREEDS_UNSUPPORTED_VERSION: {
type: BraintreeError.types.MERCHANT,
code: "THREEDS_UNSUPPORTED_VERSION",
message:
"3D Secure `1` is deprecated and no longer supported. See available versions at https://braintree.github.io/braintree-web/current/module-braintree-web_three-d-secure.html#.create",
},
};
4 changes: 3 additions & 1 deletion test/hosted-fields/unit/internal/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ exports[`internal initialize calls FieldComponent to generate the input 1`] = `
class="cvv"
data-braintree-name="cvv"
id="cvv"
inputmode="numeric"
maxlength="4"
name="cvv"
pattern="\\d*"
spellcheck="false"
type="tel"
type="text"
/>
<div
class=" field-description"
Expand Down
6 changes: 3 additions & 3 deletions test/hosted-fields/unit/internal/components/base-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ describe("Base Input", () => {
expect(instance.element.getAttribute("type")).toBe("password");
});

it('uses "tel" if not provided', () => {
it('uses "text" if not provided', () => {
expect(testContext.instance.element.getAttribute("type")).toBe(
"tel"
"text"
);
});

Expand Down Expand Up @@ -227,7 +227,7 @@ describe("Base Input", () => {
describe("defaults", () => {
it("applies type", () => {
expect(testContext.instance.element.getAttribute("type")).toBe(
"tel"
"text"
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ describe("Credit Card Input", () => {
});

describe("element", () => {
it('has type="tel"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("tel");
it('has type="text"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("text");
});

it("has autocomplete cc-number", () => {
Expand Down
4 changes: 2 additions & 2 deletions test/hosted-fields/unit/internal/components/cvv-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe("CVV Input", () => {
});

describe("element", () => {
it('has type="tel"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("tel");
it('has type="text"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("text");
});

it("has autocomplete cc-csc", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe("Expiration Date Input", () => {
it('sets element type to "text" when browser does not support formatting', () => {
const inputWithFormatting = createInput("expirationDate");

expect(inputWithFormatting.element.type).toBe("tel");
expect(inputWithFormatting.element.type).toBe("text");

jest.spyOn(RestrictedInput, "supportsFormatting").mockReturnValue(false);

Expand Down Expand Up @@ -68,8 +68,8 @@ describe("Expiration Date Input", () => {
});

describe("element", () => {
it('has type="tel"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("tel");
it('has type="text"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("text");
});

it("has autocomplete cc-exp", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ describe("Expiration Month Input", () => {
expect(testContext.input.element).toBeInstanceOf(HTMLInputElement);
});

it('has type="tel"', () => {
expect(testContext.input.element.getAttribute("type")).toMatch("tel");
it('has type="text"', () => {
expect(testContext.input.element.getAttribute("type")).toMatch("text");
});

it("sets the maxLength to 2", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ describe("Expiration Year Input", () => {
expect(testContext.input.element).toBeInstanceOf(HTMLInputElement);
});

it('has type="tel"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("tel");
it('has type="text"', () => {
expect(testContext.input.element.getAttribute("type")).toBe("text");
});

it("sets the maxLength to 4", () => {
Expand Down
Loading

0 comments on commit 05d5ac6

Please sign in to comment.