User:PiRSquared17/CORS editing example.js

From mediawiki.org

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * CORS cross-site editing example
 * NOTE: CODE ON THIS PAGE AUTOMATICALLY EDITS test.wikipedia.org
 * I am not responsible for any edits made by this script.
 * Use this script for whatever you want (CC0 version 1, PD, WTFPL, whatever)
 */
function editForeignPage(info) {
    // Custom hooks for edit success / failure (e.g., console.log)
    var errorHook = typeof info.error === 'function', // has error function?
        successHook = typeof info.success === 'function'; // has success hook?

    // Most "modern" browsers except IE support CORS
    if (!$.support.cors) {
        info.error('Your browser does not support CORS! Try Firefox.', 'cors');
        return;
    }

    // Get the foreign edit token
    $.ajax({
        url: info.url, // e.g. "//ru.wikipedia.org/w/api.php"
        dataType: 'json',
        data: {
            action: 'tokens',
            type: 'edit',
            format: 'json',
            origin: location.origin
        },
        success: function (data) { // if we get the token
            var params;
            // Handle various possible errors (possibly not needed)
            if (!(data && data.tokens && data.tokens.edittoken) && errorHook) {
                info.error(data, 'token');
                return;
            }

            params = {
                format: 'json',
                action: 'edit',
                title: info.title,
                summary: info.summary,
                origin: location.origin,
                assert: 'user', // must be logged in! [does this even work?]
                token: data.tokens.edittoken
            };
            params[info.editaction] = info.text;
            $.ajax({
                url: info.url,
                type: 'POST',
                dataType: 'json',
                data: params,
                xhrFields: { // CORS XHR magic
                    withCredentials: true
                }
            })
                .done(function (data) {
                    // Success! Run the success function passed in ``info''
                    if (data && data.edit && data.edit.result && data.edit.result === 'Success' && successHook) {
                        info.success(data);
                    } else if (errorHook) { // error, so run error hook
                        info.error(data, 'edit');
                    }
                })
                .fail(function () { // other failure
                    if (errorHook) {
                        info.error(null, 'other');
                    }
                });
        },
        xhrFields: { // CORS XHR magic
            withCredentials: true
        }
    });
}
// Example
editForeignPage({
    url: '//test.wikipedia.org/w/api.php',
    title: 'CORS testing',
    summary: 'Testing cross-site editing using CORS',
    editaction: 'appendtext', // or prependtext, text (replace)
    text: '\nThis is a test.',
    success: function (data) {
        var diff = encodeURIComponent(data.edit.newrevid),
            cont = confirm('Your edit was successful! OK to view diff'),
            protocol = location.href.split('//')[0];
        if (cont) {
            location.href = protocol + '//test.wikipedia.org/?diff=' + diff;
        }
    },
    error: function (data, errortype) {
        alert('An error occurred! Type: ' + errortype + '; details: ' + data);
        console.error(data);
    }
});

// Interactive test
/*
var hostname = prompt('Full domain name', 'test.wikipedia.org');
editForeignPage({
    url: '//' + hostname + '/w/api.php',
    title: prompt('Enter foreign page name', 'CORS testing'),
    summary: prompt('Enter summary', 'Testing cross-site editing using CORS'),
    editaction: 'appendtext', // or prependtext, text (replace)
    text: '\n' + prompt('Text to append', 'This is a test.'),
    success: function (data) {
        var diff = encodeURIComponent(data.edit.newrevid),
            cont = confirm('Your edit was successful! OK to view diff'),
            protocol = location.href.split('//')[0];
        if (cont) {
            location.href = protocol + '//' + hostname + '/?diff=' + diff;
        }
    },
    error: function (data, errortype) {
        alert('An error occurred! Type: ' + errortype + '; details: ' + data);
    }
});
*/