Skip to content

Commit 6bc11f6

Browse files
committed
[Payment Request] Validate payment method data on construction
https://bugs.webkit.org/show_bug.cgi?id=233292 <rdar://problem/85736007> Reviewed by Andy Estes. Source/WebCore: This will allow developers to replace any `ApplePaySession.supportsVersion` check(s) by attempting to create a `PaymentRequest` object with data specific to Apple Pay. This is actually an improvement, because it'll also allow developers to catch most errors in that data earlier, as previously any errors would only be thrown when `show()` is called. Spec: <w3c/payment-request#976> Test: http/tests/ssl/applepay/PaymentRequest.https.html * Modules/paymentrequest/PaymentRequest.cpp: (WebCore::PaymentRequest::show): * Modules/paymentrequest/PaymentHandler.h: Adjust `PaymentHandler::convertData` to take a `Document` so that additional validation can be performed on the provided payment method(s) (e.g. check the Apple Pay version). * Modules/applepay/PaymentRequestValidator.h: * Modules/applepay/PaymentRequestValidator.mm: (WebCore::PaymentRequestValidator::validate): Allow callers to choose what fields to validate. This is needed because when the `ApplePaySessionPaymentRequest` created/converted when validating the payment method data in the `PaymentRequest` constructor isn't able to get fields from the `PaymentRequest` as it hasn't been created yet. * Modules/applepay/ApplePaySession.cpp: (WebCore::convertAndValidate): * Modules/applepay/paymentrequest/ApplePayPaymentHandler.h: * Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp: (WebCore::convertAndValidateApplePayRequest): (WebCore::ApplePayPaymentHandler::convertData): (WebCore::ApplePayPaymentHandler::show): * Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.h: * Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp: (WebCore::convertAndValidateApplePayAMSUIRequest): (WebCore::ApplePayAMSUIPaymentHandler::convertData): LayoutTests: * http/tests/ssl/applepay/PaymentRequest.https.html: * http/tests/ssl/applepay/PaymentRequest.https-expected.txt: Canonical link: https://commits.webkit.org/244794@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286452 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 06c91a1 commit 6bc11f6

File tree

13 files changed

+192
-144
lines changed

13 files changed

+192
-144
lines changed

LayoutTests/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2021-12-02 Devin Rousso <drousso@apple.com>
2+
3+
[Payment Request] Validate payment method data on construction
4+
https://bugs.webkit.org/show_bug.cgi?id=233292
5+
<rdar://problem/85736007>
6+
7+
Reviewed by Andy Estes.
8+
9+
* http/tests/ssl/applepay/PaymentRequest.https.html:
10+
* http/tests/ssl/applepay/PaymentRequest.https-expected.txt:
11+
112
2021-12-02 Fujii Hironori <Hironori.Fujii@sony.com>
213

314
[WinCairo] Unreviewed test gardening

LayoutTests/http/tests/ssl/applepay/PaymentRequest.https-expected.txt

Lines changed: 27 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,131 +10,114 @@ PASS new PaymentRequest([validPaymentMethod()], validPaymentDetails()) did not t
1010

1111
Testing ApplePayRequest.version
1212

13-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0; request = new PaymentRequest([paymentMethod], validPaymentDetails())
14-
PASS request.show() rejected promise with InvalidAccessError: "0" is not a supported version..
15-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000; request = new PaymentRequest([paymentMethod], validPaymentDetails())
16-
PASS request.show() rejected promise with InvalidAccessError: "1000" is not a supported version..
13+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0;
14+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception InvalidAccessError: "0" is not a supported version..
15+
16+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000;
17+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception InvalidAccessError: "1000" is not a supported version..
18+
1719

1820
Testing ApplePayRequest.countryCode
1921

2022
SETUP: paymentMethod = validPaymentMethod(); delete paymentMethod.data.countryCode;
2123
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.countryCode is required and must be an instance of DOMString.
2224

23-
2425
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = undefined;
2526
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.countryCode is required and must be an instance of DOMString.
2627

28+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid';
29+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalid" is not a valid country code..
2730

28-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid'; request = new PaymentRequest([paymentMethod], validPaymentDetails())
29-
PASS request.show() rejected promise with TypeError: "invalid" is not a valid country code..
31+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = '';
32+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "" is not a valid country code..
3033

31-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = ''; request = new PaymentRequest([paymentMethod], validPaymentDetails())
32-
PASS request.show() rejected promise with TypeError: "" is not a valid country code..
34+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null;
35+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "null" is not a valid country code..
3336

34-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null; request = new PaymentRequest([paymentMethod], validPaymentDetails())
35-
PASS request.show() rejected promise with TypeError: "null" is not a valid country code..
37+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7;
38+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "7" is not a valid country code..
3639

37-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7; request = new PaymentRequest([paymentMethod], validPaymentDetails())
38-
PASS request.show() rejected promise with TypeError: "7" is not a valid country code..
3940

4041
Testing ApplePayRequest.supportedNetworks
4142

4243
SETUP: paymentMethod = validPaymentMethod(); delete paymentMethod.data.supportedNetworks;
4344
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.supportedNetworks is required and must be an instance of sequence.
4445

