diff options
Diffstat (limited to 'js/lib/security.js')
-rw-r--r-- | js/lib/security.js | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/js/lib/security.js b/js/lib/security.js new file mode 100644 index 000000000..61aa1cfcd --- /dev/null +++ b/js/lib/security.js @@ -0,0 +1,120 @@ +/** + * Hold security-related data here + */ +elgg.provide('elgg.security'); + +elgg.security.token = {}; + +elgg.security.tokenRefreshFailed = false; + +/** + * Sets the currently active security token and updates all forms and links on the current page. + * + * @param {Object} json The json representation of a token containing __elgg_ts and __elgg_token + * @return {Void} + */ +elgg.security.setToken = function(json) { + //update the convenience object + elgg.security.token = json; + + //also update all forms + $('[name=__elgg_ts]').val(json.__elgg_ts); + $('[name=__elgg_token]').val(json.__elgg_token); + + // also update all links that contain tokens and time stamps + $('[href*="__elgg_ts"][href*="__elgg_token"]').each(function() { + this.href = this.href + .replace(/__elgg_ts=\d*/, '__elgg_ts=' + json.__elgg_ts) + .replace(/__elgg_token=[0-9a-f]*/, '__elgg_token=' + json.__elgg_token); + }); +}; + +/** + * Security tokens time out, so lets refresh those every so often. + * + * @todo handle error and bad return data + */ +elgg.security.refreshToken = function() { + elgg.action('security/refreshtoken', function(data) { + + // @todo might want to move this to setToken() once http://trac.elgg.org/ticket/3127 + // is implemented. It's here right now to avoid soggy code. + if (!data || !(data.output.__elgg_ts && data.output.__elgg_token)) { + elgg.register_error(elgg.echo('js:security:token_refresh_failed', [elgg.get_site_url()])); + elgg.security.tokenRefreshFailed = true; + + // don't setToken because we refresh every 5 minutes and tokens are good for 1 + // hour by default + return; + } + + // if had problems last time, let them know it's working now + if (elgg.security.tokenRefreshFailed) { + elgg.system_message(elgg.echo('js:security:token_refreshed', [elgg.get_site_url()])); + elgg.security.tokenRefreshFailed = false; + } + + elgg.security.setToken(data.output); + }); +}; + + +/** + * Add elgg action tokens to an object, URL, or query string (with a ?). + * + * @param {Object|string} data + * @return {Object} The new data object including action tokens + * @private + */ +elgg.security.addToken = function(data) { + + // 'http://example.com?data=sofar' + if (elgg.isString(data)) { + // is this a full URL, relative URL, or just the query string? + var parts = elgg.parse_url(data), + args = {}, + base = ''; + + if (parts['host'] == undefined) { + if (data.indexOf('?') === 0) { + // query string + base = '?'; + args = elgg.parse_str(parts['query']); + } + } else { + // full or relative URL + + if (parts['query'] != undefined) { + // with query string + args = elgg.parse_str(parts['query']); + } + var split = data.split('?'); + base = split[0] + '?'; + } + args["__elgg_ts"] = elgg.security.token.__elgg_ts; + args["__elgg_token"] = elgg.security.token.__elgg_token; + + return base + jQuery.param(args); + } + + // no input! acts like a getter + if (elgg.isUndefined(data)) { + return elgg.security.token; + } + + // {...} + if (elgg.isPlainObject(data)) { + return elgg.extend(data, elgg.security.token); + } + + // oops, don't recognize that! + throw new TypeError("elgg.security.addToken not implemented for " + (typeof data) + "s"); +}; + +elgg.security.init = function() { + //refresh security token every 5 minutes + //this is set in the js/elgg PHP view. + setInterval(elgg.security.refreshToken, elgg.security.interval); +}; + +elgg.register_hook_handler('boot', 'system', elgg.security.init);
\ No newline at end of file |