Changeset 59280 in spip-zone
- Timestamp:
- Mar 13, 2012, 9:50:22 PM (9 years ago)
- Location:
- _plugins_/authentification/browserid
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
_plugins_/authentification/browserid/browserid.js.html
r54868 r59280 3 3 * Plugin BrowserID pour SPIP 4 4 * 5 * (c) Fil 201 1- Licence GNU/GPL5 * (c) Fil 2012 - Licence GNU/GPL 6 6 * 7 7 */ -
_plugins_/authentification/browserid/formulaires/login.html
r54944 r59280 3 3 * Plugin BrowserID pour SPIP 4 4 * 5 * (c) Fil 201 1- Licence GNU/GPL5 * (c) Fil 2012 - Licence GNU/GPL 6 6 * 7 7 */ 8 8 9 ]<script type="text/javascript"> 9 ] 10 11 [(#REM) 12 le formulaire de login normal continue de fonctionner ; 13 on pourrait le desactiver avec une config 14 ] 15 <div id="browserid_traditionnel"> 16 <INCLURE{fond=prive/formulaires/login,env} /> 17 </div> 18 19 20 21 <script type="text/javascript"> 10 22 [ 11 23 var url = (#ENV{url}|sinon{#EVAL{_DIR_RESTREINT_ABS}}|_q); … … 25 37 function browserid_start() { 26 38 browserid_message("connexion BrowserID en cours…"); 27 $.getScript('?page=browserid.js&v=8', browserid_login); 39 // $.getScript('?page=browserid.js&v=8', browserid_login); 40 browserid_login(); 28 41 } 29 42 </script> … … 32 45 <div class="message"></div> 33 46 </div> 34 35 [(#REM)36 le formulaire de login normal continue de fonctionner ;37 on pourrait le desactiver avec une config38 ]39 <div id="browserid_traditionnel">40 <INCLURE{fond=prive/formulaires/login,env} />41 </div>42 47 <script type="text/javascript"> 43 $("#browserid_traditionnel").hide(); 48 $("#browserid_traditionnel") 49 .hide() 50 .parent() 51 .append("<button onclick='$(\"#browserid_traditionnel\").toggle();'>login traditionnel</button>"); 44 52 </script> 45 <button onclick='$("#browserid_traditionnel").show();'>login traditionnel</button> 53 [<script src="(#URL_PAGE{browserid.js}|parametre_url{v,9})" type="text/javascript"></script>] -
_plugins_/authentification/browserid/javascript/browserid.js
r54863 r59280 2 2 * Uncompressed source can be found at https://browserid.org/include.orig.js 3 3 * 4 * ***** BEGIN LICENSE BLOCK ***** 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6 * 7 * The contents of this file are subject to the Mozilla Public License Version 8 * 1.1 (the "License"); you may not use this file except in compliance with 9 * the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14 * for the specific language governing rights and limitations under the 15 * License. 16 * 17 * The Original Code is Mozilla BrowserID. 18 * 19 * The Initial Developer of the Original Code is Mozilla. 20 * Portions created by the Initial Developer are Copyright (C) 2011 21 * the Initial Developer. All Rights Reserved. 22 * 23 * Contributor(s): 24 * 25 * Alternatively, the contents of this file may be used under the terms of 26 * either the GNU General Public License Version 2 or later (the "GPL"), or 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 * in which case the provisions of the GPL or the LGPL are applicable instead 29 * of those above. If you wish to allow use of your version of this file only 30 * under the terms of either the GPL or the LGPL, and not to allow others to 31 * use your version of this file under the terms of the MPL, indicate your 32 * decision by deleting the provisions above and replace them with the notice 33 * and other provisions required by the GPL or the LGPL. If you do not delete 34 * the provisions above, a recipient may use your version of this file under 35 * the terms of any one of the MPL, the GPL or the LGPL. 36 * 37 * ***** END LICENSE BLOCK ***** */ 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 38 7 39 8 (function() { 40 9 // this is the file that the RP includes to shim in the 41 10 // navigator.id.getVerifiedEmail() function 42 "use strict";11 // "use strict"; 43 12 44 13 // local embedded copy of jschannel: http://github.com/mozilla/jschannel 14 /** 15 * js_channel is a very lightweight abstraction on top of 16 * postMessage which defines message formats and semantics 17 * to support interactions more rich than just message passing 18 * js_channel supports: 19 * + query/response - traditional rpc 20 * + query/update/response - incremental async return of results 21 * to a query 22 * + notifications - fire and forget 23 * + error handling 24 * 25 * js_channel is based heavily on json-rpc, but is focused at the 26 * problem of inter-iframe RPC. 27 * 28 * Message types: 29 * There are 5 types of messages that can flow over this channel, 30 * and you may determine what type of message an object is by 31 * examining its parameters: 32 * 1. Requests 33 * + integer id 34 * + string method 35 * + (optional) any params 36 * 2. Callback Invocations (or just "Callbacks") 37 * + integer id 38 * + string callback 39 * + (optional) params 40 * 3. Error Responses (or just "Errors) 41 * + integer id 42 * + string error 43 * + (optional) string message 44 * 4. Responses 45 * + integer id 46 * + (optional) any result 47 * 5. Notifications 48 * + string method 49 * + (optional) any params 50 */ 45 51 var Channel = (function() { 52 "use strict"; 53 46 54 // current transaction id, start out at a random *odd* number between 1 and a million 47 55 // There is one current transaction counter id per page, and it's shared between … … 50 58 var s_curTranId = Math.floor(Math.random()*1000001); 51 59 52 // no two bound channels in the same javascript evaluation context may have the same origin & scope.53 // futher if two bound channels have the same scope, they may not have *overlapping* origins54 // (either one or both support '*'). This restriction allows a single onMessage handler to efficient 60 // no two bound channels in the same javascript evaluation context may have the same origin, scope, and window. 61 // futher if two bound channels have the same window and scope, they may not have *overlapping* origins 62 // (either one or both support '*'). This restriction allows a single onMessage handler to efficiently 55 63 // route messages based on origin and scope. The s_boundChans maps origins to scopes, to message 56 64 // handlers. Request and Notification messages are routed using this table. … … 59 67 60 68 // add a channel to s_boundChans, throwing if a dup exists 61 function s_addBoundChan(origin, scope, handler) { 69 function s_addBoundChan(win, origin, scope, handler) { 70 function hasWin(arr) { 71 for (var i = 0; i < arr.length; i++) if (arr[i].win === win) return true; 72 return false; 73 } 74 62 75 // does she exist? 63 76 var exists = false; 77 78 64 79 if (origin === '*') { 65 80 // we must check all other origins, sadly. … … 68 83 if (k === '*') continue; 69 84 if (typeof s_boundChans[k][scope] === 'object') { 70 exists = true; 85 exists = hasWin(s_boundChans[k][scope]); 86 if (exists) break; 71 87 } 72 88 } 73 89 } else { 74 90 // we must check only '*' 75 if ((s_boundChans['*'] && s_boundChans['*'][scope]) || 76 (s_boundChans[origin] && s_boundChans[origin][scope])) 91 if ((s_boundChans['*'] && s_boundChans['*'][scope])) { 92 exists = hasWin(s_boundChans['*'][scope]); 93 } 94 if (!exists && s_boundChans[origin] && s_boundChans[origin][scope]) 77 95 { 78 exists = true;79 } 80 } 81 if (exists) throw "A channel already existswhich overlaps with origin '"+ origin +"' and has scope '"+scope+"'";96 exists = hasWin(s_boundChans[origin][scope]); 97 } 98 } 99 if (exists) throw "A channel is already bound to the same window which overlaps with origin '"+ origin +"' and has scope '"+scope+"'"; 82 100 83 101 if (typeof s_boundChans[origin] != 'object') s_boundChans[origin] = { }; 84 s_boundChans[origin][scope] = handler; 85 } 86 87 function s_removeBoundChan(origin, scope) { 88 delete s_boundChans[origin][scope]; 89 // possibly leave a empty object around. whatevs. 102 if (typeof s_boundChans[origin][scope] != 'object') s_boundChans[origin][scope] = [ ]; 103 s_boundChans[origin][scope].push({win: win, handler: handler}); 104 } 105 106 function s_removeBoundChan(win, origin, scope) { 107 var arr = s_boundChans[origin][scope]; 108 for (var i = 0; i < arr.length; i++) { 109 if (arr[i].win === win) { 110 arr.splice(i,1); 111 } 112 } 113 if (s_boundChans[origin][scope].length === 0) { 114 delete s_boundChans[origin][scope] 115 } 90 116 } 91 117 … … 108 134 // is more efficient, especially for large numbers of simultaneous channels. 109 135 var s_onMessage = function(e) { 110 var m = JSON.parse(e.data); 111 if (typeof m !== 'object') return; 112 136 try { 137 var m = JSON.parse(e.data); 138 if (typeof m !== 'object' || m === null) throw "malformed"; 139 } catch(e) { 140 // just ignore any posted messages that do not consist of valid JSON 141 return; 142 } 143 144 var w = e.source; 113 145 var o = e.origin; 114 var s = null; 115 var i = null; 116 var meth = null; 146 var s, i, meth; 117 147 118 148 if (typeof m.method === 'string') { … … 128 158 if (typeof m.id !== 'undefined') i = m.id; 129 159 160 // w is message source window 130 161 // o is message origin 131 162 // m is parsed message 132 163 // s is message scope 133 // i is message id (or null)164 // i is message id (or undefined) 134 165 // meth is unscoped method name 135 166 // ^^ based on these factors we can route the message … … 138 169 // route using s_boundChans 139 170 if (typeof meth === 'string') { 171 var delivered = false; 140 172 if (s_boundChans[o] && s_boundChans[o][s]) { 141 s_boundChans[o][s](o, meth, m); 142 } else if (s_boundChans['*'] && s_boundChans['*'][s]) { 143 s_boundChans['*'][s](o, meth, m); 173 for (var i = 0; i < s_boundChans[o][s].length; i++) { 174 if (s_boundChans[o][s][i].win === w) { 175 s_boundChans[o][s][i].handler(o, meth, m); 176 delivered = true; 177 break; 178 } 179 } 180 } 181 182 if (!delivered && s_boundChans['*'] && s_boundChans['*'][s]) { 183 for (var i = 0; i < s_boundChans['*'][s].length; i++) { 184 if (s_boundChans['*'][s][i].win === w) { 185 s_boundChans['*'][s][i].handler(o, meth, m); 186 break; 187 } 188 } 144 189 } 145 190 } … … 160 205 * Arguments to Channel.build(cfg): 161 206 * 162 * cfg.window - the remote window with which we'll communicat ion207 * cfg.window - the remote window with which we'll communicate 163 208 * cfg.origin - the expected origin of the remote window, may be '*' 164 209 * which matches any origin … … 218 263 if (cfg.origin === "*") validOrigin = true; 219 264 // allow valid domains under http and https. Also, trim paths off otherwise valid origins. 220 else if (null !== (oMatch = cfg.origin.match(/^https?:\/\/(?:[-a-zA-Z0-9 \.])+(?::\d+)?/))) {221 cfg.origin = oMatch[0] ;265 else if (null !== (oMatch = cfg.origin.match(/^https?:\/\/(?:[-a-zA-Z0-9_\.])+(?::\d+)?/))) { 266 cfg.origin = oMatch[0].toLowerCase(); 222 267 validOrigin = true; 223 268 } … … 258 303 invoke: function(cbName, v) { 259 304 // verify in table 260 if (!inTbl[id]) throw "attempting to invoke a callback of a non -existant transaction: " + id;305 if (!inTbl[id]) throw "attempting to invoke a callback of a nonexistent transaction: " + id; 261 306 // verify that the callback name is valid 262 307 var valid = false; … … 270 315 completed = true; 271 316 // verify in table 272 if (!inTbl[id]) throw "error called for non -existant message: " + id;317 if (!inTbl[id]) throw "error called for nonexistent message: " + id; 273 318 274 319 // remove transaction from table … … 281 326 completed = true; 282 327 // verify in table 283 if (!inTbl[id]) throw "complete called for non -existant message: " + id;328 if (!inTbl[id]) throw "complete called for nonexistent message: " + id; 284 329 // remove transaction from table 285 330 delete inTbl[id]; … … 299 344 } 300 345 346 var setTransactionTimeout = function(transId, timeout, method) { 347 return window.setTimeout(function() { 348 if (outTbl[transId]) { 349 // XXX: what if client code raises an exception here? 350 var msg = "timeout (" + timeout + "ms) exceeded on method '" + method + "'"; 351 (1,outTbl[transId].error)("timeout_error", msg); 352 delete outTbl[transId]; 353 delete s_transIds[transId]; 354 } 355 }, timeout); 356 } 357 301 358 var onMessage = function(origin, method, m) { 302 359 // if an observer was specified at allocation time, invoke it … … 346 403 var error = "runtime_error"; 347 404 var message = null; 348 // * if it s a string then it gets an error code of 'runtime_error' and string is the message405 // * if it's a string then it gets an error code of 'runtime_error' and string is the message 349 406 if (typeof e === 'string') { 350 407 message = e; 351 408 } else if (typeof e === 'object') { 352 409 // either an array or an object 353 // * if it s an array of length two, then array[0] is the code, array[1] is the error message410 // * if it's an array of length two, then array[0] is the code, array[1] is the error message 354 411 if (e && s_isArray(e) && e.length == 2) { 355 412 error = e[0]; 356 413 message = e[1]; 357 414 } 358 // * if it s an object then we'll look form error and message parameters415 // * if it's an object then we'll look form error and message parameters 359 416 else if (typeof e.error === 'string') { 360 417 error = e.error; … … 369 426 try { 370 427 message = JSON.stringify(e); 428 /* On MSIE8, this can result in 'out of memory', which 429 * leaves message undefined. */ 430 if (typeof(message) == 'undefined') 431 message = e.toString(); 371 432 } catch (e2) { 372 433 message = e.toString(); … … 409 470 } 410 471 } 411 } ;472 } 412 473 413 474 // now register our bound channel for msg routing 414 s_addBoundChan(cfg. origin, ((typeof cfg.scope === 'string') ? cfg.scope : ''), onMessage);475 s_addBoundChan(cfg.window, cfg.origin, ((typeof cfg.scope === 'string') ? cfg.scope : ''), onMessage); 415 476 416 477 // scope method names based on cfg.scope specified when the Channel was instantiated … … 418 479 if (typeof cfg.scope === 'string' && cfg.scope.length) m = [cfg.scope, m].join("::"); 419 480 return m; 420 } ;481 } 421 482 422 483 // a small wrapper around postmessage whose primary function is to handle the … … 441 502 cfg.window.postMessage(JSON.stringify(msg), cfg.origin); 442 503 } 443 } ;504 } 444 505 445 506 var onReady = function(trans, type) { … … 485 546 if (regTbl[method]) throw "method '"+method+"' is already bound!"; 486 547 regTbl[method] = cb; 548 return this; 487 549 }, 488 550 call: function(m) { … … 517 579 if (callbackNames.length) msg.callbacks = callbackNames; 518 580 581 if (m.timeout) 582 // XXX: This function returns a timeout ID, but we don't do anything with it. 583 // We might want to keep track of it so we can cancel it using clearTimeout() 584 // when the transaction completes. 585 setTransactionTimeout(s_curTranId, m.timeout, scopeMethod(m.method)); 586 519 587 // insert into the transaction table 520 588 outTbl[s_curTranId] = { callbacks: callbacks, error: m.error, success: m.success }; … … 534 602 }, 535 603 destroy: function () { 536 s_removeBoundChan(cfg. origin, ((typeof cfg.scope === 'string') ? cfg.scope : ''));604 s_removeBoundChan(cfg.window, cfg.origin, ((typeof cfg.scope === 'string') ? cfg.scope : '')); 537 605 if (window.removeEventListener) window.removeEventListener('message', onMessage, false); 538 606 else if(window.detachEvent) window.detachEvent('onmessage', onMessage); … … 550 618 obj.bind('__ready', onReady); 551 619 setTimeout(function() { 552 postMessage({ method: scopeMethod('__ready'), params: "ping" }, true);620 // postMessage({ method: scopeMethod('__ready'), params: "ping" }, true); 553 621 }, 0); 554 622 … … 556 624 } 557 625 }; 626 })(); 627 628 // local embedded copy of winchan: http://github.com/lloyd/winchan 629 ;WinChan = (function() { 630 var RELAY_FRAME_NAME = "__winchan_relay_frame"; 631 632 // a portable addListener implementation 633 function addListener(w, event, cb) { 634 if(w.attachEvent) w.attachEvent('on' + event, cb); 635 else if (w.addEventListener) w.addEventListener(event, cb, false); 636 } 637 638 // a portable removeListener implementation 639 function removeListener(w, event, cb) { 640 if(w.detachEvent) w.detachEvent('on' + event, cb); 641 else if (w.removeEventListener) w.removeEventListener(event, cb, false); 642 } 643 644 // checking for IE8 or above 645 function isInternetExplorer() { 646 var rv = -1; // Return value assumes failure. 647 if (navigator.appName == 'Microsoft Internet Explorer') { 648 var ua = navigator.userAgent; 649 var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); 650 if (re.exec(ua) != null) 651 rv = parseFloat(RegExp.$1); 652 } 653 return rv >= 8; 654 } 655 656 // checking Mobile Firefox (Fennec) 657 function isFennec() { 658 try { 659 return (navigator.userAgent.indexOf('Fennec/') != -1); 660 } catch(e) {}; 661 return false; 662 } 663 664 // feature checking to see if this platform is supported at all 665 function isSupported() { 666 return (window.JSON && window.JSON.stringify && 667 window.JSON.parse && window.postMessage); 668 } 669 670 // given a URL, extract the origin 671 function extractOrigin(url) { 672 if (!/^https?:\/\//.test(url)) url = window.location.href; 673 var m = /^(https?:\/\/[-_a-zA-Z\.0-9:]+)/.exec(url); 674 if (m) return m[1]; 675 return url; 676 } 677 678 // find the relay iframe in the opener 679 function findRelay() { 680 var loc = window.location; 681 var frames = window.opener.frames; 682 var origin = loc.protocol + '//' + loc.host; 683 for (i = frames.length - 1; i >= 0; i++) { 684 try { 685 if (frames[i].location.href.indexOf(origin) === 0 && 686 frames[i].name === RELAY_FRAME_NAME) 687 { 688 return frames[i]; 689 } 690 } catch(e) { } 691 } 692 return; 693 } 694 695 var isIE = isInternetExplorer(); 696 697 if (isSupported()) { 698 /* General flow: 699 * 0. user clicks 700 * (IE SPECIFIC) 1. caller adds relay iframe (served from trusted domain) to DOM 701 * 2. caller opens window (with content from trusted domain) 702 * 3. window on opening adds a listener to 'message' 703 * (IE SPECIFIC) 4. window on opening finds iframe 704 * 5. window checks if iframe is "loaded" - has a 'doPost' function yet 705 * (IE SPECIFIC5) 5a. if iframe.doPost exists, window uses it to send ready event to caller 706 * (IE SPECIFIC5) 5b. if iframe.doPost doesn't exist, window waits for frame ready 707 * (IE SPECIFIC5) 5bi. once ready, window calls iframe.doPost to send ready event 708 * 6. caller upon reciept of 'ready', sends args 709 */ 710 return { 711 open: function(opts, cb) { 712 if (!cb) throw "missing required callback argument"; 713 714 // test required options 715 var err; 716 if (!opts.url) err = "missing required 'url' parameter"; 717 if (!opts.relay_url) err = "missing required 'relay_url' parameter"; 718 if (err) setTimeout(function() { cb(err); }, 0); 719 720 // supply default options 721 if (!opts.window_features || isFennec()) opts.window_features = undefined; 722 723 // opts.params may be undefined 724 725 var iframe; 726 727 // sanity check, are url and relay_url the same origin? 728 var origin = extractOrigin(opts.url); 729 if (origin !== extractOrigin(opts.relay_url)) { 730 return setTimeout(function() { 731 cb('invalid arguments: origin of url and relay_url must match'); 732 }, 0); 733 } 734 735 var messageTarget; 736 737 if (isIE) { 738 // first we need to add a "relay" iframe to the document that's served 739 // from the target domain. We can postmessage into a iframe, but not a 740 // window 741 iframe = document.createElement("iframe"); 742 // iframe.setAttribute('name', framename); 743 iframe.setAttribute('src', opts.relay_url); 744 iframe.style.display = "none"; 745 iframe.setAttribute('name', RELAY_FRAME_NAME); 746 document.body.appendChild(iframe) 747 messageTarget = iframe.contentWindow; 748 } 749 750 var w = window.open(opts.url, null, opts.window_features); 751 752 if (!messageTarget) messageTarget = w; 753 754 var req = JSON.stringify({a: 'request', d: opts.params}); 755 756 // cleanup on unload 757 function cleanup() { 758 if (iframe) document.body.removeChild(iframe); 759 iframe = undefined; 760 if (w) w.close(); 761 w = undefined; 762 } 763 764 addListener(window, 'unload', cleanup); 765 766 function onMessage(e) { 767 try { 768 var d = JSON.parse(e.data); 769 if (d.a === 'ready') messageTarget.postMessage(req, origin); 770 else if (d.a === 'error') cb(d.d); 771 else if (d.a === 'response') { 772 removeListener(window, 'message', onMessage); 773 removeListener(window, 'unload', cleanup); 774 cleanup(); 775 cb(null, d.d); 776 } 777 } catch(e) { } 778 }; 779 780 addListener(window, 'message', onMessage); 781 782 return { 783 close: cleanup, 784 focus: function() { 785 if (w) { 786 try { 787 w.focus(); 788 } 789 catch(e) { 790 /* IE7 blows up here, do nothing */ 791 } 792 } 793 } 794 }; 795 } 796 } 797 } else { 798 return { 799 open: function(url, winopts, arg, cb) { 800 setTimeout(function() { cb("unsupported browser"); }, 0); 801 } 802 }; 803 } 558 804 })(); 559 805 … … 583 829 function checkIE() { 584 830 var ieVersion = getInternetExplorerVersion(), 585 ieNosupport = ieVersion > -1 && ieVersion < 9;831 ieNosupport = ieVersion > -1 && ieVersion < 8; 586 832 587 833 if(ieNosupport) { … … 607 853 } 608 854 855 function checkJSON() { 856 if(!(window.JSON && window.JSON.stringify && window.JSON.parse)) { 857 return "JSON"; 858 } 859 } 860 609 861 function isSupported() { 610 reason = checkLocalStorage() || checkPostMessage() || explicitNosupport();862 reason = checkLocalStorage() || checkPostMessage() || checkJSON() || explicitNosupport(); 611 863 612 864 return !reason; … … 630 882 isSupported: isSupported, 631 883 /** 632 * Called after isSupported, if isSupported returns false. Gets the reason 884 * Called after isSupported, if isSupported returns false. Gets the reason 633 885 * why browser is not supported. 634 886 * @method getNoSupportReason … … 637 889 getNoSupportReason: getNoSupportReason 638 890 }; 639 640 891 }()); 641 892 … … 644 895 function _open_hidden_iframe(doc) { 645 896 var iframe = doc.createElement("iframe"); 646 // iframe.style.display = "none";647 doc.body.appendChild(iframe);648 iframe.src = ipServer + "/register_iframe";649 return iframe;650 }651 652 function _get_relayframe_id() {653 var randomString = '';654 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";655 for (var i=0; i < 4; i++) {656 randomString += possible.charAt(Math.floor(Math.random() * possible.length));657 }658 return randomString;659 }660 661 function _open_relayframe(framename) {662 var doc = window.document;663 var iframe = doc.createElement("iframe");664 iframe.setAttribute('name', framename);665 iframe.setAttribute('src', ipServer + "/relay");666 897 iframe.style.display = "none"; 667 898 doc.body.appendChild(iframe); 668 899 iframe.src = ipServer + "/communication_iframe"; 669 900 return iframe; 670 }671 672 function _open_window(url) {673 url = url || "about:blank";674 // we open the window initially blank, and only after our relay frame has675 // been constructed do we update the location. This is done because we676 // must launch the window inside a click handler, but we should wait to677 // start loading it until our relay iframe is instantiated and ready.678 // see issue #287 & #286679 var dialog = window.open(680 url,681 "_mozid_signin",682 isFennec ? undefined : "menubar=0,location=0,resizable=0,scrollbars=0,status=0,dialog=1,width=700,height=375");683 684 dialog.focus();685 return dialog;686 }687 688 function _attach_event(element, name, listener) {689 if (element.addEventListener) {690 element.addEventListener(name, listener, false);691 }692 else if(element.attachEvent) {693 // IE < 9694 element.attachEvent(name, listener);695 }696 }697 698 function _detatch_event(element, name, listener) {699 if (element.removeEventListener) {700 element.removeEventListener(name, listener, false);701 }702 else if(element.detachEvent) {703 element.detachEvent(name, listener);704 }705 901 } 706 902 … … 717 913 var ipServer = "https://browserid.org"; 718 914 var isFennec = navigator.userAgent.indexOf('Fennec/') != -1; 719 720 var chan, w, iframe; 721 722 // keep track of these so that we can re-use/re-focus an already open window. 723 navigator.id.getVerifiedEmail = function(callback) { 724 if (w) { 725 // if there is already a window open, just focus the old window. 726 w.focus(); 727 return; 728 } 729 730 if (!BrowserSupport.isSupported()) { 731 w = _open_window(ipServer + "/unsupported_dialog"); 732 return; 733 } 734 735 var frameid = _get_relayframe_id(); 736 var iframe = _open_relayframe("browserid_relay_" + frameid); 737 w = _open_window(); 738 739 // if the RP window closes, close the dialog as well. 740 _attach_event(window, 'unload', cleanup); 741 742 // clean up a previous channel that never was reaped 743 if (chan) chan.destroy(); 744 chan = Channel.build({ 745 window: iframe.contentWindow, 746 origin: ipServer, 747 scope: "mozid", 748 onReady: function() { 749 // We have to change the name of the relay frame every time or else Firefox 750 // has a problem re-attaching new iframes with the same name. Code inside 751 // of frames with the same name sometimes does not get run. 752 // See https://bugzilla.mozilla.org/show_bug.cgi?id=350023 753 w = _open_window(ipServer + "/sign_in#" + frameid); 754 } 755 }); 756 757 function cleanup() { 758 chan.destroy(); 759 chan = null; 760 915 var windowOpenOpts = 916 (isFennec ? undefined : 917 "menubar=0,location=1,resizable=0,scrollbars=0,status=0,dialog=1,width=700,height=375"); 918 919 var w; 920 921 navigator.id.get = function(callback, options) { 922 if (typeof callback !== 'function') { 923 throw "navigator.id.get() requires a callback argument"; 924 } 925 926 if (options && options.silent) { 927 _noninteractiveCall('getPersistentAssertion', { }, function(rv) { 928 callback(rv); 929 }, function(e, msg) { 930 callback(null); 931 }); 932 } else { 933 // focus an existing window 761 934 if (w) { 762 w.close(); 763 w = null; 764 } 765 766 iframe.parentNode.removeChild(iframe); 767 iframe = null; 768 769 _detatch_event(window, 'unload', cleanup); 770 } 771 772 chan.call({ 773 method: "getVerifiedEmail", 774 success: function(rv) { 775 if (callback) { 776 // return the string representation of the JWT, the client is responsible for unpacking it. 777 callback(rv); 778 } 779 cleanup(); 780 }, 781 error: function(code, msg) { 782 // XXX: we don't make the code and msg available to the user. 783 if (callback) callback(null); 784 cleanup(); 785 } 935 try { 936 w.focus(); 937 } 938 catch(e) { 939 /* IE7 blows up here, do nothing */ 940 } 941 return; 942 } 943 944 if (!BrowserSupport.isSupported()) { 945 w = window.open( 946 ipServer + "/unsupported_dialog", 947 null, 948 windowOpenOpts); 949 return; 950 } 951 952 w = WinChan.open({ 953 url: ipServer + '/sign_in', 954 relay_url: ipServer + '/relay', 955 window_features: windowOpenOpts, 956 params: { 957 method: "get", 958 params: options 959 } 960 }, function(err, r) { 961 // clear the window handle 962 w = undefined; 963 // ignore err! 964 callback(err ? null : (r ? r : null)); 965 }); 966 } 967 }; 968 969 navigator.id.getVerifiedEmail = function (callback, options) { 970 if (options) { 971 throw "getVerifiedEmail doesn't accept options. use navigator.id.get() instead."; 972 } 973 navigator.id.get(callback); 974 }; 975 976 navigator.id.logout = function(callback) { 977 _noninteractiveCall('logout', { }, function(rv) { 978 callback(rv); 979 }, function() { 980 callback(null); 786 981 }); 787 982 }; 788 983 789 /* 790 // preauthorize a particular email 791 // FIXME: lots of cut-and-paste code here, need to refactor 792 // not refactoring now because experimenting and don't want to break existing code 793 navigator.id.preauthEmail = function(email, onsuccess, onerror) { 984 var _noninteractiveCall = function(method, args, onsuccess, onerror) { 794 985 var doc = window.document; 795 var iframe = _create_iframe(doc); 796 797 // clean up a previous channel that never was reaped 798 if (chan) chan.destroy(); 799 chan = Channel.build({window: iframe.contentWindow, origin: ipServer, scope: "mozid"}); 986 var ni_iframe = _open_hidden_iframe(doc); 987 988 var chan = Channel.build({window: ni_iframe.contentWindow, origin: ipServer, scope: "mozid_ni"}); 800 989 801 990 function cleanup() { 802 991 chan.destroy(); 803 992 chan = undefined; 804 doc.body.removeChild(iframe); 805 } 806 807 chan.call({ 808 method: "preauthEmail", 809 params: email, 810 success: function(rv) { 811 onsuccess(rv); 812 cleanup(); 813 }, 814 error: function(code, msg) { 815 if (onerror) onerror(code, msg); 816 cleanup(); 817 } 818 }); 819 }; 820 */ 821 822 // get a particular verified email 823 // FIXME: needs to ditched for now until fixed 824 /* 825 navigator.id.getSpecificVerifiedEmail = function(email, token, onsuccess, onerror) { 826 var doc = window.document; 827 828 // if we have a token, we should not be opening a window, rather we should be 829 // able to do this entirely through IFRAMEs 830 var w; 831 if (token) { 832 var iframe = _create_iframe(doc); 833 w = iframe.contentWindow; 834 } else { 835 _open_window(); 836 _open_relay_frame(doc); 837 } 838 839 // clean up a previous channel that never was reaped 840 if (chan) chan.destroy(); 841 chan = Channel.build({window: w, origin: ipServer, scope: "mozid"}); 842 843 function cleanup() { 844 chan.destroy(); 845 chan = undefined; 846 if (token) { 847 // just remove the IFRAME 848 doc.body.removeChild(iframe); 849 } else { 850 w.close(); 851 } 852 } 853 854 chan.call({ 855 method: "getSpecificVerifiedEmail", 856 params: [email, token], 857 success: function(rv) { 858 if (onsuccess) { 859 // return the string representation of the JWT, the client is responsible for unpacking it. 860 onsuccess(rv); 861 } 862 cleanup(); 863 }, 864 error: function(code, msg) { 865 if (onerror) onerror(code, msg); 866 cleanup(); 867 } 868 }); 869 }; 870 */ 871 872 var _noninteractiveCall = function(method, args, onsuccess, onerror) { 873 var doc = window.document; 874 iframe = _open_hidden_iframe(doc); 875 876 // clean up channel 877 if (chan) chan.destroy(); 878 chan = Channel.build({window: iframe.contentWindow, origin: ipServer, scope: "mozid"}); 879 880 function cleanup() { 881 chan.destroy(); 882 chan = undefined; 883 doc.body.removeChild(iframe); 884 } 885 993 doc.body.removeChild(ni_iframe); 994 } 995 886 996 chan.call({ 887 997 method: method, … … 897 1007 cleanup(); 898 1008 } 899 }); 900 } 901 902 // 903 // for now, disabling primary support. 904 // 905 906 /* 907 // check if a valid cert exists for this verified email 908 // calls back with true or false 909 // FIXME: implement it for real, but 910 // be careful here because this needs to be limited 911 navigator.id.checkVerifiedEmail = function(email, onsuccess, onerror) { 912 onsuccess(false); 1009 }); 913 1010 }; 914 1011 915 // generate a keypair916 navigator.id.generateKey = function(onsuccess, onerror) {917 _noninteractiveCall("generateKey", {},918 onsuccess, onerror);919 };920 921 navigator.id.registerVerifiedEmailCertificate = function(certificate, updateURL, onsuccess, onerror) {922 _noninteractiveCall("registerVerifiedEmailCertificate",923 {cert:certificate, updateURL: updateURL},924 onsuccess, onerror);925 };926 */927 928 1012 navigator.id._getVerifiedEmailIsShimmed = true; 929 1013 } -
_plugins_/authentification/browserid/plugin.xml
r54959 r59280 2 2 <nom>BrowserID</nom> 3 3 <auteur>Fil</auteur> 4 <version>0. 2</version>4 <version>0.3</version> 5 5 <etat> 6 6 dev
Note: See TracChangeset
for help on using the changeset viewer.