From e850fd718dd726609c590a501d120c490b6462c4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 6 Oct 2016 19:54:49 +0100 Subject: [PATCH 1/2] window.postmessage for Interactive Auth fallback Require that User-Interactive auth fallback pages call `window.postMessage` to notify apps of completion. --- changelogs/client_server.rst | 3 + specification/client_server_api.rst | 107 +++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 465565e1..fc539dc0 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -34,6 +34,9 @@ (`#390 `_). - Add "Send-to-Device messaging" module (`#386 `_). + - Require that User-Interactive auth fallback pages call + ``window.postMessage`` to notify apps of completion + (`#398 `_). - Spec clarifications: diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index e12f6f40..21e2d03e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -428,7 +428,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.password", "user": "", - "password": "" + "password": "", + "session": "" } Alternatively reply using a 3pid bound to the user's account on the homeserver @@ -441,7 +442,8 @@ follows: "type": "m.login.password", "medium": "", "address": "", - "password": "" + "password": "", + "session": "" } In the case that the homeserver does not know about the supplied 3pid, the @@ -460,7 +462,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.recaptcha", - "response": "" + "response": "", + "session": "" } Token-based @@ -477,7 +480,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.token", "token": "", - "txn_id": "" + "txn_id": "", + "session": "" } The ``nonce`` should be a random string generated by the client for the @@ -544,7 +548,8 @@ To use this authentication type, clients should submit an auth dict as follows: "client_secret": "", "id_server": "" } - ] + ], + "session": "" } Dummy Auth @@ -562,12 +567,13 @@ the type and session, if provided: .. code:: json { - "type": "m.login.dummy" + "type": "m.login.dummy", + "session": "" } Fallback -<<<<<<<< +++++++++ Clients cannot be expected to be able to know how to process every single login type. If a client does not know how to handle a given login type, it can direct the user to a web browser with the URL of a fallback page which will allow the @@ -577,11 +583,92 @@ should open is:: /_matrix/client/%CLIENT_MAJOR_VERSION%/auth//fallback/web?session= Where ``auth type`` is the type name of the stage it is attempting and -``session id`` is the ID of the session given by the homeserver. +``session ID`` is the ID of the session given by the homeserver. This MUST return an HTML page which can perform this authentication stage. This -page must attempt to call the JavaScript function ``window.onAuthDone`` when -the authentication has been completed. +page must use the following JavaScript when the authentication has been +completed: + +.. code:: javascript + + if (window.onAuthDone) { + window.onAuthDone(); + } else if (window.opener && window.opener.postMessage) { + window.opener.postMessage("authDone", "*"); + } + +This allows the client to either arrange for the global function ``onAuthDone`` +to be defined in an embedded browser, or to use the HTML5 `cross-document +messaging `_ API, to receive +a notification that the authentication stage has been completed. + +Once a client receives the notificaton that the authentication stage has been +completed, it should resubmit the request with an auth dict with just the +session ID: + +.. code:: json + + { + "session": "" + } + + +Example +<<<<<<< +A client webapp might use the following javascript to open a popup window which will +handle unknown login types: + +.. code:: javascript + + /** + * Arguments: + * homeserverUrl: the base url of the homeserver (eg "https://matrix.org") + * + * apiEndpoint: the API endpoint being used (eg + * "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password") + * + * loginType: the loginType being attempted (eg "m.login.recaptcha") + * + * sessionID: the session ID given by the homeserver in earlier requests + * + * onComplete: a callback which will be called with the results of the request + */ + function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onComplete) { + var popupWindow; + + var eventListener = function(ev) { + if (ev.data !== "authDone" ) { + return; + } + + // close the popup + popupWindow.close(); + window.removeEventListener("message", eventListener); + + // repeat the request + var requestBody = { + auth: { + session: sessionID, + }, + }; + + request({ + method:'POST', url:apiEndpint, json:requestBody, + }, onComplete); + }; + + window.addEventListener("message", eventListener); + + var url = homeserverUrl + + "/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/" + + encodeURIComponent(loginType) + + "/fallback/web?session=" + + encodeURIComponent(sessionID); + + + popupWindow = window.open(url); + } + Login ~~~~~ From 6c88d698ae7d095617437e22e801b7ece7837d6d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 7 Oct 2016 16:26:28 +0100 Subject: [PATCH 2/2] uia fallback example: check event origin --- specification/client_server_api.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 21e2d03e..d95164c5 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -637,10 +637,11 @@ handle unknown login types: var popupWindow; var eventListener = function(ev) { - if (ev.data !== "authDone" ) { + // check it's the right message from the right place. + if (ev.data !== "authDone" || ev.origin !== homeserverUrl) { return; } - + // close the popup popupWindow.close(); window.removeEventListener("message", eventListener);