Giter Site home page Giter Site logo

rust-web-push's Introduction

Rust Web Push

Cargo tests crates.io docs.rs

Matrix chat

Web push notification sender.

Requirements

Clients require an async executor. System Openssl is needed for compilation.

Migration to greater than v0.7

  • The aesgcm variant of ContentEncoding has been removed. Aes128Gcm support was added in v0.8, so all uses of ContentEncoding::aesgcm can simply be changed to ContentEncoding::Aes128Gcm with no change to functionality. This will add support for Edge in the process.

  • WebPushClient::new() now returns a Result, as the default client now has a fallible constructor. Please handle this error in the case of resource starvation.

  • All GCM/FCM support has been removed. If you relied on this functionality, consider the fcm crate. If you just require web push, you will need to use VAPID to send payloads. See below for info.

  • A new error variant WebPushError::InvalidClaims has been added. This may break exhaustive matches.

Usage

To send a web push from command line, first subscribe to receive push notifications with your browser and store the subscription info into a json file. It should have the following content:

{
  "endpoint": "https://updates.push.services.mozilla.com/wpush/v1/TOKEN",
  "keys": {
    "auth": "####secret####",
    "p256dh": "####public_key####"
  }
}

Google has good instructions for building a frontend to receive notifications.

Store the subscription info to examples/test.json and send a notification with cargo run --example simple_send -- -f examples/test.json -p "It works!".

Example

use web_push::*;
use base64::URL_SAFE;
use std::fs::File;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
    let endpoint = "https://updates.push.services.mozilla.com/wpush/v1/...";
    let p256dh = "key_from_browser_as_base64";
    let auth = "auth_from_browser_as_base64";

    //You would likely get this by deserializing a browser `pushSubscription` object.  
    let subscription_info = SubscriptionInfo::new(
        endpoint,
        p256dh,
        auth
    );

    //Read signing material for payload.
    let file = File::open("private.pem").unwrap();
    let mut sig_builder = VapidSignatureBuilder::from_pem(file, &subscription_info)?.build()?;

    //Now add payload and encrypt.
    let mut builder = WebPushMessageBuilder::new(&subscription_info)?;
    let content = "Encrypted payload to be sent in the notification".as_bytes();
    builder.set_payload(ContentEncoding::Aes128Gcm, content);
    builder.set_vapid_signature(sig_builder);

    let client = WebPushClient::new()?;

    //Finally, send the notification!
    client.send(builder.build()?).await?;
    Ok(())
}

VAPID

VAPID authentication prevents unknown sources sending notifications to the client and is required by all current browsers when sending a payload.

The private key to be used by the server can be generated with OpenSSL:

openssl ecparam -genkey -name prime256v1 -out private_key.pem

To derive a public key from the just-generated private key, to be used in the JavaScript client:

openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr '/+' '_-'|tr -d '\n'

The signature is created with VapidSignatureBuilder. It automatically adds the required claims aud and exp. Adding these claims to the builder manually will override the default values.

Overview

Currently, the crate implements RFC8188 content encryption for notification payloads. This is done by delegating encryption to mozilla's ece crate. Our security is thus tied to theirs. The default client is built on isahc, but can be swapped out with a hyper based client using the hyper-client feature. Custom clients can be made using the request_builder module.

Library tested with Google's and Mozilla's push notification services. Also verified to work on Edge.

Openssl is needed to build. Install openssl-dev or equivalent on *nix, or openssl using vcpkg on Windows. A nix script is also available.

If installing on Windows, this is the exact command:

vcpkg integrate install
vcpkg install openssl:x64-windows-static-md

Debugging

If you get an error or the push notification doesn't work you can try to debug using the following instructions:

Add the following to your Cargo.toml:

log = "0.4"
pretty_env_logger = "0.3"

Add the following to your main.rs:

extern crate pretty_env_logger;

// ...
fn main() {
    pretty_env_logger::init();
    // ...
}

Or use any other logging library compatible with https://docs.rs/log/

Then run your program with the following environment variables:

RUST_LOG="web_push::client=trace" cargo run

This should print some more information about the requests to the push service which may aid you or somebody else in finding the error.

rust-web-push's People

Contributors

pimeys avatar andyblarblar avatar jcapucho avatar oliverbestmann avatar cyphernaught-0x avatar mohe2015 avatar github-actions[bot] avatar niklasf avatar thjread avatar cheolgyu avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.