web-push-libs / vapid Goto Github PK
View Code? Open in Web Editor NEWThis project forked from jrconlin/vapid
Apps and Libraries to support WebPush VAPID
License: Mozilla Public License 2.0
This project forked from jrconlin/vapid
Apps and Libraries to support WebPush VAPID
License: Mozilla Public License 2.0
In the python code in the _base_sign
function you have:
if not re.match(r"^https?://[^/:]+(:\d+)?$",
cclaims.get("aud", ""),
re.IGNORECASE
But this seems wrong. My chrome endpoint looks like this:
https://fcm.googleapis.com/fcm/send/some-letters:abun-more-letters
So it seems that this regex is wrong and that you need to change the [^/:]+
part into maybe like .+
byte strings are being b' prefixed under python3, which is bad.
Sigh, looks like main.py got lost between updated and machine moves.
Update to include new calls, remove dashboard noise, etc.
Need to support modern python.
The python code seems to supports draft-ietf-webpush-vapid-01 and draft-ietf-webpush-vapid-02, with draft 1 still the default.
However according to those links there are draft 3 and 4 and then RFC8292 (if I'm interpreting ieft.org correctly).
Are there any significant changes between draft 2 and RFC? If so could this library be updated to support the RFC?
Taking a a look at the spec, it appears that both "sub" and "aud" are required fields in a claim, so it strikes me that it should be enforced the same way that "sub" is within sign()
and _base_sign()
.
I'm fine contributing a PR to address if the maintainers feel my concern is valid :)
IDEs like PyCharm use parameter hints very well. These should be added to ease development and testing.
Python's native cryptography lib is far faster than the python based ecdsa
, plus it would reduce dependencies.
update dependencies, clippy, etc.
Standard has changed to specify the token is WebPush
nose is apparently going to break in Python 3.10 due to one of the pending deprecation.
It seems to have survived the cut of Python 3.9, but only just. See nose-devs/nose#1099
Is there a plan/preference to replace nose?
getting this straightforward-looking warning when running vapid
$ vapid --gen
/Users/me/myproject/venv/lib/python3.11/site-packages/py_vapid/init.py:200: CryptographyDeprecationWarning: Curve argument must be an instance of an EllipticCurve class. Did you pass a class by mistake? This will be an exception in a future version of cryptography.
self.private_key = ec.generate_private_key(ec.SECP256R1, default_backend())
it seems to me that you can fix it with with a pair of parens : ec.SECP256R1()
I'm leery of messing with other people's security code so just opening this as an issue.
Add a rust lang implementation.
(Note: This is my first experimentation with Rust. Suggestions and critiques gleefully accepted.)
Can you help me? I don't know how to do it :) You have from_string
method to convert to vapid key, but I need opposite of that.
the vapid claims dict now requires the "exp" field. the webpush method should generate it if it's missing like it does for the "aud" field
Also include blurb about how you can add additional key/values to vapid claims.
Add option to dump VAPID headers as a JSON blob.
An origin doesn't have a trailing slash.
I'm not opening a one character PR because I want to make sure that we understand the implications of the change and whether it might cause problems for push servers.
https://pypi.org/project/py-vapid/ is missing 1.7.1, which is a tag here
https://github.com/web-push-libs/vapid/releases/tag/1.7.1
I'm following this link to create web push notification for my App, right now I'm stuck in step2 (creating public and private key) because I can't run this command(even tough I have implemented successfully the vapid
vapid --sign claim.json
I got this error when running this command!! 'vapid' is not recognized as an internal or external command,
Env(windows 10)
mozilla/wp-web-push#120 will need a PHP library to help generate VAPID artifacts.
Feedback from: @sergioburdisso
Imagine you wake up in the morning and say to yourself "today I feel like adding web push notifications to my web app", then you google "adding web push notifications to my web app", start doing this great codelab (it's really good and helpful, seriously), once you have completed, at the bottom of the codelab a link to a list of webpush libraries is given, you're so exited because you're this close to add web push notifications to app, only the server part remains; click on pywebpush to find something like this:
WebPusher(subscription_info).send(data, headers, ttl, gcm_key)
headers is a dictionary of additional HTTP header values (e.g. VAPID self identification headers)
VAPID? headers? ttl? what?... and that's it, VAPID links to pyvapid, once again, no documentations or examples... you feel lost and probably decide to give up on adding Web Push Notifications to your app.
Instead, what I tried to accomplish with solidwebpush was: once you've finished, you continue reading the example here, and that's it, you'll end up integrating web push in your application, for instance, not being aware that you're using VAPID (among other things), note that not a single "technical word" is given in the API documentation or in the README file of solidwebpush.
As I said, I think solidwebpush is not a replacement for pywebpush, since it only works implementing VAPID (not the GCM API), so it is sort of an "easy-to-use" library for those who want to implement VAPID-based push notifications (for instance, those who've learned the "client part" from this codelab, even if they're not aware of it).
NOTE From Myself: Maybe it would be good to assess how this API compares to the node web-push library and see if there is any changes that can be made to the API
https://github.com/web-push-libs/vapid/blob/master/python/py_vapid/__init__.py#L235 sets it to 24 hours which occasionally can get rejected due to clock differences. See web-push-libs/pywebpush#74
The site I am using is https://web-push-codelab.appspot.com/
it seems to be the only one that will generate a valid private/key pair that works for Chrome, but, I cannot figure out a way to get the private key into Vapid(). I feel like I am missing an important step here but there is no documentation as to what type of string the Vapid() constructor is expecting. Would it be possible to add more detail?
ERROR:root:Could not open private key file: Error('Incorrect padding',)
Traceback (most recent call last):
File "/Users/mselevan/dev/envs/next/lib/python3.5/site-packages/py_vapid/__init__.py", line 57, in __init__
base64.urlsafe_b64decode(private_key))
File "/Users/mselevan/dev/envs/next/lib/python3.5/base64.py", line 135, in urlsafe_b64decode
return b64decode(s)
File "/Users/mselevan/dev/envs/next/lib/python3.5/base64.py", line 90, in b64decode
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
Now when I add some padding to that base64encoded private key, i get a different exception
ERROR:root:Could not open private key file: UnexpectedDER('wanted sequence (0x30), got 0x92',)
Traceback (most recent call last):
File "/Users/mselevan/dev/envs/next/lib/python3.5/site-packages/py_vapid/__init__.py", line 57, in __init__
base64.urlsafe_b64decode(private_key))
File "/Users/mselevan/dev/envs/next/lib/python3.5/site-packages/ecdsa/keys.py", line 165, in from_der
s, empty = der.remove_sequence(string)
File "/Users/mselevan/dev/envs/next/lib/python3.5/site-packages/ecdsa/der.py", line 65, in remove_sequence
raise UnexpectedDER("wanted sequence (0x30), got 0x%02x" % n)
ecdsa.der.UnexpectedDER: wanted sequence (0x30), got 0x92
These values should use minimally validated hostnames (e.g.
"domain.foo"
"localhost"
"1.2.3.4"
"8001::"
etc.
The host validation introduced in 871d67d does not allow domains that contain hyphens to pass through the check, although they should be perfectly valid domains.
Working: [email protected]
Not working: [email protected]
This is also causing the issue described in home-assistant/core#48766.
Due to a misunderstanding of the VAPID spec, "aud" is the host name of the remote push server (e.g. "push.services.mozilla.org"
jwcrypto may be a better library choice than jose. Should investigate and determine if it is.
JS library has a import_public_raw function.
Do it is possible to import instead a private key to use in web push?
Keys can be in either DER or RAW format. Library should be kind and try to determine this.
New Version.
RFC 7515
@jrconlin: Can you move this original code into web-push-libs organization?
Steps to do:
It will be perfect now, no lost.
Linked to:
i get this error when the followng line executes in my flask server :
webpush(y,
data="hello",
vapid_private_key="BBdqtyrSzY8i77ejAHFmkQjmWtr3N4IxBsDl8fpjjHcPLkTAFG4ANjNUBXe6WU_5IcLKHdE-3uUAG7YvlpvPU7M",
vapid_claims={"sub": "mailto:[email protected]"})
here,y is a dict type subscription object
I'm getting Invalid JWT tokens once in a while when doing webpush and I think it's because they are actually invalid.
This example calculates the signature length:
>>> v
<py_vapid.Vapid02 object at 0x7f7ce7900880>
>>> c
Counter()
>>> for _ in range(10000):
... d = v.sign({'sub': "mailto:[email protected]", "aud": "https://example.com:8080"})
... c[len(base64.urlsafe_b64decode(d['Authorization'].split('.')[2].split(',')[0] + '===='))] += 1
>>> c
Counter({64: 9929, 63: 71})
My understanding is that it should be 64 bytes long every time.
Edit: Been using my own fix and it solved my issue completely.
test-requirements.txt
to include requirements.txt
now that such things are possible.constants.js
file.)pushManager.subscribe
takes the option applicationServerKey
client-side. The Python documentation needs to document how to convert the generated public key into a form that can be used client-side like this.
navigator.serviceWorker.register('serviceworker.js').then(
function(serviceWorkerRegistration) {
var options = {
userVisibleOnly: true,
applicationServerKey: applicationServerKey // <-- how do I convert the public key .pem to this?
};
serviceWorkerRegistration.pushManager.subscribe(options).then(
// ...
});
Hello,
Disclaimer: Please bear with me. It is my first time implementing my own web push service on a REST API. I will do my best to specify my problem and explain my implementation's logic.
I am using Python 3.6, Django 2.0, pywebpush 1.6.0 and vapid 1.3.0
I generated my new keys on Saturday and they worked fine the next day. But Now I am trying to push a message and I am getting the following error today (two days after I generated them).
I have read that the max amount of time for the vapid_claims to expire is 24 hours. Does this mean that I have to generate a VAPID keypair every 24 hours? if yes, Any recommendations to do it on run time?
Error when subscribing with Firefox:
Push failed: <Response [401]>: {"code": 401, "errno":
109, "error": "Unauthorized", "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error- codes"
, "message": "Request did not validate Invalid bearer token: Auth expired"}
Error when suscribing with Chrome:
Push failed: <Response [400]> <HTML>
<HEAD>
<TITLE>UnauthorizedRegist </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>UnauthorizedRegistration</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
This is the code I am using:
@api_view(["POST",])
def pushMessage(request, format=None):
for user in PushClient.objects.all():
try:
webpush(subscription_info={"endpoint":user.endpoint, "expirationTime": user.expirationTime,
"keys" : {"p256dh" : user.p256dh, "auth": user.auth}},data=request.data,
vapid_private_key=VAPID_PRIVATE_KEY,vapid_claims=VAPID_CLAIMS)
except Exception as e:
logger.error(e)
user.delete()
continue
return Response(status=status.HTTP_200_OK)
This are my VAPID_CLAIMS. I used py-vapid 1.3.0 to generate my keys. Then I used toString64 using node to encode them.
VAPID_PRIVATE_KEY = 'TSH+PiQph1DlfRJjPS/j4yehCAldPy20/ZyCkIjTamU='
VAPID_PUBLIC_KEY = 'BG+xOxh5lIEgFb/3M+1ROVvHQFJnCWuZD+DRELiwTb4nHGOFLPMtDH99/cFeG/sdUnoDMe278S+cUWTizMGjeHU='
VAPID_CLAIMS = {
"sub": "mailto:****@orlandocitysc.com"
}
I don't know if this would help but here it is. This is the subscription one of my client has registered. it is one of the objects I got after I do PushClient.objects.all().
{
"id": 129,
"endpoint": "https://fcm.googleapis.com/fcm/send/dEuBF4q-YZk:APA91bGK3VrHwz0M_2TMJUdYEhCGfnmGRwo5e1XOHqUA0bQShbIodU6uVAGfWEDj3Lcn1Wtd3NtbTzREl_VruWXE-jbCVv9jLlgSxzZj4TnNZzmXujyvRF3_RiIH1UUNArGSbbRdsgfk",
"expirationTime": null,
"p256dh": "BHtmNQqwqQXpYcLB3W6nd1snkhYYj7qFVGy7D40U58tqr9jsSsLMEPGLeLckhhZzmvTFPw31eI6TIvYLLWVct-M=",
"auth": "n8-gO34skDelvWtE8CO_9Q=="
}
Google appears to have dropped support for Vapid1 (which is a-ok), so we can finally switch to Vapid02 as the default.
No idea why, but a bunch of landed commits went missing.
Reapplying.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.