ff-sdk-javascript
Version:
FatFractal clientside SDK for JavaScript/HTML5
1,169 lines (1,060 loc) • 101 kB
JavaScript
/** @namespace */
/**
@constructor
@classdesc Register Requests have (at least) the following fields. You may of course add other fields and they will form part of the new FFUser object.
<ul>
<li><strong>userName</strong> - the userName which is subsequently used in login requests
<li><strong>password</strong>
<li><strong>firstName</strong> - the user's first name
<li><strong>lastName</strong> - the user's last name
<li><strong>email</strong> - the user's email address
</ul>
@see FatFractal#register
*/
function RegisterRequest() {
this.userName = null;
this.password = null;
this.firstName = null;
this.lastName = null;
this.email = null;
return this;
}
/**
@constructor
@classdesc FFUsers have (at least) the following fields:
<ul>
<li><strong>clazz</strong> - always == 'FFUser' - maps to the FatFractal OBJECTTYPE
<li><strong>userName</strong>
<li><strong>firstName</strong>
<li><strong>lastName</strong>
<li><strong>email</strong>
<li><strong>active</strong> - whether this FFUser is currently active or not. (For example, users may be inactive while waiting for an email verification.)
</ul>
@see FatFractal#login
@see FatFractal#register
@see FatFractal#loggedInUser
*/
function FFUser() {
this.clazz = "FFUser";
this.userName = null;
this.firstName = null;
this.lastName = null;
this.email = null;
this.active = null;
return this;
}
/**
@constructor
@classdesc FFMetaData have the following fields:
<ul>
<li><strong>clazz</strong> - maps to the FatFractal OBJECTTYPE.
<li><strong>ffUrl</strong> - a String that contains the url (relative to the application base url) of this object.
<li><strong>guid</strong> - a String that contains the guid of this object. Guids must be unique within a given collection.
<li><strong>objVersion</strong> - the object's version. Objects are created with version 1, version increments on every update.
<li><strong>createdBy</strong> - a String that contains guid of the FFUser that created the object.
<li><strong>createdAt</strong> - a Date with the date/time stamp when the object was created as set by your app's backend.
<li><strong>updatedBy</strong> - a String that contains the guid of the FFUser that last updated the object.
<li><strong>updatedAt</strong> - a Date with the date/time stamp when the object was last updated as set by your app's backend.
<li><strong>ffRefs</strong> - an Array containing metadata about any blobs or referred objects that this object has.
<li><strong>ffUserCanEdit</strong> - when objects are retrieved from the backend, this flag lets the client know whether this user has permission to modify it.
</ul>
*/
function FFMetaData(obj) {
this.clazz = null;
this.ffUrl = null;
this.guid = null;
this.ffRL = null;
this.objVersion = null;
this.createdBy = null;
this.createdAt = null;
this.updatedBy = null;
this.updatedAt = null;
this.ffRefs = [];
this.ffUserCanEdit = false;
if(obj) {
this.clazz = obj.clazz;
this.ffUrl = obj.ffUrl;
this.guid = obj.guid;
this.ffRL = obj.ffRL;
this.objVersion = obj.objVersion;
this.createdBy = obj.createdBy;
this.createdAt = obj.createdAt;
this.updatedBy = obj.updatedBy;
this.updatedAt = obj.updatedAt;
this.ffRefs = obj.ffRefs;
this.ffUserCanEdit = obj.ffUserCanEdit;
}
return this;
}
/**
* @classdesc OAuth token object
* @param {String} token OAuth token
* @param {String} secret OAuth secret (OAuth 1)
* @constructor
* @see FatFractal#setTokenForScriptAuthService
* @see FatFractal#getTokenForScriptAuthService
*/
function Token(token, secret) {
this.token = token;
this.secret = secret;
}
/** Default constructor for this class
@constructor
@return {FatFractal} an instance of the FatFractal class
*/
function FatFractal() {
/*
This local variable holds the instance of this function.
*/
var m_ff = this;
/*
Prevent errors with Internet Explorer if window.console is not available.
*/
var window = window;
if (!window)
window = {};
if (!window.console || (typeof window.console === "undefined"))
window.console = {};
if (!window.console.log || (typeof window.console.log === "undefined"))
window.console.log = { log : function (/**...*/ args) {} };
if (!window.console.error || (typeof window.console.error === "undefined"))
window.console.error = { error : function (/**...*/ args) {} };
/*
Prevent errors with Internet Explorer if Array.isArray is not available.
*/
if(!Array.isArray) {
Array.isArray = function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
}
/*
Prevent errors with Internet Explorer if Object.defineProperty is not available.
*/
if (Object.prototype.__defineGetter__&&!Object.defineProperty) {
Object.defineProperty=function(obj,prop,desc) {
if ("get" in desc) obj.__defineGetter__(prop,desc.get);
if ("set" in desc) obj.__defineSetter__(prop,desc.set);
}
}
/*
Prevent errors with Internet Explorer if Array.indexOf is not available.
*/
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++) {
if (this[i] === obj) { return i; }
}
return -1;
}
}
/*
This local variable (String) will override the natural relative addressing with a specified baseUrl, defaults to null.
*/
var m_baseUrl = null;
/*
This local variable (Boolean) contains the LoggedIn status for the FatFractal library, defaults to false.
*/
var m_loggedIn = false;
/*
This local variable (FFUSer) holds the LoggedInUser object for the FatFractal library, defaults to null.
*/
var m_loggedInUser = null;
/*
This local variable (Object) contains the latest server status message.
*/
var m_serverStatusMessage = null;
/*
This local variable (Object) contains items that are cached in memory during the browser session.
*/
var m_cache = {};
/*
This local variable contains items are to store separate from JSON structure stores (blobs).
*/
var m_pendingBlobs = {};
/*
This local variable (Boolean) holds the setting of the Debug mode for the FatFractal library, defaults to false.
*/
var m_debug = false;
var m_superDebug = false;
/*
This local variable (String) holds the sessionId for the FatFractal library, defaults to null.
*/
var m_sessionId = null;
/*
This local variable (Boolean) specifies whether to "simulate" cookies by adding request headers - for example if cookies are disabled by the user.
Defaults to false.
*/
var m_simulateCookies = false;
/*
This object stores callback URIs used by ScriptAuth OAuth services.
URIs are keyed by ScriptAuth service name, e.g. "FACEBOOK"
*/
var m_scriptAuthCallbackUris = {};
/*
ScriptAuth access tokens.
*/
var m_scriptAuthTokens = {};
/*
ScriptAuth request tokens, used by OAuth 1.0a services such as Twitter.
*/
var m_scriptAuthRequestTokens = {};
/*
Defaults to true.
When true, then when Object A is loaded, its references are also loaded asynchronously in a separate request.
<br/> It's usually more desirable to have this property set to false, and use the ?depthRefs query parameter to load references
*/
var m_autoLoadRefs = true;
/*
Defaults to false.
<br> When true, then when Object A is loaded, its BLOBs are also loaded asynchronously in a separate request.
<br/> It's usually more desirable to have this property set to false, and fetch the BLOBs directly
*/
var m_autoLoadBlobs = false;
/*
This local variable (String) contains the version of the FatFractal Javascript Client-Side SDK.
*/
var m_version = "R1.5.0_R3100";
/**
* ScriptAuth service name for Facebook.
* @type {string}
* @see FatFractal#authUriForScriptAuthService
* @see FatFractal#retrieveAccessTokenForScriptAuthService
* @see FatFractal#registerWithScriptAuthService
* @see FatFractal#loginWithScriptAuthService
*/
this.SCRIPT_AUTH_SERVICE_FACEBOOK = "FACEBOOK";
/**
* ScriptAuth service name for Twitter.
* @type {string}
* @see FatFractal#authUriForScriptAuthService
* @see FatFractal#retrieveAccessTokenForScriptAuthService
* @see FatFractal#registerWithScriptAuthService
* @see FatFractal#loginWithScriptAuthService
*/
this.SCRIPT_AUTH_SERVICE_TWITTER = "TWITTER";
/*
This method will determine the File API support for the browser in use.
@return {Boolean} returns true if the HTML5 File API is supported on this browser, else false.
*/
//noinspection JSUnusedLocalSymbols
var m_fileAPI = function() {
return window.File && window.FileList && window.FileReader;
};
/**
This method will determine if the XMLHttpRequest is version 2 or not.
@return {Boolean} returns true if the HTML5 XMLHttpRequest is supported on this browser.
*/
var m_http2 = function() {
var xhr = new XMLHttpRequest();
//noinspection JSUnresolvedVariable
return xhr.upload ? true : false;
};
var m_stringify = function(obj) {
var seen = [];
return JSON.stringify(obj, function(key, val) {
if (typeof val == "object") {
if (seen.indexOf(val) >= 0) return undefined;
seen.push(val);
}
return val;
});
};
/**
This method will set the Debug mode for the FatFractal library to true, which generates
console.log messages for most operations or false which will generate error messages only.
@param {Boolean} tf will set the debug mode to true or false.
*/
this.setDebug = function(tf) {
//noinspection RedundantIfStatementJS
if (tf) {
m_debug = true;
}
else m_debug = false;
console.log("FatFractal().setDebug(boolean) set debug mode to: " + m_debug);
};
/**
This method will set the AutoLoadRefs mode for the FatFractal library
@param {Boolean} tf true or false
*/
this.setAutoLoadRefs = function(tf) {
//noinspection RedundantIfStatementJS
if (tf)
m_autoLoadRefs = true;
else
m_autoLoadRefs = false;
};
/**
This method will set the AutoLoadBlobs mode for the FatFractal library
@param {Boolean} tf true or false
*/
this.setAutoLoadBlobs = function(tf) {
//noinspection RedundantIfStatementJS
if (tf)
m_autoLoadBlobs = true;
else
m_autoLoadBlobs = false;
};
/**
This method will get the Debug mode for the FatFractal library.
@return {Boolean} returns true if the debug mode to true, else returns false.
*/
this.getDebug = function() {
if(m_debug) console.log("FatFractal().getDebug() determined debug mode is: " + m_debug);
//noinspection RedundantIfStatementJS
if (m_debug)
return true;
else
return false;
};
/**
This method will returns the version of the FatFractal library.
@return {String} returns the version of the FatFractal library.
*/
this.version = function() {
if(m_debug) console.log("FatFractal().version() determined version is: " + m_version);
return m_version;
};
function getWindowURL() {
var url = location.href; // entire url including querystring - also: window.location.href;
if(m_debug) console.log("FatFractal().getWindowURL(String) url is: " + url);
var baseURL = url.substring(0, url.indexOf('/', 14));
if(m_debug) console.log("FatFractal().getWindowURL(String) baseURL is: " + baseURL);
var pathname, index1, index2;
pathname = location.pathname; // window.location.pathname;
index1 = url.indexOf(pathname);
index2 = url.indexOf("/", index1 + 1);
var baseLocalUrl = url.substr(0, index2) + "/";
if(m_debug) console.log("FatFractal().getWindowURL(String) returning : " + baseLocalUrl);
return baseLocalUrl;
}
var m_validUrl = function(/**String*/ url, /**String=*/ type) {
if(m_debug) console.log("FatFractal().m_validUrl received url: " + url);
if(m_debug) console.log("FatFractal().m_validUrl received type: " + type);
var validUrl = null;
if(type == "extension") {
if(url.substring(0,1) == "/") {
if(url.substring(0,8) == "/ff/ext/") validUrl = url.substring(1,url.length);
else validUrl = "ff/ext" + url;
}
else if(url.substring(0,7) == "ff/ext/") validUrl = url;
else validUrl = "ff/ext/" + url;
} else if(type == "resources" || type == "resource") {
if(url.substring(0,1) == "/") {
if(url.substring(0,14) == "/ff/resources/") validUrl = url.substring(1,url.length);
else validUrl = "ff/resources" + url;
}
else if(url.substring(0,13) == "ff/resources/") validUrl = url;
else validUrl = "ff/resources/" + url;
} else {
if(url.substring(0,1) == "/") {
if(url.substring(0,14) == "/ff/resources/") validUrl = url.substring(1,url.length);
else if(url.substring(0,8) == "/ff/ext/") validUrl = url.substring(1,url.length);
else validUrl = "ff/resources" + url;
}
else if(url.substring(0,13) == "ff/resources/") validUrl = url;
else if(url.substring(0,7) == "ff/ext/") validUrl = url;
else validUrl = "ff/resources/" + url;
}
if(m_debug) console.log("FatFractal().m_validUrl returned validUrl: " + validUrl);
return validUrl;
};
/**
This method will set the base url for the FatFractal library.
@param {String} base the value the base href will be set to.
@return {String} the value the base href has been set to.
*/
this.setBaseUrl = function(base) {
if(base) {
if(base.charAt(base.length -1) == "/") {
m_baseUrl = base;
} else m_baseUrl = base + "/";
}
else m_baseUrl = null;
if(m_debug) console.log("FatFractal().setBaseUrl(String) m_baseUrl to: " + m_baseUrl);
return m_baseUrl;
};
/**
This method will get the base url for the FatFractal library.
@return {String} the value the base href has been set to.
*/
this.getBaseUrl = function() {
var url = null;
if(m_baseUrl == null) {
url = getWindowURL();
if(m_debug) console.log("FatFractal().getBaseUrl() window location is: " + url);
}
else url = m_baseUrl;
if(m_debug) console.log("FatFractal().getBaseUrl() determined base url is: " + url);
return url;
};
/**
* Obsolete
* @deprecated
*/
this.setSSLUrl = function() {
};
/**
* Obsolete - now just returns getBaseUrl
* @deprecated
* @return {String}
*/
this.getSSLUrl = function() {
return this.getBaseUrl();
};
function pSetSimulateCookies (/**Boolean*/ b) {
if (b === true)
m_simulateCookies = true;
else
m_simulateCookies = false;
}
this.setSimulateCookies = pSetSimulateCookies;
/**
This method is used to get the LoggedIn state for the FatFractal library.
@return {Boolean} returns true if user is logged in and a valid session exists, else returns false.
@see FatFractal#login
@see FatFractal#register
*/
this.loggedIn = function() {
m_sessionId = retrieveSessionID();
if(m_debug) console.log("FatFractal().loggedIn() determined m_sessionId is: " + m_sessionId);
if(retrieveFFUser().guid) m_loggedInUser = retrieveFFUser();
if(m_debug) console.log("FatFractal().loggedIn() determined m_loggedInUser is: " + m_stringify(m_loggedInUser));
if(m_sessionId && m_loggedInUser) m_loggedIn = true;
else {
m_sessionId = null;
m_loggedIn = false;
m_loggedInUser = null;
clearSessionInfo();
}
if(m_debug) console.log("FatFractal().loggedIn() determined loggedIn is: " + m_loggedIn);
return m_loggedIn;
};
/**
This method will get the LoggedIn state for the FatFractal library.
@return {FFUser} returns the FFUser that is logged in if a valid session exists, else returns null.
@see FatFractal#login
@see FatFractal#register
*/
this.loggedInUser = function() {
m_sessionId = retrieveSessionID();
if(m_debug) console.log("FatFractal().loggedInUser() determined m_sessionId is: " + m_sessionId);
if(retrieveFFUser().guid) m_loggedInUser = retrieveFFUser();
if(m_debug) console.log("FatFractal().loggedInUser() determined m_loggedInUser is: " + m_stringify(m_loggedInUser));
if(m_sessionId && m_loggedInUser) m_loggedIn = true;
else {
m_sessionId = null;
m_loggedIn = false;
m_loggedInUser = null;
clearSessionInfo();
}
if(m_debug) console.log("FatFractal().loggedInUser() determined m_loggedInUser is: " + m_stringify(m_loggedInUser));
return m_loggedInUser;
};
/**
Get the sessionId . This can only be set with login or register methods.
@return {String} Returns the sessionId if logged in, else null.
@see FatFractal#login
@see FatFractal#register
*/
this.sessionId = function() {
if(m_sessionId == null) {
m_sessionId = retrieveSessionID();
if(m_debug) console.log("FatFractal().sessionId() determined m_sessionId is: " + m_sessionId);
if(retrieveFFUser().guid) m_loggedInUser = retrieveFFUser();
if(m_debug) console.log("FatFractal().sessionId() determined m_loggedInUser is: " + m_stringify(m_loggedInUser));
if(m_sessionId && m_loggedInUser) m_loggedIn = true;
else {
m_sessionId = null;
m_loggedIn = false;
m_loggedInUser = null;
clearSessionInfo();
}
}
if(m_debug) console.log("FatFractal().sessionId() determined sessionId is: " + m_sessionId);
return m_sessionId;
};
/**
* Get callback URI for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @return {String} Callback URI
*/
this.getCallbackUriForScriptAuthService = function(scriptAuthService) {
return m_scriptAuthCallbackUris[scriptAuthService];
};
/**
* Set callback URI for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @param {String} callbackUri The callback URI
*/
this.setCallbackUriForScriptAuthService = function(scriptAuthService, callbackUri) {
m_scriptAuthCallbackUris[scriptAuthService] = callbackUri;
};
/**
* Get access token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @return {Token} Access token
*/
this.getTokenForScriptAuthService = function(scriptAuthService) {
return m_scriptAuthTokens[scriptAuthService];
};
/**
* Set access token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @param {Token} token The access token
*/
this.setTokenForScriptAuthService = function(scriptAuthService, token) {
m_scriptAuthTokens[scriptAuthService] = token;
};
/**
* Clears the access token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
*/
this.clearTokenForScriptAuthService = function(scriptAuthService) {
delete m_scriptAuthTokens[scriptAuthService];
};
/**
* Get request token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @return {Token} Access token
*/
this.getRequestTokenForScriptAuthService = function(scriptAuthService) {
return m_scriptAuthRequestTokens[scriptAuthService];
};
/**
* Set request token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
* @param {Token} token The access token
*/
this.setRequestTokenForScriptAuthService = function(scriptAuthService, token) {
m_scriptAuthRequestTokens[scriptAuthService] = token;
};
/**
* Clears the request token for the specified ScriptAuth service.
* @param {String} scriptAuthService The ScriptAuth service
*/
this.clearRequestTokenForScriptAuthService = function(scriptAuthService) {
delete m_scriptAuthRequestTokens[scriptAuthService];
};
/**
This method will get the last server status message from an HTTP request.
@return {String} returns the status message from the last HTTP request.
*/
this.serverStatusMessage = function() {return m_serverStatusMessage;};
/**
Default error handler that will report errors to the browser console. Used if a caller doesn't supply a callback.
*/
this.defaultErrorCallback = function(status, message) {
if(console.error) console.error(status + ": " + message);
};
var m_defaultErrorCallback = this.defaultErrorCallback;
/**
Default success handler that will report errors to the browser console. Used if a caller doesn't supply a callback.
*/
this.defaultSuccessCallback = function(response) {
if(console.log) console.log(response);
};
/*
This method will serialize an object to JSON.
*/
this._toJSON = JSON.stringify;
/*
This method will deserialize an object to JSON.
*/
this._fromJSON = JSON.parse;
this.AjaxParams = function() {
this.dataType = null;
this.contentType = null;
this.contentLength = null;
this.contentName = null;
this.fileName = null;
this.fileType = null;
this.fileSize = null;
};
function m_ajax (ajaxParams) {
function oldIEAjax(type, url, data, success, error) {
//noinspection JSUnresolvedFunction
var xdr = new XDomainRequest();
xdr.onload = function() {
var response;
try {
response = JSON.parse(xdr.responseText);
} catch (e) {
if (error)
error(xdr.status,xdr.responseText);
else
m_defaultErrorCallback(xdr.status,xdr.responseText)
}
if (response) {
if (success)
success(response, xdr);
}
};
xdr.onerror = xdr.ontimeout = function() {
if(console.error) console.error("FatFractal.m_ajax " + xdr.status + ", " + xdr.responseText);
if (error) error(xdr.status,xdr.responseText);
};
xdr.onprogress = function() {};
xdr.open(type, url);
xdr.send(data);
}
var xmlHTTP;
try{
xmlHTTP = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
try{
//noinspection JSUnresolvedVariable
if (typeof XDomainRequest !== "undefined") {
oldIEAjax(ajaxParams.type, ajaxParams.url, ajaxParams.data, ajaxParams.success, ajaxParams.error);
}
} catch (e){
var exceptionMessage = "A browser that supports AJAX requests is required!";
alert(exceptionMessage);
throw exceptionMessage;
}
}
}
}
var handled = false;
xmlHTTP.open(ajaxParams.type.toUpperCase(), ajaxParams.url, true);
if(!ajaxParams.dataType) xmlHTTP.setRequestHeader("Data-type","application/json");
else if((ajaxParams.dataType.toLowerCase() == "application/json") || (ajaxParams.dataType.toLowerCase() == "json")) xmlHTTP.setRequestHeader("Data-type","application/json");
else xmlHTTP.setRequestHeader("Data-type",ajaxParams.dataType);
if(!ajaxParams.contentType) xmlHTTP.setRequestHeader("Content-type","application/json");
else if((ajaxParams.contentType.toLowerCase() == "application/json") || (ajaxParams.contentType.toLowerCase() == "json")) xmlHTTP.setRequestHeader("Content-type","application/json");
else xmlHTTP.setRequestHeader("Content-type",ajaxParams.contentType);
// Blob headers
if(ajaxParams.contentLength) xmlHTTP.setRequestHeader('Content-Length', ajaxParams.contentLength);
if(ajaxParams.contentName) xmlHTTP.setRequestHeader('Content-Name', ajaxParams.contentName);
if(ajaxParams.fileName) xmlHTTP.setRequestHeader('x-file-name', ajaxParams.fileName);
if(ajaxParams.fileSize) xmlHTTP.setRequestHeader('x-file-size', ajaxParams.fileSize);
if(ajaxParams.fileType) xmlHTTP.setRequestHeader('x-file-type', ajaxParams.fileType);
//xmlHTTP.setRequestHeader("Connection", "close");
if (m_simulateCookies && m_loggedIn) {
xmlHTTP.setRequestHeader("X-Ff-Auth-User-Guid", m_loggedInUser.guid);
xmlHTTP.setRequestHeader("X-Ff-Auth-Session-Id", m_sessionId);
}
xmlHTTP.send(ajaxParams.data);
xmlHTTP.onreadystatechange = function() {
if(xmlHTTP.readyState == 4) {
if(m_debug) console.log("xmlHTTP.status: " + xmlHTTP.status + ", xmlHTTP.readyState: " + xmlHTTP.readyState + ", xmlHTTP.responseText: " + xmlHTTP.responseText);
if (handled) {
return;
}
handled = true;
if(xmlHTTP.status >= 200 && xmlHTTP.status < 300) {
var response = JSON.parse(xmlHTTP.responseText);
if (ajaxParams.success) {
if(m_debug) console.log(JSON.stringify(response));
ajaxParams.success(response);
}
else if(m_debug) console.log("no success callback");
} else if (xmlHTTP.status == 304) {
// check if in cache
}
else {
if(console.error) console.error(xmlHTTP.status + ": " + xmlHTTP.statusText);
if (xmlHTTP.status == 401) {
if(console.error) console.error("Got a 401 - clearing all session info");
m_loggedIn = false;
m_loggedInUser = null;
m_sessionId = null;
clearSessionInfo();
}
if(ajaxParams.error) {
ajaxParams.error(xmlHTTP);
if(console.error) console.error("xmlHTTP : " + m_stringify(xmlHTTP));
}
else if(m_debug) console.log("no success callback");
}
}
else if(m_debug) console.log("xmlHTTP.status: " + xmlHTTP.status + ", xmlHTTP.readyState: " + xmlHTTP.readyState + ", xmlHTTP.responseText: " + xmlHTTP.responseText);
}
}
/**
Set the default permissions for this object. If object has a specific ACL, it is removed so that the defaults
apply (PERMIT commands or, if there are no PERMIT commands, the overall system default (public can read, only
creator can write)
@param obj - the object for which we are setting permissions
@param {Function} successCallback
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.setDefaultPermission = function(obj, successCallback, errorCallback) {
var url = m_validUrl(obj.ffUrl) + "/ffACL";
if(m_baseUrl) url = m_baseUrl + url;
m_ajax({
type: "PUT",
url: url,
dataType: 'json',
contentType:'application/json',
data: null,
success: function(response) {
if (successCallback) successCallback(response);
},
error: function(xmlHTTP) {
if(console.error) console.error("FatFractal.setDefaultPermission " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
this.PermissionObject = function(_readUsers, _readGroups, _writeUsers, _writeGroups) {
this.readUsers = _readUsers ? _readUsers : null;
this.readGroups = _readGroups ? _readGroups : null;
this.writeUsers = _writeUsers ? _writeUsers : null;
this.writeGroups = _writeGroups ? _writeGroups : null;
};
/**
Using this method, permissions are granted to read or write an object by user and by group. Once permission is granted to
read or write an object by user, that permission persists until the method is reissued. If users are added or taken out of
groups, the corresponding permissions for that group obtain dynamically.
@param obj - the object for which we are setting permissions
@param readUsers - must be an array of FFUser each of which is to be given read access to the object
@param writeUsers - must be an array of FFUser each of which is to be given write access to the object
@param readGroups - must be an array of FFUserGroup each of which is to be given read access to the object
@param writeGroups - must be an array of FFUserGroup each of which is to be given write access to the object
@param {Function} successCallback Function with one argument - the registered FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.setPermission = function(obj, readUsers, readGroups, writeUsers, writeGroups, successCallback, errorCallback) {
var request = new this.PermissionObject (readUsers, readGroups, writeUsers, writeGroups);
var url = m_validUrl(obj.ffUrl) + "/ffACL";
if(m_baseUrl) url = m_baseUrl + url;
m_ajax({
type: "PUT",
url: url,
dataType: 'json',
contentType:'application/json',
data: m_ff._toJSON(request),
success: function(response) {
if (successCallback) successCallback(response);
},
error: function(xmlHTTP) {
if(console.error) console.error("FatFractal.setPermission " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
/**
Get all items from the object's named grab bag
<br>For example, grabBagGetAll(anOrder, "OrderLines")
@param parentObj - The object from whose grab bag we are retrieving
@param gbName - The grab bag name
@param {Function} successCallback Function with two arguments - an array of retrieved objects, and a String statusMessage
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.grabBagGetAll = function(parentObj, gbName, successCallback, errorCallback) {
m_ff.grabBagGetAllForQuery(parentObj, gbName, null, successCallback, errorCallback);
};
/**
Get items, via query, from the object's named grab bag
<br>For example, grabBagGetAllForQuery(anOrder, "OrderLines", "(orderLineValue gt 1000)")
@param parentObj - The object from whose grab bag we are retrieving
@param gbName - The grab bag name
@param query - The query string in FatFractal Query Language format
@param {Function} successCallback Function with one argument - an array of retrieved objects, and a String statusMessage
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.grabBagGetAllForQuery = function(parentObj, gbName, query, successCallback, errorCallback) {
var grabBagRelativeUrl = parentObj.ffUrl + "/" + gbName;
if(query != null)
grabBagRelativeUrl = grabBagRelativeUrl + "/(" + query + ")";
m_ff.getArrayFromUri(grabBagRelativeUrl, successCallback, errorCallback);
};
/**
Add an item to the object's named grab bag.
<br>For example, grabBagAdd(anOrderLine, anOrder, "OrderLines")
@param item - The item which is to be added
@param parentObj - The object whose grab bag is going to be updated
@param gbName - The grab bag name
@param {Function} successCallback Function with one argument - the registered FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.grabBagAdd = function(item, parentObj, gbName, successCallback, errorCallback) {
m_ff.handleGrabBagRequest(item, parentObj, gbName, true, successCallback, errorCallback);
};
/**
Remove an item from the object's named grab bag.
<br>For example, grabBagRemove(anOrderLine, anOrder, "OrderLines")
@param item - The item which is to be removed
@param parentObj - The object whose grab bag is going to be updated
@param gbName - The grab bag name
@param {Function} successCallback Function with one argument - the registered FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.grabBagRemove = function(item, parentObj, gbName, successCallback, errorCallback) {
m_ff.handleGrabBagRequest(item, parentObj, gbName, false, successCallback, errorCallback);
};
this.GrabBagAddOrRemoveObj = function(_ffUrl, _addOrRemove) {
this.ffUrl = _ffUrl ? _ffUrl : null;
this.AddOrRemove = _addOrRemove ? _addOrRemove : null;
};
/*
This method is responsible for interacting with the FatFractal backend with respect to GrabBags.
<br>For example, grabBagRemove(anOrderLine, anOrder, "OrderLines")
@param item - The item which is to be removed
@param parentObj - The object whose grab bag is going to be updated
@param gbName - The grab bag name
@param gbAction - The action to be performed (ADD or REMOVE).
@param {Function} successCallback
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.handleGrabBagRequest = function(item, parentObj, gbName, add, successCallback, errorCallback) {
if(! successCallback) throw new Error("FatFractal.handleGrabBagRequest: successCallback not supplied");
if(! errorCallback) errorCallback = m_ff.defaultErrorCallback;
if(! errorCallback) throw new Error("FatFractal.handleGrabBagRequest: errorCallback not supplied");
var addOrRemove = (add ? "ADD" : "REMOVE");
var grabBagRelativeUrl = parentObj.ffUrl + "/" + gbName;
var itemUrl = item.ffUrl;
var request = new this.GrabBagAddOrRemoveObj(itemUrl, addOrRemove);
var url = m_validUrl(grabBagRelativeUrl);
if(m_baseUrl) url = m_baseUrl + url;
m_ajax({
type: "POST",
url: url,
dataType: 'json',
contentType:'application/json',
data: m_ff._toJSON(request),
success: function(response) {
if (successCallback) successCallback(response);
},
error: function(xmlHTTP) {
if(console.error) console.error("FatFractal.handleGrabBagRequest " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
/**
Registers a new FFUSer
Currently a successful registration will also log the user in.
@param {RegisterRequest} registerRequest
@param {Function} successCallback Function with one argument - the registered FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
Additionally upon success, the values for some other properties that are accessible by your
application are set:
<br><b>String sessionId</b> is set to the SessionId returned by your app's backend
<br><b>String loggedInUser</b> is set to the FFUser response from the backend
<br><b>BOOL loggedIn</b> is set to true
@see RegisterRequest
@see FFUser
@see FatFractal#loggedIn
@see FatFractal#sessionId
@see FatFractal#loggedInUser
*/
this.register = function(registerRequest, successCallback, errorCallback) {
if(! successCallback) throw new Error("FatFractal.register: successCallback not supplied");
if(! errorCallback) errorCallback = m_ff.defaultErrorCallback;
if(! errorCallback) throw new Error("FatFractal.register: errorCallback not supplied");
var url = this.getBaseUrl() + "ff/register";
m_ajax({
type: "POST",
url: url,
dataType: 'json',
contentType:'application/json',
data: m_ff._toJSON(registerRequest),
success: function(response) {
if(response.result != null && response.result.loggedInUser != null) {
m_loggedIn = true;
m_loggedInUser = response.result.loggedInUser;
//noinspection JSUnresolvedVariable
m_sessionId = response.result.authResult.session.sessionId;
storeSessionInfo(m_loggedInUser, m_sessionId);
if(successCallback) successCallback(m_loggedInUser);
}
else
if(errorCallback) errorCallback(500, "No result.loggedInUser in response")
},
error: function(xmlHTTP) {
if(console.error) console.error("FatFractal.register " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
/**
* Register a new FFUser using ScriptAuth. Credential is constructed using a stored token, retrieved via {@link FatFractal#getTokenForScriptAuthService}.
* @param {String} scriptAuthService The ScriptAuth service to use
* @param {Function} successCallback Function with one argument - the registered FFUser
* @param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
* @see FatFractal#retrieveAccessTokenForScriptAuthService
* @see FatFractal#setTokenForScriptAuthService
*/
this.registerWithScriptAuthService = function(scriptAuthService, successCallback, errorCallback) {
var rr = new RegisterRequest();
rr.authDomain = "SCRIPT";
rr.scriptAuthService = scriptAuthService;
var token = this.getTokenForScriptAuthService(scriptAuthService);
rr.token = token.token;
rr.secret = token.secret;
this.register(rr, successCallback, errorCallback);
};
/**
Login using a username and password.
<br>login will succeed if there exists a registered FFUser with this userName and password. If you have set
AllowAutoRegistration to true in your application.ffdl configuration, then login will also succeed if this userName
does not exist in your app's backend.
@param {String} username - the user name - can be anything, doesn't have to be meaningful
@param {String} password - the password
@param {Function} successCallback Function with one argument - the registered FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
Additionally upon success, the values for some other properties that are accessible by your
application are set:
<br><b>String sessionId</b> is set to the SessionId returned by your app's backend
<br><b>String loggedInUser</b> is set to the FFUser response from the backend
<br><b>BOOL this.loggedIn()</b> will return true.
@see FatFractal#register
@see FFUser
@see FatFractal#loggedIn
@see FatFractal#sessionId
@see FatFractal#loggedInUser
*/
this.login = function(username, password, successCallback, errorCallback) {
var credential = {
userName: username,
password: password
};
this.loginUsingCredential(credential, successCallback, errorCallback);
};
/**
Login using console credentials.
<br>login will succeed if (a) console credentials are valid (b) console user has write permission to this backend and (c) system user is allowed to log in
@param {String} username - the FF console user name
@param {String} password - the password
@param {Function} successCallback Function with one argument - the FFUser
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
Additionally upon success, the values for some other properties that are accessible by your
application are set:
<br><b>String sessionId</b> is set to the SessionId returned by your app's backend
<br><b>String loggedInUser</b> is set to the FFUser response from the backend
<br><b>BOOL this.loggedIn()</b> will return true.
@see FatFractal#register
@see FatFractal#login
@see FFUser
@see FatFractal#loggedIn
@see FatFractal#sessionId
@see FatFractal#loggedInUser
*/
this.loginUsingConsoleCredentials = function(username, password, successCallback, errorCallback) {
var credential = {
authDomain: 'FFCONSOLE',
userName: username,
password: password
};
this.loginUsingCredential(credential, successCallback, errorCallback);
};
/**
* Log in using ScriptAuth service. Credential is constructed using a stored token, retrieved via {@link FatFractal#getTokenForScriptAuthService}.
* @param {String} scriptAuthService The ScriptAuth service
* @param {Function} successCallback Function with one argument - the FFUser
* @param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
* @see FatFractal#retrieveAccessTokenForScriptAuthService
* @see FatFractal#setTokenForScriptAuthService
*/
this.loginWithScriptAuthService = function(scriptAuthService, successCallback, errorCallback) {
var token = this.getTokenForScriptAuthService(scriptAuthService);
var credential = {
authDomain: "SCRIPT",
scriptAuthService: scriptAuthService,
token: token.token,
secret: token.secret
};
this.loginUsingCredential(credential, successCallback, errorCallback);
};
/**
* General log in function, allowing arbitrary credentials to be passed.
* @param credential Credential map
* @param {Function} successCallback Function with one argument - the FFUser
* @param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
*/
this.loginUsingCredential = function(credential, successCallback, errorCallback) {
if(! successCallback) throw new Error("FatFractal.loginUsingConsoleCredentials: successCallback not supplied");
if(! errorCallback) errorCallback = m_ff.defaultErrorCallback;
if(! errorCallback) throw new Error("FatFractal.loginUsingConsoleCredentials: errorCallback not supplied");
var req = {
credential: credential
};
var url = this.getBaseUrl() + "ff/login";
m_ajax({
type: "POST",
url: url,
dataType: 'json',
contentType: 'application/json',
data: m_ff._toJSON(req),
success: function (response) {
if (response.result != null && response.result.loggedInUser != null) {
m_loggedIn = true;
m_loggedInUser = response.result.loggedInUser;
//noinspection JSUnresolvedVariable
m_sessionId = response.result.authResult.session.sessionId;
storeSessionInfo(m_loggedInUser, m_sessionId);
if (successCallback) successCallback(m_loggedInUser);
}
else if (errorCallback) errorCallback(500, "No result.loggedInUser in response")
},
error: function (xmlHTTP) {
if (console.error) console.error("FatFractal.login " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
/**
Explicit logout from your app's backend.
@param {Function} successCallback Function with one argument - the response object
@param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
<br>Sets #loggedInSessionId to null, #loggedInUserName to null, #loggedInUser to null, #loggedIn to false
*/
this.logout = function(successCallback, errorCallback) {
if(! successCallback) successCallback = m_ff.defaultSuccessCallback;
if(! successCallback) throw new Error("FatFractal.logout: successCallback not supplied");
if(! errorCallback) errorCallback = m_ff.defaultErrorCallback;
if(! errorCallback) throw new Error("FatFractal.logout: errorCallback not supplied");
var url = "ff/logout";
if(m_baseUrl) url = m_baseUrl + "ff/logout";
m_ajax({
type: "POST",
url: url,
dataType: 'json',
contentType:'application/json',
success: function(response) {
m_loggedIn = false;
m_loggedInUser = null;
m_sessionId = null;
clearSessionInfo();
m_cache = {};
if(successCallback) successCallback(response);
},
error: function(xmlHTTP) {
if(console.error) console.error("FatFractal.logout " + xmlHTTP.status + ", " + xmlHTTP.responseText);
m_serverStatusMessage = "HTTP request failed - response code was " + xmlHTTP.status + " responseText was " + xmlHTTP.responseText;
if (errorCallback) errorCallback(xmlHTTP.status, xmlHTTP.responseText);
}
});
};
/**
* Get the authorization URI for the specified ScriptAuth service.
* The page at the resulting URI should be shown to the user.
* A callback URI must be specified with {@link FatFractal#setCallbackUriForScriptAuthService} before calling.
* When redirected to your callback URI, call {@link FatFractal#retrieveAccessTokenForScriptAuthService} to get the access token.
*
* <br><br><strong>Note:</strong> If using an OAuth 1.0a service such as Twitter, this function will generate a request token.
* In your successCallback, you <strong>must</strong> store the request token, by e.g. setting a cookie.
* The request token may be accessed using {@link FatFractal#getRequestTokenForScriptAuthService}.
* When your callback URI is called, you must then set the request token using {@link FatFractal#setRequestTokenForScriptAuthService}.
*
* @param {String} scriptAuthService The ScriptAuth service
* @param {Function} successCallback Function with one argument - the authorization URI
* @param {Function} errorCallback Function with two arguments - Number statusCode and String statusMessage
* @see FatFractal#retrieveAccessTokenForScriptAuthService
* @see FatFractal#getRequestTokenForScriptAuthService
*/
this.authUriForScriptAuthService = function(scriptAuthService, successCallback, errorCallback) {
var callbac