Skip to content

Commit 50d458c

Browse files
committed
rename: web_push -> web_push_ex
1 parent 2d2939e commit 50d458c

File tree

11 files changed

+73
-49
lines changed

11 files changed

+73
-49
lines changed

README.md

+33-21
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
# WebPush
1+
# WebPushEx
22

3-
This library implements RFC 8291 Message Encryption for Web Push.
3+
This library implements
4+
[RFC 8291](https://datatracker.ietf.org/doc/html/rfc8291/) Message Encryption
5+
for Web Push in Elixir.
46

57
It generates request details but does not make the HTTP POST request itself. The
68
generated details should be enough to feed to your HTTP client of choice.
79

8-
## Installation
9-
10-
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
11-
by adding `web_push` to your list of dependencies in `mix.exs`:
10+
#### Features
1211

13-
```elixir
14-
def deps do
15-
[
16-
{:web_push, "~> 0.1.0"}
17-
]
18-
end
19-
```
12+
* `aes128gcm` content encoding method
13+
* uses `:json` (requires Erlang/OTP >=27)
14+
* uses JOSE for handling JWT
15+
* bring your own HTTP client
16+
* tested using RFC examples
2017

2118
## Configuration
2219

@@ -27,18 +24,18 @@ generated config to your needs:
2724
$ mix web_push.vapid
2825
# in config/config.exs:
2926
30-
config :web_push, :vapid,
27+
config :web_push_ex, :vapid,
3128
public_key: "<base64 encoded public key>"
3229
subject: "[email protected]"
3330
3431
# in config/runtime.exs:
3532
36-
config :web_push, :vapid,
33+
config :web_push_ex, :vapid,
3734
private_key: System.fetch_env!("WEB_PUSH_VAPID_PRIVATE_KEY")
3835
3936
# in your environment:
4037
41-
export WEB_PUSH_VAPID_PRIVATE_KEY=<base64 encoded private key>
38+
export WEB_PUSH_EX_VAPID_PRIVATE_KEY=<base64 encoded private key>
4239
```
4340

4441
## Usage
@@ -54,21 +51,21 @@ pushManager.subscribe({
5451
}).then(...);
5552
```
5653

57-
Once you have your subscription data, you may construct a `WebPush.Request` and
54+
Once you have your subscription data, you may construct a `WebPushEx.Request` and
5855
use it to make the push notification via the HTTP client of your choice.
5956

6057
```elixir
6158
# create the struct from the subscription JSON data
6259
subscription =
63-
WebPush.Subscription.from_json("""
60+
WebPushEx.Subscription.from_json("""
6461
{"endpoint":"https://push.example.com/123","keys":{"p256dh":"user_agent_public_key","auth":"auth_secret"}}
6562
""")
6663

6764
# structured message, see example serviceWorker.js linked below
6865
message = %{title: "Notification Title", body: "lorem ipsum etc"}
6966

7067
# generate request details
71-
%WebPush.Request{} = request = WebPush.request(subscription, :json.encode(message))
68+
%WebPushEx.Request{} = request = WebPushEx.request(subscription, :json.encode(message))
7269

7370
request.endpoint
7471
# => "https://push.example.com/123"
@@ -86,14 +83,29 @@ request.headers
8683
# "Urgency" => "normal"
8784
# }
8885

89-
# send web push notification via http client e.g. tesla
90-
Tesla.post(request.endpoint, request.body, headers: Map.to_list(request.headers))
86+
# send web push notification via http client e.g. req
87+
{:ok, resp} = Req.post(request.endpoint, body: request.body, headers: request.headers)
88+
```
89+
90+
## Installation
91+
92+
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
93+
by adding `web_push` to your list of dependencies in `mix.exs`:
94+
95+
```elixir
96+
def deps do
97+
[
98+
{:web_push_ex, "~> 0.1.0"}
99+
]
100+
end
91101
```
92102

93103
## tl()
94104

95105
#### Motivation && Inspiration
96106

107+
Many thanks to maintainers and contributors to all these repos 🙇
108+
97109
* [web-push-elixir](https://github.com/midarrlabs/web-push-elixir)
98110
* [web-push-encryption](https://github.com/tuvistavie/elixir-web-push-encryption)
99111
* [web-push](https://github.com/web-push-libs/web-push)

config/dev.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Config
33
# use OTP :json for development
44
config :jose, :json_module, WebPush.JOSEjson
55

6-
config :web_push, :vapid,
6+
config :web_push_ex, :vapid,
77
public_key: "",
88
private_key: "",
99
subject: "[email protected]"

config/test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Config
22

33
# use OTP :json for testing
4-
config :jose, :json_module, WebPush.JOSEjson
4+
config :jose, :json_module, WebPushEx.JOSEjson
55

6-
config :web_push, :vapid,
6+
config :web_push_ex, :vapid,
77
public_key: "",
88
private_key: "",
99
subject: "[email protected]"

lib/mix/tasks/web_push/vapid.ex

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule Mix.Tasks.WebPush.Vapid do
1+
defmodule Mix.Tasks.WebPushEx.Vapid do
22
@moduledoc """
33
Generate VAPID keys for config.
44
@@ -23,24 +23,24 @@ defmodule Mix.Tasks.WebPush.Vapid do
2323

2424
defp encode({public_key, private_key}), do: {encode(public_key), encode(private_key)}
2525

26-
defp encode(key), do: Base.url_encode64(key, padding: false)
26+
defp encode(key), do: WebPushEx.encode(key)
2727

2828
defp build_config_message({public_key, private_key}) do
2929
"""
3030
# in config/config.exs:
3131
32-
config :web_push, :vapid,
32+
config :web_push_ex, :vapid,
3333
public_key: "#{public_key}",
3434
subject: "[email protected]"
3535
3636
# in config/runtime.exs:
3737
38-
config :web_push, :vapid,
39-
private_key: System.fetch_env!("WEB_PUSH_VAPID_PRIVATE_KEY")
38+
config :web_push_ex, :vapid,
39+
private_key: System.fetch_env!("WEB_PUSH_EX_VAPID_PRIVATE_KEY")
4040
4141
# in your environment:
4242
43-
export WEB_PUSH_VAPID_PRIVATE_KEY=#{private_key}
43+
export WEB_PUSH_EX_VAPID_PRIVATE_KEY=#{private_key}
4444
"""
4545
end
4646
end

lib/web_push.ex

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
defmodule WebPush do
1+
defmodule WebPushEx do
22
@moduledoc """
33
Web Push notifications via `aes128gcm`.
44
55
Implementation of RFC 8291, 8188, & 5689.
66
"""
77

8-
alias WebPush.{Request, Subscription}
8+
alias WebPushEx.{Request, Subscription}
99

1010
@base64_options [padding: false]
1111
@default_exp 12 * 60 * 60
@@ -176,7 +176,7 @@ defmodule WebPush do
176176

177177
@spec fetch_vapid!(vapid_key(), boolean()) :: String.t()
178178
defp fetch_vapid!(key, decode \\ true) do
179-
:web_push
179+
:web_push_ex
180180
|> Application.fetch_env!(:vapid)
181181
|> Keyword.fetch!(key)
182182
|> decode_if(key, decode)

lib/web_push/jose_json.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule WebPush.JOSEjson do
1+
defmodule WebPushEx.JOSEjson do
22
@moduledoc """
33
:json wrapper for JOSE.
44
"""

lib/web_push/request.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule WebPush.Request do
1+
defmodule WebPushEx.Request do
22
@moduledoc """
33
Request details ready for sending to the subscription endpoint.
44
"""

lib/web_push/subscription.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule WebPush.Subscription do
1+
defmodule WebPushEx.Subscription do
22
@moduledoc """
33
Subscription data structure.
44
"""

mix.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
defmodule WebPush.MixProject do
1+
defmodule WebPushEx.MixProject do
22
use Mix.Project
33

4-
@source_url "https://github.com/kenichi/web-push"
4+
@source_url "https://github.com/kenichi/web-push-ex"
55
@version "0.1.0"
66

77
def project do
88
[
9-
app: :web_push,
9+
app: :web_push_ex,
1010
version: @version,
1111
elixir: "~> 1.17",
1212
elixirc_paths: elixirc_paths(Mix.env()),

test/support/web_push_fixtures.ex renamed to test/support/web_push_ex_fixtures.ex

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
defmodule WebPushFixtures do
1+
defmodule WebPushExFixtures do
22
@moduledoc """
33
Example data from RFC 8291, section 5.
44
55
see: https://datatracker.ietf.org/doc/html/rfc8291/#section-5
66
"""
77

8-
import WebPush, only: [decode: 1]
8+
import WebPushEx, only: [decode: 1]
99

1010
@doc """
1111
WebPushSubscription fixture with default `p256dh` and `auth` values from the
@@ -21,7 +21,7 @@ defmodule WebPushFixtures do
2121
auth: "BTBZMqHH6r4Tts7J_aSIgg"
2222
}
2323
})
24-
|> then(&struct!(WebPush.Subscription, &1))
24+
|> then(&struct!(WebPushEx.Subscription, &1))
2525
end
2626

2727
@doc """

test/web_push_test.exs renamed to test/web_push_ex_test.exs

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
defmodule WebPushTest do
1+
defmodule WebPushExTest do
22
use ExUnit.Case, async: true
33

4-
import WebPushFixtures
5-
6-
alias WebPush
4+
import WebPushExFixtures
75

86
describe "request/3" do
97
test "generates details according to example in section 5/appendix A" do
108
wps = web_push_subscription_fixture()
11-
request = WebPush.request(wps, plaintext(), as_key_pair: as_key_pair(), salt: salt())
9+
request = WebPushEx.request(wps, plaintext(), as_key_pair: as_key_pair(), salt: salt())
1210

1311
assert request.headers
1412
|> Map.get("Authorization")
@@ -18,7 +16,7 @@ defmodule WebPushTest do
1816
refute Map.has_key?(request.headers, "Crypto-Key")
1917
assert Map.get(request.headers, "Urgency") == "normal"
2018

21-
assert request.body == WebPush.decode(expected())
19+
assert request.body == WebPushEx.decode(expected())
2220

2321
<<salt::binary-size(16), rs::unsigned-big-integer-size(32), idlen::8,
2422
keyid::binary-size(idlen), _ciphertext::binary>> = request.body
@@ -33,7 +31,7 @@ defmodule WebPushTest do
3331
describe "from_json/1" do
3432
test "decodes to struct" do
3533
observed =
36-
WebPush.Subscription.from_json("""
34+
WebPushEx.Subscription.from_json("""
3735
{
3836
"endpoint": "https://push.example.com/123",
3937
"keys": {
@@ -48,5 +46,19 @@ defmodule WebPushTest do
4846
assert observed.endpoint == URI.parse(expected.endpoint)
4947
assert observed.keys == expected.keys
5048
end
49+
50+
test "raises with invalid keys" do
51+
assert_raise ArgumentError, fn ->
52+
WebPushEx.Subscription.from_json("""
53+
{
54+
"end": "https://push.example.com/123",
55+
"key": {
56+
"p256": "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4",
57+
"au": "BTBZMqHH6r4Tts7J_aSIgg"
58+
}
59+
}
60+
""")
61+
end
62+
end
5163
end
5264
end

0 commit comments

Comments
 (0)