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}