From c88d1b6cc7d40192ee9a02963d5e141235478e65 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Mon, 3 Feb 2020 01:30:28 +0100 Subject: [PATCH 01/10] test: implement e2e test for #301 --- test/e2e-specs.js | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/test/e2e-specs.js b/test/e2e-specs.js index 4e1bcc9..36f4c7c 100644 --- a/test/e2e-specs.js +++ b/test/e2e-specs.js @@ -3,7 +3,7 @@ const hooks = { cordova.plugin.http.clearCookies(); helpers.enableFollowingRedirect(function() { - // server trust mode is not supported on brpwser platform + // server trust mode is not supported on browser platform if (cordova.platformId === 'browser') { return resolve(); } @@ -787,7 +787,7 @@ const tests = [ }, { description: 'should decode error body even if response type is "arraybuffer"', - expected: 'rejected: {"status": 418, ...', + expected: 'rejected: {"status":418, ...', func: function (resolve, reject) { var url = 'https://httpbin.org/status/418'; var options = { method: 'get', responseType: 'arraybuffer' }; @@ -801,7 +801,7 @@ const tests = [ }, { description: 'should serialize FormData instance correctly when it contains string value', - expected: 'resolved: {"status": 200, ...', + expected: 'resolved: {"status":200, ...', before: helpers.setMultipartSerializer, func: function (resolve, reject) { var ponyfills = cordova.plugin.http.ponyfills; @@ -820,7 +820,7 @@ const tests = [ }, { description: 'should serialize FormData instance correctly when it contains blob value', - expected: 'resolved: {"status": 200, ...', + expected: 'resolved: {"status":200, ...', before: helpers.setMultipartSerializer, func: function (resolve, reject) { var ponyfills = cordova.plugin.http.ponyfills; @@ -890,6 +890,39 @@ const tests = [ result.data.headers['access-control-allow-origin'].should.be.equal('*'); } }, + { + description: 'should decode JSON data correctly when response type is "json" #301', + expected: 'resolved: {"status":200,"data":{"slideshow": ... ', + func: function (resolve, reject) { + var url = 'https://httpbin.org/json'; + var options = { method: 'get', responseType: 'json' }; + cordova.plugin.http.sendRequest(url, options, resolve, reject); + }, + validationFunc: function (driver, result) { + result.type.should.be.equal('resolved'); + result.data.status.should.be.equal(200); + result.data.data.should.be.an('object'); + result.data.data.slideshow.should.be.eql({ + author: 'Yours Truly', + date: 'date of publication', + slides: [ + { + title: 'Wake up to WonderWidgets!', + type: 'all' + }, + { + items: [ + 'Why WonderWidgets are great', + 'Who buys WonderWidgets' + ], + title: 'Overview', + type: 'all' + } + ], + title: 'Sample Slide Show' + }); + } + }, // TODO: not ready yet // { From 69344b5357659e636428ca136d880a47184a5687 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Mon, 3 Feb 2020 01:37:21 +0100 Subject: [PATCH 02/10] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f567ecb..3465e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.4.1 - Fixed #296: multipart requests are not serialized on browser platform +- Fixed #301: data is not decoded correctly when responseType is "json" (thanks antikalk) ## 2.4.0 From 23a98ae491473b60a701cb5e0ac27d76644623d1 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Mon, 3 Feb 2020 02:46:31 +0100 Subject: [PATCH 03/10] fix #300: FormData object containing null or undefined value is not serialized correctly --- CHANGELOG.md | 1 + test/e2e-specs.js | 23 +++++++++++++++++++++++ www/ponyfills.js | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3465e55..906c1fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fixed #296: multipart requests are not serialized on browser platform - Fixed #301: data is not decoded correctly when responseType is "json" (thanks antikalk) +- Fixed #300: FormData object containing null or undefined value is not serialized correctly ## 2.4.0 diff --git a/test/e2e-specs.js b/test/e2e-specs.js index 36f4c7c..c11b244 100644 --- a/test/e2e-specs.js +++ b/test/e2e-specs.js @@ -923,6 +923,29 @@ const tests = [ }); } }, + { + description: 'should serialize FormData instance correctly when it contains null or undefined value #300', + expected: 'resolved: {"status":200, ...', + before: helpers.setMultipartSerializer, + func: function (resolve, reject) { + var ponyfills = cordova.plugin.http.ponyfills; + var formData = new ponyfills.FormData(); + formData.append('myNullValue', null); + formData.append('myUndefinedValue', undefined); + + var url = 'https://httpbin.org/anything'; + var options = { method: 'post', data: formData }; + cordova.plugin.http.sendRequest(url, options, resolve, reject); + }, + validationFunc: function (driver, result) { + helpers.checkResult(result, 'resolved'); + result.data.status.should.be.equal(200); + JSON.parse(result.data.data).form.should.be.eql({ + myNullValue: 'null', + myUndefinedValue: 'undefined' + }); + } + }, // TODO: not ready yet // { diff --git a/www/ponyfills.js b/www/ponyfills.js index 67b9bbc..e49e6d7 100644 --- a/www/ponyfills.js +++ b/www/ponyfills.js @@ -18,7 +18,7 @@ module.exports = function init(global) { value.lastModifiedDate = new Date(); value.name = filename || ''; } else { - value = value.toString ? value.toString() : value; + value = String(value); } this.__items.push([ name, value ]); From b25b7db4befdf612fa0f9ad72c7862300a5db634 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Tue, 18 Feb 2020 01:04:57 +0100 Subject: [PATCH 04/10] release v2.4.1 --- package-lock.json | 2 +- plugin.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2302d82..4e0beed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-advanced-http", - "version": "2.4.0", + "version": "2.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/plugin.xml b/plugin.xml index 0c08d4d..1918419 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,5 +1,5 @@ - + Advanced HTTP plugin Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning From f5597dd176e3a9ee639817172eda13b581b37a6a Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Thu, 5 Mar 2020 01:36:27 +0100 Subject: [PATCH 05/10] WIP: implement `setClientAuthMode()`for iOS --- src/ios/CordovaHttpPlugin.h | 1 + src/ios/CordovaHttpPlugin.m | 64 +++++++++++++++++++++++++++++++++++++ test/e2e-specs.js | 22 ++++++------- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/ios/CordovaHttpPlugin.h b/src/ios/CordovaHttpPlugin.h index 3b35e17..0e5d867 100644 --- a/src/ios/CordovaHttpPlugin.h +++ b/src/ios/CordovaHttpPlugin.h @@ -5,6 +5,7 @@ @interface CordovaHttpPlugin : CDVPlugin - (void)setServerTrustMode:(CDVInvokedUrlCommand*)command; +- (void)setClientAuthMode:(CDVInvokedUrlCommand*)command; - (void)post:(CDVInvokedUrlCommand*)command; - (void)put:(CDVInvokedUrlCommand*)command; - (void)patch:(CDVInvokedUrlCommand*)command; diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m index 2f8c750..7e5ebb0 100644 --- a/src/ios/CordovaHttpPlugin.m +++ b/src/ios/CordovaHttpPlugin.m @@ -21,6 +21,7 @@ @implementation CordovaHttpPlugin { AFSecurityPolicy *securityPolicy; + NSURLCredential *x509Credential; } - (void)pluginInitialize { @@ -39,6 +40,22 @@ } } +- (void)setupClientCertAuth:(AFHTTPSessionManager*)manager { + [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential) { + + if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodClientCertificate]) { + if (self->x509Credential) { + *credential = self->x509Credential; + return NSURLSessionAuthChallengeUseCredential; + } else { + return NSURLSessionAuthChallengePerformDefaultHandling; + } + } + + return NSURLSessionAuthChallengePerformDefaultHandling; + }]; +} + - (void)setRequestHeaders:(NSDictionary*)headers forManager:(AFHTTPSessionManager*)manager { [headers enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [manager.requestSerializer setValue:obj forHTTPHeaderField:key]; @@ -156,6 +173,7 @@ NSString *responseType = [command.arguments objectAtIndex:4]; [self setRequestSerializer: @"default" forManager: manager]; + [self setupClientCertAuth: manager]; [self setRequestHeaders: headers forManager: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; @@ -210,6 +228,7 @@ NSString *responseType = [command.arguments objectAtIndex:6]; [self setRequestSerializer: serializerName forManager: manager]; + [self setupClientCertAuth: manager]; [self setRequestHeaders: headers forManager: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; @@ -302,6 +321,51 @@ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } +- (void)setClientAuthMode:(CDVInvokedUrlCommand*)command { + CDVPluginResult* pluginResult; + NSString *mode = [command.arguments objectAtIndex:0]; + + if ([mode isEqualToString:@"none"]) { + x509Credential = nil; + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } + + if ([mode isEqualToString:@"systemstore"]) { + NSString *alias = [command.arguments objectAtIndex:1]; + + // TODO + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"mode 'systemstore' not supported on iOS"]; + } + + if ([mode isEqualToString:@"buffer"]) { + CFDataRef container = (__bridge CFDataRef) [command.arguments objectAtIndex:2]; + CFStringRef password = (__bridge CFStringRef) [command.arguments objectAtIndex:3]; + + const void *keys[] = { kSecImportExportPassphrase }; + const void *values[] = { password }; + + CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); + CFArrayRef items; + OSStatus securityError = SecPKCS12Import(container, options, &items); + CFRelease(options); + + if (securityError != noErr) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + } else { + CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); + SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); + + self->x509Credential = [NSURLCredential credentialWithIdentity:identity certificates: nil persistence:NSURLCredentialPersistenceForSession]; + CFRelease(items); + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } + } + + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +} + - (void)post:(CDVInvokedUrlCommand*)command { [self executeRequestWithData: command withMethod:@"POST"]; } diff --git a/test/e2e-specs.js b/test/e2e-specs.js index c11b244..5f1bf78 100644 --- a/test/e2e-specs.js +++ b/test/e2e-specs.js @@ -946,18 +946,16 @@ const tests = [ }); } }, - - // TODO: not ready yet - // { - // description: 'should authenticate correctly when client cert auth is configured with a PKCS12 container', - // expected: 'resolved: {"status": 200, ...', - // before: helpers.setBufferClientAuthMode, - // func: function (resolve, reject) { cordova.plugin.http.get('https://client.badssl.com/', {}, {}, resolve, reject); }, - // validationFunc: function (driver, result) { - // result.type.should.be.equal('resolved'); - // result.data.data.should.include('TLS handshake'); - // } - // } + { + description: 'should authenticate correctly when client cert auth is configured with a PKCS12 container', + expected: 'resolved: {"status": 200, ...', + before: helpers.setBufferClientAuthMode, + func: function (resolve, reject) { cordova.plugin.http.get('https://client.badssl.com/', {}, {}, resolve, reject); }, + validationFunc: function (driver, result) { + result.type.should.be.equal('resolved'); + result.data.data.should.include('TLS handshake'); + } + } ]; if (typeof module !== 'undefined' && module.exports) { From d84e3995d22a87a0d3f975fc2c74fbc93b354d85 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Thu, 5 Mar 2020 02:04:48 +0100 Subject: [PATCH 06/10] chore: update appium caps --- test/e2e-tooling/caps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e-tooling/caps.js b/test/e2e-tooling/caps.js index 0548853..fa92769 100644 --- a/test/e2e-tooling/caps.js +++ b/test/e2e-tooling/caps.js @@ -67,8 +67,8 @@ const configs = { app: 'HttpTestAppAndroid' }, browserstackAndroidDevice: { - device: 'Google Nexus 9', - os_version: '5.1', + device: 'Google Nexus 6', + os_version: '5.0', project: 'HTTP Test App', autoWebview: true, app: 'HttpTestAppAndroid' From f8f4bdc9df00f29a24bc0b4ac1ec7356f574000d Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Thu, 5 Mar 2020 03:23:28 +0100 Subject: [PATCH 07/10] fix: auth challenge block isn't handling server trust settings correctly --- src/ios/CordovaHttpPlugin.m | 43 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m index 7e5ebb0..d7f8fcc 100644 --- a/src/ios/CordovaHttpPlugin.m +++ b/src/ios/CordovaHttpPlugin.m @@ -40,20 +40,31 @@ } } -- (void)setupClientCertAuth:(AFHTTPSessionManager*)manager { - [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential) { +- (void)setupAuthChallengeBlock:(AFHTTPSessionManager*)manager { + [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition( + NSURLSession * _Nonnull session, + NSURLAuthenticationChallenge * _Nonnull challenge, + NSURLCredential * _Nullable __autoreleasing * _Nullable credential + ) { + if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodServerTrust]) { + *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; - if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodClientCertificate]) { - if (self->x509Credential) { + if (![self->securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { + return NSURLSessionAuthChallengeRejectProtectionSpace; + } + + if (credential) { + return NSURLSessionAuthChallengeUseCredential; + } + } + + if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodClientCertificate] && self->x509Credential) { *credential = self->x509Credential; return NSURLSessionAuthChallengeUseCredential; - } else { - return NSURLSessionAuthChallengePerformDefaultHandling; } - } - - return NSURLSessionAuthChallengePerformDefaultHandling; - }]; + + return NSURLSessionAuthChallengePerformDefaultHandling; + }]; } - (void)setRequestHeaders:(NSDictionary*)headers forManager:(AFHTTPSessionManager*)manager { @@ -164,7 +175,6 @@ - (void)executeRequestWithoutData:(CDVInvokedUrlCommand*)command withMethod:(NSString*) method { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; - manager.securityPolicy = securityPolicy; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *headers = [command.arguments objectAtIndex:1]; @@ -173,7 +183,7 @@ NSString *responseType = [command.arguments objectAtIndex:4]; [self setRequestSerializer: @"default" forManager: manager]; - [self setupClientCertAuth: manager]; + [self setupAuthChallengeBlock: manager]; [self setRequestHeaders: headers forManager: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; @@ -217,7 +227,6 @@ - (void)executeRequestWithData:(CDVInvokedUrlCommand*)command withMethod:(NSString*)method { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; - manager.securityPolicy = securityPolicy; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *data = [command.arguments objectAtIndex:1]; @@ -228,7 +237,7 @@ NSString *responseType = [command.arguments objectAtIndex:6]; [self setRequestSerializer: serializerName forManager: manager]; - [self setupClientCertAuth: manager]; + [self setupAuthChallengeBlock: manager]; [self setRequestHeaders: headers forManager: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; @@ -335,7 +344,7 @@ // TODO - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"mode 'systemstore' not supported on iOS"]; + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"mode 'systemstore' is not supported on iOS"]; } if ([mode isEqualToString:@"buffer"]) { @@ -396,7 +405,6 @@ - (void)uploadFiles:(CDVInvokedUrlCommand*)command { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; - manager.securityPolicy = securityPolicy; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *headers = [command.arguments objectAtIndex:1]; @@ -407,6 +415,7 @@ NSString *responseType = [command.arguments objectAtIndex:6]; [self setRequestHeaders: headers forManager: manager]; + [self setupAuthChallengeBlock: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; [self setResponseSerializer:responseType forManager:manager]; @@ -456,7 +465,6 @@ - (void)downloadFile:(CDVInvokedUrlCommand*)command { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; - manager.securityPolicy = securityPolicy; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; NSString *url = [command.arguments objectAtIndex:0]; @@ -466,6 +474,7 @@ bool followRedirect = [[command.arguments objectAtIndex:4] boolValue]; [self setRequestHeaders: headers forManager: manager]; + [self setupAuthChallengeBlock: manager]; [self setTimeout:timeoutInSeconds forManager:manager]; [self setRedirect:followRedirect forManager:manager]; From 0bfb81c57f22a0075ffeff6feb070856dc0ff97d Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Fri, 1 May 2020 23:56:39 +0200 Subject: [PATCH 08/10] chore: fix browserstack testing for android --- scripts/test-app.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test-app.sh b/scripts/test-app.sh index 245376b..4482e5e 100755 --- a/scripts/test-app.sh +++ b/scripts/test-app.sh @@ -3,8 +3,8 @@ set -e ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )"; cd ..; pwd )" -if [ $CI == "true" ] && ([ -z $SAUCE_USERNAME ] || [ -z $SAUCE_ACCESS_KEY ]); then - echo "Skipping CI tests, because Saucelabs credentials are not set."; +if [ $CI == "true" ] && ([ -z $SAUCE_USERNAME ] || [ -z $SAUCE_ACCESS_KEY ]) && ([ -z $BROWSERSTACK_USERNAME ] || [ -z $BROWSERSTACK_ACCESS_KEY ]); then + echo "Skipping CI tests, because Saucelabs and BrowserStack credentials are not set."; exit 0; fi From 6009ae82f78992ab4be31d4a0857e2a69b8ee1a7 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Sat, 2 May 2020 00:06:58 +0200 Subject: [PATCH 09/10] chore: update readme to prevent confusion on request timeout --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95980c0..b7458e0 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This defaults to `urlencoded`. You can also override the default content type he :warning: `multipart` depends on several Web API standards which need to be supported in your web view. Check out https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for more info. ### setRequestTimeout -Set how long to wait for a request to respond, in seconds. +Set the "read" timeout in seconds. This is the timeout interval to use when waiting for additional data. ```js cordova.plugin.http.setRequestTimeout(5.0); From 0a23e29403ecb0cc67c5491448b91aa778e24855 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Sat, 2 May 2020 00:48:52 +0200 Subject: [PATCH 10/10] chore: document X.509 client cert feature --- CHANGELOG.md | 4 ++++ README.md | 24 ++++++++++++++++++++++++ package.json | 4 ++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 906c1fc..335d0fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.5.0 + +- Feature #56: add support for X.509 client certificate based authentication + ## 2.4.1 - Fixed #296: multipart requests are not serialized on browser platform diff --git a/README.md b/README.md index b7458e0..4135de8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This is a fork of [Wymsee's Cordova-HTTP plugin](https://github.com/wymsee/cordo - SSL / TLS Pinning - CORS restrictions do not apply + - X.509 client certificate based authentication - Handling of HTTP code 401 - read more at [Issue CB-2415](https://issues.apache.org/jira/browse/CB-2415) ## Updates @@ -186,6 +187,29 @@ cordova.plugin.http.setServerTrustMode('nocheck', function() { }); ``` +### setClientAuthMode +Configure X.509 client certificate authentication. Takes mode and options. `mode` being one of following values: + +* `none`: disable client certificate authentication +* `systemstore` (only on Android): use client certificate installed in the Android system store; user will be presented with a list of all installed certificates +* `buffer`: use given client certificate; you will need to provide an options object: + * `rawPkcs`: ArrayBuffer containing raw PKCS12 container with client certificate and private key + * `pkcsPassword`: password of the PKCS container + +```js + // enable client auth using PKCS12 container given in ArrayBuffer `myPkcs12ArrayBuffer` + cordova.plugin.http.setClientAuthMode('buffer', { + rawPkcs: myPkcs12ArrayBuffer, + pkcsPassword: 'mySecretPassword' + }, success, fail); + + // enable client auth using certificate in system store (only on Android) + cordova.plugin.http.setClientAuthMode('systemstore', {}, success, fail); + + // disable client auth + cordova.plugin.http.setClientAuthMode('none', {}, success, fail); +``` + ### disableRedirect (deprecated) This function was deprecated in 2.0.9. Use ["setFollowRedirect"](#setFollowRedirect) instead. diff --git a/package.json b/package.json index 8548a50..c29ce3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-advanced-http", - "version": "2.4.1", + "version": "2.5.0", "description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning", "scripts": { "updatecert": "node ./scripts/update-e2e-server-cert.js && node ./scripts/update-e2e-client-cert.js", @@ -69,4 +69,4 @@ "wd": "1.4.1", "xml2js": "0.4.19" } -} +} \ No newline at end of file