@capgo/inappbrowser 6.1.1 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -6
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +1 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +9 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +71 -0
- package/dist/docs.json +51 -0
- package/dist/esm/definitions.d.ts +14 -0
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Plugin/InAppBrowserPlugin.swift +17 -2
- package/ios/Plugin/WKWebViewController.swift +25 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -297,17 +297,26 @@ Reload the current web page.
|
|
|
297
297
|
|
|
298
298
|
#### OpenOptions
|
|
299
299
|
|
|
300
|
-
| Prop | Type
|
|
301
|
-
| ---------------------------- |
|
|
302
|
-
| **`url`** | <code>string</code>
|
|
303
|
-
| **`headers`** | <code><a href="#headers">Headers</a></code>
|
|
304
|
-
| **`
|
|
305
|
-
| **`
|
|
300
|
+
| Prop | Type | Description | Since |
|
|
301
|
+
| ---------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----- |
|
|
302
|
+
| **`url`** | <code>string</code> | Target URL to load. | 0.1.0 |
|
|
303
|
+
| **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | 0.1.0 |
|
|
304
|
+
| **`credentials`** | <code><a href="#credentials">Credentials</a></code> | <a href="#credentials">Credentials</a> to send with the request and all subsequent requests for the same host. | 6.1.0 |
|
|
305
|
+
| **`isPresentAfterPageLoad`** | <code>boolean</code> | if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately. | 0.1.0 |
|
|
306
|
+
| **`preventDeeplink`** | <code>boolean</code> | | |
|
|
306
307
|
|
|
307
308
|
|
|
308
309
|
#### Headers
|
|
309
310
|
|
|
310
311
|
|
|
312
|
+
#### Credentials
|
|
313
|
+
|
|
314
|
+
| Prop | Type |
|
|
315
|
+
| -------------- | ------------------- |
|
|
316
|
+
| **`username`** | <code>string</code> |
|
|
317
|
+
| **`password`** | <code>string</code> |
|
|
318
|
+
|
|
319
|
+
|
|
311
320
|
#### ClearCookieOptions
|
|
312
321
|
|
|
313
322
|
| Prop | Type |
|
|
@@ -339,6 +348,7 @@ Reload the current web page.
|
|
|
339
348
|
| -------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------ |
|
|
340
349
|
| **`url`** | <code>string</code> | Target URL to load. | | 0.1.0 |
|
|
341
350
|
| **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | | 0.1.0 |
|
|
351
|
+
| **`credentials`** | <code><a href="#credentials">Credentials</a></code> | <a href="#credentials">Credentials</a> to send with the request and all subsequent requests for the same host. | | 6.1.0 |
|
|
342
352
|
| **`shareDisclaimer`** | <code><a href="#disclaimeroptions">DisclaimerOptions</a></code> | share options | | 0.1.0 |
|
|
343
353
|
| **`toolbarType`** | <code><a href="#toolbartype">ToolBarType</a></code> | Toolbar type | <code>ToolBarType.DEFAULT</code> | 0.1.0 |
|
|
344
354
|
| **`shareSubject`** | <code>string</code> | Share subject | | 0.1.0 |
|
|
@@ -335,6 +335,7 @@ public class InAppBrowserPlugin
|
|
|
335
335
|
final Options options = new Options();
|
|
336
336
|
options.setUrl(url);
|
|
337
337
|
options.setHeaders(call.getObject("headers"));
|
|
338
|
+
options.setCredentials(call.getObject("credentials"));
|
|
338
339
|
options.setShowReloadButton(call.getBoolean("showReloadButton", false));
|
|
339
340
|
options.setVisibleTitle(call.getBoolean("visibleTitle", true));
|
|
340
341
|
if (Boolean.TRUE.equals(options.getVisibleTitle())) {
|
|
@@ -13,6 +13,7 @@ public class Options {
|
|
|
13
13
|
private String CloseModalOk;
|
|
14
14
|
private String url;
|
|
15
15
|
private JSObject headers;
|
|
16
|
+
private JSObject credentials;
|
|
16
17
|
private String toolbarType;
|
|
17
18
|
private JSObject shareDisclaimer;
|
|
18
19
|
private String shareSubject;
|
|
@@ -98,6 +99,14 @@ public class Options {
|
|
|
98
99
|
this.headers = headers;
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
public JSObject getCredentials() {
|
|
103
|
+
return credentials;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public void setCredentials(JSObject credentials) {
|
|
107
|
+
this.credentials = credentials;
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
public String getToolbarType() {
|
|
102
111
|
return toolbarType;
|
|
103
112
|
}
|
|
@@ -17,6 +17,7 @@ import android.util.Log;
|
|
|
17
17
|
import android.view.View;
|
|
18
18
|
import android.view.Window;
|
|
19
19
|
import android.view.WindowManager;
|
|
20
|
+
import android.webkit.HttpAuthHandler;
|
|
20
21
|
import android.webkit.PermissionRequest;
|
|
21
22
|
import android.webkit.SslErrorHandler;
|
|
22
23
|
import android.webkit.ValueCallback;
|
|
@@ -29,11 +30,13 @@ import android.widget.ImageButton;
|
|
|
29
30
|
import android.widget.TextView;
|
|
30
31
|
import android.widget.Toast;
|
|
31
32
|
import android.widget.Toolbar;
|
|
33
|
+
import com.getcapacitor.JSObject;
|
|
32
34
|
import java.net.URI;
|
|
33
35
|
import java.net.URISyntaxException;
|
|
34
36
|
import java.util.HashMap;
|
|
35
37
|
import java.util.Iterator;
|
|
36
38
|
import java.util.Map;
|
|
39
|
+
import java.util.Objects;
|
|
37
40
|
|
|
38
41
|
public class WebViewDialog extends Dialog {
|
|
39
42
|
|
|
@@ -388,6 +391,74 @@ public class WebViewDialog extends Dialog {
|
|
|
388
391
|
return false;
|
|
389
392
|
}
|
|
390
393
|
|
|
394
|
+
@Override
|
|
395
|
+
public void onReceivedHttpAuthRequest(
|
|
396
|
+
WebView view,
|
|
397
|
+
HttpAuthHandler handler,
|
|
398
|
+
String host,
|
|
399
|
+
String realm
|
|
400
|
+
) {
|
|
401
|
+
final String sourceUrl = _options.getUrl();
|
|
402
|
+
final String url = view.getUrl();
|
|
403
|
+
final JSObject credentials = _options.getCredentials();
|
|
404
|
+
|
|
405
|
+
if (
|
|
406
|
+
credentials != null &&
|
|
407
|
+
credentials.getString("username") != null &&
|
|
408
|
+
credentials.getString("password") != null &&
|
|
409
|
+
sourceUrl != null &&
|
|
410
|
+
url != null
|
|
411
|
+
) {
|
|
412
|
+
String sourceProtocol = "";
|
|
413
|
+
String sourceHost = "";
|
|
414
|
+
int sourcePort = -1;
|
|
415
|
+
try {
|
|
416
|
+
URI uri = new URI(sourceUrl);
|
|
417
|
+
sourceProtocol = uri.getScheme();
|
|
418
|
+
sourceHost = uri.getHost();
|
|
419
|
+
sourcePort = uri.getPort();
|
|
420
|
+
if (
|
|
421
|
+
sourcePort == -1 && Objects.equals(sourceProtocol, "https")
|
|
422
|
+
) sourcePort = 443;
|
|
423
|
+
else if (
|
|
424
|
+
sourcePort == -1 && Objects.equals(sourceProtocol, "http")
|
|
425
|
+
) sourcePort = 80;
|
|
426
|
+
} catch (URISyntaxException e) {
|
|
427
|
+
e.printStackTrace();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
String protocol = "";
|
|
431
|
+
int port = -1;
|
|
432
|
+
try {
|
|
433
|
+
URI uri = new URI(url);
|
|
434
|
+
protocol = uri.getScheme();
|
|
435
|
+
port = uri.getPort();
|
|
436
|
+
if (port == -1 && Objects.equals(protocol, "https")) port = 443;
|
|
437
|
+
else if (port == -1 && Objects.equals(protocol, "http")) port =
|
|
438
|
+
80;
|
|
439
|
+
} catch (URISyntaxException e) {
|
|
440
|
+
e.printStackTrace();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (
|
|
444
|
+
Objects.equals(sourceHost, host) &&
|
|
445
|
+
Objects.equals(sourceProtocol, protocol) &&
|
|
446
|
+
sourcePort == port
|
|
447
|
+
) {
|
|
448
|
+
final String username = Objects.requireNonNull(
|
|
449
|
+
credentials.getString("username")
|
|
450
|
+
);
|
|
451
|
+
final String password = Objects.requireNonNull(
|
|
452
|
+
credentials.getString("password")
|
|
453
|
+
);
|
|
454
|
+
handler.proceed(username, password);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
super.onReceivedHttpAuthRequest(view, handler, host, realm);
|
|
460
|
+
}
|
|
461
|
+
|
|
391
462
|
@Override
|
|
392
463
|
public void onLoadResource(WebView view, String url) {
|
|
393
464
|
super.onLoadResource(view, url);
|
package/dist/docs.json
CHANGED
|
@@ -298,6 +298,20 @@
|
|
|
298
298
|
],
|
|
299
299
|
"type": "Headers"
|
|
300
300
|
},
|
|
301
|
+
{
|
|
302
|
+
"name": "credentials",
|
|
303
|
+
"tags": [
|
|
304
|
+
{
|
|
305
|
+
"text": "6.1.0",
|
|
306
|
+
"name": "since"
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
"docs": "Credentials to send with the request and all subsequent requests for the same host.",
|
|
310
|
+
"complexTypes": [
|
|
311
|
+
"Credentials"
|
|
312
|
+
],
|
|
313
|
+
"type": "Credentials"
|
|
314
|
+
},
|
|
301
315
|
{
|
|
302
316
|
"name": "isPresentAfterPageLoad",
|
|
303
317
|
"tags": [
|
|
@@ -327,6 +341,29 @@
|
|
|
327
341
|
"methods": [],
|
|
328
342
|
"properties": []
|
|
329
343
|
},
|
|
344
|
+
{
|
|
345
|
+
"name": "Credentials",
|
|
346
|
+
"slug": "credentials",
|
|
347
|
+
"docs": "",
|
|
348
|
+
"tags": [],
|
|
349
|
+
"methods": [],
|
|
350
|
+
"properties": [
|
|
351
|
+
{
|
|
352
|
+
"name": "username",
|
|
353
|
+
"tags": [],
|
|
354
|
+
"docs": "",
|
|
355
|
+
"complexTypes": [],
|
|
356
|
+
"type": "string"
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"name": "password",
|
|
360
|
+
"tags": [],
|
|
361
|
+
"docs": "",
|
|
362
|
+
"complexTypes": [],
|
|
363
|
+
"type": "string"
|
|
364
|
+
}
|
|
365
|
+
]
|
|
366
|
+
},
|
|
330
367
|
{
|
|
331
368
|
"name": "ClearCookieOptions",
|
|
332
369
|
"slug": "clearcookieoptions",
|
|
@@ -436,6 +473,20 @@
|
|
|
436
473
|
],
|
|
437
474
|
"type": "Headers"
|
|
438
475
|
},
|
|
476
|
+
{
|
|
477
|
+
"name": "credentials",
|
|
478
|
+
"tags": [
|
|
479
|
+
{
|
|
480
|
+
"text": "6.1.0",
|
|
481
|
+
"name": "since"
|
|
482
|
+
}
|
|
483
|
+
],
|
|
484
|
+
"docs": "Credentials to send with the request and all subsequent requests for the same host.",
|
|
485
|
+
"complexTypes": [
|
|
486
|
+
"Credentials"
|
|
487
|
+
],
|
|
488
|
+
"type": "Credentials"
|
|
489
|
+
},
|
|
439
490
|
{
|
|
440
491
|
"name": "shareDisclaimer",
|
|
441
492
|
"tags": [
|
|
@@ -38,6 +38,10 @@ export interface ClearCookieOptions {
|
|
|
38
38
|
url: string;
|
|
39
39
|
cache?: boolean;
|
|
40
40
|
}
|
|
41
|
+
export interface Credentials {
|
|
42
|
+
username: string;
|
|
43
|
+
password: string;
|
|
44
|
+
}
|
|
41
45
|
export interface OpenOptions {
|
|
42
46
|
/**
|
|
43
47
|
* Target URL to load.
|
|
@@ -49,6 +53,11 @@ export interface OpenOptions {
|
|
|
49
53
|
* @since 0.1.0
|
|
50
54
|
*/
|
|
51
55
|
headers?: Headers;
|
|
56
|
+
/**
|
|
57
|
+
* Credentials to send with the request and all subsequent requests for the same host.
|
|
58
|
+
* @since 6.1.0
|
|
59
|
+
*/
|
|
60
|
+
credentials?: Credentials;
|
|
52
61
|
/**
|
|
53
62
|
* if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.
|
|
54
63
|
* @since 0.1.0
|
|
@@ -73,6 +82,11 @@ export interface OpenWebViewOptions {
|
|
|
73
82
|
* @since 0.1.0
|
|
74
83
|
*/
|
|
75
84
|
headers?: Headers;
|
|
85
|
+
/**
|
|
86
|
+
* Credentials to send with the request and all subsequent requests for the same host.
|
|
87
|
+
* @since 6.1.0
|
|
88
|
+
*/
|
|
89
|
+
credentials?: Credentials;
|
|
76
90
|
/**
|
|
77
91
|
* share options
|
|
78
92
|
* @since 0.1.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,kCAAe,CAAA;IACf,kCAAe,CAAA;AACjB,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B;AACD,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,wCAAyB,CAAA;IACzB,8BAAe,CAAA;IACf,2BAAY,CAAA;AACd,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface UrlEvent {\n /**\n * Emit when the url changes\n *\n * @since 0.0.1\n */\n url: string;\n}\nexport interface BtnEvent {\n /**\n * Emit when a button is clicked.\n *\n * @since 0.0.1\n */\n url: string;\n}\n\nexport type UrlChangeListener = (state: UrlEvent) => void;\nexport type ConfirmBtnListener = (state: BtnEvent) => void;\n\nexport enum BackgroundColor {\n WHITE = \"white\",\n BLACK = \"black\",\n}\nexport enum ToolBarType {\n ACTIVITY = \"activity\",\n NAVIGATION = \"navigation\",\n BLANK = \"blank\",\n DEFAULT = \"\",\n}\n\nexport interface Headers {\n [key: string]: string;\n}\n\nexport interface GetCookieOptions {\n url: string;\n includeHttpOnly?: boolean;\n}\n\nexport interface ClearCookieOptions {\n url: string;\n cache?: boolean;\n}\n\nexport interface OpenOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n */\n isPresentAfterPageLoad?: boolean;\n preventDeeplink?: boolean;\n}\n\nexport interface DisclaimerOptions {\n title: string;\n message: string;\n confirmBtn: string;\n cancelBtn: string;\n}\n\nexport interface OpenWebViewOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * share options\n * @since 0.1.0\n */\n shareDisclaimer?: DisclaimerOptions;\n /**\n * Toolbar type\n * @since 0.1.0\n * @default ToolBarType.DEFAULT\n */\n toolbarType?: ToolBarType;\n /**\n * Share subject\n * @since 0.1.0\n */\n shareSubject?: string;\n /**\n * Title of the browser\n * @since 0.1.0\n * @default 'New Window'\n */\n title?: string;\n /**\n * Background color of the browser, only on IOS\n * @since 0.1.0\n * @default BackgroundColor.BLACK\n */\n backgroundColor?: BackgroundColor;\n /**\n * If true, active the native navigation within the webview, Android only\n *\n * @default false\n */\n activeNativeNavigationForWebview?: boolean;\n /**\n * Disable the possibility to go back on native application,\n * usefull to force user to stay on the webview, Android only\n *\n * @default false\n */\n disableGoBackOnNativeApplication?: boolean;\n /**\n * Open url in a new window fullscreen\n *\n * isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n * @default false\n */\n isPresentAfterPageLoad?: boolean;\n /**\n * Whether the website in the webview is inspectable or not, ios only\n *\n * @default false\n */\n isInspectable?: boolean;\n /**\n * Whether the webview opening is animated or not, ios only\n *\n * @default true\n */\n isAnimated?: boolean;\n /**\n * Shows a reload button that reloads the web page\n * @since 1.0.15\n * @default false\n */\n showReloadButton?: boolean;\n /**\n * CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately.\n *\n * @since 1.1.0\n * @default false\n */\n closeModal?: boolean;\n /**\n * CloseModalTitle: title of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalTitle?: string;\n /**\n * CloseModalDescription: description of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Are you sure you want to close this window?'\n */\n closeModalDescription?: string;\n /**\n * CloseModalOk: text of the confirm button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalOk?: string;\n /**\n * CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Cancel'\n */\n closeModalCancel?: string;\n /**\n * visibleTitle: if true the website title would be shown else shown empty\n *\n * @since 1.2.5\n * @default true\n */\n visibleTitle?: boolean;\n /**\n * toolbarColor: color of the toolbar in hex format\n *\n * @since 1.2.5\n * @default '#ffffff''\n */\n toolbarColor?: string;\n /**\n * showArrow: if true an arrow would be shown instead of cross for closing the window\n *\n * @since 1.2.5\n * @default false\n */\n showArrow?: boolean;\n /**\n * ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website.\n *\n * @since 6.1.0\n * @default false\n */\n ignoreUntrustedSSLError?: boolean;\n}\n\nexport interface InAppBrowserPlugin {\n /**\n * Open url in a new window fullscreen\n *\n * @since 0.1.0\n */\n open(options: OpenOptions): Promise<any>;\n\n /**\n * Clear cookies of url\n *\n * @since 0.5.0\n */\n clearCookies(options: ClearCookieOptions): Promise<any>;\n\n /**\n * Get cookies for a specific URL.\n * @param options The options, including the URL to get cookies for.\n * @returns A promise that resolves with the cookies.\n */\n getCookies(options: GetCookieOptions): Promise<Record<string, string>>;\n\n close(): Promise<any>;\n /**\n * Open url in a new webview with toolbars\n *\n * @since 0.1.0\n */\n openWebView(options: OpenWebViewOptions): Promise<any>;\n /**\n * Injects JavaScript code into the InAppBrowser window.\n */\n executeScript({ code }: { code: string }): Promise<void>;\n setUrl(options: { url: string }): Promise<any>;\n /**\n * Listen for url change, only for openWebView\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"urlChangeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Listen for close click only for openWebView\n *\n * @since 0.4.0\n */\n addListener(\n eventName: \"closeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when user clicks on confirm button when disclaimer is required, works only on iOS\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"confirmBtnClicked\",\n listenerFunc: ConfirmBtnListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Remove all listeners for this plugin.\n *\n * @since 1.0.0\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Reload the current web page.\n *\n * @since 1.0.0\n */\n reload(): Promise<any>; // Add this line\n}\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,kCAAe,CAAA;IACf,kCAAe,CAAA;AACjB,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B;AACD,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,wCAAyB,CAAA;IACzB,8BAAe,CAAA;IACf,2BAAY,CAAA;AACd,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface UrlEvent {\n /**\n * Emit when the url changes\n *\n * @since 0.0.1\n */\n url: string;\n}\nexport interface BtnEvent {\n /**\n * Emit when a button is clicked.\n *\n * @since 0.0.1\n */\n url: string;\n}\n\nexport type UrlChangeListener = (state: UrlEvent) => void;\nexport type ConfirmBtnListener = (state: BtnEvent) => void;\n\nexport enum BackgroundColor {\n WHITE = \"white\",\n BLACK = \"black\",\n}\nexport enum ToolBarType {\n ACTIVITY = \"activity\",\n NAVIGATION = \"navigation\",\n BLANK = \"blank\",\n DEFAULT = \"\",\n}\n\nexport interface Headers {\n [key: string]: string;\n}\n\nexport interface GetCookieOptions {\n url: string;\n includeHttpOnly?: boolean;\n}\n\nexport interface ClearCookieOptions {\n url: string;\n cache?: boolean;\n}\n\nexport interface Credentials {\n username: string;\n password: string;\n}\n\nexport interface OpenOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n */\n isPresentAfterPageLoad?: boolean;\n preventDeeplink?: boolean;\n}\n\nexport interface DisclaimerOptions {\n title: string;\n message: string;\n confirmBtn: string;\n cancelBtn: string;\n}\n\nexport interface OpenWebViewOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * share options\n * @since 0.1.0\n */\n shareDisclaimer?: DisclaimerOptions;\n /**\n * Toolbar type\n * @since 0.1.0\n * @default ToolBarType.DEFAULT\n */\n toolbarType?: ToolBarType;\n /**\n * Share subject\n * @since 0.1.0\n */\n shareSubject?: string;\n /**\n * Title of the browser\n * @since 0.1.0\n * @default 'New Window'\n */\n title?: string;\n /**\n * Background color of the browser, only on IOS\n * @since 0.1.0\n * @default BackgroundColor.BLACK\n */\n backgroundColor?: BackgroundColor;\n /**\n * If true, active the native navigation within the webview, Android only\n *\n * @default false\n */\n activeNativeNavigationForWebview?: boolean;\n /**\n * Disable the possibility to go back on native application,\n * usefull to force user to stay on the webview, Android only\n *\n * @default false\n */\n disableGoBackOnNativeApplication?: boolean;\n /**\n * Open url in a new window fullscreen\n *\n * isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n * @default false\n */\n isPresentAfterPageLoad?: boolean;\n /**\n * Whether the website in the webview is inspectable or not, ios only\n *\n * @default false\n */\n isInspectable?: boolean;\n /**\n * Whether the webview opening is animated or not, ios only\n *\n * @default true\n */\n isAnimated?: boolean;\n /**\n * Shows a reload button that reloads the web page\n * @since 1.0.15\n * @default false\n */\n showReloadButton?: boolean;\n /**\n * CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately.\n *\n * @since 1.1.0\n * @default false\n */\n closeModal?: boolean;\n /**\n * CloseModalTitle: title of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalTitle?: string;\n /**\n * CloseModalDescription: description of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Are you sure you want to close this window?'\n */\n closeModalDescription?: string;\n /**\n * CloseModalOk: text of the confirm button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalOk?: string;\n /**\n * CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Cancel'\n */\n closeModalCancel?: string;\n /**\n * visibleTitle: if true the website title would be shown else shown empty\n *\n * @since 1.2.5\n * @default true\n */\n visibleTitle?: boolean;\n /**\n * toolbarColor: color of the toolbar in hex format\n *\n * @since 1.2.5\n * @default '#ffffff''\n */\n toolbarColor?: string;\n /**\n * showArrow: if true an arrow would be shown instead of cross for closing the window\n *\n * @since 1.2.5\n * @default false\n */\n showArrow?: boolean;\n /**\n * ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website.\n *\n * @since 6.1.0\n * @default false\n */\n ignoreUntrustedSSLError?: boolean;\n}\n\nexport interface InAppBrowserPlugin {\n /**\n * Open url in a new window fullscreen\n *\n * @since 0.1.0\n */\n open(options: OpenOptions): Promise<any>;\n\n /**\n * Clear cookies of url\n *\n * @since 0.5.0\n */\n clearCookies(options: ClearCookieOptions): Promise<any>;\n\n /**\n * Get cookies for a specific URL.\n * @param options The options, including the URL to get cookies for.\n * @returns A promise that resolves with the cookies.\n */\n getCookies(options: GetCookieOptions): Promise<Record<string, string>>;\n\n close(): Promise<any>;\n /**\n * Open url in a new webview with toolbars\n *\n * @since 0.1.0\n */\n openWebView(options: OpenWebViewOptions): Promise<any>;\n /**\n * Injects JavaScript code into the InAppBrowser window.\n */\n executeScript({ code }: { code: string }): Promise<void>;\n setUrl(options: { url: string }): Promise<any>;\n /**\n * Listen for url change, only for openWebView\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"urlChangeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Listen for close click only for openWebView\n *\n * @since 0.4.0\n */\n addListener(\n eventName: \"closeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when user clicks on confirm button when disclaimer is required, works only on iOS\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"confirmBtnClicked\",\n listenerFunc: ConfirmBtnListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Remove all listeners for this plugin.\n *\n * @since 1.0.0\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Reload the current web page.\n *\n * @since 1.0.0\n */\n reload(): Promise<any>; // Add this line\n}\n"]}
|
|
@@ -137,14 +137,17 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
137
137
|
self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
|
|
138
138
|
let showReloadButton = call.getBool("showReloadButton", false)
|
|
139
139
|
|
|
140
|
+
let credentials = self.readCredentials(call)
|
|
141
|
+
|
|
140
142
|
DispatchQueue.main.async {
|
|
141
143
|
let url = URL(string: urlString)
|
|
142
144
|
|
|
143
145
|
if self.isPresentAfterPageLoad {
|
|
144
|
-
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable)
|
|
146
|
+
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials)
|
|
145
147
|
} else {
|
|
146
148
|
self.webViewController = WKWebViewController.init()
|
|
147
149
|
self.webViewController?.setHeaders(headers: headers)
|
|
150
|
+
self.webViewController?.setCredentials(credentials: credentials)
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
self.webViewController?.source = .remote(url!)
|
|
@@ -267,14 +270,17 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
267
270
|
|
|
268
271
|
self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
|
|
269
272
|
|
|
273
|
+
let credentials = self.readCredentials(call)
|
|
274
|
+
|
|
270
275
|
DispatchQueue.main.async {
|
|
271
276
|
let url = URL(string: urlString)
|
|
272
277
|
|
|
273
278
|
if self.isPresentAfterPageLoad {
|
|
274
|
-
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable)
|
|
279
|
+
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials)
|
|
275
280
|
} else {
|
|
276
281
|
self.webViewController = WKWebViewController.init()
|
|
277
282
|
self.webViewController?.setHeaders(headers: headers)
|
|
283
|
+
self.webViewController?.setCredentials(credentials: credentials)
|
|
278
284
|
}
|
|
279
285
|
|
|
280
286
|
self.webViewController?.source = .remote(url!)
|
|
@@ -338,4 +344,13 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
338
344
|
@objc func appWillResignActive(_ notification: NSNotification) {
|
|
339
345
|
self.showPrivacyScreen()
|
|
340
346
|
}
|
|
347
|
+
|
|
348
|
+
private func readCredentials(_ call: CAPPluginCall) -> WKWebViewCredentials? {
|
|
349
|
+
var credentials: WKWebViewCredentials?
|
|
350
|
+
let credentialsDict = call.getObject("credentials", [:]).mapValues { String(describing: $0 as Any) }
|
|
351
|
+
if !credentialsDict.isEmpty, let username = credentialsDict["username"], let password = credentialsDict["password"] {
|
|
352
|
+
credentials = WKWebViewCredentials(username: username, password: password)
|
|
353
|
+
}
|
|
354
|
+
return credentials
|
|
355
|
+
}
|
|
341
356
|
}
|
|
@@ -19,6 +19,11 @@ private struct UrlsHandledByApp {
|
|
|
19
19
|
static var blank = true
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
public struct WKWebViewCredentials {
|
|
23
|
+
var username: String
|
|
24
|
+
var password: String
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
@objc public protocol WKWebViewControllerDelegate {
|
|
23
28
|
@objc optional func webViewController(_ controller: WKWebViewController, canDismiss url: URL) -> Bool
|
|
24
29
|
|
|
@@ -48,21 +53,24 @@ open class WKWebViewController: UIViewController {
|
|
|
48
53
|
super.init(coder: aDecoder)
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
public init(source: WKWebSource?) {
|
|
56
|
+
public init(source: WKWebSource?, credentials: WKWebViewCredentials? = nil) {
|
|
52
57
|
super.init(nibName: nil, bundle: nil)
|
|
53
58
|
self.source = source
|
|
59
|
+
self.credentials = credentials
|
|
54
60
|
self.initWebview()
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
public init(url: URL) {
|
|
63
|
+
public init(url: URL, credentials: WKWebViewCredentials? = nil) {
|
|
58
64
|
super.init(nibName: nil, bundle: nil)
|
|
59
65
|
self.source = .remote(url)
|
|
66
|
+
self.credentials = credentials
|
|
60
67
|
self.initWebview()
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
public init(url: URL, headers: [String: String], isInspectable: Bool) {
|
|
70
|
+
public init(url: URL, headers: [String: String], isInspectable: Bool, credentials: WKWebViewCredentials? = nil) {
|
|
64
71
|
super.init(nibName: nil, bundle: nil)
|
|
65
72
|
self.source = .remote(url)
|
|
73
|
+
self.credentials = credentials
|
|
66
74
|
self.setHeaders(headers: headers)
|
|
67
75
|
self.initWebview(isInspectable: isInspectable)
|
|
68
76
|
}
|
|
@@ -104,6 +112,7 @@ open class WKWebViewController: UIViewController {
|
|
|
104
112
|
}
|
|
105
113
|
}
|
|
106
114
|
|
|
115
|
+
|
|
107
116
|
internal var customUserAgent: String? {
|
|
108
117
|
didSet {
|
|
109
118
|
guard let agent = userAgent else {
|
|
@@ -193,6 +202,8 @@ open class WKWebViewController: UIViewController {
|
|
|
193
202
|
return UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
|
194
203
|
}()
|
|
195
204
|
|
|
205
|
+
fileprivate var credentials: WKWebViewCredentials?
|
|
206
|
+
|
|
196
207
|
deinit {
|
|
197
208
|
webView?.removeObserver(self, forKeyPath: estimatedProgressKeyPath)
|
|
198
209
|
if websiteTitleInNavigationBar {
|
|
@@ -208,6 +219,10 @@ open class WKWebViewController: UIViewController {
|
|
|
208
219
|
}
|
|
209
220
|
}
|
|
210
221
|
|
|
222
|
+
open func setCredentials(credentials: WKWebViewCredentials?) {
|
|
223
|
+
self.credentials = credentials
|
|
224
|
+
}
|
|
225
|
+
|
|
211
226
|
open func initWebview(isInspectable: Bool = true) {
|
|
212
227
|
|
|
213
228
|
self.view.backgroundColor = UIColor.white
|
|
@@ -781,7 +796,12 @@ extension WKWebViewController: WKNavigationDelegate {
|
|
|
781
796
|
}
|
|
782
797
|
|
|
783
798
|
public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
|
784
|
-
if let
|
|
799
|
+
if let credentials = credentials,
|
|
800
|
+
challenge.protectionSpace.receivesCredentialSecurely,
|
|
801
|
+
let url = webView.url, challenge.protectionSpace.host == url.host, challenge.protectionSpace.protocol == url.scheme, challenge.protectionSpace.port == url.port ?? (url.scheme == "https" ? 443 : url.scheme == "http" ? 80 : nil) {
|
|
802
|
+
let urlCredential = URLCredential(user: credentials.username, password: credentials.password, persistence: .none)
|
|
803
|
+
completionHandler(.useCredential, urlCredential)
|
|
804
|
+
} else if let bypassedSSLHosts = bypassedSSLHosts, bypassedSSLHosts.contains(challenge.protectionSpace.host) {
|
|
785
805
|
let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
|
|
786
806
|
completionHandler(.useCredential, credential)
|
|
787
807
|
} else {
|
|
@@ -804,6 +824,7 @@ extension WKWebViewController: WKNavigationDelegate {
|
|
|
804
824
|
|
|
805
825
|
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
|
806
826
|
var actionPolicy: WKNavigationActionPolicy = .allow
|
|
827
|
+
|
|
807
828
|
defer {
|
|
808
829
|
decisionHandler(actionPolicy)
|
|
809
830
|
}
|