apache / cordova-ios

Apache Cordova iOS
https://cordova.apache.org/
Apache License 2.0
2.15k stars 987 forks source link

Access Cordova API from a loaded URL #1346

Closed oliveryasuna closed 1 year ago

oliveryasuna commented 1 year ago

Hi, the link http://slack.cordova.io/ does not work, so I am asking for help here.

I set up a very simple Cordova project. I want it to simply load an external webapp when the device is ready. My index.js:

document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
  // localhost for testing.
  top.location.href = 'http://localhost:8080';
}

This all works fine. Is it possible to use the Cordova API from my webapp? I tested this by adding the cordova-plugin-dialogs plugin. First, I made sure that the plugin works by adding to my onDeviceReady:

navigator.notification.alert('Hello', () => {
  }, 'Message body', 'OK');

This works fine. But when I add the same thing to my webapp (I am sure that it is executed), nothing happens.

I tried checking if navigator had the notification property, and it does not.

dpogue commented 1 year ago

The page that wants access to Cordova APIs needs to include the cordova.js file to make those APIs available.

In general though, it's not recommended to enable Cordova API access on remote-hosted web content. Partly for security reasons (i.e., a cross-site scripting vulnerability on the remote page could allow an attacker to call Cordova APIs) and partly because it violates Apple's App Store guidelines around not exposing platform functionality to 3rd party content (4.7.1)

breautek commented 1 year ago

Accessing native device APIs from remote/third-party code is against both Apple's app store rules & Google Play store rules. So it's not something that is supported or recommended.

Section 4.7 outlines what is allowed when executable code is loaded from a remote source (rather than it being bundled in the app. It reads:

only use capabilities available in a standard WebKit view (e.g. it must open and run natively in Safari without modifications or additional software); and use WebKit and JavaScript Core to run third-party software and should not attempt to extend or expose native platform APIs to third-party software;

Instead have your core app bundled, and if needed you can use the in app browser plugin to open up third-party/untrusted remote content.

Hi, the link http://slack.cordova.io/ does not work, so I am asking for help here.

For future reference, slack is being decommissioned. We have moved our support channel to https://github.com/apache/cordova/discussions, but I understand there are still links on the wbesite to slack.

oliveryasuna commented 1 year ago

@dpogue @breautek Thank you both for your quick responses.

Regardless, I tried including cordova.js in my webapp and navigator.notification is still undefined. Any idea why?

breautek commented 1 year ago

Regardless, I tried including cordova.js in my webapp and navigator.notification is still undefined. Any idea why?

cordova.js is a generated file so it differs by platform (android for example has a slightly different version cordova.js vs the ios platform).

It's intended to only work inside the cordova webview.

So your webview needs to be loaded the local file. Usually you'd have an index.html inside your <cordova-project>/www/ folder and the config.xml file will have a <content src="index.html" /> directive.

The index.html should be able to find cordova.js relative to its current directory (assuming it's in the www folder):

<script src="cordova.js"></script>

I'd recommend create a sample app (cordova create testapp) to see an example of a minimal project structure.

oliveryasuna commented 1 year ago

@breautek This is what I did. Then I redirected to my local webapp (see original post). I copied over all of the Cordova scripts and imported them in my webapp code, but navigator.notification is still undefined.

breautek commented 1 year ago

@breautek This is what I did. Then I redirected to my local webapp (see original post). I copied over all of the Cordova scripts and imported them in my webapp code, but navigator.notification is still undefined.

If you're doing something like top.location.href = 'http://localhost:8080';

Then you're switching away from the cordova app, which isn't something is really supported. As per standard browser behaviour, when you switch documents, the JS environment also gets reset, so anything loaded on the previous document will not be available in the new document unless if that new document also loads the same scripts. But your remote server should not have access to the cordova.js file by the policies of the app stores.