Support for stable MSC4191 account management actions (#5312)

This commit is contained in:
Olivier 'reivilibre
2026-01-12 12:14:16 +00:00
committed by GitHub
3 changed files with 49 additions and 16 deletions

View File

@@ -29,7 +29,7 @@ struct DiscoveryResponse {
#[serde(rename = "org.matrix.matrix-authentication-service.graphql_endpoint")]
graphql_endpoint: url::Url,
// As per MSC2965
// As per MSC4191
account_management_uri: url::Url,
account_management_actions_supported: Vec<String>,
}
@@ -183,10 +183,15 @@ pub(crate) async fn get(
// see frontend/src/routes/__root.tsx
account_management_actions_supported: vec![
"org.matrix.profile".to_owned(),
"org.matrix.devices_list".to_owned(),
"org.matrix.device_view".to_owned(),
"org.matrix.device_delete".to_owned(),
"org.matrix.cross_signing_reset".to_owned(),
// These are unstable versions from MSC4191 and we will remove them once the above
// stable values have enough adoption by clients
"org.matrix.sessions_list".to_owned(),
"org.matrix.session_view".to_owned(),
"org.matrix.session_end".to_owned(),
"org.matrix.cross_signing_reset".to_owned(),
],
})
}

View File

@@ -478,27 +478,40 @@ impl Route for RegisterFinish {
}
}
/// Actions parameters as defined by MSC2965
/// Actions parameters as defined by MSC4191
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "action")]
pub enum AccountAction {
#[serde(rename = "org.matrix.profile")]
OrgMatrixProfile,
/// DEPRECATED: Use `OrgMatrixProfile` instead
#[serde(rename = "profile")]
Profile,
#[serde(rename = "org.matrix.devices_list")]
OrgMatrixDevicesList,
/// DEPRECATED: Use `OrgMatrixDevicesList` instead
#[serde(rename = "org.matrix.sessions_list")]
OrgMatrixSessionsList,
/// DEPRECATED: Use `OrgMatrixDevicesList` instead
#[serde(rename = "sessions_list")]
SessionsList,
#[serde(rename = "org.matrix.device_view")]
OrgMatrixDeviceView { device_id: String },
/// DEPRECATED: Use `OrgMatrixDeviceView` instead
#[serde(rename = "org.matrix.session_view")]
OrgMatrixSessionView { device_id: String },
/// DEPRECATED: Use `OrgMatrixDeviceView` instead
#[serde(rename = "session_view")]
SessionView { device_id: String },
#[serde(rename = "org.matrix.device_delete")]
OrgMatrixDeviceDelete { device_id: String },
/// DEPRECATED: Use `OrgMatrixDeviceDelete` instead
#[serde(rename = "org.matrix.session_end")]
OrgMatrixSessionEnd { device_id: String },
/// DEPRECATED: Use `OrgMatrixDeviceDelete` instead
#[serde(rename = "session_end")]
SessionEnd { device_id: String },

View File

@@ -62,17 +62,29 @@ const query = queryOptions({
const actionSchema = v.variant("action", [
v.object({
action: v.picklist(["profile", "org.matrix.profile"]),
action: v.picklist(["org.matrix.profile", "profile"]),
}),
v.object({
action: v.picklist(["sessions_list", "org.matrix.sessions_list"]),
action: v.picklist([
"org.matrix.devices_list",
"sessions_list",
"org.matrix.sessions_list",
]),
}),
v.object({
action: v.picklist(["session_view", "org.matrix.session_view"]),
action: v.picklist([
"org.matrix.device_view",
"session_view",
"org.matrix.session_view",
]),
device_id: v.optional(v.string()),
}),
v.object({
action: v.picklist(["session_end", "org.matrix.session_end"]),
action: v.picklist([
"org.matrix.device_delete",
"session_end",
"org.matrix.session_end",
]),
device_id: v.optional(v.string()),
}),
v.object({
@@ -93,16 +105,18 @@ export const Route = createFileRoute({
beforeLoad({ search }) {
switch (search.action) {
case "profile": // This is an unspecced alias for org.matrix.profile that can be removed
case "org.matrix.profile": // This is from unstable MSC4191
case "org.matrix.profile":
case "profile": // This is an unspecced alias that can be removed
throw redirect({ to: "/", search: {} });
case "sessions_list": // This is an unspecced alias for org.matrix.sessions_list that can be removed
case "org.matrix.sessions_list": // This is from unstable MSC4191
case "org.matrix.devices_list":
case "sessions_list": // This is an unspecced alias that can be removed
case "org.matrix.sessions_list": // This is an unstable value from MSC4191 that can be removed once we have enough client adoption of the stable value
throw redirect({ to: "/sessions" });
case "session_view": // This is an unspecced alias for org.matrix.session_view that can be removed
case "org.matrix.session_view": // This is from unstable MSC4191
case "org.matrix.device_view":
case "session_view": // This is an unspecced alias that can be removed
case "org.matrix.session_view": // This is an unstable value from MSC4191 that can be removed once we have enough client adoption of the stable value
if (search.device_id)
throw redirect({
to: "/devices/$",
@@ -110,8 +124,9 @@ export const Route = createFileRoute({
});
throw redirect({ to: "/sessions" });
case "org.matrix.device_delete":
case "session_end": // This is the unstable MSC3824 alias for org.matrix.session_end
case "org.matrix.session_end": // This is from unstable MSC4191
case "org.matrix.session_end": // This is an unstable value from MSC4191 that can be removed once we have enough client adoption of the stable value
if (search.device_id)
throw redirect({
to: "/devices/$",
@@ -119,14 +134,14 @@ export const Route = createFileRoute({
});
throw redirect({ to: "/sessions" });
case "org.matrix.cross_signing_reset": // This is from unstable MSC4191
case "org.matrix.cross_signing_reset":
throw redirect({
to: "/reset-cross-signing",
search: { deepLink: true },
});
case "org.matrix.plan_management": {
// This is an unspecced experimental value
// We don't both checking if the plan management iframe is actually available and
// We don't bother checking if the plan management iframe is actually available and
// instead rely on the plan tab handling it.
throw redirect({ to: "/plan" });
}