Mercurial > summit-idp
view static-files/js/api.js @ 60:be00b5be37d6
half-baked proof of concept for popup auth flow.
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Mon, 28 Jun 2010 22:31:00 -0700 |
parents | ce0fb8a780a4 |
children | 2d981c2a7f9a |
line wrap: on
line source
( // Set up the public API for the Summit IDP. function(window) { // parseUri 1.2.2 // (c) Steven Levithan <stevenlevithan.com> // MIT License function parseUri (str) { var o = parseUri.options, m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), uri = {}, i = 14; while (i--) uri[o.key[i]] = m[i] || ""; uri[o.q.name] = {}; uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { if ($1) uri[o.q.name][$1] = $2; }); return uri; }; parseUri.options = { strictMode: false, key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], q: { name: "queryKey", parser: /(?:^|&)([^&=]*)=?([^&]*)/g }, parser: { strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ } }; var currId = 0; function MessageBroker(handlers, postMessage) { var awaitingResponses = {}; function sendResponse(id, value, target) { } this.callCmd = function callCmd(cmd, options, cb) { var msg = { type: "cmd", name: cmd, id: ++currId, options: options }; if (cb) { awaitingResponses[currId] = cb; msg.cb = true; } postMessage(msg); }; this.onMessage = function onMessage(msg, origin, source) { switch (msg.type) { case "response": if (msg.id in awaitingResponses) { var cb = awaitingResponses[msg.id]; delete awaitingResponses[msg.id]; cb(msg.value); } break; case "cmd": var handler = msg.name; if (handler in handlers) { var cb = undefined; if (msg.cb) cb = function(response) { postMessage({type: "response", id: msg.id, value: response }, source); }; handlers[handler](msg.options, cb, origin); } break; } }; } function Server(handlers) { var broker = new MessageBroker(handlers, postMessage); var originBrokers = {}; function brokerForOrigin(origin) { function postMessage(msg, target) { target.postMessage(JSON.stringify(msg), origin); } return new MessageBroker(handlers, postMessage); } function onMessage(event) { if (!(event.origin in originBrokers)) originBrokers[event.origin] = brokerForOrigin(event.origin); try { var obj = JSON.parse(event.data); } catch (e) { return; } originBrokers[event.origin].onMessage(obj, event.origin, event.source); } window.addEventListener("message", onMessage, false); } function GenericClient(origin, url, otherWindow) { var broker = new MessageBroker({}, postMessage); var queuedMessages = []; if (!otherWindow) { var iframe = window.document.createElement("iframe"); iframe.src = url; iframe.onload = function() { otherWindow = iframe.contentWindow; queuedMessages.forEach(postMessage); queuedMessages = []; }; iframe.style.display = "none"; window.document.documentElement.appendChild(iframe); } function postMessage(msg) { if (!otherWindow) queuedMessages.push(msg); else otherWindow.postMessage(JSON.stringify(msg), origin); } function onMessage(event) { if (event.origin == origin) { try { var obj = JSON.parse(event.data); } catch (e) { return; } broker.onMessage(obj, event.origin, event.source); } } this.callCmd = broker.callCmd; window.addEventListener("message", onMessage, false); }; function Client(url) { if (url === undefined) url = "."; var parsed = parseUri(url); if (parsed.protocol == "") { var a = window.document.createElement("a"); a.href = url; window.document.documentElement.appendChild(a); url = a.href; window.document.documentElement.removeChild(a); parsed = parseUri(url); } if (parsed.protocol != "http" && parsed.protocol != "https") throw new Error("invalid server URL: " + url); var self = this; var origin = parsed.protocol + "://" + parsed.authority; var client = new GenericClient(origin, url + "server.html"); function addMethod(name) { self[name] = function(options, cb) { if (typeof(options) == "function" && !cb) { cb = options; options = null; } client.callCmd(name, options, cb); }; } addMethod("getAllUsers"); self.authorize = function authorize(cb) { var popup = window.open(url + "confirm.html", null, "width=640,height=480"); window.addEventListener( "message", function waitForReady(event) { if (event.source == popup && event.data == "ready") { window.removeEventListener("message", waitForReady, false); var popupClient = new GenericClient(origin, null, popup); popupClient.callCmd( "requestAccess", null, function(response) { popup.close(); cb(response); } ); } }, false ); }; } window.Summit = { Client: Client, Server: Server }; } )(window);