Bug 1252570 - Remove mozPay. r=ehsan,mfinkle,fabrice

MozReview-Commit-ID: C50fvuNJoGq
This commit is contained in:
Fernando Jimenez 2016-08-19 15:14:53 +02:00 committed by Alexandre Lissy
parent 93ab0022ac
commit 16126fcd4e
48 changed files with 0 additions and 2531 deletions

View File

@ -467,9 +467,6 @@ pref("media.realtime_decoder.enabled", true);
// TCPSocket
pref("dom.mozTCPSocket.enabled", true);
// WebPayment
pref("dom.mozPay.enabled", true);
// "Preview" landing of bug 710563, which is bogged down in analysis
// of talos regression. This is a needed change for higher-framerate
// CSS animations, and incidentally works around an apparent bug in

View File

@ -9,7 +9,6 @@ window.performance.mark('gecko-shell-loadstart');
Cu.import('resource://gre/modules/ContactService.jsm');
Cu.import('resource://gre/modules/AlarmService.jsm');
Cu.import('resource://gre/modules/NotificationDB.jsm');
Cu.import('resource://gre/modules/Payment.jsm');
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
Cu.import('resource://gre/modules/Keyboard.jsm');

View File

@ -37,12 +37,6 @@ component {a6b2ab13-9037-423a-9897-dde1081be323} OMAContentHandler.js
contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.drm.message {a6b2ab13-9037-423a-9897-dde1081be323}
contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.dd+xml {a6b2ab13-9037-423a-9897-dde1081be323}
# Payments
component {8b83eabc-7929-47f4-8b48-4dea8d887e4b} PaymentGlue.js
contract @mozilla.org/payment/ui-glue;1 {8b83eabc-7929-47f4-8b48-4dea8d887e4b}
component {4834b2e1-2c91-44ea-b020-e2581ed279a4} PaymentProviderStrategy.js
contract @mozilla.org/payment/provider-strategy;1 {4834b2e1-2c91-44ea-b020-e2581ed279a4}
# TelProtocolHandler.js
component {782775dd-7351-45ea-aff1-0ffa872cfdd2} TelProtocolHandler.js
contract @mozilla.org/network/protocol;1?name=tel {782775dd-7351-45ea-aff1-0ffa872cfdd2}

View File

@ -1,202 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
// Type of MozChromEvents to handle payment dialogs.
const kOpenPaymentConfirmationEvent = "open-payment-confirmation-dialog";
const kOpenPaymentFlowEvent = "open-payment-flow-dialog";
const kClosePaymentFlowEvent = "close-payment-flow-dialog";
// Observer notification topic for payment flow cancelation.
const kPaymentFlowCancelled = "payment-flow-cancelled";
const PREF_DEBUG = "dom.payment.debug";
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
"resource://gre/modules/SystemAppProxy.jsm");
function PaymentUI() {
try {
this._debug =
Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
this._debug = false;
}
}
PaymentUI.prototype = {
confirmPaymentRequest: function confirmPaymentRequest(aRequestId,
aRequests,
aSuccessCb,
aErrorCb) {
let _error = function _error(errorMsg) {
if (aErrorCb) {
aErrorCb.onresult(aRequestId, errorMsg);
}
};
// The UI should listen for mozChromeEvent 'open-payment-confirmation-dialog'
// type in order to create and show the payment request confirmation frame
// embeded within a trusted dialog.
let id = kOpenPaymentConfirmationEvent + "-" + this.getRandomId();
let detail = {
type: kOpenPaymentConfirmationEvent,
id: id,
requestId: aRequestId,
paymentRequests: aRequests
};
// Once the user confirm the payment request and makes his choice, we get
// back to the DOM part to get the appropriate payment flow information
// based on the selected payment provider.
this._handleSelection = (function _handleSelection(evt) {
let msg = evt.detail;
if (msg.id != id) {
return;
}
if (msg.userSelection && aSuccessCb) {
aSuccessCb.onresult(aRequestId, msg.userSelection);
} else if (msg.errorMsg) {
_error(msg.errorMsg);
}
SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
this._handleSelection = null;
}).bind(this);
SystemAppProxy.addEventListener("mozContentEvent", this._handleSelection);
SystemAppProxy.dispatchEvent(detail);
},
showPaymentFlow: function showPaymentFlow(aRequestId,
aPaymentFlowInfo,
aErrorCb) {
let _error = (errorMsg) => {
if (aErrorCb) {
aErrorCb.onresult(aRequestId, errorMsg);
}
};
// We ask the UI to browse to the selected payment flow.
let id = kOpenPaymentFlowEvent + "-" + this.getRandomId();
let detail = {
type: kOpenPaymentFlowEvent,
id: id,
requestId: aRequestId
};
this._setPaymentRequest = (event) => {
let message = event.detail;
if (message.id != id) {
return;
}
let frame = message.frame;
let docshell = frame.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
docshell.paymentRequestId = aRequestId;
frame.src = aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt;
SystemAppProxy.removeEventListener("mozContentEvent",
this._setPaymentRequest);
};
SystemAppProxy.addEventListener("mozContentEvent",
this._setPaymentRequest);
// We listen for UI notifications about a closed payment flow. The UI
// should provide the reason of the closure within the 'errorMsg' parameter
this._notifyPayFlowClosed = (evt) => {
let msg = evt.detail;
if (msg.id != id) {
return;
}
if (msg.type != 'cancel') {
return;
}
if (msg.errorMsg) {
_error(msg.errorMsg);
}
SystemAppProxy.removeEventListener("mozContentEvent",
this._notifyPayFlowClosed);
this._notifyPayFlowClosed = null;
Services.obs.notifyObservers(null, kPaymentFlowCancelled, null);
};
SystemAppProxy.addEventListener("mozContentEvent",
this._notifyPayFlowClosed);
SystemAppProxy.dispatchEvent(detail);
},
closePaymentFlow: function(aRequestId) {
return new Promise((aResolve) => {
// After receiving the payment provider confirmation about the
// successful or failed payment flow, we notify the UI to close the
// payment flow dialog and return to the caller application.
let id = kClosePaymentFlowEvent + "-" + uuidgen.generateUUID().toString();
let detail = {
type: kClosePaymentFlowEvent,
id: id,
requestId: aRequestId
};
// In order to avoid race conditions, we wait for the UI to notify that
// it has successfully closed the payment flow and has recovered the
// caller app, before notifying the parent process to fire the success
// or error event over the DOMRequest.
SystemAppProxy.addEventListener("mozContentEvent",
(function closePaymentFlowReturn() {
SystemAppProxy.removeEventListener("mozContentEvent",
closePaymentFlowReturn);
this.cleanup();
aResolve();
}).bind(this));
SystemAppProxy.dispatchEvent(detail);
});
},
cleanup: function cleanup() {
if (this._handleSelection) {
SystemAppProxy.removeEventListener("mozContentEvent",
this._handleSelection);
this._handleSelection = null;
}
if (this._notifyPayFlowClosed) {
SystemAppProxy.removeEventListener("mozContentEvent",
this._notifyPayFlowClosed);
this._notifyPayFlowClosed = null;
}
},
getRandomId: function getRandomId() {
return uuidgen.generateUUID().toString();
},
classID: Components.ID("{8b83eabc-7929-47f4-8b48-4dea8d887e4b}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue])
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUI]);

View File

@ -1,178 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const PREF_DEBUG = "dom.payment.debug";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gIccService",
"@mozilla.org/icc/iccservice;1",
"nsIIccService");
XPCOMUtils.defineLazyServiceGetter(this, "gRil",
"@mozilla.org/ril;1",
"nsIRadioInterfaceLayer");
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
const kMozSettingsChangedObserverTopic = "mozsettings-changed";
const kRilDefaultDataServiceId = "ril.data.defaultServiceId";
const kRilDefaultPaymentServiceId = "ril.payment.defaultServiceId";
var _debug;
try {
_debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e){
_debug = false;
}
function LOG(s) {
if (!_debug) {
return;
}
dump("== Payment Provider == " + s + "\n");
}
function LOGE(s) {
dump("== Payment Provider ERROR == " + s + "\n");
}
function PaymentSettings() {
Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
[kRilDefaultDataServiceId, kRilDefaultPaymentServiceId].forEach(setting => {
gSettingsService.createLock().get(setting, this);
});
}
PaymentSettings.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsISettingsServiceCallback,
Ci.nsIObserver]),
dataServiceId: 0,
_paymentServiceId: 0,
get paymentServiceId() {
return this._paymentServiceId;
},
set paymentServiceId(serviceId) {
// We allow the payment provider to set the service ID that will be used
// for the payment process.
// This service ID will be the one used by the silent SMS flow.
// If the payment is done with an external SIM, the service ID must be set
// to null.
if (serviceId != null && serviceId >= gRil.numRadioInterfaces) {
LOGE("Invalid service ID " + serviceId);
return;
}
gSettingsService.createLock().set(kRilDefaultPaymentServiceId,
serviceId, 0);
this._paymentServiceId = serviceId;
},
setServiceId: function(aName, aValue) {
switch (aName) {
case kRilDefaultDataServiceId:
this.dataServiceId = aValue;
if (_debug) {
LOG("dataServiceId " + this.dataServiceId);
}
break;
case kRilDefaultPaymentServiceId:
this._paymentServiceId = aValue;
if (_debug) {
LOG("paymentServiceId " + this._paymentServiceId);
}
break;
}
},
handle: function(aName, aValue) {
if (aName != kRilDefaultDataServiceId) {
return;
}
this.setServiceId(aName, aValue);
},
observe: function(aSubject, aTopic, aData) {
if (aTopic != kMozSettingsChangedObserverTopic) {
return;
}
try {
if ("wrappedJSObject" in aSubject) {
aSubject = aSubject.wrappedJSObject;
}
if (!aSubject.key ||
(aSubject.key !== kRilDefaultDataServiceId &&
aSubject.key !== kRilDefaultPaymentServiceId)) {
return;
}
this.setServiceId(aSubject.key, aSubject.value);
} catch (e) {
LOGE(e);
}
},
cleanup: function() {
Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
}
};
function PaymentProviderStrategy() {
this._settings = new PaymentSettings();
}
PaymentProviderStrategy.prototype = {
get paymentServiceId() {
return this._settings.paymentServiceId;
},
set paymentServiceId(aServiceId) {
this._settings.paymentServiceId = aServiceId;
},
get iccInfo() {
if (!this._iccInfo) {
this._iccInfo = [];
for (let i = 0; i < gRil.numRadioInterfaces; i++) {
let icc = gIccService.getIccByServiceId(i);
let info = icc && icc.iccInfo;
if (!info) {
LOGE("Tried to get the ICC info for an invalid service ID " + i);
continue;
}
this._iccInfo.push({
iccId: info.iccid,
mcc: info.mcc,
mnc: info.mnc,
dataPrimary: i == this._settings.dataServiceId
});
}
}
return this._iccInfo;
},
cleanup: function() {
this._settings.cleanup();
},
classID: Components.ID("{4834b2e1-2c91-44ea-b020-e2581ed279a4}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentProviderStrategy])
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentProviderStrategy]);

