Вход Регистрация
Файл: monst/oksdk.js
Строк: 559
<?php
"use strict";
var 
OKSDK = (function () {
    const 
OK_CONNECT_URL 'https://connect.ok.ru/';
    const 
OK_MOB_URL 'https://m.ok.ru/';
    const 
OK_API_SERVER 'https://api.ok.ru/';

    var 
state = {
        
app_id0app_key'',
        
sessionKey''accessToken''sessionSecretKey''apiServer''widgetServer''mobServer'',
        
baseUrl'',
        
containerfalseheader_widget''
    
};
    var 
sdk_success nop;
    var 
sdk_failure nop;
    var 
rest_counter 0;

    
// ---------------------------------------------------------------------------------------------------
    // General
    // ---------------------------------------------------------------------------------------------------

    /**
     * initializes the SDK<br/>
     * If launch parameters are not detected, switches to OAUTH (via redirect)
     *
     * @param args
     * @param {Number} args.app_id application id
     * @param {String} args.app_key application key
     * @param [args.oauth] - OAUTH configuration
     * @param {String} [args.oauth.scope='VALUABLE_ACCESS'] scope
     * @param {String} [args.oauth.url=location.href] return url
     * @param {String} [args.oauth.state=''] state for security checking
     * @param {String} [args.oauth.layout='a'] authorization layout (w - web, m - mobile)
     * @param {Function} success success callback
     * @param {Function} failure failure callback
     */
    
function init(argssuccessfailure) {
        
args.oauth args.oauth || {};
        
sdk_success isFunc(success) ? success nop;
        
sdk_failure isFunc(failure) ? failure nop;

        var 
params getRequestParameters(args['location_search'] || window.location.search);
        var 
hParams getRequestParameters(args['location_hash'] || window.location.hash);

        
state.app_id args.app_id;
        
state.app_key params["application_key"] || args.app_key;
        
state.sessionKey params["session_key"];
        
state.accessToken hParams['access_token'];
        
state.sessionSecretKey params["session_secret_key"] || hParams['session_secret_key'];
        
state.apiServer args["api_server"] || params["api_server"] || OK_API_SERVER;
        
state.widgetServer args["widget_server"] || params['widget_server'] || OK_CONNECT_URL;
        
state.mobServer args["mob_server"] || params["mob_server"] || OK_MOB_URL;
        
state.baseUrl state.apiServer "fb.do";
        
state.header_widget params['header_widget'];
        
state.container params['container'];

        if (!
state.app_id || !state.app_key) {
            
sdk_failure('Required arguments app_id/app_key not passed');
            return;
        }

        if (!
params['api_server']) {
            if ((
hParams['access_token'] == null) && (hParams['error'] == null)) {
                
window.location state.widgetServer 'oauth/authorize' +
                    
'?client_id=' args['app_id'] +
                    
'&scope=' + (args.oauth.scope || 'VALUABLE_ACCESS') +
                    
'&response_type=' 'token' +
                    
'&redirect_uri=' + (args.oauth.url || window.location.href) +
                    
'&layout=' + (args.oauth.layout || 'a') +
                    
'&state=' + (args.oauth.state || '');
                return;
            }
            if (
hParams['error'] != null) {
                
sdk_failure('Error with OAUTH authorization: ' hParams['error']);
                return;
            }
        }
        
sdk_success();
    }

    
// ---------------------------------------------------------------------------------------------------
    // REST
    // ---------------------------------------------------------------------------------------------------

    
function restLoad(url) {
        var 
script document.createElement('script');
        
script.src url;
        
script.async true;
        var 
done false;
        
script.onload script.onreadystatechange = function () {
            if (!
done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
                
done true;
                
script.onload null;
                
script.onreadystatechange null;
                if (
script && script.parentNode) {
                    
script.parentNode.removeChild(script);
                }
            }
        };
        var 
headElem document.getElementsByTagName('head')[0];
        
headElem.appendChild(script);
    }

    function 
restCallPOST(querycallback) {
        const 
xhr = new XMLHttpRequest();
        
xhr.open("POST"state.baseUrltrue);
        
xhr.setRequestHeader("Content-type""application/x-www-form-urlencoded");
        
xhr.onreadystatechange = function() {
            if (
xhr.readyState ===  XMLHttpRequest.DONE) {
                if (
xhr.status === 200) {
                    if (
isFunc(callback)) {
                        
callback("ok"xhr.responseTextnull);
                    }
                } else {
                    if (
isFunc(callback)) {
                        
callback("error"nullxhr.responseText);
                    }
                }
            }
        };
        
xhr.send(query);
    }

    
/**
     * Calls a REST request
     *
     * @param {String} method
     * @param {Object} [params]
     * @param {restCallback} [callback]
     * @param {Object} [callOpts]
     * @param {boolean} [callOpts.no_session] true if REST method prohibits session
     * @param {boolean} [callOpts.no_sig] true if no signature is required for the method
     * @param {string} [callOpts.app_secret_key] required for non-session requests
     * @param {string} [callOpts.use_post] send request via POST
     * @returns {string}
     */
    
function restCall(methodparamscallbackcallOpts) {
        
params params || {};
        
params.method method;
        
params restFillParams(params);
        if (
callOpts && callOpts.no_session) {
            
delete params['session_key'];
            
delete params['access_token'];
        }

        for (const 
key in params) {
            if (
params.hasOwnProperty(key)) {
                
let param params[key];
                if (
typeof param === 'object') {
                    
params[key] = JSON.stringify(param);
                }
            }
        }

        if (!
callOpts || !callOpts.no_sig) {
            var 
secret = (callOpts && callOpts.app_secret_key) ? callOpts.app_secret_key state.sessionSecretKey;
            
params['sig'] = calcSignature(paramssecret);
        }

        
let query "";
        for (const 
key in params) {
            if (
params.hasOwnProperty(key)) {
                if (
query.length !== 0) {
                    
query += '&';
                }
                
query += key "=" encodeURIComponent(params[key]);
            }
        }

        if (
callOpts && callOpts.use_post) {
            return 
restCallPOST(querycallback);
        }

        const 
callbackId "__oksdk__callback_" + (++rest_counter);
        
window[callbackId] = function (statusdataerror) {
            if (
isFunc(callback)) {
                
callback(statusdataerror);
            }
            
window[callbackId] = null;
            try {
                
delete window[callbackId];
            } catch (
e) {}
        };
        
restLoad(state.baseUrl '?' query "&js_callback=" callbackId);
        return 
callbackId;
    }

    
/**
     * Calculates request signature basing on the specified call arguments
     *
     * @param {Object} query
     * @param {string} [secretKey] alternative secret_key (fe: app secret key for non-session requests)
     * @returns {string}
     */
    
function calcSignatureExternal(querysecretKey) {
        return 
calcSignature(restFillParams(query), secretKey);
    }

    function 
calcSignature(querysecretKey) {
        var 
ikeys = [];
        for (
i in query) {
            
keys.push(i.toString());
        }
        
keys.sort();
        var 
sign "";
        for (
0keys.lengthi++) {
            var 
key keys[i];
            if ((
"sig" != key) && ("access_token" != key)) {
                
sign += keys[i] + '=' query[keys[i]];
            }
        }
        
sign += secretKey || state.sessionSecretKey;
        
sign encodeUtf8(sign);
        return 
md5(sign);
    }

    function 
restFillParams(params) {
        
params params || {};
        
params["application_key"] = state.app_key;
        if (
state.sessionKey) {
            
params["session_key"] = state.sessionKey;
        } else {
            
params["access_token"] = state.accessToken;
        }
        
params["format"] = 'JSON';
        return 
params;
    }

    function 
wrapCallback(successfailuredataProcessor) {
        return function(
statusdataerror) {
            if (
status == 'ok') {
                if (
isFunc(success)) success(isFunc(dataProcessor) ? dataProcessor(data) : data);
            } else {
                if (
isFunc(failure)) failure(error);
            }
        };
    }

    
// ---------------------------------------------------------------------------------------------------
    // Payment
    // ---------------------------------------------------------------------------------------------------

    
function paymentShow(productNameproductPriceproductCodeoptions) {
        var 
params = {};
        
params['name'] = productName;
        
params['price'] = productPrice;
        
params['code'] = productCode;

        
options options || {};
        const 
host options['mob_pay_url'] || state.mobServer;

        
params["application_key"] = state.app_key;
        if (
state.sessionKey) {
            
params["session_key"] = state.sessionKey;
        } else {
            
params["access_token"] = state.accessToken;
        }
        
params['sig'] = calcSignature(paramsstate.sessionSecretKey);

        var 
query host 'api/show_payment?';
        for (var 
key in params) {
            if (
params.hasOwnProperty(key)) {
                
query += key "=" encodeURIComponent(params[key]) + "&";
            }
        }

        
window.open(query);
    }

    
// ---------------------------------------------------------------------------------------------------
    // Widgets
    // ---------------------------------------------------------------------------------------------------

    
const WIDGET_SIGNED_ARGS = ["st.attachment""st.return""st.redirect_uri""st.state"];

    
/**
     * Returns HTML to be used as a back button for mobile app<br/>
     * If back button is required (like js app opened in browser from native mobile app) the required html
     * will be returned in #onSucсess callback
     * @param {onSuccessCallback} onSuccess
     * @param {String} [style]
     */
    
function widgetBackButton(onSuccessstyle) {
        if (
state.container || state.accessToken) return;
        
restCall('widget.getWidgetContent',
            {
widstate.header_widget || 'mobile-header-small'stylestyle || null},
            
wrapCallback(onSuccessnull, function(data) {
                return 
decodeUtf8(atob(data))
            }));
    }

    
/**
     * Opens mediatopic post widget
     *
     * @param {String} returnUrl callback url (if null, result will be posted via postmessage and popup closed)
     * @param {Object} options options
     * @param {Object} options.attachment mediatopic (feed) to be posted
     */
    
function widgetMediatopicPost(returnUrloptions) {
        
options options || {};
        if (!
options.attachment) {
            
options = {attachmentoptions}
        }
        
options.attachment btoa(unescape(encodeURIComponent(toString(options.attachment))));
        
widgetOpen('WidgetMediatopicPost'optionsreturnUrl);
    }

    
/**
     * Opens app invite widget (invite friends to app)
     *
     * @see widgetSuggest widgetSuggest() for more details on arguments
     */
    
function widgetInvite(returnUrloptions) {
        
widgetOpen('WidgetInvite'optionsreturnUrl);
    }

    
/**
     * Opens app suggest widget (suggest app to friends, both already playing and not yet)
     *
     * @param {String} returnUrl callback url (if null, result will be posted via postmessage and popup closed)
     * @param {Object} [options] options
     * @param {int} [options.autosel] amount of friends to be preselected
     * @param {String} [options.comment] default text set in the suggestion text field
     * @param {String} [options.custom_args] custom args to be passed when app opened from suggestion
     * @param {String} [options.state] custom args to be passed to return url
     * @param {String} [options.target] comma-separated friend IDs that should be preselected by default
     */
    
function widgetSuggest(returnUrloptions) {
        
widgetOpen('WidgetSuggest'optionsreturnUrl);
    }

    function 
widgetOpen(widgetargsreturnUrl) {
        
args args || {};
        if (
returnUrl !== null) {
            
args.return = returnUrl;
        }

        var 
keys = [];
        for (var 
arg in args) {
            
keys.push(arg.toString());
        }
        
keys.sort();

        var 
sigSource '';
        var 
query state.widgetServer 'dk?st.cmd=' widget '&st.app=' state.app_id;
        for (var 
0keys.lengthi++) {
            var 
key "st." keys[i];
            var 
val args[keys[i]];
            if (
WIDGET_SIGNED_ARGS.indexOf(key) != -1) {
                
sigSource += key "=" val;
            }
            
query += "&" key "=" encodeURIComponent(val);
        }
        
sigSource += state.sessionSecretKey;
        
query += '&st.signature=' md5(sigSource);
        if (
state.accessToken != null) {
            
query += '&st.access_token=' state.accessToken;
        }
        if (
state.sessionKey) {
            
query += '&st.session_key=' state.sessionKey;
        }
        
window.open(query);
    }

    
// ---------------------------------------------------------------------------------------------------
    // Utils
    // ---------------------------------------------------------------------------------------------------

    /**
     * calculates md5 of a string
     * @param {String} str
     * @returns {String}
     */
    
function md5(str) {
        const 
hex_chr "0123456789abcdef";

        function 
rhex(num) {
            
let str "";
            for (
let j 0<= 3j++) {
                
str += hex_chr.charAt((num >> (4)) & 0x0F) +
                    
hex_chr.charAt((num >> (8)) & 0x0F);
            }
            return 
str;
        }

        
/*
         * Convert a string to a sequence of 16-word blocks, stored as an array.
         * Append padding bits and the length, as described in the MD5 standard.
         */
        
function str2blks_MD5(str) {
            
let nblk = ((str.length 8) >> 6) + 1;
            
let blks = new Array(nblk 16);
            
let i 0;
            for (
0nblk 16i++) {
                
blks[i] = 0;
            }
            for (
0str.lengthi++) {
                
blks[>> 2] |= str.charCodeAt(i) << ((4) * 8);
            }
            
blks[>> 2] |= 0x80 << ((4) * 8);
            
blks[nblk 16 2] = str.length 8;
            return 
blks;
        }

        
/*
         * Add integers, wrapping at 2^32. This uses 16-bit operations internally
         * to work around bugs in some JS interpreters.
         */
        
function add(xy) {
            
let lsw = (0xFFFF) + (0xFFFF);
            
let msw = (>> 16) + (>> 16) + (lsw >> 16);
            return (
msw << 16) | (lsw 0xFFFF);
        }

        
/*
         * Bitwise rotate a 32-bit number to the left
         */
        
function rol(numcnt) {
            return (
num << cnt) | (num >>> (32 cnt));
        }

        
/*
         * These functions implement the basic operation for each round of the
         * algorithm.
         */
        
function cmn(qabxst) {
            return 
add(rol(add(add(aq), add(xt)), s), b);
        }

        function 
ff(abcdxst) {
            return 
cmn((c) | ((~b) & d), abxst);
        }

        function 
gg(abcdxst) {
            return 
cmn((d) | (& (~d)), abxst);
        }

        function 
hh(abcdxst) {
            return 
cmn(dabxst);
        }

        function 
ii(abcdxst) {
            return 
cmn(^ (| (~d)), abxst);
        }

        
let x str2blks_MD5(str);
        
let a 1732584193;
        
let b = -271733879;
        
let c = -1732584194;
        
let d 271733878;

        for (
let i 0x.length+= 16) {
            const 
olda a;
            const 
oldb b;
            const 
oldc c;
            const 
oldd d;

            
ff(abcdx[0], 7, -680876936);
            
ff(dabcx[1], 12, -389564586);
            
ff(cdabx[2], 17606105819);
            
ff(bcdax[3], 22, -1044525330);
            
ff(abcdx[4], 7, -176418897);
            
ff(dabcx[5], 121200080426);
            
ff(cdabx[6], 17, -1473231341);
            
ff(bcdax[7], 22, -45705983);
            
ff(abcdx[8], 71770035416);
            
ff(dabcx[9], 12, -1958414417);
            
ff(cdabx[10], 17, -42063);
            
ff(bcdax[11], 22, -1990404162);
            
ff(abcdx[12], 71804603682);
            
ff(dabcx[13], 12, -40341101);
            
ff(cdabx[14], 17, -1502002290);
            
ff(bcdax[15], 221236535329);

            
gg(abcdx[1], 5, -165796510);
            
gg(dabcx[6], 9, -1069501632);
            
gg(cdabx[11], 14643717713);
            
gg(bcdax[0], 20, -373897302);
            
gg(abcdx[5], 5, -701558691);
            
gg(dabcx[10], 938016083);
            
gg(cdabx[15], 14, -660478335);
            
gg(bcdax[4], 20, -405537848);
            
gg(abcdx[9], 5568446438);
            
gg(dabcx[14], 9, -1019803690);
            
gg(cdabx[3], 14, -187363961);
            
gg(bcdax[8], 201163531501);
            
gg(abcdx[13], 5, -1444681467);
            
gg(dabcx[2], 9, -51403784);
            
gg(cdabx[7], 141735328473);
            
gg(bcdax[12], 20, -1926607734);

            
hh(abcdx[5], 4, -378558);
            
hh(dabcx[8], 11, -2022574463);
            
hh(cdabx[11], 161839030562);
            
hh(bcdax[14], 23, -35309556);
            
hh(abcdx[1], 4, -1530992060);
            
hh(dabcx[4], 111272893353);
            
hh(cdabx[7], 16, -155497632);
            
hh(bcdax[10], 23, -1094730640);
            
hh(abcdx[13], 4681279174);
            
hh(dabcx[0], 11, -358537222);
            
hh(cdabx[3], 16, -722521979);
            
hh(bcdax[6], 2376029189);
            
hh(abcdx[9], 4, -640364487);
            
hh(dabcx[12], 11, -421815835);
            
hh(cdabx[15], 16530742520);
            
hh(bcdax[2], 23, -995338651);

            
ii(abcdx[0], 6, -198630844);
            
ii(dabcx[7], 101126891415);
            
ii(cdabx[14], 15, -1416354905);
            
ii(bcdax[5], 21, -57434055);
            
ii(abcdx[12], 61700485571);
            
ii(dabcx[3], 10, -1894986606);
            
ii(cdabx[10], 15, -1051523);
            
ii(bcdax[1], 21, -2054922799);
            
ii(abcdx[8], 61873313359);
            
ii(dabcx[15], 10, -30611744);
            
ii(cdabx[6], 15, -1560198380);
            
ii(bcdax[13], 211309151649);
            
ii(abcdx[4], 6, -145523070);
            
ii(dabcx[11], 10, -1120210379);
            
ii(cdabx[2], 15718787259);
            
ii(bcdax[9], 21, -343485551);

            
add(aolda);
            
add(boldb);
            
add(coldc);
            
add(doldd);
        }
        return 
rhex(a) + rhex(b) + rhex(c) + rhex(d);
    }

    function 
isFunc(obj) {
        return 
Object.prototype.toString.call(obj) === "[object Function]";
    }

    function 
isString(obj) {
        return 
Object.prototype.toString.call(obj) === "[object String]";
    }

    function 
toString(obj) {
        return 
isString(obj) ? obj JSON.stringify(obj);
    }

    
/**
     * Parses parameters to a JS map<br/>
     * Supports both window.location.search and window.location.hash)
     * @param {String} [source=window.location.search] string to parse
     * @returns {Object}
     */
    
function getRequestParameters(source) {
        var 
res = {};
        var 
url source || window.location.search;
        if (
url) {
            
url url.substr(1);    // Drop the leading '?' / '#'
            
var nameValues url.split("&");

            for (var 
0nameValues.lengthi++) {
                var 
nameValue nameValues[i].split("=");
                var 
name nameValue[0];
                var 
value nameValue[1];
                
value decodeURIComponent(value.replace(/+/g" "));
                
res[name] = value;
            }
        }
        return 
res;
    }

    function 
encodeUtf8(string) {
        return 
unescape(encodeURIComponent(string));
    }

    function 
decodeUtf8(utftext) {
        return 
decodeURIComponent(escape(utftext));
    }

    
/** stub func */
    
function nop() {}

    
/**
     * @callback onSuccessCallback
     * @param {String} result
     */

    /**
     * @callback restCallback
     * @param {String} code (either 'ok' or 'error')
     * @param {Object} data success data
     * @param {Object} error error data
     */

    // ---------------------------------------------------------------------------------------------------
    
return {
        
initinit,
        
REST: {
            
callrestCall,
            
calcSignaturecalcSignatureExternal
        
},
        
Payment: {
            
showpaymentShow
        
},
        
Widgets: {
            
getBackButtonHtmlwidgetBackButton,
            
postwidgetMediatopicPost,
            
invitewidgetInvite,
            
suggestwidgetSuggest
        
},
        
Util: {
            
md5md5,
            
encodeUtf8encodeUtf8,
            
decodeUtf8decodeUtf8,
            
encodeBase64btoa,
            
decodeBase64atob,
            
getRequestParametersgetRequestParameters,
            
toStringtoString
        
}
    };
})();
?>
Онлайн: 0
Реклама