Source: authorization/authorization.js

/**
 * Copyright© 2016, Oracle and/or its affiliates. All rights reserved.
 */

/**
 * Class used to authorize a mobile user against Oracle Mobile Cloud Service.
 * @abstract
 * @constructor
 * @global
 */
function Authorization(backend, appKey, utils, platform, logger) {

   /**
     * Callback invoked after successfully authenticating.
     * @callback Authorization~authenticateSuccessCallback
     * @param statusCode {Number} Any HTTP status code returned from the server, if available.
     * @param message {String} The HTTP payload from the server, if available, or an error message.
     * @deprecated Use promises instead
     */

    /**
     * Callback invoked on error while authenticating.
     * @callback Authorization~errorCallback
     * @param statusCode {Number} Any HTTP status code returned from the server, if available.
     * @param message {String} The HTTP payload from the server, if available, or an error message.
     * @deprecated Use promises instead
     */


  if (this.constructor === Authorization) {
    throw new Error("Can't instantiate abstract class!");
  }

  var HEADERS = utils.HEADERS;

  var _accessToken = null;
  var _appKey = utils.validateConfiguration(appKey);
  var _isAnonymous = false;
  var _isAuthorized = false;
  var _anonymousAccessToken = null;

  /**
   * Returns true if a user has been authorized, false otherwise. A user can be authorized by calling authenticate() or authenticateAnonymous().
   * @returns {Boolean}
   */
  Object.defineProperty(this, "isAuthorized", {
    get: function() {
      return _isAuthorized;
    }
  });

  /**
   * Returns the current access token from user credentials.
   * @return current access token from user credentials.
   */
  this.getAccessToken = function () {
    return _accessToken;
  };

  this._setAccessToken = function (token) {
    _accessToken = token;
  };

  this._getApplicationKey = function () {
    return _appKey;
  };

  this._getIsAnonymous = function () {
    return _isAnonymous;
  };

  this._getIsAuthorized = function () {
    return _isAuthorized;
  };

  this._getAnonymousAccessToken = function () {
    return _anonymousAccessToken;
  };

  this._authenticateAnonymousInvoke = function(authorizationToken, headers, url, method, data) {
    var _this = this;

    this.logout();
    headers[HEADERS.AUTHORIZATION] = authorizationToken;
    headers[HEADERS.ORACLE_MOBILE_APPLICATION_KEY] = _appKey;
    headers[HEADERS.ORACLE_MOBILE_CLIENT_SDK_INFO] = backend.getClientSDKInfoHeader(utils.MODULE_NAMES.AUTHORIZATION);

    return platform.invokeService({
        url: url,
        method: method,
        headers: headers,
        data: data
      })
      .then(function responseConverter(response){
        return { orgResponse: response, authorizationToken: authorizationToken };
      })
      .then(_this._anonymousTokenResponseConverter, invokeServiceError)
      .then(_this._authenticateAnonymousSuccess);

    function invokeServiceError(response) {
      logger.error("Login failed with error: " + response.statusCode);
      _this._clearState();
      return Promise.reject(response);
    }
  };

  this._authenticateAnonymousSuccess = function(response) {
    logger.info("User logged in anonymously " + response.orgResponse.statusCode);
    _isAnonymous = true;
    _isAuthorized = true;
    _anonymousAccessToken = response.anonymousAccessToken;
    return response.orgResponse;
  };

  this._authenticateSuccess = function(response, accessToken){
    logger.info("User logged in " + response.statusCode);
    _isAnonymous = false;
    _isAuthorized = true;
    _accessToken = accessToken;
  };

  this._authenticateError = function(response){
    logger.error("Login failed with error: " + response.statusCode);
    this._clearState();
  };

  this._clearState = function(){
    _accessToken = null;
    _isAnonymous = false;
    _anonymousAccessToken = null;
    _isAuthorized = false;
  };

  /**
   * Callback invoked after downloading or updating a user resource.
   * @callback Authorization~userSuccessCallback
   * @param statusCode {Number} Any HTTP status code returned from the server, if available.
   * @param user {User} The user resource returned by the service.
   */

  /**
   * Object returned from getCurrentUser().
   * @typedef Authorization~CurrentUserData
   * @property statusCode {Number} Any HTTP status code returned from the server, if available.
   * @property user {User} The user resource returned by the service.
   */

  /**
   * Returns the user resource associated with the logged in user.
   * @param [successCallback] {Authorization~userSuccessCallback} Optional callback invoked on success (deprecated).
   * @param [errorCallback] {Authorization~errorCallback} Optional callback invoked on failure (deprecated).
   * @return {Promise.<Authorization~CurrentUserData|NetworkResponse>}
   * @example <caption>Example usage of mcs.mobileBackend.authorization.getCurrentUser()</caption>
   * mcs.mobileBackend.authorization.getCurrentUser().then(
   * function(data){
 * },
   * function(exception){
 * });
   * // returns statusCode, and the user object on successCallback function from the data parameter.
   {
     "id": "c9a5fdc5-737d-4e93-b292-d258ba334149",
     "username": "DwainDRob",
     "email": "js_sdk@mcs.com",
     "firstName": "Mobile",
     "lastName": "User",
     "properties": {}
   }
   */
  this.getCurrentUser = function(successCallback, errorCallback) {

    return platform.invokeService({
        method: 'GET',
        url: backend.getPlatformUrl("users/~"),
        headers: backend.getHttpHeaders(utils.MODULE_NAMES.AUTHORIZATION)
      })
      .then(invokeServiceSuccess, invokeServiceError);

    function invokeServiceSuccess(response) {
      var user = new User(response.data);
      if (user.links != null) {
        delete user.links;
      }
      if (successCallback && typeof successCallback === 'function') {
        successCallback(response.statusCode, user);
      }
      return { statusCode: response.statusCode, user: user };
    }

    function invokeServiceError(response) {
      if (errorCallback && typeof errorCallback === 'function') {
        errorCallback(response.statusCode, response.data);
      } else {
        return Promise.reject(response);
      }
    }
  };

  ///**
  // * Updates the user resource for the currently logged in user.
  // * @param user {Authorization~User} The user resource to update
  // * @param successCallback {Authorization~userSuccessCallback} Optional callback invoked on success.
  // * @param errorCallback {Authorization~errorCallback} Optional callback invoked on failure.
  // */
  //this.updateCurrentUser = function(user, successCallback, errorCallback) {
  //  if(!this._accessToken) {
  //    if(failureCallback != null) {
  //      failureCallback("No logged in user!");
  //      return;
  //    }
  //  }
  //
  //  var auth = this;
  //  var userString = JSON.stringify(user);
  //  var headers = auth.backend.getHttpHeaders();
  //  headers["Accept"] = "application/json";
  //  headers["Accept-Encoding"] = "gzip";
  //  headers["Content-Type"] = "application/json";
  //  headers["Content-Length"] = userString.length;
  //
  //  mcs.MobileBackendManager.platform.invokeService({
  //    method: 'PUT',
  //    url: auth.backend.getPlatformUrl("users/~"),
  //    headers: headers,
  //    body: userString,
  //    success: function(response, data) {
  //      if(successCallback != null) {
  //        successCallback(response.status, data);
  //      }
  //    },
  //    error: function(statusCode, data) {
  //      if(errorCallback != null) {
  //        errorCallback(statusCode, data);
  //      }
  //    }
  //  });
  //};
}

