diff options
Diffstat (limited to 'www/wiki/resources/src/mediawiki/mediawiki.user.js')
-rw-r--r-- | www/wiki/resources/src/mediawiki/mediawiki.user.js | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/www/wiki/resources/src/mediawiki/mediawiki.user.js b/www/wiki/resources/src/mediawiki/mediawiki.user.js new file mode 100644 index 00000000..5fc19907 --- /dev/null +++ b/www/wiki/resources/src/mediawiki/mediawiki.user.js @@ -0,0 +1,189 @@ +/** + * @class mw.user + * @singleton + */ +/* global Uint32Array */ +( function ( mw, $ ) { + var userInfoPromise, stickyRandomSessionId; + + /** + * Get the current user's groups or rights + * + * @private + * @return {jQuery.Promise} + */ + function getUserInfo() { + if ( !userInfoPromise ) { + userInfoPromise = new mw.Api().getUserInfo(); + } + return userInfoPromise; + } + + // mw.user with the properties options and tokens gets defined in mediawiki.js. + $.extend( mw.user, { + + /** + * Generate a random user session ID. + * + * This information would potentially be stored in a cookie to identify a user during a + * session or series of sessions. Its uniqueness should not be depended on unless the + * browser supports the crypto API. + * + * Known problems with Math.random(): + * Using the Math.random function we have seen sets + * with 1% of non uniques among 200,000 values with Safari providing most of these. + * Given the prevalence of Safari in mobile the percentage of duplicates in + * mobile usages of this code is probably higher. + * + * Rationale: + * We need about 64 bits to make sure that probability of collision + * on 500 million (5*10^8) is <= 1% + * See https://en.wikipedia.org/wiki/Birthday_problem#Probability_table + * + * @return {string} 64 bit integer in hex format, padded + */ + generateRandomSessionId: function () { + var rnds, i, + hexRnds = new Array( 2 ), + // Support: IE 11 + crypto = window.crypto || window.msCrypto; + + if ( crypto && crypto.getRandomValues && typeof Uint32Array === 'function' ) { + // Fill an array with 2 random values, each of which is 32 bits. + // Note that Uint32Array is array-like but does not implement Array. + rnds = new Uint32Array( 2 ); + crypto.getRandomValues( rnds ); + } else { + rnds = [ + Math.floor( Math.random() * 0x100000000 ), + Math.floor( Math.random() * 0x100000000 ) + ]; + } + // Convert number to a string with 16 hex characters + for ( i = 0; i < 2; i++ ) { + // Add 0x100000000 before converting to hex and strip the extra character + // after converting to keep the leading zeros. + hexRnds[ i ] = ( rnds[ i ] + 0x100000000 ).toString( 16 ).slice( 1 ); + } + + // Concatenation of two random integers with entropy n and m + // returns a string with entropy n+m if those strings are independent + return hexRnds.join( '' ); + }, + + /** + * A sticky generateRandomSessionId for the current JS execution context, + * cached within this class. + * + * @return {string} 64 bit integer in hex format, padded + */ + stickyRandomId: function () { + if ( !stickyRandomSessionId ) { + stickyRandomSessionId = mw.user.generateRandomSessionId(); + } + + return stickyRandomSessionId; + }, + + /** + * Get the current user's database id + * + * Not to be confused with #id. + * + * @return {number} Current user's id, or 0 if user is anonymous + */ + getId: function () { + return mw.config.get( 'wgUserId' ) || 0; + }, + + /** + * Get the current user's name + * + * @return {string|null} User name string or null if user is anonymous + */ + getName: function () { + return mw.config.get( 'wgUserName' ); + }, + + /** + * Get date user registered, if available + * + * @return {boolean|null|Date} False for anonymous users, null if data is + * unavailable, or Date for when the user registered. + */ + getRegistration: function () { + var registration; + if ( mw.user.isAnon() ) { + return false; + } + registration = mw.config.get( 'wgUserRegistration' ); + // Registration may be unavailable if the user signed up before MediaWiki + // began tracking this. + return !registration ? null : new Date( registration ); + }, + + /** + * Whether the current user is anonymous + * + * @return {boolean} + */ + isAnon: function () { + return mw.user.getName() === null; + }, + + /** + * Get an automatically generated random ID (persisted in sessionStorage) + * + * This ID is ephemeral for everyone, staying in their browser only until they + * close their browsing session. + * + * @return {string} Random session ID + */ + sessionId: function () { + var sessionId = mw.storage.session.get( 'mwuser-sessionId' ); + if ( !sessionId ) { + sessionId = mw.user.generateRandomSessionId(); + mw.storage.session.set( 'mwuser-sessionId', sessionId ); + } + return sessionId; + }, + + /** + * Get the current user's name or the session ID + * + * Not to be confused with #getId. + * + * @return {string} User name or random session ID + */ + id: function () { + return mw.user.getName() || mw.user.sessionId(); + }, + + /** + * Get the current user's groups + * + * @param {Function} [callback] + * @return {jQuery.Promise} + */ + getGroups: function ( callback ) { + var userGroups = mw.config.get( 'wgUserGroups', [] ); + + // Uses promise for backwards compatibility + return $.Deferred().resolve( userGroups ).done( callback ); + }, + + /** + * Get the current user's rights + * + * @param {Function} [callback] + * @return {jQuery.Promise} + */ + getRights: function ( callback ) { + return getUserInfo().then( + function ( userInfo ) { return userInfo.rights; }, + function () { return []; } + ).done( callback ); + } + } ); + +}( mediaWiki, jQuery ) ); |