ruma_client_api/account/register.rs
1//! `POST /_matrix/client/*/register`
2//!
3//! Register an account on this homeserver.
4
5use serde::{Deserialize, Serialize};
6
7pub mod v3 {
8 //! `/v3/` ([spec])
9 //!
10 //! [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3register
11
12 use std::time::Duration;
13
14 use ruma_common::{
15 OwnedDeviceId, OwnedUserId,
16 api::{auth_scheme::AppserviceTokenOptional, request, response},
17 metadata,
18 };
19
20 use super::{LoginType, RegistrationKind};
21 use crate::uiaa::{AuthData, UiaaResponse};
22
23 metadata! {
24 method: POST,
25 rate_limited: true,
26 authentication: AppserviceTokenOptional,
27 history: {
28 1.0 => "/_matrix/client/r0/register",
29 1.1 => "/_matrix/client/v3/register",
30 }
31 }
32
33 /// Request type for the `register` endpoint.
34 #[request(error = UiaaResponse)]
35 #[derive(Default)]
36 pub struct Request {
37 /// The desired password for the account.
38 ///
39 /// May be empty for accounts that should not be able to log in again
40 /// with a password, e.g., for guest or application service accounts.
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub password: Option<String>,
43
44 /// Localpart of the desired Matrix ID.
45 ///
46 /// If omitted, the homeserver MUST generate a Matrix ID local part.
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub username: Option<String>,
49
50 /// ID of the client device.
51 ///
52 /// If this does not correspond to a known client device, a new device will be created.
53 /// The server will auto-generate a device_id if this is not specified.
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub device_id: Option<OwnedDeviceId>,
56
57 /// A display name to assign to the newly-created device.
58 ///
59 /// Ignored if `device_id` corresponds to a known device.
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub initial_device_display_name: Option<String>,
62
63 /// Additional authentication information for the user-interactive authentication API.
64 ///
65 /// Note that this information is not used to define how the registered user should be
66 /// authenticated, but is instead used to authenticate the register call itself.
67 /// It should be left empty, or omitted, unless an earlier call returned an response
68 /// with status code 401.
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub auth: Option<AuthData>,
71
72 /// Kind of account to register
73 ///
74 /// Defaults to `User` if omitted.
75 #[ruma_api(query)]
76 #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
77 pub kind: RegistrationKind,
78
79 /// If `true`, an `access_token` and `device_id` should not be returned
80 /// from this call, therefore preventing an automatic login.
81 #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
82 pub inhibit_login: bool,
83
84 /// Login `type` used by Appservices.
85 ///
86 /// Appservices can [bypass the registration flows][admin] entirely by providing their
87 /// token in the header and setting this login `type` to `m.login.application_service`.
88 ///
89 /// [admin]: https://spec.matrix.org/latest/application-service-api/#server-admin-style-permissions
90 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
91 pub login_type: Option<LoginType>,
92
93 /// If set to `true`, the client supports [refresh tokens].
94 ///
95 /// [refresh tokens]: https://spec.matrix.org/latest/client-server-api/#refreshing-access-tokens
96 #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
97 pub refresh_token: bool,
98
99 /// A [guest user]'s access token, to upgrade to a regular account.
100 ///
101 /// If this is set, the `username` field is also required.
102 ///
103 /// [guest user]: https://spec.matrix.org/latest/client-server-api/#guest-access
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub guest_access_token: Option<String>,
106 }
107
108 /// Response type for the `register` endpoint.
109 #[response(error = UiaaResponse)]
110 pub struct Response {
111 /// An access token for the account.
112 ///
113 /// This access token can then be used to authorize other requests.
114 ///
115 /// Required if the request's `inhibit_login` was set to `false`.
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub access_token: Option<String>,
118
119 /// The fully-qualified Matrix ID that has been registered.
120 pub user_id: OwnedUserId,
121
122 /// ID of the registered device.
123 ///
124 /// Will be the same as the corresponding parameter in the request, if one was specified.
125 ///
126 /// Required if the request's `inhibit_login` was set to `false`.
127 pub device_id: Option<OwnedDeviceId>,
128
129 /// A [refresh token] for the account.
130 ///
131 /// This token can be used to obtain a new access token when it expires by calling the
132 /// [`refresh_token`] endpoint.
133 ///
134 /// Omitted if the request's `inhibit_login` was set to `true`.
135 ///
136 /// [refresh token]: https://spec.matrix.org/latest/client-server-api/#refreshing-access-tokens
137 /// [`refresh_token`]: crate::session::refresh_token
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub refresh_token: Option<String>,
140
141 /// The lifetime of the access token, in milliseconds.
142 ///
143 /// Once the access token has expired, a new access token can be obtained by using the
144 /// provided refresh token. If no refresh token is provided, the client will need to
145 /// re-login to obtain a new access token.
146 ///
147 /// If this is `None`, the client can assume that the access token will not expire.
148 ///
149 /// Omitted if the request's `inhibit_login` was set to `true`.
150 #[serde(
151 with = "ruma_common::serde::duration::opt_ms",
152 default,
153 skip_serializing_if = "Option::is_none",
154 rename = "expires_in_ms"
155 )]
156 pub expires_in: Option<Duration>,
157 }
158
159 impl Request {
160 /// Creates a new `Request` with all parameters defaulted.
161 pub fn new() -> Self {
162 Default::default()
163 }
164 }
165
166 impl Response {
167 /// Creates a new `Response` with the given user ID.
168 pub fn new(user_id: OwnedUserId) -> Self {
169 Self {
170 access_token: None,
171 user_id,
172 device_id: None,
173 refresh_token: None,
174 expires_in: None,
175 }
176 }
177 }
178}
179
180/// The kind of account being registered.
181#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
182#[serde(rename_all = "snake_case")]
183#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
184pub enum RegistrationKind {
185 /// A guest account
186 ///
187 /// These accounts may have limited permissions and may not be supported by all servers.
188 Guest,
189
190 /// A regular user account
191 #[default]
192 User,
193}
194
195/// The login type.
196#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
197#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
198pub enum LoginType {
199 /// An appservice-specific login type
200 #[serde(rename = "m.login.application_service")]
201 ApplicationService,
202}