MerchantValidationEvent.cpp (6070B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/MerchantValidationEvent.h" 8 9 #include "mozilla/dom/Document.h" 10 #include "mozilla/dom/Location.h" 11 #include "mozilla/dom/PaymentRequest.h" 12 #include "mozilla/dom/URL.h" 13 #include "nsIURI.h" 14 #include "nsNetCID.h" 15 #include "nsNetUtil.h" 16 17 namespace mozilla::dom { 18 19 NS_IMPL_CYCLE_COLLECTION_INHERITED(MerchantValidationEvent, Event, 20 mValidationURL, mRequest) 21 22 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MerchantValidationEvent, Event) 23 NS_IMPL_CYCLE_COLLECTION_TRACE_END 24 25 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MerchantValidationEvent) 26 NS_INTERFACE_MAP_END_INHERITING(Event) 27 28 NS_IMPL_ADDREF_INHERITED(MerchantValidationEvent, Event) 29 NS_IMPL_RELEASE_INHERITED(MerchantValidationEvent, Event) 30 31 // User-land code constructor 32 already_AddRefed<MerchantValidationEvent> MerchantValidationEvent::Constructor( 33 const GlobalObject& aGlobal, const nsAString& aType, 34 const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv) { 35 // validate passed URL 36 nsCOMPtr<mozilla::dom::EventTarget> owner = 37 do_QueryInterface(aGlobal.GetAsSupports()); 38 return Constructor(owner, aType, aEventInitDict, aRv); 39 } 40 41 // Internal JS object constructor 42 already_AddRefed<MerchantValidationEvent> MerchantValidationEvent::Constructor( 43 EventTarget* aOwner, const nsAString& aType, 44 const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv) { 45 RefPtr<MerchantValidationEvent> e = new MerchantValidationEvent(aOwner); 46 bool trusted = e->Init(aOwner); 47 e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable); 48 e->init(aEventInitDict, aRv); 49 if (aRv.Failed()) { 50 return nullptr; 51 } 52 e->SetTrusted(trusted); 53 e->SetComposed(aEventInitDict.mComposed); 54 return e.forget(); 55 } 56 57 void MerchantValidationEvent::init( 58 const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv) { 59 // Check methodName is valid 60 if (!aEventInitDict.mMethodName.IsEmpty()) { 61 PaymentRequest::IsValidPaymentMethodIdentifier(aEventInitDict.mMethodName, 62 aRv); 63 if (aRv.Failed()) { 64 return; 65 } 66 } 67 SetMethodName(aEventInitDict.mMethodName); 68 nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject()); 69 auto doc = window->GetExtantDoc(); 70 if (!doc) { 71 aRv.ThrowAbortError("The owner document does not exist"); 72 return; 73 } 74 75 Result<OwningNonNull<nsIURI>, nsresult> rv = 76 doc->ResolveWithBaseURI(aEventInitDict.mValidationURL); 77 if (rv.isErr()) { 78 aRv.ThrowTypeError("validationURL cannot be parsed"); 79 return; 80 } 81 mValidationURL = rv.unwrap(); 82 } 83 84 MerchantValidationEvent::MerchantValidationEvent(EventTarget* aOwner) 85 : Event(aOwner, nullptr, nullptr), mWaitForUpdate(false) { 86 MOZ_ASSERT(aOwner); 87 } 88 89 void MerchantValidationEvent::ResolvedCallback(JSContext* aCx, 90 JS::Handle<JS::Value> aValue, 91 ErrorResult& aRv) { 92 MOZ_ASSERT(aCx); 93 MOZ_ASSERT(mRequest); 94 95 if (!mWaitForUpdate) { 96 return; 97 } 98 mWaitForUpdate = false; 99 100 // If we eventually end up supporting merchant validation 101 // we would validate `aValue` here, as per: 102 // https://w3c.github.io/payment-request/#validate-merchant-s-details-algorithm 103 // 104 // Right now, MerchantValidationEvent is only implemented for standards 105 // conformance, which is why at this point we throw a 106 // NS_ERROR_DOM_NOT_SUPPORTED_ERR. 107 108 ErrorResult result; 109 result.ThrowNotSupportedError( 110 "complete() is not supported by Firefox currently"); 111 mRequest->AbortUpdate(result); 112 mRequest->SetUpdating(false); 113 } 114 115 void MerchantValidationEvent::RejectedCallback(JSContext* aCx, 116 JS::Handle<JS::Value> aValue, 117 ErrorResult& aRv) { 118 MOZ_ASSERT(mRequest); 119 if (!mWaitForUpdate) { 120 return; 121 } 122 mWaitForUpdate = false; 123 ErrorResult result; 124 result.ThrowAbortError( 125 "The promise for MerchantValidtaionEvent.complete() is rejected"); 126 mRequest->AbortUpdate(result); 127 mRequest->SetUpdating(false); 128 } 129 130 void MerchantValidationEvent::Complete(Promise& aPromise, ErrorResult& aRv) { 131 if (!IsTrusted()) { 132 aRv.ThrowInvalidStateError("Called on an untrusted event"); 133 return; 134 } 135 136 MOZ_ASSERT(mRequest); 137 138 if (mWaitForUpdate) { 139 aRv.ThrowInvalidStateError( 140 "The MerchantValidationEvent is waiting for update"); 141 return; 142 } 143 144 if (!mRequest->ReadyForUpdate()) { 145 aRv.ThrowInvalidStateError( 146 "The PaymentRequest state is not eInteractive or the PaymentRequest is " 147 "updating"); 148 return; 149 } 150 151 aPromise.AppendNativeHandler(this); 152 153 StopPropagation(); 154 StopImmediatePropagation(); 155 mWaitForUpdate = true; 156 mRequest->SetUpdating(true); 157 } 158 159 void MerchantValidationEvent::SetRequest(PaymentRequest* aRequest) { 160 MOZ_ASSERT(IsTrusted()); 161 MOZ_ASSERT(!mRequest); 162 MOZ_ASSERT(aRequest); 163 164 mRequest = aRequest; 165 } 166 167 void MerchantValidationEvent::GetValidationURL(nsAString& aValidationURL) { 168 nsAutoCString utf8href; 169 nsresult rv = mValidationURL->GetSpec(utf8href); 170 MOZ_ASSERT(NS_SUCCEEDED(rv)); 171 (void)rv; 172 aValidationURL.Assign(NS_ConvertUTF8toUTF16(utf8href)); 173 } 174 175 void MerchantValidationEvent::GetMethodName(nsAString& aMethodName) { 176 aMethodName.Assign(mMethodName); 177 } 178 179 void MerchantValidationEvent::SetMethodName(const nsAString& aMethodName) { 180 mMethodName.Assign(aMethodName); 181 } 182 183 MerchantValidationEvent::~MerchantValidationEvent() = default; 184 185 JSObject* MerchantValidationEvent::WrapObjectInternal( 186 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 187 return MerchantValidationEvent_Binding::Wrap(aCx, this, aGivenProto); 188 } 189 190 } // namespace mozilla::dom