diff --git a/.gitignore b/.gitignore index 92569d4..efa0f72 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ Thumbs.db # WebStorm # .idea/ +# TS # +test/**/*.js +*.js.map diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6c07085 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +sudo: false +node_js: + - "8" \ No newline at end of file diff --git a/README.md b/README.md index dcd2cf3..dd66c29 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The ADAL for node.js library makes it easy for node.js applications to authenticate to AAD in order to access AAD protected web resources. It supports 3 authentication modes shown in the quickstart code below. ## Versions -Current version - 0.1.23 +Current version - 0.1.24 Minimum recommended version - 0.1.22 You can find the changes for each version in the [change log](https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/blob/master/changelog.txt). diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..af40933 --- /dev/null +++ b/changelog.md @@ -0,0 +1,106 @@ +Version 0.1.24 +-------------- +Release Date: 06 November 2017 +* Added type definitions to the project. This should help users developing their apps in TypeScript #142, [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/12586). +* Replaced `"node-uuid"` with `"uuid"` #170. + +Version 0.1.23 +-------------- +Release Date: 26 Oct 2017 +* Fix Issue #95 - Change npm licenses to license and use spdx syntax +* Fix Issue #122 - Broken link on README file +* Fix Issue #155 - remove need for dynamic access to package.json to obtain lib version (util.js) +* Fix Issue #172 - Add `login.microsoftonline.us` endpoint +* Added Windows Graph Sample + +Version 0.1.22 +-------------- +Release Date: 1 Aug 2016 +* Fix Issue #132 - Trim developer provided authority to construct endpoints + +Version 0.1.21 +-------------- +Release Date: 23 Jun 2016 +* Policheck and credscan fixes + +Version 0.1.20 +-------------- +Release Date: 17 Jun 2016 +* Add support for resource owner grant flow for ADFS + +Version 0.1.19 +-------------- +Release Date: 26 Apr 2016 +* Fixed CredScan issue for the checked in pem file +* Policheck fixes +* Updated node-uuid +* Fixed Readme.md +* Inline the adal version during compile time +* Fix issue #71 - client-credential cert-bad-cert failing +* Fix issue #78 - Express dependency in package.json doesn't match syntax used in website-sample.js +* Fix issue #80 - Unreachable ADFS server results in misleading error message + +Version 0.1.18 +-------------- +Release Date: 5 Feb 2016 +* Add oid in IDTokenMap to expose for returned user info. + +Version 0.1.17 +-------------- +Release Date: 8 Oct 2015 +* Add support for cross tenant refresh token + +Version 0.1.16 +-------------- +Release Date: 3 Sep 2015 +* Add support for device profile + +Version 0.1.15 +-------------- +Release Date: 4 Aug 2015 +* Fix issue #68 - add support for wstrust 2005 endpoint. +* Fix issue #62 - escape xml chars in password before creating a xml request for wstrust. + +Version 0.1.14 +-------------- +Release Date: 5 May 2015 +* Add timestamp to the log entries. + +Version 0.1.13 +-------------- +Release Date: 1 May 2015 +* Scrub security sensitive data in WS-Trust exchange from log messages. +* Update the version of the jws dependency to the latest release. + +Version 0.1.12 +-------------- +Release Date: 19 February 2015 +* Add login.microsoftonline.com to the static list of known authorities. +* Bug fixes. (#36) + +Version 0.1.11 +-------------- +Release Date: 16 December 2014 +* Added support for certificate authentication for confidential clients. + +Version 0.1.10 +-------------- +Release Date: 24 November 2014 +* 0.1.9 published version was corrupt. + +Version 0.1.9 +-------------- +Release Date: 24 November 2014 +* Fixed issue #22 - ADAL needs a method that allows confidential clients +to acquire a new token via a refresh token.The `acquireTokenWithRefreshToken` function was updated to take an additional `clientSecret` argument. Passing this new argument is optional and the change should not breakapps using this function before the additional argument was added. + +Version 0.1.8 +-------------- +Release Date: 29 October 2014 +* Update version of xpath.js dependency to 1.0.5 +* Fix a bug in the regular expression used to parse a 401 challenge. + +Version 0.1.7 +-------------- +Release Date: 2 September 2014 +* Add caching support to AuthenticationContext.acquireTokenWithClientCredentials diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 8669d26..0000000 --- a/changelog.txt +++ /dev/null @@ -1,108 +0,0 @@ -Version 0.1.23 --------------- -Release Date: 26 Oct 2017 - * Fix Issue #95 - Change npm licenses to license and use spdx syntax - * Fix Issue #122 - Broken link on README file - * Fix Issue #155 - remove need for dynamic access to package.json to obtain lib version (util.js) - * Fix Issue #172 - Add login.microsoftonline.us endpoint - * Added Windows Graph Sample - -Version 0.1.22 --------------- -Release Date: 1 Aug 2016 - * Fix Issue #132 - Trim developer provided authority to construct endpoints - -Version 0.1.21 --------------- -Release Date: 23 Jun 2016 - * Policheck and credscan fixes - -Version 0.1.20 --------------- -Release Date: 17 Jun 2016 - * Add support for resource owner grant flow for ADFS - -Version 0.1.19 --------------- -Release Date: 26 Apr 2016 - * Fixed CredScan issue for the checked in pem file - * Policheck fixes - * Updated node-uuid - * Fixed Readme.md - * Inline the adal version during compile time - * Fix issue #71 - client-credential cert-bad-cert failing - * Fix issue #78 - Express dependency in package.json doesn't match syntax used in website-sample.js - * Fix issue #80 - Unreachable ADFS server results in misleading error message - -Version 0.1.18 --------------- -Release Date: 5 Feb 2016 - * Add oid in IDTokenMap to expose for returned user info. - -Version 0.1.17 --------------- -Release Date: 8 Oct 2015 - * Add support for cross tenant refresh token - -Version 0.1.16 --------------- -Release Date: 3 Sep 2015 - * Add support for device profile - -Version 0.1.15 --------------- -Release Date: 4 Aug 2015 - * Fix issue #68 - add support for wstrust 2005 endpoint. - * Fix issue #62 - escape xml chars in password before creating a xml request for wstrust. - -Version 0.1.14 --------------- -Release Date: 5 May 2015 - * Add timestamp to the log entries. - -Version 0.1.13 --------------- -Release Date: 1 May 2015 - * Scrub security sensitive data in WS-Trust exchange from log messages. - * Update the version of the jws dependency to the latest release. - -Version 0.1.12 --------------- -Release Date: 19 February 2015 - * Add login.microsoftonline.com to the static list of known authorities. - * Bug fixes. (#36) - -Version 0.1.11 --------------- -Release Date: 16 December 2014 - - * Added support for certificate authentication for confidential clients. - -Version 0.1.10 --------------- -Release Date: 24 November 2014 - - * 0.1.9 published version was corrupt. - -Version 0.1.9 --------------- -Release Date: 24 November 2014 - - * Fixed issue #22 - ADAL needs a method that allows confidential clients - to acquire a new token via a refresh token. The acquireTokenWithRefreshToken - function was updated to take an additional clientSecret argument. - Passing this new argument is optional and the change should not break apps - using this function before the additional argument was added. - -Version 0.1.8 --------------- -Release Date: 29 October 2014 - - * Update version of xpath.js dependency to 1.0.5 - * Fix a bug in the regular expression used to parse a 401 challenge. - -Version 0.1.7 --------------- -Release Date: 2 September 2014 - - * Add caching support to AuthenticationContext.acquireTokenWithClientCredentials diff --git a/lib/adal.d.ts b/lib/adal.d.ts new file mode 100644 index 0000000..2592520 --- /dev/null +++ b/lib/adal.d.ts @@ -0,0 +1,436 @@ +import * as http from "http"; + + +/** + * Describes the available logging levels. + * ERROR: 0, + * WARN: 1, + * INFO: 2, + * VERBOSE: 3 + * @type {number} + */ +export type LoggingLevel = 0 | 1 | 2 | 3; + +/** + * @callback LoggingCallback + * @memberOf Logging + * @param {LoggingLevel} level The level of this log entry. + * @param {string} message The text content of the log entry. + * @param {Error} [error] An Error object if this is an {@link Logging.LOGGING_LEVEL.ERROR|ERROR} level log entry. + */ +type LoggingCallback = (level: LoggingLevel, message: string, error?: Error) => void; + +/** + * @typedef LoggingOptions + * @memberOf Logging + * @property {LoggingCallback} [log] The function to call when ADAL generates a log entry. + * @property {LoggingLevel} [level] The maximum level of log entries to generate. + */ +interface LoggingOptions { + log?: LoggingCallback; + level?: LoggingLevel; +} + +export class Logging { + /** + * @property {LoggingLevel} LOGGING_LEVEL Provides information about the logging levels. + * ERROR: 0, + * WARN: 1, + * INFO: 2, + * VERBOSE: 3 + */ + static LOGGING_LEVEL: LoggingLevel; + /** + * Sets global logging options for ADAL. + * @param {LoggingOptions} options + */ + static setLoggingOptions(options: LoggingOptions): void; + /** + * Get's the current global logging options. + * @return {LoggingOptions} + */ + static getLoggingOptions(): LoggingOptions; +} + +export function setGlobalADALOptions(): any; // TODO + +export function getGlobalADALOptions(): any; // TODO + +/** + * Contains tokens and metadata upon successful completion of an acquireToken call. + * @typedef TokenResponse + */ +export interface TokenResponse { + /** + * @property {string} tokenType The type of token returned. Example 'Bearer'. + */ + tokenType: string; + /** + * @property {int} expiresIn The amount of time, in seconds, for which the token is valid. + */ + expiresIn: number; + /** + * @property {Date} expiresOn The Date on which the access token expires. + */ + expiresOn: Date | string; + /** + * @property {string} resource The resource for which the token was requested for. Example: 'https://management.core.windows.net/'. + */ + resource: string; + /** + * @property {string} accessToken The returned access token. + */ + accessToken: string; + /** + * @property {string} [refreshToken] A refresh token. + */ + refreshToken?: string; + + /** + * @property {Date} [createdOn] The date on which the access token was created. + */ + createdOn?: Date | string; + /** + * @property {string} [userId] An id for the user. May be a displayable value if is_user_id_displayable is true. + */ + userId?: string; + /** + * @property {boolean} [isUserIdDisplayable] Indicates whether the user_id property will be meaningful if displayed to a user. + */ + isUserIdDisplayable?: boolean; + /** + * @property {string} [tenantId] The identifier of the tenant under which the access token was issued. + */ + tenantId?: string; + /** + * @property {string} [oid] The object id of the user in the tenant + */ + oid?: string; + /** + * @property {string} [givenName] The given name of the principal represented by the access token. + */ + givenName?: string; + /** + * @property {string} [familyName] The family name of the principal represented by the access token. + */ + familyName?: string; + /** + * @property {string} [identityProvider] Identifies the identity provider that issued the access token. + */ + identityProvider?: string; + + /** + * @property {any} [error] Provides information about error if any. + */ + error?: any; + + /** + * @property {any} [errorDescription] Short description about error if any. + */ + errorDescription?: any; + + [x: string]: any; +} + +/** + * This will be returned in case the OAuth 2 service returns an error. + * @typedef ErrorResponse + * @property {string} [error] A server error. + * @property {string} [errorDescription] A description of the error returned. + */ +export interface ErrorResponse { + error: string; + errorDescription: string; +} + +/** + * This is the callback that is passed to all acquireToken variants below. + * @callback AcquireTokenCallback + * @param {Error} [error] If the request fails this parameter will contain an Error object. + * @param {TokenResponse|ErrorResponse} [response] On a succesful request returns a {@link TokenResposne}. + */ +export type AcquireTokenCallback = (error: Error, response: TokenResponse | ErrorResponse) => void; + +/** + * This is the callback that is passed to all acquireUserCode method below. + * @callback AcquireTokenCallback + * @param {Error} [error] If the request fails this parameter will contain an Error object. + * @param {UserCodeInfo} [response] On a succesful request returns a {@link UserCodeInfo}. + */ +export type AcquireUserCodeCallback = (error: Error, response: UserCodeInfo) => void; + +/** + * This is an interface that can be implemented to provide custom token cache persistence. + * @public + * @interface TokenCache + */ +export interface TokenCache { + /** + * Removes a collection of entries from the cache in a single batch operation. + * @param {Array} entries An array of cache entries to remove. + * @param {Function} callback This function is called when the operation is complete. Any error is provided as the + * first parameter. + */ + remove(entires: TokenResponse[], callback: { (err: Error, result: null): void }): void; + + /** + * Adds a collection of entries to the cache in a single batch operation. + * @param {Array} entries An array of entries to add to the cache. + * @param {Function} callback This function is called when the operation is complete. Any error is provided as the + * first parameter. + */ + add(entries: TokenResponse[], callback: { (err: Error, result: boolean): void }): void; + + /** + * Finds all entries in the cache that match all of the passed in values. + * @param {object} query This object will be compared to each entry in the cache. Any entries that + * match all of the values in this object will be returned. All the values + * in the passed in object must match values in a potentialy returned object + * exactly. The returned object may have more values than the passed in query + * object. Please take a look at http://underscorejs.org/#where for an example + * on how to provide query. + * @param {TokenCacheFindCallback} callback + */ + find(query: any, callback: { (err: Error, results: any[]): void }): void +} + +/** + * @class MemoryCache - Describes the in memory implementation of the token cache. + */ +export class MemoryCache implements TokenCache { + /** + * @private + * @property {Array} _entries An array of entries in the TokenCache. + */ + private _entries: TokenResponse[]; + + /** + * @constructor Creates an instance of MemoryCache + */ + constructor(); + + /** + * Removes a collection of entries from the cache in a single batch operation. + * @param {Array} entries An array of cache entries to remove. + * @param {Function} callback This function is called when the operation is complete. Any error is provided as the + * first parameter. + */ + remove(entires: TokenResponse[], callback: { (err: Error, result: null): void }): void; + + /** + * Adds a collection of entries to the cache in a single batch operation. + * @param {Array} entries An array of entries to add to the cache. + * @param {Function} callback This function is called when the operation is complete. Any error is provided as the + * first parameter. + */ + add(entries: TokenResponse[], callback: { (err: Error, result: boolean): void }): void; + + /** + * Finds all entries in the cache that match all of the passed in values. + * @param {object} query This object will be compared to each entry in the cache. Any entries that + * match all of the values in this object will be returned. All the values + * in the passed in object must match values in a potentialy returned object + * exactly. The returned object may have more values than the passed in query + * object. Please take a look at http://underscorejs.org/#where for an example + * on how to provide query. + * @param {TokenCacheFindCallback} callback + */ + find(query: any, callback: { (err: Error, results: any[]): void }): void +} + +export class AuthenticationContext { + /** + * @property {string} authority A URL that identifies a token authority. + */ + public authority: string; + /** + * @property {string} correlationId The correlation id that will be used for the next acquireToken request. + */ + public correlationId: string; + /** + * @property {any} options Options that are applied to requests generated by this AuthenticationContext instance. + */ + public options: any; + /** + * @property {TokenCache} cache The token cache used by this AuthenticationContext instance + */ + public cache: TokenCache; + + /** + * Creates a new AuthenticationContext object. By default the authority will be checked against + * a list of known Azure Active Directory authorities. If the authority is not recognized as + * one of these well known authorities then token acquisition will fail. This behavior can be + * turned off via the validateAuthority parameter below. + * @constructor + * @param {string} authority A URL that identifies a token authority. + * @param {bool} [validateAuthority] Turns authority validation on or off. This parameter default to true. + * @param {TokenCache} [cache] Sets the token cache used by this AuthenticationContext instance. If this parameter is not set + * then a default, in memory cache is used. The default in memory cache is global to the process and is + * shared by all AuthenticationContexts that are created with an empty cache parameter. To control the + * scope and lifetime of a cache you can either create a {@link MemoryCache} instance and pass it when + * constructing an AuthenticationContext or implement a custom {@link TokenCache} and pass that. Cache + * instances passed at AuthenticationContext construction time are only used by that instance of + * the AuthenticationContext and are not shared unless it has been manually passed during the + * construction of other AuthenticationContexts. + * + */ + constructor(authority: string, validateAuthority?: boolean, cache?: TokenCache); + + /** + * Gets a token for a given resource. + * @param {string} resource A URI that identifies the resource for which the token is valid. + * @param {string} clientId The OAuth client id of the calling application. + * @param {string} clientSecret The OAuth client secret of the calling application. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithClientCredentials(resource: string, clientId: string, clientSecret: string, callback: AcquireTokenCallback): void; + + /** + * Gets a token for a given resource. + * @param {string} resource A URI that identifies the resource for which the token is valid. + * @param {string} username The username of the user on behalf this application is authenticating. + * @param {string} password The password of the user named in the username parameter. + * @param {string} clientId The OAuth client id of the calling application. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithUsernamePassword(resource: string, username: string, password: string, clientId: string, callback: AcquireTokenCallback): void; + + /** + * Gets a token for a given resource. + * @param {string} authorizationCode An authorization code returned from a client. + * @param {string} redirectUri The redirect uri that was used in the authorize call. + * @param {string} resource A URI that identifies the resource for which the token is valid. + * @param {string} clientId The OAuth client id of the calling application. + * @param {string} clientSecret The OAuth client secret of the calling application. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithAuthorizationCode(authorizationCode: string, redirectUri: string, resource: string, clientId: string, clientSecret: string, callback: AcquireTokenCallback): void; + + /** + * Gets a new access token via a previously issued refresh token. + * @param {string} refreshToken A refresh token returned in a tokne response from a previous invocation of acquireToken. + * @param {string} clientId The OAuth client id of the calling application. + * @param {string} [clientSecret] The OAuth client secret of the calling application. (Note: this parameter is a late addition. + * This parameter may be ommitted entirely so that applications built before this change will continue + * to work unchanged.) + * @param {string} resource The OAuth resource for which a token is being request. This parameter is optional and can be set to null. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithRefreshToken(refreshToken: string, clientId: string, resource: string, callback: AcquireTokenCallback): void; + public acquireTokenWithRefreshToken(refreshToken: string, clientId: string, clientSecret: string, resource: string, callback: AcquireTokenCallback): void; + + /** + * Gets a token for a given resource. + * @param {string} resource A URI that identifies the resource for which the token is valid. + * @param {string} userId The username of the user on behalf this application is authenticating. + * @param {string} clientId The OAuth client id of the calling application. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireToken(resource: string, userId: string, clientId: string, callback: AcquireTokenCallback): void + + /** + * Gets the userCodeInfo which contains user_code, device_code for authenticating user on device. + * @param {string} resource A URI that identifies the resource for which the device_code and user_code is valid for. + * @param {string} clientId The OAuth client id of the calling application. + * @param {string} language The language code specifying how the message should be localized to. + * @param {AcquireUserCodeCallback} callback The callback function. + */ + public acquireUserCode(resource: string, clientId: string, language: string, callback: AcquireUserCodeCallback): void; + + /** + * Gets a new access token using via a certificate credential. + * @param {string} resource A URI that identifies the resource for which the token is valid. + * @param {string} clientId The OAuth client id of the calling application. + * @param {string} certificate A PEM encoded certificate private key. + * @param {string} thumbprint A hex encoded thumbprint of the certificate. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithClientCertificate(resource: string, clientId: string, certificate: string, thumbprint: string, callback: AcquireTokenCallback): void; + + /** + * Gets a new access token using via a device code. + * @note This method doesn't look up the cache, it only stores the returned token into cache. To look up cache before making a new request, + * please use acquireToken. + * @param {string} clientId The OAuth client id of the calling application. + * @param {object} userCodeInfo Contains device_code, retry interval, and expire time for the request for get the token. + * @param {AcquireTokenCallback} callback The callback function. + */ + public acquireTokenWithDeviceCode(resource: string, clientId: string, userCodeInfo: UserCodeInfo, callback: AcquireTokenCallback): void; + + /** + * Cancels the polling request to get token with device code. + * @param {object} userCodeInfo Contains device_code, retry interval, and expire time for the request for get the token. + * @param {AcquireTokenCallback} callback The callback function. + */ + public cancelRequestToGetTokenWithDeviceCode(userCodeInfo: UserCodeInfo, callback: AcquireTokenCallback): void; +} + +/** + * Describes the user code information that is provided by ADAL while authenticating via DeviceCode. + */ +export interface UserCodeInfo { + deviceCode: string; + expiresIn: number; + interval: number; + message: string; + userCode: string; + verificationUrl: string; + error?: any; + errorDescription?: any; + [x: string]: any; +} + +/** + * Creates a new AuthenticationContext object. By default the authority will be checked against + * a list of known Azure Active Directory authorities. If the authority is not recognized as + * one of these well known authorities then token acquisition will fail. This behavior can be + * turned off via the validateAuthority parameter below. + * @function + * @param {string} authority A URL that identifies a token authority. + * @param {bool} [validateAuthority] Turns authority validation on or off. This parameter default to true. + * @returns {AuthenticationContext} A new authentication context. + */ +export function createAuthenticationContext(authority: string, validateAuthority?: boolean): AuthenticationContext; + +/** + * @class + * Describes the parameters that are parsed from an OAuth challenge in the www-authenticate header. + */ +export class AuthenticationParameters { + authorizationUri: string; + resource: string; + /** + * @constructor Provides an instance of AuthenticationParameters + * @param {string} authorizationUri The URI of an authority that can issues tokens for the resource that issued the challenge. + * @param {string} resource The resource for a which a token should be requested from the authority. + */ + constructor(authorizationUri: string, resource: string); +} + +/** + * Creates an {@link AuthenticationParameters} object from the contents of a + * www-authenticate header received from a HTTP 401 response from a resource server. + * @param {string} challenge The content fo the www-authenticate header. + * @return {AuthenticationParameters} An AuthenticationParameters object containing the parsed values from the header. + */ +export function createAuthenticationParametersFromHeader(challenge: string): AuthenticationParameters; + +/** + * Create an {@link AuthenticationParameters} object from a node http.IncomingMessage + * object that was created as a result of a request to a resource server. This function + * expects the response to contain a HTTP 401 error code with a www-authenticate + * header. + * @param {http.IncomingMessage} response A response from a http request to a resource server. + * @return {AuthenticationParameters} + */ +export function createAuthenticationParametersFromResponse(response: http.IncomingMessage): AuthenticationParameters; + +/** + * Creates an {@link AuthenticationParameters} object by sending a get request + * to the url passed to this function, and parsing the resulting http 401 + * response. + * @param {string|url} url The url of a resource server. + * @param {AuthenticationParameters} callback Called on error or request completion. + * @param {string} [correlationId] An optional correlationId to pass along with the request and to include in any logs. + */ +export function createAuthenticationParametersFromUrl(url: string, callback: { (error: Error, parameters: AuthenticationParameters): void }, correlationId?: string): AuthenticationParameters; \ No newline at end of file diff --git a/lib/log.js b/lib/log.js index fafa0c0..8cbad26 100644 --- a/lib/log.js +++ b/lib/log.js @@ -21,7 +21,7 @@ 'use strict'; var _ = require('underscore'); -var uuid = require('node-uuid'); // want to replace with this in the future: https://gist.github.com/jed/982883 +var uuid = require('uuid'); // want to replace with this in the future: https://gist.github.com/jed/982883 diff --git a/lib/oauth2client.js b/lib/oauth2client.js index d36a341..d4cd2cc 100644 --- a/lib/oauth2client.js +++ b/lib/oauth2client.js @@ -23,7 +23,7 @@ var _ = require('underscore'); require('date-utils'); // Adds a number of convenience methods to the builtin Date object. var querystring = require('querystring'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); var request = require('request'); var url = require('url'); var async = require('async'); diff --git a/lib/self-signed-jwt.js b/lib/self-signed-jwt.js index c0ea9d0..0304346 100644 --- a/lib/self-signed-jwt.js +++ b/lib/self-signed-jwt.js @@ -26,7 +26,7 @@ var util = require('./util'); require('date-utils'); var jws = require('jws'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); /** * JavaScript dates are in milliseconds, but JWT dates are in seconds. diff --git a/lib/wstrust-request.js b/lib/wstrust-request.js index 121ff84..ff5b62c 100644 --- a/lib/wstrust-request.js +++ b/lib/wstrust-request.js @@ -21,7 +21,7 @@ 'use strict'; var request = require('request'); -var uuid = require('node-uuid'); +var uuid = require('uuid'); var Logger = require('./log').Logger; var util = require('./util'); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c511be1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1023 @@ +{ + "name": "adal-node", + "version": "0.1.24", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "@types/nock": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/nock/-/nock-8.2.1.tgz", + "integrity": "sha1-H75b3suUPBCad4VT+k0kAcuTlLQ=", + "dev": true, + "requires": { + "@types/node": "8.0.47" + } + }, + "@types/node": { + "version": "8.0.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.47.tgz", + "integrity": "sha512-kOwL746WVvt/9Phf6/JgX/bsGQvbrK5iUgzyfwZNcKVFcjAUVSpF9HxevLTld2SG9aywYHOILj38arDdY1r/iQ==" + }, + "@types/sinon": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-2.3.7.tgz", + "integrity": "sha512-w+LjztaZbgZWgt/y/VMP5BUAWLtSyoIJhXyW279hehLPyubDoBNwvhcj3WaSptcekuKYeTCVxrq60rdLc6ImJA==", + "dev": true + }, + "@types/underscore": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.4.tgz", + "integrity": "sha512-lYM1FJ9v+gxyeH13ty22qvl5Z/UPq1xCwmxZANqzPNRBddshb6Q6uOUeat2FcPNKRqVg2dunxDCEa5X9gmrqeQ==", + "dev": true + }, + "ajv": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "requires": { + "lodash": "4.17.4" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", + "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "date-utils": { + "version": "1.2.21", + "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", + "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz", + "integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE=", + "requires": { + "base64url": "2.0.0", + "safe-buffer": "5.1.1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.3.0", + "har-schema": "2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jshint": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", + "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "dev": true, + "requires": { + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.4", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" + }, + "dependencies": { + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", + "dev": true + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, + "jwa": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz", + "integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU=", + "requires": { + "base64url": "2.0.0", + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.9", + "safe-buffer": "5.1.1" + } + }, + "jws": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz", + "integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI=", + "requires": { + "base64url": "2.0.0", + "jwa": "1.1.5", + "safe-buffer": "5.1.1" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lolex": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.3.tgz", + "integrity": "sha512-BdHq78SeI+6PAUtl4atDuCt7L6E4fab3mSRtqxm4ywaXe4uP7jZ0TTcFNuU20syUjxZc2l7jFqKVMJ+AX0LnpQ==", + "dev": true + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nise": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.2.0.tgz", + "integrity": "sha512-q9jXh3UNsMV28KeqI43ILz5+c3l+RiNW8mhurEwCKckuHQbL+hTJIKKTiUlCPKlgQ/OukFvSnKB/Jk3+sFbkGA==", + "dev": true, + "requires": { + "formatio": "1.2.0", + "just-extend": "1.1.27", + "lolex": "1.6.0", + "path-to-regexp": "1.7.0", + "text-encoding": "0.6.4" + }, + "dependencies": { + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + } + } + }, + "nock": { + "version": "9.0.27", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.27.tgz", + "integrity": "sha512-UCdl4VFGBrnNLgk4Rx2NKjPbzVVk6BSsG4xjDhPcKwWwHWVxYT/TcuCT/9ObG46ez5d/jg7+4EFbPuF3XjDRtQ==", + "dev": true, + "requires": { + "chai": "3.5.0", + "debug": "2.6.9", + "deep-equal": "1.0.1", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "propagate": "0.4.0", + "qs": "6.5.1", + "semver": "5.4.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "propagate": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", + "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "sinon": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.0.2.tgz", + "integrity": "sha512-4mUsjHfjrHyPFGDTtNJl0q8cv4VOJGvQykI1r3fnn05ys0sQL9M1Y+DyyGNWLD2PMcoyqjJ/nFDm4K54V1eQOg==", + "dev": true, + "requires": { + "diff": "3.3.1", + "formatio": "1.2.0", + "lodash.get": "4.4.2", + "lolex": "2.1.3", + "nise": "1.2.0", + "supports-color": "4.4.0", + "type-detect": "4.0.3" + }, + "dependencies": { + "type-detect": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", + "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", + "dev": true + } + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.0" + } + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + }, + "typescript": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.1.tgz", + "integrity": "sha1-7znN6ierrAtQAkLWcmq5DgyEZjE=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" + }, + "xpath.js": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.0.7.tgz", + "integrity": "sha1-fpRif1QSdsvGprArXTXpQYVls+Q=" + } + } +} diff --git a/package.json b/package.json index 77a670a..1588300 100644 --- a/package.json +++ b/package.json @@ -10,30 +10,47 @@ "type": "git", "url": "https://github.com/AzureAD/azure-activedirectory-library-for-nodejs.git" }, - "version": "0.1.23", + "version": "0.1.24", "description": "Windows Azure Active Directory Client Library for node", - "keywords": [ "node", "azure", "AAD", "adal", "adfs", "oauth" ], + "keywords": [ + "node", + "azure", + "AAD", + "adal", + "adfs", + "oauth" + ], "main": "./lib/adal.js", - "engines": { "node": ">= 0.6.15" }, + "types": "./lib/adal.d.ts", + "engines": { + "node": ">= 0.6.15" + }, "dependencies": { + "@types/node": "^8.0.47", "date-utils": "*", "jws": "3.x.x", - "node-uuid": "1.4.7", + "uuid": "^3.1.0", "request": ">= 2.52.0", "underscore": ">= 1.3.1", "xmldom": ">= 0.1.x", - "xpath.js": "~1.0.5", + "xpath.js": "~1.0.5", "async": ">=0.6.0" }, "devDependencies": { "jshint": "*", "mocha": "*", "nock": "*", - "sinon": "*" + "sinon": "*", + "typescript": "^2.6.1", + "@types/nock": "^8.2.1", + "@types/mocha": "^2.2.44", + "@types/underscore": "^1.8.4", + "@types/sinon": "^2.3.7" }, "scripts": { - "test": "mocha -R spec --ui tdd test", - "cover" : "./test/util/cover", - "doc" : "jsdoc lib" + "test": "npm run tsc && mocha -R spec --ui tdd test", + "cover": "./test/util/cover", + "doc": "jsdoc lib", + "tsc": "tsc -p tsconfig.json" } } diff --git a/test/acquire-user-code.js b/test/acquire-user-code.js deleted file mode 100644 index 9ca8ab1..0000000 --- a/test/acquire-user-code.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * @copyright - * Copyright © Microsoft Open Technologies, Inc. - * - * All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http: *www.apache.org/licenses/LICENSE-2.0 - * - * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS - * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION - * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A - * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. - * - * See the Apache License, Version 2.0 for the specific language - * governing permissions and limitations under the License. - */ - -'use strict'; -/* Directive tells jshint that suite and test are globals defined by mocha */ -/* global suite */ -/* global test */ - -var assert = require('assert'); -var nock = require('nock'); -var querystring = require('querystring'); - -var util = require('./util/util'); -var testRequire = util.testRequire; -var cp = util.commonParameters; - -var adal = testRequire('adal'); -var AuthenticationContext = adal.AuthenticationContext; - -suite('acquire-user-code', function() { - function setupExpectedDeviceCodeRequestResponse(withLanguage, httpCode, returnDoc, authorityEndpoint) { - var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); - - var queryParameters = {}; - queryParameters['client_id'] = cp.clientId; - queryParameters['resource'] = cp.resource; - if (withLanguage) { - queryParameters['mkt'] = cp.language; - } - - var query = querystring.stringify(queryParameters); - - var deviceCodeRequest = nock(authEndpoint) - .filteringRequestBody(function(body) { - return util.filterQueryString(query, body); - }) - .post(cp.deviceCodeUrlPath, query) - .reply(httpCode, returnDoc); - - util.matchStandardRequestHeaders(deviceCodeRequest); - - return deviceCodeRequest; - } - - test('happy-path', function (done) { - var response = util.createDeviceCodeResponse(); - var deviceCodeRequest = setupExpectedDeviceCodeRequestResponse(true, 200, response.wireResponse); - - var context = new AuthenticationContext(cp.authUrl); - context.acquireUserCode(cp.resource, cp.clientId, cp.language, function (err, deviceCodeResponse) { - assert(!err, 'Receive unexpected error. '); - assert(util.isMathDeviceCodeResponse(response.decodedResponse, deviceCodeResponse), 'The response did not match what was expected'); - deviceCodeRequest.done(); - done(); - }); - }); - - test('happy-path-without-language', function(done) { - var response = util.createDeviceCodeResponse(); - var deviceCodeRequest = setupExpectedDeviceCodeRequestResponse(false, 200, response.wireResponse); - - var context = new AuthenticationContext(cp.authUrl); - context.acquireUserCode(cp.resource, cp.clientId, null, function (err, deviceCodeResponse) { - assert(!err, 'Receive unexpected error. '); - assert(util.isMathDeviceCodeResponse(response.decodedResponse, deviceCodeResponse), 'The response did not match what was expected'); - deviceCodeRequest.done(); - done(); - }); - }); - - test('failed-http-request', function(done) { - this.timeout(6000); - this.slow(4000); - - nock.enableNetConnect(); - var context = new AuthenticationContext('https://0.0.0.0:11/my.test.tenant.com'); - context.acquireUserCode(cp.resource, cp.clientId, cp.language, function(err) { - assert(err, 'Did not recieve expected error on failed http request.'); - nock.disableNetConnect(); - done(); - }); - }); - - test('bad-argument', function(done) { - var context = new AuthenticationContext(cp.authUrl); - - context.acquireUserCode(null, cp.clientId, cp.language, function(err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The resource parameter is required.') - }); - - context.acquireUserCode(cp.resource, null, cp.language, function(err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The clientId parameter is required.') - }); - - try{ - context.acquireUserCode(cp.resource, cp.clientId, cp.language); - } catch (e) { - assert(e, 'Did not receive expected error. '); - assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); - } - - done(); - }); - -}); \ No newline at end of file diff --git a/test/acquire-user-code.ts b/test/acquire-user-code.ts new file mode 100644 index 0000000..b0fa7d5 --- /dev/null +++ b/test/acquire-user-code.ts @@ -0,0 +1,124 @@ +/* + * @copyright + * Copyright © Microsoft Open Technologies, Inc. + * + * All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: *www.apache.org/licenses/LICENSE-2.0 + * + * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A + * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. + * + * See the Apache License, Version 2.0 for the specific language + * governing permissions and limitations under the License. + */ + +'use strict'; +/* Directive tells jshint that suite and test are globals defined by mocha */ +/* global suite */ +/* global test */ + +import * as assert from "assert"; +import * as nock from "nock"; +import * as querystring from "querystring"; + +import * as adal from "../lib/adal"; +const util = require('./util/util'); +const cp = util.commonParameters; + +const AuthenticationContext = adal.AuthenticationContext; + +suite('acquire-user-code', function () { + function setupExpectedDeviceCodeRequestResponse(withLanguage: boolean, httpCode: number, returnDoc: object, authorityEndpoint?: string) { + var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); + + var queryParameters: any = {}; + queryParameters['client_id'] = cp.clientId; + queryParameters['resource'] = cp.resource; + if (withLanguage) { + queryParameters['mkt'] = cp.language; + } + + var query = querystring.stringify(queryParameters); + + var deviceCodeRequest = nock(authEndpoint) + .filteringRequestBody(function (body: any) { + return util.filterQueryString(query, body); + }) + .post(cp.deviceCodeUrlPath, query) + .reply(httpCode, returnDoc); + + util.matchStandardRequestHeaders(deviceCodeRequest); + + return deviceCodeRequest; + } + + test('happy-path', function (done) { + var response = util.createDeviceCodeResponse(); + var deviceCodeRequest = setupExpectedDeviceCodeRequestResponse(true, 200, response.wireResponse); + + var context = new AuthenticationContext(cp.authUrl); + context.acquireUserCode(cp.resource, cp.clientId, cp.language, function (err, deviceCodeResponse) { + assert(!err, 'Receive unexpected error. '); + assert(util.isMathDeviceCodeResponse(response.decodedResponse, deviceCodeResponse), 'The response did not match what was expected'); + deviceCodeRequest.done(); + done(); + }); + }); + + test('happy-path-without-language', function (done) { + var response = util.createDeviceCodeResponse(); + var deviceCodeRequest = setupExpectedDeviceCodeRequestResponse(false, 200, response.wireResponse); + + var context = new AuthenticationContext(cp.authUrl); + context.acquireUserCode(cp.resource, cp.clientId, null as any, function (err, deviceCodeResponse) { + assert(!err, 'Receive unexpected error. '); + assert(util.isMathDeviceCodeResponse(response.decodedResponse, deviceCodeResponse), 'The response did not match what was expected'); + deviceCodeRequest.done(); + done(); + }); + }); + + test('failed-http-request', function (done) { + this.timeout(6000); + this.slow(4000); + + nock.enableNetConnect(); + var context = new AuthenticationContext('https://0.0.0.0:11/my.test.tenant.com'); + context.acquireUserCode(cp.resource, cp.clientId, cp.language, function (err) { + assert(err, 'Did not recieve expected error on failed http request.'); + nock.disableNetConnect(); + done(); + }); + }); + + test('bad-argument', function (done) { + var context = new AuthenticationContext(cp.authUrl); + + context.acquireUserCode(null as any, cp.clientId, cp.language, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The resource parameter is required.') + }); + + context.acquireUserCode(cp.resource, null as any, cp.language, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The clientId parameter is required.') + }); + + try { + context.acquireUserCode(cp.resource, cp.clientId, cp.language, null as any); + } catch (e) { + assert(e, 'Did not receive expected error. '); + assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); + } + + done(); + }); + +}); \ No newline at end of file diff --git a/test/authentication-parameters.js b/test/authentication-parameters.ts similarity index 68% rename from test/authentication-parameters.js rename to test/authentication-parameters.ts index 2b3e72d..9d538b5 100644 --- a/test/authentication-parameters.js +++ b/test/authentication-parameters.ts @@ -24,19 +24,17 @@ /* global suite */ /* global test */ -var assert = require('assert'); -var nock = require('nock'); -var url = require('url'); +import * as assert from "assert"; +import * as nock from "nock"; +import * as url from "url"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +import * as adal from "../lib/adal"; +const util = require('./util/util'); +const cp: any = util.commonParameters; -var adal = testRequire('adal'); - -suite('authentication-parameters', function() { - function runTestCases(testData, testFunc) { - for(var i = 0; i < testData.length; i++) { +suite('authentication-parameters', function () { + function runTestCases(testData: any[], testFunc: Function) { + for (var i = 0; i < testData.length; i++) { var parameters; var error = null; var testCase = testData[i]; @@ -45,7 +43,7 @@ suite('authentication-parameters', function() { try { parameters = testFunc(testInput); - } catch(err) { + } catch (err) { error = err; } @@ -61,34 +59,34 @@ suite('authentication-parameters', function() { } } - test('create-from-header', function(done) { + test('create-from-header', function (done) { var testData = [ [ 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"', { - 'authorizationUri' : 'test,lkfj,;l,', - 'resource' : 'clark, &^()- q32,shark', + 'authorizationUri': 'test,lkfj,;l,', + 'resource': 'clark, &^()- q32,shark', } ], [ 'Bearer resource="clark, &^()- q32,shark", authorization_uri="test,lkfj,;l,"', { - 'authorizationUri' : 'test,lkfj,;l,', - 'resource' : 'clark, &^()- q32,shark', + 'authorizationUri': 'test,lkfj,;l,', + 'resource': 'clark, &^()- q32,shark', } ], [ 'Bearer authorization_uri="' + cp.authorityTenant + '", resource="' + cp.resource + '"', { - 'authorizationUri' : cp.authorityTenant, - 'resource' : cp.resource, + 'authorizationUri': cp.authorityTenant, + 'resource': cp.resource, } ], [ 'Bearer authorization_uri="' + cp.authorizeUrl + '", resource="' + cp.resource + '"', { - 'authorizationUri' : cp.authorizeUrl, - 'resource' : cp.resource, + 'authorizationUri': cp.authorizeUrl, + 'resource': cp.resource, } ], // Add second = sign on first pair. @@ -155,7 +153,7 @@ suite('authentication-parameters', function() { [ 'Bearer authorization_uri="test,lkfj,;l,"', { - 'authorizationUri' : 'test,lkfj,;l,' + 'authorizationUri': 'test,lkfj,;l,' } ], // Missing authoritzation uri. @@ -178,55 +176,55 @@ suite('authentication-parameters', function() { done(); }); - test('create-from-response', function(done) { + test('create-from-response', function (done) { var testData = [ [ { - statusCode : 401, - headers : { 'www-authenticate' : 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } + statusCode: 401, + headers: { 'www-authenticate': 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } }, { - 'authorizationUri' : 'test,lkfj,;l,', - 'resource' : 'clark, &^()- q32,shark', + 'authorizationUri': 'test,lkfj,;l,', + 'resource': 'clark, &^()- q32,shark', } ], [ { - statusCode : 200, - headers : { 'www-authenticate' : 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } + statusCode: 200, + headers: { 'www-authenticate': 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } }, null ], [ { - statusCode : 401 + statusCode: 401 }, null ], [ { - statusCode : 401, - headers : { 'test' : 'this is not the www-authenticate header' } + statusCode: 401, + headers: { 'test': 'this is not the www-authenticate header' } }, null ], [ { - statusCode : 401, - headers : { 'www-authenticate' : 'Berer authorization_uri=test,lkfj,;l,", resource="clark, &^()- q32,shark",fruitcake="f" , f="test"' } + statusCode: 401, + headers: { 'www-authenticate': 'Berer authorization_uri=test,lkfj,;l,", resource="clark, &^()- q32,shark",fruitcake="f" , f="test"' } }, null ], [ { - statusCode : 401, - headers : { 'www-authenticate' : null } + statusCode: 401, + headers: { 'www-authenticate': null } }, null ], [ { - headers : { 'www-authenticate' : null } + headers: { 'www-authenticate': null } }, null ], @@ -245,23 +243,23 @@ suite('authentication-parameters', function() { var testQuery = 'a=query&string=really'; var testUrl = testHost + testPath + '?' + testQuery; - test('create-from-url-happy-path-string-url', function(done) { + test('create-from-url-happy-path-string-url', function (done) { var getResource = nock(testHost) - .filteringPath(function(path) { - return util.removeQueryStringIfMatching(path, testQuery); - }) - .get(testPath) - .reply(401, 'test', - { 'www-authenticate' : 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } - ); + .filteringPath(function (path) { + return util.removeQueryStringIfMatching(path, testQuery); + }) + .get(testPath) + .reply(401, 'test', + { 'www-authenticate': 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } + ); util.matchStandardRequestHeaders(getResource); - adal.createAuthenticationParametersFromUrl(testUrl, function(err, parameters) { + adal.createAuthenticationParametersFromUrl(testUrl, function (err, parameters) { if (!err) { var testParameters = { - 'authorizationUri' : 'test,lkfj,;l,', - 'resource' : 'clark, &^()- q32,shark', + 'authorizationUri': 'test,lkfj,;l,', + 'resource': 'clark, &^()- q32,shark', }; assert(parameters.authorizationUri === testParameters.authorizationUri, 'Parsed authorizationUri did not match expected value.: ' + parameters.authorizationUri); assert(parameters.resource === testParameters.resource, 'Parsed resource did not match expected value.: ' + parameters.resource); @@ -271,25 +269,25 @@ suite('authentication-parameters', function() { }); }); - test('create-from-url-happy-path-url-object', function(done) { + test('create-from-url-happy-path-url-object', function (done) { var getResource = nock(testHost) - .filteringPath(function(path) { - return util.removeQueryStringIfMatching(path, testQuery); - }) - .get(testPath) - .reply(401, 'test', - { 'www-authenticate' : 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } - ); + .filteringPath(function (path) { + return util.removeQueryStringIfMatching(path, testQuery); + }) + .get(testPath) + .reply(401, 'test', + { 'www-authenticate': 'Bearer authorization_uri="test,lkfj,;l,", fruitcake="f",resource="clark, &^()- q32,shark" , f="test"' } + ); util.matchStandardRequestHeaders(getResource); var urlObj = url.parse(testUrl); - adal.createAuthenticationParametersFromUrl(urlObj, function(err, parameters) { + adal.createAuthenticationParametersFromUrl(urlObj as any, function (err, parameters) { getResource.done(); if (!err) { var testParameters = { - 'authorizationUri' : 'test,lkfj,;l,', - 'resource' : 'clark, &^()- q32,shark', + 'authorizationUri': 'test,lkfj,;l,', + 'resource': 'clark, &^()- q32,shark', }; assert(parameters.authorizationUri === testParameters.authorizationUri, 'Parsed authorizationUri did not match expected value.: ' + parameters.authorizationUri); assert(parameters.resource === testParameters.resource, 'Parsed resource did not match expected value.: ' + parameters.resource); @@ -298,31 +296,31 @@ suite('authentication-parameters', function() { }); }); - test('create-from-url-bad-object', function(done) { - adal.createAuthenticationParametersFromUrl({}, function(err) { + test('create-from-url-bad-object', function (done) { + adal.createAuthenticationParametersFromUrl({} as any, function (err) { assert(err, 'Did not receive expected error'); done(); }); }); - test('create-from-url-not-passed', function(done) { - adal.createAuthenticationParametersFromUrl(null, function(err) { + test('create-from-url-not-passed', function (done) { + adal.createAuthenticationParametersFromUrl(null as any, function (err) { assert(err, 'Did not receive expected error'); done(); }); }); - test('create-from-url-no-header', function(done) { + test('create-from-url-no-header', function (done) { var getResource = nock(testHost) - .filteringPath(function(path) { - return util.removeQueryStringIfMatching(path, testQuery); - }) - .get(testPath) - .reply(401, 'test'); + .filteringPath(function (path) { + return util.removeQueryStringIfMatching(path, testQuery); + }) + .get(testPath) + .reply(401, 'test'); util.matchStandardRequestHeaders(getResource); - adal.createAuthenticationParametersFromUrl(testUrl, function(err) { + adal.createAuthenticationParametersFromUrl(testUrl, function (err) { getResource.done(); assert(err, 'Did not receive expected error'); assert(err.message.indexOf('header') >= 0, 'Error did not include message about missing header'); @@ -333,9 +331,9 @@ suite('authentication-parameters', function() { // This tests enables actual network connections but then attempts a connection to // a completely invalid address. This causes a the node request to fail with // an error rather than returning an HTTP error of some sort. - test('create-from-url-network-error', function(done) { + test('create-from-url-network-error', function (done) { nock.enableNetConnect(); - adal.createAuthenticationParametersFromUrl('https://0.0.0.0/test', function(err) { + adal.createAuthenticationParametersFromUrl('https://0.0.0.0/test', function (err) { assert(err, 'Did not receive expected error'); nock.disableNetConnect(); done(); diff --git a/test/authority.js b/test/authority.ts similarity index 87% rename from test/authority.js rename to test/authority.ts index 27d8deb..118d521 100644 --- a/test/authority.js +++ b/test/authority.ts @@ -25,11 +25,11 @@ /* global setup */ /* global teardown */ -var assert = require('assert'); +import * as assert from "assert"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; var adal = testRequire('adal'); var AuthenticationContext = adal.AuthenticationContext; @@ -55,10 +55,10 @@ suite('Authority', function() { var nonHardCodedAuthorizeEndpoint = nonHardCodedAuthority + '/oauth2/authorize'; - function setupExpectedInstanceDiscoveryRequestRetries(requestParametersList, authority) { - var nocks = []; + function setupExpectedInstanceDiscoveryRequestRetries(requestParametersList: any, authority: any) { + var nocks: any[] = []; - requestParametersList.forEach(function(request) { + requestParametersList.forEach(function(request: any) { nocks.push(util.setupExpectedInstanceDiscoveryRequest(request.httpCode, request.authority, request.returnDoc, authority)); }); @@ -83,7 +83,7 @@ suite('Authority', function() { var tokenRequest = util.setupExpectedClientCredTokenRequestResponse(200, wireResponse, nonHardCodedAuthority); var context = new AuthenticationContext(nonHardCodedAuthority); - context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err, tokenResponse) { + context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err: any, tokenResponse: any) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response does not match what was expected.: ' + JSON.stringify(tokenResponse)); instanceDiscoveryRequest.done(); @@ -93,7 +93,7 @@ suite('Authority', function() { }); }); - function performStaticInstanceDiscovery(authorityHost, callback) { + function performStaticInstanceDiscovery(authorityHost: string, callback: Function) { var hardCodedAuthority = 'https://' + authorityHost + '/' + cp.tenant; var responseOptions = { @@ -104,7 +104,7 @@ suite('Authority', function() { var tokenRequest = util.setupExpectedClientCredTokenRequestResponse(200, wireResponse, hardCodedAuthority); var context = new AuthenticationContext(hardCodedAuthority); - context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err, tokenResponse) { + context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err: any, tokenResponse: any) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response does not match what was expected.: ' + JSON.stringify(tokenResponse)); tokenRequest.done(); @@ -114,27 +114,27 @@ suite('Authority', function() { } test('success-static-instance-discovery', function(done) { - performStaticInstanceDiscovery('login.windows.net', function(err) { + performStaticInstanceDiscovery('login.windows.net', function(err: any) { if(err) { done(err); return; } - performStaticInstanceDiscovery('login.microsoftonline.com', function(err2) { + performStaticInstanceDiscovery('login.microsoftonline.com', function(err2: any) { if(err2) { done(err2); return; } - performStaticInstanceDiscovery('login.chinacloudapi.cn', function(err3) { + performStaticInstanceDiscovery('login.chinacloudapi.cn', function(err3: any) { if(err3) { done(err3); return; } - performStaticInstanceDiscovery('login-us.microsoftonline.com', function(err4) { + performStaticInstanceDiscovery('login-us.microsoftonline.com', function(err4: any) { if(err4) { done(err4); return; } - performStaticInstanceDiscovery('login.microsoftonline.us', function(err5) { + performStaticInstanceDiscovery('login.microsoftonline.us', function(err5: any) { done(err5); }) }); @@ -155,7 +155,7 @@ suite('Authority', function() { var instanceDiscoveryRequests = setupExpectedInstanceDiscoveryRequestRetries(expectedInstanceDiscoveryRequests, nonHardCodedAuthorizeEndpoint); var context = new AuthenticationContext(nonHardCodedAuthority); - context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret, function (err) { + context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret, function (err: any) { assert(err, 'No error was returned when one was expected.'); assert(err.message.indexOf('500') !== -1, 'The http error was not returned'); instanceDiscoveryRequests.forEach(function(request){ @@ -178,7 +178,7 @@ suite('Authority', function() { var instanceDiscoveryRequests = setupExpectedInstanceDiscoveryRequestRetries(expectedInstanceDiscoveryRequests, nonHardCodedAuthorizeEndpoint); var context = new AuthenticationContext(nonHardCodedAuthority); - context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret, function (err) { + context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret, function (err: any) { assert(err, 'No error was returned when one was expected.'); assert(err.message.indexOf('invalid_instance') !== -1, 'The server error was not returned'); assert(err.message.indexOf('instance was invalid') !== -1, 'The server error message was not returned'); @@ -196,7 +196,7 @@ suite('Authority', function() { var tokenRequest = util.setupExpectedClientCredTokenRequestResponse(200, wireResponse, response.authority); var context = new AuthenticationContext(cp.authorityTenant, false); - context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err, tokenResponse) { + context.acquireTokenWithClientCredentials(response.resource, cp.clientId, cp.clientSecret, function (err: any, tokenResponse: any) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response does not match what was expected.'); tokenRequest.done(); @@ -207,33 +207,25 @@ suite('Authority', function() { test('bad-url-not-https', function(done) { var errorThrown; - var context; try { - context = new AuthenticationContext('http://this.is.not.https.com/mytenant.com'); + new AuthenticationContext('http://this.is.not.https.com/mytenant.com'); } catch(err) { errorThrown = err; } - // This makes jshint happy that we haven't assigned a variable that is never uesd. - context = null; - assert(errorThrown, 'AuthenticationContext succeeded when it should have failed.'); assert(errorThrown.message.indexOf('https') >= 0, 'Error message does not mention the need for https: ' + errorThrown.message); done(); }); test('bad-url-has-query', function(done) { - var errorThrown; - var context; + var errorThrown: any; try { - context = new AuthenticationContext(cp.authorityTenant + '?this=should¬=be&here=foo'); + new AuthenticationContext(cp.authorityTenant + '?this=should¬=be&here=foo'); } catch(err) { errorThrown = err; } - // This makes jshint happy that we haven't assigned a variable that is never uesd. - context = null; - assert(errorThrown, 'AuthenticationContext succeeded when it should have failed.'); assert(errorThrown.message.indexOf('query') >= 0, 'Error message does not mention the offending query string: ' + errorThrown.message); done(); @@ -254,7 +246,7 @@ suite('Authority', function() { var authorityUrl = nonHardCodedAuthority + '/extra/path'; var authority = new Authority(authorityUrl, true); var obj = util.createEmptyADALObject(); - authority.validate(obj._callContext, function(err) { + authority.validate(obj._callContext, function(err: any) { if (err) { assert(!err, 'Received unexpected error: ' + err.stack); } diff --git a/test/authorization-code.js b/test/authorization-code.ts similarity index 77% rename from test/authorization-code.js rename to test/authorization-code.ts index d183be7..a460b96 100644 --- a/test/authorization-code.js +++ b/test/authorization-code.ts @@ -24,28 +24,26 @@ /* global suite */ /* global test */ -var assert = require('assert'); -var nock = require('nock'); -var querystring = require('querystring'); +import * as assert from "assert"; +import * as nock from "nock"; +import * as querystring from "querystring"; -var util = require('./util/util'); -var testRequire = util.testRequire; -var cp = util.commonParameters; - -var adal = testRequire('adal'); +import * as adal from "../lib/adal"; +const util = require('./util/util'); +const cp: any = util.commonParameters; var AuthenticationContext = adal.AuthenticationContext; /** * Tests AuthenticationContext.acquireTokenWithAuthorizationCode */ -suite('authorization-code', function() { +suite('authorization-code', function () { var authorizationCode = '1234870909'; var redirectUri = 'app_bundle:test.bar.baz'; - function setupExpectedAuthCodeTokenRequestResponse(httpCode, returnDoc, authorityEndpoint) { + function setupExpectedAuthCodeTokenRequestResponse(httpCode: number, returnDoc: object, authorityEndpoint?: string) { var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'authorization_code'; queryParameters['code'] = authorizationCode; queryParameters['client_id'] = cp.clientId; @@ -56,18 +54,18 @@ suite('authorization-code', function() { var query = querystring.stringify(queryParameters); var tokenRequest = nock(authEndpoint) - .filteringRequestBody(function(body) { - return util.filterQueryString(query, body); - }) - .post(cp.tokenUrlPath, query) - .reply(httpCode, returnDoc); + .filteringRequestBody(function (body) { + return util.filterQueryString(query, body); + }) + .post(cp.tokenUrlPath, query) + .reply(httpCode, returnDoc); util.matchStandardRequestHeaders(tokenRequest); return tokenRequest; } - test('happy-path', function(done) { + test('happy-path', function (done) { var response = util.createResponse(); var tokenRequest = setupExpectedAuthCodeTokenRequestResponse(200, response.wireResponse); @@ -81,7 +79,7 @@ suite('authorization-code', function() { }); }); - test('failed-http-request', function(done) { + test('failed-http-request', function (done) { this.timeout(6000); this.slow(4000); // This test takes longer than I would like to fail. It probably needs a better way of producing this error. @@ -94,9 +92,9 @@ suite('authorization-code', function() { }); }); - test('bad-argument', function(done) { + test('bad-argument', function (done) { var context = new AuthenticationContext(cp.authUrl); - context.acquireTokenWithAuthorizationCode(authorizationCode, redirectUri, null, cp.clientId, cp.clientSecret, function (err) { + context.acquireTokenWithAuthorizationCode(authorizationCode, redirectUri, null as any, cp.clientId, cp.clientSecret, function (err) { assert(err, 'Did not receive expected argument error.'); done(); }); diff --git a/test/cache-driver.js b/test/cache-driver.ts similarity index 87% rename from test/cache-driver.js rename to test/cache-driver.ts index fed27c0..c9d5801 100644 --- a/test/cache-driver.js +++ b/test/cache-driver.ts @@ -25,17 +25,16 @@ /* global test */ -var _ = require('underscore'); -var async = require('async'); +import * as _ from "underscore"; +import * as assert from "assert"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const async = require("async"); +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var assert = require('assert'); - -var MemoryCache = testRequire('memory-cache'); -var CacheDriver = testRequire('cache-driver'); +const MemoryCache = testRequire('memory-cache'); +const CacheDriver = testRequire('cache-driver'); suite('CacheDriver', function() { @@ -43,7 +42,7 @@ suite('CacheDriver', function() { assert(false, 'Unexpected attempt to refresh a token.'); } - function assertEntriesEqual(expected, received, message) { + function assertEntriesEqual(expected: any, received: any, message: string) { if (!_.isEqual(expected, received)) { util.findDiffs(expected, received); console.log('Expected:'); @@ -59,7 +58,7 @@ suite('CacheDriver', function() { * take in to account the different ways that MRRT is indicated when a cache entry is submitted to the cache * and once it is in the cache. */ - function compareInputAndCache(input, cache, numMRRTTokens, mrrtRefreshToken) { + function compareInputAndCache(input: any, cache: any, numMRRTTokens: any, mrrtRefreshToken?: any) { var foundNumMRRTTokens = 0; var cacheEntries = cache._entries; var authority = cp.authorityTenant; @@ -108,7 +107,7 @@ suite('CacheDriver', function() { var memCache = new MemoryCache(); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, response.authority, response.resource, response.clientId, memCache, unexpectedRefreshFunction); - cacheDriver.add(response.decodedResponse, function(err) { + cacheDriver.add(response.decodedResponse, function(err: any) { var stack = err ? err.stack : null; assert(!err, 'Received unexpected error: ' + stack); var length = memCache._entries.length; @@ -125,7 +124,7 @@ suite('CacheDriver', function() { var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, response.authority, response.resource, cp.clientId, null, unexpectedRefreshFunction); - cacheDriver.add(response.decodedResponse, function(err) { + cacheDriver.add(response.decodedResponse, function(err: any) { var stack = err ? err.stack : null; assert(!err, 'Received unexpected error: ' + stack); done(); @@ -143,7 +142,7 @@ suite('CacheDriver', function() { var memCache = new MemoryCache(); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, response.authority, resource, cp.clientId, memCache, unexpectedRefreshFunction); - cacheDriver.add(response.decodedResponse, function(err) { + cacheDriver.add(response.decodedResponse, function(err: any) { var stack = err ? err.stack : null; assert(!err, 'Received unexpected error: ' + stack); var length = memCache._entries.length; @@ -160,18 +159,18 @@ suite('CacheDriver', function() { * be smaller than numEntries. * @param {Function} callback returns an object with the CacheDriver etc... */ - function fillCache(numEntries, numMrrt, addExpired, callback) { + function fillCache(numEntries: any, numMrrt: any, addExpired: any, callback: any) { var fakeTokenRequest = util.createEmptyADALObject(); var memCache = new MemoryCache(); var authority = cp.authorityTenant; - var responses = []; + var responses: any = []; var divisor = Math.floor(numEntries / numMrrt); - var finalMrrt; - var expiredEntry; + var finalMrrt: any; + var expiredEntry: any; for (var i = 0; i < numEntries; i++) { - var responseOptions = { authority : cp.authorityTenant}; + var responseOptions: any = { authority : cp.authorityTenant}; if (numMrrt && ((i + 1) % divisor) === 0) { responseOptions.mrrt = true; } else if (addExpired) { @@ -184,15 +183,15 @@ suite('CacheDriver', function() { } var count = 0; - var finalRefreshToken; + var finalRefreshToken: any; async.whilst( function() { return count < numEntries; }, - function(callback) { + function(callback: any) { var resource = responses[count].resource; var clientId = responses[count].clientId; var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, authority, resource, clientId, memCache, unexpectedRefreshFunction); var responseToAdd = _.clone(responses[count].decodedResponse); - cacheDriver.add(responseToAdd, function(err) { + cacheDriver.add(responseToAdd, function(err: any) { count++; process.nextTick(function() { callback(err); @@ -200,7 +199,7 @@ suite('CacheDriver', function() { }); }); }, - function(err) { + function(err: any) { var cachedResponses = []; for (var j = 0; j < responses.length; j++) { cachedResponses.push(responses[j].cachedResponse); @@ -222,7 +221,7 @@ suite('CacheDriver', function() { test('add-multiple-entries-ensure-authority-respected', function(done) { var numMRRTTokens = 6; - fillCache(20, numMRRTTokens, false, function(err, testValues) { + fillCache(20, numMRRTTokens, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -243,15 +242,15 @@ suite('CacheDriver', function() { // the refresh token of the entries with the same authority. // update: with mega refresh token(cross tenant RT), refresh token of the entry will be updated if there is a match with userId, clientId. var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, otherAuthority, differentAuthorityResponse.resource, differentAuthorityResponse.clientId, memCache, unexpectedRefreshFunction); - cacheDriver.add(differentAuthorityResponse.decodedResponse, function(err) { + cacheDriver.add(differentAuthorityResponse.decodedResponse, function(err: any) { assert(!err, 'Unexpected err adding entry with different authority.'); var cacheDriver2 = new CacheDriver(fakeTokenRequest._callContext, cp.authorityTenant, extraMRRTResponse.resource, extraMRRTResponse.clientId, memCache, unexpectedRefreshFunction); - cacheDriver2.add(extraMRRTResponse.decodedResponse, function(err2) { + cacheDriver2.add(extraMRRTResponse.decodedResponse, function(err2: any) { assert(!err2, 'Unexpected error adding second entry with previous authority.'); // ensure that we only find the mrrt with the different authority. - cacheDriver.find( { resource : differentAuthorityResponse.resource}, function(err3, entry) { + cacheDriver.find( { resource : differentAuthorityResponse.resource}, function(err3: any, entry: any) { assert(!err3, 'Unexpected error returned from find.'); assertEntriesEqual(differentAuthorityResponse.cachedResponse, entry, 'Queried entry did not match expected indicating authority was not respected'); }); @@ -264,7 +263,7 @@ suite('CacheDriver', function() { test('add-multiple-entries-find-non-mrrt', function(done) { var numMRRTTokens = 6; - fillCache(20, numMRRTTokens, false, function(err, testValues) { + fillCache(20, numMRRTTokens, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -272,9 +271,9 @@ suite('CacheDriver', function() { if (!err) { compareInputAndCache(responses, memCache, numMRRTTokens); - var findResponse = _.find(responses, function(entry) { return !entry.isMRRT; }); + var findResponse = _.find(responses, function(entry: any) { return !entry.isMRRT; }); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, cp.authorityTenant, findResponse.resource, findResponse.clientId, memCache, unexpectedRefreshFunction); - cacheDriver.find({}, function(err, entry) { + cacheDriver.find({}, function(err: any, entry: any) { if (!err) { assert(entry, 'Find did not return any entry'); assertEntriesEqual(findResponse, entry, 'Queried entry did not match expected: ' + JSON.stringify(entry)); @@ -291,7 +290,7 @@ suite('CacheDriver', function() { test('add-multiple-entries-mrrt', function(done) { var numMRRTTokens = 6; - fillCache(19, numMRRTTokens, false, function(err, testValues) { + fillCache(19, numMRRTTokens, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var finalMrrt = testValues.finalMrrt; @@ -312,7 +311,8 @@ suite('CacheDriver', function() { // correctly. test('add-multiple-entries-mrrt-different-users--url-safe-id_token', function(done) { var numMRRTTokens = 6; - fillCache(19, numMRRTTokens, false, function(err, testValues) { + fillCache(19, numMRRTTokens, false, function(err: any, testValues: any) { + err; var responses = testValues.cachedResponses; var memCache = testValues.memCache; var finalMrrt = testValues.finalMrrt; @@ -329,7 +329,7 @@ suite('CacheDriver', function() { responses.push(refreshedResponse.cachedResponse); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, testValues.authority, refreshedResponse.resource, refreshedResponse.clientId, memCache, unexpectedRefreshFunction); - cacheDriver.add(refreshedResponse.decodedResponse, function(err) { + cacheDriver.add(refreshedResponse.decodedResponse, function(err: any) { if (!err) { compareInputAndCache(responses, memCache, numMRRTTokens + 1, finalMrrt); } @@ -341,18 +341,18 @@ suite('CacheDriver', function() { test('add-multiple-entries-find-mrrt', function(done) { var numMRRTTokens = 6; - fillCache(20, numMRRTTokens, false, function(err, testValues) { + fillCache(20, numMRRTTokens, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; - var mrrtEntry = _.findWhere(memCache._entries, { isMRRT : true }); + var mrrtEntry: any = _.findWhere(memCache._entries, { isMRRT : true }); if (!err) { compareInputAndCache(responses, memCache, numMRRTTokens); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, cp.authorityTenant, mrrtEntry.resource, mrrtEntry._clientId, memCache, unexpectedRefreshFunction); - cacheDriver.find({}, function(err, entry) { + cacheDriver.find({}, function(err: any, entry: any) { if (!err) { assert(entry, 'Find did not return any entry'); assertEntriesEqual(mrrtEntry, entry, 'Queried entry did not match expected: ' + JSON.stringify(entry)); @@ -367,8 +367,9 @@ suite('CacheDriver', function() { }); }); - function createRefreshFunction(expectedRefreshToken, response) { - var refreshFunction = function(entry, resource, callback) { + function createRefreshFunction(expectedRefreshToken: any, response: any) { + var refreshFunction = function(entry: any, resource: any, callback: any) { + resource; if (expectedRefreshToken !== entry['refreshToken']) { console.log('RECEIVED:'); console.log(entry.refreshToken); @@ -386,7 +387,7 @@ suite('CacheDriver', function() { test('add-multiple-entries-mrrt-find-refreshed-mrrt', function(done) { var numMRRTTokens = 5; - fillCache(20, 5, false, function(err, testValues) { + fillCache(20, 5, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -405,7 +406,7 @@ suite('CacheDriver', function() { responses.push(refreshedResponse.cachedResponse); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, authority, unknownResource, cp.clientId, memCache, refreshFunction); - cacheDriver.find(null, function(err, entry) { + cacheDriver.find(null, function(err: any, entry: any) { if (!err) { assert(entry, 'Expected a matching entry, but none was returned.'); assert(entry.resource === unknownResource, 'Unexpected resource returned:' + entry.resource); @@ -417,7 +418,7 @@ suite('CacheDriver', function() { userId : entry.userId, clientId : cp.clientId }; - cacheDriver.find(query, function(err, recentlyCachedEntry) { + cacheDriver.find(query, function(err: any, recentlyCachedEntry: any) { if (!err) { assert(recentlyCachedEntry, 'Expected a returned entry but none was returned.'); assertEntriesEqual(entry, recentlyCachedEntry, 'Token returned from cache was not the same as the one that was recently cached.'); @@ -440,7 +441,7 @@ suite('CacheDriver', function() { test('add-multiple-entries-failed-mrrt-refresh', function(done) { var numMRRTTokens = 5; - fillCache(20, 5, false, function(err, testValues) { + fillCache(20, 5, false, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -448,13 +449,13 @@ suite('CacheDriver', function() { var authority = testValues.authority; var unknownResource = 'unknownResource'; - var refreshFunction = function(entry, resource, callback) { callback(new Error('FAILED REFRESH')); }; + var refreshFunction = function(entry: any, resource: any, callback: any) { entry; resource; callback(new Error('FAILED REFRESH')); }; if (!err) { compareInputAndCache(responses, memCache, numMRRTTokens, finalMrrt); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, authority, unknownResource, cp.clientId, memCache, refreshFunction); - cacheDriver.find(null, function(err) { + cacheDriver.find(null, function(err: any) { assert(err, 'Did not receive expected error.'); assert(-1 !== err.message.indexOf('FAILED REFRESH'), 'Error message did not contain correct text'); compareInputAndCache(responses, memCache, numMRRTTokens, finalMrrt); @@ -468,7 +469,7 @@ suite('CacheDriver', function() { }); }); - function removeResponse(collection, response) { + function removeResponse(collection: any, response: any) { return _.filter(collection, function(entry) { if (_.isEqual(response, entry)) { return false; @@ -479,7 +480,7 @@ suite('CacheDriver', function() { test('expired-access-token', function(done) { var numMRRTTokens = 5; - fillCache(20, 5, true, function(err, testValues) { + fillCache(20, 5, true, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -498,7 +499,7 @@ suite('CacheDriver', function() { responses = removeResponse(responses, expiredEntry); responses.push(refreshedResponse.cachedResponse); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, authority, expiredEntry.resource, cp.clientId, memCache, refreshFunction); - cacheDriver.find(null, function(err, entry) { + cacheDriver.find(null, function(err: any, entry: any) { if (!err) { assert(entry, 'Expected a matching entry, but none was returned.'); assert(entry.resource === expiredEntry.resource, 'Unexpected resource returned:' + entry.resource); @@ -510,7 +511,7 @@ suite('CacheDriver', function() { userId : entry.userId, clientId : cp.clientId }; - cacheDriver.find(query, function(err, recentlyCachedEntry) { + cacheDriver.find(query, function(err: any, recentlyCachedEntry: any) { if (!err) { assert(recentlyCachedEntry, 'Expected a returned entry but none was returned.'); assertEntriesEqual(entry, recentlyCachedEntry, 'Token returned from cache was not the same as the one that was recently cached.'); @@ -533,7 +534,7 @@ suite('CacheDriver', function() { test('expired-access-token-failed-refresh', function(done) { var numMRRTTokens = 5; - fillCache(20, 5, true, function(err, testValues) { + fillCache(20, 5, true, function(err: any, testValues: any) { var responses = testValues.cachedResponses; var memCache = testValues.memCache; var fakeTokenRequest = testValues.fakeTokenRequest; @@ -541,13 +542,12 @@ suite('CacheDriver', function() { var expiredEntry = testValues.expiredEntry.cachedResponse; var finalMrrt = testValues.finalMrrt; - var refreshFunction = function(entry, resource, callback) { callback(new Error('FAILED REFRESH')); }; - + var refreshFunction = function(entry: any, resource: any, callback: any) { entry; resource; callback(new Error('FAILED REFRESH')); }; if (!err) { compareInputAndCache(responses, memCache, numMRRTTokens, finalMrrt); var cacheDriver = new CacheDriver(fakeTokenRequest._callContext, authority, expiredEntry.resource, cp.clientId, memCache, refreshFunction); - cacheDriver.find(null, function(err) { + cacheDriver.find(null, function(err: any) { assert(err, 'Did not receive expected error about failed refresh.'); assert(-1 !== err.message.indexOf('FAILED REFRESH'), 'Error message did not contain correct text'); compareInputAndCache(responses, memCache, numMRRTTokens, finalMrrt); diff --git a/test/client-credential.js b/test/client-credential.ts similarity index 92% rename from test/client-credential.js rename to test/client-credential.ts index 1e822bc..c21631e 100644 --- a/test/client-credential.js +++ b/test/client-credential.ts @@ -26,16 +26,16 @@ /* global setup */ /* global teardown */ -var _ = require('underscore'); -var assert = require('assert'); +import * as _ from "underscore"; +import * as assert from "assert"; -var util = require('./util/util'); -var testRequire = util.testRequire; -var cp = util.commonParameters; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var adal = testRequire('adal'); -var AuthenticationContext = adal.AuthenticationContext; -var SelfSignedJwt = testRequire('self-signed-jwt'); +import * as adal from "../lib/adal"; +const AuthenticationContext = adal.AuthenticationContext; +const SelfSignedJwt = testRequire('self-signed-jwt'); /** * Tests AuthenticationContext.acquireTokenWithClientCredentials @@ -112,7 +112,7 @@ suite('client-credential', function() { var nullUser = null; var context2 = new AuthenticationContext(cp.authUrl); - context2.acquireToken(response.resource, nullUser, cp.clientId, function (err, tokenResponse) { + context2.acquireToken(response.resource, nullUser as any, cp.clientId, function (err, tokenResponse) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The cached response did not match what was expected'); } @@ -125,7 +125,7 @@ suite('client-credential', function() { var context = new AuthenticationContext(cp.authorityTenant); var argumentError; try { - context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret); + context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, cp.clientSecret, null as any); } catch(err) { argumentError = err; } @@ -138,7 +138,7 @@ suite('client-credential', function() { test('no-arguments', function(done) { var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithClientCredentials(null, null, null, function(err) { + context.acquireTokenWithClientCredentials(null as any, null as any, null as any, function(err) { assert(err, 'Did not receive expected error.'); assert(err.message.indexOf('parameter') >= 0, 'Error was not specific to a parameter.'); done(); @@ -147,7 +147,7 @@ suite('client-credential', function() { test('no-client-secret', function(done) { var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, null, function(err) { + context.acquireTokenWithClientCredentials(cp.resource, cp.clientId, null as any, function(err) { assert(err, 'Did not receive expected error.'); assert(err.message.indexOf('parameter') >= 0, 'Error was not specific to a parameter.'); done(); @@ -156,7 +156,7 @@ suite('client-credential', function() { test('no-client-id', function(done) { var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithClientCredentials(cp.resource, null, cp.clientSecret, function(err) { + context.acquireTokenWithClientCredentials(cp.resource, null as any, cp.clientSecret, function(err) { assert(err, 'Did not receive expected error.'); assert(err.message.indexOf('parameter') >= 0, 'Error was not specific to a parameter.'); done(); @@ -165,7 +165,7 @@ suite('client-credential', function() { test('no-resource', function(done) { var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithClientCredentials(null, cp.clientId, cp.clientSecret, function(err) { + context.acquireTokenWithClientCredentials(null as any, cp.clientId, cp.clientSecret, function(err) { assert(err, 'Did not receive expected error.'); assert(err.message.indexOf('parameter') >= 0, 'Error was not specific to a parameter.'); done(); @@ -237,7 +237,7 @@ suite('client-credential', function() { }); function updateSelfSignedJwtStubs() { - var savedProto = {}; + var savedProto: any = {}; savedProto._getDateNow = SelfSignedJwt.prototype._getDateNow; savedProto._getNewJwtId = SelfSignedJwt.prototype._getNewJwtId; @@ -247,7 +247,7 @@ suite('client-credential', function() { return savedProto; } - function resetSelfSignedJwtStubs(saveProto) { + function resetSelfSignedJwtStubs(saveProto: any) { _.extend(SelfSignedJwt.prototype, saveProto); } diff --git a/test/device-code.js b/test/device-code.js deleted file mode 100644 index 5abd36f..0000000 --- a/test/device-code.js +++ /dev/null @@ -1,261 +0,0 @@ -/* - * @copyright - * Copyright © Microsoft Open Technologies, Inc. - * - * All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http: *www.apache.org/licenses/LICENSE-2.0 - * - * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS - * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION - * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A - * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. - * - * See the Apache License, Version 2.0 for the specific language - * governing permissions and limitations under the License. - */ - -'use strict'; -/* Directive tells jshint that suite and test are globals defined by mocha */ -/* global suite */ -/* global test */ - -var assert = require('assert'); -var nock = require('nock'); -var querystring = require('querystring'); -var url = require('url'); - -var util = require('./util/util'); -var testRequire = util.testRequire; -var cp = util.commonParameters; - -var adal = testRequire('adal'); -var MemoryCache = testRequire('memory-cache'); -var AuthenticationContext = adal.AuthenticationContext; - -suite('device-code', function () { - setup(function () { - util.resetLogging(); - util.clearStaticCache(); - }); - - function setupExpectedTokenRequestResponse(httpCode, returnDoc, authorityEndpoint, extraQP) { - var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); - - var queryParameters = {}; - queryParameters['grant_type'] = 'device_code'; - queryParameters['client_id'] = cp.clientId; - queryParameters['resource'] = cp.resource; - queryParameters['code'] = cp.deviceCode; - - var query = querystring.stringify(queryParameters); - - var tokenRequest = nock(authEndpoint) - .filteringRequestBody(function (body) { - return util.filterQueryString(query, body); - }) - .post(cp.tokenUrlPath, query) - .reply(httpCode, returnDoc); - - util.matchStandardRequestHeaders(tokenRequest); - - return tokenRequest; - } - - test('happy-path-successOnFirstRequest', function (done) { - var response = util.createResponse(); - var tokenRequest = setupExpectedTokenRequestResponse(200, response.wireResponse); - - var userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 1 }; - var context = new AuthenticationContext(cp.authUrl); - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { - assert(!err, 'Receive unexpected error'); - tokenRequest.done(); - done(err); - }); - }); - - function setupExpectedTokenRequestResponseWithAuthPending(returnDoc, authorityEndpoint) { - var authEndpoint = util.getNockAuthorityHost(); - - var queryParameter = {}; - queryParameter['grant_type'] = 'device_code'; - queryParameter['client_id'] = cp.clientId; - queryParameter['resource'] = cp.resource; - queryParameter['code'] = cp.deviceCode; - var query = querystring.stringify(queryParameter); - - var authPendingResponse = { error: 'authorization_pending'}; - - var tokenRequest = nock(authEndpoint) - .filteringRequestBody(function(body) { - return util.filterQueryString(query, body); - }) - .post(cp.tokenUrlPath, query) - .reply(400, authPendingResponse) - .post(cp.tokenUrlPath, query) - .reply(200, returnDoc); - - util.matchStandardRequestHeaders(tokenRequest); - - return tokenRequest; - } - - test('happy-path-pendingOnFirstRequest', function (done) { - var response = util.createResponse(); - var tokenRequest = setupExpectedTokenRequestResponseWithAuthPending(response.wireResponse); - - var userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; - var context = new AuthenticationContext(cp.authUrl); - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { - if (!err) { - assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); - tokenRequest.done(); - } - done(err); - }); - }); - - test('happy-path-cancelRequest', function (done) { - nock.cleanAll(); - var response = util.createResponse(); - var tokenRequest = setupExpectedTokenRequestResponseWithAuthPending(response.wireResponse); - - var userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; - var context = new AuthenticationContext(cp.authUrl); - - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { - assert(err, 'Did not receive expected error'); - assert(err.message === 'Polling_Request_Cancelled'); - done(); - }); - - context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function(err) { - assert(!err, 'Receive unexpected error.') - }); - }); - - test('bad-argument', function (done) { - nock.cleanAll(); - var context = new AuthenticationContext(cp.authUrl); - - var userCodeInfo = { interval: 5, expiresIn: 1000}; - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo is missing device_code'); - }); - - userCodeInfo = { deviceCode: 'test_device_code', expiresIn: 1000 }; - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo is missing interval'); - }); - - userCodeInfo = { deviceCode: 'test_device_code', interval: 5 }; - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo is missing expires_in'); - }); - - // test if usercodeInfo is null - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, null, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo parameter is required'); - }); - - userCodeInfo = { deviceCode: 'test_device_code', interval: 5, expiresIn: 1000 }; - try { - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo); - } catch (e) { - assert(e, 'Did not receive expected error. '); - assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); - } - - userCodeInfo = { deviceCode: 'test_device_code', interval: 0, expiresIn: 1000 }; - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { - assert(err, 'Did not receive expected error.'); - assert(err.message === 'invalid refresh interval'); - }); - - done(); - }); - - test('bad-argument-cancel-request', function (done) { - var context = new AuthenticationContext(cp.authUrl); - - var userCodeInfo = { interval: 5, expiresIn: 1000 }; - context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo is missing device_code'); - }); - - // test if usercodeInfo is null - context.cancelRequestToGetTokenWithDeviceCode(null, function (err) { - assert(err, 'Did not receive expected argument error'); - assert(err.message === 'The userCodeInfo parameter is required'); - }); - - userCodeInfo = { deviceCode: 'test_device_code', interval: 5, expiresIn: 1000 }; - try { - context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo); - } catch (e) { - assert(e, 'Did not receive expected error. '); - assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); - } - - userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; - context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function (err) { - assert(err, 'Did not receive expected error. '); - assert(err.message === 'No acquireTokenWithDeviceCodeRequest existed to be cancelled', 'Unexpected error message returned.'); - }) - - done(); - }); - - test('cross-tenant-refresh-token', function (done) { - var memCache = new MemoryCache(); - var response = util.createResponse({mrrt: true}); - var tokenRequest = setupExpectedTokenRequestResponse(200, response.wireResponse); - - var userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 1 }; - var context = new AuthenticationContext(cp.authUrl, false, memCache); - context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { - assert(!err, 'Receive unexpected error'); - - var someOtherAuthority = url.parse(cp.evoEndpoint + '/' + 'anotherTenant'); - var responseOptions = { refreshedRefresh : true, mrrt: true}; - var response = util.createResponse(responseOptions); - var wireResponse = response.wireResponse; - wireResponse.id_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9jY2ViYTE0Yy02YTAwLTQ5YWMtYjgwNi04NGRlNTJiZjFkNDIvIiwiaWF0IjpudWxsLCJleHAiOm51bGwsImF1ZCI6ImU5NThjMDlhLWFjMzctNDkwMC1iNGQ3LWZiM2VlYWY3MzM4ZCIsInN1YiI6IjRnVHY0RXRvWVctRFRvdzBiRG5KZDFBQTRzZkNoQmJqZXJtcXQ2UV9aYTQiLCJ0aWQiOiJkM2I3ODEzZC0zYTAzLTQyZmEtODk2My1iOTBhNzQ1NTIyYTUiLCJvaWQiOiJhNDQzMjA0YS1hYmM5LTRjYjgtYWRjMS1jMGRmYzEyMzAwYWEiLCJ1cG4iOiJycmFuZGFsbEBycmFuZGFsbGFhZDEub25taWNyb3NvZnQuY29tIiwidW5pcXVlX25hbWUiOiJycmFuZGFsbEBycmFuZGFsbGFhZDEub25taWNyb3NvZnQuY29tIiwiZmFtaWx5X25hbWUiOiJSYW5kYWxsIiwiZ2l2ZW5fbmFtZSI6IlJpY2gifQ.r-XHRqqtxI_7IEmwciFTBJpzwetz4wrM2Is_Z8-O7lw"; - //need to change tokenUrlPath for the different tenant token request, and make sure get it changed back to not affect other tests - var tokenUrlPath = cp.tokenUrlPath; - cp.tokenUrlPath = someOtherAuthority.pathname + cp.tokenPath + cp.extraQP; - - var refreshRequest = util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, someOtherAuthority, response.resource); - cp.tokenUrlPath = tokenUrlPath; - var conextForAnotherAuthority = new AuthenticationContext(someOtherAuthority, false, memCache); - - conextForAnotherAuthority.acquireToken(response.resource, tokenResponse.userId, response.clientId, function (error, tokenResponseForAnotherAuthority) { - assert(!error, 'Receive unexpected error'); - - assert(memCache._entries.length === 2, 'There should two cache entries in the cache'); - memCache.find({userId: tokenResponse.userId, _clientId: response.clientId, _authority: cp.evoEndpoint + '/' + cp.tenant}, function (err, entry) { - assert(!err, 'Unexpected error received'); - assert(entry.length === 1, 'no result returned for given tenant.'); - assert(entry[0].tenantId === 'cceba14c-6a00-49ac-b806-84de52bf1d42'); - }); - - memCache.find({userId: tokenResponse.userId, _clientId: response.clientId, _authority: url.format(someOtherAuthority)}, function (err, entry) { - assert(!err, 'unexpected error received'); - assert(entry.length === 1, 'no result returned for given tenant.'); - assert(entry[0].tenantId === 'd3b7813d-3a03-42fa-8963-b90a745522a5'); - }); - done(err); - }); - }); - }); -}); \ No newline at end of file diff --git a/test/device-code.ts b/test/device-code.ts new file mode 100644 index 0000000..1f79e11 --- /dev/null +++ b/test/device-code.ts @@ -0,0 +1,259 @@ +/* + * @copyright + * Copyright © Microsoft Open Technologies, Inc. + * + * All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: *www.apache.org/licenses/LICENSE-2.0 + * + * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A + * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. + * + * See the Apache License, Version 2.0 for the specific language + * governing permissions and limitations under the License. + */ + +'use strict'; +/* Directive tells jshint that suite and test are globals defined by mocha */ +/* global suite */ +/* global test */ + +import * as assert from "assert"; +import * as nock from "nock"; +import * as querystring from "querystring"; +import * as url from "url"; + +import * as adal from "../lib/adal"; +const util = require('./util/util'); +const cp: any = util.commonParameters; +const AuthenticationContext = adal.AuthenticationContext; +const MemoryCache = adal.MemoryCache; + +suite('device-code', function () { + setup(function () { + util.resetLogging(); + util.clearStaticCache(); + }); + + function setupExpectedTokenRequestResponse(httpCode: number, returnDoc: object, authorityEndpoint?: string) { + var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); + + var queryParameters: any = {}; + queryParameters['grant_type'] = 'device_code'; + queryParameters['client_id'] = cp.clientId; + queryParameters['resource'] = cp.resource; + queryParameters['code'] = cp.deviceCode; + + var query = querystring.stringify(queryParameters); + + var tokenRequest = nock(authEndpoint) + .filteringRequestBody(function (body) { + return util.filterQueryString(query, body); + }) + .post(cp.tokenUrlPath, query) + .reply(httpCode, returnDoc); + + util.matchStandardRequestHeaders(tokenRequest); + + return tokenRequest; + } + + test('happy-path-successOnFirstRequest', function (done) { + var response = util.createResponse(); + var tokenRequest = setupExpectedTokenRequestResponse(200, response.wireResponse); + + var userCodeInfo: any = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 1 }; + var context = new AuthenticationContext(cp.authUrl); + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo as any, function (err) { + assert(!err, 'Receive unexpected error'); + tokenRequest.done(); + done(err); + }); + }); + + function setupExpectedTokenRequestResponseWithAuthPending(returnDoc: object) { + var authEndpoint = util.getNockAuthorityHost(); + + var queryParameter: any = {}; + queryParameter['grant_type'] = 'device_code'; + queryParameter['client_id'] = cp.clientId; + queryParameter['resource'] = cp.resource; + queryParameter['code'] = cp.deviceCode; + var query = querystring.stringify(queryParameter); + + var authPendingResponse = { error: 'authorization_pending' }; + + var tokenRequest = nock(authEndpoint) + .filteringRequestBody(function (body) { + return util.filterQueryString(query, body); + }) + .post(cp.tokenUrlPath, query) + .reply(400, authPendingResponse) + .post(cp.tokenUrlPath, query) + .reply(200, returnDoc); + + util.matchStandardRequestHeaders(tokenRequest); + + return tokenRequest; + } + + test('happy-path-pendingOnFirstRequest', function (done) { + var response = util.createResponse(); + var tokenRequest = setupExpectedTokenRequestResponseWithAuthPending(response.wireResponse); + + var userCodeInfo: any = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; + var context = new AuthenticationContext(cp.authUrl); + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { + if (!err) { + assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); + tokenRequest.done(); + } + done(err); + }); + }); + + test('happy-path-cancelRequest', function (done) { + nock.cleanAll(); + var response = util.createResponse(); + setupExpectedTokenRequestResponseWithAuthPending(response.wireResponse); + + var userCodeInfo: any = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; + var context = new AuthenticationContext(cp.authUrl); + + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { + assert(err, 'Did not receive expected error'); + assert(err.message === 'Polling_Request_Cancelled'); + done(); + }); + + context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function (err) { + assert(!err, 'Receive unexpected error.') + }); + }); + + test('bad-argument', function (done) { + nock.cleanAll(); + var context = new AuthenticationContext(cp.authUrl); + + let userCodeInfo: any = { interval: 5, expiresIn: 1000 }; + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo is missing device_code'); + }); + + userCodeInfo = { deviceCode: 'test_device_code', expiresIn: 1000 }; + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo is missing interval'); + }); + + userCodeInfo = { deviceCode: 'test_device_code', interval: 5 }; + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo is missing expires_in'); + }); + + // test if usercodeInfo is null + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, null as any, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo parameter is required'); + }); + + userCodeInfo = { deviceCode: 'test_device_code', interval: 5, expiresIn: 1000 }; + try { + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, null as any); + } catch (e) { + assert(e, 'Did not receive expected error. '); + assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); + } + + userCodeInfo = { deviceCode: 'test_device_code', interval: 0, expiresIn: 1000 }; + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err) { + assert(err, 'Did not receive expected error.'); + assert(err.message === 'invalid refresh interval'); + }); + + done(); + }); + + test('bad-argument-cancel-request', function (done) { + let context = new AuthenticationContext(cp.authUrl); + + let userCodeInfo: any = { interval: 5, expiresIn: 1000 }; + context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo is missing device_code'); + }); + + // test if usercodeInfo is null + context.cancelRequestToGetTokenWithDeviceCode(null as any, function (err) { + assert(err, 'Did not receive expected argument error'); + assert(err.message === 'The userCodeInfo parameter is required'); + }); + + userCodeInfo = { deviceCode: 'test_device_code', interval: 5, expiresIn: 1000 }; + try { + context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, null as any); + } catch (e) { + assert(e, 'Did not receive expected error. '); + assert(e.message === 'acquireToken requires a function callback parameter.', 'Unexpected error message returned.'); + } + + userCodeInfo = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 200 }; + context.cancelRequestToGetTokenWithDeviceCode(userCodeInfo, function (err) { + assert(err, 'Did not receive expected error. '); + assert(err.message === 'No acquireTokenWithDeviceCodeRequest existed to be cancelled', 'Unexpected error message returned.'); + }) + + done(); + }); + + test('cross-tenant-refresh-token', function (done) { + var memCache = new MemoryCache(); + var response = util.createResponse({ mrrt: true }); + setupExpectedTokenRequestResponse(200, response.wireResponse); + + var userCodeInfo: any = { deviceCode: cp.deviceCode, interval: 1, expiresIn: 1 }; + var context = new AuthenticationContext(cp.authUrl, false, memCache); + context.acquireTokenWithDeviceCode(cp.resource, cp.clientId, userCodeInfo, function (err, tokenResponse) { + assert(!err, 'Receive unexpected error'); + + var someOtherAuthority = url.parse(cp.evoEndpoint + '/' + 'anotherTenant'); + var responseOptions = { refreshedRefresh: true, mrrt: true }; + var response = util.createResponse(responseOptions); + var wireResponse = response.wireResponse; + wireResponse.id_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9jY2ViYTE0Yy02YTAwLTQ5YWMtYjgwNi04NGRlNTJiZjFkNDIvIiwiaWF0IjpudWxsLCJleHAiOm51bGwsImF1ZCI6ImU5NThjMDlhLWFjMzctNDkwMC1iNGQ3LWZiM2VlYWY3MzM4ZCIsInN1YiI6IjRnVHY0RXRvWVctRFRvdzBiRG5KZDFBQTRzZkNoQmJqZXJtcXQ2UV9aYTQiLCJ0aWQiOiJkM2I3ODEzZC0zYTAzLTQyZmEtODk2My1iOTBhNzQ1NTIyYTUiLCJvaWQiOiJhNDQzMjA0YS1hYmM5LTRjYjgtYWRjMS1jMGRmYzEyMzAwYWEiLCJ1cG4iOiJycmFuZGFsbEBycmFuZGFsbGFhZDEub25taWNyb3NvZnQuY29tIiwidW5pcXVlX25hbWUiOiJycmFuZGFsbEBycmFuZGFsbGFhZDEub25taWNyb3NvZnQuY29tIiwiZmFtaWx5X25hbWUiOiJSYW5kYWxsIiwiZ2l2ZW5fbmFtZSI6IlJpY2gifQ.r-XHRqqtxI_7IEmwciFTBJpzwetz4wrM2Is_Z8-O7lw"; + //need to change tokenUrlPath for the different tenant token request, and make sure get it changed back to not affect other tests + var tokenUrlPath = cp.tokenUrlPath; + cp.tokenUrlPath = someOtherAuthority.pathname + cp.tokenPath + cp.extraQP; + + util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, someOtherAuthority, response.resource); + cp.tokenUrlPath = tokenUrlPath; + var conextForAnotherAuthority = new AuthenticationContext(someOtherAuthority as any, false, memCache); + + conextForAnotherAuthority.acquireToken(response.resource, (tokenResponse as adal.TokenResponse).userId as string, response.clientId, function (error) { + assert(!error, 'Receive unexpected error'); + + assert((memCache as any)._entries.length === 2, 'There should two cache entries in the cache'); + memCache.find({ userId: (tokenResponse as adal.TokenResponse).userId, _clientId: response.clientId, _authority: cp.evoEndpoint + '/' + cp.tenant }, function (err, entry) { + assert(!err, 'Unexpected error received'); + assert(entry.length === 1, 'no result returned for given tenant.'); + assert(entry[0].tenantId === 'cceba14c-6a00-49ac-b806-84de52bf1d42'); + }); + + memCache.find({ userId: (tokenResponse as adal.TokenResponse).userId, _clientId: response.clientId, _authority: url.format(someOtherAuthority) }, function (err, entry) { + assert(!err, 'unexpected error received'); + assert(entry.length === 1, 'no result returned for given tenant.'); + assert(entry[0].tenantId === 'd3b7813d-3a03-42fa-8963-b90a745522a5'); + }); + done(err); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/log.js b/test/log.ts similarity index 87% rename from test/log.js rename to test/log.ts index 5e77234..ce217ac 100644 --- a/test/log.js +++ b/test/log.ts @@ -24,18 +24,17 @@ /* global suite */ /* global test */ -var _ = require('underscore'); -var assert = require('assert'); +import * as _ from "underscore"; +import * as assert from "assert"; -var util = require('./util/util'); -var testRequire = util.testRequire; +const util = require('./util/util'); -var adal = testRequire('adal'); +import * as adal from "../lib/adal"; suite('log', function() { test('settings-none', function(done) { var currentOptions = adal.Logging.getLoggingOptions(); - adal.Logging.setLoggingOptions(); + adal.Logging.setLoggingOptions(currentOptions); var options = adal.Logging.getLoggingOptions(); var noOptionsSet = (!options || @@ -62,7 +61,7 @@ suite('log', function() { // future tests are logged as they should be. adal.Logging.setLoggingOptions(currentOptions); - assert(level === 3, 'Logging level was not the expected value of 3: ', options.level); + assert(level === 3, `Logging level was not the expected value of 3: ${options.level}`); assert(_.isFunction(logFunc), 'Unexpected logging function: ' + logFunc); done(); }); diff --git a/test/mex.js b/test/mex.ts similarity index 87% rename from test/mex.js rename to test/mex.ts index 6067d9f..097a34e 100644 --- a/test/mex.js +++ b/test/mex.ts @@ -23,15 +23,15 @@ /* global suite */ /* global test */ -var assert = require('assert'); -var fs = require('fs'); -var nock = require('nock'); +import * as assert from "assert"; +import * as nock from "nock"; +import * as fs from "fs"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var Mex = testRequire('mex'); +const Mex = testRequire('mex'); /** * Tests the Mex class which does Mex retrieval and parsing. @@ -40,20 +40,20 @@ suite('MEX', function() { this.slow(200); // Tell mocha not to consider any of these tests // slow until after 200ms. XML parsing takes time! :( - function setupExpectedMexResponse(filename) { + function setupExpectedMexResponse(filename: string) { var mexDoc = fs.readFileSync(__dirname + '/mex/' + filename, 'utf8'); - var mexRequest = nock(cp.adfsUrlNoPath).get(cp.adfsMexPath).reply('200', mexDoc); + var mexRequest = nock(cp.adfsUrlNoPath).get(cp.adfsMexPath).reply(200, mexDoc); util.matchStandardRequestHeaders(mexRequest); return mexRequest; } - function happyPathTest(testFile, expectedUrl, done) { + function happyPathTest(testFile: any, expectedUrl :string, done: Function) { var mexRequest = setupExpectedMexResponse(testFile); var mex = new Mex(cp.callContext, cp.adfsMex); - mex.discover(function(err) { + mex.discover(function(err: Error) { if (!err) { assert(mex.usernamePasswordPolicy.url === expectedUrl, 'returned url did not match: ' + expectedUrl + ': ' + mex.usernamePasswordPolicy.url); @@ -79,11 +79,11 @@ suite('MEX', function() { happyPathTest('usystech.mex.xml', 'https://sts.usystech.net/adfs/services/trust/2005/usernamemixed', done); }); - function badMexDocTest(testFile, done) { + function badMexDocTest(testFile: any, done: Function) { var mexRequest = setupExpectedMexResponse(testFile); var mex = new Mex(cp.callContext, cp.adfsMex); - mex.discover(function(err) { + mex.discover(function(err: any) { mexRequest.done(); assert(err, 'badMexDocTest expected parsing error'); done(); @@ -130,7 +130,7 @@ suite('MEX', function() { var mexRequest = util.setupExpectedFailedMexCommon(); var mex = new Mex(cp.callContext, cp.adfsMex); - mex.discover(function(err) { + mex.discover(function(err: any) { assert(err, 'Did not receive error as expected'); mexRequest.done(); done(); diff --git a/test/refresh-token.js b/test/refresh-token.ts similarity index 92% rename from test/refresh-token.js rename to test/refresh-token.ts index 74e4640..6188db2 100644 --- a/test/refresh-token.js +++ b/test/refresh-token.ts @@ -27,16 +27,13 @@ // Run // npm test // from root of the repo +import * as assert from "assert"; -var assert = require('assert'); -var util = require('./util/util'); - -var cp = util.commonParameters; -var testRequire = util.testRequire; - -var adal = testRequire('adal'); -var AuthenticationContext = adal.AuthenticationContext; +const util = require('./util/util'); +const cp = util.commonParameters; +import * as adal from "../lib/adal"; +const AuthenticationContext = adal.AuthenticationContext; suite('refresh-token', function() { test('happy-path-no-resource', function(done) { @@ -46,7 +43,7 @@ suite('refresh-token', function() { var tokenRequest = util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, response.authority); var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null, null, function(err, tokenResponse) { + context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null as any, null as any, function(err, tokenResponse) { if (!err) { tokenRequest.done(); assert(util.isMatchTokenResponse(response.decodedResponse, tokenResponse), 'The response did not match what was expected: ' + JSON.stringify(tokenResponse)); @@ -62,7 +59,7 @@ suite('refresh-token', function() { var tokenRequest = util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, response.authority, response.resource); var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null, cp.resource, function(err, tokenResponse) { + context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null as any, cp.resource, function(err, tokenResponse) { if (!err) { tokenRequest.done(); assert(util.isMatchTokenResponse(response.decodedResponse, tokenResponse), 'The response did not match what was expected: ' + JSON.stringify(tokenResponse)) ; @@ -78,7 +75,7 @@ suite('refresh-token', function() { var tokenRequest = util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, response.authority, null, cp.clientSecret); var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, cp.clientSecret, null, function(err, tokenResponse) { + context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, cp.clientSecret, null as any, function(err, tokenResponse) { if (!err) { tokenRequest.done(); assert(util.isMatchTokenResponse(response.decodedResponse, tokenResponse), 'The response did not match what was expected: ' + JSON.stringify(tokenResponse)); @@ -110,7 +107,7 @@ suite('refresh-token', function() { var tokenRequest = util.setupExpectedRefreshTokenRequestResponse(200, wireResponse, response.authority); var context = new AuthenticationContext(cp.authorityTenant); - context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null, function(err, tokenResponse) { + context.acquireTokenWithRefreshToken(cp.refreshToken, cp.clientId, null as any, function(err, tokenResponse) { if (!err) { tokenRequest.done(); assert(util.isMatchTokenResponse(response.decodedResponse, tokenResponse), 'The response did not match what was expected: ' + JSON.stringify(tokenResponse)); diff --git a/test/self-signed-jwt.js b/test/self-signed-jwt.ts similarity index 68% rename from test/self-signed-jwt.js rename to test/self-signed-jwt.ts index 4ef11c0..5c4e56b 100644 --- a/test/self-signed-jwt.js +++ b/test/self-signed-jwt.ts @@ -24,24 +24,24 @@ /* global suite */ /* global test */ -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var SelfSignedJwt = testRequire('self-signed-jwt'); +const SelfSignedJwt = testRequire('self-signed-jwt'); -var assert = require('assert'); -var sinon = require('sinon'); +import * as assert from "assert"; +import * as sinon from "sinon"; -var testNowDate = new Date(1418433646179); -var testJwtId = '09841beb-a2c2-4777-a347-34ef055238a8'; -var expectedJwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IndWM3FobGF0MzJlLWdESFlYcjNjV3RiRU51RSJ9.eyJhdWQiOiJodHRwczovL2xvZ2luLndpbmRvd3MubmV0L25hdHVyYWxjYXVzZXMuY29tL29hdXRoMi90b2tlbiIsImlzcyI6ImQ2ODM1NzEzLWI3NDUtNDhkMS1iYjYyLTdhODI0ODQ3N2QzNSIsInN1YiI6ImQ2ODM1NzEzLWI3NDUtNDhkMS1iYjYyLTdhODI0ODQ3N2QzNSIsIm5iZiI6MTQxODQzMzY0NiwiZXhwIjoxNDE4NDM0MjQ2LCJqdGkiOiIwOTg0MWJlYi1hMmMyLTQ3NzctYTM0Ny0zNGVmMDU1MjM4YTgifQ.AS3jyf9nUqBPeEFKccYA2NfSOSjDoWGW_QTj7Jqjbwpmp8jnQRkJ1Q9QrWLBIspesUVtctiKZQAl_BMochF_4yopY_JbYkPKEVvpbTojtwjKgTpVF175NUjXibUNCijx1BXRxEHJUbVJqzVSWBFtRCbXVBPg_ODqC0JJWutynnwMDec93gGOdWGi8AfRwj855zP41aDZGhQVFiOn3apzN4yfhOGoEeTbG4_6921Tkducz2jWpfVTxIS4yIOKCa97J6XInIlP1iW8XAsnGnTevanj8ubfCtYNRcCOrzq_qZstD6tSDqhQjJlTj5B0zlVvMjTT6oDTAOjzL4TuruENEg'; -var testAuthority = {tokenEndpoint:'https://login.windows.net/naturalcauses.com/oauth2/token'}; -var testClientId = 'd6835713-b745-48d1-bb62-7a8248477d35'; -var testCert = util.getSelfSignedCert(); +const testNowDate = new Date(1418433646179); +const testJwtId = '09841beb-a2c2-4777-a347-34ef055238a8'; +const expectedJwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IndWM3FobGF0MzJlLWdESFlYcjNjV3RiRU51RSJ9.eyJhdWQiOiJodHRwczovL2xvZ2luLndpbmRvd3MubmV0L25hdHVyYWxjYXVzZXMuY29tL29hdXRoMi90b2tlbiIsImlzcyI6ImQ2ODM1NzEzLWI3NDUtNDhkMS1iYjYyLTdhODI0ODQ3N2QzNSIsInN1YiI6ImQ2ODM1NzEzLWI3NDUtNDhkMS1iYjYyLTdhODI0ODQ3N2QzNSIsIm5iZiI6MTQxODQzMzY0NiwiZXhwIjoxNDE4NDM0MjQ2LCJqdGkiOiIwOTg0MWJlYi1hMmMyLTQ3NzctYTM0Ny0zNGVmMDU1MjM4YTgifQ.AS3jyf9nUqBPeEFKccYA2NfSOSjDoWGW_QTj7Jqjbwpmp8jnQRkJ1Q9QrWLBIspesUVtctiKZQAl_BMochF_4yopY_JbYkPKEVvpbTojtwjKgTpVF175NUjXibUNCijx1BXRxEHJUbVJqzVSWBFtRCbXVBPg_ODqC0JJWutynnwMDec93gGOdWGi8AfRwj855zP41aDZGhQVFiOn3apzN4yfhOGoEeTbG4_6921Tkducz2jWpfVTxIS4yIOKCa97J6XInIlP1iW8XAsnGnTevanj8ubfCtYNRcCOrzq_qZstD6tSDqhQjJlTj5B0zlVvMjTT6oDTAOjzL4TuruENEg'; +const testAuthority = {tokenEndpoint:'https://login.windows.net/naturalcauses.com/oauth2/token'}; +const testClientId = 'd6835713-b745-48d1-bb62-7a8248477d35'; +const testCert = util.getSelfSignedCert(); suite('self-signed-jwt', function() { - function createJwt(cert, thumbprint) { + function createJwt(cert: any, thumbprint: any) { var ssjwt = new SelfSignedJwt(cp.callContext, testAuthority, testClientId); sinon.stub(ssjwt, '_getDateNow').returns(testNowDate); sinon.stub(ssjwt, '_getNewJwtId').returns(testJwtId); @@ -49,7 +49,7 @@ suite('self-signed-jwt', function() { return jwt; } - function createJwtAndMatchExpected(cert, thumbprint) { + function createJwtAndMatchExpected(cert: any, thumbprint: any) { var jwt = createJwt(cert, thumbprint); assert(jwt, 'No JWT generated'); assert(jwt === expectedJwt, 'Generated JWT does not match expected: ' + jwt); diff --git a/test/user-realm.js b/test/user-realm.ts similarity index 90% rename from test/user-realm.js rename to test/user-realm.ts index 9e81a53..4c25d30 100644 --- a/test/user-realm.js +++ b/test/user-realm.ts @@ -23,15 +23,14 @@ /* Directive tells jshint that suite and test are globals defined by mocha */ /* global suite */ /* global test */ +import * as assert from "assert"; +import * as nock from "nock"; -var assert = require('assert'); -var nock = require('nock'); +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; - -var UserRealm = testRequire('user-realm'); +const UserRealm = testRequire('user-realm'); /** * Tests the UserRealm class and user realm discovery. @@ -40,7 +39,7 @@ suite('UserRealm', function() { var authority = 'https://login.windows.net/'; var user = 'test@federatedtenant-com'; - function setupExpectedResponse(doc) { + function setupExpectedResponse(doc: any) { var userRealmPath = cp.userRealmPathTemplate.replace('', encodeURIComponent(user)); var query = 'api-version=1.0'; @@ -56,11 +55,11 @@ suite('UserRealm', function() { return userRealmRequest; } - function negativeTest(response, done) { + function negativeTest(response: any, done: Function) { var userRealmRequest = setupExpectedResponse(response); var userRealm = new UserRealm(cp.callContext, user, authority); - userRealm.discover(function(err) { + userRealm.discover(function(err: Error) { userRealmRequest.done(); assert(err, 'Did not receive expected error'); done(); @@ -72,7 +71,7 @@ suite('UserRealm', function() { var userRealmRequest = setupExpectedResponse(userRealmResponse); var userRealm = new UserRealm(cp.callContext, user, authority); - userRealm.discover(function(err) { + userRealm.discover(function(err: Error) { userRealmRequest.done(); if (!err) { assert(userRealm.federationMetadataUrl === 'https://adfs.federatedtenant.com/adfs/services/trust/mex', diff --git a/test/username-password.js b/test/username-password.ts similarity index 93% rename from test/username-password.js rename to test/username-password.ts index d897123..c8cf1f0 100644 --- a/test/username-password.js +++ b/test/username-password.ts @@ -26,28 +26,28 @@ /* global setup */ /* global teardown */ -var _ = require('underscore'); +import * as fs from "fs"; +import * as assert from "assert"; +import * as nock from "nock"; +import * as querystring from "querystring"; +import * as _ from "underscore"; +const sinon = require('sinon'); require('date-utils'); -var fs = require('fs'); -var assert = require('assert'); -var nock = require('nock'); -var querystring = require('querystring'); -var sinon = require('sinon'); - -var util = require('./util/util'); -var testRequire = util.testRequire; -var cp = util.commonParameters; - -var adal = testRequire('adal'); -var AuthenticationContext = adal.AuthenticationContext; - -var MemoryCache = testRequire('memory-cache'); -var Mex = testRequire('mex'); -var OAuth2Client = testRequire('oauth2client'); -var TokenRequest = testRequire('token-request'); -var UserRealm = testRequire('user-realm'); -var WSTrustRequest = testRequire('wstrust-request'); -var WSTrustResponse = testRequire('wstrust-response'); + +const util = require('./util/util'); +const testRequire = util.testRequire; +const cp = util.commonParameters; + +import * as adal from "../lib/adal"; +const AuthenticationContext = adal.AuthenticationContext; +const MemoryCache = adal.MemoryCache; + +const Mex = testRequire('mex'); +const OAuth2Client = testRequire('oauth2client'); +const TokenRequest = testRequire('token-request'); +const UserRealm = testRequire('user-realm'); +const WSTrustRequest = testRequire('wstrust-request'); +const WSTrustResponse = testRequire('wstrust-response'); /** * Tests AuthenticationContext.acquireTokenWithUsernamePassword @@ -65,11 +65,11 @@ suite('username-password', function() { util.clearStaticCache(); }); - function setupExpectedOAuthAssertionRequest(response) { + function setupExpectedOAuthAssertionRequest(response: any) { var assertion = fs.readFileSync(cp.AssertionFile, 'utf8'); - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'urn:ietf:params:oauth:grant-type:saml1_1-bearer'; queryParameters['client_id'] = response.clientId; queryParameters['resource'] = response.resource; @@ -79,9 +79,9 @@ suite('username-password', function() { return util.setupExpectedOAuthResponse(queryParameters, cp.tokenUrlPath, 200, response.wireResponse, cp.authority); } - function setupExpectedUserNamePasswordRequestResponse(httpCode, returnDoc, authorityEndpoint, isAdfs) { + function setupExpectedUserNamePasswordRequestResponse(httpCode: number, returnDoc: object, authorityEndpoint?: string, isAdfs?: boolean) { var authEndpoint = util.getNockAuthorityHost(authorityEndpoint); - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'password'; queryParameters['client_id'] = cp.clientId; queryParameters['resource'] = cp.resource; @@ -251,6 +251,7 @@ suite('username-password', function() { assert(util.isMatchTokenResponse(refreshResponse.cachedResponse, secondTokenResponse), 'Response did not match expected: ' + JSON.stringify(tokenResponse)); // Check that the pre-existing cache entry was not changed at all. memCache.find(alternateUserResponse.cachedResponse, function(err3, results) { + if (err3) done(err3); var alternateUserEntry = results[0]; assert(_.isEqual(alternateUserEntry, alternateUserResponse.cachedResponse), 'The pre-existing alternate user cache entry was ' + 'inappropriately altered.'); @@ -284,11 +285,11 @@ suite('username-password', function() { upRequest.done(); assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'Response did not match expected: ' + JSON.stringify(tokenResponse)); - var numCacheEntries = memCache._entries.length; + var numCacheEntries = (memCache as any)._entries.length; assert(numCacheEntries === 1, 'Incorrect number of entries in the cache: ' + numCacheEntries); // make the single cache entry expired. - memCache._entries[0]['expiresOn'] = Date.yesterday(); + (memCache as any)._entries[0]['expiresOn'] = (Date as any).yesterday(); // Call again to make sure we get a cached entry and refresh it. context.acquireTokenWithUsernamePassword(refreshResponse.resource, cp.username, cp.password, cp.clientId, function(err, secondTokenResponse) { @@ -317,16 +318,17 @@ suite('username-password', function() { var assertion = setupExpectedOAuthAssertionRequest(response); var logFunctionCalled = false; - var foundServerReturnedCorrelationId; - var testCorrelationIdLog = function(level, message) { + var foundServerReturnedCorrelationId: boolean; + var testCorrelationIdLog = function(level: any, message: string) { logFunctionCalled = true; + level; assert(message.indexOf(correlationId) >= 0, 'Did not see expected correlationId in this message: ' + message); if (message.indexOf('correlationId: ' + correlationId) >= 0) { foundServerReturnedCorrelationId = true; } }; - var logOptions = { - level : 3, + var logOptions: adal.LoggingOptions = { + level: 3, log : testCorrelationIdLog }; @@ -377,14 +379,14 @@ suite('username-password', function() { }); }); - function createMexStub(usernamePasswordUrl, err) { + function createMexStub(usernamePasswordUrl: any, err?: Error) { var mex = new Mex(cp.callContext, ''); sinon.stub(mex, 'discover').callsArgWith(0, err); mex._usernamePasswordPolicy = {url: usernamePasswordUrl}; return mex; } - function createUserRealmStub(protocol, accountType, mexUrl, wstrustUrl, err) { + function createUserRealmStub(protocol: any, accountType: any, mexUrl: any, wstrustUrl: any, err?: Error) { var userRealm = new UserRealm(cp.callContext, '', ''); sinon.stub(userRealm, 'discover').callsArgWith(0, err); userRealm._federationProtocol = protocol; @@ -394,7 +396,7 @@ suite('username-password', function() { return userRealm; } - function createWSTrustRequestStub(err, tokenType, noToken) { + function createWSTrustRequestStub(err: Error | null, tokenType: string, noToken?: boolean) { var wstrustResponse = new WSTrustResponse(cp.callContext,'', ''); sinon.stub(wstrustResponse, 'parse'); if (!noToken) { @@ -408,19 +410,19 @@ suite('username-password', function() { return wstrustRequest; } - function createAuthenticationContextStub(authority) { + function createAuthenticationContextStub(authority :string) { var context = new AuthenticationContext(authority, false); - context._authority._tokenEndpoint = authority + cp.tokenPath; + (context as any)._authority._tokenEndpoint = authority + cp.tokenPath; return context; } - function createOAuth2ClientStub(authority, tokenResponse, err) { + function createOAuth2ClientStub(authority: string, tokenResponse: adal.TokenResponse, err?: Error) { var client = new OAuth2Client(cp.callContext, authority); sinon.stub(client, 'getToken').callsArgWith(1, err, tokenResponse); return client; } - function stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient) { + function stubOutTokenRequestDependencies(tokenRequest: any, userRealm: any, mex: any, wstrustRequest?: any, oauthClient?: any) { sinon.stub(tokenRequest, '_createUserRealmRequest').returns(userRealm); sinon.stub(tokenRequest, '_createMex').returns(mex); sinon.stub(tokenRequest, '_createWSTrustRequest').returns(wstrustRequest); @@ -434,12 +436,12 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:1.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err, tokenResponse) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error, tokenResponse: adal.TokenResponse) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); } @@ -454,13 +456,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:1.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err, tokenResponse) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error, tokenResponse: adal.TokenResponse) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); } @@ -475,13 +477,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:1.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function (err, tokenResponse) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function (err: Error, tokenResponse: adal.TokenResponse) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); } @@ -497,7 +499,7 @@ suite('username-password', function() { var tokenRequest = new TokenRequest(cp.callContext, context, cp.clientId, cp.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err :Error) { assert(err, 'Did not receive expected err.'); assert(-1 !== err.message.indexOf('unknown AccountType'), 'Did not receive expected error message.'); done(); @@ -511,13 +513,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:2.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err, tokenResponse) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error, tokenResponse: adal.TokenResponse) { if (!err) { assert(util.isMatchTokenResponse(response.cachedResponse, tokenResponse), 'The response did not match what was expected'); } @@ -532,13 +534,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:100.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error) { assert(err, 'Did not receive expected error.'); assert(-1 !== err.message.indexOf('token type'), 'Error message did not contain \'token type\'.'); done(); @@ -552,13 +554,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(new Error('Network not available'), 'urn:oasis:names:tc:SAML:1.0:assertion'); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error) { assert(err, 'Did not receive expected error'); done(); }); @@ -571,13 +573,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:2.0:assertion', true); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error) { assert(err, 'Did not receive expected error'); done(); }); @@ -590,13 +592,13 @@ suite('username-password', function() { var wstrustRequest = createWSTrustRequestStub(null, 'urn:oasis:names:tc:SAML:100.0:assertion', true); var response = util.createResponse(); - var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, null); + var oauthClient = createOAuth2ClientStub(cp.authority, response.decodedResponse, undefined); //util.turnOnLogging(); var tokenRequest = new TokenRequest(cp.callContext, context, response.clientId, response.resource); stubOutTokenRequestDependencies(tokenRequest, userRealm, mex, wstrustRequest, oauthClient); - tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err) { + tokenRequest.getTokenWithUsernamePassword('username', 'password', function(err: Error) { assert(err, 'Did not receive expected error'); done(); }); @@ -721,7 +723,8 @@ suite('username-password', function() { var preRequests = util.setupExpectedUserRealmResponseCommon(false); var response = util.createResponse(); - function findIdTokenWarning(level, message) { + function findIdTokenWarning(level: any, message: string) { + level; if (message.indexOf('decoded') >= 0) { foundWarning = true; } diff --git a/test/util/util.js b/test/util/util.ts similarity index 76% rename from test/util/util.js rename to test/util/util.ts index accebdc..2e6c813 100644 --- a/test/util/util.js +++ b/test/util/util.ts @@ -1,26 +1,28 @@ 'use strict'; -var _ = require('underscore'); +import * as _ from 'underscore'; +import * as fs from "fs"; +import * as nock from "nock"; +import * as querystring from "querystring"; +import * as url from "url"; require('date-utils'); -var fs = require('fs'); -var nock = require('nock'); -var querystring = require('querystring'); -var url = require('url'); var adaldir = process.env.ADAL_COV ? '../../lib-cov/' : '../../lib/'; -function testRequire(file) { +function testRequire(file: any) { return require(adaldir + file); } nock.disableNetConnect(); var adal = testRequire('adal'); +//import * as adal from "../../lib/adal"; + var log = testRequire('log'); -var util = {}; +var util: any = {}; -var successResponse = { +var successResponse: any = { 'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC82MmYwMzQ3MS02N2MxLTRjNTAtYjlkMS0xMzQ1MDc5ZDk3NzQvIiwiaWF0IjoxMzc4NjAxMTY4LCJuYmYiOjEzNzg2MDExNjgsImV4cCI6MTM3ODYyOTk2OCwidmVyIjoiMS4wIiwidGlkIjoiNjJmMDM0NzEtNjdjMS00YzUwLWI5ZDEtMTM0NTA3OWQ5Nzc0Iiwib2lkIjoiZjEzMDkzNDEtZDcyMy00YTc1LTk2YzktNGIyMTMzMzk0Mjg3Iiwic3ViIjoiZjEzMDkzNDEtZDcyMy00YTc1LTk2YzktNGIyMTMzMzk0Mjg3IiwiYXBwaWQiOiI1YzI1ZDFiZi1iMjMyLTQwMzUtYjZiOS0yYjdlN2U4MzQ2ZDYiLCJhcHBpZGFjciI6IjEifQ.qXM7f9TTiLApxVMwaSrISQQ6UAnfKvKhoIlN9rB0Eff2VXvIWKGRsclPkMQ5x42BQz2N6pSXEsN-LsNCZlQ76Rc3rVRONzeCYh7q_NXcCJG_d6SJTtV5GBfgqFlgT8UF5rblabbMdOiOrddvJm048hWt2Nm3qD3QjQdPBlD7Ksn-lUR1jEJPIqDaBjGom8RawrZTW6X1cy1Kr8mEYFkxcbU91k_RZUumONep9FTR8gfPkboeD8zyvOy64UeysEtcuaNCfhHSBFcwC8MwjUr5r_T7au7ywAcYDOVgoa7oF_dN1JNweiDoNNZ9tyUS-RY3sa3-gXk77gRxpA4CkpittQ', 'token_type': 'Bearer', 'expires_in': 28800, @@ -28,21 +30,21 @@ var successResponse = { }; var refreshToken = 'AwABAAAAvPM1KaPlrEqdFSBzjqfTGCDeE7YHWD9jkU2WWYKLjxu928QAbkoFyWpgJLFcp65DcbBqOSYVq5Ty_60YICIdFw61SG4-eT1nWHNOPdzsL2ZzloUsp2DpqlIr1s5Z3953oQBi7dOqiHk37NXQqmNEJ7MfmDp6w3EOa29EPARvjGIHFgtICW1-Y82npw1v1g8Ittb02pksNU2XzH2X0E3l3TuSZWsX5lpl-kfPOc8zppU6bwvT-VOPHZVVLQedDIQZyOiFst9HLUjbiIvBgV7tNwbB4H5yF56QQscz49Nrb3g0ibuNDo7efFawLzNoVHzoTrOTcCGSG1pt8Z-npByrEe7vg1o4nNFjspuxlyMGdnYRAnaZfvgzqROP_m7ZqSd6IAA'; -var successResponseWithRefresh = _.clone(successResponse); +var successResponseWithRefresh: any = _.clone(successResponse); _.extend(successResponseWithRefresh, { - 'scope' : '62e90394-69f5-4237-9190-012177145e10', - 'refresh_token' : refreshToken + 'scope': '62e90394-69f5-4237-9190-012177145e10', + 'refresh_token': refreshToken }); var encodedIdToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiJlOTU4YzA5YS1hYzM3LTQ5MDAtYjRkNy1mYjNlZWFmNzMzOGQiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9jY2ViYTE0Yy02YTAwLTQ5YWMtYjgwNi04NGRlNTJiZjFkNDIvIiwiaWF0IjoxMzkxNjQ1NDU4LCJuYmYiOjEzOTE2NDU0NTgsImV4cCI6MTM5MTY0OTM1OCwidmVyIjoiMS4wIiwidGlkIjoiY2NlYmExNGMtNmEwMC00OWFjLWI4MDYtODRkZTUyYmYxZDQyIiwib2lkIjoiYTQ0MzIwNGEtYWJjOS00Y2I4LWFkYzEtYzBkZmMxMjMwMGFhIiwidXBuIjoicnJhbmRhbGxAcnJhbmRhbGxhYWQxLm9ubWljcm9zb2Z0LmNvbSIsInVuaXF1ZV9uYW1lIjoicnJhbmRhbGxAcnJhbmRhbGxhYWQxLm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IjRnVHY0RXRvWVctRFRvdzBiRG5KZDFBQTRzZkNoQmJqZXJtcXQ2UV9aYTQiLCJmYW1pbHlfbmFtZSI6IlJhbmRhbGwiLCJnaXZlbl9uYW1lIjoiUmljaCJ9.'; var parsedIdToken = { - 'tenantId' : 'cceba14c-6a00-49ac-b806-84de52bf1d42', - 'userId' : 'rrandall@rrandallaad1.onmicrosoft.com', - 'givenName' : 'Rich', - 'familyName' : 'Randall', - 'isUserIdDisplayable' : true, - 'oid' : 'a443204a-abc9-4cb8-adc1-c0dfc12300aa' + 'tenantId': 'cceba14c-6a00-49ac-b806-84de52bf1d42', + 'userId': 'rrandall@rrandallaad1.onmicrosoft.com', + 'givenName': 'Rich', + 'familyName': 'Randall', + 'isUserIdDisplayable': true, + 'oid': 'a443204a-abc9-4cb8-adc1-c0dfc12300aa' }; @@ -65,15 +67,15 @@ var decodedIdToken = { var encodedIdTokenUrlSafe = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiJlOTU4YzA5YS1hYzM3LTQ5MDAtYjRkNy1mYjNlZWFmNzMzOGQiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9jY2ViYTE0Yy02YTAwLTQ5YWMtYjgwNi04NGRlNTJiZjFkNDIvIiwiaWF0IjoxMzkxNjQ1NDU4LCJuYmYiOjEzOTE2NDU0NTgsImV4cCI6MTM5MTY0OTM1OCwidmVyIjoiMS4wIiwidGlkIjoiY2NlYmExNGMtNmEwMC00OWFjLWI4MDYtODRkZTUyYmYxZDQyIiwib2lkIjoiYTQ0MzIwNGEtYWJjOS00Y2I4LWFkYzEtYzBkZmMxMjMwMGFhIiwidXBuIjoiZm9vYmFyQHNvbWVwbGFjZWVsc2UuY29tIiwidW5pcXVlX25hbWUiOiJycmFuZGFsbEBycmFuZGFsbGFhZDEub25taWNyb3NvZnQuY29tIiwic3ViIjoiNGdUdjRFdG9ZVy1EVG93MGJEbkpkMUFBNHNmQ2hCYmplcm1xdDZRX1phNCIsImZhbWlseV9uYW1lIjoiUmFuZGFsbCIsImdpdmVuX25hbWUiOiJSaTw_Y2gifQ==.'; var parsedIdTokenUrlSafe = { - 'tenantId' : 'cceba14c-6a00-49ac-b806-84de52bf1d42', - 'userId' : 'test@someplaceelse.com', - 'givenName' : 'Ri'; parameters.authorityHosts = { - global : 'login.windows.net', - china : 'login.chinacloudapi.cn', - gov : 'login-us.microsoftonline.com', - us : 'login.microsoftonline.us' + global: 'login.windows.net', + china: 'login.chinacloudapi.cn', + gov: 'login-us.microsoftonline.com', + us: 'login.microsoftonline.us' }; parameters.language = 'en'; parameters.deviceCode = 'ABCDE:device_code'; @@ -131,7 +133,7 @@ parameters.authorizePath = '/oauth/authorize'; parameters.authorizeUrlPath = parameters.authUrl.pathname + parameters.authorizePath; parameters.authorizeUrl = parameters.authUrl.href + parameters.authorizePath; parameters.instanceDiscoverySuccessResponse = { - 'tenant_discovery_endpoint' : parameters.authority + 'tenant_discovery_endpoint': parameters.authority }; parameters.userRealmPathTemplate = '/common/UserRealm/'; @@ -142,8 +144,8 @@ parameters.MexFile = __dirname + '/../mex/common.mex.xml'; // These two files go together. Editing one without changing the other will break the test. parameters.RSTRFile = __dirname + '/../wstrust/common.rstr.xml'; parameters.AssertionFile = __dirname + '/../wstrust/common.base64.encoded.assertion.txt'; -parameters.logContext = { correlationId : 'test-correlation-id-123456789' }; -parameters.callContext = { _logContext : parameters.logContext }; +parameters.logContext = { correlationId: 'test-correlation-id-123456789' }; +parameters.callContext = { _logContext: parameters.logContext }; // This is a dummy RSA private cert used for testing purpose.It does not represent valid credential. @@ -151,7 +153,7 @@ parameters.callContext = { _logContext : parameters.logContext }; // Hence the following message is added to suppress CredScan warning. //[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine")] -util.getSelfSignedCert = function() { +util.getSelfSignedCert = function () { var privatePem = '-----BEGIN RSA PRIVATE KEY-----\n' + 'MIIEpAIBAAKCAQEAoMGZTZi0vU/ICYVgV4vcTwzvZCNXdJ9EgGBBFu1E0/j4FF0Y\n' + 'Fd2sP7IwmWVZLlWJ5VbwAtdMiRdrogX/QnWPfsNfsPzDdRRJD+Erh9tmBzJm08h7\n' + @@ -186,7 +188,7 @@ parameters.certHash = 'C1:5D:EA:86:56:AD:DF:67:BE:80:31:D8:5E:BD:DC:5A:D6:C4:36: parameters.nowDate = new Date(1418433646179); parameters.jwtId = '09841beb-a2c2-4777-a347-34ef055238a8'; parameters.expectedJwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IndWM3FobGF0MzJlLWdESFlYcjNjV3RiRU51RSJ9.eyJhdWQiOiJodHRwczovL2xvZ2luLndpbmRvd3MubmV0L3JyYW5kYWxsYWFkMS5vbm1pY3Jvc29mdC5jb20vb2F1dGgyL3Rva2VuIiwiaXNzIjoiY2xpZW4mJj8_P3RJZCIsInN1YiI6ImNsaWVuJiY_Pz90SWQiLCJuYmYiOjE0MTg0MzM2NDYsImV4cCI6MTQxODQzNDI0NiwianRpIjoiMDk4NDFiZWItYTJjMi00Nzc3LWEzNDctMzRlZjA1NTIzOGE4In0.dgF0TRlcASgTMp_1dlm8vd7tudr6n40VeuOQGFnz566s3n76WR_jJDBBBKlYeqc9gwCPFOzrLVAJehVYZ3N7YPzVdulf47rLoQdAp8R_p4Q4hdBZuIzfgDWwXjnP9x_NlfzezEYE4r8KTS2g5BBzPmx538AfIdNM93hWIxQySZGWY5UAhTkT1qE1ce1Yjo1M2HqzEJhTg5TTyfrnDtNxFxmzYhSyA9B41lB5kBuJTXUWXPrr-6eG8cEUOS-iiH7YB1Tf4J7_9JQloevTiOrfv4pSp6xLLXm2ntNBg3gaKsGKdYd-3tsCG0mHn7BzL0b-QCLalkUr8KtgtLqkxuAiLQ'; -parameters.cert = util.getSelfSignedCert(); +parameters.cert = (util as any).getSelfSignedCert(); util.commonParameters = parameters; @@ -195,12 +197,13 @@ util.testRequire = testRequire; var correlationIdRegex = /[^\s]+/; util.testCorrelationId = correlationIdRegex; -util.setCorrelationId = function(correlationId) { +util.setCorrelationId = function (correlationId: any) { util.testCorrelationId = correlationId || correlationIdRegex; }; -util.turnOnLogging = function(level, logFunc) { - var consoleLog = function(level, message, error) { +util.turnOnLogging = function (level: any, logFunc: any) { + var consoleLog = function (level: any, message: any, error: any) { + level; console.log(message); if (error) { console.log(error); @@ -211,18 +214,18 @@ util.turnOnLogging = function(level, logFunc) { var loggingFunction = logFunc || consoleLog; var loggingLevel = level || log.LOGGING_LEVEL.VERBOSE; log.setLoggingOptions( - { - level : loggingLevel, - log : loggingFunction - }); + { + level: loggingLevel, + log: loggingFunction + }); }; -util.resetLogging = function() { +util.resetLogging = function () { var log = adal.Logging; log.setLoggingOptions(); }; -var TOKEN_RESPONSE_MAP = {}; +var TOKEN_RESPONSE_MAP: any = {}; TOKEN_RESPONSE_MAP['token_type'] = 'tokenType'; TOKEN_RESPONSE_MAP['access_token'] = 'accessToken'; TOKEN_RESPONSE_MAP['refresh_token'] = 'refreshToken'; @@ -233,7 +236,7 @@ TOKEN_RESPONSE_MAP['error'] = 'error'; TOKEN_RESPONSE_MAP['error_description'] = 'errorDescription'; TOKEN_RESPONSE_MAP['resource'] = 'resource'; -var DEVICE_CODE_RESPONSE_MAP = {}; +var DEVICE_CODE_RESPONSE_MAP: any = {}; DEVICE_CODE_RESPONSE_MAP['device_code'] = 'deviceCode'; DEVICE_CODE_RESPONSE_MAP['user_code'] = 'userCode'; DEVICE_CODE_RESPONSE_MAP['verification_url'] = 'verificationUrl'; @@ -242,7 +245,7 @@ DEVICE_CODE_RESPONSE_MAP['expires_in'] = 'expiresIn'; DEVICE_CODE_RESPONSE_MAP['error'] = 'error'; DEVICE_CODE_RESPONSE_MAP['error_description'] = 'errorDescription'; -function mapFields(inObj, outObj, map) { +function mapFields(inObj: any, outObj: any, map: any) { for (var key in inObj) { if (map[key]) { var mappedKey = map[key]; @@ -257,20 +260,20 @@ function mapFields(inObj, outObj, map) { * @param iteration Iteraton will be used to create a distinct token for each value of iteration and it will always return that same token * for same value of iteration. */ -util.createResponse = function(options, iteration) { +util.createResponse = function (options: any, iteration: any) { options = options || {}; var authority = options.authority || parameters.authorityTenant; - var baseResponse = { - 'token_type' : 'Bearer', + var baseResponse :any = { + 'token_type': 'Bearer', 'expires_in': 28800 }; var resource = options.resource || parameters.resource; - var iterated = { + var iterated: any = { 'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC82MmYwMzQ3MS02N2MxLTRjNTAtYjlkMS0xMzQ1MDc5ZDk3NzQvIiwiaWF0IjoxMzc4NjAxMTY4LCJuYmYiOjEzNzg2MDExNjgsImV4cCI6MTM3ODYyOTk2OCwidmVyIjoiMS4wIiwidGlkIjoiNjJmMDM0NzEtNjdjMS00YzUwLWI5ZDEtMTM0NTA3OWQ5Nzc0Iiwib2lkIjoiZjEzMDkzNDEtZDcyMy00YTc1LTk2YzktNGIyMTMzMzk0Mjg3Iiwic3ViIjoiZjEzMDkzNDEtZDcyMy00YTc1LTk2YzktNGIyMTMzMzk0Mjg3IiwiYXBwaWQiOiI1YzI1ZDFiZi1iMjMyLTQwMzUtYjZiOS0yYjdlN2U4MzQ2ZDYiLCJhcHBpZGFjciI6IjEifQ.qXM7f9TTiLApxVMwaSrISQQ6UAnfKvKhoIlN9rB0Eff2VXvIWKGRsclPkMQ5x42BQz2N6pSXEsN-LsNCZlQ76Rc3rVRONzeCYh7q_NXcCJG_d6SJTtV5GBfgqFlgT8UF5rblabbMdOiOrddvJm048hWt2Nm3qD3QjQdPBlD7Ksn-lUR1jEJPIqDaBjGom8RawrZTW6X1cy1Kr8mEYFkxcbU91k_RZUumONep9FTR8gfPkboeD8zyvOy64UeysEtcuaNCfhHSBFcwC8MwjUr5r_T7au7ywAcYDOVgoa7oF_dN1JNweiDoNNZ9tyUS-RY3sa3-gXk77gRxpA4CkpittQ', - 'resource' : resource + 'resource': resource }; if (!options.noRefresh) { @@ -296,10 +299,10 @@ util.createResponse = function(options, iteration) { } var dateNow = new Date(); - var wireResponse = _.clone(baseResponse); + var wireResponse: any = _.clone(baseResponse); wireResponse['created_on'] = dateNow.getTime(); - var decodedResponse = {}; + var decodedResponse: any = {}; mapFields(wireResponse, decodedResponse, TOKEN_RESPONSE_MAP); decodedResponse['createdOn'] = dateNow; @@ -311,9 +314,9 @@ util.createResponse = function(options, iteration) { var expiresOnDate; if (options.expired) { - expiresOnDate = Date.yesterday(); + expiresOnDate = (Date as any).yesterday(); } else { - expiresOnDate = (new Date()).addSeconds(decodedResponse['expiresIn']); + expiresOnDate = ((new Date()) as any).addSeconds(decodedResponse['expiresIn']); } decodedResponse['expiresOn'] = expiresOnDate; @@ -327,88 +330,89 @@ util.createResponse = function(options, iteration) { } return { - wireResponse : wireResponse, - decodedResponse : decodedResponse, - cachedResponse : cachedResponse, - decodedIdToken : decodedIdToken, - resource : iterated['resource'], - refreshToken : iterated['refresh_token'], - clientId : cachedResponse['_clientId'], - authority : authority + wireResponse: wireResponse, + decodedResponse: decodedResponse, + cachedResponse: cachedResponse, + decodedIdToken: decodedIdToken, + resource: iterated['resource'], + refreshToken: iterated['refresh_token'], + clientId: cachedResponse['_clientId'], + authority: authority }; }; -util.createDeviceCodeResponse = function (options, iteration) { - options = options || {}; - - var authority = options.authority || parameters.authorityTenant; - var resource = options.resource || parameters.resource; +util.createDeviceCodeResponse = function (options: any, iteration: any) { + iteration; + options = options || {}; - var wireResponse = {}; - wireResponse['expires_in'] = 28800; - wireResponse['device_code'] = 'device_code:12345'; - wireResponse['user_code'] = 'user_code:12345'; - wireResponse['verification_url'] = 'go:to:verify'; - wireResponse['interval'] = 5; + var authority: any = options.authority || parameters.authorityTenant; + var resource: any = options.resource || parameters.resource; + authority; resource; + var wireResponse: any = {}; + wireResponse['expires_in'] = 28800; + wireResponse['device_code'] = 'device_code:12345'; + wireResponse['user_code'] = 'user_code:12345'; + wireResponse['verification_url'] = 'go:to:verify'; + wireResponse['interval'] = 5; - var decodedResponse = {}; - mapFields(wireResponse, decodedResponse, DEVICE_CODE_RESPONSE_MAP); + var decodedResponse = {}; + mapFields(wireResponse, decodedResponse, DEVICE_CODE_RESPONSE_MAP); - return { - wireResponse : wireResponse, - decodedResponse : decodedResponse - }; + return { + wireResponse: wireResponse, + decodedResponse: decodedResponse + }; }; -util.compareQueryStrings = function(left, right) { +util.compareQueryStrings = function (left: any, right: any) { var leftParameters = querystring.parse(left); var rightParameters = querystring.parse(right); return _.isEqual(leftParameters, rightParameters); }; -util.filterQueryString = function(expected, received) { +util.filterQueryString = function (expected: any, received: any) { return util.compareQueryStrings(expected, received) ? expected : received; }; -util.removeQueryStringIfMatching = function(path, query) { +util.removeQueryStringIfMatching = function (path: any, query: any) { var pathUrl = url.parse(path); return util.compareQueryStrings(pathUrl.query, query) ? pathUrl.pathname : path; }; -function valExists(val) { +function valExists(val: any) { return val; } -util.matchStandardRequestHeaders = function(nockRequest) { +util.matchStandardRequestHeaders = function (nockRequest: any) { nockRequest.matchHeader('x-client-SKU', 'Node') - .matchHeader('x-client-Ver', function(ver) { - return (ver && ver.indexOf('0.') === 0); - }) - .matchHeader('x-client-OS', valExists) - .matchHeader('x-client-CPU', valExists) - .matchHeader('client-request-id', util.testCorrelationId); + .matchHeader('x-client-Ver', function (ver: any) { + return (ver && ver.indexOf('0.') === 0); + }) + .matchHeader('x-client-OS', valExists) + .matchHeader('x-client-CPU', valExists) + .matchHeader('client-request-id', util.testCorrelationId); }; -util.setupExpectedOAuthResponse = function(queryParameters, tokenPath, httpCode, returnDoc, authorityEndpoint) { +util.setupExpectedOAuthResponse = function (queryParameters: any, tokenPath: any, httpCode: any, returnDoc: any, authorityEndpoint: any) { var query = querystring.stringify(queryParameters); - + decodedTokenUrlSafeTest; var authEndpoint = this.getNockAuthorityHost(authorityEndpoint); var tokenRequest = nock(authEndpoint) - .filteringRequestBody(function(body) { - return util.filterQueryString(query, body); - }) - .post(tokenPath, query) - .reply(httpCode, returnDoc, { 'client-request-id' : util.testCorrelationId }); + .filteringRequestBody(function (body) { + return util.filterQueryString(query, body); + }) + .post(tokenPath, query) + .reply(httpCode, returnDoc, { 'client-request-id': util.testCorrelationId }); util.matchStandardRequestHeaders(tokenRequest); return tokenRequest; }; -util.setupExpectedClientCredTokenRequestResponse = function(httpCode, returnDoc, authorityEndpoint) { +util.setupExpectedClientCredTokenRequestResponse = function (httpCode: any, returnDoc: any, authorityEndpoint: any) { var authEndpoint = authorityEndpoint || parameters.authority; - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'client_credentials'; queryParameters['client_id'] = parameters.clientId; queryParameters['client_secret'] = parameters.clientSecret; @@ -417,8 +421,8 @@ util.setupExpectedClientCredTokenRequestResponse = function(httpCode, returnDoc, return util.setupExpectedOAuthResponse(queryParameters, parameters.tokenUrlPath, httpCode, returnDoc, authEndpoint); }; -util.setupExpectedInstanceDiscoveryRequest = function(httpCode, discoveryHost, returnDoc, authority) { - var instanceDiscoveryUrl = {}; +util.setupExpectedInstanceDiscoveryRequest = function (httpCode: any, discoveryHost: any, returnDoc: any, authority: any) { + var instanceDiscoveryUrl: any = {}; instanceDiscoveryUrl.protocol = 'https:'; instanceDiscoveryUrl.host = discoveryHost; instanceDiscoveryUrl.pathname = '/common/discovery/instance'; @@ -431,15 +435,15 @@ util.setupExpectedInstanceDiscoveryRequest = function(httpCode, discoveryHost, r var instanceDiscoveryEndpoint = this.trimPathFromUrl(instanceDiscoveryUrl); var discoveryRequest = nock(instanceDiscoveryEndpoint) - .get(instanceDiscoveryUrl.path) - .reply(httpCode, returnDoc); + .get(instanceDiscoveryUrl.path) + .reply(httpCode, returnDoc); util.matchStandardRequestHeaders(discoveryRequest); return discoveryRequest; }; -util.setupExpectedInstanceDiscoveryRequestCommon = function() { +util.setupExpectedInstanceDiscoveryRequestCommon = function () { return util.setupExpectedInstanceDiscoveryRequest( 200, parameters.authority, @@ -447,7 +451,8 @@ util.setupExpectedInstanceDiscoveryRequestCommon = function() { parameters.authority); }; -util.setupExpectedUserRealmResponse = function(httpCode, returnDoc, authority) { +util.setupExpectedUserRealmResponse = function (httpCode: any, returnDoc: any, authority: any) { + httpCode; var userRealmAuthority = authority || parameters.authority; userRealmAuthority = this.trimPathFromUrl(userRealmAuthority); @@ -455,11 +460,11 @@ util.setupExpectedUserRealmResponse = function(httpCode, returnDoc, authority) { var query = 'api-version=1.0'; var userRealmRequest = nock(userRealmAuthority) - .filteringPath(function(path) { - return util.removeQueryStringIfMatching(path, query); - }) - .get(userRealmPath) - .reply(200, returnDoc); + .filteringPath(function (path) { + return util.removeQueryStringIfMatching(path, query); + }) + .get(userRealmPath) + .reply(200, returnDoc); util.matchStandardRequestHeaders(userRealmRequest); @@ -471,7 +476,7 @@ util.setupExpectedUserRealmResponse = function(httpCode, returnDoc, authority) { * @param {bool} federated Indicates whether the response should indicate a federated or managed tenant. * @return {nock} */ -util.setupExpectedUserRealmResponseCommon = function(federated) { +util.setupExpectedUserRealmResponseCommon = function (federated: any) { var responseDoc; if (federated) { @@ -483,19 +488,19 @@ util.setupExpectedUserRealmResponseCommon = function(federated) { return util.setupExpectedUserRealmResponse(200, responseDoc, parameters.authority); }; -util.setupExpectedInstanceDiscoveryAndUserRealmRequest = function(federated) { +util.setupExpectedInstanceDiscoveryAndUserRealmRequest = function (federated: any) { var instanceDiscovery = util.setupExpectedInstanceDiscoveryRequestCommon(); var userRealm = util.setupExpectedUserRealmResponseCommon(federated); return { - done : function() { + done: function () { instanceDiscovery.done(); userRealm.done(); } }; }; -util.setupExpectedFailedMexCommon = function() { +util.setupExpectedFailedMexCommon = function () { var mexRequest = nock(parameters.adfsUrlNoPath).get(parameters.adfsMexPath).reply(500); util.matchStandardRequestHeaders(mexRequest); @@ -503,43 +508,43 @@ util.setupExpectedFailedMexCommon = function() { return mexRequest; }; -util.setupExpectedMexCommon = function() { +util.setupExpectedMexCommon = function () { var mexDoc = fs.readFileSync(parameters.MexFile, 'utf8'); - var mexRequest = nock(parameters.adfsUrlNoPath).get(parameters.adfsMexPath).reply('200', mexDoc); + var mexRequest = nock(parameters.adfsUrlNoPath).get(parameters.adfsMexPath).reply(200, mexDoc); util.matchStandardRequestHeaders(mexRequest); return mexRequest; }; -util.setupExpectedWSTrustRequestCommon = function() { +util.setupExpectedWSTrustRequestCommon = function () { var RSTRDoc = fs.readFileSync(parameters.RSTRFile, 'utf8'); var wstrustRequest = nock(parameters.adfsUrlNoPath) - .filteringRequestBody(function() {return '*';}) - .post(parameters.adfsWsTrustPath, '*') - .reply(200, RSTRDoc); + .filteringRequestBody(function () { return '*'; }) + .post(parameters.adfsWsTrustPath, '*') + .reply(200, RSTRDoc); util.matchStandardRequestHeaders(wstrustRequest); return wstrustRequest; }; -util.setupExpectedMexWSTrustRequestCommon = function() { +util.setupExpectedMexWSTrustRequestCommon = function () { var expectedMex = util.setupExpectedMexCommon(); var expectedWsTrust = util.setupExpectedWSTrustRequestCommon(); - var doneFunc = function() { + var doneFunc = function () { expectedMex.done(); expectedWsTrust.done(); }; - return { done : doneFunc }; + return { done: doneFunc }; }; -util.setupExpectedRefreshTokenRequestResponse = function(httpCode, returnDoc, authorityEndpoint, resource, clientSecret) { +util.setupExpectedRefreshTokenRequestResponse = function (httpCode: any, returnDoc: any, authorityEndpoint: any, resource: any, clientSecret: any) { var authEndpoint = authorityEndpoint || parameters.authority; - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'refresh_token'; queryParameters['scope'] = 'openid'; queryParameters['client_id'] = parameters.clientId; @@ -554,10 +559,10 @@ util.setupExpectedRefreshTokenRequestResponse = function(httpCode, returnDoc, au return util.setupExpectedOAuthResponse(queryParameters, parameters.tokenUrlPath, httpCode, returnDoc, authEndpoint); }; -util.setupExpectedClientAssertionTokenRequestResponse = function(httpCode, returnDoc, authorityEndpoint) { +util.setupExpectedClientAssertionTokenRequestResponse = function (httpCode: any, returnDoc: any, authorityEndpoint: any) { var authEndpoint = authorityEndpoint || parameters.authority; - var queryParameters = {}; + var queryParameters: any = {}; queryParameters['grant_type'] = 'client_credentials'; queryParameters['client_assertion_type'] = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'; queryParameters['client_assertion'] = parameters.expectedJwt; @@ -567,7 +572,7 @@ util.setupExpectedClientAssertionTokenRequestResponse = function(httpCode, retur return util.setupExpectedOAuthResponse(queryParameters, parameters.tokenUrlPath, httpCode, returnDoc, authEndpoint); }; -function isDateWithinTolerance(date, expectedDate) { +function isDateWithinTolerance(date: any, expectedDate?: any) { var expected = expectedDate || new Date(); var fiveBefore = expected.clone(); fiveBefore.addSeconds(-5); @@ -580,19 +585,19 @@ function isDateWithinTolerance(date, expectedDate) { return false; } -function isExpiresWithinTolerance(expiresOn, expired){ +function isExpiresWithinTolerance(expiresOn: any, expired?: any) { if (!expiresOn) { console.log('no expires_on'); return false; } // Add the expected expires_in latency. - var expectedExpires = expired ? new Date() : Date.yesterday(); + var expectedExpires = expired ? new Date() : (Date as any).yesterday(); expectedExpires = expiresOn.addSeconds(28800); return isDateWithinTolerance(expiresOn, expectedExpires); } -util.isMatchTokenResponse = function(expected, received, print) { +util.isMatchTokenResponse = function (expected: any, received: any, print: any) { var expiresOn = received['expiresOn']; var createdOn = received['createdOn']; @@ -629,56 +634,56 @@ util.isMatchTokenResponse = function(expected, received, print) { return isEqual; }; -util.isMathDeviceCodeResponse = function(expected, received, print) { - if (print) { - console.log('DIFFS'); - util.findDiffs(expected, received); - console.log('EXPECTED'); - console.log(expected); - console.log('RECEIVED'); - console.log(received); - } +util.isMathDeviceCodeResponse = function (expected: any, received: any, print: any) { + if (print) { + console.log('DIFFS'); + util.findDiffs(expected, received); + console.log('EXPECTED'); + console.log(expected); + console.log('RECEIVED'); + console.log(received); + } - var receivedClone = _.clone(received); - var expectedClone = _.clone(expected); + var receivedClone = _.clone(received); + var expectedClone = _.clone(expected); - var isEqual = _.isEqual(expectedClone, receivedClone); + var isEqual = _.isEqual(expectedClone, receivedClone); - return isEqual; + return isEqual; }; -util.createTokenResponseWithIdToken = function(response) { +util.createTokenResponseWithIdToken = function (response: any) { response = response || _.clone(parameters.successResponseWithRefresh); _.extend(response, parsedIdToken); return response; }; -util.isMatchIdTokenResponse = function(expected, received) { +util.isMatchIdTokenResponse = function (expected: any, received: any) { expected = _.clone(expected); _.extend(expected, parsedIdToken); return util.isMatchTokenResponse(expected, received); }; -util.createIdTokenServerResponse = function(baseResponse) { +util.createIdTokenServerResponse = function (baseResponse: any) { var sourceResponse = baseResponse || _.clone(parameters.successResponseWithRefresh); sourceResponse = _.clone(sourceResponse); sourceResponse['id_token'] = encodedIdToken; return sourceResponse; }; -util.createEmptyADALObject = function() { +util.createEmptyADALObject = function () { var context = log.createLogContext(); var component = 'TEST'; var logger = new log.Logger(component, context); - var callContext = { _logContext : context }; + var callContext = { _logContext: context }; var adalObject = { - _log : logger, - _callContext : callContext + _log: logger, + _callContext: callContext }; return adalObject; }; -util.findDiffs = function(leftObj, rightObj) { +util.findDiffs = function (leftObj: any, rightObj: any) { var keys = _.keys(leftObj); var rightKeys = _.keys(rightObj); if (keys.length !== rightKeys.length) { @@ -688,12 +693,12 @@ util.findDiffs = function(leftObj, rightObj) { for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (leftObj[key] !== rightObj[key]) { - console.log(key +': ' + leftObj[key] + ' | ' + rightObj[key]); + console.log(key + ': ' + leftObj[key] + ' | ' + rightObj[key]); } } }; -util.clearStaticCache = function() { +util.clearStaticCache = function () { var context = new adal.AuthenticationContext(parameters.authorityTenant); var cacheArray = context.cache._entries; @@ -703,14 +708,14 @@ util.clearStaticCache = function() { } while (entry); }; -util.trimPathFromUrl = function(stringUrl) { - var u = url.parse(stringUrl); +util.trimPathFromUrl = function (stringUrl: string) { + var u: any = url.parse(stringUrl); return url.resolve(u, '/'); }; -util.getNockAuthorityHost = function(authority) { - var authEndpoint = authority || this.commonParameters.evoEndpoint; - return this.trimPathFromUrl(authEndpoint); +util.getNockAuthorityHost = function (authority: any) { + var authEndpoint = authority || this.commonParameters.evoEndpoint; + return this.trimPathFromUrl(authEndpoint); }; module.exports = util; diff --git a/test/wstrust-request.js b/test/wstrust-request.ts similarity index 59% rename from test/wstrust-request.js rename to test/wstrust-request.ts index 34f3d93..254a866 100644 --- a/test/wstrust-request.js +++ b/test/wstrust-request.ts @@ -24,27 +24,27 @@ /* global suite */ /* global test */ -var assert = require('assert'); -var fs = require('fs'); -var nock = require('nock'); +import * as assert from "assert"; +import * as nock from "nock"; +import * as fs from "fs"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var xmldom = require('xmldom'); -var DOMParser = xmldom.DOMParser; +const xmldom = require('xmldom'); +const DOMParser = xmldom.DOMParser; -var WSTrustRequest = testRequire('wstrust-request'); -var WSTrustVersion = testRequire('constants').WSTrustVersion; +const WSTrustRequest = testRequire('wstrust-request'); +const WSTrustVersion = testRequire('constants').WSTrustVersion; /** * Tests the WSTrustRequest class that creates and sends a ws-trust RST request. */ -suite('WSTrustRequest', function() { +suite('WSTrustRequest', function () { var wstrustEndpoint = 'https://test.wstrust.endpoint/'; - function getMessageIdFromRSTR(body) { + function getMessageIdFromRSTR(body: any) { var urnPrefix = 'urn:uuid:'; var pos = body.indexOf(urnPrefix); if (-1 === pos) { @@ -57,7 +57,7 @@ suite('WSTrustRequest', function() { return messageId; } - function getDateFromRST(body, elementName) { + function getDateFromRST(body: any, elementName: string) { var searchString = elementName + '>'; var pos = body.indexOf(searchString); if (-1 === pos) { @@ -67,7 +67,7 @@ suite('WSTrustRequest', function() { return body.substr(pos + searchString.length, exampleDate.length); } - function replaceDateInTemplate(body, rst, elementName, replaceKey) { + function replaceDateInTemplate(body: any, rst: string, elementName: string, replaceKey: string) { var date = getDateFromRST(body, elementName); if (!date) { return; @@ -75,36 +75,36 @@ suite('WSTrustRequest', function() { return rst.replace(replaceKey, date); } - function compareRSTDocs(rst1, rst2) { + function compareRSTDocs(rst1: string, rst2: string) { var left = rst1.replace(/\s/g, '').replace(/"/g, '\''); var right = rst2.replace(/\s/g, '').replace(/"/g, '\''); return left === right; } - function setupUpOutgoingRSTCompare(rst) { + function setupUpOutgoingRSTCompare(rst: any) { var rstRequest = nock(wstrustEndpoint) - .filteringRequestBody(function(body) { - var messageId = getMessageIdFromRSTR(body); - assert(messageId, 'Could not find message id in return RST'); - rst = rst.replace('%MESSAGE_ID%', messageId); + .filteringRequestBody(function (body) { + var messageId = getMessageIdFromRSTR(body); + assert(messageId, 'Could not find message id in return RST'); + rst = rst.replace('%MESSAGE_ID%', messageId); - rst = replaceDateInTemplate(body, rst, 'Created', '%CREATED%'); - assert(rst, 'Could not find Created date'); + rst = replaceDateInTemplate(body, rst, 'Created', '%CREATED%'); + assert(rst, 'Could not find Created date'); - rst = replaceDateInTemplate(body, rst, 'Expires', '%EXPIRES%'); - assert(rst, 'Could not find Expires date'); - assert(compareRSTDocs(rst, body), 'RST returned does not match expected RST:\n' + body); - return 'OK'; - }) - .post('/', 'OK').reply(200, 'OK'); + rst = replaceDateInTemplate(body, rst, 'Expires', '%EXPIRES%'); + assert(rst, 'Could not find Expires date'); + assert(compareRSTDocs(rst, body), 'RST returned does not match expected RST:\n' + body); + return 'OK'; + }) + .post('/', 'OK').reply(200, 'OK'); util.matchStandardRequestHeaders(rstRequest); return rstRequest; } - test('happy-path', function(done) { + test('happy-path', function (done) { var username = 'test_username'; var password = 'test_password'; var appliesTo = 'test_appliesTo'; @@ -116,17 +116,18 @@ suite('WSTrustRequest', function() { // Take over handling the response to short circuit without having WSTrustRequest attmpt // to proceed with response parsing. - request._handleRSTR = function(body, callback) { + request._handleRSTR = function (body: any, callback: Function) { + body; callback(); }; - request.acquireToken(username, password, function(err) { + request.acquireToken(username, password, function (err: Error) { rstRequest.done(); done(err); }); }); - test('happy-path-wstrust2005', function(done) { + test('happy-path-wstrust2005', function (done) { var username = 'test_username'; var password = 'test_password'; var appliesTo = 'test_appliesTo'; @@ -136,32 +137,33 @@ suite('WSTrustRequest', function() { var rstRequest = setupUpOutgoingRSTCompare(rst); var request = new WSTrustRequest(cp.callContext, wstrustEndpoint, appliesTo, WSTrustVersion.WSTRUST2005); - request._handleRSTR = function(body, callback) { - callback(); + request._handleRSTR = function (body: any, callback: Function) { + body; + callback(); }; - request.acquireToken(username, password, function(err) { - rstRequest.done(); - done(err); + request.acquireToken(username, password, function (err: Error) { + rstRequest.done(); + done(err); }); }); - test('fail-wstrustversion-undefined', function(done) { - var username = 'test_username'; - var password = 'test_password'; - var appliesTo = 'test_appliesTo'; - var templateRST = fs.readFileSync(__dirname + '/wstrust/RST2005.xml', 'utf8'); - var rst = templateRST.replace('%USERNAME%', username).replace('%PASSWORD%', password).replace('%APPLIES_TO%', appliesTo).replace('%WSTRUST_ENDPOINT%', wstrustEndpoint); - - var request = new WSTrustRequest(cp.callContext, wstrustEndpoint, appliesTo, WSTrustVersion.UNDEFINED); - request.acquireToken(username, password, function (err) { - assert(err, 'Did not receive expected error.'); - assert(err.message === 'Unsupported wstrust endpoint version. Current support version is wstrust2005 or wstrust13.'); - done(); - }); + test('fail-wstrustversion-undefined', function (done) { + var username = 'test_username'; + var password = 'test_password'; + var appliesTo = 'test_appliesTo'; + var templateRST = fs.readFileSync(__dirname + '/wstrust/RST2005.xml', 'utf8'); + templateRST.replace('%USERNAME%', username).replace('%PASSWORD%', password).replace('%APPLIES_TO%', appliesTo).replace('%WSTRUST_ENDPOINT%', wstrustEndpoint); + + var request = new WSTrustRequest(cp.callContext, wstrustEndpoint, appliesTo, WSTrustVersion.UNDEFINED); + request.acquireToken(username, password, function (err: Error) { + assert(err, 'Did not receive expected error.'); + assert(err.message === 'Unsupported wstrust endpoint version. Current support version is wstrust2005 or wstrust13.'); + done(); + }); }); - test('fail-to-parse-rstr', function(done) { + test('fail-to-parse-rstr', function (done) { var username = 'test_username'; var password = 'test_password'; var appliesTo = 'test_appliesTo'; @@ -171,32 +173,31 @@ suite('WSTrustRequest', function() { var rstRequest = setupUpOutgoingRSTCompare(rst); var request = new WSTrustRequest(cp.callContext, wstrustEndpoint, appliesTo, WSTrustVersion.WSTRUST13); - request.acquireToken(username, password, function(err) { + request.acquireToken(username, password, function (err: any) { rstRequest.done(); assert(err, 'Did not receive expected error.'); done(); }); }); - test('xml-format-test', function (done) { + test('xml-format-test', function (done) { var username = 'test_username'; var password = 'test_password&<>\'"'; var appliesTo = 'test_appliesTo'; - var templateRST = fs.readFileSync(__dirname + '/wstrust/RST.xml', 'utf8'); var rst = new WSTrustRequest(cp.callContext, wstrustEndpoint, appliesTo, WSTrustVersion.WSTRUST13)._buildRST(username, password); var options = { - errorHandler : function () { throw new Error(); } + errorHandler: function () { throw new Error(); } }; - + try { - new DOMParser(options).parseFromString(rst); + new DOMParser(options).parseFromString(rst); } - catch (e) { - assert(!e, 'Unexpected error received.'); + catch (e) { + assert(!e, 'Unexpected error received.'); } - + done(); }); }); diff --git a/test/wstrust-response.js b/test/wstrust-response.ts similarity index 95% rename from test/wstrust-response.js rename to test/wstrust-response.ts index 0111253..f962368 100644 --- a/test/wstrust-response.js +++ b/test/wstrust-response.ts @@ -24,15 +24,15 @@ /* global suite */ /* global test */ -var assert = require('assert'); -var fs = require('fs'); +import * as assert from "assert"; +import * as fs from "fs"; -var util = require('./util/util'); -var cp = util.commonParameters; -var testRequire = util.testRequire; +const util = require('./util/util'); +const cp = util.commonParameters; +const testRequire = util.testRequire; -var WSTrustResponse = testRequire('wstrust-response'); -var WSTrustVersion = testRequire('constants').WSTrustVersion; +const WSTrustResponse = testRequire('wstrust-response'); +const WSTrustVersion = testRequire('constants').WSTrustVersion; /** * Tests the WSTrustResponse class which parses a ws-trust RSTR. diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3acd6bf --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "module": "commonjs", + "noImplicitAny": true, + "preserveConstEnums": true, + "sourceMap": true, + "newLine": "LF", + "target": "es6", + "moduleResolution": "node", + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "allowJs": false, + "strict": true, + "strictNullChecks": true, + "lib": [ + "dom", + "dom.iterable", + "es5", + "es6", + "es7", + "esnext", + "esnext.asynciterable", + "es2015.iterable" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules" + ], + "include": [ + "./lib/adal.d.ts", + "./test" + ] +} \ No newline at end of file