Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

window.postmessage for Interactive Auth fallback #398

Merged
merged 2 commits into from
Oct 10, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelogs/client_server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
(`#390 <https://github.com/matrix-org/matrix-doc/pull/390>`_).
- Add "Send-to-Device messaging" module
(`#386 <https://github.com/matrix-org/matrix-doc/pull/386>`_).
- Require that User-Interactive auth fallback pages call
``window.postMessage`` to notify apps of completion
(`#398 <https://github.com/matrix-org/matrix-doc/pull/398>`_).

- Spec clarifications:

Expand Down
107 changes: 97 additions & 10 deletions specification/client_server_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,8 @@ To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.password",
"user": "<user_id or user localpart>",
"password": "<password>"
"password": "<password>",
"session": "<session ID>"
}

Alternatively reply using a 3pid bound to the user's account on the homeserver
Expand All @@ -441,7 +442,8 @@ follows:
"type": "m.login.password",
"medium": "<The medium of the third party identifier. Must be 'email'>",
"address": "<The third party address of the user>",
"password": "<password>"
"password": "<password>",
"session": "<session ID>"
}

In the case that the homeserver does not know about the supplied 3pid, the
Expand All @@ -460,7 +462,8 @@ To use this authentication type, clients should submit an auth dict as follows:

{
"type": "m.login.recaptcha",
"response": "<captcha response>"
"response": "<captcha response>",
"session": "<session ID>"
}

Token-based
Expand All @@ -477,7 +480,8 @@ To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.token",
"token": "<token>",
"txn_id": "<client generated nonce>"
"txn_id": "<client generated nonce>",
"session": "<session ID>"
}

The ``nonce`` should be a random string generated by the client for the
Expand Down Expand Up @@ -544,7 +548,8 @@ To use this authentication type, clients should submit an auth dict as follows:
"client_secret": "<identity server client secret>",
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>"
}
]
],
"session": "<session ID>"
}

Dummy Auth
Expand All @@ -562,12 +567,13 @@ the type and session, if provided:
.. code:: json

{
"type": "m.login.dummy"
"type": "m.login.dummy",
"session": "<session ID>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be slightly confusing since there's no reason you'd ever submit a session with dummy auth

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we agreed to leave this as-is for consistency with the other login types. The logic is "if you get a session id, send it back", not "if you get a session id, send it back, unless you're doing dummy auth, in which case you don't need to bother".

}


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
Expand All @@ -577,11 +583,92 @@ should open is::
/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/<auth type>/fallback/web?session=<session ID>

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 <https://www.w3.org/TR/webmessaging/#web-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": "<session ID>"
}


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" ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably ought to check the domain of the event sender here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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
~~~~~
Expand Down