View File

@ -18,8 +18,6 @@ EXTRA_COMPONENTS += [
'HelperAppDialog.js',
'MailtoProtocolHandler.js',
'OMAContentHandler.js',
'PaymentGlue.js',
'PaymentProviderStrategy.js',
'PresentationRequestUIGlue.js',
'ProcessGlobal.js',
'SmsProtocolHandler.js',

View File

@ -39,7 +39,6 @@ MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
MOZ_TIME_MANAGER=1
MOZ_SIMPLEPUSH=1
MOZ_PAY=1
MOZ_TOOLKIT_SEARCH=
MOZ_B2G=1

View File

@ -40,7 +40,6 @@ fi
MOZ_APP_ID={d1bfe7d9-c01e-4237-998b-7b5f960a4314}
MOZ_TIME_MANAGER=1
MOZ_PAY=1
MOZ_TOOLKIT_SEARCH=
MOZ_PLACES=
MOZ_B2G=1

View File

@ -186,7 +186,6 @@
@RESPATH@/components/dom_notification.xpt
@RESPATH@/components/dom_html.xpt
@RESPATH@/components/dom_offline.xpt
@RESPATH@/components/dom_payment.xpt
@RESPATH@/components/dom_json.xpt
@RESPATH@/components/dom_messages.xpt
@RESPATH@/components/dom_power.xpt
@ -627,11 +626,6 @@
@RESPATH@/components/ActivityWrapper.js
@RESPATH@/components/ActivityMessageConfigurator.js
@RESPATH@/components/Payment.js
@RESPATH@/components/PaymentFlowInfo.js
@RESPATH@/components/PaymentProvider.js
@RESPATH@/components/Payment.manifest
@RESPATH@/components/DownloadsAPI.js
@RESPATH@/components/DownloadsAPI.manifest
@ -873,8 +867,6 @@ bin/libfreebl_32int64_3.so
@RESPATH@/components/DirectoryProvider.js
@RESPATH@/components/ProcessGlobal.js
@RESPATH@/components/OMAContentHandler.js
@RESPATH@/components/PaymentGlue.js
@RESPATH@/components/PaymentProviderStrategy.js
@RESPATH@/components/RecoveryService.js
@RESPATH@/components/MailtoProtocolHandler.js
@RESPATH@/components/SmsProtocolHandler.js

View File

@ -54,8 +54,6 @@ MAR_CHANNEL_ID=firefox-mozilla-central
MOZ_PROFILE_MIGRATOR=1
MOZ_APP_STATIC_INI=1
MOZ_WEBGL_CONFORMANT=1
# Enable navigator.mozPay
MOZ_PAY=1
MOZ_JSDOWNLOADS=1
MOZ_RUST_MP4PARSE=1

View File

@ -226,7 +226,6 @@
@RESPATH@/components/dom_xhr.xpt
@RESPATH@/components/dom_xpath.xpt
@RESPATH@/components/dom_xul.xpt
@RESPATH@/components/dom_payment.xpt
@RESPATH@/components/dom_presentation.xpt
@RESPATH@/components/downloads.xpt
@RESPATH@/components/editor.xpt
@ -545,10 +544,6 @@
@RESPATH@/components/TVSimulatorService.js
@RESPATH@/components/TVSimulatorService.manifest
@RESPATH@/components/Payment.js
@RESPATH@/components/PaymentFlowInfo.js
@RESPATH@/components/Payment.manifest
#ifdef MOZ_WEBRTC
@RESPATH@/components/PeerConnection.js
@RESPATH@/components/PeerConnection.manifest

View File

@ -14558,37 +14558,6 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetPaymentRequestId(const nsAString& aPaymentRequestId)
{
mPaymentRequestId = aPaymentRequestId;
return NS_OK;
}
nsString
nsDocShell::GetInheritedPaymentRequestId()
{
if (!mPaymentRequestId.IsEmpty()) {
return mPaymentRequestId;
}
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetSameTypeParent(getter_AddRefs(parentAsItem));
nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
if (!parent) {
return mPaymentRequestId;
}
return static_cast<nsDocShell*>(parent.get())->GetInheritedPaymentRequestId();
}
NS_IMETHODIMP
nsDocShell::GetPaymentRequestId(nsAString& aPaymentRequestId)
{
aPaymentRequestId = GetInheritedPaymentRequestId();
return NS_OK;
}
bool
nsDocShell::InFrameSwap()
{

View File

@ -1017,10 +1017,6 @@ protected:
// origin attribute set.
uint32_t mPrivateBrowsingId;
nsString mPaymentRequestId;
nsString GetInheritedPaymentRequestId();
nsString mInterceptedDocumentId;
private:

View File

@ -1073,11 +1073,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean hasLoadedNonBlankURI;
/**
* Holds the id of the payment request associated with this docshell if any.
*/
attribute DOMString paymentRequestId;
/**
* Allow usage of -moz-window-dragging:drag for content docshells.
* True for top level chrome docshells. Throws if set to false with

View File

@ -124,11 +124,6 @@
#include <cutils/properties.h>
#endif
#ifdef MOZ_PAY
#include "nsIPaymentContentHelperService.h"
#include "mozilla/dom/DOMRequest.h"
#endif
namespace mozilla {
namespace dom {
@ -2273,36 +2268,6 @@ Navigator::MozE10sEnabled()
return true;
}
#ifdef MOZ_PAY
already_AddRefed<DOMRequest>
Navigator::MozPay(JSContext* aCx,
JS::Handle<JS::Value> aJwts,
ErrorResult& aRv)
{
if (!mWindow || !mWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsresult rv;
nsCOMPtr<nsIPaymentContentHelperService> service =
do_GetService("@mozilla.org/payment/content-helper-service;1", &rv);
if (!service) {
aRv.Throw(rv);
return nullptr;
}
RefPtr<nsIDOMDOMRequest> request;
rv = service->Pay(mWindow, aJwts, getter_AddRefs(request));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
}
#endif // MOZ_PAY
/* static */
already_AddRefed<nsPIDOMWindowInner>
Navigator::GetWindowFromGlobal(JSObject* aGlobal)

View File

@ -294,12 +294,6 @@ public:
bool MozE10sEnabled();
#ifdef MOZ_PAY
already_AddRefed<DOMRequest> MozPay(JSContext* aCx,
JS::Handle<JS::Value> aJwts,
ErrorResult& aRv);
#endif // MOZ_PAY
static void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
// WebIDL helper methods

View File

@ -132,9 +132,6 @@ if CONFIG['MOZ_B2G_RIL']:
'wappush',
]
if CONFIG['MOZ_PAY']:
DIRS += ['payment']
if CONFIG['MOZ_NFC']:
DIRS += ['nfc']

View File

@ -1,120 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
const PAYMENT_IPC_MSG_NAMES = ["Payment:Success",
"Payment:Failed"];
const PREF_DEBUG = "dom.payment.debug";
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
var _debug;
try {
_debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
_debug = false;
}
function LOG(s) {
if (!_debug) {
return;
}
dump("-*- PaymentContentHelper: " + s + "\n");
}
function PaymentContentHelper(aWindow) {
this.initDOMRequestHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
};
PaymentContentHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
receiveMessage: function receiveMessage(aMessage) {
let name = aMessage.name;
let msg = aMessage.json;
if (_debug) {
LOG("Received message '" + name + "': " + JSON.stringify(msg));
}
let requestId = msg.requestId;
let request = this.takeRequest(requestId);
if (!request) {
return;
}
switch (name) {
case "Payment:Success":
Services.DOMRequest.fireSuccess(request, msg.result);
break;
case "Payment:Failed":
Services.DOMRequest.fireError(request, msg.errorMsg);
break;
}
},
};
function PaymentContentHelperService() {
};
PaymentContentHelperService.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentContentHelperService]),
classID: Components.ID("{80035846-6732-4fcc-961b-f336b65218f4}"),
contractID: "@mozilla.org/payment/content-helper-service;1",
_xpcom_factory: XPCOMUtils.generateSingletonFactory(PaymentContentHelperService),
// keys are windows and values are PaymentContentHelpers
helpers: new WeakMap(),
// nsINavigatorPayment
pay: function pay(aWindow, aJwts) {
let requestHelper = this.helpers.get(aWindow);
if (!requestHelper) {
requestHelper = new PaymentContentHelper(aWindow);
this.helpers.set(aWindow, requestHelper);
}
let request = requestHelper.createRequest();
let requestId = requestHelper.getRequestId(request);
let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isActive) {
if (_debug) {
LOG("The caller application is a background app. No request will be " +
"sent");
}
let runnable = {
run: function run() {
Services.DOMRequest.fireError(request, "BACKGROUND_APP");
}
}
Services.tm.currentThread.dispatch(runnable,
Ci.nsIThread.DISPATCH_NORMAL);
return request;
}
if (!Array.isArray(aJwts)) {
aJwts = [aJwts];
}
cpmm.sendAsyncMessage("Payment:Pay", {
jwts: aJwts,
requestId: requestId
});
return request;
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentContentHelperService]);