45-
4646
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = '';
4747
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
4848

49-
5049
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = null;
5150
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
5251

53-
5452
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = undefined;
5553
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.supportedNetworks is required and must be an instance of sequence.
5654

57-
5855
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = 7;
5956
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
6057

58+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = [];
59+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: At least one supported network must be provided..
6160

62-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = []; request = new PaymentRequest([paymentMethod], validPaymentDetails())
63-
PASS request.show() rejected promise with TypeError: At least one supported network must be provided..
61+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork'];
62+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalidNetwork" is not a valid payment network..
6463

65-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork']; request = new PaymentRequest([paymentMethod], validPaymentDetails())
66-
PASS request.show() rejected promise with TypeError: "invalidNetwork" is not a valid payment network..
64+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa'];
65+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalidNetwork" is not a valid payment network..
6766

68-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa']; request = new PaymentRequest([paymentMethod], validPaymentDetails())
69-
PASS request.show() rejected promise with TypeError: "invalidNetwork" is not a valid payment network..
7067

7168
Testing ApplePayRequest.merchantCapabilities
7269

7370
SETUP: paymentMethod = validPaymentMethod(); delete paymentMethod.data.merchantCapabilities;
7471
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.merchantCapabilities is required and must be an instance of sequence.
7572

76-
7773
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = '';
7874
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
7975

80-
8176
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = null;
8277
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
8378

84-
8579
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = undefined;
8680
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.merchantCapabilities is required and must be an instance of sequence.
8781

88-
8982
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = 7;
9083
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
9184

92-
9385
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability'];
9486
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
9587

96-
9788
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability', 'supports3DS'];
9889
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
9990

91+
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = [];
92+
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: At least one merchant capability must be provided..
10093

101-
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = []; request = new PaymentRequest([paymentMethod], validPaymentDetails())
102-
PASS request.show() rejected promise with TypeError: At least one merchant capability must be provided..
10394

10495
Testing ApplePayRequest.requiredBillingContactFields
10596

10697
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = '';
10798
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
10899

109-
110100
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = null;
111101
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
112102

113-
114103
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = 7;
115104
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
116105

117-
118106
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = { };
119107
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
120108

121-
122109
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [''];
123110
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
124111

125-
126112
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [null];
127113
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
128114

129-
130115
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [undefined];
131116
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
132117

133-
134118
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [{}];
135119
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
136120

137-
138121
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = ['invalid'];
139122
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
140123

@@ -144,7 +127,6 @@ Testing ApplePayRequest.billingContact
144127
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.billingContact = '';
145128
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
146129

147-
148130
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.billingContact = 7;
149131
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
150132

@@ -154,35 +136,27 @@ Testing ApplePayRequest.requiredShippingContactFields
154136
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = '';
155137
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
156138

157-
158139
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = null;
159140
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
160141

161-
162142
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = 7;
163143
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence.
164144

165-
166145
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = { };
167146
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
168147

169-
170148
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [''];
171149
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
172150

173-
174151
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [null];
175152
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
176153

177-
178154
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [undefined];
179155
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
180156

181-
182157
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [{}];
183158
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
184159

185-
186160
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = ['invalid'];
187161
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
188162

@@ -192,7 +166,6 @@ Testing ApplePayRequest.shippingContact
192166
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = '';
193167
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
194168

195-
196169
SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = 7;
197170
PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error.
198171

@@ -229,13 +202,13 @@ PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception
229202
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: '', value: '0' } };
230203
PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception RangeError: "" is not a valid currency code..
231204

232-
233205
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: 'USD', value:'-10.00'} };
234206
PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception TypeError: Total currency values cannot be negative..
235207

236208
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: 'USD', value: '10000000000.00' } }; request = new PaymentRequest([validPaymentMethod()], paymentDetails)
237209
PASS request.show() rejected promise with TypeError: Total amount is too big..
238210

211+
239212
Testing PaymentDetails.displayItems
240213

241214
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.displayItems = '';
@@ -273,6 +246,8 @@ PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception
273246

274247
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.displayItems = [{ label: 'label', amount: { currency: 'EUR', value: '10.00' } }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails)
275248
PASS request.show() rejected promise with TypeError: "EUR" does not match the expected currency of "USD". Apple Pay requires all PaymentCurrencyAmounts to use the same currency code..
249+
250+
276251
Testing PaymentDetails.shippingOptions
277252

278253
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.shippingOptions = '';
@@ -310,6 +285,8 @@ PASS new PaymentRequest([validPaymentMethod()], paymentDetails, {requestShipping
310285

311286
SETUP: paymentDetails = validPaymentDetails(); paymentDetails.shippingOptions = [{ amount: { currency: 'EUR', value: '10.00' }, id: '', label: '' }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails, {requestShipping: true})
312287
PASS request.show() rejected promise with TypeError: "EUR" does not match the expected currency of "USD". Apple Pay requires all PaymentCurrencyAmounts to use the same currency code..
288+
289+
313290
Testing PaymentOptions
314291

315292
SETUP: paymentOptions = {}; paymentOptions.shippingType = '';

0 commit comments

Comments
 (0)