Skip to main content

palpo_core/client/
register.rs

1//! `POST /_matrix/client/*/register`
2//!
3//! Register an account on this homeserver.
4//! `/v3/` ([spec])
5//!
6//! [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3register
7
8use std::time::Duration;
9
10use salvo::prelude::*;
11use serde::{Deserialize, Serialize};
12
13use crate::client::account::{LoginType, RegistrationKind};
14use crate::client::uiaa::AuthData;
15use crate::{OwnedClientSecret, OwnedDeviceId, OwnedSessionId, OwnedUserId};
16
17/// Request type for the `register` endpoint.
18#[derive(ToSchema, Deserialize, Default, Debug)]
19pub struct RegisterReqBody {
20    /// The desired password for the account.
21    ///
22    /// May be empty for accounts that should not be able to log in again
23    /// with a password, e.g., for guest or application service accounts.
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub password: Option<String>,
26
27    /// Localpart of the desired Matrix ID.
28    ///
29    /// If omitted, the homeserver MUST generate a Matrix ID local part.
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub username: Option<String>,
32
33    /// ID of the client device.
34    ///
35    /// If this does not correspond to a known client device, a new device will be created.
36    /// The server will auto-generate a device_id if this is not specified.
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub device_id: Option<OwnedDeviceId>,
39
40    /// A display name to assign to the newly-created device.
41    ///
42    /// Ignored if `device_id` corresponds to a known device.
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub initial_device_display_name: Option<String>,
45
46    /// Additional authentication information for the user-interactive authentication API.
47    ///
48    /// Note that this information is not used to define how the registered user should be
49    /// authenticated, but is instead used to authenticate the register call itself.
50    /// It should be left empty, or omitted, unless an earlier call returned an response
51    /// with status code 401.
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub auth: Option<AuthData>,
54
55    /// Kind of account to register
56    ///
57    /// Defaults to `User` if omitted.
58    #[salvo(parameter(parameter_in = Query))]
59    #[serde(default, skip_serializing_if = "crate::serde::is_default")]
60    pub kind: RegistrationKind,
61
62    /// If `true`, an `access_token` and `device_id` should not be returned
63    /// from this call, therefore preventing an automatic login.
64    #[serde(default, skip_serializing_if = "crate::serde::is_default")]
65    pub inhibit_login: bool,
66
67    /// Login `type` used by Appservices.
68    ///
69    /// Appservices can [bypass the registration flows][admin] entirely by providing their
70    /// token in the header and setting this login `type` to `m.login.application_service`.
71    ///
72    /// [admin]: https://spec.matrix.org/latest/application-service-api/#server-admin-style-permissions
73    #[serde(default, rename = "type", skip_serializing_if = "Option::is_none")]
74    pub login_type: Option<LoginType>,
75
76    /// If set to `true`, the client supports [refresh tokens].
77    ///
78    /// [refresh tokens]: https://spec.matrix.org/latest/client-server-api/#refreshing-access-tokens
79    #[serde(default, skip_serializing_if = "crate::serde::is_default")]
80    pub refresh_token: bool,
81}
82impl RegisterReqBody {
83    pub fn is_default(&self) -> bool {
84        self.password.is_none()
85            && self.username.is_none()
86            && self.device_id.is_none()
87            && self.initial_device_display_name.is_none()
88            && self.auth.is_none()
89            && self.kind == Default::default()
90            && !self.inhibit_login
91            && self.login_type.is_none()
92            && !self.refresh_token
93    }
94}
95
96/// Response type for the `register` endpoint.
97#[derive(ToSchema, Serialize, Debug)]
98pub struct RegisterResBody {
99    /// An access token for the account.
100    ///
101    /// This access token can then be used to authorize other requests.
102    ///
103    /// Required if the request's `inhibit_login` was set to `false`.
104    #[serde(default, skip_serializing_if = "Option::is_none")]
105    pub access_token: Option<String>,
106
107    /// The fully-qualified Matrix ID that has been registered.
108    pub user_id: OwnedUserId,
109
110    /// ID of the registered device.
111    ///
112    /// Will be the same as the corresponding parameter in the request, if one was specified.
113    ///
114    /// Required if the request's `inhibit_login` was set to `false`.
115    pub device_id: Option<OwnedDeviceId>,
116
117    /// A [refresh token] for the account.
118    ///
119    /// This token can be used to obtain a new access token when it expires by calling the
120    /// [`refresh_token`] endpoint.
121    ///
122    /// Omitted if the request's `inhibit_login` was set to `true`.
123    ///
124    /// [refresh token]: https://spec.matrix.org/latest/client-server-api/#refreshing-access-tokens
125    /// [`refresh_token`]: crate::session::refresh_token
126    #[serde(default, skip_serializing_if = "Option::is_none")]
127    pub refresh_token: Option<String>,
128
129    /// The lifetime of the access token, in milliseconds.
130    ///
131    /// Once the access token has expired, a new access token can be obtained by using the
132    /// provided refresh token. If no refresh token is provided, the client will need to
133    /// re-login to obtain a new access token.
134    ///
135    /// If this is `None`, the client can assume that the access token will not expire.
136    ///
137    /// Omitted if the request's `inhibit_login` was set to `true`.
138    #[serde(
139        with = "palpo_core::serde::duration::opt_ms",
140        default,
141        skip_serializing_if = "Option::is_none",
142        rename = "expires_in_ms"
143    )]
144    pub expires_in: Option<Duration>,
145}
146
147/// `GET /_matrix/client/*/register/available`
148///        1.0 => "/_matrix/client/r0/register/available",
149///        1.1 => "/_matrix/client/v3/register/available",
150///
151/// Checks to see if a username is available, and valid, for the server.
152/// `/v3/` ([spec])
153///
154/// [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3registeravailable
155
156/// Response type for the `get_username_availability` endpoint.
157#[derive(ToSchema, Serialize, Debug)]
158pub struct AvailableResBody {
159    /// A flag to indicate that the username is available.
160    /// This should always be true when the server replies with 200 OK.
161    pub available: bool,
162}
163impl AvailableResBody {
164    /// Creates a new `AvailableResBody` with the given availability.
165    pub fn new(available: bool) -> Self {
166        Self { available }
167    }
168}
169
170/// `GET /_matrix/client/*/register/m.login.registration_token/validity`
171///
172/// Checks to see if the given registration token is valid.
173/// `/v1/` ([spec])
174///
175/// [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1registermloginregistration_tokenvalidity
176
177// const METADATA: Metadata = metadata! {
178//     method: GET,
179//     rate_limited: true,
180//     authentication: None,
181//     history: {
182//         unstable => "/_matrix/client/unstable/org.matrix.msc3231/register/org.matrix.msc3231.login.registration_token/validity",
183//         1.2 => "/_matrix/client/v1/register/m.login.registration_token/validity",
184//     }
185// };
186
187/// Request type for the `check_registration_token_validity` endpoint.
188#[derive(ToSchema, Deserialize, Debug)]
189pub struct ValidateTokenReqBody {
190    /// The registration token to check the validity of.
191    pub registration_token: String,
192}
193
194/// Response type for the `check_registration_token_validity` endpoint.
195#[derive(ToSchema, Serialize, Debug)]
196
197pub struct ValidateTokenResBody {
198    /// A flag to indicate that the registration token is valid.
199    pub valid: bool,
200}
201
202// `POST /_matrix/client/*/register/email/requestToken`
203/// Request a registration token with a 3rd party email.
204///
205/// `/v3/` ([spec])
206///
207/// [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3registeremailrequesttoken
208
209// const METADATA: Metadata = metadata! {
210//     method: POST,
211//     rate_limited: false,
212//     authentication: None,
213//     history: {
214//         1.0 => "/_matrix/client/r0/register/email/requestToken",
215//         1.1 => "/_matrix/client/v3/register/email/requestToken",
216//     }
217// };
218
219/// Request type for the `request_registration_token_via_email` endpoint.
220#[derive(ToSchema, Deserialize, Debug)]
221pub struct TokenVisEmailReqBody {
222    /// Client-generated secret string used to protect this session.
223    pub client_secret: OwnedClientSecret,
224
225    /// The email address.
226    pub email: String,
227
228    /// Used to distinguish protocol level retries from requests to re-send the email.
229    pub send_attempt: u64,
230
231    /// Return URL for identity server to redirect the client back to.
232    #[serde(default, skip_serializing_if = "Option::is_none")]
233    pub next_link: Option<String>,
234}
235
236/// Response type for the `request_registration_token_via_email` endpoint.
237#[derive(ToSchema, Serialize, Debug)]
238
239pub struct TokenVisEmailResBody {
240    /// The session identifier given by the identity server.
241    pub sid: OwnedSessionId,
242
243    /// URL to submit validation token to.
244    ///
245    /// If omitted, verification happens without client.
246    #[serde(
247        skip_serializing_if = "Option::is_none",
248        default,
249        deserialize_with = "crate::serde::empty_string_as_none"
250    )]
251    pub submit_url: Option<String>,
252}
253
254/// `POST /_matrix/client/*/register/msisdn/requestToken`
255///
256/// Request a registration token with a phone number.
257/// `/v3/` ([spec])
258///
259/// [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3registermsisdnrequesttoken
260
261// const METADATA: Metadata = metadata! {
262//     method: POST,
263//     rate_limited: false,
264//     authentication: None,
265//     history: {
266//         1.0 => "/_matrix/client/r0/register/msisdn/requestToken",
267//         1.1 => "/_matrix/client/v3/register/msisdn/requestToken",
268//     }
269// };
270
271/// Request type for the `request_registration_token_via_msisdn` endpoint.
272#[derive(ToSchema, Deserialize, Debug)]
273pub struct TokenVisMsisdnReqBody {
274    /// Client-generated secret string used to protect this session.
275    pub client_secret: OwnedClientSecret,
276
277    /// Two-letter ISO 3166 country code for the phone number.
278    pub country: String,
279
280    /// Phone number to validate.
281    pub phone_number: String,
282
283    /// Used to distinguish protocol level retries from requests to re-send the SMS.
284    pub send_attempt: u64,
285
286    /// Return URL for identity server to redirect the client back to.
287    #[serde(default, skip_serializing_if = "Option::is_none")]
288    pub next_link: Option<String>,
289}
290
291/// Response type for the `request_registration_token_via_msisdn` endpoint.
292#[derive(ToSchema, Serialize, Debug)]
293
294pub struct TokenVisMsisdnResBody {
295    /// The session identifier given by the identity server.
296    pub sid: OwnedSessionId,
297
298    /// URL to submit validation token to.
299    ///
300    /// If omitted, verification happens without client.
301    #[serde(
302        skip_serializing_if = "Option::is_none",
303        default,
304        deserialize_with = "crate::serde::empty_string_as_none"
305    )]
306    pub submit_url: Option<String>,
307}