View File

@ -1,422 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = [];
const PAYMENT_IPC_MSG_NAMES = ["Payment:Pay",
"Payment:Success",
"Payment:Failed"];
const PREF_PAYMENTPROVIDERS_BRANCH = "dom.payment.provider.";
const PREF_PAYMENT_BRANCH = "dom.payment.";
const PREF_DEBUG = "dom.payment.debug";
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageListenerManager");
XPCOMUtils.defineLazyServiceGetter(this, "prefService",
"@mozilla.org/preferences-service;1",
"nsIPrefService");
var PaymentManager = {
init: function init() {
// Payment providers data are stored as a preference.
this.registeredProviders = null;
this.messageManagers = {};
// The dom.payment.skipHTTPSCheck pref is supposed to be used only during
// development process. This preference should not be active for a
// production build.
let paymentPrefs = prefService.getBranch(PREF_PAYMENT_BRANCH);
this.checkHttps = true;
try {
if (paymentPrefs.getPrefType("skipHTTPSCheck")) {
this.checkHttps = !paymentPrefs.getBoolPref("skipHTTPSCheck");
}
} catch(e) {}
for (let msgname of PAYMENT_IPC_MSG_NAMES) {
ppmm.addMessageListener(msgname, this);
}
Services.obs.addObserver(this, "xpcom-shutdown", false);
try {
this._debug =
Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
this._debug = false;
}
},
/**
* Process a message from the content process.
*/
receiveMessage: function receiveMessage(aMessage) {
let name = aMessage.name;
let msg = aMessage.json;
if (this._debug) {
this.LOG("Received '" + name + "' message from content process");
}
switch (name) {
case "Payment:Pay": {
// First of all, we register the payment providers.
if (!this.registeredProviders) {
this.registeredProviders = {};
this.registerPaymentProviders();
}
// We save the message target message manager so we can later dispatch
// back messages without broadcasting to all child processes.
let requestId = msg.requestId;
this.messageManagers[requestId] = aMessage.target;
// We check the jwt type and look for a match within the
// registered payment providers to get the correct payment request
// information.
let paymentRequests = [];
let jwtTypes = [];
for (let i in msg.jwts) {
let pr = this.getPaymentRequestInfo(requestId, msg.jwts[i]);
if (!pr) {
continue;
}
// We consider jwt type repetition an error.
if (jwtTypes[pr.type]) {
this.paymentFailed(requestId,
"PAY_REQUEST_ERROR_DUPLICATED_JWT_TYPE");
return;
}
jwtTypes[pr.type] = true;
paymentRequests.push(pr);
}
if (!paymentRequests.length) {
this.paymentFailed(requestId,
"PAY_REQUEST_ERROR_NO_VALID_REQUEST_FOUND");
return;
}
// After getting the list of valid payment requests, we ask the user
// for confirmation before sending any request to any payment provider.
// If there is more than one choice, we also let the user select the one
// that he prefers.
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
if (!glue) {
if (this._debug) {
this.LOG("Could not create nsIPaymentUIGlue instance");
}
this.paymentFailed(requestId,
"INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED");
return;
}
let confirmPaymentSuccessCb = function successCb(aRequestId,
aResult) {
// Get the appropriate payment provider data based on user's choice.
let selectedProvider = this.registeredProviders[aResult];
if (!selectedProvider || !selectedProvider.uri) {
if (this._debug) {
this.LOG("Could not retrieve a valid provider based on user's " +
"selection");
}
this.paymentFailed(aRequestId,
"INTERNAL_ERROR_NO_VALID_SELECTED_PROVIDER");
return;
}
let jwt;
for (let i in paymentRequests) {
if (paymentRequests[i].type == aResult) {
jwt = paymentRequests[i].jwt;
break;
}
}
if (!jwt) {
if (this._debug) {
this.LOG("The selected request has no JWT information " +
"associated");
}
this.paymentFailed(aRequestId,
"INTERNAL_ERROR_NO_JWT_ASSOCIATED_TO_REQUEST");
return;
}
this.showPaymentFlow(aRequestId, selectedProvider, jwt);
};
let confirmPaymentErrorCb = this.paymentFailed;
glue.confirmPaymentRequest(requestId,
paymentRequests,
confirmPaymentSuccessCb.bind(this),
confirmPaymentErrorCb.bind(this));
break;
}
case "Payment:Success":
case "Payment:Failed": {
let mm = this.messageManagers[msg.requestId];
mm.sendAsyncMessage(name, {
requestId: msg.requestId,
result: msg.result,
errorMsg: msg.errorMsg
});
break;
}
}
},
/**
* Helper function to register payment providers stored as preferences.
*/
registerPaymentProviders: function registerPaymentProviders() {
let paymentProviders = prefService
.getBranch(PREF_PAYMENTPROVIDERS_BRANCH)
.getChildList("");
// First get the numbers of the providers by getting all ###.uri prefs.
let nums = [];
for (let i in paymentProviders) {
let match = /^(\d+)\.uri$/.exec(paymentProviders[i]);
if (!match) {
continue;
} else {
nums.push(match[1]);
}
}
#ifdef MOZ_B2G
let appsService = Cc["@mozilla.org/AppsService;1"]
.getService(Ci.nsIAppsService);
let systemAppId = Ci.nsIScriptSecurityManager.NO_APP_ID;
try {
let manifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
systemAppId = appsService.getAppLocalIdByManifestURL(manifestURL);
this.LOG("System app id=" + systemAppId);
} catch(e) {}
#endif
// Now register the payment providers.
for (let i in nums) {
let branch = prefService
.getBranch(PREF_PAYMENTPROVIDERS_BRANCH + nums[i] + ".");
let vals = branch.getChildList("");
if (vals.length == 0) {
return;
}
try {
let type = branch.getCharPref("type");
if (type in this.registeredProviders) {
continue;
}
let provider = this.registeredProviders[type] = {
name: branch.getCharPref("name"),
uri: branch.getCharPref("uri"),
description: branch.getCharPref("description"),
requestMethod: branch.getCharPref("requestMethod")
};
#ifdef MOZ_B2G
// Let this payment provider access the firefox-accounts API when
// it's loaded in the trusted UI.
if (systemAppId != Ci.nsIScriptSecurityManager.NO_APP_ID) {
this.LOG("Granting firefox-accounts permission to " + provider.uri);
let uri = Services.io.newURI(provider.uri, null, null);
let attrs = {appId: systemAppId, inIsolatedMozBrowser: true};
let principal =
Services.scriptSecurityManager.createCodebasePrincipal(uri, attrs);
Services.perms.addFromPrincipal(principal, "firefox-accounts",
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION);
}
#endif
if (this._debug) {
this.LOG("Registered Payment Providers: " +
JSON.stringify(this.registeredProviders[type]));
}
} catch (ex) {
if (this._debug) {
this.LOG("An error ocurred registering a payment provider. " + ex);
}
}
}
},
/**
* Helper for sending a Payment:Failed message to the parent process.
*/
paymentFailed: function paymentFailed(aRequestId, aErrorMsg) {
let mm = this.messageManagers[aRequestId];
mm.sendAsyncMessage("Payment:Failed", {
requestId: aRequestId,
errorMsg: aErrorMsg
});
},
/**
* Helper function to get the payment request info according to the jwt
* type. Payment provider's data is stored as a preference.
*/
getPaymentRequestInfo: function getPaymentRequestInfo(aRequestId, aJwt) {
if (!aJwt) {
this.paymentFailed(aRequestId, "INTERNAL_ERROR_CALL_WITH_MISSING_JWT");
return true;
}
// First thing, we check that the jwt type is an allowed type and has a
// payment provider flow information associated.
// A jwt string consists in three parts separated by period ('.'): header,
// payload and signature.
let segments = aJwt.split('.');
if (segments.length !== 3) {
if (this._debug) {
this.LOG("Error getting payment provider's uri. " +
"Not enough or too many segments");
}
this.paymentFailed(aRequestId,
"PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT");
return true;
}
let payloadObject;
try {
// We only care about the payload segment, which contains the jwt type
// that should match with any of the stored payment provider's data and
// the payment request information to be shown to the user.
// Before decoding the JWT string we need to normalize it to be compliant
// with RFC 4648.
segments[1] = segments[1].replace(/-/g, "+").replace(/_/g, "/");
let payload = atob(segments[1]);
if (this._debug) {
this.LOG("Payload " + payload);
}
if (!payload.length) {
this.paymentFailed(aRequestId, "PAY_REQUEST_ERROR_EMPTY_PAYLOAD");
return true;
}
payloadObject = JSON.parse(payload);
if (!payloadObject) {
this.paymentFailed(aRequestId,
"PAY_REQUEST_ERROR_ERROR_PARSING_JWT_PAYLOAD");
return true;
}
} catch (e) {
this.paymentFailed(aRequestId,
"PAY_REQUEST_ERROR_ERROR_DECODING_JWT");
return true;
}
if (!payloadObject.typ) {
this.paymentFailed(aRequestId,
"PAY_REQUEST_ERROR_NO_TYP_PARAMETER");
return true;
}
if (!payloadObject.request) {
this.paymentFailed(aRequestId,
"PAY_REQUEST_ERROR_NO_REQUEST_PARAMETER");
return true;
}
// Once we got the jwt 'typ' value we look for a match within the payment
// providers stored preferences. If the jwt 'typ' is not recognized as one
// of the allowed values for registered payment providers, we skip the jwt
// validation but we don't fire any error. This way developers might have
// a default set of well formed JWTs that might be used in different B2G
// devices with a different set of allowed payment providers.
let provider = this.registeredProviders[payloadObject.typ];
if (!provider) {
if (this._debug) {
this.LOG("Not registered payment provider for jwt type: " +
payloadObject.typ);
}
return false;
}
if (!provider.uri || !provider.name) {
this.paymentFailed(aRequestId,
"INTERNAL_ERROR_WRONG_REGISTERED_PAY_PROVIDER");
return true;
}
// We only allow https for payment providers uris.
if (this.checkHttps && !/^https/.exec(provider.uri.toLowerCase())) {
// We should never get this far.
if (this._debug) {
this.LOG("Payment provider uris must be https: " + provider.uri);
}
this.paymentFailed(aRequestId,
"INTERNAL_ERROR_NON_HTTPS_PROVIDER_URI");
return true;
}
let pldRequest = payloadObject.request;
return { jwt: aJwt, type: payloadObject.typ, providerName: provider.name };
},
showPaymentFlow: function showPaymentFlow(aRequestId,
aPaymentProvider,
aJwt) {
let paymentFlowInfo = Cc["@mozilla.org/payment/flow-info;1"]
.createInstance(Ci.nsIPaymentFlowInfo);
paymentFlowInfo.uri = aPaymentProvider.uri;
paymentFlowInfo.requestMethod = aPaymentProvider.requestMethod;
paymentFlowInfo.jwt = aJwt;
paymentFlowInfo.name = aPaymentProvider.name;
paymentFlowInfo.description = aPaymentProvider.description;
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
if (!glue) {
if (this._debug) {
this.LOG("Could not create nsIPaymentUIGlue instance");
}
this.paymentFailed(aRequestId,
"INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED");
return false;
}
glue.showPaymentFlow(aRequestId,
paymentFlowInfo,
this.paymentFailed.bind(this));
},
// nsIObserver
observe: function observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
for (let msgname of PAYMENT_IPC_MSG_NAMES) {
ppmm.removeMessageListener(msgname, this);
}
this.registeredProviders = null;
this.messageManagers = null;
Services.obs.removeObserver(this, "xpcom-shutdown");
}
},
LOG: function LOG(s) {
if (!this._debug) {
return;
}
dump("-*- PaymentManager: " + s + "\n");
}
};
PaymentManager.init();

