tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PaymentRequestParent.cpp (16263B)


      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 "PaymentRequestParent.h"
      8 
      9 #include "PaymentRequestData.h"
     10 #include "PaymentRequestService.h"
     11 #include "mozilla/ipc/InputStreamUtils.h"
     12 #include "nsArrayUtils.h"
     13 #include "nsCOMPtr.h"
     14 #include "nsIPaymentRequestService.h"
     15 #include "nsISupportsPrimitives.h"
     16 #include "nsServiceManagerUtils.h"
     17 
     18 namespace mozilla::dom {
     19 
     20 PaymentRequestParent::PaymentRequestParent()
     21    : mActorAlive(true), mRequestId(u""_ns) {}
     22 
     23 mozilla::ipc::IPCResult PaymentRequestParent::RecvRequestPayment(
     24    const IPCPaymentActionRequest& aRequest) {
     25  if (!mActorAlive) {
     26    return IPC_FAIL_NO_REASON(this);
     27  }
     28  switch (aRequest.type()) {
     29    case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest: {
     30      const IPCPaymentCreateActionRequest& request = aRequest;
     31      mRequestId = request.requestId();
     32      break;
     33    }
     34    case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest: {
     35      const IPCPaymentCanMakeActionRequest& request = aRequest;
     36      mRequestId = request.requestId();
     37      break;
     38    }
     39    case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
     40      const IPCPaymentShowActionRequest& request = aRequest;
     41      mRequestId = request.requestId();
     42      break;
     43    }
     44    case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
     45      const IPCPaymentAbortActionRequest& request = aRequest;
     46      mRequestId = request.requestId();
     47      break;
     48    }
     49    case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
     50      const IPCPaymentCompleteActionRequest& request = aRequest;
     51      mRequestId = request.requestId();
     52      break;
     53    }
     54    case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
     55      const IPCPaymentUpdateActionRequest& request = aRequest;
     56      mRequestId = request.requestId();
     57      break;
     58    }
     59    case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
     60      const IPCPaymentCloseActionRequest& request = aRequest;
     61      mRequestId = request.requestId();
     62      break;
     63    }
     64    case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
     65      const IPCPaymentRetryActionRequest& request = aRequest;
     66      mRequestId = request.requestId();
     67      break;
     68    }
     69    default: {
     70      return IPC_FAIL(this, "Unknown PaymentRequest action type");
     71    }
     72  }
     73  nsCOMPtr<nsIPaymentRequestService> service =
     74      do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
     75  MOZ_ASSERT(service);
     76  PaymentRequestService* rowService =
     77      static_cast<PaymentRequestService*>(service.get());
     78  MOZ_ASSERT(rowService);
     79  (void)NS_WARN_IF(
     80      NS_FAILED(rowService->RequestPayment(mRequestId, aRequest, this)));
     81  return IPC_OK();
     82 }
     83 
     84 nsresult PaymentRequestParent::RespondPayment(
     85    nsIPaymentActionResponse* aResponse) {
     86  if (!NS_IsMainThread()) {
     87    RefPtr<PaymentRequestParent> self = this;
     88    nsCOMPtr<nsIPaymentActionResponse> response = aResponse;
     89    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
     90        "PaymentRequestParent::RespondPayment",
     91        [self, response]() { self->RespondPayment(response); });
     92    return NS_DispatchToMainThread(r);
     93  }
     94 
     95  if (!mActorAlive) {
     96    return NS_ERROR_FAILURE;
     97  }
     98  uint32_t type;
     99  nsresult rv = aResponse->GetType(&type);
    100  NS_ENSURE_SUCCESS(rv, rv);
    101  nsAutoString requestId;
    102  rv = aResponse->GetRequestId(requestId);
    103  NS_ENSURE_SUCCESS(rv, rv);
    104  switch (type) {
    105    case nsIPaymentActionResponse::CANMAKE_ACTION: {
    106      nsCOMPtr<nsIPaymentCanMakeActionResponse> response =
    107          do_QueryInterface(aResponse);
    108      MOZ_ASSERT(response);
    109      bool result;
    110      rv = response->GetResult(&result);
    111      NS_ENSURE_SUCCESS(rv, rv);
    112      IPCPaymentCanMakeActionResponse actionResponse(requestId, result);
    113      if (!SendRespondPayment(actionResponse)) {
    114        return NS_ERROR_FAILURE;
    115      }
    116      break;
    117    }
    118    case nsIPaymentActionResponse::SHOW_ACTION: {
    119      nsCOMPtr<nsIPaymentShowActionResponse> response =
    120          do_QueryInterface(aResponse);
    121      MOZ_ASSERT(response);
    122      uint32_t acceptStatus;
    123      NS_ENSURE_SUCCESS(response->GetAcceptStatus(&acceptStatus),
    124                        NS_ERROR_FAILURE);
    125      nsAutoString methodName;
    126      NS_ENSURE_SUCCESS(response->GetMethodName(methodName), NS_ERROR_FAILURE);
    127      IPCPaymentResponseData ipcData;
    128      if (acceptStatus == nsIPaymentActionResponse::PAYMENT_ACCEPTED) {
    129        nsCOMPtr<nsIPaymentResponseData> data;
    130        NS_ENSURE_SUCCESS(response->GetData(getter_AddRefs(data)),
    131                          NS_ERROR_FAILURE);
    132        MOZ_ASSERT(data);
    133        NS_ENSURE_SUCCESS(SerializeResponseData(ipcData, data),
    134                          NS_ERROR_FAILURE);
    135      } else {
    136        ipcData = IPCGeneralResponse();
    137      }
    138 
    139      nsAutoString payerName;
    140      NS_ENSURE_SUCCESS(response->GetPayerName(payerName), NS_ERROR_FAILURE);
    141      nsAutoString payerEmail;
    142      NS_ENSURE_SUCCESS(response->GetPayerEmail(payerEmail), NS_ERROR_FAILURE);
    143      nsAutoString payerPhone;
    144      NS_ENSURE_SUCCESS(response->GetPayerPhone(payerPhone), NS_ERROR_FAILURE);
    145      IPCPaymentShowActionResponse actionResponse(
    146          requestId, acceptStatus, methodName, ipcData, payerName, payerEmail,
    147          payerPhone);
    148      if (!SendRespondPayment(actionResponse)) {
    149        return NS_ERROR_FAILURE;
    150      }
    151      break;
    152    }
    153    case nsIPaymentActionResponse::ABORT_ACTION: {
    154      nsCOMPtr<nsIPaymentAbortActionResponse> response =
    155          do_QueryInterface(aResponse);
    156      MOZ_ASSERT(response);
    157      bool isSucceeded;
    158      rv = response->IsSucceeded(&isSucceeded);
    159      NS_ENSURE_SUCCESS(rv, rv);
    160      IPCPaymentAbortActionResponse actionResponse(requestId, isSucceeded);
    161      if (!SendRespondPayment(actionResponse)) {
    162        return NS_ERROR_FAILURE;
    163      }
    164      break;
    165    }
    166    case nsIPaymentActionResponse::COMPLETE_ACTION: {
    167      nsCOMPtr<nsIPaymentCompleteActionResponse> response =
    168          do_QueryInterface(aResponse);
    169      MOZ_ASSERT(response);
    170      bool isCompleted;
    171      rv = response->IsCompleted(&isCompleted);
    172      NS_ENSURE_SUCCESS(rv, rv);
    173      IPCPaymentCompleteActionResponse actionResponse(requestId, isCompleted);
    174      if (!SendRespondPayment(actionResponse)) {
    175        return NS_ERROR_FAILURE;
    176      }
    177      break;
    178    }
    179    default: {
    180      return NS_ERROR_FAILURE;
    181    }
    182  }
    183  return NS_OK;
    184 }
    185 
    186 nsresult PaymentRequestParent::ChangeShippingAddress(
    187    const nsAString& aRequestId, nsIPaymentAddress* aAddress) {
    188  if (!NS_IsMainThread()) {
    189    RefPtr<PaymentRequestParent> self = this;
    190    nsCOMPtr<nsIPaymentAddress> address = aAddress;
    191    nsAutoString requestId(aRequestId);
    192    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
    193        "dom::PaymentRequestParent::ChangeShippingAddress",
    194        [self, requestId, address]() {
    195          self->ChangeShippingAddress(requestId, address);
    196        });
    197    return NS_DispatchToMainThread(r);
    198  }
    199  if (!mActorAlive) {
    200    return NS_ERROR_FAILURE;
    201  }
    202 
    203  IPCPaymentAddress ipcAddress;
    204  nsresult rv = SerializeAddress(ipcAddress, aAddress);
    205  NS_ENSURE_SUCCESS(rv, rv);
    206 
    207  nsAutoString requestId(aRequestId);
    208  if (!SendChangeShippingAddress(requestId, ipcAddress)) {
    209    return NS_ERROR_FAILURE;
    210  }
    211  return NS_OK;
    212 }
    213 
    214 nsresult PaymentRequestParent::ChangeShippingOption(const nsAString& aRequestId,
    215                                                    const nsAString& aOption) {
    216  if (!NS_IsMainThread()) {
    217    RefPtr<PaymentRequestParent> self = this;
    218    nsAutoString requestId(aRequestId);
    219    nsAutoString option(aOption);
    220    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
    221        "dom::PaymentRequestParent::ChangeShippingOption",
    222        [self, requestId, option]() {
    223          self->ChangeShippingOption(requestId, option);
    224        });
    225    return NS_DispatchToMainThread(r);
    226  }
    227  if (!mActorAlive) {
    228    return NS_ERROR_FAILURE;
    229  }
    230  nsAutoString requestId(aRequestId);
    231  nsAutoString option(aOption);
    232  if (!SendChangeShippingOption(requestId, option)) {
    233    return NS_ERROR_FAILURE;
    234  }
    235  return NS_OK;
    236 }
    237 
    238 nsresult PaymentRequestParent::ChangePayerDetail(const nsAString& aRequestId,
    239                                                 const nsAString& aPayerName,
    240                                                 const nsAString& aPayerEmail,
    241                                                 const nsAString& aPayerPhone) {
    242  nsAutoString requestId(aRequestId);
    243  nsAutoString payerName(aPayerName);
    244  nsAutoString payerEmail(aPayerEmail);
    245  nsAutoString payerPhone(aPayerPhone);
    246  if (!NS_IsMainThread()) {
    247    RefPtr<PaymentRequestParent> self = this;
    248    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
    249        "dom::PaymentRequestParent::ChangePayerDetail",
    250        [self, requestId, payerName, payerEmail, payerPhone]() {
    251          self->ChangePayerDetail(requestId, payerName, payerEmail, payerPhone);
    252        });
    253    return NS_DispatchToMainThread(r);
    254  }
    255  if (!mActorAlive) {
    256    return NS_ERROR_FAILURE;
    257  }
    258  if (!SendChangePayerDetail(requestId, payerName, payerEmail, payerPhone)) {
    259    return NS_ERROR_FAILURE;
    260  }
    261  return NS_OK;
    262 }
    263 
    264 nsresult PaymentRequestParent::ChangePaymentMethod(
    265    const nsAString& aRequestId, const nsAString& aMethodName,
    266    nsIMethodChangeDetails* aMethodDetails) {
    267  nsAutoString requestId(aRequestId);
    268  nsAutoString methodName(aMethodName);
    269  nsCOMPtr<nsIMethodChangeDetails> methodDetails(aMethodDetails);
    270  if (!NS_IsMainThread()) {
    271    RefPtr<PaymentRequestParent> self = this;
    272    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
    273        "dom::PaymentRequestParent::ChangePaymentMethod",
    274        [self, requestId, methodName, methodDetails]() {
    275          self->ChangePaymentMethod(requestId, methodName, methodDetails);
    276        });
    277    return NS_DispatchToMainThread(r);
    278  }
    279  if (!mActorAlive) {
    280    return NS_ERROR_FAILURE;
    281  }
    282 
    283  // Convert nsIMethodChangeDetails to IPCMethodChangeDetails
    284  // aMethodChangeDetails can be null
    285  IPCMethodChangeDetails ipcChangeDetails;
    286  if (aMethodDetails) {
    287    uint32_t dataType;
    288    NS_ENSURE_SUCCESS(aMethodDetails->GetType(&dataType), NS_ERROR_FAILURE);
    289    switch (dataType) {
    290      case nsIMethodChangeDetails::GENERAL_DETAILS: {
    291        nsCOMPtr<nsIGeneralChangeDetails> details =
    292            do_QueryInterface(methodDetails);
    293        MOZ_ASSERT(details);
    294        IPCGeneralChangeDetails ipcGeneralDetails;
    295        NS_ENSURE_SUCCESS(details->GetDetails(ipcGeneralDetails.details()),
    296                          NS_ERROR_FAILURE);
    297        ipcChangeDetails = ipcGeneralDetails;
    298        break;
    299      }
    300      case nsIMethodChangeDetails::BASICCARD_DETAILS: {
    301        nsCOMPtr<nsIBasicCardChangeDetails> details =
    302            do_QueryInterface(methodDetails);
    303        MOZ_ASSERT(details);
    304        IPCBasicCardChangeDetails ipcBasicCardDetails;
    305        nsCOMPtr<nsIPaymentAddress> address;
    306        NS_ENSURE_SUCCESS(details->GetBillingAddress(getter_AddRefs(address)),
    307                          NS_ERROR_FAILURE);
    308        IPCPaymentAddress ipcAddress;
    309        NS_ENSURE_SUCCESS(SerializeAddress(ipcAddress, address),
    310                          NS_ERROR_FAILURE);
    311        ipcBasicCardDetails.billingAddress() = ipcAddress;
    312        ipcChangeDetails = ipcBasicCardDetails;
    313        break;
    314      }
    315      default: {
    316        return NS_ERROR_FAILURE;
    317      }
    318    }
    319  }
    320  if (!SendChangePaymentMethod(requestId, methodName, ipcChangeDetails)) {
    321    return NS_ERROR_FAILURE;
    322  }
    323  return NS_OK;
    324 }
    325 
    326 mozilla::ipc::IPCResult PaymentRequestParent::Recv__delete__() {
    327  mActorAlive = false;
    328  return IPC_OK();
    329 }
    330 
    331 void PaymentRequestParent::ActorDestroy(ActorDestroyReason aWhy) {
    332  mActorAlive = false;
    333  nsCOMPtr<nsIPaymentRequestService> service =
    334      do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
    335  MOZ_ASSERT(service);
    336  if (!mRequestId.Equals(u""_ns)) {
    337    nsCOMPtr<nsIPaymentRequest> request;
    338    nsresult rv =
    339        service->GetPaymentRequestById(mRequestId, getter_AddRefs(request));
    340    if (NS_WARN_IF(NS_FAILED(rv))) {
    341      return;
    342    }
    343    if (!request) {
    344      return;
    345    }
    346    payments::PaymentRequest* rowRequest =
    347        static_cast<payments::PaymentRequest*>(request.get());
    348    MOZ_ASSERT(rowRequest);
    349    rowRequest->SetIPC(nullptr);
    350  }
    351 }
    352 
    353 nsresult PaymentRequestParent::SerializeAddress(IPCPaymentAddress& aIPCAddress,
    354                                                nsIPaymentAddress* aAddress) {
    355  // address can be nullptr
    356  if (!aAddress) {
    357    return NS_OK;
    358  }
    359  nsAutoString country;
    360  nsresult rv = aAddress->GetCountry(country);
    361  NS_ENSURE_SUCCESS(rv, rv);
    362 
    363  nsCOMPtr<nsIArray> iaddressLine;
    364  rv = aAddress->GetAddressLine(getter_AddRefs(iaddressLine));
    365  NS_ENSURE_SUCCESS(rv, rv);
    366 
    367  nsAutoString region;
    368  rv = aAddress->GetRegion(region);
    369  NS_ENSURE_SUCCESS(rv, rv);
    370 
    371  nsAutoString regionCode;
    372  rv = aAddress->GetRegionCode(regionCode);
    373  NS_ENSURE_SUCCESS(rv, rv);
    374 
    375  nsAutoString city;
    376  rv = aAddress->GetCity(city);
    377  NS_ENSURE_SUCCESS(rv, rv);
    378 
    379  nsAutoString dependentLocality;
    380  rv = aAddress->GetDependentLocality(dependentLocality);
    381  NS_ENSURE_SUCCESS(rv, rv);
    382 
    383  nsAutoString postalCode;
    384  rv = aAddress->GetPostalCode(postalCode);
    385  NS_ENSURE_SUCCESS(rv, rv);
    386 
    387  nsAutoString sortingCode;
    388  rv = aAddress->GetSortingCode(sortingCode);
    389  NS_ENSURE_SUCCESS(rv, rv);
    390 
    391  nsAutoString organization;
    392  rv = aAddress->GetOrganization(organization);
    393  NS_ENSURE_SUCCESS(rv, rv);
    394 
    395  nsAutoString recipient;
    396  rv = aAddress->GetRecipient(recipient);
    397  NS_ENSURE_SUCCESS(rv, rv);
    398 
    399  nsAutoString phone;
    400  rv = aAddress->GetPhone(phone);
    401  NS_ENSURE_SUCCESS(rv, rv);
    402 
    403  nsTArray<nsString> addressLine;
    404  uint32_t length;
    405  rv = iaddressLine->GetLength(&length);
    406  NS_ENSURE_SUCCESS(rv, rv);
    407  for (uint32_t index = 0; index < length; ++index) {
    408    nsCOMPtr<nsISupportsString> iaddress =
    409        do_QueryElementAt(iaddressLine, index);
    410    MOZ_ASSERT(iaddress);
    411    nsAutoString address;
    412    rv = iaddress->GetData(address);
    413    NS_ENSURE_SUCCESS(rv, rv);
    414    addressLine.AppendElement(address);
    415  }
    416 
    417  aIPCAddress = IPCPaymentAddress(country, addressLine, region, regionCode,
    418                                  city, dependentLocality, postalCode,
    419                                  sortingCode, organization, recipient, phone);
    420  return NS_OK;
    421 }
    422 
    423 nsresult PaymentRequestParent::SerializeResponseData(
    424    IPCPaymentResponseData& aIPCData, nsIPaymentResponseData* aData) {
    425  NS_ENSURE_ARG_POINTER(aData);
    426  uint32_t dataType;
    427  NS_ENSURE_SUCCESS(aData->GetType(&dataType), NS_ERROR_FAILURE);
    428  switch (dataType) {
    429    case nsIPaymentResponseData::GENERAL_RESPONSE: {
    430      nsCOMPtr<nsIGeneralResponseData> response = do_QueryInterface(aData);
    431      MOZ_ASSERT(response);
    432      IPCGeneralResponse data;
    433      NS_ENSURE_SUCCESS(response->GetData(data.data()), NS_ERROR_FAILURE);
    434      aIPCData = data;
    435      break;
    436    }
    437    case nsIPaymentResponseData::BASICCARD_RESPONSE: {
    438      nsCOMPtr<nsIBasicCardResponseData> response = do_QueryInterface(aData);
    439      MOZ_ASSERT(response);
    440      IPCBasicCardResponse data;
    441      NS_ENSURE_SUCCESS(response->GetCardholderName(data.cardholderName()),
    442                        NS_ERROR_FAILURE);
    443      NS_ENSURE_SUCCESS(response->GetCardNumber(data.cardNumber()),
    444                        NS_ERROR_FAILURE);
    445      NS_ENSURE_SUCCESS(response->GetExpiryMonth(data.expiryMonth()),
    446                        NS_ERROR_FAILURE);
    447      NS_ENSURE_SUCCESS(response->GetExpiryYear(data.expiryYear()),
    448                        NS_ERROR_FAILURE);
    449      NS_ENSURE_SUCCESS(response->GetCardSecurityCode(data.cardSecurityCode()),
    450                        NS_ERROR_FAILURE);
    451      nsCOMPtr<nsIPaymentAddress> address;
    452      NS_ENSURE_SUCCESS(response->GetBillingAddress(getter_AddRefs(address)),
    453                        NS_ERROR_FAILURE);
    454      IPCPaymentAddress ipcAddress;
    455      NS_ENSURE_SUCCESS(SerializeAddress(ipcAddress, address),
    456                        NS_ERROR_FAILURE);
    457      data.billingAddress() = ipcAddress;
    458      aIPCData = data;
    459      break;
    460    }
    461    default: {
    462      return NS_ERROR_FAILURE;
    463    }
    464  }
    465  return NS_OK;
    466 }
    467 }  // namespace mozilla::dom