Stripe in wkwebview open a browser page loading script - ios

we're moving with our APP to new new wkweview due to the apple requirements.
One of APPs, is using StripeJS sdk in order to allow payment in app. Problem occurs when APP is bootstraping and the stripe sdk is include with the following code:
// Payment service is not initialized yet
$.ajax({
type: "GET",
cache: true,
url: "https://js.stripe.com/v3/",
dataType: "script",
error: function(XMLHttpRequest, textStatus, errorThrown) {
Logger.error("An error ocurred during SDK download");
def.reject();
},
success: function() {
Logger.debug("Stipe JDK downloaded correctly");
initialized = true;
def.resolve();
}
});
We already tried to use '' head tag in the index.html or creating dynamically one script TAG and appenging it to the body: but no one fix the problem.
Script Inclusion Tests
[Angular $http method]
$http({
method: "GET",
url: "https://js.stripe.com/v3/"
}).then(
function(res) {
angular.element("body").append("<script>" + res.data + "</script>");
}, function(err) {
def.reject();
});
[index.html]
<html>
<head>
<script type="text/javascript" src="https://js.stripe.com/v3/"></script>
...
Problem
A browser page is opened and APP is left in the background; being more specific, the "METRICS_CONTROLLER" case is catch in switch at row 767 ( see library at url < https://js.stripe.com/v3/ > ).
Have anyone an idea why including that script the browser page is opened ?

just to answer my question we found the problem.
The problem was about permission to navigate url not allowed by the cordova configuration ( file 'config.xml' ).
More specifically, we need to add the following row in our config. file
<allow-navigation href="http://*/*" />
<allow-navigation href="https://*/*" />
So finally, our CORS permission definition is:
<access origin="*" />
<allow-intent href="sms:*" />
<allow-intent href="tel:*" />
<allow-intent href="geo:*" />
<allow-intent href="mailto:*" />
<allow-intent href="file://*/*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-navigation href="http://*/*" />
<allow-navigation href="https://*/*" />
'*' is due to the fact that the APP can trigger outside resource, so we cannot known which url will be opened by user in APP.
Hope this help #saperlipopette
Simon

Related

How to get hosted nodejs website to run on cordova?

I have a website(HTML5 Game) that uses NodeJS to manage a database among other things, i am trying to port it too android and IOS using Cordova, but i do not know how to get Cordova to load the website using a URL, i need it to load into the URL because of all the server side stuff. Does anyone have any advise on how to do this?
I've looked at countless articles/posts but every time i test it out by clicking on index.HTML it doesn't redirect/show my website.
I have tried several plugins and even just using simple javascript to load the website but nothing has been working.
i get the following error on when i open the index.html
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“default-src”).
my config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>HelloCordova</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="http://mysite.us*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
<cordova>
<access origin="http://mysite.us*"/>
</cordova>
My index.js
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var app = {
// Application Constructor
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
// deviceready Event Handler
//
// Bind any cordova events here. Common events are:
// 'pause', 'resume', etc.
onDeviceReady: function() {
this.receivedEvent('deviceready');
window.location="http://mysite.us";
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
app.initialize();
Here is the code I use:
<plugin name="cordova-plugin-whitelist" source="npm" />
<allow-navigation href="https://example.org/*" />
<allow-intent href="https://example.org/*" />
<access origin="https://example.org/*" />
It doesn't need to be in a platform tag and you will obviously need to replace the url with your own.
If you need you select everything in a folder or domain, you can use the wildcard: * (Like shown above)
EDIT:
Keep in mind that you will also need to whitelist like that all resources loaded by your webapp like for example:
If you load jQuery via a cdn, then you will need to whitelist that url or the cdn's whole domain name.
Remember too that if outside urls were blacklisted in the first place is to prevent Xss injection. If you whitelist too much urls, people may be able to load a script from a source you have whitelisted so to deceive a user via your app.
EDIT 2:
You can also simply use an iframe instead of using window.location
<iframe src="https://example.com/nodejs-webapp/" style="border: 0; width: 100%; height: 100%">Your browser doesn't support iFrames.</iframe>
And this goes in the head tag
<style>body{margin:0;}</style>

Submit button is not working in phonegap

I wrote the code for login page,when i am running on desktop using phonegap desktop it working perfectly,but while i build that using phonegap build and when i tried to open in my phone the submit button is not working.Here is my code:
<script>
$(document).ready(function(){
});
function btnclick(){
debugger;
$.ajax({
type:"GET",
url: url/"+$('#useName').val()+"/"+$('#Password').val(),
contentType: "application/javascript",
jsonpCallback: "Login",
dataType: "jsonp", //Expected data format from server
});
}
function Login(data)
{
if(data==true)
{
window.location.assign("home.html");
}
else{
$('#error').show();
}
}
</script>
</html>
And for giving input:
<form>
<input id="useName" type="text" placeholder="E-mail address" />
<input id="Password" type="password" placeholder="Password" />
<input type="submit" value="submit" id="btnclick" onclick="btnclick()" />
</form>
The only thing I can think of that is causing you troubles is the whitelist configuration needed for navigating external sources.
you should add on your config.xml something like:
<access origin = "*" />
<allow-navigation href="http://*/*" />
you can modify them to fit your needs but do try it out fist with a global access to verify that this is your problem.
Also add the cordova whitelist plugin
<gap:plugin name="cordova-plugin-whitelist" source="npm" version="1.0.0"/>

Allow call (and maps, and mail) in cordova

I've been struggling with this for a while. I'm trying to make a call after people press 'Call' from a popup. Funny thing is, that it goes straight to calling when they click the phone number. But when they hit 'Call', console returns:
ERROR Internal navigation rejected - <allow-navigation> not set for url='tel:06-83237516
Code:
Controller:
$scope.callPerson = function() {
var link = "tel:" + $scope.person.phonenumber;
var confirmTel = $ionicPopup.confirm({
title: $scope.person.phonenumber,
cancelText: 'Cancel',
okText: 'Call'
});
confirmTel.then(function(res) {
if (res) {
window.open(link);
} else {
console.log('cancel call');
}
});
}
Config.xml:
<access origin="*"/>
<allow-intent href="tel:*"/>
<allow-intent href="mailto:*"/>
<access origin="tel:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
html:
<div ng-click="callPerson()"> {{person.phonenumber}}</div>
With Mail, it doesn't work at all, and returns an identical error.
Same for opening maps. It does work in the PhoneGap test app, but not when deployed.
Maps code:
$scope.openmaps = function() {
var address = $scope.person.adres + ", " + $scope.person.plaats;
var url = '';
if (ionic.Platform === 'iOS' || ionic.Platform === 'iPhone' || navigator.userAgent.match(/(iPhone|iPod|iPad)/)) {
url = "http://maps.apple.com/maps?q=" + encodeURIComponent(address);
} else if (navigator.userAgent.match(/(Android|BlackBerry|IEMobile)/)) {
url = "geo:?q=" + encodeURIComponent(address);
} else {
url = "http://maps.google.com?q=" + encodeURIComponent(address);
}
window.open(url);
};
May be it is too late but I want to comment so that other users couldn't face this issue.
Because I didn't find any working solution anywhere.
You need to add
<allow-navigation href="tel:*" /> in config.xml
I was facing same issue for mailto intent. It was working when I tried it directly
<a onclick="mailto:test#me.com">Email</a>
But I got an error when I tried to call it using javascript window.location.href = 'mailto:test#me.com
internal navigation rejected - <allow-navigation> not set for url='mailto:test#me.com'
All you need to is to add allow-navigation in your config.xml
So your config.xml will be:
<access origin="mailto:*" launch-external="yes"/>
<allow-intent href="mailto:*" />
<plugin name="cordova-plugin-whitelist" version="1" />
<allow-navigation href="mailto:*" />
I use this config in config.xml
for ios
<allow-navigation href="tel:*" />
for android
<allow-intent href="tel:*"/>
Altering Cordova's WhiteListPlugin in config.xml did not work for me -- <access >,`. I tried many combinations, including those above. Doesn't mean these won't work necessarily, just for my setup it doesn't. (Building for Browser, Android, and iOS)
However, using the Cordova InAppBrowser Plugin worked:
Use the inAppBrowser plugin and set the target to _system.
cordova.InAppBrowser.open('tel:123456789', '_system');
This by passes the issues I was seeing in iOS with unsupported url, and launches the native system's web browser (i.e., Does not rely on WhiteListPlugin to allow the URL call).
Hope this helps.
Cordova version 6.3.1.

Can I use indexedDB in a cordova iOS application?

I'm getting an InvalidAccessError when I try to open a Indexed Database in my cordova iOS application.
Platform:
cordova: 5.4.1
cordova-ios: 4.0.1
iOS 9.2 (simulator and real device)
I already added the Plugin to use the WKWebview which made the the indexedDB object at least defined, but the error is thrown. The code works in chrome, safari and mobile safari if I run it via cordova's own web server.
config.xml looks like this
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<feature name="CDVWKWebViewEngine">
<param name="ios-package" value="CDVWKWebViewEngine" />
</feature>
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
and I try to open the indexedDB with this:
openDb: function() {
var openRequest = window.indexedDB.open(DB_NAME, DB_VERSION);
openRequest.onupgradeneeded = function(event) {
console.log('upgrade needed');
console.log(event);
myIndexDb = event.target.result;
var options = {
autoIncrement: true,
keyPath: 'key'
};
var objectStore = myIndexDb.createObjectStore(DB_STORE_NAME, options);
};
openRequest.onerror = function(event) {
console.log(event);
console.log('indexDB open Error!');
};
openRequest.onsuccess = function(event) {
console.log('open success');
myIndexDb = this.result;
};
openRequest.onblocked = function(event) {
console.log('request is blocked');
console.log(event);
}
}
At the moment it works with the Telerik Plugin https://github.com/Telerik-Verified-Plugins/WKWebView (and cordova-ios 3.9.2)
EDIT:
Looks like IndexedDB problems were fixed on iOS 10, and also added it to UIWebView.
OLD ANSWER:
The way to workaround the problem with cordova-plugin-wkwebview-engine and IndexedDB is to use a local webserver.
You can use the wkwebview-engine-localhost plugin to workaround the bug adding the local webserver. To install the plugin use
cordova plugin add https://github.com/apache/cordova-plugins/tree/master/wkwebview-engine-localhost

Cordova/Phonegap Build geolocation on iOS timeout

I have been experiencing the same issue, and have tried in the past 2 weeks numerous solutions found online for this with no success, any help appreciated :)
I am writing a simple app using Cordova for IOS and Android and building it using Phonegap build. The problem is that I cannot get the "navigator.geolocation.getCurrentPosition" (or navigator.geolocation.watchPosition) calls to return anything except a timeout error on iOS. (works perfectly on Android)
Additionally, the location services dialog never appears (requesting user permission to allow GPS for the app)
To add to this strange behavior, it seems that i have to touch the screen after the app is loaded to initiate the geolocation call, on most cases the app just sits there and does nothing until the screen is touched.
Testing this on iPhone 5 with iOS 9
Things I tried:
Changing timeout settings (up to 30 seconds)
Setting enableHighAccuracy true/false
Running code with or without the geolocation plugin
Manually adding the NSLocationWhenInUseUsageDescription/NSLocationAlwaysUsageDescription settings (or both) to the plist file
Installing different plugin versions for the geolocation plugin
Changing Content Security Policy meta tag
Trying to add or remove the <plugin> declaration from root config.xml
Current plugins installed ($cordova plugin list):
cordova-plugin-dialogs 1.2.0 "Notification"
cordova-plugin-geolocation 1.0.1 "Geolocation"
cordova-plugin-whitelist 1.2.0 "Whitelist"
cordova.plugins.diagnostic 2.3.5 "Diagnostic"
Root config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget id="info.test" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>App name</name>
<description>
App Name
</description>
<author email="test#test.com" href="http://test.com">
App Team
</author>
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
index.js
var geo = {
getGeo: function() {
navigator.geolocation.getCurrentPosition(
geo.onSuccess,
geo.onError,
{maximumAge:0, timeout: 5000, enableHighAccuracy: false});
},
onSuccess: function(position) {
alert('GOT location');
alert(position.coords.latitude + ' --- ' + position.coords.longitude);
},
onError: function(error) {
alert('error getting geo!');
}
};
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
geo.getGeo();
}
};
app.initialize();
iOS Plist file:
<key>NSLocationAlwaysUsageDescription</key>
<string>This app requires constant access to your location in order to track your position, even when the screen is off.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string/>
Index.html:
<html>
<head>
<!--
Customize this policy to fit your own app's needs. For more guidance, see:
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
Some notes:
* gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
* Enable inline JS: add 'unsafe-inline' to default-src
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
Any help in the right direction appreciated!
#daddio
Oh. that's it. I should be more dogmatic on this. This should take care of the problem.
It is not advisable to use Phonegap CLI to make your Phonegap Build build project. Phonegap build requires that index.html and config.xml both sit in the root directory. All the extra files that you are required to use with Phonegap CLI, never are created or needed with Phonegap Build.
So, I'm going to give you one of my working demos. Notice that all the files are in one (1) directory.
tutorial/blog entry - An HTML Boilerplate for Phonegap Build
source code Phonegap--Generic-Boilerplate
Notice how the compiler version is set to:
<preference name="phonegap-version" value="cli-5.2.0" />
Notice, if you change cli-5.2.0 to 3.7.0, nothing appears to change.
Basically for Phonegap Build, you need index.html and config.xml - that's it. Then for security reasons (as of Cordova Tools 5.0.0), it is advisable to create a css file and a javascript file. However, I'll show you how to get around this.
Here is my complete list of Demo Apps.
Phonegap Demo Apps
YOUR FIX
This is my working code, test with 3.5.0 and cli-5.1.1 and cli5.2.0
source code Phonegap-GPS-Test
On Your fix, notice how the version is set to: <preference name="phonegap-version" value="3.5.0" />
Okay, I trust all of this will work for you. As such, your documentation is here:
https://build.phonegap.com/docs
There are some special rules for adding plugins, but I'll give you those when your program is running.
How to add Plugins with Phonegap Build
FOR THE MOST IMMEDIATE FUTURE, get your *core* plugins from this list:
http://cordova.apache.org/docs/en/5.4.0/cordova/plugins/pluginapis.html
Get your 3rd-party plugin from this source:
http://cordova.apache.org/plugins/
When using Phonegap Build, sometimes the pluins get fixed (or updated) and this breaks Phonegap Build. This is because the "fixes" require the latest version of the compiler, and Phonegap Build is always at least one version behind.
There are two ways to deal with 3; see 4 and 5.
I have created this Worksheet. You may want to make a copy or just use it as a reference. I use this worksheet to create my demos, I so know the list is good. I am working on cli-5.2.0 right now. (Should finish by Monday or so.) However, I do not test ALL 3rd-party plugins; there are 800+ plugins.
If you fail to set the version number on a plugin, you will get the latest version. If your build fails, then set the version. If the build still fails, try the previous two or three version to find one that works. NOTE, these older plugins may have bugs that prevent you from using them. So, try an even earlier version.
Lastly, if you think you have hit a bug, then here is a page with links to the Bug respository for each plugin. Last Update is on the top left. Best of Luck.

Resources