From: Gabriel Rodríguez Date: Wed, 1 May 2024 00:46:28 +0000 (-0400) Subject: add name change tool X-Git-Url: https://sipb.mit.edu:444/gitweb.cgi/wiki.git/commitdiff_plain/HEAD?ds=sidebyside add name change tool --- diff --git a/names/code.js b/names/code.js new file mode 100644 index 0000000..fd9cb67 --- /dev/null +++ b/names/code.js @@ -0,0 +1,75 @@ +// 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 diff --git a/names/index.html b/names/index.html new file mode 100644 index 0000000..ed7417c --- /dev/null +++ b/names/index.html @@ -0,0 +1,48 @@ + + + + + + Names + + + + +

Finger/Hesiod name change

+

+ +

+ + What is this? (click for more info) + + + + +
+

+
+

+ +

+
+ + + + + + + + diff --git a/names/loading.gif b/names/loading.gif new file mode 100644 index 0000000..c2146b7 Binary files /dev/null and b/names/loading.gif differ diff --git a/names/loading2.gif b/names/loading2.gif new file mode 100644 index 0000000..4219c4f Binary files /dev/null and b/names/loading2.gif differ diff --git a/names/loading3.gif b/names/loading3.gif new file mode 100644 index 0000000..a0f01dd Binary files /dev/null and b/names/loading3.gif differ diff --git a/names/pacman.gif b/names/pacman.gif new file mode 100644 index 0000000..0e24b23 Binary files /dev/null and b/names/pacman.gif differ diff --git a/names/style.css b/names/style.css new file mode 100644 index 0000000..e69de29 diff --git a/names/webathena-login.js b/names/webathena-login.js new file mode 100644 index 0000000..ece05ab --- /dev/null +++ b/names/webathena-login.js @@ -0,0 +1,40 @@ +(function () { + var WEBATHENA_HOST = "https://webathena.mit.edu"; + var REALM = "ATHENA.MIT.EDU"; + var PRINCIPAL = ["moira", "moira7.mit.edu"]; + + var button = document.getElementById("login"); + button.addEventListener("click", function (ev) { + document.getElementById("loading").hidden = false; + + WinChan.open({ + url: WEBATHENA_HOST + "/#!request_ticket_v1", + relay_url: WEBATHENA_HOST + "/relay.html", + params: { + realm: REALM, + principal: PRINCIPAL, + } + }, + function (err, r) { + if (err) { + console.log(err); + window.alert(err); + return; + } + if (r.status !== "OK") { + console.log(r); + if (r.code == "BAD_ORIGIN") { + window.alert("Please use HTTPS to connect to this URL"); + } + return; + } + console.log(r); + var session = JSON.stringify(r.session); + + // Store the encoded ticket as a global variable + webathena_base64 = btoa(session); + + onLogin(); + }); + }); +})(); diff --git a/names/winchan.js b/names/winchan.js new file mode 100644 index 0000000..5d66bcc --- /dev/null +++ b/names/winchan.js @@ -0,0 +1,271 @@ +;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); + } + }; + } +})();