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