View File

@ -1,8 +0,0 @@
component {80035846-6732-4fcc-961b-f336b65218f4} Payment.js
contract @mozilla.org/payment/content-helper-service;1 {80035846-6732-4fcc-961b-f336b65218f4}
component {b8bce4e7-fbf0-4719-a634-b1bf9018657c} PaymentFlowInfo.js
contract @mozilla.org/payment/flow-info;1 {b8bce4e7-fbf0-4719-a634-b1bf9018657c}
component {82144756-72ab-45b7-8621-f3dad431dd2f} PaymentProvider.js
contract @mozilla.org/payment/provider;1 {82144756-72ab-45b7-8621-f3dad431dd2f}

View File

@ -1,24 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function PaymentFlowInfo() {
};
PaymentFlowInfo.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentFlowInfo]),
classID: Components.ID("{b8bce4e7-fbf0-4719-a634-b1bf9018657c}"),
uri: null,
jwt: null,
requestMethod: null,
name: null,
description: null
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentFlowInfo]);

View File

@ -1,306 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
const PREF_DEBUG = "dom.payment.debug";
var _debug;
try {
_debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
_debug = false;
}
function DEBUG(s) {
if (!_debug) {
return;
}
dump("== Payment Provider == " + s + "\n");
}
function DEBUG_E(s) {
dump("== Payment Provider ERROR == " + s + "\n");
}
const kPaymentFlowCancelled = "payment-flow-cancelled";
function PaymentProvider() {
}
PaymentProvider.prototype = {
init: function(aWindow) {
let docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
this._requestId = docshell.paymentRequestId;
this._oncancelObserver = this.oncancel.bind(this);
Services.obs.addObserver(this._oncancelObserver,
kPaymentFlowCancelled,
false);
this._strategy = Cc["@mozilla.org/payment/provider-strategy;1"]
.createInstance(Ci.nsIPaymentProviderStrategy);
this._window = aWindow;
},
paymentSuccess: function(aResult) {
_debug && DEBUG("paymentSuccess " + aResult);
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
glue.closePaymentFlow(this._requestId).then(() => {
if (!this._requestId) {
return;
}
cpmm.sendAsyncMessage("Payment:Success", { result: aResult,
requestId: this._requestId });
});
},
paymentFailed: function(aError) {
_debug && DEBUG("paymentFailed " + aError);
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
.createInstance(Ci.nsIPaymentUIGlue);
glue.closePaymentFlow(this._requestId).then(() => {
if (!this._requestId) {
return;
}
cpmm.sendAsyncMessage("Payment:Failed", { errorMsg: aError,
requestId: this._requestId });
});
},
get paymentServiceId() {
return this._strategy.paymentServiceId;
},
set paymentServiceId(aServiceId) {
this._strategy.paymentServiceId = aServiceId;
},
/**
* We expose to the payment provider the information of all the SIMs
* available in the device. iccInfo is an object of this form:
* {
* "serviceId1": {
* mcc: <string>,
* mnc: <string>,
* iccId: <string>,
* dataPrimary: <boolean>
* },
* "serviceIdN": {...}
* }
*/
get iccInfo() {
return this._strategy.iccInfo;
},
oncancel: function() {
_debug && DEBUG("Cleaning up!");
this._strategy.cleanup();
Services.obs.removeObserver(this._oncancelObserver, kPaymentFlowCancelled);
if (this._cleanup) {
this._cleanup();
}
},
classID: Components.ID("{82144756-72ab-45b7-8621-f3dad431dd2f}"),
contractID: "@mozilla.org/payment/provider;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIObserver,
Ci.nsIDOMGlobalPropertyInitializer])
};
#if defined(MOZ_B2G_RIL) || defined(MOZ_WIDGET_ANDROID)
XPCOMUtils.defineLazyServiceGetter(this, "smsService",
"@mozilla.org/sms/smsservice;1",
"nsISmsService");
const kSilentSmsReceivedTopic = "silent-sms-received";
// In order to send messages through nsISmsService, we need to implement
// nsIMobileMessageCallback, as the WebSMS API implementation is not usable
// from JS.
function SilentSmsRequest(aDOMRequest) {
this.request = aDOMRequest;
}
SilentSmsRequest.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
classID: Components.ID("{1d58889c-5660-4cca-a8fd-97ef63e5d3b2}"),
notifyMessageSent: function notifyMessageSent(aMessage) {
_debug && DEBUG("Silent message successfully sent");
Services.DOMRequest.fireSuccessAsync(this.request, aMessage);
},
notifySendMessageFailed: function notifySendMessageFailed(aError) {
DEBUG_E("Error sending silent message " + aError);
Services.DOMRequest.fireErrorAsync(this.request, aError);
}
};
PaymentProvider.prototype._silentNumbers = null;
PaymentProvider.prototype._silentSmsObservers = null;
PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
_debug && DEBUG("Sending silent message " + aNumber + " - " + aMessage);
let request = Services.DOMRequest.createRequest(this._window);
if (this._strategy.paymentServiceId === null) {
DEBUG_E("No payment service ID set. Cannot send silent SMS");
Services.DOMRequest.fireErrorAsync(request,
"NO_PAYMENT_SERVICE_ID");
return request;
}
let smsRequest = new SilentSmsRequest(request);
smsService.send(this._strategy.paymentServiceId, aNumber, aMessage, true,
smsRequest);
return request;
};
PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
_debug && DEBUG("observeSilentSms " + aNumber);
if (!this._silentSmsObservers) {
this._silentSmsObservers = {};
this._silentNumbers = [];
this._onSilentSmsObserver = this._onSilentSms.bind(this);
Services.obs.addObserver(this._onSilentSmsObserver,
kSilentSmsReceivedTopic,
false);
}
if (!this._silentSmsObservers[aNumber]) {
this._silentSmsObservers[aNumber] = [];
this._silentNumbers.push(aNumber);
smsService.addSilentNumber(aNumber);
}
if (this._silentSmsObservers[aNumber].indexOf(aCallback) == -1) {
this._silentSmsObservers[aNumber].push(aCallback);
}
return;
};
PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
_debug && DEBUG("removeSilentSmsObserver " + aNumber);
if (!this._silentSmsObservers || !this._silentSmsObservers[aNumber]) {
_debug && DEBUG("No observers for " + aNumber);
return;
}
let index = this._silentSmsObservers[aNumber].indexOf(aCallback);
if (index != -1) {
this._silentSmsObservers[aNumber].splice(index, 1);
if (this._silentSmsObservers[aNumber].length == 0) {
this._silentSmsObservers[aNumber] = null;
this._silentNumbers.splice(this._silentNumbers.indexOf(aNumber), 1);
smsService.removeSilentNumber(aNumber);
}
} else if (_debug) {
DEBUG("No callback found for " + aNumber);
}
return;
};
PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
if (!aSubject || !(aSubject instanceof Ci.nsISmsMessage)) {
_debug && DEBUG("Invalid subject when receiving silent message!");
return;
}
let message = aSubject.QueryInterface(Ci.nsISmsMessage);
_debug && DEBUG("Got silent message! " + message.sender + " - " + message.body);
let number = message.sender;
if (!number || this._silentNumbers.indexOf(number) == -1) {
_debug && DEBUG("No observers for " + number);
return;
}
// If the service ID is null it means that the payment provider asked the
// user for her MSISDN, so we are in a MT only SMS auth flow. In this case
// we manually set the service ID to the one corresponding with the SIM
// that received the SMS.
if (this._strategy.paymentServiceId === null) {
let i = 0;
while(i < gRil.numRadioInterfaces) {
if (this.iccInfo[i].iccId === message.iccId) {
this._strategy.paymentServiceId = i;
break;
}
i++;
}
}
this._silentSmsObservers[number].forEach(function(callback) {
callback({
iccId: message.iccId,
sender: message.sender,
body: message.body,
timestamp: message.timestamp,
sentTimestamp: message.sentTimestamp
});
});
};
PaymentProvider.prototype._cleanup = function() {
if (!this._silentNumbers) {
return;
}
while (this._silentNumbers.length) {
let number = this._silentNumbers.pop();
smsService.removeSilentNumber(number);
}
this._silentNumbers = null;
this._silentSmsObservers = null;
Services.obs.removeObserver(this._onSilentSmsObserver,
kSilentSmsReceivedTopic);
};
#else
PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
};
#endif
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentProvider]);

