adal-node
Version:
Windows Azure Active Directory Client Library for node
237 lines (208 loc) • 7.37 kB
JavaScript
/*
* @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.
*/
;
var _ = require('underscore');
var uuid = require('uuid'); // want to replace with this in the future: https://gist.github.com/jed/982883
var LEVEL_STRING_MAP = {
0 : 'ERROR:',
1 : 'WARNING:',
2 : 'INFO:',
3 : 'VERBOSE:'
};
/**
* Methods for controling global logging options for ADAL
* @namespace
*/
var Logging = {
/**
* @callback LoggingCallback
* @memberOf Logging
* @param {Logging.LOGGING_LEVEL} 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.
*/
/**
* @typedef LoggingOptions
* @memberOf Logging
* @property {LoggingCallback} [log] The function to call when ADAL generates a log entry.
* @property {Logging.LOGGING_LEVEL} [level] The maximum level of log entries to generate.
*/
/**
* Describes the available logging levels.
* @enum
* @type {Number}
*/
LOGGING_LEVEL : {
ERROR : 0,
WARN : 1,
INFO : 2,
VERBOSE : 3
},
/**
* Sets global logging options for ADAL.
* @param {LoggingOptions} options
*/
setLoggingOptions : function(options) {
if (!options) {
options = {};
}
if (options.log) {
if (!_.isFunction(options.log)) {
throw new Error('setLogOptions expects the log key in the options parameter to be a function');
}
} else {
// if no log function was passed set it to a default no op function.
options.log = function() {};
}
if (options.level) {
var level = options.level;
if (level < 0 || level > 3) {
throw new Error('setLogOptions expects the level key to be in the range 0 to 3 inclusive');
}
} else {
options.level = this.LOGGING_LEVEL.ERROR;
}
if (options.loggingWithPII != true) {
options.loggingWithPII = false;
}
this.LogOptions = options;
},
/**
* Get's the current global logging options.
* @return {LoggingOptions}
*/
getLoggingOptions : function() {
return this.LogOptions;
},
/**
* Stores the current global logging options.
* @private
* @type {LoggingOptions}
*/
LogOptions : {
log : function() {},
level : 0,
loggingWithPII: false
}
};
/**
* An internal logging object.
* @class
* @private
* @param {string} componentName The name of the component that created this instance. This name will be
* prepended to the beginning of all log entries generated by this instance.
*/
function Logger(componentName, logContext) {
if (!logContext) {
throw new Error('Logger: logContext is a required parameter');
}
this._componentName = componentName;
this._logContext = logContext;
}
Object.defineProperty(Logger.prototype, 'context', {
get: function () {
return this._logContext;
}
});
/**
* Generates a log entry
* @param {Logging.LOGGING_LEVEL} level The level of this log entry
* @param {string|function} message A message string, or a function that returns a message string, to log.
* @param {Error} [error] If this is a {@link Logging.LOGGING_LEVEL.ERROR|ERROR} level log entry then the caller
* should pass an error object in this parameter.
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.log = function (level, message, error, containsPII) {
if (containsPII == true && !Logging.LogOptions.loggingWithPII) {
return;
}
if (level <= Logging.LogOptions.level) {
if (_.isFunction(message)) {
message = message();
}
var correlationId = this._logContext.correlationId || '<no correlation id>';
var timeStamp = new Date().toUTCString();
var formattedMessage = timeStamp + ':' + correlationId + ' - ' + this._componentName + ': ' + LEVEL_STRING_MAP[level] + ' ' + message;
if (error) {
formattedMessage += '\nStack:\n' + error.stack;
}
Logging.LogOptions.log(level, formattedMessage, error);
}
};
/**
* Generate an {@link Logging.LOGGING_LEVEL.ERROR|ERROR} level log entry.
* @param {string} message A message to log
* @param {Error} error The Error object associated with this log entry
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.error = function (message, error, containsPII) {
this.log(Logging.LOGGING_LEVEL.ERROR, message, error, containsPII);
};
/**
* Generate an {@link Logging.LOGGING_LEVEL.WARN|WARN} level log entry.
* @param {string} message A message to log
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.warn = function (message, containsPII) {
this.log(Logging.LOGGING_LEVEL.WARN, message, null, containsPII);
};
/**
* Generate an {@link Logging.LOGGING_LEVEL.INFO|INFO} level log entry.
* @param {string} message A message to log
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.info = function (message, containsPII) {
this.log(Logging.LOGGING_LEVEL.INFO, message, null, containsPII);
};
/**
* Generate an {@link Logging.LOGGING_LEVEL.VERBOSE|VERBOSE} level log entry.
* @param {string} message A message to log
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.verbose = function (message, containsPII) {
this.log(Logging.LOGGING_LEVEL.VERBOSE, message, null, containsPII);
};
/**
* Generate a {@link Logging.LOGGING_LEVEL.ERROR|ERROR} level log entry, as well as an
* Error object to go with it. This is a convenience method for throwing logged errors.
* @param {string} message A message to log
* @param {boolean} [containsPII] Determines if the log message contains personal information. Default value is false.
*/
Logger.prototype.createError = function(message, containsPII) {
var err = new Error(message);
this.error(message, err, containsPII);
return err;
};
/**
* Creates a new log context based on the correlationId passed in. If no correlationId is passed in
* then one is generated, by the function uuid.v4()
* @private
*/
function createLogContext(correlationId) {
var id = correlationId || uuid.v4();
return { correlationId : id };
}
var exports = {
Logging : Logging,
Logger : Logger,
createLogContext : createLogContext
};
module.exports = exports;