cordova-plugin-ms-adal
Advanced tools
Comparing version 0.8.1 to 0.9.0
@@ -0,1 +1,9 @@ | ||
0.9.0 - February 8, 2017 | ||
* Use alternative sources to populate 'userInfo' in case if 'idToken' is not defined | ||
* Make AuthenticationSettings.setUseBroker available across platforms | ||
* Bump Android version to 1.10.0 | ||
* windows: Fix login issues on Windows when user id is specified | ||
* android: Fix silent token acquisition using broker component | ||
* ios: Put ADAL CODE_SIGN_ENTITLEMENTS according to ios@4.3.0 Api | ||
0.8.1 - September 22, 2016 | ||
@@ -2,0 +10,0 @@ * added `cordovaDependencies` section to package.json |
{ | ||
"name": "cordova-plugin-ms-adal", | ||
"version": "0.8.1", | ||
"version": "0.9.0", | ||
"description": "Provides Microsoft Azure Active Directory (ADAL) OAuth client.", | ||
@@ -25,2 +25,7 @@ "cordova": { | ||
}, | ||
"0.9.0": { | ||
"cordova-android": ">=4.1.0", | ||
"cordova-windows": ">=4.1.0", | ||
"cordova": ">=5.4.0" | ||
}, | ||
"1.0.0": { | ||
@@ -27,0 +32,0 @@ "cordova": ">=100" |
@@ -13,5 +13,21 @@ # Active Directory Authentication Library (ADAL) plugin for Apache Cordova apps | ||
## NOTICE: iOS 10 and Azure Authentication | ||
**If you're using plugin version < 0.8.x on iOS platform, we strongly recommend you to update your application to use newest version of the plugin in order to support authentication on iOS 10, otherwise your users will not be able to sign-in once iOS 10 is released.** | ||
Once you’ve updated plugin to the latest version your application will continue to work, there is no further code changes required for your application to continue working. | ||
### To update your application using Cordova CLI | ||
- navigate to your app's directory | ||
- run the following commands: | ||
``` | ||
cordova plugin rm cordova-plugin-ms-adal --save | ||
cordova plugin add cordova-plugin-ms-adal@0.8.x --save | ||
``` | ||
## Community Help and Support | ||
We leverage [Stack Overflow](http://stackoverflow.com/) to work with the community on supporting Azure Active Directory and its SDKs, including this one! We highly recommend you ask your questions on Stack Overflow (we're all on there!) Also browser existing issues to see if someone has had your question before. | ||
We leverage [Stack Overflow](http://stackoverflow.com/) to work with the community on supporting Azure Active Directory and its SDKs, including this one! We highly recommend you ask your questions on Stack Overflow (we're all on there!) Also browser existing issues to see if someone has had your question before. | ||
@@ -28,7 +44,7 @@ We recommend you use the "adal" tag so we can see it! Here is the latest Q&A on Stack Overflow for ADAL: [http://stackoverflow.com/questions/tagged/adal](http://stackoverflow.com/questions/tagged/adal) | ||
```javascriptMicrosoft.ADAL.AuthenticationSettings.setUseBroker(false) | ||
```javascript | ||
// Shows user authentication dialog if required | ||
function authenticate(authCompletedCallback, errorCallback) { | ||
var authContext = new Microsoft.ADAL.AuthenticationContext(authority); | ||
var authContext = new Microsoft.ADAL.AuthenticationContext(authority); | ||
authContext.tokenCache.readItems().then(function (items) { | ||
@@ -42,3 +58,3 @@ if (items.length > 0) { | ||
.then(authCompletedCallback, function () { | ||
// We require user cridentials so triggers authentication dialog | ||
// We require user credentials so triggers authentication dialog | ||
authContext.acquireTokenAsync(resourceUri, clientId, redirectUri) | ||
@@ -76,3 +92,3 @@ .then(authCompletedCallback, errorCallback); | ||
#### Example | ||
var authContext = new Microsoft.ADAL.AuthenticationContext("https://login.windows.net/common"); | ||
var authContext = new Microsoft.ADAL.AuthenticationContext("https://login.windows.net/common"); | ||
@@ -156,5 +172,5 @@ ## AuthenticationContext methods and properties | ||
* err.details - Raw error information returned by Apache Cordova bridge and native implementation (if available). | ||
## Known issues and workarounds | ||
@@ -257,3 +273,7 @@ | ||
`Microsoft.ADAL.AuthenticationSettings.setUseBroker(true);` | ||
```javascript | ||
Microsoft.ADAL.AuthenticationSettings.setUseBroker(true) | ||
.then(function() { | ||
... | ||
``` | ||
@@ -260,0 +280,0 @@ __Note__: Developer needs to register special redirectUri for broker usage. RedirectUri is in the format of `msauth://packagename/Base64UrlencodedSignature` |
@@ -14,4 +14,3 @@ | ||
var AUTH_RESULT_SUCCESS_STATUS = 0; | ||
var REQUIRED_DISPLAYABLE_ID = Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.requiredDisplayableId, | ||
UNIQUE_ID = Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.uniqueId; | ||
var OPTIONAL_DISPLAYABLE_ID = Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.optionalDisplayableId; | ||
@@ -28,3 +27,3 @@ var ctxCache = {}; | ||
function mapUserUniqueIdToDisplayName(context, uniqueId) { | ||
function tryMapUniqueIdToDisplayName(context, uniqueId) { | ||
var cacheItems = context.tokenCache.readItems(); | ||
@@ -39,4 +38,34 @@ | ||
} | ||
return null; | ||
} | ||
function tryMapDisplayNameToUniqueId(context, displayName) { | ||
var cacheItems = context.tokenCache.readItems(); | ||
for (var i = 0; i < cacheItems.length; i++) { | ||
try { | ||
if (cacheItems[i].displayableId === displayName) { | ||
return cacheItems[i].uniqueId; | ||
} | ||
} catch (e) { } | ||
} | ||
return null; | ||
} | ||
function getUserIdentifier(context, userId) { | ||
var uniqueId = tryMapDisplayNameToUniqueId(context, userId); | ||
if (uniqueId !== null) { | ||
return wrapUserId(userId, OPTIONAL_DISPLAYABLE_ID); | ||
} | ||
var displayName = tryMapUniqueIdToDisplayName(context, userId); | ||
if (displayName !== null) { | ||
return wrapUserId(displayName, OPTIONAL_DISPLAYABLE_ID); | ||
} | ||
return wrapUserId(userId, OPTIONAL_DISPLAYABLE_ID); | ||
} | ||
function wrapUserId(userId, type) { | ||
@@ -104,15 +133,7 @@ return (userId !== '' && userId != null) ? new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(userId, type) | ||
var extraQueryParameters = args[6]; | ||
var userIdentifier; | ||
var displayName; | ||
ADALProxy.getOrCreateCtx(authority, validateAuthority).then(function (context) { | ||
displayName = mapUserUniqueIdToDisplayName(context, userId); | ||
userIdentifier = getUserIdentifier(context, userId); | ||
if (typeof displayName !== 'undefined') { | ||
userIdentifier = wrapUserId(displayName, REQUIRED_DISPLAYABLE_ID); | ||
} else { | ||
userIdentifier = wrapUserId(userId, UNIQUE_ID); | ||
} | ||
if (isPhone) { | ||
@@ -185,5 +206,4 @@ // Continuation callback is used when we're running on WindowsPhone which uses | ||
var userIdentifier = wrapUserId(userId, UNIQUE_ID); | ||
ADALProxy.getOrCreateCtx(authority, validateAuthority).then(function (context) { | ||
var userIdentifier = getUserIdentifier(context, userId); | ||
context.acquireTokenSilentAsync(resourceUrl, clientId, userIdentifier).then(function (res) { | ||
@@ -190,0 +210,0 @@ handleAuthResult(win, fail, res); |
@@ -87,2 +87,6 @@ | ||
it("Should get token successfully if created using constructor", function (done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
var context = new AuthenticationContext(AUTHORITY_URL); | ||
@@ -168,2 +172,6 @@ context.acquireTokenSilentAsync(RESOURCE_URL, APP_ID, TEST_USER_ID) | ||
xit("Should acquire token via 'acquireTokenAsync' method", function (done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
authContext.acquireTokenAsync(RESOURCE_URL, APP_ID, REDIRECT_URL) | ||
@@ -194,2 +202,6 @@ .then(function (authResult) { | ||
it("Should acquire token via 'acquireTokenSilentAsync' method", function (done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
authContext.acquireTokenSilentAsync(RESOURCE_URL, APP_ID, TEST_USER_ID) | ||
@@ -212,2 +224,6 @@ .then(function (authResult) { | ||
it("Should fail to acquire token via 'acquireTokenSilentAsync' method if username is not valid", function (done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
authContext.acquireTokenSilentAsync(RESOURCE_URL, APP_ID, INVALID_USER_ID) | ||
@@ -251,2 +267,6 @@ .then(function (authResult) { | ||
it("Should acquire native cache via 'readItems' method", function (done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
cache.readItems() | ||
@@ -265,2 +285,6 @@ .then(function (cacheItems) { | ||
it("Should be able to delete item via 'deleteItem' method", function(done) { | ||
// skip tests that require user interaction if running on CI | ||
if (window.IS_CI) { | ||
pending(); | ||
} | ||
@@ -302,2 +326,11 @@ var fail = function (err) { | ||
}); | ||
it("AuthenticationSettings.setUseBroker should not crash", function(done) { | ||
Microsoft.ADAL.AuthenticationSettings.setUseBroker(false).then(function() { | ||
done(); | ||
}, function(err) { | ||
expect(err).not.toBeDefined(); | ||
done(); | ||
}); | ||
}) | ||
}); | ||
@@ -372,2 +405,35 @@ }; | ||
createActionButton("Acquire token with userId (specified as DisplayableId aka email)", function () { | ||
if (!context) { | ||
contentEl.innerHTML = "Create context first"; | ||
return; | ||
} | ||
context.tokenCache.readItems() | ||
.then(function function_name(items) { | ||
var itemsWithDisplayableId = items.filter(function (item) { | ||
return item && item.displayableId; | ||
}); | ||
if (itemsWithDisplayableId.length <= 0) { | ||
contentEl.innerHTML = "No users withDisplayableId found in cache, please acquire token first"; | ||
return; | ||
} | ||
context.acquireTokenAsync(RESOURCE_URL, APP_ID, REDIRECT_URL, itemsWithDisplayableId[0].displayableId).then(function (authRes) { | ||
TEST_USER_ID = itemsWithDisplayableId[0].displayableId; | ||
contentEl.innerHTML = authRes; | ||
contentEl.innerHTML += "<br /> AccessToken: " + authRes.accessToken; | ||
contentEl.innerHTML += "<br /> ExpiresOn: " + authRes.expiresOn; | ||
}, function (err) { | ||
contentEl.innerHTML = err ? err.message : ""; | ||
}); | ||
contentEl.innerHTML = JSON.stringify(items, null, 4); | ||
}, function (err) { | ||
contentEl.innerHTML = err ? err.message : ""; | ||
}); | ||
}); | ||
createActionButton("Acquire token silently", function () { | ||
@@ -389,2 +455,58 @@ | ||
createActionButton("Acquire token silently with userId", function () { | ||
if (!context) { | ||
contentEl.innerHTML = "Create context first"; | ||
return; | ||
} | ||
context.tokenCache.readItems() | ||
.then(function function_name(items) { | ||
var itemsWithUserId = items.filter(function (item) { | ||
return item.userInfo && item.userInfo.userId; | ||
}); | ||
if (itemsWithUserId.length <= 0) { | ||
contentEl.innerHTML = "No users withUserId found in cache, please acquire token first"; | ||
return; | ||
} | ||
context.acquireTokenSilentAsync(RESOURCE_URL, APP_ID, itemsWithUserId[0].userInfo.userId).then(function (authRes) { | ||
contentEl.innerHTML = authRes; | ||
contentEl.innerHTML += "<br /> AccessToken: " + authRes.accessToken; | ||
contentEl.innerHTML += "<br /> ExpiresOn: " + authRes.expiresOn; | ||
}, function (err) { | ||
contentEl.innerHTML = err ? err.message : ""; | ||
}); | ||
}); | ||
}); | ||
createActionButton("Acquire token silently with userId (specified as DisplayableId aka email)", function () { | ||
if (!context) { | ||
contentEl.innerHTML = "Create context first"; | ||
return; | ||
} | ||
context.tokenCache.readItems() | ||
.then(function function_name(items) { | ||
var itemsWithDisplayableId = items.filter(function (item) { | ||
return item && item.displayableId; | ||
}); | ||
if (itemsWithDisplayableId.length <= 0) { | ||
contentEl.innerHTML = "No users withDisplayableId found in cache, please acquire token first"; | ||
return; | ||
} | ||
context.acquireTokenSilentAsync(RESOURCE_URL, APP_ID, itemsWithDisplayableId[0].displayableId).then(function (authRes) { | ||
contentEl.innerHTML = authRes; | ||
contentEl.innerHTML += "<br /> AccessToken: " + authRes.accessToken; | ||
contentEl.innerHTML += "<br /> ExpiresOn: " + authRes.expiresOn; | ||
}, function (err) { | ||
contentEl.innerHTML = err ? err.message : ""; | ||
}); | ||
}); | ||
}); | ||
createActionButton("Read token cache items", function () { | ||
@@ -391,0 +513,0 @@ |
@@ -14,3 +14,3 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
* Constructs context to use with known authority to get the token. It reuses existing context | ||
* for this authority URL in native proxy or creates a new one if it doesn't exists. | ||
* for this authority URL in native proxy or creates a new one if it doesn't exist. | ||
* Corresponding native context will be created at first time when it will be needed. | ||
@@ -41,3 +41,3 @@ * | ||
* Constructs context asynchronously to use with known authority to get the token. | ||
* It reuses existing context for this authority URL in native proxy or creates a new one if it doesn't exists. | ||
* It reuses existing context for this authority URL in native proxy or creates a new one if it doesn't exist. | ||
* | ||
@@ -44,0 +44,0 @@ * @param {String} authority Authority url to send code and token requests |
@@ -20,3 +20,12 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
this.userInfo = authResult.idToken ? UserInfo.fromJWT(authResult.idToken) : null; | ||
var jwtToken = authResult.idToken || authResult.accessToken; | ||
this.userInfo = null; | ||
if (jwtToken) { | ||
this.userInfo = UserInfo.fromJWT(jwtToken); | ||
} | ||
if (!this.userInfo) { | ||
this.userInfo = new UserInfo(authResult.userInfo); | ||
} | ||
} | ||
@@ -23,0 +32,0 @@ |
@@ -24,4 +24,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
return bridge.executeNativeMethod('setUseBroker', [!!useBroker]); | ||
if (cordova.platformId === 'android') { | ||
return bridge.executeNativeMethod('setUseBroker', [!!useBroker]); | ||
} | ||
// Broker is handled by system on Windows/iOS | ||
var deferred = new Deferred(); | ||
deferred.resolve(); | ||
return deferred; | ||
} | ||
} |
@@ -8,4 +8,5 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
var GENERIC_ERR_MESSAGE = "Error occured while executing native method."; | ||
var GENERIC_ERR_MESSAGE = "Error occurred while executing native method."; | ||
var GENERIC_ERR_CODE = "NATIVE_METHOD_GENERAL_FAILURE"; | ||
/** | ||
@@ -12,0 +13,0 @@ * Implements proxy between Cordova JavaScript and Native functionality |
@@ -25,3 +25,3 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
/** | ||
* Parses jwt token that contains a use information and produces a valid UserInfo structure. | ||
* Parses jwt token that contains user information and produces a valid UserInfo structure. | ||
* This method is intended for internal use and should not be used by end-user. | ||
@@ -28,0 +28,0 @@ * |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13270316
5744
298