mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-13 20:26:52 +00:00
feat(push): Add MSC4174 web push
This commit is contained in:
1 parent
dbcffe8af0
commit
ed1e634579
23 files changed
+1864
-281
No files matched your search
@@ -13,6 +13,7 @@ use ruma::{
|
||||
},
|
||||
assign,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::Ruma;
|
||||
|
||||
@@ -55,5 +56,10 @@ pub(crate) async fn get_capabilities_route(
|
||||
assign!(ProfileFieldsCapability::new(true), { disallowed: Some(services.oidc.restricted_profile_fields()) }),
|
||||
);
|
||||
|
||||
capabilities.set(
|
||||
"org.matrix.msc4174.webpush",
|
||||
json!({ "enabled": true, "vapid": services.pusher.webpush_vapid_public_key() }),
|
||||
)?;
|
||||
|
||||
Ok(get_capabilities::v3::Response::new(capabilities))
|
||||
}
|
||||
+77
-8
@@ -1,13 +1,16 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use axum::extract::State;
|
||||
use conduwuit::{Err, Error, Result, err};
|
||||
use conduwuit_service::Services;
|
||||
use conduwuit::{Err, Error, Result, err, utils::IterStream};
|
||||
use conduwuit_service::{Services, pusher::ActivationOutcome};
|
||||
use futures::StreamExt;
|
||||
use ruma::{
|
||||
CanonicalJsonObject, CanonicalJsonValue,
|
||||
api::{
|
||||
client::push::{
|
||||
delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions,
|
||||
get_pushrule_enabled, get_pushrules_all, get_pushrules_global_scope, set_pusher,
|
||||
set_pushrule, set_pushrule_actions, set_pushrule_enabled,
|
||||
delete_pushrule, get_pushrule, get_pushrule_actions, get_pushrule_enabled,
|
||||
get_pushrules_all, get_pushrules_global_scope, set_pushrule, set_pushrule_actions,
|
||||
set_pushrule_enabled,
|
||||
},
|
||||
error::ErrorKind,
|
||||
},
|
||||
@@ -20,6 +23,12 @@ use ruma::{
|
||||
RemovePushRuleError, Ruleset,
|
||||
},
|
||||
};
|
||||
use ruminuwuity::pushers::{
|
||||
PusherKind,
|
||||
ack::unstable as pushers_ack,
|
||||
get_pushers::{self, v3::PusherWithActivation},
|
||||
set_pusher,
|
||||
};
|
||||
|
||||
use crate::Ruma;
|
||||
|
||||
@@ -460,7 +469,29 @@ pub(crate) async fn get_pushers_route(
|
||||
) -> Result<get_pushers::v3::Response> {
|
||||
let sender_user = body.identity.expect_sender_user()?;
|
||||
|
||||
Ok(get_pushers::v3::Response::new(services.pusher.get_pushers(sender_user).await))
|
||||
let pushers = services
|
||||
.pusher
|
||||
.get_pushers(sender_user)
|
||||
.await
|
||||
.into_iter()
|
||||
.stream()
|
||||
.then(async |pusher| {
|
||||
let activated = match pusher.kind {
|
||||
| PusherKind::WebPush(_) => Some(
|
||||
services
|
||||
.pusher
|
||||
.is_webpush_activated(sender_user, pusher.ids.pushkey.as_str())
|
||||
.await,
|
||||
),
|
||||
| _ => None,
|
||||
};
|
||||
|
||||
PusherWithActivation { pusher, activated }
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
Ok(get_pushers::v3::Response::new(pushers))
|
||||
}
|
||||
|
||||
/// # `POST /_matrix/client/r0/pushers/set`
|
||||
@@ -475,12 +506,50 @@ pub(crate) async fn set_pushers_route(
|
||||
let sender_user = body.identity.expect_sender_user()?;
|
||||
let sender_device = body.identity.expect_sender_device()?;
|
||||
|
||||
services
|
||||
let needs_activation = services
|
||||
.pusher
|
||||
.set_pusher(sender_user, sender_device, &body.action)
|
||||
.await?;
|
||||
|
||||
Ok(set_pusher::v3::Response::new())
|
||||
Ok(set_pusher::v3::Response::new(needs_activation))
|
||||
}
|
||||
|
||||
pub(crate) async fn pushers_ack_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<pushers_ack::Request>,
|
||||
) -> Result<pushers_ack::Response> {
|
||||
let sender_user = body.identity.expect_sender_user()?;
|
||||
|
||||
match services
|
||||
.pusher
|
||||
.activate_webpush_pusher(sender_user, &body.app_id, &body.ack_token)
|
||||
.await?
|
||||
{
|
||||
| ActivationOutcome::Activated => Ok(pushers_ack::Response::new()),
|
||||
| ActivationOutcome::NoSuchPusher => {
|
||||
Err!(Request(NotFound("No pusher with this app ID exists.")))
|
||||
},
|
||||
| ActivationOutcome::UnknownToken => Err(Error::Request(
|
||||
UNKNOWN_ACTIVATION_TOKEN.clone(),
|
||||
"Unknown activation token.".into(),
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
)),
|
||||
| ActivationOutcome::Expired => Err(Error::Request(
|
||||
EXPIRED_ACTIVATION_TOKEN.clone(),
|
||||
"Activation token has expired.".into(),
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
static EXPIRED_ACTIVATION_TOKEN: LazyLock<ErrorKind> =
|
||||
LazyLock::new(|| custom_error_kind("ORG.MATRIX.MSC4174_EXPIRED_ACTIVATION_TOKEN"));
|
||||
static UNKNOWN_ACTIVATION_TOKEN: LazyLock<ErrorKind> =
|
||||
LazyLock::new(|| custom_error_kind("ORG.MATRIX.MSC4174_UNKNOWN_ACTIVATION_TOKEN"));
|
||||
|
||||
fn custom_error_kind(errcode: &str) -> ErrorKind {
|
||||
serde_json::from_value(serde_json::json!({ "errcode": errcode }))
|
||||
.expect("errcode deserializes into an ErrorKind")
|
||||
}
|
||||
|
||||
/// user somehow has bad push rules, these must always exist per spec.
|
||||
|
||||
Reference in new issue
Block a user