Fixed notifications VAPID
Build and Publish / Build and Publish Docker Image (push) Successful in 1m26s
Build and Publish / Build and Publish Docker Image (push) Successful in 1m26s
This commit is contained in:
@@ -11,13 +11,10 @@ fn main() {
|
||||
.expect("generated key must be valid")
|
||||
.public_key()
|
||||
.to_encoded_point(false);
|
||||
println!(
|
||||
"WEB_PETTING_VAPID_PRIVATE_KEY={}",
|
||||
URL_SAFE_NO_PAD.encode(&private)
|
||||
);
|
||||
println!(
|
||||
"WEB_PETTING_VAPID_PUBLIC_KEY={}",
|
||||
URL_SAFE_NO_PAD.encode(public.as_bytes())
|
||||
);
|
||||
println!("WEB_PETTING_VAPID_SUBJECT=mailto:admin@example.com");
|
||||
println!("VAPID private key (copy only the next line):");
|
||||
println!("{}", URL_SAFE_NO_PAD.encode(&private));
|
||||
println!("\nVAPID public key (copy only the next line):");
|
||||
println!("{}", URL_SAFE_NO_PAD.encode(public.as_bytes()));
|
||||
println!("\nVAPID subject:");
|
||||
println!("mailto:admin@example.com");
|
||||
}
|
||||
|
||||
@@ -310,6 +310,9 @@ pub struct Translations {
|
||||
pub portal_notifications_enable: &'static str,
|
||||
pub portal_notifications_disable: &'static str,
|
||||
pub portal_notifications_denied: &'static str,
|
||||
pub portal_notifications_active: &'static str,
|
||||
pub portal_notifications_error: &'static str,
|
||||
pub portal_notifications_unsupported: &'static str,
|
||||
pub portal_calendar: &'static str,
|
||||
pub portal_future_visit: &'static str,
|
||||
pub portal_previous: &'static str,
|
||||
@@ -456,6 +459,9 @@ static RU: Translations = Translations {
|
||||
portal_notifications_enable: "Включить уведомления",
|
||||
portal_notifications_disable: "Отключить уведомления",
|
||||
portal_notifications_denied: "Уведомления заблокированы в настройках браузера.",
|
||||
portal_notifications_active: "Уведомления подключены на этом устройстве.",
|
||||
portal_notifications_error: "Не удалось сохранить подписку. Обновите страницу и попробуйте ещё раз.",
|
||||
portal_notifications_unsupported: "Этот браузер не поддерживает фоновые уведомления.",
|
||||
portal_calendar: "Календарь визитов",
|
||||
portal_future_visit: "Будущий визит",
|
||||
portal_previous: "Назад",
|
||||
@@ -703,6 +709,9 @@ static EN: Translations = Translations {
|
||||
portal_notifications_enable: "Enable notifications",
|
||||
portal_notifications_disable: "Disable notifications",
|
||||
portal_notifications_denied: "Notifications are blocked in your browser settings.",
|
||||
portal_notifications_active: "Notifications are enabled on this device.",
|
||||
portal_notifications_error: "The subscription could not be saved. Reload the page and try again.",
|
||||
portal_notifications_unsupported: "This browser does not support background notifications.",
|
||||
portal_calendar: "Visit calendar",
|
||||
portal_future_visit: "Future visit",
|
||||
portal_previous: "Previous",
|
||||
|
||||
+13
-1
@@ -507,6 +507,7 @@ async fn portal_push_subscribe(
|
||||
db: Database,
|
||||
Path(token): Path<String>,
|
||||
) -> cot::Result<Response> {
|
||||
tracing::info!("client Web Push subscription request");
|
||||
if crate::web_push::load_config(&db).await.is_none() {
|
||||
return Html::new("404").into_response();
|
||||
}
|
||||
@@ -522,8 +523,19 @@ async fn portal_push_subscribe(
|
||||
|| form.keys.p256dh.len() > 512
|
||||
|| form.keys.auth.len() > 256
|
||||
{
|
||||
return Html::new("400").into_response();
|
||||
let mut response = Response::new(cot::Body::fixed(
|
||||
"{\"ok\":false,\"error\":\"invalid subscription\"}",
|
||||
));
|
||||
*response.status_mut() = cot::StatusCode::BAD_REQUEST;
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("content-type", "application/json".parse().unwrap());
|
||||
return Ok(response);
|
||||
}
|
||||
tracing::info!(
|
||||
client_id = client.id.unwrap(),
|
||||
"client Web Push subscription saved"
|
||||
);
|
||||
let endpoint = form.endpoint.clone();
|
||||
let now = chrono::Utc::now().naive_utc();
|
||||
if let Some(mut subscription) = query!(PushSubscription, $endpoint == endpoint)
|
||||
|
||||
+24
-3
@@ -23,9 +23,30 @@ pub async fn load_config(db: &Database) -> Option<VapidConfig> {
|
||||
.map(|setting| setting.value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
};
|
||||
let public_key = value("vapid_public_key")?;
|
||||
let private_key = value("vapid_private_key")?;
|
||||
let subject = value("vapid_subject").unwrap_or_else(|| "mailto:admin@localhost".to_string());
|
||||
let strip_assignment = |value: String, name: &str| {
|
||||
value
|
||||
.strip_prefix(&format!("{name}="))
|
||||
.unwrap_or(&value)
|
||||
.trim()
|
||||
.to_string()
|
||||
};
|
||||
let public_key = strip_assignment(value("vapid_public_key")?, "WEB_PETTING_VAPID_PUBLIC_KEY");
|
||||
let private_key =
|
||||
strip_assignment(value("vapid_private_key")?, "WEB_PETTING_VAPID_PRIVATE_KEY");
|
||||
let subject = strip_assignment(
|
||||
value("vapid_subject").unwrap_or_else(|| "mailto:admin@localhost".to_string()),
|
||||
"WEB_PETTING_VAPID_SUBJECT",
|
||||
);
|
||||
let public_bytes = URL_SAFE_NO_PAD.decode(&public_key).ok()?;
|
||||
let private_bytes = URL_SAFE_NO_PAD.decode(&private_key).ok()?;
|
||||
if public_bytes.len() != 65 || public_bytes.first() != Some(&4) || private_bytes.len() != 32 {
|
||||
tracing::warn!(
|
||||
public_key_bytes = public_bytes.len(),
|
||||
private_key_bytes = private_bytes.len(),
|
||||
"invalid VAPID configuration in database"
|
||||
);
|
||||
return None;
|
||||
}
|
||||
Some(VapidConfig {
|
||||
public_key,
|
||||
private_key,
|
||||
|
||||
Reference in New Issue
Block a user