(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i #site-owner').html(`Site Owned by: ${ownerName}`); } $('footer > #security').empty(); if (isAuthenticated) { if (isOwner) { logoutTitle = "Sign-out"; logoutIconClass = 'fa fa-unlock fa-lg fa-fw'; } else { logoutTitle = "Not Owner : Sign-out"; logoutIconClass = 'fa fa-lock fa-lg fa-fw notOwner'; } $('footer > #security').append(``); $('footer > #security > #logout').on('click', function(e) { var myInit; e.preventDefault(); myInit = { method: 'GET', cache: 'no-cache', mode: 'same-origin', credentials: 'include' }; return fetch('/logout', myInit).then(function(response) { var user; if (response.ok) { window.isAuthenticated = false; user = ''; document.cookie = "state=loggedOut" + ";domain=." + settings.cookieDomain + "; path=/; max-age=60; sameSite=Strict;"; return update_footer(ownerName, isAuthenticated); } else { return console.log('logout failed: ', response); } }); }); if (!isClaimed) { $('footer > #security').append(""); return $('footer > #security > #claim').on('click', function(e) { e.preventDefault(); return claim_wiki(); }); } } else { if (!isClaimed) { signonTitle = 'Claim this Wiki'; } else { signonTitle = 'Wiki Owner Sign-on'; } $('footer > #security').append(``); return $('footer > #security > #show-security-dialog').on('click', function(e) { var w; e.preventDefault(); document.cookie = `wikiName=${window.location.host}` + `;domain=.${settings.cookieDomain}; path=/; max-age=300; sameSite=Strict;`; return w = WinChan.open({ url: settings.dialogURL, relay_url: settings.relayURL, window_features: "menubar=0, location=0, resizable=0, scrollbars=1, status=0, dialog=1, width=700, height=375", params: {} }, function(err, r) { if (err) { return console.log(err); } else { window.isAuthenticated = true; if (!isClaimed) { return claim_wiki(); } else { if (wiki.lineup.bestTitle() === 'Login Required') { return location.reload(); } else { return update_footer(ownerName, true); } } } }); }); } }; setup = function(user) { var lastCookie, myInit; if (!$("link[href='https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css']").length) { $('').appendTo("head"); } // signon could happen in a different window, so listen for cookie changes lastCookie = document.cookie; window.setInterval(function() { var currentCookie, myInit; currentCookie = document.cookie; if (currentCookie !== lastCookie) { console.log("Cookie changed"); if (document.cookie.match('(?:^|;)\\s?state=(.*?)(?:;|$)') !== null) { try { switch (document.cookie.match('(?:^|;)\\s?state=(.*?)(?:;|$)')[1]) { case 'loggedIn': window.isAuthenticated = true; break; case 'loggedOut': window.isAuthenticated = false; } myInit = { method: 'GET', cache: 'no-cache', mode: 'same-origin' }; fetch('/auth/client-settings.json', myInit).then(function(response) { return response.json().then(function(json) { window.isOwner = json.isOwner; return update_footer(ownerName, isAuthenticated); }); }); } catch (error) {} } return lastCookie = currentCookie; } }, 100); if (!$("link[href='/security/style.css']").length) { $('').appendTo("head"); } myInit = { method: 'GET', cache: 'no-cache', mode: 'same-origin' }; return fetch('/auth/client-settings.json', myInit).then(function(response) { if (response.ok) { return response.json().then(function(json) { var dialogHost, dialogProtocol; window.isOwner = json.isOwner; settings = json; if (settings.wikiHost) { dialogHost = settings.wikiHost; } else { dialogHost = window.location.hostname; } settings.cookieDomain = dialogHost; if (settings.useHttps) { dialogProtocol = 'https:'; } else { dialogProtocol = window.location.protocol; if (window.location.port) { dialogHost = dialogHost + ':' + window.location.port; } } settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'; settings.relayURL = dialogProtocol + '//' + dialogHost + '/auth/relay.html'; settings.dialogAddAltURL = dialogProtocol + '//' + dialogHost + '/auth/addAuthDialog'; return update_footer(ownerName, isAuthenticated); }); } else { return console.log('Unable to fetch client settings: ', response); } }); }; window.plugins.security = {setup, claim_wiki, update_footer}; },{"./winchan.js":2}],2:[function(require,module,exports){ var WinChan = (function() { var RELAY_FRAME_NAME = "__winchan_relay_frame"; var CLOSE_CMD = "die"; // a portable addListener implementation function addListener(w, event, cb) { if(w.attachEvent) w.attachEvent('on' + event, cb); else if (w.addEventListener) w.addEventListener(event, cb, false); } // a portable removeListener implementation function removeListener(w, event, cb) { if(w.detachEvent) w.detachEvent('on' + event, cb); else if (w.removeEventListener) w.removeEventListener(event, cb, false); } // checking for IE8 or above function isInternetExplorer() { var rv = -1; // Return value assumes failure. var ua = navigator.userAgent; if (navigator.appName === 'Microsoft Internet Explorer') { var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if (re.exec(ua) != null) rv = parseFloat(RegExp.$1); } // IE > 11 else if (ua.indexOf("Trident") > -1) { var re = new RegExp("rv:([0-9]{2,2}[\.0-9]{0,})"); if (re.exec(ua) !== null) { rv = parseFloat(RegExp.$1); } } return rv >= 8; } // checking Mobile Firefox (Fennec) function isFennec() { try { // We must check for both XUL and Java versions of Fennec. Both have // distinct UA strings. var userAgent = navigator.userAgent; return (userAgent.indexOf('Fennec/') != -1) || // XUL (userAgent.indexOf('Firefox/') != -1 && userAgent.indexOf('Android') != -1); // Java } catch(e) {} return false; } // feature checking to see if this platform is supported at all function isSupported() { return (window.JSON && window.JSON.stringify && window.JSON.parse && window.postMessage); } // given a URL, extract the origin. Taken from: https://github.com/firebase/firebase-simple-login/blob/d2cb95b9f812d8488bdbfba51c3a7c153ba1a074/js/src/simple-login/transports/WinChan.js#L25-L30 function extractOrigin(url) { if (!/^https?:\/\//.test(url)) url = window.location.href; var m = /^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(url); if (m) return m[1]; return url; } // find the relay iframe in the opener function findRelay() { var loc = window.location; var frames = window.opener.frames; for (var i = frames.length - 1; i >= 0; i--) { try { if (frames[i].location.protocol === window.location.protocol && frames[i].location.host === window.location.host && frames[i].name === RELAY_FRAME_NAME) { return frames[i]; } } catch(e) { } } return; } var isIE = isInternetExplorer(); if (isSupported()) { /* General flow: * 0. user clicks * (IE SPECIFIC) 1. caller adds relay iframe (served from trusted domain) to DOM * 2. caller opens window (with content from trusted domain) * 3. window on opening adds a listener to 'message' * (IE SPECIFIC) 4. window on opening finds iframe * 5. window checks if iframe is "loaded" - has a 'doPost' function yet * (IE SPECIFIC5) 5a. if iframe.doPost exists, window uses it to send ready event to caller * (IE SPECIFIC5) 5b. if iframe.doPost doesn't exist, window waits for frame ready * (IE SPECIFIC5) 5bi. once ready, window calls iframe.doPost to send ready event * 6. caller upon reciept of 'ready', sends args */ return { open: function(opts, cb) { if (!cb) throw "missing required callback argument"; // test required options var err; if (!opts.url) err = "missing required 'url' parameter"; if (!opts.relay_url) err = "missing required 'relay_url' parameter"; if (err) setTimeout(function() { cb(err); }, 0); // supply default options if (!opts.window_name) opts.window_name = null; if (!opts.window_features || isFennec()) opts.window_features = undefined; // opts.params may be undefined var iframe; // sanity check, are url and relay_url the same origin? var origin = extractOrigin(opts.url); if (origin !== extractOrigin(opts.relay_url)) { return setTimeout(function() { cb('invalid arguments: origin of url and relay_url must match'); }, 0); } var messageTarget; if (isIE) { // first we need to add a "relay" iframe to the document that's served // from the target domain. We can postmessage into a iframe, but not a // window iframe = document.createElement("iframe"); // iframe.setAttribute('name', framename); iframe.setAttribute('src', opts.relay_url); iframe.style.display = "none"; iframe.setAttribute('name', RELAY_FRAME_NAME); document.body.appendChild(iframe); messageTarget = iframe.contentWindow; } var w = opts.popup || window.open(opts.url, opts.window_name, opts.window_features); if (opts.popup) { w.location.href = opts.url; } if (!messageTarget) messageTarget = w; // lets listen in case the window blows up before telling us var closeInterval = setInterval(function() { if (w && w.closed) { cleanup(); if (cb) { cb('User closed the popup window'); cb = null; } } }, 500); var req = JSON.stringify({a: 'request', d: opts.params}); // cleanup on unload function cleanup() { if (iframe) document.body.removeChild(iframe); iframe = undefined; if (closeInterval) closeInterval = clearInterval(closeInterval); removeListener(window, 'message', onMessage); removeListener(window, 'unload', cleanup); if (w) { try { w.close(); } catch (securityViolation) { // This happens in Opera 12 sometimes // see https://github.com/mozilla/browserid/issues/1844 messageTarget.postMessage(CLOSE_CMD, origin); } } w = messageTarget = undefined; } addListener(window, 'unload', cleanup); function onMessage(e) { if (e.origin !== origin) { return; } try { var d = JSON.parse(e.data); if (d.a === 'ready') messageTarget.postMessage(req, origin); else if (d.a === 'error') { cleanup(); if (cb) { cb(d.d); cb = null; } } else if (d.a === 'response') { cleanup(); if (cb) { cb(null, d.d); cb = null; } } } catch(err) { } } addListener(window, 'message', onMessage); return { close: cleanup, focus: function() { if (w) { try { w.focus(); } catch (e) { // IE7 blows up here, do nothing } } } }; }, onOpen: function(cb) { var o = "*"; var msgTarget = isIE ? findRelay() : window.opener; if (!msgTarget) throw "can't find relay frame"; function doPost(msg) { msg = JSON.stringify(msg); if (isIE) msgTarget.doPost(msg, o); else msgTarget.postMessage(msg, o); } function onMessage(e) { // only one message gets through, but let's make sure it's actually // the message we're looking for (other code may be using // postmessage) - we do this by ensuring the payload can // be parsed, and it's got an 'a' (action) value of 'request'. var d; try { d = JSON.parse(e.data); } catch(err) { } if (!d || d.a !== 'request') return; removeListener(window, 'message', onMessage); o = e.origin; if (cb) { // this setTimeout is critically important for IE8 - // in ie8 sometimes addListener for 'message' can synchronously // cause your callback to be invoked. awesome. setTimeout(function() { cb(o, d.d, function(r) { cb = undefined; doPost({a: 'response', d: r}); }); }, 0); } } function onDie(e) { if (e.data === CLOSE_CMD) { try { window.close(); } catch (o_O) {} } } addListener(isIE ? msgTarget : window, 'message', onMessage); addListener(isIE ? msgTarget : window, 'message', onDie); // we cannot post to our parent that we're ready before the iframe // is loaded. (IE specific possible failure) try { doPost({a: "ready"}); } catch(e) { // this code should never be exectued outside IE addListener(msgTarget, 'load', function(e) { doPost({a: "ready"}); }); } // if window is unloaded and the client hasn't called cb, it's an error var onUnload = function() { try { // IE8 doesn't like this... removeListener(isIE ? msgTarget : window, 'message', onDie); } catch (ohWell) { } if (cb) doPost({ a: 'error', d: 'client closed window' }); cb = undefined; // explicitly close the window, in case the client is trying to reload or nav try { window.close(); } catch (e) { } }; addListener(window, 'unload', onUnload); return { detach: function() { removeListener(window, 'unload', onUnload); } }; } }; } else { return { open: function(url, winopts, arg, cb) { setTimeout(function() { cb("unsupported browser"); }, 0); }, onOpen: function(cb) { setTimeout(function() { cb("unsupported browser"); }, 0); } }; } })(); if (typeof module !== 'undefined' && module.exports) { module.exports = WinChan; } },{}]},{},[1]);