View File

@ -1,30 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/NavigatorBinding.h"
#include "PaymentProviderUtils.h"
#include "nsGlobalWindow.h"
#include "nsJSUtils.h"
#include "nsIDocShell.h"
using namespace mozilla::dom;
/* static */ bool
PaymentProviderUtils::EnabledForScope(JSContext* aCx,
JSObject* aGlobal)
{
nsCOMPtr<nsPIDOMWindowInner> win =
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
NS_ENSURE_TRUE(win, false);
nsIDocShell *docShell = win->GetDocShell();
NS_ENSURE_TRUE(docShell, false);
nsString paymentRequestId;
docShell->GetPaymentRequestId(paymentRequestId);
return !paymentRequestId.IsEmpty();
}

View File

@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_payment_PaymentProviderEnabler_h
#define mozilla_dom_payment_PaymentProviderEnabler_h
#include "jsapi.h"
struct JSContext;
class JSObject;
namespace mozilla {
namespace dom {
class PaymentProviderUtils
{
public:
static bool EnabledForScope(JSContext*, JSObject*);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_payment_PaymentProviderEnabler_h

View File

@ -1,15 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIPaymentContentHelperService.idl',
'nsIPaymentFlowInfo.idl',
'nsIPaymentProviderStrategy.idl',
'nsIPaymentUIGlue.idl',
]
XPIDL_MODULE = 'dom_payment'

View File

@ -1,18 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "domstubs.idl"
interface nsIDOMDOMRequest;
interface mozIDOMWindow;
[scriptable, uuid(80035846-6732-4fcc-961b-f336b65218f4)]
interface nsIPaymentContentHelperService : nsISupports
{
// The 'jwts' parameter can be either a single DOMString or an array of
// DOMStrings. In both cases, it represents the base64url encoded and
// digitally signed payment information. Each payment provider should
// define its supported JWT format.
nsIDOMDOMRequest pay(in mozIDOMWindow window, in jsval jwts);
};

View File

@ -1,25 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(f3fe3b48-fe81-4ec9-90ab-648ac9403466)]
interface nsIPaymentFlowInfo : nsISupports
{
// Payment provider uri.
attribute DOMString uri;
// Base64 encoded and digitally signed payment request information.
attribute DOMString jwt;
// Payment providers expect the payment information as GET or POST
// parameters.
attribute DOMString requestMethod;
// Payment provider name.
attribute DOMString name;
// Payment provider description.
attribute DOMString description;
};

View File

@ -1,14 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(c3971bd9-0fbf-48d3-9498-0ac340d0d216)]
interface nsIPaymentProviderStrategy : nsISupports
{
attribute DOMString paymentServiceId;
readonly attribute jsval iccInfo;
void cleanup();
};

View File

@ -1,32 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIPaymentFlowInfo;
[scriptable, function, uuid(b9afa678-71a5-4975-bcdb-0c4098730eff)]
interface nsIPaymentUIGlueCallback : nsISupports
{
void onresult(in DOMString requestId, in DOMString result);
};
[scriptable, uuid(4dc09e33-d395-4e1d-acb4-e85415181270)]
interface nsIPaymentUIGlue : nsISupports
{
// The 'paymentRequestsInfo' contains the payment request information
// for each JWT provided via navigator.mozPay call.
void confirmPaymentRequest(in DOMString requestId,
in jsval paymentRequestsInfo,
in nsIPaymentUIGlueCallback successCb,
in nsIPaymentUIGlueCallback errorCb);
void showPaymentFlow(in DOMString requestId,
in nsIPaymentFlowInfo paymentFlowInfo,
in nsIPaymentUIGlueCallback errorCb);
// The promise resolves with no value as soon as the payment window is
// closed.
jsval /*Promise*/ closePaymentFlow(in DOMString requestId);
};

View File

@ -1,39 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += ['interfaces']
EXPORTS.mozilla.dom += [
'PaymentProviderUtils.h',
]
SOURCES += [
'PaymentProviderUtils.cpp',
]
EXTRA_PP_JS_MODULES += [
'Payment.jsm',
]
EXTRA_COMPONENTS += [
'Payment.js',
'Payment.manifest',
'PaymentFlowInfo.js'
]
EXTRA_PP_COMPONENTS += [
'PaymentProvider.js'
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base'
]
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']

View File

@ -1,91 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cm = Components.manager;
const Cu = Components.utils;
const CONTRACT_ID = "@mozilla.org/payment/ui-glue;1";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
var oldClassID, oldFactory;
var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
var newFactory = {
createInstance: function(aOuter, aIID) {
if (aOuter) {
throw Components.results.NS_ERROR_NO_AGGREGATION;
}
return new MockPaymentsUIGlueInstance().QueryInterface(aIID);
},
lockFactory: function(aLock) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
};
addMessageListener("MockPaymentsUIGlue.init", function (message) {
try {
oldClassID = registrar.contractIDToCID(CONTRACT_ID);
oldFactory = Cm.getClassObject(oldClassID, Ci.nsIFactory);
} catch (ex) {
oldClassID = "";
oldFactory = null;
dump("TEST-INFO | can't get payments ui glue registered component, " +
"assuming there is none\n");
}
if (oldFactory) {
registrar.unregisterFactory(oldClassID, oldFactory);
}
registrar.registerFactory(newClassID, "", CONTRACT_ID, newFactory);});
addMessageListener("MockPaymentsUIGlue.cleanup", function (message) {
if (oldClassID) {
registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
}
});
var payments = new Map();
function MockPaymentsUIGlueInstance() {
};
MockPaymentsUIGlueInstance.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue]),
confirmPaymentRequest: function(aRequestId,
aRequests,
aSuccessCb,
aErrorCb) {
aSuccessCb.onresult(aRequestId, aRequests[0].type);
},
showPaymentFlow: function(aRequestId,
aPaymentFlowInfo,
aErrorCb) {
let win = Services.ww.openWindow(null,
null,
"_blank",
"chrome,dialog=no,resizable,scrollbars,centerscreen",
null);
payments.set(aRequestId, win);
let docshell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
docshell.paymentRequestId = aRequestId;
win.document.location = aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt;
},
closePaymentFlow: function(aRequestId) {
payments.get(aRequestId).close();
payments.delete(aRequestId);
return Promise.resolve();
},
};

View File

@ -1,28 +0,0 @@
<!--
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test app for bug 1097928 - Check if MozPaymentProvider API is exposed</title>
</head>
<body>
<div id='test'>
<script type="application/javascript;version=1.8">
function receiveMessage(event) {
let message = JSON.parse(event.data);
let exposed = (navigator.mozPaymentProvider != undefined);
window.parent.postMessage(JSON.stringify({
iframeType: message.iframeType,
exposed: exposed
}), "*");
}
window.addEventListener("message", receiveMessage, false, true);
</script>
</div>
</body>
</html>

View File

@ -1,12 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
navigator.mozPaymentProvider.paymentFailed();
</script>
</body>
</html>

View File

@ -1,12 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
navigator.mozPaymentProvider.paymentSuccess("aResult");
</script>
</body>
</html>

View File

@ -1,11 +0,0 @@
[DEFAULT]
skip-if=buildapp != 'b2g'
support-files=
file_mozpayproviderchecker.html
file_payprovidersuccess.html
file_payproviderfailure.html
MockPaymentsUIChromeScript.js
[test_mozpaymentprovider.html]
[test_mozpay_callbacks.html]

View File

