UNPKG

cloudmine

Version:

CloudMine JavaScript library for node and browsers

1,309 lines (1,185 loc) 87.7 kB
/* 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