Stabilisation of supported MSC4191 account management actions

- Support the stable names and the unstable names
- Advertise both the stable names and the unstable names

This means that MAS supports either names. We can remove the unstable names once the is enough client adoption of the stable names.

n.b. this does not change the oauth2-types crate as not used by MAS.
This commit is contained in:
Hugh Nimmo-Smith
2025-12-03 10:43:39 +00:00
parent ee4d1304ab
commit ca9cedcfda
3 changed files with 36 additions and 16 deletions
+6 -2
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,14 @@ 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(),
],
})
}
+14 -1
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 },
+16 -13
View File
@@ -62,17 +62,17 @@ 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 +93,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 +112,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 +122,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" });
}