@ -1,112 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1097928
-->
<html>
<head>
<title>Test for navigator.mozPay. Bug 1097928</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();
let tests = [() => {
/*
{
"iss": "323d34dc-b5cf-4822-8e47-6a4515dc74db",
"typ": "mozilla/payments/test/success",
"request": {
"name": "Virtual Kiwi",
"id": "af1f960a-3f90-4e2d-a20f-d5170aee49f2",
"postbackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
"productData": "localTransID=14546cd1-db9b-4759-986f-2a6a295fdcc1",
"chargebackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
"description": "The forbidden fruit"
}
}
*/
let jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzMjNkMzRkYy1iNWNmLTQ4MjItOGU0Ny02YTQ1MTVkYzc0ZGIiLCJyZXF1ZXN0Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGZvcmJpZGRlbiBmcnVpdCIsImlkIjoiYWYxZjk2MGEtM2Y5MC00ZTJkLWEyMGYtZDUxNzBhZWU0OWYyIiwicG9zdGJhY2tVUkwiOiJodHRwczovL2luYXBwLXBheS10ZXN0LnBhYXMuYWxsaXpvbS5vcmcvbW96cGF5L3Bvc3RiYWNrIiwicHJvZHVjdERhdGEiOiJsb2NhbFRyYW5zSUQ9MTQ1NDZjZDEtZGI5Yi00NzU5LTk4NmYtMmE2YTI5NWZkY2MxIiwiY2hhcmdlYmFja1VSTCI6Imh0dHBzOi8vaW5hcHAtcGF5LXRlc3QucGFhcy5hbGxpem9tLm9yZy9tb3pwYXkvY2hhcmdlYmFjayIsIm5hbWUiOiJWaXJ0dWFsIEtpd2kifSwidHlwIjoibW96aWxsYS9wYXltZW50cy90ZXN0L3N1Y2Nlc3MifQ.8zaeYFUCwKkZWk2TFf2wEJWrmiSYQGNbpKc2ADkvL9s";
let req = window.navigator.mozPay(jwt);
req.onsuccess = (result) => {
ok(true, "Expected mozPay success");
runTest();
};
req.onerror = (error) => {
ok(false, "Unexpected mozPay error " + error);
SimpleTest.finish();
};
}, () => {
/*
{
"iss": "323d34dc-b5cf-4822-8e47-6a4515dc74db",
"typ": "mozilla/payments/test/failure",
"request": {
"name": "Virtual Kiwi",
"id": "af1f960a-3f90-4e2d-a20f-d5170aee49f2",
"postbackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
"productData": "localTransID=cc3c0994-33e8-4a21-aa2c-75ee44f5fe75",
"chargebackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
"description": "The forbidden fruit"
}
}
*/
let jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzMjNkMzRkYy1iNWNmLTQ4MjItOGU0Ny02YTQ1MTVkYzc0ZGIiLCJyZXF1ZXN0Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGZvcmJpZGRlbiBmcnVpdCIsImlkIjoiYWYxZjk2MGEtM2Y5MC00ZTJkLWEyMGYtZDUxNzBhZWU0OWYyIiwicG9zdGJhY2tVUkwiOiJodHRwczovL2luYXBwLXBheS10ZXN0LnBhYXMuYWxsaXpvbS5vcmcvbW96cGF5L3Bvc3RiYWNrIiwicHJvZHVjdERhdGEiOiJsb2NhbFRyYW5zSUQ9Y2MzYzA5OTQtMzNlOC00YTIxLWFhMmMtNzVlZTQ0ZjVmZTc1IiwiY2hhcmdlYmFja1VSTCI6Imh0dHBzOi8vaW5hcHAtcGF5LXRlc3QucGFhcy5hbGxpem9tLm9yZy9tb3pwYXkvY2hhcmdlYmFjayIsIm5hbWUiOiJWaXJ0dWFsIEtpd2kifSwidHlwIjoibW96aWxsYS9wYXltZW50cy90ZXN0L2ZhaWx1cmUifQ.1uV4-HkmwO0oDv50wi1Ma4tNpnxoFGaw5zaPj8xkcAc";
let req = window.navigator.mozPay(jwt);
req.onsuccess = (result) => {
ok(false, "Unexpected mozPay success " + result);
SimpleTest.finish();
};
req.onerror = (error) => {
ok(true, "Expected mozPay error");
runTest();
};
}];
function runTest() {
if (!tests.length) {
ok(true, "Done!");
SimpleTest.finish();
return;
}
tests.shift()();
}
const uiGlue = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('MockPaymentsUIChromeScript.js'));
SimpleTest.registerCleanupFunction(() => {
uiGlue.sendAsyncMessage("MockPaymentsUIGlue.cleanup", {});
});
uiGlue.sendAsyncMessage("MockPaymentsUIGlue.init", {});
SpecialPowers.pushPrefEnv({
"set": [
["dom.payment.skipHTTPSCheck", "true"],
["dom.payment.debug", "true"],
["dom.payment.provider.1.name", "SuccessProvider"],
["dom.payment.provider.1.description", ""],
["dom.payment.provider.1.uri",
"https://example.com:443/tests/dom/payment/tests/mochitest/file_payprovidersuccess.html?req="],
["dom.payment.provider.1.type", "mozilla/payments/test/success"],
["dom.payment.provider.1.requestMethod", "GET"],
["dom.payment.provider.2.name", "FailureProvider"],
["dom.payment.provider.2.description", ""],
["dom.payment.provider.2.uri",
"https://example.com:443/tests/dom/payment/tests/mochitest/file_payproviderfailure.html?req="],
["dom.payment.provider.2.type", "mozilla/payments/test/failure"],
["dom.payment.provider.2.requestMethod", "GET"],
]
}, () => {
runTest();
});
</script>
</pre>
</body>
</html>

View File

@ -1,93 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1097928
-->
<html>
<head>
<title>Test for navigator.mozPaymentProvider exposure. Bug 1097928</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();
// We create two iframes. The first one is a regular iframe with no payment
// information and so it should not have access to the MozPaymentProvider
// API. For the second iframe we set a dummy payment request ID which should
// expose the MozPaymentProvider API.
let tests = [function() {
// Iframe with no payment information.
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.src = "file_mozpayproviderchecker.html";
document.getElementById("content").appendChild(iframe);
iframe.addEventListener("load", function onLoad() {
iframe.removeEventListener("load", onLoad);
iframe.contentWindow.postMessage(JSON.stringify({
iframeType: "regular"
}), "*");
}, false);
}, function() {
// Payment iframe.
let paymentIframe = document.createElement("iframe");
paymentIframe.setAttribute("mozbrowser", "true");
paymentIframe.src = "file_mozpayproviderchecker.html";
document.getElementById("content").appendChild(paymentIframe);
let Ci = SpecialPowers.Ci;
let docshell = SpecialPowers.wrap(paymentIframe.contentWindow)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
docshell.paymentRequestId = "dummyid";
paymentIframe.addEventListener("load", function onLoad() {
paymentIframe.removeEventListener("load", onLoad);
paymentIframe.contentWindow.postMessage(JSON.stringify({
iframeType: "payment"
}), "*");
}, false);
}];
function receiveMessage(event) {
let message = JSON.parse(event.data);
switch (message.iframeType) {
case "regular":
ok(!message.exposed, "MozPaymentProvider is not exposed in regular iframe");
break;
case "payment":
ok(message.exposed, "MozPaymentProvider is exposed in payment iframe");
break;
default:
ok(false, "Unexpected iframe type");
SimpleTest.finish();
}
runTest();
}
function runTest() {
if (!tests.length) {
ok(true, "Done!");
SimpleTest.finish();
return;
}
tests.shift()();
}
window.addEventListener("message", receiveMessage, false, true);
runTest();
</script>
</pre>
</body>
</html>

View File

@ -1,38 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
/**
* Start a new payment module.
*
* @param custom_ns
* Namespace with symbols to be injected into the new payment module
* namespace.
*
* @return an object that represents the payment module's namespace.
*/
function newPaymentModule(custom_ns) {
let payment_ns = {
importScripts: function fakeImportScripts() {
Array.slice(arguments).forEach(function (script) {
subscriptLoader.loadSubScript("resource://gre/modules/" + script, this);
}, this);
},
};
// Copy the custom definitions over.
for (let key in custom_ns) {
payment_ns[key] = custom_ns[key];
}
// Load the payment module itself.
payment_ns.importScripts("Payment.jsm");
return payment_ns;
}

View File

