Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 102 additions & 9 deletions src/adal.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,88 @@

import * as application from 'tns-core-modules/application';
import * as utils from 'tns-core-modules/utils/utils';
import { isAndroid } from 'tns-core-modules/ui/frame/frame';
import { getString, setString } from "tns-core-modules/application-settings";

export interface MultiPlatformRedirectUri {
ios: string;
android: string;
}

const USERID_KEY = "USER_ID";
const LOGINHINT_KEY = "LOGIN_HINT";

export class AdalContext {

private activity: any;
private authority: string;
private clientId: string;
private context: com.microsoft.aad.adal.AuthenticationContext;
private loginHint: string = '';
private _loginHint: string;
private get loginHint(): string {
if(this.useBroker) {
return '';
}
if(this._loginHint == null) {
this._loginHint = getString(LOGINHINT_KEY);
if(this._loginHint == null) {
this.loginHint = '';
}
}
return this._loginHint;
}
private set loginHint(value: string) {
this._loginHint = value;
setString(LOGINHINT_KEY, this._loginHint);
}
private redirectUri: string = 'urn:ietf:wg:oauth:2.0:oob';
private useBroker: boolean;
private resourceId: string;
private userId: string;

private _userId: string;
private get userId(): string {
if(this._userId == null) {
this._userId = getString(USERID_KEY);
}
return this._userId;
}
private set userId(value: string) {
this._userId = value;
setString(USERID_KEY, this._userId);
}
// Authority is in the form of https://login.microsoftonline.com/yourtenant.onmicrosoft.com
constructor(authority: string, clientId: string, resourceId: string) {
constructor(authority: string, clientId: string, resourceId: string, redirectUri?: MultiPlatformRedirectUri | string, useBroker?: boolean) {
this.authority = authority;
this.clientId = clientId;
this.resourceId = resourceId;
if(redirectUri != null) {
if (typeof redirectUri === "string") {
this.redirectUri = redirectUri;
} else {
this.redirectUri = redirectUri.android;
}
}
this.useBroker = ((useBroker == null) ? false : useBroker);
};
public initContext() {
if(this.context != null) {
console.log("Context already initialised");
return;
}
this.activity = application.android.foregroundActivity || application.android.startActivity;

this.context = new com.microsoft.aad.adal.AuthenticationContext(utils.ad.getApplicationContext(), this.authority, true);

com.microsoft.aad.adal.AuthenticationSettings.INSTANCE.setUseBroker(this.useBroker);
application.android.on('activityResult', (args) => {
let intent: android.content.Intent = args.activity.getIntent();
if (this.context) {
this.context.onActivityResult(args.requestCode, args.resultCode, args.intent);
}
});
}

public login(): Promise<string> {
if(!this.isContextInit()) {
this.initContext();
}
var that = this;
return new Promise<string>((resolve: any, reject: any) => {
this.context.acquireToken(
this.activity,
Expand All @@ -41,7 +93,8 @@ export class AdalContext {
this.loginHint,
new com.microsoft.aad.adal.AuthenticationCallback({
onSuccess(result: com.microsoft.aad.adal.AuthenticationResult): void {
this.userId = result.getUserInfo().getUserId();
that.userId = result.getUserInfo().getUserId();
that.loginHint = result.getUserInfo().getDisplayableId();
resolve(result.getAccessToken());
},
onError(error: javalangException): void {
Expand All @@ -53,20 +106,60 @@ export class AdalContext {
}

public getToken(): Promise<string> {
if(!this.isContextInit()) {
this.initContext();
}
if(this.userId == null) {
return this.login();
}
var that = this;
return new Promise<string>((resolve: any, reject) => {
this.context.acquireTokenSilentAsync(
this.clientId,
this.resourceId,
this.clientId,
this.userId,
new com.microsoft.aad.adal.AuthenticationCallback({
onSuccess(result: com.microsoft.aad.adal.AuthenticationResult): void {
console.log("expires on = " + result.getExpiresOn().toGMTString());
that.userId = result.getUserInfo().getUserId();
that.loginHint = result.getUserInfo().getDisplayableId();
resolve(result.getAccessToken());
},
onError(error: javalangException): void {
if (error instanceof com.microsoft.aad.adal.AuthenticationException) {
if(error.getCode() == com.microsoft.aad.adal.ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED) {
that.context.acquireToken(
that.activity,
that.resourceId,
that.clientId,
that.redirectUri,
that.loginHint,
new com.microsoft.aad.adal.AuthenticationCallback({
onSuccess(result: com.microsoft.aad.adal.AuthenticationResult): void {
that.userId = result.getUserInfo().getUserId();
that.loginHint = result.getUserInfo().getDisplayableId();
resolve(result.getAccessToken());
},
onError(error: javalangException): void {
reject(error);
}
}));
return;
}
}
reject(error);
}
})
);
});
}

private isContextInit(): boolean {
if(this.context == null) {
console.log("Context not initialised");
return false;
}
console.log("Context initialised");
return true;
}
}
72 changes: 66 additions & 6 deletions src/adal.ios.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
/// <reference path="./platforms/ios/typings/adal-library.ios.d.ts" />
/// <reference path="./platforms/ios/typings/adal-library.ios.d.ts" />import { isIOS } from "tns-core-modules/ui/frame/frame";


import { getString, setString } from "tns-core-modules/application-settings";
declare var interop: any;
declare var NSURL: any;

export interface MultiPlatformRedirectUri {
ios: string;
android: string;
}

export class AdalContext {

private authError: any;
Expand All @@ -11,20 +18,43 @@ export class AdalContext {
private clientId: string;
private context: ADAuthenticationContext;
private redirectUri: string = 'urn:ietf:wg:oauth:2.0:oob';
private useBroker: boolean;
private resourceId: string;
private userId: string;

// Authority is in the form of https://login.microsoftonline.com/yourtenant.onmicrosoft.com
constructor(authority: string, clientId: string, resourceId: string) {
constructor(authority: string, clientId: string, resourceId: string, redirectUri?: MultiPlatformRedirectUri | string, useBroker?: boolean) {
this.authError = new interop.Reference();
this.authority = authority;
this.clientId = clientId;
this.resourceId = resourceId;
if(redirectUri != null) {
if (typeof redirectUri === "string") {
this.redirectUri = redirectUri;
} else {
this.redirectUri = redirectUri.ios;
}
}
this.useBroker = ((useBroker == null) ? false : useBroker);

}
public initContext() {
if(this.context != null) {
console.log("Context already initialised");
return;
}
ADAuthenticationSettings.sharedInstance().setDefaultKeychainGroup(null);
this.context = ADAuthenticationContext.authenticationContextWithAuthorityError(this.authority, this.authError);
if(this.useBroker) {
this.context.credentialsType = ADCredentialsType.D_CREDENTIALS_AUTO;
} else {
this.context.credentialsType = ADCredentialsType.D_CREDENTIALS_EMBEDDED;
}
}

public login(): Promise<string> {
if(!this.isContextInit()) {
this.initContext();
}
this.authError = new interop.Reference();
return new Promise<string>((resolve, reject) => {
this.context.acquireTokenWithResourceClientIdRedirectUriCompletionBlock(
Expand All @@ -44,15 +74,45 @@ export class AdalContext {
}

public getToken(): Promise<string> {
return new Promise<string>((resolve) => {
if(!this.isContextInit()) {
this.initContext();
}
return new Promise<string>((resolve, reject) => {
this.context.acquireTokenSilentWithResourceClientIdRedirectUriCompletionBlock(
this.clientId,
this.resourceId,
this.clientId,
NSURL.URLWithString(this.redirectUri),
(result: ADAuthenticationResult) => {
resolve(result.accessToken);
if(result.accessToken == null) {
Promise.resolve().then(() => {
this.context.acquireTokenWithResourceClientIdRedirectUriCompletionBlock(
this.resourceId,
this.clientId,
NSURL.URLWithString(this.redirectUri),
(result: ADAuthenticationResult) => {
this.authResult = result;
if (result.error) {
reject(result.error);
} else {
this.userId = result.tokenCacheItem.userInformation.userObjectId;
resolve(result.accessToken);
}
});
});
} else {
resolve(result.accessToken);
}
}
);
});
}

private isContextInit(): boolean {
if(this.context == null) {
console.log("Context not initialised");
return false;
}
console.log("Context initialised");
return true;
}
}
25 changes: 20 additions & 5 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
/**
* iOS and Android apis should match.
* It doesn't matter if you export `.ios` or `.android`, either one but only one.
*/
export * from './adal.ios';
export interface MultiPlatformRedirectUri {
ios: string;
android: string;
}
export declare class AdalContext {
private authError;
private authResult;
private authority;
private clientId;
private context;
private redirectUri;
private useBroker;
private resourceId;
private userId;
constructor(authority: string, clientId: string, resourceId: string, redirectUri?: MultiPlatformRedirectUri | string, useBroker?: boolean);
initContext(): void;
login(): Promise<string>;
getToken(): Promise<string>;
private isContextInit();
}