specs/draft/7.html

35 lines
24 KiB
HTML

<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>7/GROUP-CHAT - Status Specification</title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script type="text/javascript" src="/assets/js/vendor/lunr.min.js"></script> <script type="text/javascript" src="/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Begin Jekyll SEO tag v2.7.1 --> <title>7/GROUP-CHAT | Status Specification</title> <meta name="generator" content="Jekyll v4.2.1" /> <meta property="og:title" content="7/GROUP-CHAT" /> <meta property="og:locale" content="en_US" /> <link rel="canonical" href="https://specs.status.im/draft/7" /> <meta property="og:url" content="https://specs.status.im/draft/7" /> <meta property="og:site_name" content="Status Specification" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="7/GROUP-CHAT" /> <script type="application/ld+json"> {"@type":"WebPage","url":"https://specs.status.im/draft/7","headline":"7/GROUP-CHAT","@context":"https://schema.org"}</script> <!-- End Jekyll SEO tag --> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> </svg> <div class="side-bar"> <div class="site-header"> <a href="https://specs.status.im/" class="site-title lh-tight"> Status Specification </a> <a href="#" id="menu-button" class="site-button"> <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg> </a> </div> <nav role="navigation" aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="https://specs.status.im/spec/" class="nav-list-link">Stable specs</a><ul class="nav-list "><li class="nav-list-item "><a href="https://specs.status.im/spec/1" class="nav-list-link">1/CLIENT</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/10" class="nav-list-link">10/WAKU-USAGE</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/11" class="nav-list-link">11/WAKU-MAILSERVER</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/15" class="nav-list-link">15/NOTIFICATIONS</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/2" class="nav-list-link">2/ACCOUNT</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/3" class="nav-list-link">3/WHISPER-USAGE</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/4" class="nav-list-link">4/WHISPER-MAILSERVER</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/5" class="nav-list-link">5/SECURE-TRANSPORT</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/6" class="nav-list-link">6/PAYLOADS</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/8" class="nav-list-link">8/EIPS</a></li><li class="nav-list-item "><a href="https://specs.status.im/spec/9" class="nav-list-link">9/ETHEREUM-USAGE</a></li></ul></li><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="https://specs.status.im/draft/" class="nav-list-link">Draft specs</a><ul class="nav-list "><li class="nav-list-item "><a href="https://specs.status.im/draft/12" class="nav-list-link">12/IPFS gateway for Sticker Pack</a></li><li class="nav-list-item "><a href="https://specs.status.im/draft/13" class="nav-list-link">13/3RD-PARTY-USAGE</a></li><li class="nav-list-item "><a href="https://specs.status.im/draft/14" class="nav-list-link">14/Dapp browser API usage</a></li><li class="nav-list-item "><a href="https://specs.status.im/draft/16" class="nav-list-link">16/Keycard Usage for Wallet and Chat Keys</a></li><li class="nav-list-item "><a href="https://specs.status.im/draft/3" class="nav-list-link">3/WHISPER-USAGE</a></li><li class="nav-list-item "><a href="https://specs.status.im/draft/6" class="nav-list-link">6/PAYLOADS</a></li><li class="nav-list-item active"><a href="https://specs.status.im/draft/7" class="nav-list-link active">7/GROUP-CHAT</a></li></ul></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="https://specs.status.im/raw/" class="nav-list-link">Raw specs</a><ul class="nav-list "><li class="nav-list-item "><a href="https://specs.status.im/raw/16" class="nav-list-link">16/PUSH-NOTIFICATION-SERVER</a></li></ul></li><li class="nav-list-item"><a href="https://specs.status.im/development" class="nav-list-link">DEVELOPMENT</a></li><li class="nav-list-item"><a href="https://specs.status.im/style-guideline" class="nav-list-link">STYLE-GUIDELINE</a></li></ul> </nav> <footer class="site-footer"> This site uses <a href="https://github.com/pmarsceill/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </footer> </div> <div class="main" id="top"> <div id="main-header" class="main-header"> <div class="search"> <div class="search-input-wrap"> <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search Status Specification" aria-label="Search Status Specification" autocomplete="off"> <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label> </div> <div id="search-results" class="search-results"></div> </div> </div> <div id="main-content-wrap" class="main-content-wrap"> <nav aria-label="Breadcrumb" class="breadcrumb-nav"> <ol class="breadcrumb-nav-list"> <li class="breadcrumb-nav-list-item"><a href="https://specs.status.im/draft/">Draft specs</a></li> <li class="breadcrumb-nav-list-item"><span>7/GROUP-CHAT</span></li> </ol> </nav> <div id="main-content" class="main-content" role="main"> <h1 id="7group-chat"> <a href="#7group-chat" class="anchor-heading" aria-labelledby="7group-chat"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> 7/GROUP-CHAT </h1> <blockquote> <p>Version: 0.1</p> <p>Status: Draft</p> <p>Authors: Andrea Maria Piana <a href="mailto:andreap@status.im">andreap@status.im</a></p> </blockquote> <h2 id="table-of-contents"> <a href="#table-of-contents" class="anchor-heading" aria-labelledby="table-of-contents"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Table of Contents </h2> <ul> <li><a href="#abstract">Abstract</a></li> <li><a href="#membership-updates">Membership updates</a> <ul> <li><a href="#chat-id">Chat ID</a></li> <li><a href="#signature">Signature</a></li> <li><a href="#group-membership-event">Group membership event</a> <ul> <li><a href="#chat_created">chat-created</a></li> <li><a href="#name_changed">name-changed</a></li> <li><a href="#members_added">members-added</a></li> <li><a href="#member_joined">members-joined</a></li> <li><a href="#admins_added">admins-added</a></li> <li><a href="#member_removed">members-removed</a></li> <li><a href="#admin_removed">admin-removed</a></li> </ul> </li> </ul> </li> </ul> <h2 id="abstract"> <a href="#abstract" class="anchor-heading" aria-labelledby="abstract"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Abstract </h2> <p>This document describes the group chat protocol used by the status application. The node uses pairwise encryption among member so a message is exchanged between each participant, similarly to a one-to-one message.</p> <h2 id="membership-updates"> <a href="#membership-updates" class="anchor-heading" aria-labelledby="membership-updates"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Membership updates </h2> <p>The node uses membership updates messages to propagate group chat membership changes. The protobuf format is described in the <a href="https://specs.status.im/spec/6">6/PAYLOADS</a>. Below describes each specific field.</p> <p>The protobuf messages are:</p> <div class="language-protobuf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// MembershipUpdateMessage is a message used to propagate information</span>
<span class="c1">// about group membership changes.</span>
<span class="kd">message</span> <span class="nc">MembershipUpdateMessage</span> <span class="p">{</span>
<span class="c1">// The chat id of the private group chat</span>
<span class="kt">string</span> <span class="na">chat_id</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="c1">// A list of events for this group chat, first 65 bytes are the signature, then is a </span>
<span class="c1">// protobuf encoded MembershipUpdateEvent</span>
<span class="k">repeated</span> <span class="kt">bytes</span> <span class="na">events</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="c1">// An optional chat message</span>
<span class="n">ChatMessage</span> <span class="kd">message</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">message</span> <span class="nc">MembershipUpdateEvent</span> <span class="p">{</span>
<span class="c1">// Lamport timestamp of the event as described in [Status Payload Specs](status-payload-specs.md#clock-vs-timestamp-and-message-ordering)</span>
<span class="kt">uint64</span> <span class="na">clock</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="c1">// List of public keys of the targets of the action</span>
<span class="k">repeated</span> <span class="kt">string</span> <span class="na">members</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="c1">// Name of the chat for the CHAT_CREATED/NAME_CHANGED event types</span>
<span class="kt">string</span> <span class="na">name</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="c1">// The type of the event</span>
<span class="n">EventType</span> <span class="na">type</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="kd">enum</span> <span class="n">EventType</span> <span class="p">{</span>
<span class="na">UNKNOWN</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="na">CHAT_CREATED</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// See [CHAT_CREATED](#chat-created)</span>
<span class="na">NAME_CHANGED</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">// See [NAME_CHANGED](#name-changed)</span>
<span class="na">MEMBERS_ADDED</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> <span class="c1">// See [MEMBERS_ADDED](#members-added)</span>
<span class="na">MEMBER_JOINED</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span> <span class="c1">// See [MEMBER_JOINED](#member-joined)</span>
<span class="na">MEMBER_REMOVED</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="c1">// See [MEMBER_REMOVED](#member-removed)</span>
<span class="na">ADMINS_ADDED</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span> <span class="c1">// See [ADMINS_ADDED](#admins-added)</span>
<span class="na">ADMIN_REMOVED</span> <span class="o">=</span> <span class="mi">7</span><span class="p">;</span> <span class="c1">// See [ADMIN_REMOVED](#admin-removed)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div> <h3 id="payload"> <a href="#payload" class="anchor-heading" aria-labelledby="payload"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Payload </h3> <p><code class="language-plaintext highlighter-rouge">MembershipUpdateMessage</code>:</p> <div class="table-wrapper"><table> <thead> <tr> <th>Field</th> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>chat-id</td> <td><code class="language-plaintext highlighter-rouge">string</code></td> <td>The chat id of the chat where the change is to take place</td> </tr> <tr> <td>2</td> <td>events</td> <td>See details</td> <td>A list of events that describe the membership changes, in their encoded protobuf form</td> </tr> <tr> <td>3</td> <td>message</td> <td><code class="language-plaintext highlighter-rouge">ChatMessage</code></td> <td>An optional message, described in <a href="./6-payloads.md#message">Message</a></td> </tr> </tbody> </table></div> <p><code class="language-plaintext highlighter-rouge">MembershipUpdateEvent</code>:</p> <div class="table-wrapper"><table> <thead> <tr> <th>Field</th> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>clock</td> <td><code class="language-plaintext highlighter-rouge">uint64</code></td> <td>The clock value of the event</td> </tr> <tr> <td>2</td> <td>members</td> <td><code class="language-plaintext highlighter-rouge">[]string</code></td> <td>An optional list of hex encoded (prefixed with <code class="language-plaintext highlighter-rouge">0x</code>) public keys, the targets of the action</td> </tr> <tr> <td>3</td> <td>name</td> <td><code class="language-plaintext highlighter-rouge">name</code></td> <td>An optional name, for those events that make use of it</td> </tr> <tr> <td>4</td> <td>type</td> <td><code class="language-plaintext highlighter-rouge">EventType</code></td> <td>The type of event sent, described below</td> </tr> </tbody> </table></div> <h3 id="chat-id"> <a href="#chat-id" class="anchor-heading" aria-labelledby="chat-id"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Chat ID </h3> <p>Each membership update MUST be sent with a corresponding <code class="language-plaintext highlighter-rouge">chatId</code>. The format of this chat ID MUST be a string of <a href="https://tools.ietf.org/html/rfc4122">UUID</a>, concatenated with the hex-encoded public key of the creator of the chat, joined by <code class="language-plaintext highlighter-rouge">-</code>. This chatId MUST be validated by all clients, and MUST be discarded if it does not follow these rules.</p> <h3 id="signature"> <a href="#signature" class="anchor-heading" aria-labelledby="signature"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Signature </h3> <p>The node calculates the signature for each event by encoding each <code class="language-plaintext highlighter-rouge">MembershipUpdateEvent</code> in its protobuf representation and prepending the bytes of the chatID, lastly the node signs the <code class="language-plaintext highlighter-rouge">Keccak256</code> of the bytes using the private key by the author and added to the <code class="language-plaintext highlighter-rouge">events</code> field of MembershipUpdateMessage.</p> <h3 id="group-membership-event"> <a href="#group-membership-event" class="anchor-heading" aria-labelledby="group-membership-event"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Group membership event </h3> <p>Any <code class="language-plaintext highlighter-rouge">group membership</code> event received MUST be verified by calculating the signature as per the method described above. The author MUST be extracted from it, if the verification fails the event MUST be discarded.</p> <h4 id="chat_created"> <a href="#chat_created" class="anchor-heading" aria-labelledby="chat_created"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> CHAT_CREATED </h4> <p>Chat <code class="language-plaintext highlighter-rouge">created event</code> is the first event that needs to be sent. Any event with a clock value lower than this MUST be discarded. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates and create a chat with identified by <code class="language-plaintext highlighter-rouge">chatId</code> and named <code class="language-plaintext highlighter-rouge">name</code>.</p> <h4 id="name_changed"> <a href="#name_changed" class="anchor-heading" aria-labelledby="name_changed"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> NAME_CHANGED </h4> <p><code class="language-plaintext highlighter-rouge">admins</code> use a <code class="language-plaintext highlighter-rouge">name changed</code> event to change the name of the group chat. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored. If the event is valid the chat name SHOULD be changed to <code class="language-plaintext highlighter-rouge">name</code>.</p> <h4 id="members_added"> <a href="#members_added" class="anchor-heading" aria-labelledby="members_added"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> MEMBERS_ADDED </h4> <p><code class="language-plaintext highlighter-rouge">admins</code> use a <code class="language-plaintext highlighter-rouge">members added</code> event to add members to the chat. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates and MUST ensure the author of the event is an admin of the chat, otherwise the event MUST be ignored. If the event is valid a client MUST update the list of members of the chat who have not joined, adding the <code class="language-plaintext highlighter-rouge">members</code> received. <code class="language-plaintext highlighter-rouge">members</code> is an array of hex encoded public keys.</p> <h4 id="member_joined"> <a href="#member_joined" class="anchor-heading" aria-labelledby="member_joined"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> MEMBER_JOINED </h4> <p><code class="language-plaintext highlighter-rouge">members</code> use a <code class="language-plaintext highlighter-rouge">members joined</code> event to signal that they want to start receiving messages from this chat. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates. If the event is valid a client MUST update the list of members of the chat who joined, adding the signer. Any <code class="language-plaintext highlighter-rouge">message</code> sent to the group chat should now include the newly joined member.</p> <h4 id="admins_added"> <a href="#admins_added" class="anchor-heading" aria-labelledby="admins_added"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> ADMINS_ADDED </h4> <p><code class="language-plaintext highlighter-rouge">admins</code> use an <code class="language-plaintext highlighter-rouge">admins added</code> event to add make other admins in the chat. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates, MUST ensure the author of the event is an admin of the chat and MUST ensure all <code class="language-plaintext highlighter-rouge">members</code> are already <code class="language-plaintext highlighter-rouge">members</code> of the chat, otherwise the event MUST be ignored. If the event is valid a client MUST update the list of admins of the chat, adding the <code class="language-plaintext highlighter-rouge">members</code> received. <code class="language-plaintext highlighter-rouge">members</code> is an array of hex encoded public keys.</p> <h4 id="member_removed"> <a href="#member_removed" class="anchor-heading" aria-labelledby="member_removed"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> MEMBER_REMOVED </h4> <p><code class="language-plaintext highlighter-rouge">members</code> and/or <code class="language-plaintext highlighter-rouge">admins</code> use a <code class="language-plaintext highlighter-rouge">member-removed</code> event to leave or kick members of the chat. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates, MUST ensure that:</p> <ul> <li>If the author of the event is an admin, target can only be themselves or a non-admin member.</li> <li> <h2 id="if-the-author-of-the-event-is-not-an-admin-the-target-of-the-event-can-only-be-themselves"> <a href="#if-the-author-of-the-event-is-not-an-admin-the-target-of-the-event-can-only-be-themselves" class="anchor-heading" aria-labelledby="if-the-author-of-the-event-is-not-an-admin-the-target-of-the-event-can-only-be-themselves"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> If the author of the event is not an admin, the target of the event can only be themselves. </h2> <p>If the event is valid a client MUST remove the member from the list of <code class="language-plaintext highlighter-rouge">members</code>/<code class="language-plaintext highlighter-rouge">admins</code> of the chat, and no further message should be sent to them.</p> </li> </ul> <h4 id="admin_removed"> <a href="#admin_removed" class="anchor-heading" aria-labelledby="admin_removed"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> ADMIN_REMOVED </h4> <p><code class="language-plaintext highlighter-rouge">Admins</code> use an <code class="language-plaintext highlighter-rouge">admin-removed</code> event to drop admin privileges. Upon receiving this event a client MUST validate the <code class="language-plaintext highlighter-rouge">chatId</code> provided with the updates, MUST ensure that the author of the event is also the target of the event.</p> <p>If the event is valid a client MUST remove the member from the list of <code class="language-plaintext highlighter-rouge">admins</code> of the chat.</p> <h2 id="copyright"> <a href="#copyright" class="anchor-heading" aria-labelledby="copyright"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Copyright </h2> <p>Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>.</p> </div> </div> <div class="search-overlay"></div> </div> </body> </html>