Merge "Remove $wgEnotifUseJobQ"
[mediawiki.git] / resources / src / mediawiki / ForeignApi.js
blobb8cc05981951fadef77ec4bed7af6a29f513e4b4
1 ( function ( mw, $ ) {
3         /**
4          * Create an object like mw.Api, but automatically handling everything required to communicate
5          * with another MediaWiki wiki via cross-origin requests (CORS).
6          *
7          * The foreign wiki must be configured to accept requests from the current wiki. See
8          * <https://www.mediawiki.org/wiki/Manual:$wgCrossSiteAJAXdomains> for details.
9          *
10          *     var api = new mw.ForeignApi( 'https://commons.wikimedia.org/w/api.php' );
11          *     api.get( {
12          *         action: 'query',
13          *         meta: 'userinfo'
14          *     } ).done( function ( data ) {
15          *         console.log( data );
16          *     } );
17          *
18          * To ensure that the user at the foreign wiki is logged in, pass the `assert: 'user'` parameter
19          * to #get/#post (since MW 1.23): if they are not, the API request will fail. (Note that this
20          * doesn't guarantee that it's the same user.)
21          *
22          * Authentication-related MediaWiki extensions may extend this class to ensure that the user
23          * authenticated on the current wiki will be automatically authenticated on the foreign one. These
24          * extension modules should be registered using the ResourceLoaderForeignApiModules hook. See
25          * CentralAuth for a practical example. The general pattern to extend and override the name is:
26          *
27          *     function MyForeignApi() {};
28          *     OO.inheritClass( MyForeignApi, mw.ForeignApi );
29          *     mw.ForeignApi = MyForeignApi;
30          *
31          * @class mw.ForeignApi
32          * @extends mw.Api
33          * @since 1.26
34          *
35          * @constructor
36          * @param {string|mw.Uri} url URL pointing to another wiki's `api.php` endpoint.
37          * @param {Object} [options] See mw.Api.
38          *
39          * @author Bartosz DziewoƄski
40          * @author Jon Robson
41          */
42         function CoreForeignApi( url, options ) {
43                 if ( !url || $.isPlainObject( url ) ) {
44                         throw new Error( 'mw.ForeignApi() requires a `url` parameter' );
45                 }
47                 this.apiUrl = String( url );
49                 options = $.extend( /*deep=*/ true,
50                         {
51                                 ajax: {
52                                         url: this.apiUrl,
53                                         xhrFields: {
54                                                 withCredentials: true
55                                         }
56                                 },
57                                 parameters: {
58                                         // Add 'origin' query parameter to all requests.
59                                         origin: this.getOrigin()
60                                 }
61                         },
62                         options
63                 );
65                 // Call parent constructor
66                 CoreForeignApi.parent.call( this, options );
67         }
69         OO.inheritClass( CoreForeignApi, mw.Api );
71         /**
72          * Return the origin to use for API requests, in the required format (protocol, host and port, if
73          * any).
74          *
75          * @protected
76          * @return {string}
77          */
78         CoreForeignApi.prototype.getOrigin = function () {
79                 var origin = location.protocol + '//' + location.hostname;
80                 if ( location.port ) {
81                         origin += ':' + location.port;
82                 }
83                 return origin;
84         };
86         /**
87          * @inheritdoc
88          */
89         CoreForeignApi.prototype.ajax = function ( parameters, ajaxOptions ) {
90                 var url, origin, newAjaxOptions;
92                 // 'origin' query parameter must be part of the request URI, and not just POST request body
93                 if ( ajaxOptions.type === 'POST' ) {
94                         url = ( ajaxOptions && ajaxOptions.url ) || this.defaults.ajax.url;
95                         origin = ( parameters && parameters.origin ) || this.defaults.parameters.origin;
96                         url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) +
97                                 'origin=' + encodeURIComponent( origin );
98                         newAjaxOptions = $.extend( {}, ajaxOptions, { url: url } );
99                 } else {
100                         newAjaxOptions = ajaxOptions;
101                 }
103                 return CoreForeignApi.parent.prototype.ajax.call( this, parameters, newAjaxOptions );
104         };
106         // Expose
107         mw.ForeignApi = CoreForeignApi;
109 }( mediaWiki, jQuery ) );