@ -1,348 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function getPaymentHelper() {
let error;
let paym = newPaymentModule();
paym.PaymentManager.paymentFailed = function paymentFailed(aRequestId,
errorMsg) {
error = errorMsg;
};
return {
get paymentModule() {
return paym;
},
get error() {
return error;
}
};
}
function run_test() {
run_next_test();
}
function testGetPaymentRequest(paymentProviders, test) {
let helper = getPaymentHelper();
let paym = helper.paymentModule;
paym.PaymentManager.registeredProviders = paymentProviders;
let ret = paym.PaymentManager.getPaymentRequestInfo("", test.jwt);
if (!test.result) {
test.ret ? do_check_true(ret) : do_check_false(ret);
}
if (test.error !== null) {
do_check_eq(helper.error, test.error);
} else {
do_check_eq(typeof ret, "object");
do_check_eq(ret.jwt, test.jwt);
do_check_eq(ret.type, test.result.type);
do_check_eq(ret.providerName, test.result.providerName);
}
}
add_test(function test_successfull_request() {
let providers = {};
let type = "mock/payments/inapp/v1";
providers[type] = {
name: "mockprovider",
description: "Mock Payment Provider",
uri: "https://mockpayprovider.phpfogapp.com/?req=",
requestMethod: "GET"
};
// Payload
// {
// "aud": "mockpayprovider.phpfogapp.com",
// "iss": "Enter you app key here!",
// "request": {
// "name": "Piece of Cake",
// "price": "10.50",
// "priceTier": 1,
// "productdata": "transaction_id=86",
// "currencyCode": "USD",
// "description": "Virtual chocolate cake to fill your virtual tummy"
// },
// "exp": 1352232792,
// "iat": 1352229192,
// "typ": "mock/payments/inapp/v1"
// }
let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
"llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
"iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
"Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
"WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
"15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
"gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
"IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
testGetPaymentRequest(providers, {
jwt: jwt,
ret: true,
error: null,
result: {
type: type,
providerName: providers[type].name
}
});
run_next_test();
});
add_test(function test_successfull_request_html_description() {
let providers = {};
let type = "mozilla/payments/pay/v1";
providers[type] = {
name: "webpay",
description: "Mozilla Payment Provider",
uri: "https://marketplace.firefox.com/mozpay/?req=",
requestMethod: "GET"
};
// Payload
// {
// "aud": "marketplace.firefox.com",
// "iss": "marketplace-dev.allizom.org",
// "request": {
// "name": "Krupa's paid app 1",
// "chargebackURL": "http://localhost:8002/telefonica/services/webpay/"
// "chargeback",
// "postbackURL": "http://localhost:8002/telefonica/services/webpay/"
// "postback",
// "productData": "addon_id=85&seller_uuid=d4855df9-6ce0-45cd-81cb-"
// "cf8737e1e7aa&contrib_uuid=201868b7ac2cda410a99b3"
// "ed4c11a8ea",
// "pricePoint": 1,
// "id": "maude:85",
// "description": "This app has been automatically generated by <a href="
// "\"http://outgoing.mozilla.org/v1/ba7f373ae16789eff3ab"
// "fd95ca8d3c15d18dc9009afa204dc43f85a55b1f6ef1/http%3A/"
// "/testmanifest.com\" rel=\"nofollow\">testmanifest.com"
// "</a>"
// },
// "exp": 1358379147,
// "iat": 1358375547,
// "typ": "mozilla/payments/pay/v1"
// }
let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibWFya2V0cGx" +
"hY2UuZmlyZWZveC5jb20iLCAiaXNzIjogIm1hcmtldHBsYWNlLWRldi5hbGxpem9" +
"tLm9yZyIsICJyZXF1ZXN0IjogeyJuYW1lIjogIktydXBhJ3MgcGFpZCBhcHAgMSI" +
"sICJjaGFyZ2ViYWNrVVJMIjogImh0dHA6Ly9sb2NhbGhvc3Q6ODAwMi90ZWxlZm9" +
"uaWNhL3NlcnZpY2VzL3dlYnBheS9jaGFyZ2ViYWNrIiwgInBvc3RiYWNrVVJMIjo" +
"gImh0dHA6Ly9sb2NhbGhvc3Q6ODAwMi90ZWxlZm9uaWNhL3NlcnZpY2VzL3dlYnB" +
"heS9wb3N0YmFjayIsICJwcm9kdWN0RGF0YSI6ICJhZGRvbl9pZD04NSZzZWxsZXJ" +
"fdXVpZD1kNDg1NWRmOS02Y2UwLTQ1Y2QtODFjYi1jZjg3MzdlMWU3YWEmY29udHJ" +
"pYl91dWlkPTIwMTg2OGI3YWMyY2RhNDEwYTk5YjNlZDRjMTFhOGVhIiwgInByaWN" +
"lUG9pbnQiOiAxLCAiaWQiOiAibWF1ZGU6ODUiLCAiZGVzY3JpcHRpb24iOiAiVGh" +
"pcyBhcHAgaGFzIGJlZW4gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgPGEgaHJ" +
"lZj1cImh0dHA6Ly9vdXRnb2luZy5tb3ppbGxhLm9yZy92MS9iYTdmMzczYWUxNjc" +
"4OWVmZjNhYmZkOTVjYThkM2MxNWQxOGRjOTAwOWFmYTIwNGRjNDNmODVhNTViMWY" +
"2ZWYxL2h0dHAlM0EvL3Rlc3RtYW5pZmVzdC5jb21cIiByZWw9XCJub2ZvbGxvd1w" +
"iPnRlc3RtYW5pZmVzdC5jb208L2E-In0sICJleHAiOiAxMzU4Mzc5MTQ3LCAiaWF" +
"0IjogMTM1ODM3NTU0NywgInR5cCI6ICJtb3ppbGxhL3BheW1lbnRzL3BheS92MSJ" +
"9.kgSt636OSRBezMGtm9QLeDxlEOevL4xcOoDj8VRJyD8";
testGetPaymentRequest(providers, {
jwt: jwt,
ret: true,
error: null,
result: {
type: type,
providerName: providers[type].name
}
});
run_next_test();
});
add_test(function test_empty_jwt() {
testGetPaymentRequest(null, {
jwt: "",
ret: true,
error: "INTERNAL_ERROR_CALL_WITH_MISSING_JWT"
});
run_next_test();
});
add_test(function test_wrong_segments_count() {
// 1 segment JWT
let OneSegJwt = "eyJhbGciOiJIUzI1NiJ9";
testGetPaymentRequest(null, {
jwt: OneSegJwt,
ret: true,
error: "PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT"
});
// 2 segments JWT
let TwoSegJwt = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwNTg2NDkwMTM2NTY2N" +
"zU1ODY2MSIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZS9" +
"wYXltZW50cy9pbmFwcC9pdGVtL3YxIiwiaWF0IjoxMzUyMjIwM" +
"jEyLCJleHAiOjEzNTIzMDY2MTIsInJlcXVlc3QiOnsiY3VycmV" +
"uY3lDb2RlIjoiVVNEIiwicHJpY2UiOiIzLjAwIiwibmFtZSI6I" +
"kdvbGQgU3RhciIsInNlbGxlckRhdGEiOiJzb21lIG9wYXF1ZSB" +
"kYXRhIiwiZGVzY3JpcHRpb24iOiJBIHNoaW5pbmcgYmFkZ2Ugb" +
"2YgZGlzdGluY3Rpb24ifX0";
testGetPaymentRequest(null, {
jwt: TwoSegJwt,
ret: true,
error: "PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT"
});
run_next_test();
});
add_test(function test_empty_payload() {
let EmptyPayloadJwt = "eyJhbGciOiJIUzI1NiJ9..eyJpc3MiOiIwNTg2NDkwMTM2NTY2N";
testGetPaymentRequest(null, {
jwt: EmptyPayloadJwt,
ret: true,
error: "PAY_REQUEST_ERROR_EMPTY_PAYLOAD"
});
run_next_test();
});
add_test(function test_missing_typ_parameter() {
// Payload
// {
// "iss": "640ae477-df33-45cd-83b8-6f1f910a6494",
// "iat": 1361203745,
// "request": {
// "description": "detailed description",
// "id": "799db970-7afa-4028-bdb7-8b045eb8babc",
// "postbackURL": "http://inapp-pay-test.farmdev.com/postback",
// "productData": "transaction_id=58",
// "pricePoint": 1,
// "chargebackURL": "http://inapp-pay-test.farmdev.com/chargeback",
// "name": "The Product"
// },
// "aud": "marketplace-dev.allizom.org",
// "exp": 1361207345
// }
let missingTypJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9." +
"eyJpc3MiOiAiNjQwYWU0NzctZGYzMy00NWNkLTgzY" +
"jgtNmYxZjkxMGE2NDk0IiwgImlhdCI6IDEzNjEyMD" +
"M3NDUsICJyZXF1ZXN0IjogeyJkZXNjcmlwdGlvbiI" +
"6ICJkZXRhaWxlZCBkZXNjcmlwdGlvbiIsICJpZCI6" +
"ICI3OTlkYjk3MC03YWZhLTQwMjgtYmRiNy04YjA0N" +
"WViOGJhYmMiLCAicG9zdGJhY2tVUkwiOiAiaHR0cD" +
"ovL2luYXBwLXBheS10ZXN0LmZhcm1kZXYuY29tL3B" +
"vc3RiYWNrIiwgInByb2R1Y3REYXRhIjogInRyYW5z" +
"YWN0aW9uX2lkPTU4IiwgInByaWNlUG9pbnQiOiAxL" +
"CAiY2hhcmdlYmFja1VSTCI6ICJodHRwOi8vaW5hcH" +
"AtcGF5LXRlc3QuZmFybWRldi5jb20vY2hhcmdlYmF" +
"jayIsICJuYW1lIjogIlRoZSBQcm9kdWN0In0sICJh" +
"dWQiOiAibWFya2V0cGxhY2UtZGV2LmFsbGl6b20ub" +
"3JnIiwgImV4cCI6IDEzNjEyMDczNDV9.KAHsJX1Hy" +
"fmwNvAckdVUqlpPvdHggpx9yX276TWacRg";
testGetPaymentRequest(null, {
jwt: missingTypJwt,
ret: true,
error: "PAY_REQUEST_ERROR_NO_TYP_PARAMETER"
});
run_next_test();
});
add_test(function test_missing_request_parameter() {
// Payload
// {
// "iss": "Enter you app key here!",
// "iat": 1352225299,
// "typ": "mock/payments/inapp/v1",
// "aud": "mockpayprovider.phpfogapp.com",
// "exp": 1352228899
// }
let missingRequestJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9." +
"eyJpc3MiOiAiRW50ZXIgeW91IGFwcCBrZXkgaGVyZ" +
"SEiLCAiaWF0IjogMTM1MjIyNTI5OSwgInR5cCI6IC" +
"Jtb2NrL3BheW1lbnRzL2luYXBwL3YxIiwgImF1ZCI" +
"6ICJtb2NrcGF5cHJvdmlkZXIucGhwZm9nYXBwLmNv" +
"bSIsICJleHAiOiAxMzUyMjI4ODk5fQ.yXGinvZiUs" +
"v9JWvdfM6zPD0iOX9DgCPcIwIbCrL4tcs";
testGetPaymentRequest(null, {
jwt: missingRequestJwt,
ret: true,
error: "PAY_REQUEST_ERROR_NO_REQUEST_PARAMETER"
});
run_next_test();
});
add_test(function test_jwt_decoding_error() {
let wrongJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.^eyJhdWQiOiAibW9" +
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
"llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
"iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
"Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
"WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
"15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
"gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
"IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
testGetPaymentRequest(null, {
jwt: wrongJwt,
ret: true,
error: "PAY_REQUEST_ERROR_ERROR_DECODING_JWT"
});
run_next_test();
});
add_test(function test_non_https_provider() {
let providers = {};
let type = "mock/payments/inapp/v1";
providers[type] = {
name: "mockprovider",
description: "Mock Payment Provider",
uri: "http://mockpayprovider.phpfogapp.com/?req=",
requestMethod: "GET"
};
// Payload
// {
// "aud": "mockpayprovider.phpfogapp.com",
// "iss": "Enter you app key here!",
// "request": {
// "name": "Piece of Cake",
// "price": "10.50",
// "priceTier": 1,
// "productdata": "transaction_id=86",
// "currencyCode": "USD",
// "description": "Virtual chocolate cake to fill your virtual tummy"
// },
// "exp": 1352232792,
// "iat": 1352229192,
// "typ": "mock/payments/inapp/v1"
// }
let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
"llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
"iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
"Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
"WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
"15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
"gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
"IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
testGetPaymentRequest(providers, {
jwt: jwt,
ret: true,
error: "INTERNAL_ERROR_NON_HTTPS_PROVIDER_URI"
});
run_next_test();
});

