Skip to content

Add method to get subscriptions' fields used to register #6671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

[Full Changelog](In progress)

### Push
- Add `listSubscriptionReq` and `SubscriptionRequest` to list informations used to subscribe. May be used to subscribe to another pusher

# v137.0 (_2025-03-03_)

## ✨ What's New ✨
Expand Down
22 changes: 21 additions & 1 deletion components/push/src/internal/push_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use crate::internal::communications::{Connection, PersistedRateLimiter};
use crate::internal::config::PushConfiguration;
use crate::internal::crypto::KeyV1 as Key;
use crate::internal::storage::{PushRecord, Storage};
use crate::{KeyInfo, PushSubscriptionChanged, SubscriptionInfo, SubscriptionResponse};
use crate::{
KeyInfo, PushSubscriptionChanged, SubscriptionInfo, SubscriptionRequest, SubscriptionResponse,
};

use super::crypto::{Cryptography, PushPayload};
const UPDATE_RATE_LIMITER_INTERVAL: u64 = 24 * 60 * 60; // 24 hours.
Expand All @@ -35,6 +37,15 @@ impl From<Key> for KeyInfo {
}
}

impl From<PushRecord> for SubscriptionRequest {
fn from(record: PushRecord) -> Self {
SubscriptionRequest {
scope: record.scope,
app_server_key: record.app_server_key,
}
}
}

impl From<PushRecord> for PushSubscriptionChanged {
fn from(record: PushRecord) -> Self {
PushSubscriptionChanged {
Expand Down Expand Up @@ -156,6 +167,15 @@ impl<Co: Connection, Cr: Cryptography, S: Storage> PushManager<Co, Cr, S> {
.transpose()
}

pub fn list_subscription_req(&self) -> Result<Vec<SubscriptionRequest>> {
Ok(self
.store
.get_record_list()?
.into_iter()
.map(SubscriptionRequest::from)
.collect())
}

pub fn unsubscribe(&mut self, scope: &str) -> Result<bool> {
let (uaid, auth) = self.ensure_auth_pair()?;
let record = self.store.get_record_by_scope(scope)?;
Expand Down
15 changes: 15 additions & 0 deletions components/push/src/internal/storage/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub trait Storage: Sized {

fn get_record_by_scope(&self, scope: &str) -> Result<Option<PushRecord>>;

fn get_record_list(&self) -> Result<Vec<PushRecord>>;

fn put_record(&self, record: &PushRecord) -> Result<bool>;

fn delete_record(&self, chid: &str) -> Result<bool>;
Expand Down Expand Up @@ -118,6 +120,19 @@ impl Storage for PushDb {
self.try_query_row(&query, &[(":scope", scope)], PushRecord::from_row, false)
}

fn get_record_list(&self) -> Result<Vec<PushRecord>> {
let query = format!(
"SELECT {common_cols}
FROM push_record",
common_cols = schema::COMMON_COLS,
);
self.query_rows_and_then(
&query,
[],
|row| -> Result<PushRecord> { Ok(PushRecord::from_row(row)?) },
)
}

fn put_record(&self, record: &PushRecord) -> Result<bool> {
log::debug!(
"adding push subscription for scope '{}', channel '{}', endpoint '{}'",
Expand Down
21 changes: 21 additions & 0 deletions components/push/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,20 @@ impl PushManager {
self.internal.lock().unwrap().get_subscription(scope)
}

/// List existing subscription requests
/// Contains scope and application server key from existing subscriptions
///
/// # Returns
/// The list of existing [`SubscriptionRequest`]
///
/// # Errors
/// Returns an error if:
/// - An error occurred accessing the PushManagers's persistent storage
#[handle_error(PushError)]
pub fn list_subscription_req(&self) -> ApiResult<Vec<SubscriptionRequest>> {
self.internal.lock().unwrap().list_subscription_req()
}

/// Unsubscribe from given channelID, ending that subscription for the user.
///
/// # Arguments
Expand Down Expand Up @@ -381,6 +395,13 @@ impl PushManager {
}
}

/// Fields needed to do a subscription request: the scope and the application server key
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct SubscriptionRequest {
pub scope: String,
pub app_server_key: Option<String>,
}

/// Key Information that can be used to encrypt payloads. These are encoded as base64
/// so will need to be decoded before they can actually be used as keys.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
Expand Down
26 changes: 26 additions & 0 deletions components/push/src/push.udl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ interface PushManager {
[Throws=PushApiError]
SubscriptionResponse? get_subscription([ByRef] string scope);

/// List existing scopes
///
/// # Returns
/// The list of subscribed scopes
///
/// # Errors
/// Returns an error if:
/// - An error occurred accessing the PushManagers's persistent storage

/// List existing subscription requests
/// Contains scope and application server key from existing subscriptions
///
/// # Returns
/// The list of existing [`SubscriptionRequest`]
///
/// # Errors
/// Returns an error if:
/// - An error occurred accessing the PushManagers's persistent storage
[Throws=PushApiError]
sequence<SubscriptionRequest> list_subscription_req();

/// Unsubscribe from given scope, ending that subscription for the user.
///
/// # Arguments
Expand Down Expand Up @@ -141,6 +162,11 @@ interface PushManager {
DecryptResponse decrypt(record<DOMString, string> payload);
};

/// Fields needed to do a subscription request: the scope and the application server key
dictionary SubscriptionRequest {
string scope;
string? app_server_key;
};
/// Key Information that can be used to encrypt payloads
dictionary KeyInfo {
string auth;
Expand Down