/**
 * Returns true if the access token returned by the service is still valid.
 * @abstract
 * @returns {Boolean}
 */
Authorization.prototype.isTokenValid = function () {
  throw new Error("Abstract method!");
};

/**
 * Callback invoked after successfully authenticating.
 * @callback Authorization~authenticateSuccessCallback
 * @param statusCode {Number} Any HTTP status code returned from the server, if available.
 * @param message {String} The HTTP payload from the server, if available, or an error message.
 */

/**
 * Callback invoked on error while authenticating.
 * @callback Authorization~authenticateErrorCallback
 * @param statusCode {Number} Any HTTP status code returned from the server, if available.
 * @param message {String} The HTTP payload from the server, if available, or an error message.
 */

/**
 * Authenticates an anonymous user against the service. The user remains logged in until logout() is called.
 * @abstract
 * @param [successCallback] {Authorization~authenticateSuccessCallback} Optional callback invoked on success (deprecated).
 * @param [errorCallback] {Authorization~authenticateErrorCallback} Optional callback invoked on failure (deprecated).
 */
Authorization.prototype.authenticateAnonymous = function(successCallback, errorCallback) {
  throw new Error("Abstract method!");
};

/**
 * Authenticates a user with the given credentials against the service. The user remains logged in until logout() is called.
 * @abstract
 */
Authorization.prototype.authenticate = function() {
  throw new Error("Abstract method!");
};
/**
 * Refreshes the authentication token if it has expired. The authentication scheme should support refresh.
 * @abstract
 * @param [successCallback] {Authorization~authenticateSuccessCallback} Optional callback invoked on success.
 * @param [errorCallback] {Authorization~errorCallback} Optional callback invoked on failure.
 */
Authorization.prototype.refreshToken = function(successCallback, errorCallback) {
  throw new Error("Abstract method!");
};

/**
 * Logs out the current user and clears credentials and tokens.
 * @abstract
 */
Authorization.prototype.logout = function(){
  throw new Error("Abstract method!");
};

/**
 * Convert response to response token
 * @abstract
 * @param response
 * @private
 * @ignore
 */
Authorization.prototype._anonymousTokenResponseConverter = function(response){
  throw new Error("Abstract method!");
};

/**
 * Return headers
 * @abstract
 * @param headers
 * @private
 * @ignore
 */
Authorization.prototype._getHttpHeaders = function(headers) {
  throw new Error("Abstract method!");
};