HEX
Server: Apache/2.2.34 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141
System: Linux Kou-Etsu-Dou 4.4.59+ #25556 SMP PREEMPT Thu Mar 4 18:03:46 CST 2021 x86_64
User: hosam (1026)
PHP: 7.2.29
Disabled: NONE
Upload Files
File: /volume1/@appstore/SynologyApplicationService/ui/browser_pair/js/webpush.js
(function (root) {
	SYNO = root.SYNO || {};
	SYNO.WebPush = {};

	/* browser related utils */
	SYNO.isChrome = function() {
		return (/\bchrome\b/.test(navigator.userAgent.toLowerCase()));
	};

	SYNO.isSafari = function() {
		return !SYNO.isChrome() && (/safari/.test(navigator.userAgent.toLowerCase()));
	};

	SYNO.isFirefox = function() {
		return (navigator.userAgent.toLowerCase().indexOf('firefox') > -1);
	};

	SYNO.GetBrowserName = function() {
		if (SYNO.isChrome()) {
			return 'Chrome';
		} else if (SYNO.isSafari()) {
			return 'Safari';
		} else if (SYNO.isFirefox()) {
			return 'Firefox';
		}

		return 'unknown';
	};

	SYNO.GetBrowserVersion = function() {
		var version = 'unknown';
		var match;

		if (SYNO.isChrome()) {
			match = navigator.userAgent.match(/(chrome)\/([\d.]*)/i);

			if (match) {
				version = match[2];
			}
		} else if (SYNO.isSafari()) {
			match = navigator.userAgent.match(/(safari)\/([\d.]*)/i);

			if (match) {
				version = match[2];
			}
		} else if (SYNO.isFirefox()) {
			match = navigator.userAgent.match(/(Firefox)\/([\d.]*)/i);

			if (match) {
				version = match[2];
			}
		}

		return version;
	};

	SYNO.WebPush.SERVICE_WORKER_URL = './service-worker.js';

	SYNO.WebPush.isSupported = function(platform) {
		if (location.protocol == "http:") {
			// TODO: domain name + valid certificate
			return false;
		}

		if (!SYNO.isChrome() && !SYNO.isFirefox()) {
			return false;
		}

		if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
			// Service Worker basic support IE: X, Safari: X, Chrome: 40.0+, Firefox: 44.0+
			return false;
		}

		if (SYNO.isChrome() && (SYNO.GetBrowserVersion() < 52)) {
			return false;
		}

		// Ignore platform not support NodeJS: 6281 and qoriq
		if (platform.indexOf('6281') != -1 || platform.indexOf('qoriq') != -1) {
			return false;
		}

		return true;
	};

	SYNO.WebPush.registerServiceWorker = function() {
		if (('serviceWorker' in navigator) && ('PushManager' in window)) {
			return navigator.serviceWorker.register(SYNO.WebPush.SERVICE_WORKER_URL, {scope: '/'})
				.then(function(reg) {
					if (reg.update) {
						// 1. install new worker if is not byte-by-byte identical
						// 2. bypasses any browser caches if the previous fetch occurred over 24 hours ago
						reg.update();
					}
					return reg;
				})['catch'](function(error) {
					console.error("serviceWorker.register failed");
					return Promise.reject(error);
				});
		} else {
			console.error("browser not support");
			return Promise.reject();
		}
	};

	SYNO.WebPush.getSWRegistration = function() {
		return navigator.serviceWorker.getRegistration(SYNO.WebPush.SERVICE_WORKER_URL);
	};

	SYNO.WebPush.getEndpoint = function() {
		return SYNO.WebPush.getSWRegistration()
			.then(function(reg) {
				if (!reg) {
					return Promise.reject();
				}

				return reg.pushManager.getSubscription();
			})
		.then(function(subscription) {
			if (!subscription || !subscription.endpoint) {
				return Promise.reject();
			}

			return Promise.resolve(subscription.endpoint);
		});
	};

	SYNO.WebPush.subscribeNotification = function(reg, appServerKey) {
		var appKey = (appServerKey + "====".substr(appServerKey.length % 4))
						.replace(/\-/g, "+")
						.replace(/\_/g, "/");

		return reg.pushManager.subscribe({
				userVisibleOnly: true,
				applicationServerKey: SYNO.SAS.sodium.from_base64(appKey)
			})
			.then(function(subscription){
				var data = {};
				if (!subscription.endpoint || !subscription.getKey) {
					console.error("no endpoint or getKey, subscription: " + JSON.stringify(subscription));
					return Promise.reject();
				}

				data.endpoint = subscription.endpoint;
				try {
					data.p256dh = SYNO.SAS.sodium.to_base64(new Uint8Array(subscription.getKey('p256dh')))
								.replace(/\=/g, '')
								.replace(/\+/g, '-')
								.replace(/\//g, '_');
				} catch(e) {
					console.error("sodium.to_base64() failed of p256dh");
					return Promise.reject();
				}
				try {
					data.auth = SYNO.SAS.sodium.to_base64(new Uint8Array(subscription.getKey('auth')))
								.replace(/\=/g, '')
								.replace(/\+/g, '-')
								.replace(/\//g, '_');
				} catch (e) {
					console.error("sodium.to_base64() failed of auth");
					return Promise.reject();
				}

				return data;
			});
	};

	SYNO.WebPush.unsubscribeNotification = function(reg) {
		return reg.pushManager.getSubscription()
			.then(function(subscription) {
				if (!subscription) {
					return true;
				}
				return subscription.unsubscribe();
			})
			.then(function(event) {
				return true;
			})
			['catch'](function(error) {
				return Promise.reject(error);
			});
	};

	if (typeof module !== 'undefined' && module.exports) {
        module.exports = SYNO;
    } else if (!root.SYNO) {
        root.SYNO = SYNO;
    }
})(this);