cloudmine
Version:
CloudMine JavaScript library for node and browsers
1,309 lines (1,185 loc) • 87.7 kB
JavaScript
/* CloudMine JavaScript Library v0.10.x cloudmineinc.com | https://github.com/cloudmine/cloudmine-js/blob/master/LICENSE */
(function() {
var version = '0.10.1';
/**
* Construct a new WebService instance
*
* <p>Each method on the WebService instance will return an APICall object which may be used to
* access the results of the method called. You can chain multiple events together with the
* returned object (an APICall instance).
*
* <p>All events are at least guaranteed to have the callback signature: function(data, apicall).
* supported events:
* <p> 200, 201, 400, 401, 404, 409, ok, created, badrequest, unauthorized, notfound, conflict,
* success, error, complete, meta, result, abort
* <p>Event order: success callbacks, meta callbacks, result callbacks, error callbacks, complete
* callbacks
*
* <p>Example:
* <pre class='code'>
* var ws = new cloudmine.WebService({appid: "abc", apikey: "abc", appname: 'SampleApp', appversion: '1.0'});
* ws.get("MyKey").on("success", function(data, apicall) {
* console.log("MyKey value: %o", data["MyKey"]);
* }).on("error", function(data, apicall) {
* console.log("Failed to get MyKey: %o", apicall.status);
* }).on("unauthorized", function(data, apicall) {
* console.log("I'm not authorized to access 'appid'");
* }).on(404, function(data, apicall) {
* console.log("Could not find 'MyKey'");
* }).on("complete", function(data, apicall) {
* console.log("Finished get on 'MyKey':", data);
* });
* </pre>
* <p>Refer to APICall's documentation for further information on events.
*
* @param {object} Default configuration for this WebService
* @config {string} [appid] The application id for requests (Required)
* @config {string} [apikey] The api key for requests (Required)
* @config {string} [xuniqueid] The X-Unique-ID you want to apply to all requests using this WebService (optional)
* @config {string} [appname] An alphanumeric identifier for your app, used for stats purposes
* @config {string} [appversion] A version identifier for you app, used for stats purposes
* @config {boolean} [applevel] If true, always send requests to application.
* If false, always send requests to user-level, trigger error if not logged in.
* Otherwise, send requests to user-level if logged in.
* @config {boolean} [savelogin] If true, session token and email / username will be persisted between logins.
* @config {integer} [limit] Set the default result limit for requests
* @config {string} [sort] Set the field on which to sort results
* @config {integer} [skip] Set the default number of results to skip for requests
* @config {boolean} [count] Return the count of results for request.
* @config {string} [snippet] Run the specified code snippet during the request.
* @config {string|object} [params] Parameters to give the code snippet (applies only for code snippets)
* @config {boolean} [dontwait] Don't wait for the result of the code snippet (applies only for code snippets)
* @config {boolean} [resultsonly] Only return results from the code snippet (applies only for code snippets)
* @name WebService
* @constructor
*/
function WebService(options) {
this.options = opts(this, options);
if(!this.options.apiroot) this.options.apiroot = "https://api.cloudmine.io";
var src = this.options.appid;
if (options.savelogin) {
if (!this.options.email) this.options.email = retrieve('email', src);
if (!this.options.username) this.options.username = retrieve('username', src);
if (!this.options.session_token) this.options.session_token = retrieve('session_token', src);
}
this.options.user_token = retrieve('ut', src) || store('ut', this.keygen(), src);
}
/** @namespace WebService.prototype */
WebService.prototype = {
/**
* generic function for calling the api with a minimal set of logic and optons
* @param {string} action Action endpoint - 'text', 'data', etc
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @param {object} [data] Request body (optional). If present, will be automatically stringified.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name api
* @memberOf WebService.prototype
*/
api: function(action, options, data) {
options = opts(this, options);
var method = options.method || 'GET';
var args = {
action: action,
type: method,
options: options
};
if (options.query) {
args.query = options.query;
delete args.options.query;
}
if (data !== undefined) {
args.data = JSON.stringify(data);
}
return new APICall(args);
},
/**
* Get data from CloudMine.
* Results may be affected by defaults and/or by the options parameter.
* @param {string|string[]|null} [keys] If set, return the specified keys, otherwise return all keys.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
get: function(keys, options) {
if (isArray(keys)) keys = keys.join(',');
else if (isObject(keys)) {
options = keys;
keys = null;
}
options = opts(this, options);
var query = keys ? server_params(options, {keys: keys}) : null;
return new APICall({
action: 'text',
type: 'GET',
options: options,
query: query
});
},
/**
* Create new data, and merge existing data.
* The data must be convertable to JSON.
* Results may be affected by defaults and/or by the options parameter.
* @param {object} data An object hash where the top level properties are the keys.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name update
* @memberOf WebService.prototype
*/
/**
* Create new data, and merge existing data.
* The data must be convertable to JSON.
* Results may be affected by defaults and/or by the options parameter.
* @param {string|null} key The key to affect. If given null, a random key will be assigned.
* @param {string|number|object} value The value of the object
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name update^2
* @memberOf WebService.prototype
*/
update: function(key, value, options) {
if (isObject(key)) options = value;
else {
if (!key) key = this.keygen();
var out = {};
out[key] = value;
key = out;
}
options = opts(this, options);
return new APICall({
action: 'text',
type: 'POST',
options: options,
query: server_params(options),
data: JSON.stringify(key)
});
},
/**
* Create or overwrite existing objects in CloudMine with the given key or keys.
* The data must be convertable to JSON.
* Results may be affected by defaults and/or by the options parameter.
* @param {object} data An object hash where the top level properties are the keys.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name set
* @memberOf WebService.prototype
*/
/**
* Create or overwrite existing objects in CloudMine with the given key or keys.
* The data must be convertable to JSON.
* Results may be affected by defaults and/or by the options parameter.
* @param {string|null} key The key to affect. If given null, a random key will be assigned.
* @param {string|number|object} value The object to store.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name set^2
* @memberOf WebService.prototype
*/
set: function(key, value, options) {
if (isObject(key)) options = value;
else {
if (!key) key = this.keygen();
var out = {};
out[key] = value;
key = out;
}
options = opts(this, options);
return new APICall({
action: 'text',
type: 'PUT',
options: options,
query: server_params(options),
data: JSON.stringify(key)
});
},
/**
* Destroy one or more keys on the server.
* If given null and options.all is true, delete all objects on the server.
* Results may be affected by defaults and/or by the options parameter.
* @param {string|string[]|null} keys The keys to delete on the server.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters. Pass all:true with null keys to really delete all values, or query with a query object or string to delete objects matching query. WARNING: using the query is DANGEROUS. Triple check your query!
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
destroy: function(keys, options) {
options = opts(this, options);
var params = {};
if (keys == null && options.all === true) params = {all: true};
else if (options.query){
params = {q: convertQueryInput(options.query)};
delete options.query;
} else {
params = {keys: (isArray(keys) ? keys.join(',') : keys)};
}
return new APICall({
action: 'data',
type: 'DELETE',
options: options,
query: server_params(options, params)
});
},
/**
* Run a code snippet directly.
* Default http method is 'GET', to change the method set the method option for options.
* @param {string} snippet The name of the code snippet to run.
* @param {object} params Data to send to the code snippet (optional).
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
run: function(snippet, parameters, options) {
options = opts(this, options);
parameters = merge({}, options.params, parameters);
options.params = null;
options.snippet = null;
var call_opts = {
action: 'run/' + snippet,
type: options.method || 'GET',
options: options
};
if(call_opts.type === 'GET')
call_opts.query = parameters;
else {
call_opts.data = JSON.stringify(parameters);
}
return new APICall(call_opts);
},
/**
* Search CloudMine for text objects.
* Results may be affected by defaults and/or by the options parameter.
* @param {string} query Query parameters to search for.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
search: function(query, options) {
options = opts(this, options);
query = {q: query != null ? convertQueryInput(query) : ''}
var data = undefined;
if(options.method === "POST"){
data = JSON.stringify(query);
query = {}; // don't send q in URL
}
return new APICall({
action: 'search',
type: options.method || 'GET',
query: server_params(options, query),
data: data,
options: options
});
},
/**
* Search CloudMine for text objects.
* Results may be affected by defaults and/or by the options parameter.
* @param {string} klass The Elasticsearch __class__ you want to query.
* @param {string} query The Elasticsearch query to be executed.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
searchES: function(klass, query, options) {
if(isObject(query)) query = JSON.stringify(query);
options = opts(this, options);
options.version = 'v2';
return new APICall({
action: 'class/' + klass + '/elasticsearch',
type: 'POST',
data: query,
options: options
});
},
/**
* Search CloudMine for user-level ACLs.
* Results may be affected by defaults and/or by the options parameter.
* @param {string} query The query to be used when searching for target ACLs.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
searchACLs: function(query, options) {
query = {q: query != null ? convertQueryInput(query) : ''}
options = opts(this, options);
return new APICall({
action: 'access/search',
type: 'GET',
query: server_params(options, query),
options: options
});
},
/**
* Search CloudMine explicitly querying for files.
* Note: This does not search the contents of files.
* Results may be affected by defaults and/or by the options parameter.
* @param {string} query Additional query parameters to search for.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
searchFiles: function (query, options) {
query = convertQueryInput(query);
var newQuery = '[__type__ = "file"';
if (!query || query.replace(/\s+/, '').length == 0) {
newQuery += ']';
} else if (query[0] != '[') {
newQuery += '].' + query;
} else {
newQuery += (query[1] == ']' ? '' : ', ') + query.substring(1);
}
return this.search(newQuery, options);
},
/**
* Search CloudMine user objects by custom attributes.
* Results may be affected by defaults and/or by the options parameter.
* @param {string} query Additional query parameters to search for in [key="value", key="value"] format.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name searchUsers
* @memberOf WebService.prototype
*/
/**
* Search CloudMine user objects by custom attributes.
* Results may be affected by defaults and/or by the options parameter.
* @param {object} query Additional query parameters to search for in {key: value, key: value} format.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name searchUsers^2
* @memberOf WebService.prototype
*/
searchUsers: function(query, options) {
query = {p: query != null ? convertQueryInput(query) : ''}
options = opts(this, options);
return new APICall({
action: 'account/search',
type: 'GET',
query: server_params(options, query),
options: options
});
},
/**
* Get all user objects.
* Results may be affected by defaults and/or by the options parameter.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
allUsers: function(options) {
options = opts(this, options);
return new APICall({
action: 'account',
type: 'GET',
query: server_params(options),
options: options
});
},
/**
* Sends a push notification to your users.
* This requires an API key with push permission.
* @param {object} [notification] A notification object. This object can have one or more fields for dispatching the notification.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
pushNotification: function(notification, options) {
options = opts(this, options);
return new APICall({
action: 'push',
type: 'POST',
query: server_params(options),
options: options,
data: JSON.stringify(notification)
});
},
/**
* Get specific user by id.
* @param {string} id User id being requested.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* Results may be affected by defaults and/or by the options parameter.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
getUser: function(id, options) {
options = opts(this, options);
return new APICall({
action: 'account/' + id,
type: 'GET',
query: server_params(options),
options: options
});
},
/**
* Search using CloudMine's geoquery API.
* @param {string} field Field to search on.
* @param {number} longitude The longitude to search for objects at.
* @param {number} latitude The latitude to search for objects at.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @param {string} [options.units = 'km'] The unit to use when not specified for. Can be 'km', 'mi', 'm', 'ft'.
* @param {boolean} [options.distance = false] If true, include distance calculations in the meta result for objects.
* @param {string|number} [options.radius] Distance around the target. If string, include units. If number, specify the unit in options.unit.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
/**
* Search using CloudMine's geoquery API.
* @param {string} field Field to search on.
* @param {object} target A reference object that has geo-location data.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @param {string} [options.units = 'km'] The unit to use when not specified for. Can be 'km', 'mi', 'm', 'ft'.
* @param {boolean} [options.distance = false] If true, include distance calculations in the meta result for objects.
* @param {string|number} [options.radius] Distance around the target. If string, include units. If number, specify the unit in options.unit.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name searchGeo^2
* @memberOf WebService.prototype
*/
searchGeo: function(field, longitude, latitude, options) {
var geo, options;
// Source is 1 argument for object, 2 for lat/long
if (isObject(longitude)) {
options = latitude || {};
geo = extractGeo(longitude, field);
} else {
if (!options) options = {};
geo = extractGeo(longitude, latitude);
}
if (!geo) throw new TypeError('Parameters given do not provide geolocation data');
// Handle radius formats
var radius = options.radius;
if (isNumber(radius)) radius = ', ' + radius + (options && options.units ? options.units : 'km');
else if (isString(radius) && radius.length) {
radius = ', ' + radius;
if (!options.units) options.units = radius.match(/mi?|km|ft/)[0];
}
else radius = '';
var locTerms = (field || 'location') + ' near (' + geo.longitude + ', ' + geo.latitude + ')' + radius;
return this.search('[' + locTerms + ']', options);
},
/**
* Upload a file stored in CloudMine.
* @param {string} key The binary file's object key.
* @param {file|string} file FileAPI: A HTML5 FileAPI File object, Node.js: The filename to upload.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
upload: function(key, file, options) {
options = opts(this, options);
if (!key) key = this.keygen();
if (!options.filename) options.filename = key;
// Warning: may not necessarily use ajax to perform upload.
var apicall = new APICall({
action: 'binary/' + key,
type: 'post',
later: true,
encoding: 'binary',
options: options,
processResponse: APICall.basicResponse
});
function upload(data, type) {
if (!options.contentType) options.contentType = type || defaultType;
APICall.binaryUpload(apicall, data, options.filename, options.contentType).done();
}
if (isString(file) || (Buffer && file instanceof Buffer)) {
// Upload by filename
if (isNode) {
if (isString(file)) file = fs.readFileSync(file);
upload(file);
}
else NotSupported();
} else if (file.toDataURL) {
// Canvas will have a toDataURL function.
upload(file, 'image/png');
} else if (CanvasRenderingContext2D && file instanceof CanvasRenderingContext2D) {
upload(file.canvas, 'image/png');
} else if (isBinary(file)) {
// Binary files are base64 encoded from a buffer.
var reader = new FileReader();
/** @private */
reader.onabort = function() {
apicall.setData("FileReader aborted").abort();
}
/** @private */
reader.onerror = function(e) {
apicall.setData(e.target.error).abort();
}
/** @private */
reader.onload = function(e) {
upload(e.target.result);
}
// Don't need to transform Files to Blobs.
if (File && file instanceof File) {
if (!options.contentType && file.type != "") options.contentType = file.type;
} else {
file = new Blob([ new Uint8Array(file) ], {type: options.contentType || defaultType});
}
reader.readAsDataURL(file);
} else NotSupported();
return apicall;
},
/**
* Download a file stored in CloudMine.
* @param {string} key The binary file's object key.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @config {string} [filename] If present, the file will be downloaded directly to the computer with the
* filename given. This does not validate the filename given!
* @config {string} [mode] If buffer, automatically move returning data to either an ArrayBuffer or Buffer
* if supported. Otherwise the result will be a standard string.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
download: function(key, options) {
options = opts(this, options);
var response = {success: {}}, query;
if (options.filename) {
query = {
force_download: true,
apikey: options.apikey,
session_token: options.session_token,
filename: options.filename
}
}
var apicall = new APICall({
action: 'binary/' + key,
type: 'GET',
later: true,
encoding: 'binary',
options: options,
query: query
});
// Download file directly to computer if given a filename.
if (options.filename) {
if (isNode) {
apicall.setProcessor(function(data) {
response.success[key] = fs.writeFileSync(options.filename, data, 'binary');
return response;
}).done();
} else {
function detach() {
if (iframe.parentNode) document.body.removeChild(iframe);
}
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
setTimeout(function() { iframe.src = apicall.url; }, 25);
iframe.onload = function() {
clearTimeout(detach.timer);
detach.timer = setTimeout(detach, 5000);
};
detach.timer = setTimeout(detach, 60000);
response.success[key] = iframe;
}
apicall.done(response);
} else if (options.mode === 'buffer' && (ArrayBuffer || Buffer)) {
apicall.setProcessor(function(data) {
var buffer;
if (Buffer) {
buffer = new Buffer(data, 'binary');
} else {
buffer = new ArrayBuffer(data.length);
var charView = new Uint8Array(buffer);
for (var i = 0; i < data.length; ++i) {
charView[i] = data[i] & 0xFF;
}
}
response.success[key] = buffer;
return response;
}).done();
} else {
// Raw data return. Do not attempt to process the result.
apicall.setProcessor(function(data) {
response.success[key] = data;
return response;
}).done();
}
return apicall;
},
/**
* Create a new user.
* @param {object} data An object with an email, username, and password field.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @config {object} [options.profile] Create a user with the given user profile.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name createUser
* @memberOf WebService.prototype
*/
/**
* Create a new user.
* @param {string} auth The email to login as.
* @param {string} password The password to login as.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @config {object} [options.profile] Create a user with the given user profile.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name createUser^2
* @memberOf WebService.prototype
*/
createUser: function(auth, password, options) {
if (isObject(auth)) options = password;
else auth = {email: auth, password: password};
options = opts(this, options);
options.applevel = true;
var payload = JSON.stringify({
credentials: {
email: auth.email,
username: auth.username,
password: auth.password
},
profile: options.profile
});
return new APICall({
action: 'account/create',
type: 'POST',
options: options,
processResponse: APICall.basicResponse,
data: payload
});
},
/**
* Update user object of logged in user.
* @param {object} data An object to merge into the logged in user object.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name updateUser
* @memberOf WebService.prototype
*/
/**
* Update user object of logged in user.
* @param {string} field The field to merge into the logged in user object.
* @param {string} value The value to set the field to.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name updateUser^2
* @memberOf WebService.prototype
*/
updateUser: function(field, value, options) {
if (isObject(field)) options = value;
else {
var out = {};
out[field] = value;
field = out;
}
options = opts(this, options);
return new APICall({
action: 'account',
type: 'POST',
options: options,
query: server_params(options),
data: JSON.stringify(field)
});
},
/**
* Update a user object without having a session token. Requires the use of the master key
* @param {string} user_id the user id of the user to update.
* @param {object} profile a JSON object representing the profile
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
*/
updateUserMaster: function(user_id, profile, options) {
options = opts(this, options);
return new APICall({
action: 'account/' + user_id,
type: 'POST',
options: options,
query: server_params(options),
data: JSON.stringify(profile)
});
},
/**
* Replace a user object without having a session token. Requires the use of the master key
* @param {string} user_id the user id of the user to update.
* @param {object} profile a JSON object representing the profile
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
*/
replaceUserMaster: function(user_id, profile, options) {
options = opts(this, options);
return new APICall({
action: 'account/' + user_id,
type: 'PUT',
options: options,
query: server_params(options),
data: JSON.stringify(profile)
});
},
/**
* Change a user's password
* @param {object} data An object with email, password, and oldpassword fields.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name changePassword
* @memberOf WebService.prototype
*/
/**
* Change a user's password
* @param {string} user The email to change the password.
* @param {string} oldpassword The existing password for the user.
* @param {string} password The new password for the user.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name changePassword^2
* @memberOf WebService.prototype
*/
changePassword: function(auth, oldpassword, password, options) {
if (isObject(auth)) options = oldpassword;
else auth = {email: auth, oldpassword: oldpassword, password: password};
options = opts(this, options);
options.applevel = true;
var payload = JSON.stringify({
email: auth.email,
username: auth.username,
password: auth.oldpassword,
credentials: {
password: auth.password
}
});
return new APICall({
action: 'account/password/change',
type: 'POST',
data: payload,
options: options,
processResponse: APICall.basicResponse
});
},
/**
* Update a user password without having a session token. Requires the use of the master key
* @param {string} user_id The id of the user to change the password.
* @param {string} password The new password for the user.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
changePasswordMaster: function(user_id, password, options) {
options = opts(this, options);
var payload = JSON.stringify({
password: password
});
return new APICall({
action: 'account/' + user_id + '/password/change',
type: 'POST',
options: options,
processResponse: APICall.basicResponse,
data: payload
});
},
/**
* Change a user's credentials: user/email and/or password
* @param {object} auth An object with email, username, password, and new_password, new_email, new_username fields.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name changeCredentials
* @memberOf WebService.prototype
*/
changeCredentials: function(auth, options) {
options = opts(this, options);
options.applevel = true;
var payload = JSON.stringify({
email: auth.email,
username: auth.username,
password: auth.password,
credentials: {
password: auth.new_password,
username: auth.new_username,
email: auth.new_email
}
});
return new APICall({
action: 'account/credentials',
type: 'POST',
data: payload,
options: options,
processResponse: APICall.basicResponse
});
},
/**
* Initiate a password reset request.
* @param {string} email The email to send a reset password email to.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
resetPassword: function(email, options) {
options = opts(this, options);
options.applevel = true;
var payload = JSON.stringify({
email: email
});
return new APICall({
action: 'account/password/reset',
type: 'POST',
options: options,
processResponse: APICall.basicResponse,
data: payload
});
},
/**
* Change the password for an account from the token received from password reset.
* @param {string} token The token for password reset. Usually received by email.
* @param {string} newPassword The password to assign to the user.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
confirmReset: function(token, newPassword, options) {
options = opts(this, options);
options.applevel = true;
var payload = JSON.stringify({
password: newPassword
});
return new APICall({
action: "account/password/reset/" + token,
type: 'POST',
data: payload,
processResponse: APICall.basicResponse,
options: options
});
},
/**
* Login as a user to access user-level data.
* @param {object} data An object hash with email / username, and password fields.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name login
* @memberOf WebService.prototype
*/
/**
* Login as a user to access user-level data.
* @param {string} auth The email of the user to login as
* @param {string} password The password for the user
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name login^2
* @memberOf WebService.prototype
*/
login: function(auth, password, options) {
if (isObject(auth)) options = password;
else auth = {email: auth, password: password};
options = opts(this, options);
options.applevel = true;
// Wipe out existing login information.
this.options.email = null;
this.options.username = null;
this.options.session_token = null;
if (options.savelogin) {
store('email', null, this.options.appid);
store('username', null, this.options.appid);
store('session_token', null, this.options.appid);
}
var payload = JSON.stringify({
username: auth.username,
email: auth.email,
password: auth.password
})
var self = this;
return new APICall({
action: 'account/login',
type: 'POST',
options: options,
data: payload,
processResponse: APICall.basicResponse
}).on('success', function(data) {
if (options.savelogin) {
store('email', auth.email, self.options.appid);
store('username', auth.username, self.options.appid);
store('session_token', data.session_token, self.options.appid);
}
self.options.email = auth.email;
self.options.username = auth.username;
self.options.session_token = data.session_token;
});
},
/**
* Login a user via a social network credentials.
* This only works for browsers (i.e. not in a node.js environment) and requires user interaction (a browser window).
* @param {string} network A network to authenticate against. @see WebService.SocialNetworks
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @config {string} [options.link] If false, do not link social network to currently logged in user.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
loginSocial: function(network, options) {
// This does not work with Node.JS, or unrecognized services.
if (isNode) NotSupported();
options = opts(this, options);
options.applevel = true;
var challenge = uuid(), self = this;
var apicall = new APICall({
action: 'account/social/login/status/'+challenge,
options: options,
later: true,
processResponse: function(data) {
if (data.finished) {
self.options.session_token = data.session_token;
self.options.userid = data.profile.__id__;
data = { success: data }
}
else {
self.options.session_token = null;
self.options.userid = null;
data = { errors: [ "Login unsuccessful." ] }
}
if (options.savelogin) {
store('session_token', data.success.session_token, self.options.appid);
store('userid', data.success.profile.__id__, self.options.appid);
}
return data;
}
});
var url = this.options.apiroot+"/v1/app/"+options.appid+"/account/social/login";
var urlParams = {
service: network,
apikey: options.apikey,
challenge: challenge
};
if (this.options.session_token && options.link !== false) {
urlParams.session_token = this.options.session_token;
}
if (options.scope) urlParams.scope = options.scope;
var sep = url.indexOf("?") === -1 ? "?" : "&";
url = url + sep + stringify(urlParams);
var win = window.open(url, challenge, "width=600,height=400,menubar=0,location=0,toolbar=0,status=0");
function checkOpen() {
if (win.closed) {
clearTimeout(checkOpen.interval);
apicall.done();
}
}
checkOpen.interval = setInterval(checkOpen, 50);
return apicall;
},
/**
* Query a social network.
* Must be logged in as a user who has logged in to a social network.
* @param {object} query An object with the parameters of the query.
* @config {string} query.network A network to authenticate against. @see WebService.SocialNetworks
* @config {string} query.endpoint The endpoint to hit, on the social network side. See the social network's documentation for more details.
* @config {string} query.method HTTP verb to use when querying.
* @config {object} query.headers Extra headers to pass in the HTTP request to the social network.
* @config {object} query.params Extra parameters to pass in the HTTP request to the social network.
* @config {string} query.data Data to pass in the body of the HTTP request.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @throws {Error} If the user is not logged in.
* @throws {Error} If query.headers is truthy and not an object.
* @throws {Error} If query.params is truthy and not an object.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
socialQuery: function(query, options) {
options = opts(this, options);
if(!options.session_token) throw new Error("Must be logged in to perform a social query");
if(query.headers && !isObject(query.headers)) throw new Error("Headers must be an object");
if(query.params && !isObject(query.params)) throw new Error("Extra parameters must be an object");
var url = "social/"+query.network+"/"+query.endpoint;
var urlParams = {};
if(query.headers) urlParams.headers = query.headers;
if(query.params) urlParams.params = query.params;
var apicall = new APICall({
action: url,
type: query.method,
query: urlParams,
options: options,
data: query.data,
contentType: 'application/octet-stream'
});
return apicall;
},
/**
* Logout the current user.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*/
logout: function(options) {
options = opts(this, options);
options.applevel = true;
var token = this.options.session_token;
this.options.email = null;
this.options.username = null;
this.options.session_token = null;
if (options.savelogin) {
store('email', null, this.options.appid);
store('username', null, this.options.appid);
store('session_token', this.options.appid);
}
return new APICall({
action: 'account/logout',
type: 'POST',
processResponse: APICall.basicResponse,
headers: {
'X-CloudMine-SessionToken': token
},
options: options
});
},
/**
* Verify if the given login and password is valid.
* @param {object} data An object with email / username, and password fields.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name verify
* @memberOf WebService.prototype
*/
/**
* Verify if the given email and password is valid.
* @param {string} auth The email to login
* @param {string} password The password of the user to login
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name verify^2
* @memberOf WebService.prototype
*/
verify: function(auth, password, options) {
if (isObject(auth)) opts = password;
else auth = {email: auth, password: password};
options = opts(this, options);
options.applevel = true;
return new APICall({
action: 'account/login',
type: 'POST',
processResponse: APICall.basicResponse,
data: JSON.stringify(auth),
options: options
});
},
/**
* Delete a user.
* If you are using the master api key, omit the user password to delete the user.
* If you are not using the master api key, provide the user name and password in the corresponding
* email and password fields.
*
* @param {object} data An object that may contain email / username fields and optionally a password field.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name deleteUser
* @memberOf WebService.prototype
*/
/**
* Delete a user.
* If you are using the master api key, omit the user password to delete the user.
* If you are not using the master api key, provide the user name and password in the corresponding
* email and password fields.
*
* @param {string} email The email of the user to delete. If using a master key use a user id.
* @param {string} password The password for the account. Omit if using a master key.
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name deleteUser^2
* @memberOf WebService.prototype
*/
deleteUser: function(auth, password, options) {
if (isObject(auth)) options = password;
else auth = {email: auth, password: password}
options = opts(this, options);
options.applevel = true;
var config = {
action: 'account',
type: 'DELETE',
options: options,
processResponse: APICall.basicResponse
};
// Drop session if we are referring to ourselves.
if (auth.email == this.options.email) {
this.options.session_token = null;
this.options.email = null;
if (options.savelogin) {
store('email', null, this.options.appid);
store('username', null, this.options.appid);
store('session_token', null, this.options.appid);
}
}
if (auth.password) {
// Non-master key access
config.data = JSON.stringify({
email: auth.email,
username: auth.username,
password: auth.password
})
} else {
// Master key access
config.action += '/' + auth.email;
}
return new APICall(config);
},
/**
* Create or update an ACL rule for user-level objects. The API will automatically generate
* an id field if an __id__ attribute is not present. If it is, the ACL rule is updated.
*
* @param {object} acl The ACL object. See CloudMine documentation for reference. Example:
* {
* "__id__": "a4f84f89b2f14a87a3faa87289d72f98",
* "members": ["8490e9c8d6d64e6f8d18df334ae4f4fb", "ecced9c0c4bd41f0ab0dcb93d2840fd8"],
* "permissions": ["r", "u"],
* "segments": {
* "public": true,
* "logged_in": true
* },
* "my_extra_info": 12345
* }
*
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name updateACL
* @memberOf WebService.prototype
*/
updateACL: function(acl, options){
options = opts(this, options);
return new APICall({
action: 'access',
type: 'PUT',
processResponse: APICall.basicResponse,
data: JSON.stringify(acl),
options: options
});
},
/**
* Deletes an ACL via id.
*
* @param {string} aclid The ACL id value to be deleted.
*
* @param {object} [options] Override defaults set on WebService. See WebService constructor for parameters.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name deleteACL
* @memberOf WebService.prototype
*/
deleteACL: function(aclid, options){
options = opts(this, options);
return new APICall({
action: 'access/' + aclid,
type: 'DELETE',
processResponse: APICall.basicResponse,
options: options
});
},
/**
* Get an ACL rule for user-level objects by id.
*
* @param {string} aclid The id of the ACL object to fetch.
* @return {APICall} An APICall instance for the web service request used to attach events.
*
* @function
* @name updateACL
* @memberOf WebService.prototype
*/
getACL: function(aclid, options){
options = opts(this, options);
return new APICall({
action: 'a