/** * 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!"); };