Skip to main content

tuwunel_api_client/account/3pid/
add_3pid.rs

1use axum::extract::State;
2use ruma::{
3	MilliSecondsSinceUnixEpoch,
4	api::client::account::add_3pid::{self, v3::Response},
5};
6use tuwunel_core::{Err, Result, err, utils::BoolExt};
7
8use crate::{ClientIp, Ruma, router::auth_uiaa, utils::check_email_domain};
9
10/// # `POST /_matrix/client/v3/account/3pid/add`
11///
12/// Bind a verified email address to this account.
13///
14/// - Requires UIAA to confirm account ownership
15/// - Consumes a previously validated email verification session
16#[tracing::instrument(skip_all, fields(%client), name = "add_3pid")]
17pub(crate) async fn add_3pid_route(
18	State(services): State<crate::State>,
19	ClientIp(client): ClientIp,
20	body: Ruma<add_3pid::v3::Request>,
21) -> Result<Response> {
22	if !services.sendmail.is_enabled() {
23		return Err!(Request(ThreepidDenied("Email verification is not configured")));
24	}
25
26	let ref sender_user = auth_uiaa(&services, &body).await?;
27
28	let association = services
29		.threepid
30		.redeem_validated(body.sid.as_str(), body.client_secret.as_str())
31		.await?;
32
33	check_email_domain(&services, &association.address)?;
34
35	let now = MilliSecondsSinceUnixEpoch::now();
36
37	services
38		.threepid
39		.bind_unclaimed(sender_user, &association.address, association.medium, now)
40		.await?
41		.into_option()
42		.ok_or_else(|| err!(Request(ThreepidInUse("That email address is already in use"))))?;
43
44	Ok(Response::new())
45}