mirror of https://github.com/moparisthebest/xeps
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
441 lines
19 KiB
441 lines
19 KiB
<?xml version='1.0' encoding='UTF-8'?> |
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [ |
|
<!ENTITY % ents SYSTEM 'xep.ent'> |
|
%ents; |
|
]> |
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?> |
|
<xep> |
|
<header> |
|
<title>Ad-hoc Account Invitation Generation</title> |
|
<abstract>This document defines a protocol and URI scheme for user invitation in order to allow a third party to register on a server. The goal of this is to make onboarding for XMPP IM newcomers as easy as possible.</abstract> |
|
&LEGALNOTICE; |
|
<number>0401</number> |
|
<status>Proposed</status> |
|
<lastcall>2021-10-20</lastcall> |
|
<type>Standards Track</type> |
|
<sig>Standards</sig> |
|
<approver>Council</approver> |
|
<dependencies> |
|
<spec>XMPP Core</spec> |
|
<spec>XEP-0001</spec> |
|
<spec>XEP-0050</spec> |
|
<spec>XEP-0082</spec> |
|
<spec>XEP-0077</spec> |
|
<spec>XEP-0147</spec> |
|
<spec>XEP-0379</spec> |
|
</dependencies> |
|
<supersedes/> |
|
<supersededby/> |
|
<shortname>N/A</shortname> |
|
<author> |
|
<firstname>Marc</firstname> |
|
<surname>Schink</surname> |
|
</author> |
|
<author> |
|
<firstname>Georg</firstname> |
|
<surname>Lukas</surname> |
|
</author> |
|
<revision> |
|
<version>0.5.0</version> |
|
<date>2021-10-06</date> |
|
<initials>gl</initials> |
|
<remark>Factor out XEP-0445</remark> |
|
</revision> |
|
<revision> |
|
<version>0.4.0</version> |
|
<date>2020-01-08</date> |
|
<initials>jsc</initials> |
|
<remark>Revert version 0.3.0, which was merged prematurely and incorrectly.</remark> |
|
</revision> |
|
<revision> |
|
<version>0.3.0</version> |
|
<date>2020-01-02</date> |
|
<initials>gl</initials> |
|
<remark>Use pre-auth-IQ instead of re-using IBR as per council feedback.</remark> |
|
</revision> |
|
<revision> |
|
<version>0.2.0</version> |
|
<date>2018-02-11</date> |
|
<initials>ms</initials> |
|
<remark> |
|
<p>Used Data Forms for extension of In-Band Registration as required by <strong>XEP-0077</strong> § 4.</p> |
|
<p>Added "defined condition" elements in error stanzas as required by <strong>RFC 6120</strong> § 8.3.2.</p> |
|
<p>Changed type of "invalid-token" error to "modify".</p> |
|
<p>Fix namespacing of Ad-Hoc commands</p> |
|
<p>Bump namespace to invite:1</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.1.0</version> |
|
<date>2018-01-25</date> |
|
<initials>XEP Editor (jwi)</initials> |
|
<remark>Accepted by vote of Council on 2018-01-17.</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.1</version> |
|
<date>2018-01-10</date> |
|
<initials>ms</initials> |
|
<remark><p>First submission.</p></remark> |
|
</revision> |
|
</header> |
|
<section1 topic='Introduction' anchor='intro'> |
|
<p>Romeo is an active XMPP IM (Instant Messaging) user or the operator of |
|
an XMPP server. He convinces Juliet (who may not have an XMPP account yet) |
|
to install a client but she may still need to choose an XMPP server, |
|
create an account, and add Romeo as a contact. |
|
This specification defines two ways for Romeo to simplify this process for Juliet:</p> |
|
<section2 topic='User Invitation'> |
|
<p>If Romeo is an XMPP user, he can create an out-of-band link (URI) |
|
which allows Juliet to:</p> |
|
<ol> |
|
<li>Download an XMPP client (if needed).</li> |
|
<li>Optionally register an account with Romeo's server (if permitted by |
|
the server rules), or with a public server.</li> |
|
<li>Establish a mutual presence subscription between Romeo and Juliet.</li> |
|
</ol> |
|
<p>The process is designed to automatically skip steps that Juliet already |
|
completed, to make the overall experience as smooth as possible.</p> |
|
</section2> |
|
<section2 topic='Account Creation'> |
|
<p>If Romeo is an administrator of an XMPP server, he can create an |
|
out-of-band link (URI) which allows Juliet to:</p> |
|
<ol> |
|
<li>Download an XMPP client (if needed).</li> |
|
<li>Register an account on Romeo's server (with a user name pre-defined |
|
by Romeo or chosen by Juliet, and a password not known to Romeo).</li> |
|
<li>Establish a mutual presence subscription between Romeo and Juliet.</li> |
|
</ol> |
|
</section2> |
|
</section1> |
|
<section1 topic='Requirements' anchor='reqs'> |
|
<p>This specification makes use of XMPP URIs. The basic URI scheme for XMPP |
|
is defined in &rfc5122; and extended in &xep0147; and &xep0379;. |
|
Furthermore, this heavily builds upon the blocks provided in |
|
<cite>XEP-0379</cite> for landing page and roster subscription. |
|
</p> |
|
<p> |
|
To create out-of-band invitation links, Romeo's server needs to implement |
|
the &xep0050; commands specified in the following section, and his client |
|
must be able to execute them. |
|
</p> |
|
<p> |
|
Furthermore, Romeo's server SHOULD provide a HTTPS service hosting the |
|
landing page. |
|
</p> |
|
<p>Romeo's server MUST support at least one <link url="#preauth-ibr">Pre-Authenticated In-Band |
|
Registration</link> mechanism.</p> |
|
</section1> |
|
<section1 topic='Discovery' anchor='discover'> |
|
<p>Romeo can query his server for the availability of "User Invitation" and |
|
"Account Creation" commands:</p> |
|
<example caption="Discover available ad-hoc commands"><![CDATA[ |
|
<iq type='get' from='romeo@example.com' to='example.com' id='disco'> |
|
<query xmlns='http://jabber.org/protocol/disco#items' |
|
node='http://jabber.org/protocol/commands'/> |
|
</iq> |
|
]]></example> |
|
<p>TODO: use appropriate node namespace.</p> |
|
<example caption="Discovery result for available ad-hoc commands"><![CDATA[ |
|
<iq type='result' to='romeo@example.com' from='example.com' id='disco'> |
|
<query xmlns='http://jabber.org/protocol/disco#items' |
|
node='http://jabber.org/protocol/commands'> |
|
<item jid='example.com' |
|
node='urn:xmpp:invite#invite' |
|
name='Invite user'/> |
|
<item jid='example.com' |
|
node='urn:xmpp:invite#create-account' |
|
name='Create account'/> |
|
</query> |
|
</iq> |
|
]]></example> |
|
</section1> |
|
<section1 topic='Glossary' anchor='glossary'> |
|
<p>OPTIONAL.</p> |
|
</section1> |
|
<section1 topic='Use Cases' anchor='usecases'> |
|
<section2 topic='Creating a User Invitation' anchor='create-invitation'> |
|
<p>A user can execute the 'invite' command to obtain a new invitation link |
|
with a unique invitation token.</p> |
|
<example caption="Execute user invitation command"><![CDATA[ |
|
<iq type='set' from='romeo@example.com' to='example.com' id='exec1'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
node='urn:xmpp:invite#invite' |
|
action='execute'/> |
|
</iq> |
|
]]></example> |
|
<example caption="User invitation finished"><![CDATA[ |
|
<iq type='result' to='romeo@example.com' from='example.com' id='exec2'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
node='urn:xmpp:invite#invite' |
|
status='completed'> |
|
<x xmlns='jabber:x:data' type='result'> |
|
<item> |
|
<field var='uri'> |
|
<value>xmpp:inviter@example.com?roster;preauth=TOKEN;ibr=y</value> |
|
</field> |
|
<field var='landing-url'> |
|
<value>https://example.com/invite/#TOKEN</value> |
|
</field> |
|
<field var='expire'> |
|
<value>2017-11-06T02:56:15Z</value> |
|
</field> |
|
</item> |
|
</x> |
|
</command> |
|
</iq> |
|
]]></example> |
|
<p>The token should be unique, sufficiently |
|
long and generated by a strong random number generator.</p> |
|
<p>A server MUST provide the <strong>uri</strong> field which contains an |
|
XMPP URI of the following format:</p> |
|
<code>xmpp:inviter@example.com?roster;preauth=TOKEN;ibr=y</code> |
|
<p>The <strong>ibr</strong> query component in the XMPP URI indicates that |
|
the invitee is allowed to create an account on Romeo's server, using the |
|
'preauth' token. |
|
If the server does not support or allow in-band registration for invited |
|
users, the server MUST omit the <strong>ibr</strong> query component.</p> |
|
<p>Additionally, the server SHOULD provide the <strong>landing-url</strong> |
|
field which contains an HTTPS URL of a web-based landing page as described |
|
in &xep0379; § 3.3. The URL format may differ from the example shown here |
|
depending on where the landing page is hosted.</p> |
|
<p>If the server omits the <strong>landing-page</strong> field, Romeo's |
|
client SHOULD generate an appropriate landing page URL hosted by the |
|
client developer or a trusted third party.</p> |
|
<p>A server MAY provide a field which provides the expiration date of the |
|
generated token. The expiration date MUST conform to the DateTime profile |
|
specified in &xep0082;. If the field is not provided, the token does not |
|
expire.</p> |
|
<p>Romeo's client should provide adequate means to export the |
|
<strong>landing-page</strong> URL, possibly accompanied with a short |
|
description and the <strong>expire</strong> information, so that Romeo can |
|
share it with Juliet by other means than XMPP, like e-mail or a QR code.</p> |
|
</section2> |
|
<section2 topic='Landing Page' anchor='landing-page'> |
|
<p>The landing page that the generated URL points to should correspond to |
|
the format described in <cite>XEP-0379</cite> §3.3, and it needs to |
|
convey the following information:</p> |
|
<ul> |
|
<li>A short text that this is an XMPP invitation from Romeo.</li> |
|
<li>A client recommendation (based on the detected web browser/OS) with download links.</li> |
|
<li>A prominent button that activates the encoded <strong>xmpp:</strong> link.</li> |
|
</ul> |
|
<p>If the landing page is hosted by Romeo's server, the server MAY display |
|
additional information based on the supplied TOKEN value, like the name |
|
of the inviter or validity information.</p> |
|
</section2> |
|
<section2 topic='Redeeming a User Invitation' anchor='redeem-invitation'> |
|
<p>If Juliet does not have an XMPP client installed, she will not be able |
|
to open the <strong>xmpp:</strong> link from the invitation page. |
|
For this case, the landing page needs to indicate that a client must be |
|
installed first, and that the link will not work as intended without. |
|
The automatic installation of an appropriate IM client when a user |
|
clicks on an <strong>xmpp:</strong> is outside of the scope of this |
|
document.</p> |
|
<p>With an XMPP client installed, Juliet can open the |
|
<strong>xmpp:</strong> link and have the client process it |
|
appropriately, as follows:</p> |
|
<section3 topic='Pre-Configured Account' anchor='redeem-preconfigured'> |
|
<p>If Juliet's client is already configured with an account, the default |
|
action for the presented |
|
<strong>xmpp:inviter@example.com?roster;...</strong> URI is to add the |
|
inviter to Juliet's roster. This should be performed as described in |
|
§3.4 of <cite>XEP-0379</cite>, by sending a presence subscription |
|
request containing the 'preauth' token.</p> |
|
<p>If Juliet already has Romeo in her roster, her client should open the |
|
appropriate chat interface instead.</p> |
|
</section3> |
|
<section3 topic='No Configured Account' anchor='redeem-no-account'> |
|
<p>If Juliet's client does not have an XMPP account configured, she |
|
needs to login or register an account first. Therefore, the client |
|
should provide an interface with the following options:</p> |
|
<ul> |
|
<li>Login with an existing XMPP account.</li> |
|
<li>Register an account with Romeo's server (if the URI contains a |
|
<strong>ibr=y</strong> parameter).</li> |
|
<li>Register an account with a public or client-endorsed server.</li> |
|
</ul> |
|
<p>If the <strong>xmpp:</strong> URI provided by Romeo contains the |
|
<strong>ibr=y</strong> parameter, it indicates that the server |
|
supports the <link url="#preauth-ibr">Pre-Authenticated In-Band |
|
Registration</link> defined in this document. If Juliet chooses this |
|
approach, the server will ensure that after the registration, Romeo is |
|
added to her roster with a full presence subscription.</p> <p>If |
|
Juliet chooses to login or register with a different server, her |
|
client must complete the respective process and issue a subscription |
|
request as described in §3.4 of <cite>XEP-0379</cite>.</p> |
|
</section3> |
|
</section2> |
|
<section2 topic='Initiating Account Creation' anchor='account-creation'> |
|
<p>If Romeo is the administrator of an XMPP server, he might want to |
|
ensure that Juliet obtains an account on this server, with a username |
|
defined either by Romeo or by Juliet, and in a way that does not require |
|
the out-of-band communication of user passwords.</p> |
|
<p>TODO: description of overall process steps, design motivation.</p> |
|
<example caption="Exceute account creation command"><![CDATA[ |
|
<iq type='set' from='romeo@example.com' to='example.com' id='exec1'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
node='urn:xmpp:invite#create-account' |
|
action='execute'/> |
|
</iq> |
|
]]></example> |
|
<example caption="Service returns form for account creation"><![CDATA[ |
|
<iq type='result' to='romeo@example.com' from='example.com' id='exec1'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
sessionid='config:20020923T213616Z-700' |
|
node='urn:xmpp:invite#create-account' |
|
status='executing'> |
|
<actions execute='complete'> |
|
<complete/> |
|
</actions> |
|
<x xmlns='jabber:x:data' type='form'> |
|
<field var='username' label='Username' type='text-single'/> |
|
<field var='roster-subscription' label='Roster subscription' type='boolean'/> |
|
</x> |
|
</command> |
|
</iq> |
|
]]></example> |
|
<p>A server MAY require a username to be specified for account creation. |
|
In this case, the server MUST add the <required/> element to the |
|
username field. |
|
The username MUST be a valid localpart as defined in &rfc6122; §2.3.</p> |
|
<example caption="Account creation with specified username"><![CDATA[ |
|
<iq type='set' from='romeo@example.com' to='example.com' id='exec2'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
sessionid='config:20020923T213616Z-700' |
|
node='urn:xmpp:invite#create-account'> |
|
<x xmlns='jabber:x:data' type='submit'> |
|
<field var='username'> |
|
<value>juliet</value> |
|
</field> |
|
</x> |
|
</command> |
|
</iq> |
|
]]></example> |
|
<example caption="Account creation finished"><![CDATA[ |
|
<iq type='result' to='romeo@example.com' from='example.com' id='exec2'> |
|
<command xmlns='http://jabber.org/protocol/commands' |
|
sessionid='config:20020923T213616Z-700' |
|
node='urn:xmpp:invite#create-account' |
|
status='completed'> |
|
<x xmlns='jabber:x:data' type='result'> |
|
<item> |
|
<field var='uri'> |
|
<value>xmpp:juliet@example.com?register;preauth=TOKEN</value> |
|
</field> |
|
<field var='landing-url'> |
|
<value>https://example.com/invite/#TOKEN</value> |
|
</field> |
|
<field var='expire'> |
|
<value>2017-11-06T02:56:15Z</value> |
|
</field> |
|
</item> |
|
</x> |
|
</command> |
|
</iq> |
|
]]></example> |
|
<p>The server's response for account creation is the same as for user |
|
invitation except for the format of the <strong>uri</strong> field which |
|
contains an XMPP URI of the following format:</p> |
|
<code>xmpp:juliet@example.com?register;preauth=TOKEN</code> |
|
<p>If no username was specified during the account creation process, the |
|
local part of the JID in the XMPP URI is omitted by the server which |
|
results in the following format:</p> |
|
<code>xmpp:example.com?register;preauth=TOKEN</code> |
|
<p>TODO: note about sensitivity of TOKEN</p> |
|
</section2> |
|
<section2 topic='Pre-Authenticated In-Band Registration' anchor='preauth-ibr'> |
|
<p>In order to allow invited users to register on a server, the |
|
server must support pre-authenticated in-band registration based on one |
|
of the following specifications: |
|
</p> |
|
<ul> |
|
<li>&xep0445;</li> |
|
<li>TODO: define a mechanism based on &xep0389;</li> |
|
</ul> |
|
<p> |
|
The invited user's client needs to connect to the server, check which of |
|
the above mechanisms are supported, and continue as specified in the |
|
respective document. |
|
</p> |
|
<p>After the invitee has successfully registered on the inviter's server |
|
and roster subscription is enabled for account creation, the server MUST |
|
use roster pushes as defined in &rfc6121; §2.1.6 in order to inform the |
|
inviter about the invitee's new account without the need to reconnect.</p> |
|
<example caption="Push roster item of invitee to inviter"><![CDATA[ |
|
<iq type='set' from='romeo@example.com' id='push'> |
|
<query xmlns='jabber:iq:roster'> |
|
<item subscription='both' jid='juliet@example.com'/> |
|
</query> |
|
</iq> |
|
]]></example> |
|
</section2> |
|
</section1> |
|
<section1 topic='Business Rules' anchor='rules'> |
|
<section2 topic='Fallback to Client-Side PARS'> |
|
<p>If the inviter's server does not support user invitation, the client |
|
application SHOULD silently fall back to &xep0379; for a good user |
|
experience.</p> |
|
</section2> |
|
<section2 topic='Account Creation'> |
|
<p>If a username was specified during the account creation process, the |
|
server SHOULD NOT create an account on the server until the invitee |
|
actually registers it with the corresponding token. |
|
The server MUST reserve the username at least until the corresponding |
|
token expires.</p> |
|
</section2> |
|
</section1> |
|
<section1 topic='Implementation Notes' anchor='impl'> |
|
<section2 topic='XMPP Server Suggestion for Invitees'> |
|
<p>If the invitee opens an invitation URI with <strong>ibr=y</strong> and |
|
chooses to create a new account, the client SHOULD pre-fill the |
|
inviter JID's domain part as the new account's domain. The client MAY |
|
provide a mechanism to enter or choose a different server, though.</p> |
|
</section2> |
|
</section1> |
|
<section1 topic='Accessibility Considerations' anchor='access'> |
|
<p>OPTIONAL.</p> |
|
</section1> |
|
<section1 topic='Internationalization Considerations' anchor='i18n'> |
|
<p>OPTIONAL.</p> |
|
</section1> |
|
<section1 topic='Security Considerations' anchor='security'> |
|
<p>See security considerations in &xep0379;.</p> |
|
</section1> |
|
<section1 topic='IANA Considerations' anchor='iana'> |
|
<p>This document requires no interaction with &IANA;.</p> |
|
</section1> |
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'> |
|
<p>As authorized by &xep0147;, the XMPP Registrar maintains a registry of |
|
queries and key-value pairs for use in XMPP URIs (see &QUERYTYPES;).</p> |
|
<p>The key-value parameter <strong>preauth</strong> is added to the |
|
<strong>register</strong> query action as defined in &xep0077;</p> |
|
<code><![CDATA[ |
|
<querytype> |
|
<name>register</name> |
|
... |
|
<key> |
|
<name>preauth</name> |
|
<desc>the token used to allow one-time in-band registration on the inviter's server</desc> |
|
</key> |
|
</querytype> |
|
]]></code> |
|
|
|
<p>In addition to the <strong>preauth</strong> key-value parameter define |
|
in &xep0379;, the <strong>ibr</strong> parameter is added to the |
|
<strong>roster</strong> query action.</p> |
|
<code><![CDATA[ |
|
<querytype> |
|
<name>roster</name> |
|
... |
|
<key> |
|
<name>ibr</name> |
|
<value>y</value> |
|
<desc>the parameter to indicate that the token allows the invitee to create an account on the inviter's server via in-band registration</desc> |
|
</key> |
|
</querytype> |
|
]]></code> |
|
</section1> |
|
<section1 topic='XML Schema' anchor='schema'> |
|
<p>REQUIRED for protocol specifications.</p> |
|
</section1> |
|
</xep>
|
|
|