--- /dev/null
+// Force HTTPS - agnostic of which htaccess to use
+// https://stackoverflow.com/questions/4723213/detect-http-or-https-then-force-https-in-javascript
+if (location.protocol !== 'https:') {
+ location.replace(`https:${location.href.substring(location.protocol.length)}`);
+}
+
+// Temporary host: the non-production VM inside matrix.mit.edu
+const API_HOST = "https://uplink.mit.edu";
+
+document.getElementById("fingerToFull").addEventListener("click", function (ev) {
+ document.getElementById("fingerName").value = moira_user_info.full_name;
+});
+
+async function loadUserInfo() {
+ const response = await fetch(API_HOST + "/users/me/", {
+ headers: {
+ "Authorization": "webathena " + webathena_base64,
+ }
+ });
+ const json = await response.json();
+ console.log(json);
+ document.getElementById("displayName").innerText = json.full_name;
+
+ // Set global variable
+ moira_user_info = json;
+}
+
+async function loadFinger() {
+ const response = await fetch(API_HOST + "/users/me/finger", {
+ headers: {
+ "Authorization": "webathena " + webathena_base64,
+ }
+ });
+ const json = await response.json();
+ document.getElementById("fingerName").value = json.fullname;
+ console.log(json);
+
+ // Set global variable
+ moira_finger = json;
+}
+
+async function onLogin() {
+ document.getElementById("login").hidden = true;
+ await loadUserInfo();
+ await loadFinger();
+ document.getElementById("loading").hidden = true;
+ document.getElementById("names").hidden = false;
+}
+
+document.getElementById("apply").addEventListener("click", async function (ev) {
+ document.getElementById("applied").hidden = true;
+ document.getElementById("loading").hidden = false;
+ document.getElementById("names").hidden = true;
+ const input = {
+ fullname: document.getElementById("fingerName").value,
+ };
+ const response = await fetch(API_HOST + "/users/me/finger", {
+ method: "PATCH",
+ headers: {
+ "Authorization": "webathena " + webathena_base64,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(input),
+ });
+ console.log(response);
+ if (response.status === 200) {
+ await onLogin();
+ document.getElementById("applied").hidden = false;
+ } else {
+ const json = await(response.json());
+ console.log(json);
+ document.getElementById("loading").hidden = false;
+ alert(`An error occured: ${json.name}`);
+ }
+});
\ No newline at end of file
--- /dev/null
+;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.
+ if (navigator.appName === 'Microsoft Internet Explorer') {
+ var ua = navigator.userAgent;
+ var re = new RegExp("MSIE ([0-9]{1,}[\.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
+ 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;
+ var origin = loc.protocol + '//' + loc.host;
+ for (var i = frames.length - 1; i >= 0; i--) {
+ try {
+ if (frames[i].location.href.indexOf(origin) === 0 &&
+ 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 = window.open(opts.url, opts.window_name, opts.window_features);
+
+ if (!messageTarget) messageTarget = w;
+
+ var req = JSON.stringify({a: 'request', d: opts.params});
+
+ // cleanup on unload
+ function cleanup() {
+ if (iframe) document.body.removeChild(iframe);
+ iframe = undefined;
+ 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) {
+ try {
+ var d = JSON.parse(e.data);
+ if (d.a === 'ready') messageTarget.postMessage(req, origin);
+ else if (d.a === 'error') {
+ if (cb) {
+ cb(d.d);
+ cb = null;
+ }
+ } else if (d.a === 'response') {
+ removeListener(window, 'message', onMessage);
+ removeListener(window, 'unload', cleanup);
+ 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);
+ }
+ };
+ }
+})();