View File

@ -1,6 +0,0 @@
[DEFAULT]
head = header_helper.js
tail =
skip-if = toolkit == 'gonk'
[test_paymanager_get_payment_request.js]

View File

@ -1,41 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
dictionary PaymentIccInfo {
DOMString mcc;
DOMString mnc;
DOMString iccId;
boolean dataPrimary;
};
dictionary PaymentSmsMessage {
DOMString iccId;
DOMString sender;
DOMString body;
DOMTimeStamp timestamp;
DOMTimeStamp sentTimestamp;
};
callback SilentSmsCallback = void (optional PaymentSmsMessage message);
[NavigatorProperty="mozPaymentProvider",
NoInterfaceObject,
HeaderFile="mozilla/dom/PaymentProviderUtils.h",
Func="mozilla::dom::PaymentProviderUtils::EnabledForScope",
JSImplementation="@mozilla.org/payment/provider;1"]
interface PaymentProvider {
readonly attribute DOMString? paymentServiceId;
// We expose to the payment provider the information of all the SIMs
// available in the device.
[Cached, Pure] readonly attribute sequence<PaymentIccInfo>? iccInfo;
void paymentSuccess(optional DOMString result);
void paymentFailed(optional DOMString error);
DOMRequest sendSilentSms(DOMString number, DOMString message);
void observeSilentSms(DOMString number, SilentSmsCallback callback);
void removeSilentSmsObserver(DOMString number, SilentSmsCallback callback);
};

View File

@ -439,17 +439,6 @@ partial interface Navigator {
};
#endif
#ifdef MOZ_PAY
partial interface Navigator {
[Throws, NewObject, Pref="dom.mozPay.enabled"]
// The 'jwts' parameter can be either a single DOMString or an array of
// DOMStrings. In both cases, it represents the base64url encoded and
// digitally signed payment information. Each payment provider should
// define its supported JWT format.
DOMRequest mozPay(any jwts);
};
#endif
[NoInterfaceObject, Exposed=(Window,Worker)]
interface NavigatorConcurrentHardware {
readonly attribute unsigned long long hardwareConcurrency;

View File

@ -918,11 +918,6 @@ if CONFIG['MOZ_EME']:
'WidevineCDMManifest.webidl',
]
if CONFIG['MOZ_PAY']:
WEBIDL_FILES += [
'MozPaymentProvider.webidl'
]
if CONFIG['MOZ_B2G']:
WEBIDL_FILES += [
'Apps.webidl',

View File

@ -76,7 +76,6 @@ skip-if = android_version == "18"
[src/org/mozilla/gecko/tests/testBrowserDiscovery.java]
[src/org/mozilla/gecko/tests/testFilePicker.java]
[src/org/mozilla/gecko/tests/testHistoryService.java]
# [src/org/mozilla/gecko/tests/testMozPay.java] # see bug 945675
[src/org/mozilla/gecko/tests/testOSLocale.java]
# disabled on 4.3: Bug 1124494
skip-if = android_version == "18"

View File

@ -1,25 +0,0 @@
<html>
<head>
<script type="text/javascript">
function start() {
if (!mozPaymentProvider)
window.close();
// We don't have a way to mock these values yet. This check just makes sure the world
// doesn't crash if we ask for them.
var mcc = mozPaymentProvider.mcc;
var mnc = mozPaymentProvider.mnc;
// We use the jwt passed in here to test calling paymentFailed/Success
if (window.location.hash == "#pass")
mozPaymentProvider.paymentSuccess("PAID CORRECTLY");
else if (window.location.hash == "#fail")
mozPaymentProvider.paymentFailed("FAILED CORRECTLY");
else
mozPaymentProvider.paymentFailed("invalid hash " + window.location.hash);
}
document.addEventListener("DOMContentLoaded", start);
</script>
</head>
</html>

View File

@ -1,13 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tests;
public class testMozPay extends JavascriptTest {
public testMozPay() {
super("testMozPay.js");
}
}

View File

@ -1,102 +0,0 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
Components.utils.import("resource://gre/modules/SharedPreferences.jsm");
Components.utils.import("resource://gre/modules/Promise.jsm");
var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
var deferred = 0;
var shouldPass = true;
var reqId = 0;
function getRequestId(increment) {
reqId += increment;
return "Request" + reqId;
}
var paymentSuccess = {
receiveMessage: function(aMsg) {
let msg = aMsg.json;
if (shouldPass) {
do_check_eq(msg.requestId, getRequestId(0));
} else {
do_throw("Test should not have passed");
}
deferred.resolve();
}
}
var paymentFailed = {
receiveMessage: function(aMsg) {
let msg = aMsg.json;
if (shouldPass) {
do_throw("Test should not have failed: " + msg.errorMsg);
} else {
do_check_eq(msg.requestId, getRequestId(0));
do_check_eq(msg.errorMsg, "FAILED CORRECTLY");
}
deferred.resolve();
}
}
add_task(function test_get_set() {
let ui = Cc["@mozilla.org/payment/ui-glue;1"].getService(Ci.nsIPaymentUIGlue);
deferred = Promise.defer();
let id = getRequestId(1);
ui.confirmPaymentRequest(id,
[{ wrappedJSObject: { type: "Fake Provider" } }],
function(aRequestId, type) {
do_check_eq(type, "Fake Provider");
deferred.resolve();
},
function(id, msg) {
do_throw("confirmPaymentRequest should not have failed");
deferred.resolve();
});
yield deferred.promise;
});
add_task(function test_default() {
ppmm.addMessageListener("Payment:Success", paymentSuccess);
ppmm.addMessageListener("Payment:Failed", paymentFailed);
let ui = Cc["@mozilla.org/payment/ui-glue;1"].getService(Ci.nsIPaymentUIGlue);
deferred = Promise.defer();
let id = getRequestId(1);
shouldPass = true;
ui.showPaymentFlow(id,
{
uri: "chrome://roboextender/content/paymentsUI.html",
jwt: "#pass"
},
function(id, msg) {
do_throw("confirmPaymentRequest should not have failed");
deferred.resolve();
});
yield deferred.promise;
deferred = Promise.defer();
id = getRequestId(1);
shouldPass = false;
ui.showPaymentFlow(id,
{
uri: "chrome://roboextender/content/paymentsUI.html",
jwt: "#fail"
},
function(id, msg) {
do_throw("confirmPaymentRequest should not have failed");
deferred.resolve();
});
yield deferred.promise;
ppmm.removeMessageListener("Payment:Success", paymentSuccess);
ppmm.removeMessageListener("Payment:Failed", paymentFailed);
});
run_next_test();

View File

@ -2374,7 +2374,6 @@ MOZ_INSTALL_TRACKING=
ACCESSIBILITY=1
MOZ_TIME_MANAGER=
MOZ_SIMPLEPUSH=
MOZ_PAY=
MOZ_AUDIO_CHANNEL_MANAGER=
MOZ_CONTENT_SANDBOX=
MOZ_GMP_SANDBOX=
@ -4937,14 +4936,6 @@ if test -n "$MOZ_SIMPLEPUSH"; then
fi
AC_SUBST(MOZ_SIMPLEPUSH)
dnl ========================================================
dnl = Enable Support for Payment API
dnl ========================================================
if test -n "$MOZ_PAY"; then
AC_DEFINE(MOZ_PAY)
fi
AC_SUBST(MOZ_PAY)
dnl ========================================================
dnl = Enable Support for AudioChannelManager API
dnl ========================================================